diff options
author | David S. Miller <davem@davemloft.net> | 2011-07-14 10:56:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-14 10:56:40 -0400 |
commit | 6a7ebdf2fd15417e87b4fd02ff411aeaca34da5f (patch) | |
tree | 86b15d8cd3e25c97b348b5a61bdb16c02726a480 /drivers/media | |
parent | f6b72b6217f8c24f2a54988e58af858b4e66024d (diff) | |
parent | 51414d41084496aaefd06d7f19eb8206e8bfac2d (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
net/bluetooth/l2cap_core.c
Diffstat (limited to 'drivers/media')
40 files changed, 586 insertions, 583 deletions
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 8fa539dde1b4..7f7079b12f23 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c | |||
@@ -597,12 +597,17 @@ static void __devexit fintek_remove(struct pnp_dev *pdev) | |||
597 | static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state) | 597 | static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state) |
598 | { | 598 | { |
599 | struct fintek_dev *fintek = pnp_get_drvdata(pdev); | 599 | struct fintek_dev *fintek = pnp_get_drvdata(pdev); |
600 | unsigned long flags; | ||
600 | 601 | ||
601 | fit_dbg("%s called", __func__); | 602 | fit_dbg("%s called", __func__); |
602 | 603 | ||
604 | spin_lock_irqsave(&fintek->fintek_lock, flags); | ||
605 | |||
603 | /* disable all CIR interrupts */ | 606 | /* disable all CIR interrupts */ |
604 | fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS); | 607 | fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS); |
605 | 608 | ||
609 | spin_unlock_irqrestore(&fintek->fintek_lock, flags); | ||
610 | |||
606 | fintek_config_mode_enable(fintek); | 611 | fintek_config_mode_enable(fintek); |
607 | 612 | ||
608 | /* disable cir logical dev */ | 613 | /* disable cir logical dev */ |
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 3f3c70716268..6bc35eeb653b 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -307,6 +307,14 @@ static const struct { | |||
307 | /* 0xffdc iMON MCE VFD */ | 307 | /* 0xffdc iMON MCE VFD */ |
308 | { 0x00010000ffffffeell, KEY_VOLUMEUP }, | 308 | { 0x00010000ffffffeell, KEY_VOLUMEUP }, |
309 | { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, | 309 | { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, |
310 | { 0x00000001ffffffeell, KEY_MUTE }, | ||
311 | { 0x0000000fffffffeell, KEY_MEDIA }, | ||
312 | { 0x00000012ffffffeell, KEY_UP }, | ||
313 | { 0x00000013ffffffeell, KEY_DOWN }, | ||
314 | { 0x00000014ffffffeell, KEY_LEFT }, | ||
315 | { 0x00000015ffffffeell, KEY_RIGHT }, | ||
316 | { 0x00000016ffffffeell, KEY_ENTER }, | ||
317 | { 0x00000017ffffffeell, KEY_ESC }, | ||
310 | /* iMON Knob values */ | 318 | /* iMON Knob values */ |
311 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, | 319 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, |
312 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, | 320 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, |
@@ -1582,16 +1590,16 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1582 | /* Only panel type events left to process now */ | 1590 | /* Only panel type events left to process now */ |
1583 | spin_lock_irqsave(&ictx->kc_lock, flags); | 1591 | spin_lock_irqsave(&ictx->kc_lock, flags); |
1584 | 1592 | ||
1593 | do_gettimeofday(&t); | ||
1585 | /* KEY_MUTE repeats from knob need to be suppressed */ | 1594 | /* KEY_MUTE repeats from knob need to be suppressed */ |
1586 | if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { | 1595 | if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { |
1587 | do_gettimeofday(&t); | ||
1588 | msec = tv2int(&t, &prev_time); | 1596 | msec = tv2int(&t, &prev_time); |
1589 | prev_time = t; | ||
1590 | if (msec < ictx->idev->rep[REP_DELAY]) { | 1597 | if (msec < ictx->idev->rep[REP_DELAY]) { |
1591 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1598 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
1592 | return; | 1599 | return; |
1593 | } | 1600 | } |
1594 | } | 1601 | } |
1602 | prev_time = t; | ||
1595 | kc = ictx->kc; | 1603 | kc = ictx->kc; |
1596 | 1604 | ||
1597 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1605 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
@@ -1603,7 +1611,9 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1603 | input_report_key(ictx->idev, kc, 0); | 1611 | input_report_key(ictx->idev, kc, 0); |
1604 | input_sync(ictx->idev); | 1612 | input_sync(ictx->idev); |
1605 | 1613 | ||
1614 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1606 | ictx->last_keycode = kc; | 1615 | ictx->last_keycode = kc; |
1616 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1607 | 1617 | ||
1608 | return; | 1618 | return; |
1609 | 1619 | ||
@@ -1740,6 +1750,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1740 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1750 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1741 | break; | 1751 | break; |
1742 | /* iMON VFD, MCE IR */ | 1752 | /* iMON VFD, MCE IR */ |
1753 | case 0x46: | ||
1754 | case 0x7e: | ||
1743 | case 0x9e: | 1755 | case 0x9e: |
1744 | dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); | 1756 | dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); |
1745 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1757 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
@@ -1755,6 +1767,9 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1755 | dev_info(ictx->dev, "Unknown 0xffdc device, " | 1767 | dev_info(ictx->dev, "Unknown 0xffdc device, " |
1756 | "defaulting to VFD and iMON IR"); | 1768 | "defaulting to VFD and iMON IR"); |
1757 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1769 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1770 | /* We don't know which one it is, allow user to set the | ||
1771 | * RC6 one from userspace if OTHER wasn't correct. */ | ||
1772 | allowed_protos |= RC_TYPE_RC6; | ||
1758 | break; | 1773 | break; |
1759 | } | 1774 | } |
1760 | 1775 | ||
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 11c19d8d0ee0..423ed45d6c55 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c | |||
@@ -114,18 +114,20 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) | |||
114 | s64 delta; /* ns */ | 114 | s64 delta; /* ns */ |
115 | DEFINE_IR_RAW_EVENT(ev); | 115 | DEFINE_IR_RAW_EVENT(ev); |
116 | int rc = 0; | 116 | int rc = 0; |
117 | int delay; | ||
117 | 118 | ||
118 | if (!dev->raw) | 119 | if (!dev->raw) |
119 | return -EINVAL; | 120 | return -EINVAL; |
120 | 121 | ||
121 | now = ktime_get(); | 122 | now = ktime_get(); |
122 | delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); | 123 | delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); |
124 | delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); | ||
123 | 125 | ||
124 | /* Check for a long duration since last event or if we're | 126 | /* Check for a long duration since last event or if we're |
125 | * being called for the first time, note that delta can't | 127 | * being called for the first time, note that delta can't |
126 | * possibly be negative. | 128 | * possibly be negative. |
127 | */ | 129 | */ |
128 | if (delta > IR_MAX_DURATION || !dev->raw->last_type) | 130 | if (delta > delay || !dev->raw->last_type) |
129 | type |= IR_START_EVENT; | 131 | type |= IR_START_EVENT; |
130 | else | 132 | else |
131 | ev.duration = delta; | 133 | ev.duration = delta; |
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index e716b931cf7e..ecd3d0280768 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c | |||
@@ -1347,6 +1347,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1347 | { /* 0: ITE8704 */ | 1347 | { /* 0: ITE8704 */ |
1348 | .model = "ITE8704 CIR transceiver", | 1348 | .model = "ITE8704 CIR transceiver", |
1349 | .io_region_size = IT87_IOREG_LENGTH, | 1349 | .io_region_size = IT87_IOREG_LENGTH, |
1350 | .io_rsrc_no = 0, | ||
1350 | .hw_tx_capable = true, | 1351 | .hw_tx_capable = true, |
1351 | .sample_period = (u32) (1000000000ULL / 115200), | 1352 | .sample_period = (u32) (1000000000ULL / 115200), |
1352 | .tx_carrier_freq = 38000, | 1353 | .tx_carrier_freq = 38000, |
@@ -1371,6 +1372,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1371 | { /* 1: ITE8713 */ | 1372 | { /* 1: ITE8713 */ |
1372 | .model = "ITE8713 CIR transceiver", | 1373 | .model = "ITE8713 CIR transceiver", |
1373 | .io_region_size = IT87_IOREG_LENGTH, | 1374 | .io_region_size = IT87_IOREG_LENGTH, |
1375 | .io_rsrc_no = 0, | ||
1374 | .hw_tx_capable = true, | 1376 | .hw_tx_capable = true, |
1375 | .sample_period = (u32) (1000000000ULL / 115200), | 1377 | .sample_period = (u32) (1000000000ULL / 115200), |
1376 | .tx_carrier_freq = 38000, | 1378 | .tx_carrier_freq = 38000, |
@@ -1395,6 +1397,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1395 | { /* 2: ITE8708 */ | 1397 | { /* 2: ITE8708 */ |
1396 | .model = "ITE8708 CIR transceiver", | 1398 | .model = "ITE8708 CIR transceiver", |
1397 | .io_region_size = IT8708_IOREG_LENGTH, | 1399 | .io_region_size = IT8708_IOREG_LENGTH, |
1400 | .io_rsrc_no = 0, | ||
1398 | .hw_tx_capable = true, | 1401 | .hw_tx_capable = true, |
1399 | .sample_period = (u32) (1000000000ULL / 115200), | 1402 | .sample_period = (u32) (1000000000ULL / 115200), |
1400 | .tx_carrier_freq = 38000, | 1403 | .tx_carrier_freq = 38000, |
@@ -1420,6 +1423,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1420 | { /* 3: ITE8709 */ | 1423 | { /* 3: ITE8709 */ |
1421 | .model = "ITE8709 CIR transceiver", | 1424 | .model = "ITE8709 CIR transceiver", |
1422 | .io_region_size = IT8709_IOREG_LENGTH, | 1425 | .io_region_size = IT8709_IOREG_LENGTH, |
1426 | .io_rsrc_no = 2, | ||
1423 | .hw_tx_capable = true, | 1427 | .hw_tx_capable = true, |
1424 | .sample_period = (u32) (1000000000ULL / 115200), | 1428 | .sample_period = (u32) (1000000000ULL / 115200), |
1425 | .tx_carrier_freq = 38000, | 1429 | .tx_carrier_freq = 38000, |
@@ -1461,6 +1465,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1461 | struct rc_dev *rdev = NULL; | 1465 | struct rc_dev *rdev = NULL; |
1462 | int ret = -ENOMEM; | 1466 | int ret = -ENOMEM; |
1463 | int model_no; | 1467 | int model_no; |
1468 | int io_rsrc_no; | ||
1464 | 1469 | ||
1465 | ite_dbg("%s called", __func__); | 1470 | ite_dbg("%s called", __func__); |
1466 | 1471 | ||
@@ -1490,10 +1495,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1490 | 1495 | ||
1491 | /* get the description for the device */ | 1496 | /* get the description for the device */ |
1492 | dev_desc = &ite_dev_descs[model_no]; | 1497 | dev_desc = &ite_dev_descs[model_no]; |
1498 | io_rsrc_no = dev_desc->io_rsrc_no; | ||
1493 | 1499 | ||
1494 | /* validate pnp resources */ | 1500 | /* validate pnp resources */ |
1495 | if (!pnp_port_valid(pdev, 0) || | 1501 | if (!pnp_port_valid(pdev, io_rsrc_no) || |
1496 | pnp_port_len(pdev, 0) != dev_desc->io_region_size) { | 1502 | pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) { |
1497 | dev_err(&pdev->dev, "IR PNP Port not valid!\n"); | 1503 | dev_err(&pdev->dev, "IR PNP Port not valid!\n"); |
1498 | goto failure; | 1504 | goto failure; |
1499 | } | 1505 | } |
@@ -1504,7 +1510,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1504 | } | 1510 | } |
1505 | 1511 | ||
1506 | /* store resource values */ | 1512 | /* store resource values */ |
1507 | itdev->cir_addr = pnp_port_start(pdev, 0); | 1513 | itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no); |
1508 | itdev->cir_irq = pnp_irq(pdev, 0); | 1514 | itdev->cir_irq = pnp_irq(pdev, 0); |
1509 | 1515 | ||
1510 | /* initialize spinlocks */ | 1516 | /* initialize spinlocks */ |
diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h index 16a19f5fd718..aa899a0b9750 100644 --- a/drivers/media/rc/ite-cir.h +++ b/drivers/media/rc/ite-cir.h | |||
@@ -57,6 +57,9 @@ struct ite_dev_params { | |||
57 | /* size of the I/O region */ | 57 | /* size of the I/O region */ |
58 | int io_region_size; | 58 | int io_region_size; |
59 | 59 | ||
60 | /* IR pnp I/O resource number */ | ||
61 | int io_rsrc_no; | ||
62 | |||
60 | /* true if the hardware supports transmission */ | 63 | /* true if the hardware supports transmission */ |
61 | bool hw_tx_capable; | 64 | bool hw_tx_capable; |
62 | 65 | ||
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index bb10ffe086b4..8d558ae63456 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | |||
@@ -15,43 +15,39 @@ | |||
15 | /* Pinnacle PCTV HD 800i mini remote */ | 15 | /* Pinnacle PCTV HD 800i mini remote */ |
16 | 16 | ||
17 | static struct rc_map_table pinnacle_pctv_hd[] = { | 17 | static struct rc_map_table pinnacle_pctv_hd[] = { |
18 | 18 | /* Key codes for the tiny Pinnacle remote*/ | |
19 | { 0x0f, KEY_1 }, | 19 | { 0x0700, KEY_MUTE }, |
20 | { 0x15, KEY_2 }, | 20 | { 0x0701, KEY_MENU }, /* Pinnacle logo */ |
21 | { 0x10, KEY_3 }, | 21 | { 0x0739, KEY_POWER }, |
22 | { 0x18, KEY_4 }, | 22 | { 0x0703, KEY_VOLUMEUP }, |
23 | { 0x1b, KEY_5 }, | 23 | { 0x0709, KEY_VOLUMEDOWN }, |
24 | { 0x1e, KEY_6 }, | 24 | { 0x0706, KEY_CHANNELUP }, |
25 | { 0x11, KEY_7 }, | 25 | { 0x070c, KEY_CHANNELDOWN }, |
26 | { 0x21, KEY_8 }, | 26 | { 0x070f, KEY_1 }, |
27 | { 0x12, KEY_9 }, | 27 | { 0x0715, KEY_2 }, |
28 | { 0x27, KEY_0 }, | 28 | { 0x0710, KEY_3 }, |
29 | 29 | { 0x0718, KEY_4 }, | |
30 | { 0x24, KEY_ZOOM }, | 30 | { 0x071b, KEY_5 }, |
31 | { 0x2a, KEY_SUBTITLE }, | 31 | { 0x071e, KEY_6 }, |
32 | 32 | { 0x0711, KEY_7 }, | |
33 | { 0x00, KEY_MUTE }, | 33 | { 0x0721, KEY_8 }, |
34 | { 0x01, KEY_ENTER }, /* Pinnacle Logo */ | 34 | { 0x0712, KEY_9 }, |
35 | { 0x39, KEY_POWER }, | 35 | { 0x0727, KEY_0 }, |
36 | 36 | { 0x0724, KEY_ZOOM }, /* 'Square' key */ | |
37 | { 0x03, KEY_VOLUMEUP }, | 37 | { 0x072a, KEY_SUBTITLE }, /* 'T' key */ |
38 | { 0x09, KEY_VOLUMEDOWN }, | 38 | { 0x072d, KEY_REWIND }, |
39 | { 0x06, KEY_CHANNELUP }, | 39 | { 0x0730, KEY_PLAYPAUSE }, |
40 | { 0x0c, KEY_CHANNELDOWN }, | 40 | { 0x0733, KEY_FASTFORWARD }, |
41 | 41 | { 0x0736, KEY_RECORD }, | |
42 | { 0x2d, KEY_REWIND }, | 42 | { 0x073c, KEY_STOP }, |
43 | { 0x30, KEY_PLAYPAUSE }, | 43 | { 0x073f, KEY_HELP }, /* '?' key */ |
44 | { 0x33, KEY_FASTFORWARD }, | ||
45 | { 0x3c, KEY_STOP }, | ||
46 | { 0x36, KEY_RECORD }, | ||
47 | { 0x3f, KEY_EPG }, /* Labeled "?" */ | ||
48 | }; | 44 | }; |
49 | 45 | ||
50 | static struct rc_map_list pinnacle_pctv_hd_map = { | 46 | static struct rc_map_list pinnacle_pctv_hd_map = { |
51 | .map = { | 47 | .map = { |
52 | .scan = pinnacle_pctv_hd, | 48 | .scan = pinnacle_pctv_hd, |
53 | .size = ARRAY_SIZE(pinnacle_pctv_hd), | 49 | .size = ARRAY_SIZE(pinnacle_pctv_hd), |
54 | .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ | 50 | .rc_type = RC_TYPE_RC5, |
55 | .name = RC_MAP_PINNACLE_PCTV_HD, | 51 | .name = RC_MAP_PINNACLE_PCTV_HD, |
56 | } | 52 | } |
57 | }; | 53 | }; |
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index fd237ab120bb..27997a9ceb0d 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c | |||
@@ -55,6 +55,8 @@ struct irctl { | |||
55 | struct lirc_buffer *buf; | 55 | struct lirc_buffer *buf; |
56 | unsigned int chunk_size; | 56 | unsigned int chunk_size; |
57 | 57 | ||
58 | struct cdev *cdev; | ||
59 | |||
58 | struct task_struct *task; | 60 | struct task_struct *task; |
59 | long jiffies_to_wait; | 61 | long jiffies_to_wait; |
60 | }; | 62 | }; |
@@ -62,7 +64,6 @@ struct irctl { | |||
62 | static DEFINE_MUTEX(lirc_dev_lock); | 64 | static DEFINE_MUTEX(lirc_dev_lock); |
63 | 65 | ||
64 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; | 66 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; |
65 | static struct cdev cdevs[MAX_IRCTL_DEVICES]; | ||
66 | 67 | ||
67 | /* Only used for sysfs but defined to void otherwise */ | 68 | /* Only used for sysfs but defined to void otherwise */ |
68 | static struct class *lirc_class; | 69 | static struct class *lirc_class; |
@@ -167,9 +168,13 @@ static struct file_operations lirc_dev_fops = { | |||
167 | 168 | ||
168 | static int lirc_cdev_add(struct irctl *ir) | 169 | static int lirc_cdev_add(struct irctl *ir) |
169 | { | 170 | { |
170 | int retval; | 171 | int retval = -ENOMEM; |
171 | struct lirc_driver *d = &ir->d; | 172 | struct lirc_driver *d = &ir->d; |
172 | struct cdev *cdev = &cdevs[d->minor]; | 173 | struct cdev *cdev; |
174 | |||
175 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); | ||
176 | if (!cdev) | ||
177 | goto err_out; | ||
173 | 178 | ||
174 | if (d->fops) { | 179 | if (d->fops) { |
175 | cdev_init(cdev, d->fops); | 180 | cdev_init(cdev, d->fops); |
@@ -180,12 +185,20 @@ static int lirc_cdev_add(struct irctl *ir) | |||
180 | } | 185 | } |
181 | retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); | 186 | retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); |
182 | if (retval) | 187 | if (retval) |
183 | return retval; | 188 | goto err_out; |
184 | 189 | ||
185 | retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); | 190 | retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); |
186 | if (retval) | 191 | if (retval) { |
187 | kobject_put(&cdev->kobj); | 192 | kobject_put(&cdev->kobj); |
193 | goto err_out; | ||
194 | } | ||
195 | |||
196 | ir->cdev = cdev; | ||
197 | |||
198 | return 0; | ||
188 | 199 | ||
200 | err_out: | ||
201 | kfree(cdev); | ||
189 | return retval; | 202 | return retval; |
190 | } | 203 | } |
191 | 204 | ||
@@ -214,7 +227,7 @@ int lirc_register_driver(struct lirc_driver *d) | |||
214 | if (MAX_IRCTL_DEVICES <= d->minor) { | 227 | if (MAX_IRCTL_DEVICES <= d->minor) { |
215 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " | 228 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " |
216 | "\"minor\" must be between 0 and %d (%d)!\n", | 229 | "\"minor\" must be between 0 and %d (%d)!\n", |
217 | MAX_IRCTL_DEVICES-1, d->minor); | 230 | MAX_IRCTL_DEVICES - 1, d->minor); |
218 | err = -EBADRQC; | 231 | err = -EBADRQC; |
219 | goto out; | 232 | goto out; |
220 | } | 233 | } |
@@ -369,7 +382,7 @@ int lirc_unregister_driver(int minor) | |||
369 | 382 | ||
370 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { | 383 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { |
371 | printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " | 384 | printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " |
372 | "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1); | 385 | "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES - 1); |
373 | return -EBADRQC; | 386 | return -EBADRQC; |
374 | } | 387 | } |
375 | 388 | ||
@@ -380,7 +393,7 @@ int lirc_unregister_driver(int minor) | |||
380 | return -ENOENT; | 393 | return -ENOENT; |
381 | } | 394 | } |
382 | 395 | ||
383 | cdev = &cdevs[minor]; | 396 | cdev = ir->cdev; |
384 | 397 | ||
385 | mutex_lock(&lirc_dev_lock); | 398 | mutex_lock(&lirc_dev_lock); |
386 | 399 | ||
@@ -410,6 +423,7 @@ int lirc_unregister_driver(int minor) | |||
410 | } else { | 423 | } else { |
411 | lirc_irctl_cleanup(ir); | 424 | lirc_irctl_cleanup(ir); |
412 | cdev_del(cdev); | 425 | cdev_del(cdev); |
426 | kfree(cdev); | ||
413 | kfree(ir); | 427 | kfree(ir); |
414 | irctls[minor] = NULL; | 428 | irctls[minor] = NULL; |
415 | } | 429 | } |
@@ -453,7 +467,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) | |||
453 | goto error; | 467 | goto error; |
454 | } | 468 | } |
455 | 469 | ||
456 | cdev = &cdevs[iminor(inode)]; | 470 | cdev = ir->cdev; |
457 | if (try_module_get(cdev->owner)) { | 471 | if (try_module_get(cdev->owner)) { |
458 | ir->open++; | 472 | ir->open++; |
459 | retval = ir->d.set_use_inc(ir->d.data); | 473 | retval = ir->d.set_use_inc(ir->d.data); |
@@ -484,13 +498,15 @@ EXPORT_SYMBOL(lirc_dev_fop_open); | |||
484 | int lirc_dev_fop_close(struct inode *inode, struct file *file) | 498 | int lirc_dev_fop_close(struct inode *inode, struct file *file) |
485 | { | 499 | { |
486 | struct irctl *ir = irctls[iminor(inode)]; | 500 | struct irctl *ir = irctls[iminor(inode)]; |
487 | struct cdev *cdev = &cdevs[iminor(inode)]; | 501 | struct cdev *cdev; |
488 | 502 | ||
489 | if (!ir) { | 503 | if (!ir) { |
490 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | 504 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); |
491 | return -EINVAL; | 505 | return -EINVAL; |
492 | } | 506 | } |
493 | 507 | ||
508 | cdev = ir->cdev; | ||
509 | |||
494 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); | 510 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); |
495 | 511 | ||
496 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); | 512 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); |
@@ -503,6 +519,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) | |||
503 | lirc_irctl_cleanup(ir); | 519 | lirc_irctl_cleanup(ir); |
504 | cdev_del(cdev); | 520 | cdev_del(cdev); |
505 | irctls[ir->d.minor] = NULL; | 521 | irctls[ir->d.minor] = NULL; |
522 | kfree(cdev); | ||
506 | kfree(ir); | 523 | kfree(ir); |
507 | } | 524 | } |
508 | 525 | ||
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index ad927fcaa020..06dfe0957b5e 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c | |||
@@ -108,6 +108,12 @@ static int debug = 1; | |||
108 | static int debug; | 108 | static int debug; |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #define mce_dbg(dev, fmt, ...) \ | ||
112 | do { \ | ||
113 | if (debug) \ | ||
114 | dev_info(dev, fmt, ## __VA_ARGS__); \ | ||
115 | } while (0) | ||
116 | |||
111 | /* general constants */ | 117 | /* general constants */ |
112 | #define SEND_FLAG_IN_PROGRESS 1 | 118 | #define SEND_FLAG_IN_PROGRESS 1 |
113 | #define SEND_FLAG_COMPLETE 2 | 119 | #define SEND_FLAG_COMPLETE 2 |
@@ -246,6 +252,9 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
246 | .driver_info = MCE_GEN2_TX_INV }, | 252 | .driver_info = MCE_GEN2_TX_INV }, |
247 | /* SMK eHome Infrared Transceiver */ | 253 | /* SMK eHome Infrared Transceiver */ |
248 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, | 254 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, |
255 | /* SMK/I-O Data GV-MC7/RCKIT Receiver */ | ||
256 | { USB_DEVICE(VENDOR_SMK, 0x0353), | ||
257 | .driver_info = MCE_GEN2_NO_TX }, | ||
249 | /* Tatung eHome Infrared Transceiver */ | 258 | /* Tatung eHome Infrared Transceiver */ |
250 | { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, | 259 | { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, |
251 | /* Shuttle eHome Infrared Transceiver */ | 260 | /* Shuttle eHome Infrared Transceiver */ |
@@ -606,12 +615,15 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | |||
606 | if (ir) { | 615 | if (ir) { |
607 | len = urb->actual_length; | 616 | len = urb->actual_length; |
608 | 617 | ||
609 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", | 618 | mce_dbg(ir->dev, "callback called (status=%d len=%d)\n", |
610 | urb->status, len); | 619 | urb->status, len); |
611 | 620 | ||
612 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); | 621 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); |
613 | } | 622 | } |
614 | 623 | ||
624 | /* the transfer buffer and urb were allocated in mce_request_packet */ | ||
625 | kfree(urb->transfer_buffer); | ||
626 | usb_free_urb(urb); | ||
615 | } | 627 | } |
616 | 628 | ||
617 | /* request incoming or send outgoing usb packet - used to initialize remote */ | 629 | /* request incoming or send outgoing usb packet - used to initialize remote */ |
@@ -655,17 +667,17 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, | |||
655 | return; | 667 | return; |
656 | } | 668 | } |
657 | 669 | ||
658 | dev_dbg(dev, "receive request called (size=%#x)\n", size); | 670 | mce_dbg(dev, "receive request called (size=%#x)\n", size); |
659 | 671 | ||
660 | async_urb->transfer_buffer_length = size; | 672 | async_urb->transfer_buffer_length = size; |
661 | async_urb->dev = ir->usbdev; | 673 | async_urb->dev = ir->usbdev; |
662 | 674 | ||
663 | res = usb_submit_urb(async_urb, GFP_ATOMIC); | 675 | res = usb_submit_urb(async_urb, GFP_ATOMIC); |
664 | if (res) { | 676 | if (res) { |
665 | dev_dbg(dev, "receive request FAILED! (res=%d)\n", res); | 677 | mce_dbg(dev, "receive request FAILED! (res=%d)\n", res); |
666 | return; | 678 | return; |
667 | } | 679 | } |
668 | dev_dbg(dev, "receive request complete (res=%d)\n", res); | 680 | mce_dbg(dev, "receive request complete (res=%d)\n", res); |
669 | } | 681 | } |
670 | 682 | ||
671 | static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) | 683 | static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) |
@@ -673,9 +685,9 @@ static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) | |||
673 | mce_request_packet(ir, data, size, MCEUSB_TX); | 685 | mce_request_packet(ir, data, size, MCEUSB_TX); |
674 | } | 686 | } |
675 | 687 | ||
676 | static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) | 688 | static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size) |
677 | { | 689 | { |
678 | mce_request_packet(ir, data, size, MCEUSB_RX); | 690 | mce_request_packet(ir, NULL, size, MCEUSB_RX); |
679 | } | 691 | } |
680 | 692 | ||
681 | /* Send data out the IR blaster port(s) */ | 693 | /* Send data out the IR blaster port(s) */ |
@@ -794,7 +806,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
794 | ir->carrier = carrier; | 806 | ir->carrier = carrier; |
795 | cmdbuf[2] = MCE_CMD_SIG_END; | 807 | cmdbuf[2] = MCE_CMD_SIG_END; |
796 | cmdbuf[3] = MCE_IRDATA_TRAILER; | 808 | cmdbuf[3] = MCE_IRDATA_TRAILER; |
797 | dev_dbg(ir->dev, "%s: disabling carrier " | 809 | mce_dbg(ir->dev, "%s: disabling carrier " |
798 | "modulation\n", __func__); | 810 | "modulation\n", __func__); |
799 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | 811 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); |
800 | return carrier; | 812 | return carrier; |
@@ -806,7 +818,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
806 | ir->carrier = carrier; | 818 | ir->carrier = carrier; |
807 | cmdbuf[2] = prescaler; | 819 | cmdbuf[2] = prescaler; |
808 | cmdbuf[3] = divisor; | 820 | cmdbuf[3] = divisor; |
809 | dev_dbg(ir->dev, "%s: requesting %u HZ " | 821 | mce_dbg(ir->dev, "%s: requesting %u HZ " |
810 | "carrier\n", __func__, carrier); | 822 | "carrier\n", __func__, carrier); |
811 | 823 | ||
812 | /* Transmit new carrier to mce device */ | 824 | /* Transmit new carrier to mce device */ |
@@ -879,7 +891,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
879 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 891 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) |
880 | * US_TO_NS(MCE_TIME_UNIT); | 892 | * US_TO_NS(MCE_TIME_UNIT); |
881 | 893 | ||
882 | dev_dbg(ir->dev, "Storing %s with duration %d\n", | 894 | mce_dbg(ir->dev, "Storing %s with duration %d\n", |
883 | rawir.pulse ? "pulse" : "space", | 895 | rawir.pulse ? "pulse" : "space", |
884 | rawir.duration); | 896 | rawir.duration); |
885 | 897 | ||
@@ -911,7 +923,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
911 | if (ir->parser_state != CMD_HEADER && !ir->rem) | 923 | if (ir->parser_state != CMD_HEADER && !ir->rem) |
912 | ir->parser_state = CMD_HEADER; | 924 | ir->parser_state = CMD_HEADER; |
913 | } | 925 | } |
914 | dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); | 926 | mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); |
915 | ir_raw_event_handle(ir->rc); | 927 | ir_raw_event_handle(ir->rc); |
916 | } | 928 | } |
917 | 929 | ||
@@ -933,7 +945,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
933 | 945 | ||
934 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | 946 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { |
935 | ir->send_flags = SEND_FLAG_COMPLETE; | 947 | ir->send_flags = SEND_FLAG_COMPLETE; |
936 | dev_dbg(ir->dev, "setup answer received %d bytes\n", | 948 | mce_dbg(ir->dev, "setup answer received %d bytes\n", |
937 | buf_len); | 949 | buf_len); |
938 | } | 950 | } |
939 | 951 | ||
@@ -951,7 +963,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
951 | 963 | ||
952 | case -EPIPE: | 964 | case -EPIPE: |
953 | default: | 965 | default: |
954 | dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status); | 966 | mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status); |
955 | break; | 967 | break; |
956 | } | 968 | } |
957 | 969 | ||
@@ -961,7 +973,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
961 | static void mceusb_gen1_init(struct mceusb_dev *ir) | 973 | static void mceusb_gen1_init(struct mceusb_dev *ir) |
962 | { | 974 | { |
963 | int ret; | 975 | int ret; |
964 | int maxp = ir->len_in; | ||
965 | struct device *dev = ir->dev; | 976 | struct device *dev = ir->dev; |
966 | char *data; | 977 | char *data; |
967 | 978 | ||
@@ -978,8 +989,8 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) | |||
978 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | 989 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
979 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, | 990 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, |
980 | data, USB_CTRL_MSG_SZ, HZ * 3); | 991 | data, USB_CTRL_MSG_SZ, HZ * 3); |
981 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | 992 | mce_dbg(dev, "%s - ret = %d\n", __func__, ret); |
982 | dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", | 993 | mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", |
983 | __func__, data[0], data[1]); | 994 | __func__, data[0], data[1]); |
984 | 995 | ||
985 | /* set feature: bit rate 38400 bps */ | 996 | /* set feature: bit rate 38400 bps */ |
@@ -987,71 +998,56 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) | |||
987 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, | 998 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
988 | 0xc04e, 0x0000, NULL, 0, HZ * 3); | 999 | 0xc04e, 0x0000, NULL, 0, HZ * 3); |
989 | 1000 | ||
990 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | 1001 | mce_dbg(dev, "%s - ret = %d\n", __func__, ret); |
991 | 1002 | ||
992 | /* bRequest 4: set char length to 8 bits */ | 1003 | /* bRequest 4: set char length to 8 bits */ |
993 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1004 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
994 | 4, USB_TYPE_VENDOR, | 1005 | 4, USB_TYPE_VENDOR, |
995 | 0x0808, 0x0000, NULL, 0, HZ * 3); | 1006 | 0x0808, 0x0000, NULL, 0, HZ * 3); |
996 | dev_dbg(dev, "%s - retB = %d\n", __func__, ret); | 1007 | mce_dbg(dev, "%s - retB = %d\n", __func__, ret); |
997 | 1008 | ||
998 | /* bRequest 2: set handshaking to use DTR/DSR */ | 1009 | /* bRequest 2: set handshaking to use DTR/DSR */ |
999 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1010 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
1000 | 2, USB_TYPE_VENDOR, | 1011 | 2, USB_TYPE_VENDOR, |
1001 | 0x0000, 0x0100, NULL, 0, HZ * 3); | 1012 | 0x0000, 0x0100, NULL, 0, HZ * 3); |
1002 | dev_dbg(dev, "%s - retC = %d\n", __func__, ret); | 1013 | mce_dbg(dev, "%s - retC = %d\n", __func__, ret); |
1003 | 1014 | ||
1004 | /* device reset */ | 1015 | /* device reset */ |
1005 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | 1016 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); |
1006 | mce_sync_in(ir, NULL, maxp); | ||
1007 | 1017 | ||
1008 | /* get hw/sw revision? */ | 1018 | /* get hw/sw revision? */ |
1009 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); | 1019 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
1010 | mce_sync_in(ir, NULL, maxp); | ||
1011 | 1020 | ||
1012 | kfree(data); | 1021 | kfree(data); |
1013 | }; | 1022 | }; |
1014 | 1023 | ||
1015 | static void mceusb_gen2_init(struct mceusb_dev *ir) | 1024 | static void mceusb_gen2_init(struct mceusb_dev *ir) |
1016 | { | 1025 | { |
1017 | int maxp = ir->len_in; | ||
1018 | |||
1019 | /* device reset */ | 1026 | /* device reset */ |
1020 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | 1027 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); |
1021 | mce_sync_in(ir, NULL, maxp); | ||
1022 | 1028 | ||
1023 | /* get hw/sw revision? */ | 1029 | /* get hw/sw revision? */ |
1024 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); | 1030 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
1025 | mce_sync_in(ir, NULL, maxp); | ||
1026 | 1031 | ||
1027 | /* unknown what the next two actually return... */ | 1032 | /* unknown what the next two actually return... */ |
1028 | mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); | 1033 | mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); |
1029 | mce_sync_in(ir, NULL, maxp); | ||
1030 | mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); | 1034 | mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); |
1031 | mce_sync_in(ir, NULL, maxp); | ||
1032 | } | 1035 | } |
1033 | 1036 | ||
1034 | static void mceusb_get_parameters(struct mceusb_dev *ir) | 1037 | static void mceusb_get_parameters(struct mceusb_dev *ir) |
1035 | { | 1038 | { |
1036 | int maxp = ir->len_in; | ||
1037 | |||
1038 | /* get the carrier and frequency */ | 1039 | /* get the carrier and frequency */ |
1039 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); | 1040 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); |
1040 | mce_sync_in(ir, NULL, maxp); | ||
1041 | 1041 | ||
1042 | if (!ir->flags.no_tx) { | 1042 | if (!ir->flags.no_tx) |
1043 | /* get the transmitter bitmask */ | 1043 | /* get the transmitter bitmask */ |
1044 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); | 1044 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); |
1045 | mce_sync_in(ir, NULL, maxp); | ||
1046 | } | ||
1047 | 1045 | ||
1048 | /* get receiver timeout value */ | 1046 | /* get receiver timeout value */ |
1049 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); | 1047 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); |
1050 | mce_sync_in(ir, NULL, maxp); | ||
1051 | 1048 | ||
1052 | /* get receiver sensor setting */ | 1049 | /* get receiver sensor setting */ |
1053 | mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); | 1050 | mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); |
1054 | mce_sync_in(ir, NULL, maxp); | ||
1055 | } | 1051 | } |
1056 | 1052 | ||
1057 | static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) | 1053 | static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) |
@@ -1122,7 +1118,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1122 | bool tx_mask_normal; | 1118 | bool tx_mask_normal; |
1123 | int ir_intfnum; | 1119 | int ir_intfnum; |
1124 | 1120 | ||
1125 | dev_dbg(&intf->dev, "%s called\n", __func__); | 1121 | mce_dbg(&intf->dev, "%s called\n", __func__); |
1126 | 1122 | ||
1127 | idesc = intf->cur_altsetting; | 1123 | idesc = intf->cur_altsetting; |
1128 | 1124 | ||
@@ -1150,7 +1146,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1150 | ep_in = ep; | 1146 | ep_in = ep; |
1151 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | 1147 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; |
1152 | ep_in->bInterval = 1; | 1148 | ep_in->bInterval = 1; |
1153 | dev_dbg(&intf->dev, "acceptable inbound endpoint " | 1149 | mce_dbg(&intf->dev, "acceptable inbound endpoint " |
1154 | "found\n"); | 1150 | "found\n"); |
1155 | } | 1151 | } |
1156 | 1152 | ||
@@ -1165,12 +1161,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1165 | ep_out = ep; | 1161 | ep_out = ep; |
1166 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | 1162 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; |
1167 | ep_out->bInterval = 1; | 1163 | ep_out->bInterval = 1; |
1168 | dev_dbg(&intf->dev, "acceptable outbound endpoint " | 1164 | mce_dbg(&intf->dev, "acceptable outbound endpoint " |
1169 | "found\n"); | 1165 | "found\n"); |
1170 | } | 1166 | } |
1171 | } | 1167 | } |
1172 | if (ep_in == NULL) { | 1168 | if (ep_in == NULL) { |
1173 | dev_dbg(&intf->dev, "inbound and/or endpoint not found\n"); | 1169 | mce_dbg(&intf->dev, "inbound and/or endpoint not found\n"); |
1174 | return -ENODEV; | 1170 | return -ENODEV; |
1175 | } | 1171 | } |
1176 | 1172 | ||
@@ -1215,16 +1211,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1215 | if (!ir->rc) | 1211 | if (!ir->rc) |
1216 | goto rc_dev_fail; | 1212 | goto rc_dev_fail; |
1217 | 1213 | ||
1218 | /* flush buffers on the device */ | ||
1219 | mce_sync_in(ir, NULL, maxp); | ||
1220 | mce_sync_in(ir, NULL, maxp); | ||
1221 | |||
1222 | /* wire up inbound data handler */ | 1214 | /* wire up inbound data handler */ |
1223 | usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, | 1215 | usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, |
1224 | maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); | 1216 | maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); |
1225 | ir->urb_in->transfer_dma = ir->dma_in; | 1217 | ir->urb_in->transfer_dma = ir->dma_in; |
1226 | ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1218 | ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1227 | 1219 | ||
1220 | /* flush buffers on the device */ | ||
1221 | mce_dbg(&intf->dev, "Flushing receive buffers\n"); | ||
1222 | mce_flush_rx_buffer(ir, maxp); | ||
1223 | |||
1228 | /* initialize device */ | 1224 | /* initialize device */ |
1229 | if (ir->flags.microsoft_gen1) | 1225 | if (ir->flags.microsoft_gen1) |
1230 | mceusb_gen1_init(ir); | 1226 | mceusb_gen1_init(ir); |
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index bf3060ea6107..565f24c20d77 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c | |||
@@ -991,7 +991,6 @@ static int nvt_open(struct rc_dev *dev) | |||
991 | unsigned long flags; | 991 | unsigned long flags; |
992 | 992 | ||
993 | spin_lock_irqsave(&nvt->nvt_lock, flags); | 993 | spin_lock_irqsave(&nvt->nvt_lock, flags); |
994 | nvt->in_use = true; | ||
995 | nvt_enable_cir(nvt); | 994 | nvt_enable_cir(nvt); |
996 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | 995 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); |
997 | 996 | ||
@@ -1004,7 +1003,6 @@ static void nvt_close(struct rc_dev *dev) | |||
1004 | unsigned long flags; | 1003 | unsigned long flags; |
1005 | 1004 | ||
1006 | spin_lock_irqsave(&nvt->nvt_lock, flags); | 1005 | spin_lock_irqsave(&nvt->nvt_lock, flags); |
1007 | nvt->in_use = false; | ||
1008 | nvt_disable_cir(nvt); | 1006 | nvt_disable_cir(nvt); |
1009 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | 1007 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); |
1010 | } | 1008 | } |
diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 379795d61ea7..1241fc89a36c 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h | |||
@@ -70,7 +70,6 @@ struct nvt_dev { | |||
70 | struct ir_raw_event rawir; | 70 | struct ir_raw_event rawir; |
71 | 71 | ||
72 | spinlock_t nvt_lock; | 72 | spinlock_t nvt_lock; |
73 | bool in_use; | ||
74 | 73 | ||
75 | /* for rx */ | 74 | /* for rx */ |
76 | u8 buf[RX_BUF_LEN]; | 75 | u8 buf[RX_BUF_LEN]; |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f57cd5677ac2..3186ac7c2c10 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -522,18 +522,20 @@ EXPORT_SYMBOL_GPL(rc_g_keycode_from_table); | |||
522 | /** | 522 | /** |
523 | * ir_do_keyup() - internal function to signal the release of a keypress | 523 | * ir_do_keyup() - internal function to signal the release of a keypress |
524 | * @dev: the struct rc_dev descriptor of the device | 524 | * @dev: the struct rc_dev descriptor of the device |
525 | * @sync: whether or not to call input_sync | ||
525 | * | 526 | * |
526 | * This function is used internally to release a keypress, it must be | 527 | * This function is used internally to release a keypress, it must be |
527 | * called with keylock held. | 528 | * called with keylock held. |
528 | */ | 529 | */ |
529 | static void ir_do_keyup(struct rc_dev *dev) | 530 | static void ir_do_keyup(struct rc_dev *dev, bool sync) |
530 | { | 531 | { |
531 | if (!dev->keypressed) | 532 | if (!dev->keypressed) |
532 | return; | 533 | return; |
533 | 534 | ||
534 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); | 535 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); |
535 | input_report_key(dev->input_dev, dev->last_keycode, 0); | 536 | input_report_key(dev->input_dev, dev->last_keycode, 0); |
536 | input_sync(dev->input_dev); | 537 | if (sync) |
538 | input_sync(dev->input_dev); | ||
537 | dev->keypressed = false; | 539 | dev->keypressed = false; |
538 | } | 540 | } |
539 | 541 | ||
@@ -549,7 +551,7 @@ void rc_keyup(struct rc_dev *dev) | |||
549 | unsigned long flags; | 551 | unsigned long flags; |
550 | 552 | ||
551 | spin_lock_irqsave(&dev->keylock, flags); | 553 | spin_lock_irqsave(&dev->keylock, flags); |
552 | ir_do_keyup(dev); | 554 | ir_do_keyup(dev, true); |
553 | spin_unlock_irqrestore(&dev->keylock, flags); | 555 | spin_unlock_irqrestore(&dev->keylock, flags); |
554 | } | 556 | } |
555 | EXPORT_SYMBOL_GPL(rc_keyup); | 557 | EXPORT_SYMBOL_GPL(rc_keyup); |
@@ -578,7 +580,7 @@ static void ir_timer_keyup(unsigned long cookie) | |||
578 | */ | 580 | */ |
579 | spin_lock_irqsave(&dev->keylock, flags); | 581 | spin_lock_irqsave(&dev->keylock, flags); |
580 | if (time_is_before_eq_jiffies(dev->keyup_jiffies)) | 582 | if (time_is_before_eq_jiffies(dev->keyup_jiffies)) |
581 | ir_do_keyup(dev); | 583 | ir_do_keyup(dev, true); |
582 | spin_unlock_irqrestore(&dev->keylock, flags); | 584 | spin_unlock_irqrestore(&dev->keylock, flags); |
583 | } | 585 | } |
584 | 586 | ||
@@ -597,6 +599,7 @@ void rc_repeat(struct rc_dev *dev) | |||
597 | spin_lock_irqsave(&dev->keylock, flags); | 599 | spin_lock_irqsave(&dev->keylock, flags); |
598 | 600 | ||
599 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); | 601 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); |
602 | input_sync(dev->input_dev); | ||
600 | 603 | ||
601 | if (!dev->keypressed) | 604 | if (!dev->keypressed) |
602 | goto out; | 605 | goto out; |
@@ -622,29 +625,28 @@ EXPORT_SYMBOL_GPL(rc_repeat); | |||
622 | static void ir_do_keydown(struct rc_dev *dev, int scancode, | 625 | static void ir_do_keydown(struct rc_dev *dev, int scancode, |
623 | u32 keycode, u8 toggle) | 626 | u32 keycode, u8 toggle) |
624 | { | 627 | { |
625 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); | 628 | bool new_event = !dev->keypressed || |
626 | 629 | dev->last_scancode != scancode || | |
627 | /* Repeat event? */ | 630 | dev->last_toggle != toggle; |
628 | if (dev->keypressed && | ||
629 | dev->last_scancode == scancode && | ||
630 | dev->last_toggle == toggle) | ||
631 | return; | ||
632 | 631 | ||
633 | /* Release old keypress */ | 632 | if (new_event && dev->keypressed) |
634 | ir_do_keyup(dev); | 633 | ir_do_keyup(dev, false); |
635 | 634 | ||
636 | dev->last_scancode = scancode; | 635 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); |
637 | dev->last_toggle = toggle; | ||
638 | dev->last_keycode = keycode; | ||
639 | 636 | ||
640 | if (keycode == KEY_RESERVED) | 637 | if (new_event && keycode != KEY_RESERVED) { |
641 | return; | 638 | /* Register a keypress */ |
639 | dev->keypressed = true; | ||
640 | dev->last_scancode = scancode; | ||
641 | dev->last_toggle = toggle; | ||
642 | dev->last_keycode = keycode; | ||
643 | |||
644 | IR_dprintk(1, "%s: key down event, " | ||
645 | "key 0x%04x, scancode 0x%04x\n", | ||
646 | dev->input_name, keycode, scancode); | ||
647 | input_report_key(dev->input_dev, keycode, 1); | ||
648 | } | ||
642 | 649 | ||
643 | /* Register a keypress */ | ||
644 | dev->keypressed = true; | ||
645 | IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", | ||
646 | dev->input_name, keycode, scancode); | ||
647 | input_report_key(dev->input_dev, dev->last_keycode, 1); | ||
648 | input_sync(dev->input_dev); | 650 | input_sync(dev->input_dev); |
649 | } | 651 | } |
650 | 652 | ||
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a97cf2750bd9..834a48394bce 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
3474 | if (0 != t->index) | 3474 | if (0 != t->index) |
3475 | return -EINVAL; | 3475 | return -EINVAL; |
3476 | 3476 | ||
3477 | bttv_call_all(btv, tuner, g_tuner, t); | 3477 | bttv_call_all(btv, tuner, s_tuner, t); |
3478 | return 0; | 3478 | return 0; |
3479 | } | 3479 | } |
3480 | 3480 | ||
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 1933d4d11bf2..e80134f52ef5 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -695,14 +695,10 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
695 | 695 | ||
696 | cx18_call_all(cx, tuner, g_tuner, vt); | 696 | cx18_call_all(cx, tuner, g_tuner, vt); |
697 | 697 | ||
698 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 698 | if (vt->type == V4L2_TUNER_RADIO) |
699 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); | 699 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); |
700 | vt->type = V4L2_TUNER_RADIO; | 700 | else |
701 | } else { | ||
702 | strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); | 701 | strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); |
703 | vt->type = V4L2_TUNER_ANALOG_TV; | ||
704 | } | ||
705 | |||
706 | return 0; | 702 | return 0; |
707 | } | 703 | } |
708 | 704 | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f9e347dae739..120c7d8e0895 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -1184,14 +1184,10 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
1184 | 1184 | ||
1185 | ivtv_call_all(itv, tuner, g_tuner, vt); | 1185 | ivtv_call_all(itv, tuner, g_tuner, vt); |
1186 | 1186 | ||
1187 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | 1187 | if (vt->type == V4L2_TUNER_RADIO) |
1188 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); | 1188 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); |
1189 | vt->type = V4L2_TUNER_RADIO; | 1189 | else |
1190 | } else { | ||
1191 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); | 1190 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); |
1192 | vt->type = V4L2_TUNER_ANALOG_TV; | ||
1193 | } | ||
1194 | |||
1195 | return 0; | 1191 | return 0; |
1196 | } | 1192 | } |
1197 | 1193 | ||
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h index 10b55c854487..89d09a8914f8 100644 --- a/drivers/media/video/m5mols/m5mols.h +++ b/drivers/media/video/m5mols/m5mols.h | |||
@@ -2,10 +2,10 @@ | |||
2 | * Header for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Header for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -106,23 +106,23 @@ struct m5mols_capture { | |||
106 | * The each value according to each scenemode is recommended in the documents. | 106 | * The each value according to each scenemode is recommended in the documents. |
107 | */ | 107 | */ |
108 | struct m5mols_scenemode { | 108 | struct m5mols_scenemode { |
109 | u32 metering; | 109 | u8 metering; |
110 | u32 ev_bias; | 110 | u8 ev_bias; |
111 | u32 wb_mode; | 111 | u8 wb_mode; |
112 | u32 wb_preset; | 112 | u8 wb_preset; |
113 | u32 chroma_en; | 113 | u8 chroma_en; |
114 | u32 chroma_lvl; | 114 | u8 chroma_lvl; |
115 | u32 edge_en; | 115 | u8 edge_en; |
116 | u32 edge_lvl; | 116 | u8 edge_lvl; |
117 | u32 af_range; | 117 | u8 af_range; |
118 | u32 fd_mode; | 118 | u8 fd_mode; |
119 | u32 mcc; | 119 | u8 mcc; |
120 | u32 light; | 120 | u8 light; |
121 | u32 flash; | 121 | u8 flash; |
122 | u32 tone; | 122 | u8 tone; |
123 | u32 iso; | 123 | u8 iso; |
124 | u32 capt_mode; | 124 | u8 capt_mode; |
125 | u32 wdr; | 125 | u8 wdr; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | /** | 128 | /** |
@@ -154,7 +154,6 @@ struct m5mols_version { | |||
154 | u8 str[VERSION_STRING_SIZE]; | 154 | u8 str[VERSION_STRING_SIZE]; |
155 | u8 af; | 155 | u8 af; |
156 | }; | 156 | }; |
157 | #define VERSION_SIZE sizeof(struct m5mols_version) | ||
158 | 157 | ||
159 | /** | 158 | /** |
160 | * struct m5mols_info - M-5MOLS driver data structure | 159 | * struct m5mols_info - M-5MOLS driver data structure |
@@ -216,9 +215,9 @@ struct m5mols_info { | |||
216 | bool lock_ae; | 215 | bool lock_ae; |
217 | bool lock_awb; | 216 | bool lock_awb; |
218 | u8 resolution; | 217 | u8 resolution; |
219 | u32 interrupt; | 218 | u8 interrupt; |
220 | u32 mode; | 219 | u8 mode; |
221 | u32 mode_save; | 220 | u8 mode_save; |
222 | int (*set_power)(struct device *dev, int on); | 221 | int (*set_power)(struct device *dev, int on); |
223 | }; | 222 | }; |
224 | 223 | ||
@@ -256,9 +255,11 @@ struct m5mols_info { | |||
256 | * +-------+---+----------+-----+------+------+------+------+ | 255 | * +-------+---+----------+-----+------+------+------+------+ |
257 | * - d[0..3]: according to size1 | 256 | * - d[0..3]: according to size1 |
258 | */ | 257 | */ |
259 | int m5mols_read(struct v4l2_subdev *sd, u32 reg_comb, u32 *val); | 258 | int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val); |
259 | int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val); | ||
260 | int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val); | ||
260 | int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val); | 261 | int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val); |
261 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); | 262 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 value); |
262 | 263 | ||
263 | /* | 264 | /* |
264 | * Mode operation of the M-5MOLS | 265 | * Mode operation of the M-5MOLS |
@@ -280,12 +281,12 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); | |||
280 | * The available executing order between each modes are as follows: | 281 | * The available executing order between each modes are as follows: |
281 | * PARAMETER <---> MONITOR <---> CAPTURE | 282 | * PARAMETER <---> MONITOR <---> CAPTURE |
282 | */ | 283 | */ |
283 | int m5mols_mode(struct m5mols_info *info, u32 mode); | 284 | int m5mols_mode(struct m5mols_info *info, u8 mode); |
284 | 285 | ||
285 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg); | 286 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg); |
286 | int m5mols_sync_controls(struct m5mols_info *info); | 287 | int m5mols_sync_controls(struct m5mols_info *info); |
287 | int m5mols_start_capture(struct m5mols_info *info); | 288 | int m5mols_start_capture(struct m5mols_info *info); |
288 | int m5mols_do_scenemode(struct m5mols_info *info, u32 mode); | 289 | int m5mols_do_scenemode(struct m5mols_info *info, u8 mode); |
289 | int m5mols_lock_3a(struct m5mols_info *info, bool lock); | 290 | int m5mols_lock_3a(struct m5mols_info *info, bool lock); |
290 | int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); | 291 | int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); |
291 | 292 | ||
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c index d71a3903b60f..d9471928369d 100644 --- a/drivers/media/video/m5mols/m5mols_capture.c +++ b/drivers/media/video/m5mols/m5mols_capture.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * The Capture code for Fujitsu M-5MOLS ISP | 2 | * The Capture code for Fujitsu M-5MOLS ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -58,9 +58,9 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num, | |||
58 | { | 58 | { |
59 | u32 num, den; | 59 | u32 num, den; |
60 | 60 | ||
61 | int ret = m5mols_read(sd, addr_num, &num); | 61 | int ret = m5mols_read_u32(sd, addr_num, &num); |
62 | if (!ret) | 62 | if (!ret) |
63 | ret = m5mols_read(sd, addr_den, &den); | 63 | ret = m5mols_read_u32(sd, addr_den, &den); |
64 | if (ret) | 64 | if (ret) |
65 | return ret; | 65 | return ret; |
66 | *val = den == 0 ? 0 : num / den; | 66 | *val = den == 0 ? 0 : num / den; |
@@ -99,20 +99,20 @@ static int m5mols_capture_info(struct m5mols_info *info) | |||
99 | if (ret) | 99 | if (ret) |
100 | return ret; | 100 | return ret; |
101 | 101 | ||
102 | ret = m5mols_read(sd, EXIF_INFO_ISO, (u32 *)&exif->iso_speed); | 102 | ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed); |
103 | if (!ret) | 103 | if (!ret) |
104 | ret = m5mols_read(sd, EXIF_INFO_FLASH, (u32 *)&exif->flash); | 104 | ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash); |
105 | if (!ret) | 105 | if (!ret) |
106 | ret = m5mols_read(sd, EXIF_INFO_SDR, (u32 *)&exif->sdr); | 106 | ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr); |
107 | if (!ret) | 107 | if (!ret) |
108 | ret = m5mols_read(sd, EXIF_INFO_QVAL, (u32 *)&exif->qval); | 108 | ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval); |
109 | if (ret) | 109 | if (ret) |
110 | return ret; | 110 | return ret; |
111 | 111 | ||
112 | if (!ret) | 112 | if (!ret) |
113 | ret = m5mols_read(sd, CAPC_IMAGE_SIZE, &info->cap.main); | 113 | ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main); |
114 | if (!ret) | 114 | if (!ret) |
115 | ret = m5mols_read(sd, CAPC_THUMB_SIZE, &info->cap.thumb); | 115 | ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb); |
116 | if (!ret) | 116 | if (!ret) |
117 | info->cap.total = info->cap.main + info->cap.thumb; | 117 | info->cap.total = info->cap.main + info->cap.thumb; |
118 | 118 | ||
@@ -122,7 +122,7 @@ static int m5mols_capture_info(struct m5mols_info *info) | |||
122 | int m5mols_start_capture(struct m5mols_info *info) | 122 | int m5mols_start_capture(struct m5mols_info *info) |
123 | { | 123 | { |
124 | struct v4l2_subdev *sd = &info->sd; | 124 | struct v4l2_subdev *sd = &info->sd; |
125 | u32 resolution = info->resolution; | 125 | u8 resolution = info->resolution; |
126 | int timeout; | 126 | int timeout; |
127 | int ret; | 127 | int ret; |
128 | 128 | ||
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c index 817c16fec368..d135d20d09cf 100644 --- a/drivers/media/video/m5mols/m5mols_controls.c +++ b/drivers/media/video/m5mols/m5mols_controls.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * Controls for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Controls for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -130,7 +130,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = { | |||
130 | * | 130 | * |
131 | * WARNING: The execution order is important. Do not change the order. | 131 | * WARNING: The execution order is important. Do not change the order. |
132 | */ | 132 | */ |
133 | int m5mols_do_scenemode(struct m5mols_info *info, u32 mode) | 133 | int m5mols_do_scenemode(struct m5mols_info *info, u8 mode) |
134 | { | 134 | { |
135 | struct v4l2_subdev *sd = &info->sd; | 135 | struct v4l2_subdev *sd = &info->sd; |
136 | struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; | 136 | struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; |
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index 76eac26e84ae..43c68f51c5ce 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * Driver for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Driver for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -133,13 +133,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length) | |||
133 | /** | 133 | /** |
134 | * m5mols_read - I2C read function | 134 | * m5mols_read - I2C read function |
135 | * @reg: combination of size, category and command for the I2C packet | 135 | * @reg: combination of size, category and command for the I2C packet |
136 | * @size: desired size of I2C packet | ||
136 | * @val: read value | 137 | * @val: read value |
137 | */ | 138 | */ |
138 | int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | 139 | static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val) |
139 | { | 140 | { |
140 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 141 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
141 | u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1]; | 142 | u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1]; |
142 | u8 size = I2C_SIZE(reg); | ||
143 | u8 category = I2C_CATEGORY(reg); | 143 | u8 category = I2C_CATEGORY(reg); |
144 | u8 cmd = I2C_COMMAND(reg); | 144 | u8 cmd = I2C_COMMAND(reg); |
145 | struct i2c_msg msg[2]; | 145 | struct i2c_msg msg[2]; |
@@ -149,11 +149,6 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | |||
149 | if (!client->adapter) | 149 | if (!client->adapter) |
150 | return -ENODEV; | 150 | return -ENODEV; |
151 | 151 | ||
152 | if (size != 1 && size != 2 && size != 4) { | ||
153 | v4l2_err(sd, "Wrong data size\n"); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | msg[0].addr = client->addr; | 152 | msg[0].addr = client->addr; |
158 | msg[0].flags = 0; | 153 | msg[0].flags = 0; |
159 | msg[0].len = 5; | 154 | msg[0].len = 5; |
@@ -184,6 +179,52 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | |||
184 | return 0; | 179 | return 0; |
185 | } | 180 | } |
186 | 181 | ||
182 | int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val) | ||
183 | { | ||
184 | u32 val_32; | ||
185 | int ret; | ||
186 | |||
187 | if (I2C_SIZE(reg) != 1) { | ||
188 | v4l2_err(sd, "Wrong data size\n"); | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | |||
192 | ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32); | ||
193 | if (ret) | ||
194 | return ret; | ||
195 | |||
196 | *val = (u8)val_32; | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val) | ||
201 | { | ||
202 | u32 val_32; | ||
203 | int ret; | ||
204 | |||
205 | if (I2C_SIZE(reg) != 2) { | ||
206 | v4l2_err(sd, "Wrong data size\n"); | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | *val = (u16)val_32; | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val) | ||
219 | { | ||
220 | if (I2C_SIZE(reg) != 4) { | ||
221 | v4l2_err(sd, "Wrong data size\n"); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | |||
225 | return m5mols_read(sd, I2C_SIZE(reg), reg, val); | ||
226 | } | ||
227 | |||
187 | /** | 228 | /** |
188 | * m5mols_write - I2C command write function | 229 | * m5mols_write - I2C command write function |
189 | * @reg: combination of size, category and command for the I2C packet | 230 | * @reg: combination of size, category and command for the I2C packet |
@@ -231,13 +272,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val) | |||
231 | return 0; | 272 | return 0; |
232 | } | 273 | } |
233 | 274 | ||
234 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) | 275 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 mask) |
235 | { | 276 | { |
236 | u32 busy, i; | 277 | u8 busy; |
278 | int i; | ||
237 | int ret; | 279 | int ret; |
238 | 280 | ||
239 | for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) { | 281 | for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) { |
240 | ret = m5mols_read(sd, I2C_REG(category, cmd, 1), &busy); | 282 | ret = m5mols_read_u8(sd, I2C_REG(category, cmd, 1), &busy); |
241 | if (ret < 0) | 283 | if (ret < 0) |
242 | return ret; | 284 | return ret; |
243 | if ((busy & mask) == mask) | 285 | if ((busy & mask) == mask) |
@@ -252,14 +294,14 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) | |||
252 | * Before writing desired interrupt value the INT_FACTOR register should | 294 | * Before writing desired interrupt value the INT_FACTOR register should |
253 | * be read to clear pending interrupts. | 295 | * be read to clear pending interrupts. |
254 | */ | 296 | */ |
255 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) | 297 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg) |
256 | { | 298 | { |
257 | struct m5mols_info *info = to_m5mols(sd); | 299 | struct m5mols_info *info = to_m5mols(sd); |
258 | u32 mask = is_available_af(info) ? REG_INT_AF : 0; | 300 | u8 mask = is_available_af(info) ? REG_INT_AF : 0; |
259 | u32 dummy; | 301 | u8 dummy; |
260 | int ret; | 302 | int ret; |
261 | 303 | ||
262 | ret = m5mols_read(sd, SYSTEM_INT_FACTOR, &dummy); | 304 | ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy); |
263 | if (!ret) | 305 | if (!ret) |
264 | ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); | 306 | ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); |
265 | return ret; | 307 | return ret; |
@@ -271,7 +313,7 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) | |||
271 | * It always accompanies a little delay changing the M-5MOLS mode, so it is | 313 | * It always accompanies a little delay changing the M-5MOLS mode, so it is |
272 | * needed checking current busy status to guarantee right mode. | 314 | * needed checking current busy status to guarantee right mode. |
273 | */ | 315 | */ |
274 | static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) | 316 | static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode) |
275 | { | 317 | { |
276 | int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode); | 318 | int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode); |
277 | 319 | ||
@@ -286,16 +328,16 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) | |||
286 | * can be guaranteed only when the sensor is operating in mode which which | 328 | * can be guaranteed only when the sensor is operating in mode which which |
287 | * a command belongs to. | 329 | * a command belongs to. |
288 | */ | 330 | */ |
289 | int m5mols_mode(struct m5mols_info *info, u32 mode) | 331 | int m5mols_mode(struct m5mols_info *info, u8 mode) |
290 | { | 332 | { |
291 | struct v4l2_subdev *sd = &info->sd; | 333 | struct v4l2_subdev *sd = &info->sd; |
292 | int ret = -EINVAL; | 334 | int ret = -EINVAL; |
293 | u32 reg; | 335 | u8 reg; |
294 | 336 | ||
295 | if (mode < REG_PARAMETER && mode > REG_CAPTURE) | 337 | if (mode < REG_PARAMETER && mode > REG_CAPTURE) |
296 | return ret; | 338 | return ret; |
297 | 339 | ||
298 | ret = m5mols_read(sd, SYSTEM_SYSMODE, ®); | 340 | ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, ®); |
299 | if ((!ret && reg == mode) || ret) | 341 | if ((!ret && reg == mode) || ret) |
300 | return ret; | 342 | return ret; |
301 | 343 | ||
@@ -344,41 +386,37 @@ int m5mols_mode(struct m5mols_info *info, u32 mode) | |||
344 | static int m5mols_get_version(struct v4l2_subdev *sd) | 386 | static int m5mols_get_version(struct v4l2_subdev *sd) |
345 | { | 387 | { |
346 | struct m5mols_info *info = to_m5mols(sd); | 388 | struct m5mols_info *info = to_m5mols(sd); |
347 | union { | 389 | struct m5mols_version *ver = &info->ver; |
348 | struct m5mols_version ver; | 390 | u8 *str = ver->str; |
349 | u8 bytes[VERSION_SIZE]; | 391 | int i; |
350 | } version; | ||
351 | u32 *value; | ||
352 | u8 cmd = CAT0_VER_CUSTOMER; | ||
353 | int ret; | 392 | int ret; |
354 | 393 | ||
355 | do { | 394 | ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer); |
356 | value = (u32 *)&version.bytes[cmd]; | 395 | if (!ret) |
357 | ret = m5mols_read(sd, SYSTEM_CMD(cmd), value); | 396 | ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project); |
358 | if (ret) | 397 | if (!ret) |
359 | return ret; | 398 | ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw); |
360 | } while (cmd++ != CAT0_VER_AWB); | 399 | if (!ret) |
400 | ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw); | ||
401 | if (!ret) | ||
402 | ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param); | ||
403 | if (!ret) | ||
404 | ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb); | ||
405 | if (!ret) | ||
406 | ret = m5mols_read_u8(sd, AF_VERSION, &ver->af); | ||
407 | if (ret) | ||
408 | return ret; | ||
361 | 409 | ||
362 | do { | 410 | for (i = 0; i < VERSION_STRING_SIZE; i++) { |
363 | value = (u32 *)&version.bytes[cmd]; | 411 | ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]); |
364 | ret = m5mols_read(sd, SYSTEM_VER_STRING, value); | ||
365 | if (ret) | 412 | if (ret) |
366 | return ret; | 413 | return ret; |
367 | if (cmd >= VERSION_SIZE - 1) | 414 | } |
368 | return -EINVAL; | ||
369 | } while (version.bytes[cmd++]); | ||
370 | |||
371 | value = (u32 *)&version.bytes[cmd]; | ||
372 | ret = m5mols_read(sd, AF_VERSION, value); | ||
373 | if (ret) | ||
374 | return ret; | ||
375 | 415 | ||
376 | /* store version information swapped for being readable */ | 416 | ver->fw = be16_to_cpu(ver->fw); |
377 | info->ver = version.ver; | 417 | ver->hw = be16_to_cpu(ver->hw); |
378 | info->ver.fw = be16_to_cpu(info->ver.fw); | 418 | ver->param = be16_to_cpu(ver->param); |
379 | info->ver.hw = be16_to_cpu(info->ver.hw); | 419 | ver->awb = be16_to_cpu(ver->awb); |
380 | info->ver.param = be16_to_cpu(info->ver.param); | ||
381 | info->ver.awb = be16_to_cpu(info->ver.awb); | ||
382 | 420 | ||
383 | v4l2_info(sd, "Manufacturer\t[%s]\n", | 421 | v4l2_info(sd, "Manufacturer\t[%s]\n", |
384 | is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? | 422 | is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? |
@@ -722,7 +760,7 @@ static int m5mols_init_controls(struct m5mols_info *info) | |||
722 | int ret; | 760 | int ret; |
723 | 761 | ||
724 | /* Determine value's range & step of controls for various FW version */ | 762 | /* Determine value's range & step of controls for various FW version */ |
725 | ret = m5mols_read(sd, AE_MAX_GAIN_MON, (u32 *)&max_exposure); | 763 | ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure); |
726 | if (!ret) | 764 | if (!ret) |
727 | step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1; | 765 | step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1; |
728 | if (ret) | 766 | if (ret) |
@@ -842,18 +880,18 @@ static void m5mols_irq_work(struct work_struct *work) | |||
842 | struct m5mols_info *info = | 880 | struct m5mols_info *info = |
843 | container_of(work, struct m5mols_info, work_irq); | 881 | container_of(work, struct m5mols_info, work_irq); |
844 | struct v4l2_subdev *sd = &info->sd; | 882 | struct v4l2_subdev *sd = &info->sd; |
845 | u32 reg; | 883 | u8 reg; |
846 | int ret; | 884 | int ret; |
847 | 885 | ||
848 | if (!is_powered(info) || | 886 | if (!is_powered(info) || |
849 | m5mols_read(sd, SYSTEM_INT_FACTOR, &info->interrupt)) | 887 | m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt)) |
850 | return; | 888 | return; |
851 | 889 | ||
852 | switch (info->interrupt & REG_INT_MASK) { | 890 | switch (info->interrupt & REG_INT_MASK) { |
853 | case REG_INT_AF: | 891 | case REG_INT_AF: |
854 | if (!is_available_af(info)) | 892 | if (!is_available_af(info)) |
855 | break; | 893 | break; |
856 | ret = m5mols_read(sd, AF_STATUS, ®); | 894 | ret = m5mols_read_u8(sd, AF_STATUS, ®); |
857 | v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", | 895 | v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", |
858 | reg == REG_AF_FAIL ? "Failed" : | 896 | reg == REG_AF_FAIL ? "Failed" : |
859 | reg == REG_AF_SUCCESS ? "Success" : | 897 | reg == REG_AF_SUCCESS ? "Success" : |
diff --git a/drivers/media/video/m5mols/m5mols_reg.h b/drivers/media/video/m5mols/m5mols_reg.h index b83e36fc6ac6..c755bd6edfe9 100644 --- a/drivers/media/video/m5mols/m5mols_reg.h +++ b/drivers/media/video/m5mols/m5mols_reg.h | |||
@@ -2,10 +2,10 @@ | |||
2 | * Register map for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Register map for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -56,13 +56,24 @@ | |||
56 | * more specific contents, see definition if file m5mols.h. | 56 | * more specific contents, see definition if file m5mols.h. |
57 | */ | 57 | */ |
58 | #define CAT0_VER_CUSTOMER 0x00 /* customer version */ | 58 | #define CAT0_VER_CUSTOMER 0x00 /* customer version */ |
59 | #define CAT0_VER_AWB 0x09 /* Auto WB version */ | 59 | #define CAT0_VER_PROJECT 0x01 /* project version */ |
60 | #define CAT0_VER_FIRMWARE 0x02 /* Firmware version */ | ||
61 | #define CAT0_VER_HARDWARE 0x04 /* Hardware version */ | ||
62 | #define CAT0_VER_PARAMETER 0x06 /* Parameter version */ | ||
63 | #define CAT0_VER_AWB 0x08 /* Auto WB version */ | ||
60 | #define CAT0_VER_STRING 0x0a /* string including M-5MOLS */ | 64 | #define CAT0_VER_STRING 0x0a /* string including M-5MOLS */ |
61 | #define CAT0_SYSMODE 0x0b /* SYSTEM mode register */ | 65 | #define CAT0_SYSMODE 0x0b /* SYSTEM mode register */ |
62 | #define CAT0_STATUS 0x0c /* SYSTEM mode status register */ | 66 | #define CAT0_STATUS 0x0c /* SYSTEM mode status register */ |
63 | #define CAT0_INT_FACTOR 0x10 /* interrupt pending register */ | 67 | #define CAT0_INT_FACTOR 0x10 /* interrupt pending register */ |
64 | #define CAT0_INT_ENABLE 0x11 /* interrupt enable register */ | 68 | #define CAT0_INT_ENABLE 0x11 /* interrupt enable register */ |
65 | 69 | ||
70 | #define SYSTEM_VER_CUSTOMER I2C_REG(CAT_SYSTEM, CAT0_VER_CUSTOMER, 1) | ||
71 | #define SYSTEM_VER_PROJECT I2C_REG(CAT_SYSTEM, CAT0_VER_PROJECT, 1) | ||
72 | #define SYSTEM_VER_FIRMWARE I2C_REG(CAT_SYSTEM, CAT0_VER_FIRMWARE, 2) | ||
73 | #define SYSTEM_VER_HARDWARE I2C_REG(CAT_SYSTEM, CAT0_VER_HARDWARE, 2) | ||
74 | #define SYSTEM_VER_PARAMETER I2C_REG(CAT_SYSTEM, CAT0_VER_PARAMETER, 2) | ||
75 | #define SYSTEM_VER_AWB I2C_REG(CAT_SYSTEM, CAT0_VER_AWB, 2) | ||
76 | |||
66 | #define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1) | 77 | #define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1) |
67 | #define REG_SYSINIT 0x00 /* SYSTEM mode */ | 78 | #define REG_SYSINIT 0x00 /* SYSTEM mode */ |
68 | #define REG_PARAMETER 0x01 /* PARAMETER mode */ | 79 | #define REG_PARAMETER 0x01 /* PARAMETER mode */ |
@@ -382,8 +393,8 @@ | |||
382 | #define REG_CAP_START_MAIN 0x01 | 393 | #define REG_CAP_START_MAIN 0x01 |
383 | #define REG_CAP_START_THUMB 0x03 | 394 | #define REG_CAP_START_THUMB 0x03 |
384 | 395 | ||
385 | #define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 1) | 396 | #define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 4) |
386 | #define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 1) | 397 | #define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 4) |
387 | 398 | ||
388 | /* | 399 | /* |
389 | * Category F - Flash | 400 | * Category F - Flash |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index de5d481b0328..c43c81f5f978 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -480,12 +480,14 @@ static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
480 | struct msp_state *state = to_state(sd); | 480 | struct msp_state *state = to_state(sd); |
481 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 481 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
482 | 482 | ||
483 | if (state->radio) | 483 | if (vt->type != V4L2_TUNER_ANALOG_TV) |
484 | return 0; | 484 | return 0; |
485 | if (state->opmode == OPMODE_AUTOSELECT) | 485 | if (!state->radio) { |
486 | msp_detect_stereo(client); | 486 | if (state->opmode == OPMODE_AUTOSELECT) |
487 | vt->audmode = state->audmode; | 487 | msp_detect_stereo(client); |
488 | vt->rxsubchans = state->rxsubchans; | 488 | vt->rxsubchans = state->rxsubchans; |
489 | } | ||
490 | vt->audmode = state->audmode; | ||
489 | vt->capability |= V4L2_TUNER_CAP_STEREO | | 491 | vt->capability |= V4L2_TUNER_CAP_STEREO | |
490 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | 492 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
491 | return 0; | 493 | return 0; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index bc0c23a1009c..63f8a0cc33d8 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -444,12 +444,9 @@ static int mx1_camera_add_device(struct soc_camera_device *icd) | |||
444 | { | 444 | { |
445 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 445 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
446 | struct mx1_camera_dev *pcdev = ici->priv; | 446 | struct mx1_camera_dev *pcdev = ici->priv; |
447 | int ret; | ||
448 | 447 | ||
449 | if (pcdev->icd) { | 448 | if (pcdev->icd) |
450 | ret = -EBUSY; | 449 | return -EBUSY; |
451 | goto ebusy; | ||
452 | } | ||
453 | 450 | ||
454 | dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n", | 451 | dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n", |
455 | icd->devnum); | 452 | icd->devnum); |
@@ -458,8 +455,7 @@ static int mx1_camera_add_device(struct soc_camera_device *icd) | |||
458 | 455 | ||
459 | pcdev->icd = icd; | 456 | pcdev->icd = icd; |
460 | 457 | ||
461 | ebusy: | 458 | return 0; |
462 | return ret; | ||
463 | } | 459 | } |
464 | 460 | ||
465 | static void mx1_camera_remove_device(struct soc_camera_device *icd) | 461 | static void mx1_camera_remove_device(struct soc_camera_device *icd) |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 4ada9be1d430..4d07c5844402 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -982,6 +982,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, | |||
982 | startindex = (vout->vid == OMAP_VIDEO1) ? | 982 | startindex = (vout->vid == OMAP_VIDEO1) ? |
983 | video1_numbuffers : video2_numbuffers; | 983 | video1_numbuffers : video2_numbuffers; |
984 | 984 | ||
985 | /* Check the size of the buffer */ | ||
986 | if (*size > vout->buffer_size) { | ||
987 | v4l2_err(&vout->vid_dev->v4l2_dev, | ||
988 | "buffer allocation mismatch [%u] [%u]\n", | ||
989 | *size, vout->buffer_size); | ||
990 | return -ENOMEM; | ||
991 | } | ||
992 | |||
985 | for (i = startindex; i < *count; i++) { | 993 | for (i = startindex; i < *count; i++) { |
986 | vout->buffer_size = *size; | 994 | vout->buffer_size = *size; |
987 | 995 | ||
@@ -1228,6 +1236,14 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) | |||
1228 | (vma->vm_pgoff << PAGE_SHIFT)); | 1236 | (vma->vm_pgoff << PAGE_SHIFT)); |
1229 | return -EINVAL; | 1237 | return -EINVAL; |
1230 | } | 1238 | } |
1239 | /* Check the size of the buffer */ | ||
1240 | if (size > vout->buffer_size) { | ||
1241 | v4l2_err(&vout->vid_dev->v4l2_dev, | ||
1242 | "insufficient memory [%lu] [%u]\n", | ||
1243 | size, vout->buffer_size); | ||
1244 | return -ENOMEM; | ||
1245 | } | ||
1246 | |||
1231 | q->bufs[i]->baddr = vma->vm_start; | 1247 | q->bufs[i]->baddr = vma->vm_start; |
1232 | 1248 | ||
1233 | vma->vm_flags |= VM_RESERVED; | 1249 | vma->vm_flags |= VM_RESERVED; |
@@ -2391,7 +2407,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) | |||
2391 | /* Register the Video device with V4L2 | 2407 | /* Register the Video device with V4L2 |
2392 | */ | 2408 | */ |
2393 | vfd = vout->vfd; | 2409 | vfd = vout->vfd; |
2394 | if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) { | 2410 | if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) { |
2395 | dev_err(&pdev->dev, ": Could not register " | 2411 | dev_err(&pdev->dev, ": Could not register " |
2396 | "Video for Linux device\n"); | 2412 | "Video for Linux device\n"); |
2397 | vfd->minor = -1; | 2413 | vfd->minor = -1; |
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c index 2aa6a76c5e59..8ae74817a110 100644 --- a/drivers/media/video/omap/omap_voutlib.c +++ b/drivers/media/video/omap/omap_voutlib.c | |||
@@ -193,7 +193,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
193 | return -EINVAL; | 193 | return -EINVAL; |
194 | 194 | ||
195 | if (cpu_is_omap24xx()) { | 195 | if (cpu_is_omap24xx()) { |
196 | if (crop->height != win->w.height) { | 196 | if (try_crop.height != win->w.height) { |
197 | /* If we're resizing vertically, we can't support a | 197 | /* If we're resizing vertically, we can't support a |
198 | * crop width wider than 768 pixels. | 198 | * crop width wider than 768 pixels. |
199 | */ | 199 | */ |
@@ -202,7 +202,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
202 | } | 202 | } |
203 | } | 203 | } |
204 | /* vertical resizing */ | 204 | /* vertical resizing */ |
205 | vresize = (1024 * crop->height) / win->w.height; | 205 | vresize = (1024 * try_crop.height) / win->w.height; |
206 | if (cpu_is_omap24xx() && (vresize > 2048)) | 206 | if (cpu_is_omap24xx() && (vresize > 2048)) |
207 | vresize = 2048; | 207 | vresize = 2048; |
208 | else if (cpu_is_omap34xx() && (vresize > 4096)) | 208 | else if (cpu_is_omap34xx() && (vresize > 4096)) |
@@ -221,7 +221,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
221 | try_crop.height = 2; | 221 | try_crop.height = 2; |
222 | } | 222 | } |
223 | /* horizontal resizing */ | 223 | /* horizontal resizing */ |
224 | hresize = (1024 * crop->width) / win->w.width; | 224 | hresize = (1024 * try_crop.width) / win->w.width; |
225 | if (cpu_is_omap24xx() && (hresize > 2048)) | 225 | if (cpu_is_omap24xx() && (hresize > 2048)) |
226 | hresize = 2048; | 226 | hresize = 2048; |
227 | else if (cpu_is_omap34xx() && (hresize > 4096)) | 227 | else if (cpu_is_omap34xx() && (hresize > 4096)) |
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index c9fd04ee70a8..94b6ed89e195 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -1748,7 +1748,7 @@ static int isp_register_entities(struct isp_device *isp) | |||
1748 | goto done; | 1748 | goto done; |
1749 | 1749 | ||
1750 | /* Register external entities */ | 1750 | /* Register external entities */ |
1751 | for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) { | 1751 | for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { |
1752 | struct v4l2_subdev *sensor; | 1752 | struct v4l2_subdev *sensor; |
1753 | struct media_entity *input; | 1753 | struct media_entity *input; |
1754 | unsigned int flags; | 1754 | unsigned int flags; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 9d0dd08f57f8..e98d38212791 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) | |||
3046 | if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { | 3046 | if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { |
3047 | struct v4l2_tuner vt; | 3047 | struct v4l2_tuner vt; |
3048 | memset(&vt, 0, sizeof(vt)); | 3048 | memset(&vt, 0, sizeof(vt)); |
3049 | vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? | ||
3050 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
3049 | vt.audmode = hdw->audiomode_val; | 3051 | vt.audmode = hdw->audiomode_val; |
3050 | v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); | 3052 | v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); |
3051 | } | 3053 | } |
@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) | |||
5171 | { | 5173 | { |
5172 | struct v4l2_tuner *vtp = &hdw->tuner_signal_info; | 5174 | struct v4l2_tuner *vtp = &hdw->tuner_signal_info; |
5173 | memset(vtp, 0, sizeof(*vtp)); | 5175 | memset(vtp, 0, sizeof(*vtp)); |
5176 | vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? | ||
5177 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
5174 | hdw->tuner_signal_stale = 0; | 5178 | hdw->tuner_signal_stale = 0; |
5175 | /* Note: There apparently is no replacement for VIDIOC_CROPCAP | 5179 | /* Note: There apparently is no replacement for VIDIOC_CROPCAP |
5176 | using v4l2-subdev - therefore we can't support that AT ALL right | 5180 | using v4l2-subdev - therefore we can't support that AT ALL right |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 1593f8deb810..760b4de13adf 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -1414,7 +1414,7 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1414 | { | 1414 | { |
1415 | ARG_DEF(struct pwc_probe, probe) | 1415 | ARG_DEF(struct pwc_probe, probe) |
1416 | 1416 | ||
1417 | strcpy(ARGR(probe).name, pdev->vdev->name); | 1417 | strcpy(ARGR(probe).name, pdev->vdev.name); |
1418 | ARGR(probe).type = pdev->type; | 1418 | ARGR(probe).type = pdev->type; |
1419 | ARG_OUT(probe) | 1419 | ARG_OUT(probe) |
1420 | break; | 1420 | break; |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 356cd42b593b..b0bde5a87c8a 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -40,7 +40,7 @@ | |||
40 | Oh yes, convention: to disctinguish between all the various pointers to | 40 | Oh yes, convention: to disctinguish between all the various pointers to |
41 | device-structures, I use these names for the pointer variables: | 41 | device-structures, I use these names for the pointer variables: |
42 | udev: struct usb_device * | 42 | udev: struct usb_device * |
43 | vdev: struct video_device * | 43 | vdev: struct video_device (member of pwc_dev) |
44 | pdev: struct pwc_devive * | 44 | pdev: struct pwc_devive * |
45 | */ | 45 | */ |
46 | 46 | ||
@@ -152,6 +152,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
152 | size_t count, loff_t *ppos); | 152 | size_t count, loff_t *ppos); |
153 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | 153 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); |
154 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); | 154 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); |
155 | static void pwc_video_release(struct video_device *vfd); | ||
155 | 156 | ||
156 | static const struct v4l2_file_operations pwc_fops = { | 157 | static const struct v4l2_file_operations pwc_fops = { |
157 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
@@ -164,42 +165,12 @@ static const struct v4l2_file_operations pwc_fops = { | |||
164 | }; | 165 | }; |
165 | static struct video_device pwc_template = { | 166 | static struct video_device pwc_template = { |
166 | .name = "Philips Webcam", /* Filled in later */ | 167 | .name = "Philips Webcam", /* Filled in later */ |
167 | .release = video_device_release, | 168 | .release = pwc_video_release, |
168 | .fops = &pwc_fops, | 169 | .fops = &pwc_fops, |
170 | .ioctl_ops = &pwc_ioctl_ops, | ||
169 | }; | 171 | }; |
170 | 172 | ||
171 | /***************************************************************************/ | 173 | /***************************************************************************/ |
172 | |||
173 | /* Okay, this is some magic that I worked out and the reasoning behind it... | ||
174 | |||
175 | The biggest problem with any USB device is of course: "what to do | ||
176 | when the user unplugs the device while it is in use by an application?" | ||
177 | We have several options: | ||
178 | 1) Curse them with the 7 plagues when they do (requires divine intervention) | ||
179 | 2) Tell them not to (won't work: they'll do it anyway) | ||
180 | 3) Oops the kernel (this will have a negative effect on a user's uptime) | ||
181 | 4) Do something sensible. | ||
182 | |||
183 | Of course, we go for option 4. | ||
184 | |||
185 | It happens that this device will be linked to two times, once from | ||
186 | usb_device and once from the video_device in their respective 'private' | ||
187 | pointers. This is done when the device is probed() and all initialization | ||
188 | succeeded. The pwc_device struct links back to both structures. | ||
189 | |||
190 | When a device is unplugged while in use it will be removed from the | ||
191 | list of known USB devices; I also de-register it as a V4L device, but | ||
192 | unfortunately I can't free the memory since the struct is still in use | ||
193 | by the file descriptor. This free-ing is then deferend until the first | ||
194 | opportunity. Crude, but it works. | ||
195 | |||
196 | A small 'advantage' is that if a user unplugs the cam and plugs it back | ||
197 | in, it should get assigned the same video device minor, but unfortunately | ||
198 | it's non-trivial to re-link the cam back to the video device... (that | ||
199 | would surely be magic! :)) | ||
200 | */ | ||
201 | |||
202 | /***************************************************************************/ | ||
203 | /* Private functions */ | 174 | /* Private functions */ |
204 | 175 | ||
205 | /* Here we want the physical address of the memory. | 176 | /* Here we want the physical address of the memory. |
@@ -1016,16 +987,15 @@ static ssize_t show_snapshot_button_status(struct device *class_dev, | |||
1016 | static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, | 987 | static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, |
1017 | NULL); | 988 | NULL); |
1018 | 989 | ||
1019 | static int pwc_create_sysfs_files(struct video_device *vdev) | 990 | static int pwc_create_sysfs_files(struct pwc_device *pdev) |
1020 | { | 991 | { |
1021 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1022 | int rc; | 992 | int rc; |
1023 | 993 | ||
1024 | rc = device_create_file(&vdev->dev, &dev_attr_button); | 994 | rc = device_create_file(&pdev->vdev.dev, &dev_attr_button); |
1025 | if (rc) | 995 | if (rc) |
1026 | goto err; | 996 | goto err; |
1027 | if (pdev->features & FEATURE_MOTOR_PANTILT) { | 997 | if (pdev->features & FEATURE_MOTOR_PANTILT) { |
1028 | rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt); | 998 | rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt); |
1029 | if (rc) | 999 | if (rc) |
1030 | goto err_button; | 1000 | goto err_button; |
1031 | } | 1001 | } |
@@ -1033,19 +1003,17 @@ static int pwc_create_sysfs_files(struct video_device *vdev) | |||
1033 | return 0; | 1003 | return 0; |
1034 | 1004 | ||
1035 | err_button: | 1005 | err_button: |
1036 | device_remove_file(&vdev->dev, &dev_attr_button); | 1006 | device_remove_file(&pdev->vdev.dev, &dev_attr_button); |
1037 | err: | 1007 | err: |
1038 | PWC_ERROR("Could not create sysfs files.\n"); | 1008 | PWC_ERROR("Could not create sysfs files.\n"); |
1039 | return rc; | 1009 | return rc; |
1040 | } | 1010 | } |
1041 | 1011 | ||
1042 | static void pwc_remove_sysfs_files(struct video_device *vdev) | 1012 | static void pwc_remove_sysfs_files(struct pwc_device *pdev) |
1043 | { | 1013 | { |
1044 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1045 | |||
1046 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1014 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1047 | device_remove_file(&vdev->dev, &dev_attr_pan_tilt); | 1015 | device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt); |
1048 | device_remove_file(&vdev->dev, &dev_attr_button); | 1016 | device_remove_file(&pdev->vdev.dev, &dev_attr_button); |
1049 | } | 1017 | } |
1050 | 1018 | ||
1051 | #ifdef CONFIG_USB_PWC_DEBUG | 1019 | #ifdef CONFIG_USB_PWC_DEBUG |
@@ -1106,7 +1074,7 @@ static int pwc_video_open(struct file *file) | |||
1106 | if (ret >= 0) | 1074 | if (ret >= 0) |
1107 | { | 1075 | { |
1108 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", | 1076 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", |
1109 | pdev->vdev->name, | 1077 | pdev->vdev.name, |
1110 | pwc_sensor_type_to_string(i), i); | 1078 | pwc_sensor_type_to_string(i), i); |
1111 | } | 1079 | } |
1112 | } | 1080 | } |
@@ -1180,16 +1148,15 @@ static int pwc_video_open(struct file *file) | |||
1180 | return 0; | 1148 | return 0; |
1181 | } | 1149 | } |
1182 | 1150 | ||
1183 | 1151 | static void pwc_video_release(struct video_device *vfd) | |
1184 | static void pwc_cleanup(struct pwc_device *pdev) | ||
1185 | { | 1152 | { |
1186 | pwc_remove_sysfs_files(pdev->vdev); | 1153 | struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev); |
1187 | video_unregister_device(pdev->vdev); | 1154 | int hint; |
1188 | 1155 | ||
1189 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1156 | /* search device_hint[] table if we occupy a slot, by any chance */ |
1190 | if (pdev->button_dev) | 1157 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) |
1191 | input_unregister_device(pdev->button_dev); | 1158 | if (device_hint[hint].pdev == pdev) |
1192 | #endif | 1159 | device_hint[hint].pdev = NULL; |
1193 | 1160 | ||
1194 | kfree(pdev); | 1161 | kfree(pdev); |
1195 | } | 1162 | } |
@@ -1199,7 +1166,7 @@ static int pwc_video_close(struct file *file) | |||
1199 | { | 1166 | { |
1200 | struct video_device *vdev = file->private_data; | 1167 | struct video_device *vdev = file->private_data; |
1201 | struct pwc_device *pdev; | 1168 | struct pwc_device *pdev; |
1202 | int i, hint; | 1169 | int i; |
1203 | 1170 | ||
1204 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 1171 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
1205 | 1172 | ||
@@ -1234,12 +1201,6 @@ static int pwc_video_close(struct file *file) | |||
1234 | } | 1201 | } |
1235 | pdev->vopen--; | 1202 | pdev->vopen--; |
1236 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); | 1203 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); |
1237 | } else { | ||
1238 | pwc_cleanup(pdev); | ||
1239 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
1240 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
1241 | if (device_hint[hint].pdev == pdev) | ||
1242 | device_hint[hint].pdev = NULL; | ||
1243 | } | 1204 | } |
1244 | 1205 | ||
1245 | return 0; | 1206 | return 0; |
@@ -1715,19 +1676,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1715 | init_waitqueue_head(&pdev->frameq); | 1676 | init_waitqueue_head(&pdev->frameq); |
1716 | pdev->vcompression = pwc_preferred_compression; | 1677 | pdev->vcompression = pwc_preferred_compression; |
1717 | 1678 | ||
1718 | /* Allocate video_device structure */ | 1679 | /* Init video_device structure */ |
1719 | pdev->vdev = video_device_alloc(); | 1680 | memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1720 | if (!pdev->vdev) { | 1681 | pdev->vdev.parent = &intf->dev; |
1721 | PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); | 1682 | pdev->vdev.lock = &pdev->modlock; |
1722 | rc = -ENOMEM; | 1683 | strcpy(pdev->vdev.name, name); |
1723 | goto err_free_mem; | 1684 | video_set_drvdata(&pdev->vdev, pdev); |
1724 | } | ||
1725 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); | ||
1726 | pdev->vdev->parent = &intf->dev; | ||
1727 | pdev->vdev->lock = &pdev->modlock; | ||
1728 | pdev->vdev->ioctl_ops = &pwc_ioctl_ops; | ||
1729 | strcpy(pdev->vdev->name, name); | ||
1730 | video_set_drvdata(pdev->vdev, pdev); | ||
1731 | 1685 | ||
1732 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | 1686 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); |
1733 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); | 1687 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); |
@@ -1746,8 +1700,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1746 | } | 1700 | } |
1747 | } | 1701 | } |
1748 | 1702 | ||
1749 | pdev->vdev->release = video_device_release; | ||
1750 | |||
1751 | /* occupy slot */ | 1703 | /* occupy slot */ |
1752 | if (hint < MAX_DEV_HINTS) | 1704 | if (hint < MAX_DEV_HINTS) |
1753 | device_hint[hint].pdev = pdev; | 1705 | device_hint[hint].pdev = pdev; |
@@ -1759,16 +1711,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1759 | pwc_set_leds(pdev, 0, 0); | 1711 | pwc_set_leds(pdev, 0, 0); |
1760 | pwc_camera_power(pdev, 0); | 1712 | pwc_camera_power(pdev, 0); |
1761 | 1713 | ||
1762 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1714 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); |
1763 | if (rc < 0) { | 1715 | if (rc < 0) { |
1764 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | 1716 | PWC_ERROR("Failed to register as video device (%d).\n", rc); |
1765 | goto err_video_release; | 1717 | goto err_free_mem; |
1766 | } | 1718 | } |
1767 | rc = pwc_create_sysfs_files(pdev->vdev); | 1719 | rc = pwc_create_sysfs_files(pdev); |
1768 | if (rc) | 1720 | if (rc) |
1769 | goto err_video_unreg; | 1721 | goto err_video_unreg; |
1770 | 1722 | ||
1771 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | 1723 | PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev)); |
1772 | 1724 | ||
1773 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1725 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
1774 | /* register webcam snapshot button input device */ | 1726 | /* register webcam snapshot button input device */ |
@@ -1776,7 +1728,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1776 | if (!pdev->button_dev) { | 1728 | if (!pdev->button_dev) { |
1777 | PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); | 1729 | PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); |
1778 | rc = -ENOMEM; | 1730 | rc = -ENOMEM; |
1779 | pwc_remove_sysfs_files(pdev->vdev); | 1731 | pwc_remove_sysfs_files(pdev); |
1780 | goto err_video_unreg; | 1732 | goto err_video_unreg; |
1781 | } | 1733 | } |
1782 | 1734 | ||
@@ -1794,7 +1746,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1794 | if (rc) { | 1746 | if (rc) { |
1795 | input_free_device(pdev->button_dev); | 1747 | input_free_device(pdev->button_dev); |
1796 | pdev->button_dev = NULL; | 1748 | pdev->button_dev = NULL; |
1797 | pwc_remove_sysfs_files(pdev->vdev); | 1749 | pwc_remove_sysfs_files(pdev); |
1798 | goto err_video_unreg; | 1750 | goto err_video_unreg; |
1799 | } | 1751 | } |
1800 | #endif | 1752 | #endif |
@@ -1804,10 +1756,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1804 | err_video_unreg: | 1756 | err_video_unreg: |
1805 | if (hint < MAX_DEV_HINTS) | 1757 | if (hint < MAX_DEV_HINTS) |
1806 | device_hint[hint].pdev = NULL; | 1758 | device_hint[hint].pdev = NULL; |
1807 | video_unregister_device(pdev->vdev); | 1759 | video_unregister_device(&pdev->vdev); |
1808 | pdev->vdev = NULL; /* So we don't try to release it below */ | ||
1809 | err_video_release: | ||
1810 | video_device_release(pdev->vdev); | ||
1811 | err_free_mem: | 1760 | err_free_mem: |
1812 | kfree(pdev); | 1761 | kfree(pdev); |
1813 | return rc; | 1762 | return rc; |
@@ -1816,10 +1765,8 @@ err_free_mem: | |||
1816 | /* The user yanked out the cable... */ | 1765 | /* The user yanked out the cable... */ |
1817 | static void usb_pwc_disconnect(struct usb_interface *intf) | 1766 | static void usb_pwc_disconnect(struct usb_interface *intf) |
1818 | { | 1767 | { |
1819 | struct pwc_device *pdev; | 1768 | struct pwc_device *pdev = usb_get_intfdata(intf); |
1820 | int hint; | ||
1821 | 1769 | ||
1822 | pdev = usb_get_intfdata (intf); | ||
1823 | mutex_lock(&pdev->modlock); | 1770 | mutex_lock(&pdev->modlock); |
1824 | usb_set_intfdata (intf, NULL); | 1771 | usb_set_intfdata (intf, NULL); |
1825 | if (pdev == NULL) { | 1772 | if (pdev == NULL) { |
@@ -1836,30 +1783,25 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1836 | } | 1783 | } |
1837 | 1784 | ||
1838 | /* We got unplugged; this is signalled by an EPIPE error code */ | 1785 | /* We got unplugged; this is signalled by an EPIPE error code */ |
1839 | if (pdev->vopen) { | 1786 | pdev->error_status = EPIPE; |
1840 | PWC_INFO("Disconnected while webcam is in use!\n"); | 1787 | pdev->unplugged = 1; |
1841 | pdev->error_status = EPIPE; | ||
1842 | } | ||
1843 | 1788 | ||
1844 | /* Alert waiting processes */ | 1789 | /* Alert waiting processes */ |
1845 | wake_up_interruptible(&pdev->frameq); | 1790 | wake_up_interruptible(&pdev->frameq); |
1846 | /* Wait until device is closed */ | ||
1847 | if (pdev->vopen) { | ||
1848 | pdev->unplugged = 1; | ||
1849 | pwc_iso_stop(pdev); | ||
1850 | } else { | ||
1851 | /* Device is closed, so we can safely unregister it */ | ||
1852 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); | ||
1853 | 1791 | ||
1854 | disconnect_out: | 1792 | /* No need to keep the urbs around after disconnection */ |
1855 | /* search device_hint[] table if we occupy a slot, by any chance */ | 1793 | pwc_isoc_cleanup(pdev); |
1856 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
1857 | if (device_hint[hint].pdev == pdev) | ||
1858 | device_hint[hint].pdev = NULL; | ||
1859 | } | ||
1860 | 1794 | ||
1795 | disconnect_out: | ||
1861 | mutex_unlock(&pdev->modlock); | 1796 | mutex_unlock(&pdev->modlock); |
1862 | pwc_cleanup(pdev); | 1797 | |
1798 | pwc_remove_sysfs_files(pdev); | ||
1799 | video_unregister_device(&pdev->vdev); | ||
1800 | |||
1801 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
1802 | if (pdev->button_dev) | ||
1803 | input_unregister_device(pdev->button_dev); | ||
1804 | #endif | ||
1863 | } | 1805 | } |
1864 | 1806 | ||
1865 | 1807 | ||
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index e947766337d6..083f8b15df73 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -162,9 +162,9 @@ struct pwc_imgbuf | |||
162 | 162 | ||
163 | struct pwc_device | 163 | struct pwc_device |
164 | { | 164 | { |
165 | struct video_device *vdev; | 165 | struct video_device vdev; |
166 | 166 | ||
167 | /* Pointer to our usb_device */ | 167 | /* Pointer to our usb_device, may be NULL after unplug */ |
168 | struct usb_device *udev; | 168 | struct usb_device *udev; |
169 | 169 | ||
170 | int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ | 170 | int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index d142b40ea64e..81b4a826ee5e 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Samsung S5P SoC series camera interface (camera capture) driver | 2 | * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | 4 | * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. |
5 | * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> | 5 | * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -262,12 +262,7 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) | |||
262 | { | 262 | { |
263 | if (!fr || plane >= fr->fmt->memplanes) | 263 | if (!fr || plane >= fr->fmt->memplanes) |
264 | return 0; | 264 | return 0; |
265 | |||
266 | dbg("%s: w: %d. h: %d. depth[%d]: %d", | ||
267 | __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]); | ||
268 | |||
269 | return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; | 265 | return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; |
270 | |||
271 | } | 266 | } |
272 | 267 | ||
273 | static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | 268 | static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, |
@@ -283,24 +278,14 @@ static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | |||
283 | 278 | ||
284 | *num_planes = fmt->memplanes; | 279 | *num_planes = fmt->memplanes; |
285 | 280 | ||
286 | dbg("%s, buffer count=%d, plane count=%d", | ||
287 | __func__, *num_buffers, *num_planes); | ||
288 | |||
289 | for (i = 0; i < fmt->memplanes; i++) { | 281 | for (i = 0; i < fmt->memplanes; i++) { |
290 | sizes[i] = get_plane_size(&ctx->d_frame, i); | 282 | sizes[i] = get_plane_size(&ctx->d_frame, i); |
291 | dbg("plane: %u, plane_size: %lu", i, sizes[i]); | ||
292 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 283 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
293 | } | 284 | } |
294 | 285 | ||
295 | return 0; | 286 | return 0; |
296 | } | 287 | } |
297 | 288 | ||
298 | static int buffer_init(struct vb2_buffer *vb) | ||
299 | { | ||
300 | /* TODO: */ | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static int buffer_prepare(struct vb2_buffer *vb) | 289 | static int buffer_prepare(struct vb2_buffer *vb) |
305 | { | 290 | { |
306 | struct vb2_queue *vq = vb->vb2_queue; | 291 | struct vb2_queue *vq = vb->vb2_queue; |
@@ -380,7 +365,6 @@ static struct vb2_ops fimc_capture_qops = { | |||
380 | .queue_setup = queue_setup, | 365 | .queue_setup = queue_setup, |
381 | .buf_prepare = buffer_prepare, | 366 | .buf_prepare = buffer_prepare, |
382 | .buf_queue = buffer_queue, | 367 | .buf_queue = buffer_queue, |
383 | .buf_init = buffer_init, | ||
384 | .wait_prepare = fimc_unlock, | 368 | .wait_prepare = fimc_unlock, |
385 | .wait_finish = fimc_lock, | 369 | .wait_finish = fimc_lock, |
386 | .start_streaming = start_streaming, | 370 | .start_streaming = start_streaming, |
@@ -903,6 +887,7 @@ err_vd_reg: | |||
903 | err_v4l2_reg: | 887 | err_v4l2_reg: |
904 | v4l2_device_unregister(v4l2_dev); | 888 | v4l2_device_unregister(v4l2_dev); |
905 | err_info: | 889 | err_info: |
890 | kfree(ctx); | ||
906 | dev_err(&fimc->pdev->dev, "failed to install\n"); | 891 | dev_err(&fimc->pdev->dev, "failed to install\n"); |
907 | return ret; | 892 | return ret; |
908 | } | 893 | } |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index dc91a8511af6..bdf19ada9172 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * S5P camera interface (video postprocessor) driver | 2 | * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | 4 | * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. |
5 | * | 5 | * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com> |
6 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published | 8 | * it under the terms of the GNU General Public License as published |
@@ -42,7 +41,6 @@ static struct fimc_fmt fimc_formats[] = { | |||
42 | .color = S5P_FIMC_RGB565, | 41 | .color = S5P_FIMC_RGB565, |
43 | .memplanes = 1, | 42 | .memplanes = 1, |
44 | .colplanes = 1, | 43 | .colplanes = 1, |
45 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
46 | .flags = FMT_FLAGS_M2M, | 44 | .flags = FMT_FLAGS_M2M, |
47 | }, { | 45 | }, { |
48 | .name = "BGR666", | 46 | .name = "BGR666", |
@@ -232,11 +230,7 @@ static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift) | |||
232 | return 0; | 230 | return 0; |
233 | } | 231 | } |
234 | } | 232 | } |
235 | |||
236 | *shift = 0, *ratio = 1; | 233 | *shift = 0, *ratio = 1; |
237 | |||
238 | dbg("s: %d, t: %d, shift: %d, ratio: %d", | ||
239 | src, tar, *shift, *ratio); | ||
240 | return 0; | 234 | return 0; |
241 | } | 235 | } |
242 | 236 | ||
@@ -268,10 +262,8 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
268 | err("invalid source size: %d x %d", sx, sy); | 262 | err("invalid source size: %d x %d", sx, sy); |
269 | return -EINVAL; | 263 | return -EINVAL; |
270 | } | 264 | } |
271 | |||
272 | sc->real_width = sx; | 265 | sc->real_width = sx; |
273 | sc->real_height = sy; | 266 | sc->real_height = sy; |
274 | dbg("sx= %d, sy= %d, tx= %d, ty= %d", sx, sy, tx, ty); | ||
275 | 267 | ||
276 | ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor); | 268 | ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor); |
277 | if (ret) | 269 | if (ret) |
@@ -711,22 +703,18 @@ static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | |||
711 | f = ctx_get_frame(ctx, vq->type); | 703 | f = ctx_get_frame(ctx, vq->type); |
712 | if (IS_ERR(f)) | 704 | if (IS_ERR(f)) |
713 | return PTR_ERR(f); | 705 | return PTR_ERR(f); |
714 | |||
715 | /* | 706 | /* |
716 | * Return number of non-contigous planes (plane buffers) | 707 | * Return number of non-contigous planes (plane buffers) |
717 | * depending on the configured color format. | 708 | * depending on the configured color format. |
718 | */ | 709 | */ |
719 | if (f->fmt) | 710 | if (!f->fmt) |
720 | *num_planes = f->fmt->memplanes; | 711 | return -EINVAL; |
721 | 712 | ||
713 | *num_planes = f->fmt->memplanes; | ||
722 | for (i = 0; i < f->fmt->memplanes; i++) { | 714 | for (i = 0; i < f->fmt->memplanes; i++) { |
723 | sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3; | 715 | sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8; |
724 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 716 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
725 | } | 717 | } |
726 | |||
727 | if (*num_buffers == 0) | ||
728 | *num_buffers = 1; | ||
729 | |||
730 | return 0; | 718 | return 0; |
731 | } | 719 | } |
732 | 720 | ||
@@ -852,7 +840,7 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) | |||
852 | 840 | ||
853 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { | 841 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { |
854 | fmt = &fimc_formats[i]; | 842 | fmt = &fimc_formats[i]; |
855 | if (fmt->fourcc == f->fmt.pix.pixelformat && | 843 | if (fmt->fourcc == f->fmt.pix_mp.pixelformat && |
856 | (fmt->flags & mask)) | 844 | (fmt->flags & mask)) |
857 | break; | 845 | break; |
858 | } | 846 | } |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 3beb1e5320ce..1f70772daaf0 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -1,7 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Samsung Electronics | 2 | * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. |
3 | * | ||
4 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | ||
5 | * | 3 | * |
6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
@@ -135,9 +133,10 @@ enum fimc_color_fmt { | |||
135 | * @name: format description | 133 | * @name: format description |
136 | * @fourcc: the fourcc code for this format, 0 if not applicable | 134 | * @fourcc: the fourcc code for this format, 0 if not applicable |
137 | * @color: the corresponding fimc_color_fmt | 135 | * @color: the corresponding fimc_color_fmt |
138 | * @depth: per plane driver's private 'number of bits per pixel' | ||
139 | * @memplanes: number of physically non-contiguous data planes | 136 | * @memplanes: number of physically non-contiguous data planes |
140 | * @colplanes: number of physically contiguous data planes | 137 | * @colplanes: number of physically contiguous data planes |
138 | * @depth: per plane driver's private 'number of bits per pixel' | ||
139 | * @flags: flags indicating which operation mode format applies to | ||
141 | */ | 140 | */ |
142 | struct fimc_fmt { | 141 | struct fimc_fmt { |
143 | enum v4l2_mbus_pixelcode mbus_code; | 142 | enum v4l2_mbus_pixelcode mbus_code; |
@@ -171,7 +170,7 @@ struct fimc_dma_offset { | |||
171 | }; | 170 | }; |
172 | 171 | ||
173 | /** | 172 | /** |
174 | * struct fimc_effect - the configuration data for the "Arbitrary" image effect | 173 | * struct fimc_effect - color effect information |
175 | * @type: effect type | 174 | * @type: effect type |
176 | * @pat_cb: cr value when type is "arbitrary" | 175 | * @pat_cb: cr value when type is "arbitrary" |
177 | * @pat_cr: cr value when type is "arbitrary" | 176 | * @pat_cr: cr value when type is "arbitrary" |
@@ -184,7 +183,6 @@ struct fimc_effect { | |||
184 | 183 | ||
185 | /** | 184 | /** |
186 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler | 185 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler |
187 | * | ||
188 | * @scaleup_h: flag indicating scaling up horizontally | 186 | * @scaleup_h: flag indicating scaling up horizontally |
189 | * @scaleup_v: flag indicating scaling up vertically | 187 | * @scaleup_v: flag indicating scaling up vertically |
190 | * @copy_mode: flag indicating transparent DMA transfer (no scaling | 188 | * @copy_mode: flag indicating transparent DMA transfer (no scaling |
@@ -220,7 +218,6 @@ struct fimc_scaler { | |||
220 | 218 | ||
221 | /** | 219 | /** |
222 | * struct fimc_addr - the FIMC physical address set for DMA | 220 | * struct fimc_addr - the FIMC physical address set for DMA |
223 | * | ||
224 | * @y: luminance plane physical address | 221 | * @y: luminance plane physical address |
225 | * @cb: Cb plane physical address | 222 | * @cb: Cb plane physical address |
226 | * @cr: Cr plane physical address | 223 | * @cr: Cr plane physical address |
@@ -234,6 +231,7 @@ struct fimc_addr { | |||
234 | /** | 231 | /** |
235 | * struct fimc_vid_buffer - the driver's video buffer | 232 | * struct fimc_vid_buffer - the driver's video buffer |
236 | * @vb: v4l videobuf buffer | 233 | * @vb: v4l videobuf buffer |
234 | * @list: linked list structure for buffer queue | ||
237 | * @paddr: precalculated physical address set | 235 | * @paddr: precalculated physical address set |
238 | * @index: buffer index for the output DMA engine | 236 | * @index: buffer index for the output DMA engine |
239 | */ | 237 | */ |
@@ -254,11 +252,10 @@ struct fimc_vid_buffer { | |||
254 | * @offs_v: image vertical pixel offset | 252 | * @offs_v: image vertical pixel offset |
255 | * @width: image pixel width | 253 | * @width: image pixel width |
256 | * @height: image pixel weight | 254 | * @height: image pixel weight |
257 | * @paddr: image frame buffer physical addresses | ||
258 | * @buf_cnt: number of buffers depending on a color format | ||
259 | * @payload: image size in bytes (w x h x bpp) | 255 | * @payload: image size in bytes (w x h x bpp) |
260 | * @color: color format | 256 | * @paddr: image frame buffer physical addresses |
261 | * @dma_offset: DMA offset in bytes | 257 | * @dma_offset: DMA offset in bytes |
258 | * @fmt: fimc color format pointer | ||
262 | */ | 259 | */ |
263 | struct fimc_frame { | 260 | struct fimc_frame { |
264 | u32 f_width; | 261 | u32 f_width; |
@@ -390,21 +387,22 @@ struct fimc_ctx; | |||
390 | 387 | ||
391 | /** | 388 | /** |
392 | * struct fimc_dev - abstraction for FIMC entity | 389 | * struct fimc_dev - abstraction for FIMC entity |
393 | * | ||
394 | * @slock: the spinlock protecting this data structure | 390 | * @slock: the spinlock protecting this data structure |
395 | * @lock: the mutex protecting this data structure | 391 | * @lock: the mutex protecting this data structure |
396 | * @pdev: pointer to the FIMC platform device | 392 | * @pdev: pointer to the FIMC platform device |
397 | * @pdata: pointer to the device platform data | 393 | * @pdata: pointer to the device platform data |
394 | * @variant: the IP variant information | ||
398 | * @id: FIMC device index (0..FIMC_MAX_DEVS) | 395 | * @id: FIMC device index (0..FIMC_MAX_DEVS) |
399 | * @num_clocks: the number of clocks managed by this device instance | 396 | * @num_clocks: the number of clocks managed by this device instance |
400 | * @clock[]: the clocks required for FIMC operation | 397 | * @clock: clocks required for FIMC operation |
401 | * @regs: the mapped hardware registers | 398 | * @regs: the mapped hardware registers |
402 | * @regs_res: the resource claimed for IO registers | 399 | * @regs_res: the resource claimed for IO registers |
403 | * @irq: interrupt number of the FIMC subdevice | 400 | * @irq: FIMC interrupt number |
404 | * @irq_queue: | 401 | * @irq_queue: interrupt handler waitqueue |
405 | * @m2m: memory-to-memory V4L2 device information | 402 | * @m2m: memory-to-memory V4L2 device information |
406 | * @vid_cap: camera capture device information | 403 | * @vid_cap: camera capture device information |
407 | * @state: flags used to synchronize m2m and capture mode operation | 404 | * @state: flags used to synchronize m2m and capture mode operation |
405 | * @alloc_ctx: videobuf2 memory allocator context | ||
408 | */ | 406 | */ |
409 | struct fimc_dev { | 407 | struct fimc_dev { |
410 | spinlock_t slock; | 408 | spinlock_t slock; |
@@ -427,8 +425,7 @@ struct fimc_dev { | |||
427 | 425 | ||
428 | /** | 426 | /** |
429 | * fimc_ctx - the device context data | 427 | * fimc_ctx - the device context data |
430 | * | 428 | * @slock: spinlock protecting this data structure |
431 | * @lock: mutex protecting this data structure | ||
432 | * @s_frame: source frame properties | 429 | * @s_frame: source frame properties |
433 | * @d_frame: destination frame properties | 430 | * @d_frame: destination frame properties |
434 | * @out_order_1p: output 1-plane YCBCR order | 431 | * @out_order_1p: output 1-plane YCBCR order |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ff6c0e97563e..d4ee24bf6928 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -963,7 +963,7 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | |||
963 | * to work with other protocols. | 963 | * to work with other protocols. |
964 | */ | 964 | */ |
965 | if (!ir->active) { | 965 | if (!ir->active) { |
966 | timeout = jiffies + jiffies_to_msecs(15); | 966 | timeout = jiffies + msecs_to_jiffies(15); |
967 | mod_timer(&ir->timer, timeout); | 967 | mod_timer(&ir->timer, timeout); |
968 | ir->active = true; | 968 | ir->active = true; |
969 | } | 969 | } |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 9363ed91a4cb..cfa9f7efe93d 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -724,19 +724,15 @@ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) | |||
724 | } | 724 | } |
725 | 725 | ||
726 | /** | 726 | /** |
727 | * set_mode_freq - Switch tuner to other mode. | 727 | * set_mode - Switch tuner to other mode. |
728 | * @client: struct i2c_client pointer | ||
729 | * @t: a pointer to the module's internal struct_tuner | 728 | * @t: a pointer to the module's internal struct_tuner |
730 | * @mode: enum v4l2_type (radio or TV) | 729 | * @mode: enum v4l2_type (radio or TV) |
731 | * @freq: frequency to set (0 means to use the previous one) | ||
732 | * | 730 | * |
733 | * If tuner doesn't support the needed mode (radio or TV), prints a | 731 | * If tuner doesn't support the needed mode (radio or TV), prints a |
734 | * debug message and returns -EINVAL, changing its state to standby. | 732 | * debug message and returns -EINVAL, changing its state to standby. |
735 | * Otherwise, changes the state and sets frequency to the last value, if | 733 | * Otherwise, changes the mode and returns 0. |
736 | * the tuner can sleep or if it supports both Radio and TV. | ||
737 | */ | 734 | */ |
738 | static int set_mode_freq(struct i2c_client *client, struct tuner *t, | 735 | static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) |
739 | enum v4l2_tuner_type mode, unsigned int freq) | ||
740 | { | 736 | { |
741 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 737 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
742 | 738 | ||
@@ -752,17 +748,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t, | |||
752 | t->mode = mode; | 748 | t->mode = mode; |
753 | tuner_dbg("Changing to mode %d\n", mode); | 749 | tuner_dbg("Changing to mode %d\n", mode); |
754 | } | 750 | } |
751 | return 0; | ||
752 | } | ||
753 | |||
754 | /** | ||
755 | * set_freq - Set the tuner to the desired frequency. | ||
756 | * @t: a pointer to the module's internal struct_tuner | ||
757 | * @freq: frequency to set (0 means to use the current frequency) | ||
758 | */ | ||
759 | static void set_freq(struct tuner *t, unsigned int freq) | ||
760 | { | ||
761 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
762 | |||
755 | if (t->mode == V4L2_TUNER_RADIO) { | 763 | if (t->mode == V4L2_TUNER_RADIO) { |
756 | if (freq) | 764 | if (!freq) |
757 | t->radio_freq = freq; | 765 | freq = t->radio_freq; |
758 | set_radio_freq(client, t->radio_freq); | 766 | set_radio_freq(client, freq); |
759 | } else { | 767 | } else { |
760 | if (freq) | 768 | if (!freq) |
761 | t->tv_freq = freq; | 769 | freq = t->tv_freq; |
762 | set_tv_freq(client, t->tv_freq); | 770 | set_tv_freq(client, freq); |
763 | } | 771 | } |
764 | |||
765 | return 0; | ||
766 | } | 772 | } |
767 | 773 | ||
768 | /* | 774 | /* |
@@ -817,7 +823,8 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
817 | /** | 823 | /** |
818 | * tuner_fixup_std - force a given video standard variant | 824 | * tuner_fixup_std - force a given video standard variant |
819 | * | 825 | * |
820 | * @t: tuner internal struct | 826 | * @t: tuner internal struct |
827 | * @std: TV standard | ||
821 | * | 828 | * |
822 | * A few devices or drivers have problem to detect some standard variations. | 829 | * A few devices or drivers have problem to detect some standard variations. |
823 | * On other operational systems, the drivers generally have a per-country | 830 | * On other operational systems, the drivers generally have a per-country |
@@ -827,57 +834,39 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
827 | * to distinguish all video standard variations, a modprobe parameter can | 834 | * to distinguish all video standard variations, a modprobe parameter can |
828 | * be used to force a video standard match. | 835 | * be used to force a video standard match. |
829 | */ | 836 | */ |
830 | static int tuner_fixup_std(struct tuner *t) | 837 | static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) |
831 | { | 838 | { |
832 | if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { | 839 | if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) { |
833 | switch (pal[0]) { | 840 | switch (pal[0]) { |
834 | case '6': | 841 | case '6': |
835 | tuner_dbg("insmod fixup: PAL => PAL-60\n"); | 842 | return V4L2_STD_PAL_60; |
836 | t->std = V4L2_STD_PAL_60; | ||
837 | break; | ||
838 | case 'b': | 843 | case 'b': |
839 | case 'B': | 844 | case 'B': |
840 | case 'g': | 845 | case 'g': |
841 | case 'G': | 846 | case 'G': |
842 | tuner_dbg("insmod fixup: PAL => PAL-BG\n"); | 847 | return V4L2_STD_PAL_BG; |
843 | t->std = V4L2_STD_PAL_BG; | ||
844 | break; | ||
845 | case 'i': | 848 | case 'i': |
846 | case 'I': | 849 | case 'I': |
847 | tuner_dbg("insmod fixup: PAL => PAL-I\n"); | 850 | return V4L2_STD_PAL_I; |
848 | t->std = V4L2_STD_PAL_I; | ||
849 | break; | ||
850 | case 'd': | 851 | case 'd': |
851 | case 'D': | 852 | case 'D': |
852 | case 'k': | 853 | case 'k': |
853 | case 'K': | 854 | case 'K': |
854 | tuner_dbg("insmod fixup: PAL => PAL-DK\n"); | 855 | return V4L2_STD_PAL_DK; |
855 | t->std = V4L2_STD_PAL_DK; | ||
856 | break; | ||
857 | case 'M': | 856 | case 'M': |
858 | case 'm': | 857 | case 'm': |
859 | tuner_dbg("insmod fixup: PAL => PAL-M\n"); | 858 | return V4L2_STD_PAL_M; |
860 | t->std = V4L2_STD_PAL_M; | ||
861 | break; | ||
862 | case 'N': | 859 | case 'N': |
863 | case 'n': | 860 | case 'n': |
864 | if (pal[1] == 'c' || pal[1] == 'C') { | 861 | if (pal[1] == 'c' || pal[1] == 'C') |
865 | tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); | 862 | return V4L2_STD_PAL_Nc; |
866 | t->std = V4L2_STD_PAL_Nc; | 863 | return V4L2_STD_PAL_N; |
867 | } else { | ||
868 | tuner_dbg("insmod fixup: PAL => PAL-N\n"); | ||
869 | t->std = V4L2_STD_PAL_N; | ||
870 | } | ||
871 | break; | ||
872 | case '-': | ||
873 | /* default parameter, do nothing */ | ||
874 | break; | ||
875 | default: | 864 | default: |
876 | tuner_warn("pal= argument not recognised\n"); | 865 | tuner_warn("pal= argument not recognised\n"); |
877 | break; | 866 | break; |
878 | } | 867 | } |
879 | } | 868 | } |
880 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | 869 | if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { |
881 | switch (secam[0]) { | 870 | switch (secam[0]) { |
882 | case 'b': | 871 | case 'b': |
883 | case 'B': | 872 | case 'B': |
@@ -885,63 +874,42 @@ static int tuner_fixup_std(struct tuner *t) | |||
885 | case 'G': | 874 | case 'G': |
886 | case 'h': | 875 | case 'h': |
887 | case 'H': | 876 | case 'H': |
888 | tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | 877 | return V4L2_STD_SECAM_B | |
889 | t->std = V4L2_STD_SECAM_B | | 878 | V4L2_STD_SECAM_G | |
890 | V4L2_STD_SECAM_G | | 879 | V4L2_STD_SECAM_H; |
891 | V4L2_STD_SECAM_H; | ||
892 | break; | ||
893 | case 'd': | 880 | case 'd': |
894 | case 'D': | 881 | case 'D': |
895 | case 'k': | 882 | case 'k': |
896 | case 'K': | 883 | case 'K': |
897 | tuner_dbg("insmod fixup: SECAM => SECAM-DK\n"); | 884 | return V4L2_STD_SECAM_DK; |
898 | t->std = V4L2_STD_SECAM_DK; | ||
899 | break; | ||
900 | case 'l': | 885 | case 'l': |
901 | case 'L': | 886 | case 'L': |
902 | if ((secam[1] == 'C') || (secam[1] == 'c')) { | 887 | if ((secam[1] == 'C') || (secam[1] == 'c')) |
903 | tuner_dbg("insmod fixup: SECAM => SECAM-L'\n"); | 888 | return V4L2_STD_SECAM_LC; |
904 | t->std = V4L2_STD_SECAM_LC; | 889 | return V4L2_STD_SECAM_L; |
905 | } else { | ||
906 | tuner_dbg("insmod fixup: SECAM => SECAM-L\n"); | ||
907 | t->std = V4L2_STD_SECAM_L; | ||
908 | } | ||
909 | break; | ||
910 | case '-': | ||
911 | /* default parameter, do nothing */ | ||
912 | break; | ||
913 | default: | 890 | default: |
914 | tuner_warn("secam= argument not recognised\n"); | 891 | tuner_warn("secam= argument not recognised\n"); |
915 | break; | 892 | break; |
916 | } | 893 | } |
917 | } | 894 | } |
918 | 895 | ||
919 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | 896 | if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { |
920 | switch (ntsc[0]) { | 897 | switch (ntsc[0]) { |
921 | case 'm': | 898 | case 'm': |
922 | case 'M': | 899 | case 'M': |
923 | tuner_dbg("insmod fixup: NTSC => NTSC-M\n"); | 900 | return V4L2_STD_NTSC_M; |
924 | t->std = V4L2_STD_NTSC_M; | ||
925 | break; | ||
926 | case 'j': | 901 | case 'j': |
927 | case 'J': | 902 | case 'J': |
928 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 903 | return V4L2_STD_NTSC_M_JP; |
929 | t->std = V4L2_STD_NTSC_M_JP; | ||
930 | break; | ||
931 | case 'k': | 904 | case 'k': |
932 | case 'K': | 905 | case 'K': |
933 | tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | 906 | return V4L2_STD_NTSC_M_KR; |
934 | t->std = V4L2_STD_NTSC_M_KR; | ||
935 | break; | ||
936 | case '-': | ||
937 | /* default parameter, do nothing */ | ||
938 | break; | ||
939 | default: | 907 | default: |
940 | tuner_info("ntsc= argument not recognised\n"); | 908 | tuner_info("ntsc= argument not recognised\n"); |
941 | break; | 909 | break; |
942 | } | 910 | } |
943 | } | 911 | } |
944 | return 0; | 912 | return std; |
945 | } | 913 | } |
946 | 914 | ||
947 | /* | 915 | /* |
@@ -1058,10 +1026,9 @@ static void tuner_status(struct dvb_frontend *fe) | |||
1058 | static int tuner_s_radio(struct v4l2_subdev *sd) | 1026 | static int tuner_s_radio(struct v4l2_subdev *sd) |
1059 | { | 1027 | { |
1060 | struct tuner *t = to_tuner(sd); | 1028 | struct tuner *t = to_tuner(sd); |
1061 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1062 | 1029 | ||
1063 | if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL) | 1030 | if (set_mode(t, V4L2_TUNER_RADIO) == 0) |
1064 | return 0; | 1031 | set_freq(t, 0); |
1065 | return 0; | 1032 | return 0; |
1066 | } | 1033 | } |
1067 | 1034 | ||
@@ -1072,16 +1039,20 @@ static int tuner_s_radio(struct v4l2_subdev *sd) | |||
1072 | /** | 1039 | /** |
1073 | * tuner_s_power - controls the power state of the tuner | 1040 | * tuner_s_power - controls the power state of the tuner |
1074 | * @sd: pointer to struct v4l2_subdev | 1041 | * @sd: pointer to struct v4l2_subdev |
1075 | * @on: a zero value puts the tuner to sleep | 1042 | * @on: a zero value puts the tuner to sleep, non-zero wakes it up |
1076 | */ | 1043 | */ |
1077 | static int tuner_s_power(struct v4l2_subdev *sd, int on) | 1044 | static int tuner_s_power(struct v4l2_subdev *sd, int on) |
1078 | { | 1045 | { |
1079 | struct tuner *t = to_tuner(sd); | 1046 | struct tuner *t = to_tuner(sd); |
1080 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 1047 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
1081 | 1048 | ||
1082 | /* FIXME: Why this function don't wake the tuner if on != 0 ? */ | 1049 | if (on) { |
1083 | if (on) | 1050 | if (t->standby && set_mode(t, t->mode) == 0) { |
1051 | tuner_dbg("Waking up tuner\n"); | ||
1052 | set_freq(t, 0); | ||
1053 | } | ||
1084 | return 0; | 1054 | return 0; |
1055 | } | ||
1085 | 1056 | ||
1086 | tuner_dbg("Putting tuner to sleep\n"); | 1057 | tuner_dbg("Putting tuner to sleep\n"); |
1087 | t->standby = true; | 1058 | t->standby = true; |
@@ -1093,28 +1064,36 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on) | |||
1093 | static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) | 1064 | static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) |
1094 | { | 1065 | { |
1095 | struct tuner *t = to_tuner(sd); | 1066 | struct tuner *t = to_tuner(sd); |
1096 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1097 | 1067 | ||
1098 | if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL) | 1068 | if (set_mode(t, V4L2_TUNER_ANALOG_TV)) |
1099 | return 0; | 1069 | return 0; |
1100 | 1070 | ||
1101 | t->std = std; | 1071 | t->std = tuner_fixup_std(t, std); |
1102 | tuner_fixup_std(t); | 1072 | if (t->std != std) |
1103 | 1073 | tuner_dbg("Fixup standard %llx to %llx\n", std, t->std); | |
1074 | set_freq(t, 0); | ||
1104 | return 0; | 1075 | return 0; |
1105 | } | 1076 | } |
1106 | 1077 | ||
1107 | static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | 1078 | static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) |
1108 | { | 1079 | { |
1109 | struct tuner *t = to_tuner(sd); | 1080 | struct tuner *t = to_tuner(sd); |
1110 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1111 | |||
1112 | if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL) | ||
1113 | return 0; | ||
1114 | 1081 | ||
1082 | if (set_mode(t, f->type) == 0) | ||
1083 | set_freq(t, f->frequency); | ||
1115 | return 0; | 1084 | return 0; |
1116 | } | 1085 | } |
1117 | 1086 | ||
1087 | /** | ||
1088 | * tuner_g_frequency - Get the tuned frequency for the tuner | ||
1089 | * @sd: pointer to struct v4l2_subdev | ||
1090 | * @f: pointer to struct v4l2_frequency | ||
1091 | * | ||
1092 | * At return, the structure f will be filled with tuner frequency | ||
1093 | * if the tuner matches the f->type. | ||
1094 | * Note: f->type should be initialized before calling it. | ||
1095 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1096 | */ | ||
1118 | static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | 1097 | static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) |
1119 | { | 1098 | { |
1120 | struct tuner *t = to_tuner(sd); | 1099 | struct tuner *t = to_tuner(sd); |
@@ -1122,8 +1101,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
1122 | 1101 | ||
1123 | if (check_mode(t, f->type) == -EINVAL) | 1102 | if (check_mode(t, f->type) == -EINVAL) |
1124 | return 0; | 1103 | return 0; |
1125 | f->type = t->mode; | 1104 | if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) { |
1126 | if (fe_tuner_ops->get_frequency && !t->standby) { | ||
1127 | u32 abs_freq; | 1105 | u32 abs_freq; |
1128 | 1106 | ||
1129 | fe_tuner_ops->get_frequency(&t->fe, &abs_freq); | 1107 | fe_tuner_ops->get_frequency(&t->fe, &abs_freq); |
@@ -1131,12 +1109,22 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
1131 | DIV_ROUND_CLOSEST(abs_freq * 2, 125) : | 1109 | DIV_ROUND_CLOSEST(abs_freq * 2, 125) : |
1132 | DIV_ROUND_CLOSEST(abs_freq, 62500); | 1110 | DIV_ROUND_CLOSEST(abs_freq, 62500); |
1133 | } else { | 1111 | } else { |
1134 | f->frequency = (V4L2_TUNER_RADIO == t->mode) ? | 1112 | f->frequency = (V4L2_TUNER_RADIO == f->type) ? |
1135 | t->radio_freq : t->tv_freq; | 1113 | t->radio_freq : t->tv_freq; |
1136 | } | 1114 | } |
1137 | return 0; | 1115 | return 0; |
1138 | } | 1116 | } |
1139 | 1117 | ||
1118 | /** | ||
1119 | * tuner_g_tuner - Fill in tuner information | ||
1120 | * @sd: pointer to struct v4l2_subdev | ||
1121 | * @vt: pointer to struct v4l2_tuner | ||
1122 | * | ||
1123 | * At return, the structure vt will be filled with tuner information | ||
1124 | * if the tuner matches vt->type. | ||
1125 | * Note: vt->type should be initialized before calling it. | ||
1126 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1127 | */ | ||
1140 | static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | 1128 | static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
1141 | { | 1129 | { |
1142 | struct tuner *t = to_tuner(sd); | 1130 | struct tuner *t = to_tuner(sd); |
@@ -1145,48 +1133,58 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
1145 | 1133 | ||
1146 | if (check_mode(t, vt->type) == -EINVAL) | 1134 | if (check_mode(t, vt->type) == -EINVAL) |
1147 | return 0; | 1135 | return 0; |
1148 | vt->type = t->mode; | 1136 | if (vt->type == t->mode && analog_ops->get_afc) |
1149 | if (analog_ops->get_afc) | ||
1150 | vt->afc = analog_ops->get_afc(&t->fe); | 1137 | vt->afc = analog_ops->get_afc(&t->fe); |
1151 | if (t->mode == V4L2_TUNER_ANALOG_TV) | 1138 | if (vt->type == V4L2_TUNER_ANALOG_TV) |
1152 | vt->capability |= V4L2_TUNER_CAP_NORM; | 1139 | vt->capability |= V4L2_TUNER_CAP_NORM; |
1153 | if (t->mode != V4L2_TUNER_RADIO) { | 1140 | if (vt->type != V4L2_TUNER_RADIO) { |
1154 | vt->rangelow = tv_range[0] * 16; | 1141 | vt->rangelow = tv_range[0] * 16; |
1155 | vt->rangehigh = tv_range[1] * 16; | 1142 | vt->rangehigh = tv_range[1] * 16; |
1156 | return 0; | 1143 | return 0; |
1157 | } | 1144 | } |
1158 | 1145 | ||
1159 | /* radio mode */ | 1146 | /* radio mode */ |
1160 | vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 1147 | if (vt->type == t->mode) { |
1161 | if (fe_tuner_ops->get_status) { | 1148 | vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
1162 | u32 tuner_status; | 1149 | if (fe_tuner_ops->get_status) { |
1163 | 1150 | u32 tuner_status; | |
1164 | fe_tuner_ops->get_status(&t->fe, &tuner_status); | 1151 | |
1165 | vt->rxsubchans = | 1152 | fe_tuner_ops->get_status(&t->fe, &tuner_status); |
1166 | (tuner_status & TUNER_STATUS_STEREO) ? | 1153 | vt->rxsubchans = |
1167 | V4L2_TUNER_SUB_STEREO : | 1154 | (tuner_status & TUNER_STATUS_STEREO) ? |
1168 | V4L2_TUNER_SUB_MONO; | 1155 | V4L2_TUNER_SUB_STEREO : |
1156 | V4L2_TUNER_SUB_MONO; | ||
1157 | } | ||
1158 | if (analog_ops->has_signal) | ||
1159 | vt->signal = analog_ops->has_signal(&t->fe); | ||
1160 | vt->audmode = t->audmode; | ||
1169 | } | 1161 | } |
1170 | if (analog_ops->has_signal) | ||
1171 | vt->signal = analog_ops->has_signal(&t->fe); | ||
1172 | vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | 1162 | vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; |
1173 | vt->audmode = t->audmode; | ||
1174 | vt->rangelow = radio_range[0] * 16000; | 1163 | vt->rangelow = radio_range[0] * 16000; |
1175 | vt->rangehigh = radio_range[1] * 16000; | 1164 | vt->rangehigh = radio_range[1] * 16000; |
1176 | 1165 | ||
1177 | return 0; | 1166 | return 0; |
1178 | } | 1167 | } |
1179 | 1168 | ||
1169 | /** | ||
1170 | * tuner_s_tuner - Set the tuner's audio mode | ||
1171 | * @sd: pointer to struct v4l2_subdev | ||
1172 | * @vt: pointer to struct v4l2_tuner | ||
1173 | * | ||
1174 | * Sets the audio mode if the tuner matches vt->type. | ||
1175 | * Note: vt->type should be initialized before calling it. | ||
1176 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1177 | */ | ||
1180 | static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | 1178 | static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
1181 | { | 1179 | { |
1182 | struct tuner *t = to_tuner(sd); | 1180 | struct tuner *t = to_tuner(sd); |
1183 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1184 | 1181 | ||
1185 | if (set_mode_freq(client, t, vt->type, 0) == -EINVAL) | 1182 | if (set_mode(t, vt->type)) |
1186 | return 0; | 1183 | return 0; |
1187 | 1184 | ||
1188 | if (t->mode == V4L2_TUNER_RADIO) | 1185 | if (t->mode == V4L2_TUNER_RADIO) |
1189 | t->audmode = vt->audmode; | 1186 | t->audmode = vt->audmode; |
1187 | set_freq(t, 0); | ||
1190 | 1188 | ||
1191 | return 0; | 1189 | return 0; |
1192 | } | 1190 | } |
@@ -1221,7 +1219,8 @@ static int tuner_resume(struct i2c_client *c) | |||
1221 | tuner_dbg("resume\n"); | 1219 | tuner_dbg("resume\n"); |
1222 | 1220 | ||
1223 | if (!t->standby) | 1221 | if (!t->standby) |
1224 | set_mode_freq(c, t, t->type, 0); | 1222 | if (set_mode(t, t->mode) == 0) |
1223 | set_freq(t, 0); | ||
1225 | 1224 | ||
1226 | return 0; | 1225 | return 0; |
1227 | } | 1226 | } |
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c index c3ab0c813be2..48fea373c25a 100644 --- a/drivers/media/video/uvc/uvc_entity.c +++ b/drivers/media/video/uvc/uvc_entity.c | |||
@@ -27,14 +27,20 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
27 | struct uvc_entity *entity) | 27 | struct uvc_entity *entity) |
28 | { | 28 | { |
29 | const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; | 29 | const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; |
30 | struct uvc_entity *remote; | 30 | struct media_entity *sink; |
31 | unsigned int i; | 31 | unsigned int i; |
32 | u8 remote_pad; | 32 | int ret; |
33 | int ret = 0; | 33 | |
34 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) | ||
35 | ? (entity->vdev ? &entity->vdev->entity : NULL) | ||
36 | : &entity->subdev.entity; | ||
37 | if (sink == NULL) | ||
38 | return 0; | ||
34 | 39 | ||
35 | for (i = 0; i < entity->num_pads; ++i) { | 40 | for (i = 0; i < entity->num_pads; ++i) { |
36 | struct media_entity *source; | 41 | struct media_entity *source; |
37 | struct media_entity *sink; | 42 | struct uvc_entity *remote; |
43 | u8 remote_pad; | ||
38 | 44 | ||
39 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) | 45 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) |
40 | continue; | 46 | continue; |
@@ -43,10 +49,11 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
43 | if (remote == NULL) | 49 | if (remote == NULL) |
44 | return -EINVAL; | 50 | return -EINVAL; |
45 | 51 | ||
46 | source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) | 52 | source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING) |
47 | ? &remote->vdev->entity : &remote->subdev.entity; | 53 | ? (remote->vdev ? &remote->vdev->entity : NULL) |
48 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) | 54 | : &remote->subdev.entity; |
49 | ? &entity->vdev->entity : &entity->subdev.entity; | 55 | if (source == NULL) |
56 | continue; | ||
50 | 57 | ||
51 | remote_pad = remote->num_pads - 1; | 58 | remote_pad = remote->num_pads - 1; |
52 | ret = media_entity_create_link(source, remote_pad, | 59 | ret = media_entity_create_link(source, remote_pad, |
@@ -55,11 +62,10 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
55 | return ret; | 62 | return ret; |
56 | } | 63 | } |
57 | 64 | ||
58 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) | 65 | if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) |
59 | ret = v4l2_device_register_subdev(&chain->dev->vdev, | 66 | return 0; |
60 | &entity->subdev); | ||
61 | 67 | ||
62 | return ret; | 68 | return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); |
63 | } | 69 | } |
64 | 70 | ||
65 | static struct v4l2_subdev_ops uvc_subdev_ops = { | 71 | static struct v4l2_subdev_ops uvc_subdev_ops = { |
@@ -84,9 +90,11 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) | |||
84 | 90 | ||
85 | ret = media_entity_init(&entity->subdev.entity, | 91 | ret = media_entity_init(&entity->subdev.entity, |
86 | entity->num_pads, entity->pads, 0); | 92 | entity->num_pads, entity->pads, 0); |
87 | } else | 93 | } else if (entity->vdev != NULL) { |
88 | ret = media_entity_init(&entity->vdev->entity, | 94 | ret = media_entity_init(&entity->vdev->entity, |
89 | entity->num_pads, entity->pads, 0); | 95 | entity->num_pads, entity->pads, 0); |
96 | } else | ||
97 | ret = 0; | ||
90 | 98 | ||
91 | return ret; | 99 | return ret; |
92 | } | 100 | } |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 109a06384a8f..f90ce9fce539 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -104,6 +104,8 @@ static int __uvc_free_buffers(struct uvc_video_queue *queue) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | if (queue->count) { | 106 | if (queue->count) { |
107 | uvc_queue_cancel(queue, 0); | ||
108 | INIT_LIST_HEAD(&queue->mainqueue); | ||
107 | vfree(queue->mem); | 109 | vfree(queue->mem); |
108 | queue->count = 0; | 110 | queue->count = 0; |
109 | } | 111 | } |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index fc766b9f24c5..49994793cc77 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -1255,8 +1255,10 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) | |||
1255 | 1255 | ||
1256 | /* Commit the streaming parameters. */ | 1256 | /* Commit the streaming parameters. */ |
1257 | ret = uvc_commit_video(stream, &stream->ctrl); | 1257 | ret = uvc_commit_video(stream, &stream->ctrl); |
1258 | if (ret < 0) | 1258 | if (ret < 0) { |
1259 | uvc_queue_enable(&stream->queue, 0); | ||
1259 | return ret; | 1260 | return ret; |
1261 | } | ||
1260 | 1262 | ||
1261 | return uvc_init_video(stream, GFP_KERNEL); | 1263 | return uvc_init_video(stream, GFP_KERNEL); |
1262 | } | 1264 | } |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 19d5ae293780..06f14008b346 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -167,6 +167,12 @@ static void v4l2_device_release(struct device *cd) | |||
167 | 167 | ||
168 | mutex_unlock(&videodev_lock); | 168 | mutex_unlock(&videodev_lock); |
169 | 169 | ||
170 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
171 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
172 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
173 | media_device_unregister_entity(&vdev->entity); | ||
174 | #endif | ||
175 | |||
170 | /* Release video_device and perform other | 176 | /* Release video_device and perform other |
171 | cleanups as needed. */ | 177 | cleanups as needed. */ |
172 | vdev->release(vdev); | 178 | vdev->release(vdev); |
@@ -389,9 +395,6 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
389 | static int v4l2_open(struct inode *inode, struct file *filp) | 395 | static int v4l2_open(struct inode *inode, struct file *filp) |
390 | { | 396 | { |
391 | struct video_device *vdev; | 397 | struct video_device *vdev; |
392 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
393 | struct media_entity *entity = NULL; | ||
394 | #endif | ||
395 | int ret = 0; | 398 | int ret = 0; |
396 | 399 | ||
397 | /* Check if the video device is available */ | 400 | /* Check if the video device is available */ |
@@ -405,17 +408,6 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
405 | /* and increase the device refcount */ | 408 | /* and increase the device refcount */ |
406 | video_get(vdev); | 409 | video_get(vdev); |
407 | mutex_unlock(&videodev_lock); | 410 | mutex_unlock(&videodev_lock); |
408 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
409 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
410 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | ||
411 | entity = media_entity_get(&vdev->entity); | ||
412 | if (!entity) { | ||
413 | ret = -EBUSY; | ||
414 | video_put(vdev); | ||
415 | return ret; | ||
416 | } | ||
417 | } | ||
418 | #endif | ||
419 | if (vdev->fops->open) { | 411 | if (vdev->fops->open) { |
420 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { | 412 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
421 | ret = -ERESTARTSYS; | 413 | ret = -ERESTARTSYS; |
@@ -431,14 +423,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
431 | 423 | ||
432 | err: | 424 | err: |
433 | /* decrease the refcount in case of an error */ | 425 | /* decrease the refcount in case of an error */ |
434 | if (ret) { | 426 | if (ret) |
435 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
436 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
437 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
438 | media_entity_put(entity); | ||
439 | #endif | ||
440 | video_put(vdev); | 427 | video_put(vdev); |
441 | } | ||
442 | return ret; | 428 | return ret; |
443 | } | 429 | } |
444 | 430 | ||
@@ -455,11 +441,6 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
455 | if (vdev->lock) | 441 | if (vdev->lock) |
456 | mutex_unlock(vdev->lock); | 442 | mutex_unlock(vdev->lock); |
457 | } | 443 | } |
458 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
459 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
460 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
461 | media_entity_put(&vdev->entity); | ||
462 | #endif | ||
463 | /* decrease the refcount unconditionally since the release() | 444 | /* decrease the refcount unconditionally since the release() |
464 | return value is ignored. */ | 445 | return value is ignored. */ |
465 | video_put(vdev); | 446 | video_put(vdev); |
@@ -754,12 +735,6 @@ void video_unregister_device(struct video_device *vdev) | |||
754 | if (!vdev || !video_is_registered(vdev)) | 735 | if (!vdev || !video_is_registered(vdev)) |
755 | return; | 736 | return; |
756 | 737 | ||
757 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
758 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
759 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
760 | media_device_unregister_entity(&vdev->entity); | ||
761 | #endif | ||
762 | |||
763 | mutex_lock(&videodev_lock); | 738 | mutex_lock(&videodev_lock); |
764 | /* This must be in a critical section to prevent a race with v4l2_open. | 739 | /* This must be in a critical section to prevent a race with v4l2_open. |
765 | * Once this bit has been cleared video_get may never be called again. | 740 | * Once this bit has been cleared video_get may never be called again. |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 506edcc2ddeb..69e8c6ffcc49 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file, | |||
1822 | if (!ops->vidioc_g_tuner) | 1822 | if (!ops->vidioc_g_tuner) |
1823 | break; | 1823 | break; |
1824 | 1824 | ||
1825 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1826 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1825 | ret = ops->vidioc_g_tuner(file, fh, p); | 1827 | ret = ops->vidioc_g_tuner(file, fh, p); |
1826 | if (!ret) | 1828 | if (!ret) |
1827 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1829 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file, | |||
1840 | 1842 | ||
1841 | if (!ops->vidioc_s_tuner) | 1843 | if (!ops->vidioc_s_tuner) |
1842 | break; | 1844 | break; |
1845 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1846 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1843 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1847 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
1844 | "capability=0x%x, rangelow=%d, " | 1848 | "capability=0x%x, rangelow=%d, " |
1845 | "rangehigh=%d, signal=%d, afc=%d, " | 1849 | "rangehigh=%d, signal=%d, afc=%d, " |
@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file, | |||
1858 | if (!ops->vidioc_g_frequency) | 1862 | if (!ops->vidioc_g_frequency) |
1859 | break; | 1863 | break; |
1860 | 1864 | ||
1865 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1866 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1861 | ret = ops->vidioc_g_frequency(file, fh, p); | 1867 | ret = ops->vidioc_g_frequency(file, fh, p); |
1862 | if (!ret) | 1868 | if (!ret) |
1863 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1869 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
@@ -1940,13 +1946,19 @@ static long __video_do_ioctl(struct file *file, | |||
1940 | case VIDIOC_S_HW_FREQ_SEEK: | 1946 | case VIDIOC_S_HW_FREQ_SEEK: |
1941 | { | 1947 | { |
1942 | struct v4l2_hw_freq_seek *p = arg; | 1948 | struct v4l2_hw_freq_seek *p = arg; |
1949 | enum v4l2_tuner_type type; | ||
1943 | 1950 | ||
1944 | if (!ops->vidioc_s_hw_freq_seek) | 1951 | if (!ops->vidioc_s_hw_freq_seek) |
1945 | break; | 1952 | break; |
1953 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1954 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1946 | dbgarg(cmd, | 1955 | dbgarg(cmd, |
1947 | "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", | 1956 | "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", |
1948 | p->tuner, p->type, p->seek_upward, p->wrap_around); | 1957 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); |
1949 | ret = ops->vidioc_s_hw_freq_seek(file, fh, p); | 1958 | if (p->type != type) |
1959 | ret = -EINVAL; | ||
1960 | else | ||
1961 | ret = ops->vidioc_s_hw_freq_seek(file, fh, p); | ||
1950 | break; | 1962 | break; |
1951 | } | 1963 | } |
1952 | case VIDIOC_ENUM_FRAMESIZES: | 1964 | case VIDIOC_ENUM_FRAMESIZES: |
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 6ba1461d51ef..3015e6000946 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
@@ -492,13 +492,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
492 | return -EINVAL; | 492 | return -EINVAL; |
493 | } | 493 | } |
494 | 494 | ||
495 | /* | ||
496 | * If the same number of buffers and memory access method is requested | ||
497 | * then return immediately. | ||
498 | */ | ||
499 | if (q->memory == req->memory && req->count == q->num_buffers) | ||
500 | return 0; | ||
501 | |||
502 | if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) { | 495 | if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) { |
503 | /* | 496 | /* |
504 | * We already have buffers allocated, so first check if they | 497 | * We already have buffers allocated, so first check if they |
@@ -539,9 +532,9 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
539 | /* Finally, allocate buffers and video memory */ | 532 | /* Finally, allocate buffers and video memory */ |
540 | ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes, | 533 | ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes, |
541 | plane_sizes); | 534 | plane_sizes); |
542 | if (ret < 0) { | 535 | if (ret == 0) { |
543 | dprintk(1, "Memory allocation failed with error: %d\n", ret); | 536 | dprintk(1, "Memory allocation failed\n"); |
544 | return ret; | 537 | return -ENOMEM; |
545 | } | 538 | } |
546 | 539 | ||
547 | /* | 540 | /* |
@@ -1196,6 +1189,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
1196 | * has not already dequeued before initiating cancel. | 1189 | * has not already dequeued before initiating cancel. |
1197 | */ | 1190 | */ |
1198 | INIT_LIST_HEAD(&q->done_list); | 1191 | INIT_LIST_HEAD(&q->done_list); |
1192 | atomic_set(&q->queued_count, 0); | ||
1199 | wake_up_all(&q->done_wq); | 1193 | wake_up_all(&q->done_wq); |
1200 | 1194 | ||
1201 | /* | 1195 | /* |
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/video/videobuf2-dma-sg.c index b2d9485aac75..10a20d9509d9 100644 --- a/drivers/media/video/videobuf2-dma-sg.c +++ b/drivers/media/video/videobuf2-dma-sg.c | |||
@@ -62,7 +62,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size) | |||
62 | goto fail_pages_array_alloc; | 62 | goto fail_pages_array_alloc; |
63 | 63 | ||
64 | for (i = 0; i < buf->sg_desc.num_pages; ++i) { | 64 | for (i = 0; i < buf->sg_desc.num_pages; ++i) { |
65 | buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); | 65 | buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN); |
66 | if (NULL == buf->pages[i]) | 66 | if (NULL == buf->pages[i]) |
67 | goto fail_pages_alloc; | 67 | goto fail_pages_alloc; |
68 | sg_set_page(&buf->sg_desc.sglist[i], | 68 | sg_set_page(&buf->sg_desc.sglist[i], |