diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-18 18:08:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-18 18:08:02 -0500 |
commit | a310410f616c78f24490de1274487a7b7b137d97 (patch) | |
tree | dbc2fc187800e6e7014263bf83e10d0155620029 /drivers | |
parent | cdd278db0e3dd714e8076e58f723f3c59547591b (diff) | |
parent | 80f93c7b0f4599ffbdac8d964ecd1162b8b618b9 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
"This series include:
- a new Remote Controller driver for ST SoC with the corresponding DT
bindings
- a new frontend (cx24117)
- a new I2C camera flash driver (lm3560)
- a new mem2mem driver for TI SoC (ti-vpe)
- support for Raphael r828d added to r820t driver
- some improvements on buffer allocation at VB2 core
- usual driver fixes and improvements
PS this time, we have a smaller number of patches. While it is hard
to pinpoint to the reasons, I believe that it is mainly due to:
1) there are several patch series ready, but depending on DT review.
I decided to grant some extra time for DT maintainers to look on
it, as they're expecting to have more time with the changes agreed
during ARM mini-summit and KS. If they can't review in time for
3.14, I'll review myself and apply for the next merge window.
2) I suspect that having both LinuxCon EU and LinuxCon NA happening
during the same merge window affected the development
productivity, as several core media developers participated on
both events"
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (151 commits)
[media] media: st-rc: Add ST remote control driver
[media] gpio-ir-recv: Include linux/of.h header
[media] tvp7002: Include linux/of.h header
[media] tvp514x: Include linux/of.h header
[media] ths8200: Include linux/of.h header
[media] adv7343: Include linux/of.h header
[media] v4l: Fix typo in v4l2_subdev_get_try_crop()
[media] media: i2c: add driver for dual LED Flash, lm3560
[media] rtl28xxu: add 15f4:0131 Astrometa DVB-T2
[media] rtl28xxu: add RTL2832P + R828D support
[media] rtl2832: add new tuner R828D
[media] r820t: add support for R828D
[media] media/i2c: ths8200: fix build failure with gcc 4.5.4
[media] Add support for KWorld UB435-Q V2
[media] staging/media: fix msi3101 build errors
[media] ddbridge: Remove casting the return value which is a void pointer
[media] ngene: Remove casting the return value which is a void pointer
[media] dm1105: remove unneeded not-null test
[media] sh_mobile_ceu_camera: remove deprecated IRQF_DISABLED
[media] media: rcar_vin: Add preliminary r8a7790 support
...
Diffstat (limited to 'drivers')
170 files changed, 8680 insertions, 930 deletions
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c index f2199e43e803..185c285f70fc 100644 --- a/drivers/media/common/b2c2/flexcop-sram.c +++ b/drivers/media/common/b2c2/flexcop-sram.c | |||
@@ -85,7 +85,7 @@ static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 * | |||
85 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | 85 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { |
86 | mdelay(1); | 86 | mdelay(1); |
87 | retries--; | 87 | retries--; |
88 | }; | 88 | } |
89 | 89 | ||
90 | if (retries == 0) | 90 | if (retries == 0) |
91 | printk("%s: SRAM timeout\n", __func__); | 91 | printk("%s: SRAM timeout\n", __func__); |
@@ -110,7 +110,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, | |||
110 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | 110 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { |
111 | mdelay(1); | 111 | mdelay(1); |
112 | retries--; | 112 | retries--; |
113 | }; | 113 | } |
114 | 114 | ||
115 | if (retries == 0) | 115 | if (retries == 0) |
116 | printk("%s: SRAM timeout\n", __func__); | 116 | printk("%s: SRAM timeout\n", __func__); |
@@ -122,7 +122,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, | |||
122 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | 122 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { |
123 | mdelay(1); | 123 | mdelay(1); |
124 | retries--; | 124 | retries--; |
125 | }; | 125 | } |
126 | 126 | ||
127 | if (retries == 0) | 127 | if (retries == 0) |
128 | printk("%s: SRAM timeout\n", __func__); | 128 | printk("%s: SRAM timeout\n", __func__); |
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c index bb6ee5191eb1..34b0d0ddeef3 100644 --- a/drivers/media/common/saa7146/saa7146_core.c +++ b/drivers/media/common/saa7146/saa7146_core.c | |||
@@ -411,7 +411,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent | |||
411 | saa7146_write(dev, MC2, 0xf8000000); | 411 | saa7146_write(dev, MC2, 0xf8000000); |
412 | 412 | ||
413 | /* request an interrupt for the saa7146 */ | 413 | /* request an interrupt for the saa7146 */ |
414 | err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED, | 414 | err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED, |
415 | dev->name, dev); | 415 | dev->name, dev); |
416 | if (err < 0) { | 416 | if (err < 0) { |
417 | ERR("request_irq() failed\n"); | 417 | ERR("request_irq() failed\n"); |
@@ -524,8 +524,6 @@ static void saa7146_remove_one(struct pci_dev *pdev) | |||
524 | DEB_EE("dev:%p\n", dev); | 524 | DEB_EE("dev:%p\n", dev); |
525 | 525 | ||
526 | dev->ext->detach(dev); | 526 | dev->ext->detach(dev); |
527 | /* Zero the PCI drvdata after use. */ | ||
528 | pci_set_drvdata(pdev, NULL); | ||
529 | 527 | ||
530 | /* shut down all video dma transfers */ | 528 | /* shut down all video dma transfers */ |
531 | saa7146_write(dev, MC1, 0x00ff0000); | 529 | saa7146_write(dev, MC1, 0x00ff0000); |
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index a142f7942a01..050984c5b1e3 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c | |||
@@ -922,8 +922,8 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
922 | u32 i, *ptr; | 922 | u32 i, *ptr; |
923 | u8 *payload = firmware->payload; | 923 | u8 *payload = firmware->payload; |
924 | int rc = 0; | 924 | int rc = 0; |
925 | firmware->start_address = le32_to_cpu(firmware->start_address); | 925 | firmware->start_address = le32_to_cpup((__le32 *)&firmware->start_address); |
926 | firmware->length = le32_to_cpu(firmware->length); | 926 | firmware->length = le32_to_cpup((__le32 *)&firmware->length); |
927 | 927 | ||
928 | mem_address = firmware->start_address; | 928 | mem_address = firmware->start_address; |
929 | 929 | ||
@@ -982,7 +982,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
982 | if (rc < 0) | 982 | if (rc < 0) |
983 | goto exit_fw_download; | 983 | goto exit_fw_download; |
984 | 984 | ||
985 | sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", | 985 | sms_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", |
986 | calc_checksum); | 986 | calc_checksum); |
987 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ, | 987 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ, |
988 | sizeof(msg->x_msg_header) + | 988 | sizeof(msg->x_msg_header) + |
@@ -1562,7 +1562,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1562 | { | 1562 | { |
1563 | struct sms_msg_data *validity = (struct sms_msg_data *) phdr; | 1563 | struct sms_msg_data *validity = (struct sms_msg_data *) phdr; |
1564 | 1564 | ||
1565 | sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", | 1565 | sms_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", |
1566 | validity->msg_data[0]); | 1566 | validity->msg_data[0]); |
1567 | complete(&coredev->data_validity_done); | 1567 | complete(&coredev->data_validity_done); |
1568 | break; | 1568 | break; |
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 63676a8b024c..85151efdd94c 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c | |||
@@ -44,14 +44,14 @@ module_param_named(debug, sms_dbg, int, 0644); | |||
44 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | 44 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); |
45 | 45 | ||
46 | 46 | ||
47 | u32 sms_to_guard_interval_table[] = { | 47 | static u32 sms_to_guard_interval_table[] = { |
48 | [0] = GUARD_INTERVAL_1_32, | 48 | [0] = GUARD_INTERVAL_1_32, |
49 | [1] = GUARD_INTERVAL_1_16, | 49 | [1] = GUARD_INTERVAL_1_16, |
50 | [2] = GUARD_INTERVAL_1_8, | 50 | [2] = GUARD_INTERVAL_1_8, |
51 | [3] = GUARD_INTERVAL_1_4, | 51 | [3] = GUARD_INTERVAL_1_4, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | u32 sms_to_code_rate_table[] = { | 54 | static u32 sms_to_code_rate_table[] = { |
55 | [0] = FEC_1_2, | 55 | [0] = FEC_1_2, |
56 | [1] = FEC_2_3, | 56 | [1] = FEC_2_3, |
57 | [2] = FEC_3_4, | 57 | [2] = FEC_3_4, |
@@ -60,14 +60,14 @@ u32 sms_to_code_rate_table[] = { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | 62 | ||
63 | u32 sms_to_hierarchy_table[] = { | 63 | static u32 sms_to_hierarchy_table[] = { |
64 | [0] = HIERARCHY_NONE, | 64 | [0] = HIERARCHY_NONE, |
65 | [1] = HIERARCHY_1, | 65 | [1] = HIERARCHY_1, |
66 | [2] = HIERARCHY_2, | 66 | [2] = HIERARCHY_2, |
67 | [3] = HIERARCHY_4, | 67 | [3] = HIERARCHY_4, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | u32 sms_to_modulation_table[] = { | 70 | static u32 sms_to_modulation_table[] = { |
71 | [0] = QPSK, | 71 | [0] = QPSK, |
72 | [1] = QAM_16, | 72 | [1] = QAM_16, |
73 | [2] = QAM_64, | 73 | [2] = QAM_64, |
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 3485655fa082..58de4410c525 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c | |||
@@ -476,7 +476,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
476 | void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, | 476 | void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, |
477 | size_t count) | 477 | size_t count) |
478 | { | 478 | { |
479 | spin_lock(&demux->lock); | 479 | unsigned long flags; |
480 | |||
481 | spin_lock_irqsave(&demux->lock, flags); | ||
480 | 482 | ||
481 | while (count--) { | 483 | while (count--) { |
482 | if (buf[0] == 0x47) | 484 | if (buf[0] == 0x47) |
@@ -484,7 +486,7 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, | |||
484 | buf += 188; | 486 | buf += 188; |
485 | } | 487 | } |
486 | 488 | ||
487 | spin_unlock(&demux->lock); | 489 | spin_unlock_irqrestore(&demux->lock, flags); |
488 | } | 490 | } |
489 | 491 | ||
490 | EXPORT_SYMBOL(dvb_dmx_swfilter_packets); | 492 | EXPORT_SYMBOL(dvb_dmx_swfilter_packets); |
@@ -519,8 +521,9 @@ static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, | |||
519 | { | 521 | { |
520 | int p = 0, i, j; | 522 | int p = 0, i, j; |
521 | const u8 *q; | 523 | const u8 *q; |
524 | unsigned long flags; | ||
522 | 525 | ||
523 | spin_lock(&demux->lock); | 526 | spin_lock_irqsave(&demux->lock, flags); |
524 | 527 | ||
525 | if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */ | 528 | if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */ |
526 | i = demux->tsbufp; | 529 | i = demux->tsbufp; |
@@ -564,7 +567,7 @@ static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, | |||
564 | } | 567 | } |
565 | 568 | ||
566 | bailout: | 569 | bailout: |
567 | spin_unlock(&demux->lock); | 570 | spin_unlock_irqrestore(&demux->lock, flags); |
568 | } | 571 | } |
569 | 572 | ||
570 | void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) | 573 | void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) |
@@ -581,11 +584,13 @@ EXPORT_SYMBOL(dvb_dmx_swfilter_204); | |||
581 | 584 | ||
582 | void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) | 585 | void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) |
583 | { | 586 | { |
584 | spin_lock(&demux->lock); | 587 | unsigned long flags; |
588 | |||
589 | spin_lock_irqsave(&demux->lock, flags); | ||
585 | 590 | ||
586 | demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK); | 591 | demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK); |
587 | 592 | ||
588 | spin_unlock(&demux->lock); | 593 | spin_unlock_irqrestore(&demux->lock, flags); |
589 | } | 594 | } |
590 | EXPORT_SYMBOL(dvb_dmx_swfilter_raw); | 595 | EXPORT_SYMBOL(dvb_dmx_swfilter_raw); |
591 | 596 | ||
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 0e2ec6f73b05..bddbab43a2df 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig | |||
@@ -200,6 +200,13 @@ config DVB_CX24116 | |||
200 | help | 200 | help |
201 | A DVB-S/S2 tuner module. Say Y when you want to support this frontend. | 201 | A DVB-S/S2 tuner module. Say Y when you want to support this frontend. |
202 | 202 | ||
203 | config DVB_CX24117 | ||
204 | tristate "Conexant CX24117 based" | ||
205 | depends on DVB_CORE && I2C | ||
206 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
207 | help | ||
208 | A Dual DVB-S/S2 tuner module. Say Y when you want to support this frontend. | ||
209 | |||
203 | config DVB_SI21XX | 210 | config DVB_SI21XX |
204 | tristate "Silicon Labs SI21XX based" | 211 | tristate "Silicon Labs SI21XX based" |
205 | depends on DVB_CORE && I2C | 212 | depends on DVB_CORE && I2C |
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index cebc0faffab5..f9cb43d9aed9 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile | |||
@@ -76,6 +76,7 @@ obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o | |||
76 | obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o | 76 | obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o |
77 | obj-$(CONFIG_DVB_AF9013) += af9013.o | 77 | obj-$(CONFIG_DVB_AF9013) += af9013.o |
78 | obj-$(CONFIG_DVB_CX24116) += cx24116.o | 78 | obj-$(CONFIG_DVB_CX24116) += cx24116.o |
79 | obj-$(CONFIG_DVB_CX24117) += cx24117.o | ||
79 | obj-$(CONFIG_DVB_SI21XX) += si21xx.o | 80 | obj-$(CONFIG_DVB_SI21XX) += si21xx.o |
80 | obj-$(CONFIG_DVB_STV0288) += stv0288.o | 81 | obj-$(CONFIG_DVB_STV0288) += stv0288.o |
81 | obj-$(CONFIG_DVB_STB6000) += stb6000.o | 82 | obj-$(CONFIG_DVB_STB6000) += stb6000.o |
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 0cd6927e654c..95b981cd7115 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c | |||
@@ -378,7 +378,7 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
378 | return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40); | 378 | return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40); |
379 | default: | 379 | default: |
380 | return -EINVAL; | 380 | return -EINVAL; |
381 | }; | 381 | } |
382 | } | 382 | } |
383 | 383 | ||
384 | static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 384 | static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c new file mode 100644 index 000000000000..476b422ccf19 --- /dev/null +++ b/drivers/media/dvb-frontends/cx24117.c | |||
@@ -0,0 +1,1650 @@ | |||
1 | /* | ||
2 | Conexant cx24117/cx24132 - Dual DVBS/S2 Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2013 Luis Alves <ljalvs@gmail.com> | ||
5 | July, 6th 2013 | ||
6 | First release based on cx24116 driver by: | ||
7 | Steven Toth and Georg Acher, Darron Broad, Igor Liplianin | ||
8 | Cards currently supported: | ||
9 | TBS6980 - Dual DVBS/S2 PCIe card | ||
10 | TBS6981 - Dual DVBS/S2 PCIe card | ||
11 | |||
12 | This program is free software; you can redistribute it and/or modify | ||
13 | it under the terms of the GNU General Public License as published by | ||
14 | the Free Software Foundation; either version 2 of the License, or | ||
15 | (at your option) any later version. | ||
16 | |||
17 | This program is distributed in the hope that it will be useful, | ||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | GNU General Public License for more details. | ||
21 | |||
22 | You should have received a copy of the GNU General Public License | ||
23 | along with this program; if not, write to the Free Software | ||
24 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <linux/slab.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/firmware.h> | ||
33 | |||
34 | #include "tuner-i2c.h" | ||
35 | #include "dvb_frontend.h" | ||
36 | #include "cx24117.h" | ||
37 | |||
38 | |||
39 | #define CX24117_DEFAULT_FIRMWARE "dvb-fe-cx24117.fw" | ||
40 | #define CX24117_SEARCH_RANGE_KHZ 5000 | ||
41 | |||
42 | /* known registers */ | ||
43 | #define CX24117_REG_COMMAND (0x00) /* command buffer */ | ||
44 | #define CX24117_REG_EXECUTE (0x1f) /* execute command */ | ||
45 | |||
46 | #define CX24117_REG_FREQ3_0 (0x34) /* frequency */ | ||
47 | #define CX24117_REG_FREQ2_0 (0x35) | ||
48 | #define CX24117_REG_FREQ1_0 (0x36) | ||
49 | #define CX24117_REG_STATE0 (0x39) | ||
50 | #define CX24117_REG_SSTATUS0 (0x3a) /* demod0 signal high / status */ | ||
51 | #define CX24117_REG_SIGNAL0 (0x3b) | ||
52 | #define CX24117_REG_FREQ5_0 (0x3c) /* +-freq */ | ||
53 | #define CX24117_REG_FREQ6_0 (0x3d) | ||
54 | #define CX24117_REG_SRATE2_0 (0x3e) /* +- 1000 * srate */ | ||
55 | #define CX24117_REG_SRATE1_0 (0x3f) | ||
56 | #define CX24117_REG_QUALITY2_0 (0x40) | ||
57 | #define CX24117_REG_QUALITY1_0 (0x41) | ||
58 | |||
59 | #define CX24117_REG_BER4_0 (0x47) | ||
60 | #define CX24117_REG_BER3_0 (0x48) | ||
61 | #define CX24117_REG_BER2_0 (0x49) | ||
62 | #define CX24117_REG_BER1_0 (0x4a) | ||
63 | #define CX24117_REG_DVBS_UCB2_0 (0x4b) | ||
64 | #define CX24117_REG_DVBS_UCB1_0 (0x4c) | ||
65 | #define CX24117_REG_DVBS2_UCB2_0 (0x50) | ||
66 | #define CX24117_REG_DVBS2_UCB1_0 (0x51) | ||
67 | #define CX24117_REG_QSTATUS0 (0x93) | ||
68 | #define CX24117_REG_CLKDIV0 (0xe6) | ||
69 | #define CX24117_REG_RATEDIV0 (0xf0) | ||
70 | |||
71 | |||
72 | #define CX24117_REG_FREQ3_1 (0x55) /* frequency */ | ||
73 | #define CX24117_REG_FREQ2_1 (0x56) | ||
74 | #define CX24117_REG_FREQ1_1 (0x57) | ||
75 | #define CX24117_REG_STATE1 (0x5a) | ||
76 | #define CX24117_REG_SSTATUS1 (0x5b) /* demod1 signal high / status */ | ||
77 | #define CX24117_REG_SIGNAL1 (0x5c) | ||
78 | #define CX24117_REG_FREQ5_1 (0x5d) /* +- freq */ | ||
79 | #define CX24117_REG_FREQ4_1 (0x5e) | ||
80 | #define CX24117_REG_SRATE2_1 (0x5f) | ||
81 | #define CX24117_REG_SRATE1_1 (0x60) | ||
82 | #define CX24117_REG_QUALITY2_1 (0x61) | ||
83 | #define CX24117_REG_QUALITY1_1 (0x62) | ||
84 | #define CX24117_REG_BER4_1 (0x68) | ||
85 | #define CX24117_REG_BER3_1 (0x69) | ||
86 | #define CX24117_REG_BER2_1 (0x6a) | ||
87 | #define CX24117_REG_BER1_1 (0x6b) | ||
88 | #define CX24117_REG_DVBS_UCB2_1 (0x6c) | ||
89 | #define CX24117_REG_DVBS_UCB1_1 (0x6d) | ||
90 | #define CX24117_REG_DVBS2_UCB2_1 (0x71) | ||
91 | #define CX24117_REG_DVBS2_UCB1_1 (0x72) | ||
92 | #define CX24117_REG_QSTATUS1 (0x9f) | ||
93 | #define CX24117_REG_CLKDIV1 (0xe7) | ||
94 | #define CX24117_REG_RATEDIV1 (0xf1) | ||
95 | |||
96 | |||
97 | /* arg buffer size */ | ||
98 | #define CX24117_ARGLEN (0x1e) | ||
99 | |||
100 | /* rolloff */ | ||
101 | #define CX24117_ROLLOFF_020 (0x00) | ||
102 | #define CX24117_ROLLOFF_025 (0x01) | ||
103 | #define CX24117_ROLLOFF_035 (0x02) | ||
104 | |||
105 | /* pilot bit */ | ||
106 | #define CX24117_PILOT_OFF (0x00) | ||
107 | #define CX24117_PILOT_ON (0x40) | ||
108 | #define CX24117_PILOT_AUTO (0x80) | ||
109 | |||
110 | /* signal status */ | ||
111 | #define CX24117_HAS_SIGNAL (0x01) | ||
112 | #define CX24117_HAS_CARRIER (0x02) | ||
113 | #define CX24117_HAS_VITERBI (0x04) | ||
114 | #define CX24117_HAS_SYNCLOCK (0x08) | ||
115 | #define CX24117_STATUS_MASK (0x0f) | ||
116 | #define CX24117_SIGNAL_MASK (0xc0) | ||
117 | |||
118 | |||
119 | /* arg offset for DiSEqC */ | ||
120 | #define CX24117_DISEQC_DEMOD (1) | ||
121 | #define CX24117_DISEQC_BURST (2) | ||
122 | #define CX24117_DISEQC_ARG3_2 (3) /* unknown value=2 */ | ||
123 | #define CX24117_DISEQC_ARG4_0 (4) /* unknown value=0 */ | ||
124 | #define CX24117_DISEQC_ARG5_0 (5) /* unknown value=0 */ | ||
125 | #define CX24117_DISEQC_MSGLEN (6) | ||
126 | #define CX24117_DISEQC_MSGOFS (7) | ||
127 | |||
128 | /* DiSEqC burst */ | ||
129 | #define CX24117_DISEQC_MINI_A (0) | ||
130 | #define CX24117_DISEQC_MINI_B (1) | ||
131 | |||
132 | |||
133 | #define CX24117_PNE (0) /* 0 disabled / 2 enabled */ | ||
134 | #define CX24117_OCC (1) /* 0 disabled / 1 enabled */ | ||
135 | |||
136 | |||
137 | enum cmds { | ||
138 | CMD_SET_VCO = 0x10, | ||
139 | CMD_TUNEREQUEST = 0x11, | ||
140 | CMD_MPEGCONFIG = 0x13, | ||
141 | CMD_TUNERINIT = 0x14, | ||
142 | CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ | ||
143 | CMD_LNBDCLEVEL = 0x22, | ||
144 | CMD_SET_TONE = 0x23, | ||
145 | CMD_UPDFWVERS = 0x35, | ||
146 | CMD_TUNERSLEEP = 0x36, | ||
147 | }; | ||
148 | |||
149 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
150 | static DEFINE_MUTEX(cx24117_list_mutex); | ||
151 | |||
152 | /* The Demod/Tuner can't easily provide these, we cache them */ | ||
153 | struct cx24117_tuning { | ||
154 | u32 frequency; | ||
155 | u32 symbol_rate; | ||
156 | fe_spectral_inversion_t inversion; | ||
157 | fe_code_rate_t fec; | ||
158 | |||
159 | fe_delivery_system_t delsys; | ||
160 | fe_modulation_t modulation; | ||
161 | fe_pilot_t pilot; | ||
162 | fe_rolloff_t rolloff; | ||
163 | |||
164 | /* Demod values */ | ||
165 | u8 fec_val; | ||
166 | u8 fec_mask; | ||
167 | u8 inversion_val; | ||
168 | u8 pilot_val; | ||
169 | u8 rolloff_val; | ||
170 | }; | ||
171 | |||
172 | /* Basic commands that are sent to the firmware */ | ||
173 | struct cx24117_cmd { | ||
174 | u8 len; | ||
175 | u8 args[CX24117_ARGLEN]; | ||
176 | }; | ||
177 | |||
178 | /* common to both fe's */ | ||
179 | struct cx24117_priv { | ||
180 | u8 demod_address; | ||
181 | struct i2c_adapter *i2c; | ||
182 | u8 skip_fw_load; | ||
183 | struct mutex fe_lock; | ||
184 | |||
185 | /* Used for sharing this struct between demods */ | ||
186 | struct tuner_i2c_props i2c_props; | ||
187 | struct list_head hybrid_tuner_instance_list; | ||
188 | }; | ||
189 | |||
190 | /* one per each fe */ | ||
191 | struct cx24117_state { | ||
192 | struct cx24117_priv *priv; | ||
193 | struct dvb_frontend frontend; | ||
194 | |||
195 | struct cx24117_tuning dcur; | ||
196 | struct cx24117_tuning dnxt; | ||
197 | struct cx24117_cmd dsec_cmd; | ||
198 | |||
199 | int demod; | ||
200 | }; | ||
201 | |||
202 | /* modfec (modulation and FEC) lookup table */ | ||
203 | /* Check cx24116.c for a detailed description of each field */ | ||
204 | static struct cx24117_modfec { | ||
205 | fe_delivery_system_t delivery_system; | ||
206 | fe_modulation_t modulation; | ||
207 | fe_code_rate_t fec; | ||
208 | u8 mask; /* In DVBS mode this is used to autodetect */ | ||
209 | u8 val; /* Passed to the firmware to indicate mode selection */ | ||
210 | } cx24117_modfec_modes[] = { | ||
211 | /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */ | ||
212 | |||
213 | /*mod fec mask val */ | ||
214 | { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 }, | ||
215 | { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ | ||
216 | { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ | ||
217 | { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ | ||
218 | { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ | ||
219 | { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ | ||
220 | { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ | ||
221 | { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ | ||
222 | { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ | ||
223 | { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 }, | ||
224 | /* NBC-QPSK */ | ||
225 | { SYS_DVBS2, QPSK, FEC_NONE, 0x00, 0x00 }, | ||
226 | { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 }, | ||
227 | { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 }, | ||
228 | { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 }, | ||
229 | { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 }, | ||
230 | { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 }, | ||
231 | { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 }, | ||
232 | { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a }, | ||
233 | { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b }, | ||
234 | { SYS_DVBS2, QPSK, FEC_AUTO, 0x00, 0x00 }, | ||
235 | /* 8PSK */ | ||
236 | { SYS_DVBS2, PSK_8, FEC_NONE, 0x00, 0x00 }, | ||
237 | { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c }, | ||
238 | { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d }, | ||
239 | { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e }, | ||
240 | { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f }, | ||
241 | { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 }, | ||
242 | { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 }, | ||
243 | { SYS_DVBS2, PSK_8, FEC_AUTO, 0x00, 0x00 }, | ||
244 | /* | ||
245 | * 'val' can be found in the FECSTATUS register when tuning. | ||
246 | * FECSTATUS will give the actual FEC in use if tuning was successful. | ||
247 | */ | ||
248 | }; | ||
249 | |||
250 | |||
251 | static int cx24117_writereg(struct cx24117_state *state, u8 reg, u8 data) | ||
252 | { | ||
253 | u8 buf[] = { reg, data }; | ||
254 | struct i2c_msg msg = { .addr = state->priv->demod_address, | ||
255 | .flags = 0, .buf = buf, .len = 2 }; | ||
256 | int ret; | ||
257 | |||
258 | dev_dbg(&state->priv->i2c->dev, | ||
259 | "%s() demod%d i2c wr @0x%02x=0x%02x\n", | ||
260 | __func__, state->demod, reg, data); | ||
261 | |||
262 | ret = i2c_transfer(state->priv->i2c, &msg, 1); | ||
263 | if (ret < 0) { | ||
264 | dev_warn(&state->priv->i2c->dev, | ||
265 | "%s: demod%d i2c wr err(%i) @0x%02x=0x%02x\n", | ||
266 | KBUILD_MODNAME, state->demod, ret, reg, data); | ||
267 | return ret; | ||
268 | } | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int cx24117_writecmd(struct cx24117_state *state, | ||
273 | struct cx24117_cmd *cmd) | ||
274 | { | ||
275 | struct i2c_msg msg; | ||
276 | u8 buf[CX24117_ARGLEN+1]; | ||
277 | int ret; | ||
278 | |||
279 | dev_dbg(&state->priv->i2c->dev, | ||
280 | "%s() demod%d i2c wr cmd len=%d\n", | ||
281 | __func__, state->demod, cmd->len); | ||
282 | |||
283 | buf[0] = CX24117_REG_COMMAND; | ||
284 | memcpy(&buf[1], cmd->args, cmd->len); | ||
285 | |||
286 | msg.addr = state->priv->demod_address; | ||
287 | msg.flags = 0; | ||
288 | msg.len = cmd->len+1; | ||
289 | msg.buf = buf; | ||
290 | ret = i2c_transfer(state->priv->i2c, &msg, 1); | ||
291 | if (ret < 0) { | ||
292 | dev_warn(&state->priv->i2c->dev, | ||
293 | "%s: demod%d i2c wr cmd err(%i) len=%d\n", | ||
294 | KBUILD_MODNAME, state->demod, ret, cmd->len); | ||
295 | return ret; | ||
296 | } | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static int cx24117_readreg(struct cx24117_state *state, u8 reg) | ||
301 | { | ||
302 | int ret; | ||
303 | u8 recv = 0; | ||
304 | struct i2c_msg msg[] = { | ||
305 | { .addr = state->priv->demod_address, .flags = 0, | ||
306 | .buf = ®, .len = 1 }, | ||
307 | { .addr = state->priv->demod_address, .flags = I2C_M_RD, | ||
308 | .buf = &recv, .len = 1 } | ||
309 | }; | ||
310 | |||
311 | ret = i2c_transfer(state->priv->i2c, msg, 2); | ||
312 | if (ret < 0) { | ||
313 | dev_warn(&state->priv->i2c->dev, | ||
314 | "%s: demod%d i2c rd err(%d) @0x%x\n", | ||
315 | KBUILD_MODNAME, state->demod, ret, reg); | ||
316 | return ret; | ||
317 | } | ||
318 | |||
319 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d i2c rd @0x%02x=0x%02x\n", | ||
320 | __func__, state->demod, reg, recv); | ||
321 | |||
322 | return recv; | ||
323 | } | ||
324 | |||
325 | static int cx24117_readregN(struct cx24117_state *state, | ||
326 | u8 reg, u8 *buf, int len) | ||
327 | { | ||
328 | int ret; | ||
329 | struct i2c_msg msg[] = { | ||
330 | { .addr = state->priv->demod_address, .flags = 0, | ||
331 | .buf = ®, .len = 1 }, | ||
332 | { .addr = state->priv->demod_address, .flags = I2C_M_RD, | ||
333 | .buf = buf, .len = len } | ||
334 | }; | ||
335 | |||
336 | ret = i2c_transfer(state->priv->i2c, msg, 2); | ||
337 | if (ret < 0) { | ||
338 | dev_warn(&state->priv->i2c->dev, | ||
339 | "%s: demod%d i2c rd err(%d) @0x%x\n", | ||
340 | KBUILD_MODNAME, state->demod, ret, reg); | ||
341 | return ret; | ||
342 | } | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int cx24117_set_inversion(struct cx24117_state *state, | ||
347 | fe_spectral_inversion_t inversion) | ||
348 | { | ||
349 | dev_dbg(&state->priv->i2c->dev, "%s(%d) demod%d\n", | ||
350 | __func__, inversion, state->demod); | ||
351 | |||
352 | switch (inversion) { | ||
353 | case INVERSION_OFF: | ||
354 | state->dnxt.inversion_val = 0x00; | ||
355 | break; | ||
356 | case INVERSION_ON: | ||
357 | state->dnxt.inversion_val = 0x04; | ||
358 | break; | ||
359 | case INVERSION_AUTO: | ||
360 | state->dnxt.inversion_val = 0x0C; | ||
361 | break; | ||
362 | default: | ||
363 | return -EINVAL; | ||
364 | } | ||
365 | |||
366 | state->dnxt.inversion = inversion; | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int cx24117_lookup_fecmod(struct cx24117_state *state, | ||
372 | fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f) | ||
373 | { | ||
374 | int i, ret = -EINVAL; | ||
375 | |||
376 | dev_dbg(&state->priv->i2c->dev, | ||
377 | "%s(demod(0x%02x,0x%02x) demod%d\n", | ||
378 | __func__, m, f, state->demod); | ||
379 | |||
380 | for (i = 0; i < ARRAY_SIZE(cx24117_modfec_modes); i++) { | ||
381 | if ((d == cx24117_modfec_modes[i].delivery_system) && | ||
382 | (m == cx24117_modfec_modes[i].modulation) && | ||
383 | (f == cx24117_modfec_modes[i].fec)) { | ||
384 | ret = i; | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int cx24117_set_fec(struct cx24117_state *state, | ||
393 | fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec) | ||
394 | { | ||
395 | int ret; | ||
396 | |||
397 | dev_dbg(&state->priv->i2c->dev, | ||
398 | "%s(0x%02x,0x%02x) demod%d\n", | ||
399 | __func__, mod, fec, state->demod); | ||
400 | |||
401 | ret = cx24117_lookup_fecmod(state, delsys, mod, fec); | ||
402 | if (ret < 0) | ||
403 | return ret; | ||
404 | |||
405 | state->dnxt.fec = fec; | ||
406 | state->dnxt.fec_val = cx24117_modfec_modes[ret].val; | ||
407 | state->dnxt.fec_mask = cx24117_modfec_modes[ret].mask; | ||
408 | dev_dbg(&state->priv->i2c->dev, | ||
409 | "%s() demod%d mask/val = 0x%02x/0x%02x\n", __func__, | ||
410 | state->demod, state->dnxt.fec_mask, state->dnxt.fec_val); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int cx24117_set_symbolrate(struct cx24117_state *state, u32 rate) | ||
416 | { | ||
417 | dev_dbg(&state->priv->i2c->dev, "%s(%d) demod%d\n", | ||
418 | __func__, rate, state->demod); | ||
419 | |||
420 | state->dnxt.symbol_rate = rate; | ||
421 | |||
422 | dev_dbg(&state->priv->i2c->dev, | ||
423 | "%s() demod%d symbol_rate = %d\n", | ||
424 | __func__, state->demod, rate); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int cx24117_load_firmware(struct dvb_frontend *fe, | ||
430 | const struct firmware *fw); | ||
431 | |||
432 | static int cx24117_firmware_ondemand(struct dvb_frontend *fe) | ||
433 | { | ||
434 | struct cx24117_state *state = fe->demodulator_priv; | ||
435 | const struct firmware *fw; | ||
436 | int ret = 0; | ||
437 | |||
438 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d skip_fw_load=%d\n", | ||
439 | __func__, state->demod, state->priv->skip_fw_load); | ||
440 | |||
441 | if (state->priv->skip_fw_load) | ||
442 | return 0; | ||
443 | |||
444 | /* check if firmware if already running */ | ||
445 | if (cx24117_readreg(state, 0xeb) != 0xa) { | ||
446 | /* Load firmware */ | ||
447 | /* request the firmware, this will block until loaded */ | ||
448 | dev_dbg(&state->priv->i2c->dev, | ||
449 | "%s: Waiting for firmware upload (%s)...\n", | ||
450 | __func__, CX24117_DEFAULT_FIRMWARE); | ||
451 | ret = request_firmware(&fw, CX24117_DEFAULT_FIRMWARE, | ||
452 | state->priv->i2c->dev.parent); | ||
453 | dev_dbg(&state->priv->i2c->dev, | ||
454 | "%s: Waiting for firmware upload(2)...\n", __func__); | ||
455 | if (ret) { | ||
456 | dev_err(&state->priv->i2c->dev, | ||
457 | "%s: No firmware uploaded " | ||
458 | "(timeout or file not found?)\n", __func__); | ||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | /* Make sure we don't recurse back through here | ||
463 | * during loading */ | ||
464 | state->priv->skip_fw_load = 1; | ||
465 | |||
466 | ret = cx24117_load_firmware(fe, fw); | ||
467 | if (ret) | ||
468 | dev_err(&state->priv->i2c->dev, | ||
469 | "%s: Writing firmware failed\n", __func__); | ||
470 | release_firmware(fw); | ||
471 | |||
472 | dev_info(&state->priv->i2c->dev, | ||
473 | "%s: Firmware upload %s\n", __func__, | ||
474 | ret == 0 ? "complete" : "failed"); | ||
475 | |||
476 | /* Ensure firmware is always loaded if required */ | ||
477 | state->priv->skip_fw_load = 0; | ||
478 | } | ||
479 | |||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | /* Take a basic firmware command structure, format it | ||
484 | * and forward it for processing | ||
485 | */ | ||
486 | static int cx24117_cmd_execute_nolock(struct dvb_frontend *fe, | ||
487 | struct cx24117_cmd *cmd) | ||
488 | { | ||
489 | struct cx24117_state *state = fe->demodulator_priv; | ||
490 | int i, ret; | ||
491 | |||
492 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", | ||
493 | __func__, state->demod); | ||
494 | |||
495 | /* Load the firmware if required */ | ||
496 | ret = cx24117_firmware_ondemand(fe); | ||
497 | if (ret != 0) | ||
498 | return ret; | ||
499 | |||
500 | /* Write the command */ | ||
501 | cx24117_writecmd(state, cmd); | ||
502 | |||
503 | /* Start execution and wait for cmd to terminate */ | ||
504 | cx24117_writereg(state, CX24117_REG_EXECUTE, 0x01); | ||
505 | i = 0; | ||
506 | while (cx24117_readreg(state, CX24117_REG_EXECUTE)) { | ||
507 | msleep(20); | ||
508 | if (i++ > 40) { | ||
509 | /* Avoid looping forever if the firmware does | ||
510 | not respond */ | ||
511 | dev_warn(&state->priv->i2c->dev, | ||
512 | "%s() Firmware not responding\n", __func__); | ||
513 | return -EIO; | ||
514 | } | ||
515 | } | ||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int cx24117_cmd_execute(struct dvb_frontend *fe, struct cx24117_cmd *cmd) | ||
520 | { | ||
521 | struct cx24117_state *state = fe->demodulator_priv; | ||
522 | int ret; | ||
523 | |||
524 | mutex_lock(&state->priv->fe_lock); | ||
525 | ret = cx24117_cmd_execute_nolock(fe, cmd); | ||
526 | mutex_unlock(&state->priv->fe_lock); | ||
527 | |||
528 | return ret; | ||
529 | } | ||
530 | |||
531 | static int cx24117_load_firmware(struct dvb_frontend *fe, | ||
532 | const struct firmware *fw) | ||
533 | { | ||
534 | struct cx24117_state *state = fe->demodulator_priv; | ||
535 | struct cx24117_cmd cmd; | ||
536 | int i, ret; | ||
537 | unsigned char vers[4]; | ||
538 | |||
539 | struct i2c_msg msg; | ||
540 | u8 *buf; | ||
541 | |||
542 | dev_dbg(&state->priv->i2c->dev, | ||
543 | "%s() demod%d FW is %zu bytes (%02x %02x .. %02x %02x)\n", | ||
544 | __func__, state->demod, fw->size, fw->data[0], fw->data[1], | ||
545 | fw->data[fw->size - 2], fw->data[fw->size - 1]); | ||
546 | |||
547 | cx24117_writereg(state, 0xea, 0x00); | ||
548 | cx24117_writereg(state, 0xea, 0x01); | ||
549 | cx24117_writereg(state, 0xea, 0x00); | ||
550 | |||
551 | cx24117_writereg(state, 0xce, 0x92); | ||
552 | |||
553 | cx24117_writereg(state, 0xfb, 0x00); | ||
554 | cx24117_writereg(state, 0xfc, 0x00); | ||
555 | |||
556 | cx24117_writereg(state, 0xc3, 0x04); | ||
557 | cx24117_writereg(state, 0xc4, 0x04); | ||
558 | |||
559 | cx24117_writereg(state, 0xce, 0x00); | ||
560 | cx24117_writereg(state, 0xcf, 0x00); | ||
561 | |||
562 | cx24117_writereg(state, 0xea, 0x00); | ||
563 | cx24117_writereg(state, 0xeb, 0x0c); | ||
564 | cx24117_writereg(state, 0xec, 0x06); | ||
565 | cx24117_writereg(state, 0xed, 0x05); | ||
566 | cx24117_writereg(state, 0xee, 0x03); | ||
567 | cx24117_writereg(state, 0xef, 0x05); | ||
568 | |||
569 | cx24117_writereg(state, 0xf3, 0x03); | ||
570 | cx24117_writereg(state, 0xf4, 0x44); | ||
571 | |||
572 | cx24117_writereg(state, CX24117_REG_RATEDIV0, 0x04); | ||
573 | cx24117_writereg(state, CX24117_REG_CLKDIV0, 0x02); | ||
574 | |||
575 | cx24117_writereg(state, CX24117_REG_RATEDIV1, 0x04); | ||
576 | cx24117_writereg(state, CX24117_REG_CLKDIV1, 0x02); | ||
577 | |||
578 | cx24117_writereg(state, 0xf2, 0x04); | ||
579 | cx24117_writereg(state, 0xe8, 0x02); | ||
580 | cx24117_writereg(state, 0xea, 0x01); | ||
581 | cx24117_writereg(state, 0xc8, 0x00); | ||
582 | cx24117_writereg(state, 0xc9, 0x00); | ||
583 | cx24117_writereg(state, 0xca, 0x00); | ||
584 | cx24117_writereg(state, 0xcb, 0x00); | ||
585 | cx24117_writereg(state, 0xcc, 0x00); | ||
586 | cx24117_writereg(state, 0xcd, 0x00); | ||
587 | cx24117_writereg(state, 0xe4, 0x03); | ||
588 | cx24117_writereg(state, 0xeb, 0x0a); | ||
589 | |||
590 | cx24117_writereg(state, 0xfb, 0x00); | ||
591 | cx24117_writereg(state, 0xe0, 0x76); | ||
592 | cx24117_writereg(state, 0xf7, 0x81); | ||
593 | cx24117_writereg(state, 0xf8, 0x00); | ||
594 | cx24117_writereg(state, 0xf9, 0x00); | ||
595 | |||
596 | buf = kmalloc(fw->size + 1, GFP_KERNEL); | ||
597 | if (buf == NULL) { | ||
598 | state->priv->skip_fw_load = 0; | ||
599 | return -ENOMEM; | ||
600 | } | ||
601 | |||
602 | /* fw upload reg */ | ||
603 | buf[0] = 0xfa; | ||
604 | memcpy(&buf[1], fw->data, fw->size); | ||
605 | |||
606 | /* prepare i2c message to send */ | ||
607 | msg.addr = state->priv->demod_address; | ||
608 | msg.flags = 0; | ||
609 | msg.len = fw->size + 1; | ||
610 | msg.buf = buf; | ||
611 | |||
612 | /* send fw */ | ||
613 | ret = i2c_transfer(state->priv->i2c, &msg, 1); | ||
614 | if (ret < 0) | ||
615 | return ret; | ||
616 | |||
617 | kfree(buf); | ||
618 | |||
619 | cx24117_writereg(state, 0xf7, 0x0c); | ||
620 | cx24117_writereg(state, 0xe0, 0x00); | ||
621 | |||
622 | /* CMD 1B */ | ||
623 | cmd.args[0] = 0x1b; | ||
624 | cmd.args[1] = 0x00; | ||
625 | cmd.args[2] = 0x01; | ||
626 | cmd.args[3] = 0x00; | ||
627 | cmd.len = 4; | ||
628 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
629 | if (ret != 0) | ||
630 | goto error; | ||
631 | |||
632 | /* CMD 10 */ | ||
633 | cmd.args[0] = CMD_SET_VCO; | ||
634 | cmd.args[1] = 0x06; | ||
635 | cmd.args[2] = 0x2b; | ||
636 | cmd.args[3] = 0xd8; | ||
637 | cmd.args[4] = 0xa5; | ||
638 | cmd.args[5] = 0xee; | ||
639 | cmd.args[6] = 0x03; | ||
640 | cmd.args[7] = 0x9d; | ||
641 | cmd.args[8] = 0xfc; | ||
642 | cmd.args[9] = 0x06; | ||
643 | cmd.args[10] = 0x02; | ||
644 | cmd.args[11] = 0x9d; | ||
645 | cmd.args[12] = 0xfc; | ||
646 | cmd.len = 13; | ||
647 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
648 | if (ret != 0) | ||
649 | goto error; | ||
650 | |||
651 | /* CMD 15 */ | ||
652 | cmd.args[0] = 0x15; | ||
653 | cmd.args[1] = 0x00; | ||
654 | cmd.args[2] = 0x01; | ||
655 | cmd.args[3] = 0x00; | ||
656 | cmd.args[4] = 0x00; | ||
657 | cmd.args[5] = 0x01; | ||
658 | cmd.args[6] = 0x01; | ||
659 | cmd.args[7] = 0x01; | ||
660 | cmd.args[8] = 0x00; | ||
661 | cmd.args[9] = 0x05; | ||
662 | cmd.args[10] = 0x02; | ||
663 | cmd.args[11] = 0x02; | ||
664 | cmd.args[12] = 0x00; | ||
665 | cmd.len = 13; | ||
666 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
667 | if (ret != 0) | ||
668 | goto error; | ||
669 | |||
670 | /* CMD 13 */ | ||
671 | cmd.args[0] = CMD_MPEGCONFIG; | ||
672 | cmd.args[1] = 0x00; | ||
673 | cmd.args[2] = 0x00; | ||
674 | cmd.args[3] = 0x00; | ||
675 | cmd.args[4] = 0x01; | ||
676 | cmd.args[5] = 0x00; | ||
677 | cmd.len = 6; | ||
678 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
679 | if (ret != 0) | ||
680 | goto error; | ||
681 | |||
682 | /* CMD 14 */ | ||
683 | for (i = 0; i < 2; i++) { | ||
684 | cmd.args[0] = CMD_TUNERINIT; | ||
685 | cmd.args[1] = (u8) i; | ||
686 | cmd.args[2] = 0x00; | ||
687 | cmd.args[3] = 0x05; | ||
688 | cmd.args[4] = 0x00; | ||
689 | cmd.args[5] = 0x00; | ||
690 | cmd.args[6] = 0x55; | ||
691 | cmd.args[7] = 0x00; | ||
692 | cmd.len = 8; | ||
693 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
694 | if (ret != 0) | ||
695 | goto error; | ||
696 | } | ||
697 | |||
698 | cx24117_writereg(state, 0xce, 0xc0); | ||
699 | cx24117_writereg(state, 0xcf, 0x00); | ||
700 | cx24117_writereg(state, 0xe5, 0x04); | ||
701 | |||
702 | /* Firmware CMD 35: Get firmware version */ | ||
703 | cmd.args[0] = CMD_UPDFWVERS; | ||
704 | cmd.len = 2; | ||
705 | for (i = 0; i < 4; i++) { | ||
706 | cmd.args[1] = i; | ||
707 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
708 | if (ret != 0) | ||
709 | goto error; | ||
710 | vers[i] = cx24117_readreg(state, 0x33); | ||
711 | } | ||
712 | dev_info(&state->priv->i2c->dev, | ||
713 | "%s: FW version %i.%i.%i.%i\n", __func__, | ||
714 | vers[0], vers[1], vers[2], vers[3]); | ||
715 | return 0; | ||
716 | error: | ||
717 | state->priv->skip_fw_load = 0; | ||
718 | dev_err(&state->priv->i2c->dev, "%s() Error running FW.\n", __func__); | ||
719 | return ret; | ||
720 | } | ||
721 | |||
722 | static int cx24117_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
723 | { | ||
724 | struct cx24117_state *state = fe->demodulator_priv; | ||
725 | int lock; | ||
726 | |||
727 | lock = cx24117_readreg(state, | ||
728 | (state->demod == 0) ? CX24117_REG_SSTATUS0 : | ||
729 | CX24117_REG_SSTATUS1) & | ||
730 | CX24117_STATUS_MASK; | ||
731 | |||
732 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d status = 0x%02x\n", | ||
733 | __func__, state->demod, lock); | ||
734 | |||
735 | *status = 0; | ||
736 | |||
737 | if (lock & CX24117_HAS_SIGNAL) | ||
738 | *status |= FE_HAS_SIGNAL; | ||
739 | if (lock & CX24117_HAS_CARRIER) | ||
740 | *status |= FE_HAS_CARRIER; | ||
741 | if (lock & CX24117_HAS_VITERBI) | ||
742 | *status |= FE_HAS_VITERBI; | ||
743 | if (lock & CX24117_HAS_SYNCLOCK) | ||
744 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | static int cx24117_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
750 | { | ||
751 | struct cx24117_state *state = fe->demodulator_priv; | ||
752 | int ret; | ||
753 | u8 buf[4]; | ||
754 | u8 base_reg = (state->demod == 0) ? | ||
755 | CX24117_REG_BER4_0 : | ||
756 | CX24117_REG_BER4_1; | ||
757 | |||
758 | ret = cx24117_readregN(state, base_reg, buf, 4); | ||
759 | if (ret != 0) | ||
760 | return ret; | ||
761 | |||
762 | *ber = (buf[0] << 24) | (buf[1] << 16) | | ||
763 | (buf[1] << 8) | buf[0]; | ||
764 | |||
765 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d ber=0x%04x\n", | ||
766 | __func__, state->demod, *ber); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static int cx24117_read_signal_strength(struct dvb_frontend *fe, | ||
772 | u16 *signal_strength) | ||
773 | { | ||
774 | struct cx24117_state *state = fe->demodulator_priv; | ||
775 | struct cx24117_cmd cmd; | ||
776 | int ret; | ||
777 | u16 sig_reading; | ||
778 | u8 buf[2]; | ||
779 | u8 reg = (state->demod == 0) ? | ||
780 | CX24117_REG_SSTATUS0 : CX24117_REG_SSTATUS1; | ||
781 | |||
782 | /* Firmware CMD 1A */ | ||
783 | cmd.args[0] = 0x1a; | ||
784 | cmd.args[1] = (u8) state->demod; | ||
785 | cmd.len = 2; | ||
786 | ret = cx24117_cmd_execute(fe, &cmd); | ||
787 | if (ret != 0) | ||
788 | return ret; | ||
789 | |||
790 | ret = cx24117_readregN(state, reg, buf, 2); | ||
791 | if (ret != 0) | ||
792 | return ret; | ||
793 | sig_reading = ((buf[0] & CX24117_SIGNAL_MASK) << 2) | buf[1]; | ||
794 | |||
795 | *signal_strength = -100 * sig_reading + 94324; | ||
796 | |||
797 | dev_dbg(&state->priv->i2c->dev, | ||
798 | "%s() demod%d raw / cooked = 0x%04x / 0x%04x\n", | ||
799 | __func__, state->demod, sig_reading, *signal_strength); | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int cx24117_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
805 | { | ||
806 | struct cx24117_state *state = fe->demodulator_priv; | ||
807 | int ret; | ||
808 | u8 buf[2]; | ||
809 | u8 reg = (state->demod == 0) ? | ||
810 | CX24117_REG_QUALITY2_0 : CX24117_REG_QUALITY2_1; | ||
811 | |||
812 | ret = cx24117_readregN(state, reg, buf, 2); | ||
813 | if (ret != 0) | ||
814 | return ret; | ||
815 | |||
816 | *snr = (buf[0] << 8) | buf[1]; | ||
817 | |||
818 | dev_dbg(&state->priv->i2c->dev, | ||
819 | "%s() demod%d snr = 0x%04x\n", | ||
820 | __func__, state->demod, *snr); | ||
821 | |||
822 | return ret; | ||
823 | } | ||
824 | |||
825 | static int cx24117_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
826 | { | ||
827 | struct cx24117_state *state = fe->demodulator_priv; | ||
828 | fe_delivery_system_t delsys = fe->dtv_property_cache.delivery_system; | ||
829 | int ret; | ||
830 | u8 buf[2]; | ||
831 | u8 reg = (state->demod == 0) ? | ||
832 | CX24117_REG_DVBS_UCB2_0 : | ||
833 | CX24117_REG_DVBS_UCB2_1; | ||
834 | |||
835 | switch (delsys) { | ||
836 | case SYS_DVBS: | ||
837 | break; | ||
838 | case SYS_DVBS2: | ||
839 | reg += (CX24117_REG_DVBS2_UCB2_0 - CX24117_REG_DVBS_UCB2_0); | ||
840 | break; | ||
841 | default: | ||
842 | return -EINVAL; | ||
843 | } | ||
844 | |||
845 | ret = cx24117_readregN(state, reg, buf, 2); | ||
846 | if (ret != 0) | ||
847 | return ret; | ||
848 | *ucblocks = (buf[0] << 8) | buf[1]; | ||
849 | |||
850 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d ucb=0x%04x\n", | ||
851 | __func__, state->demod, *ucblocks); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | /* Overwrite the current tuning params, we are about to tune */ | ||
857 | static void cx24117_clone_params(struct dvb_frontend *fe) | ||
858 | { | ||
859 | struct cx24117_state *state = fe->demodulator_priv; | ||
860 | state->dcur = state->dnxt; | ||
861 | } | ||
862 | |||
863 | /* Wait for LNB */ | ||
864 | static int cx24117_wait_for_lnb(struct dvb_frontend *fe) | ||
865 | { | ||
866 | struct cx24117_state *state = fe->demodulator_priv; | ||
867 | int i; | ||
868 | u8 val, reg = (state->demod == 0) ? CX24117_REG_QSTATUS0 : | ||
869 | CX24117_REG_QSTATUS1; | ||
870 | |||
871 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d qstatus = 0x%02x\n", | ||
872 | __func__, state->demod, cx24117_readreg(state, reg)); | ||
873 | |||
874 | /* Wait for up to 300 ms */ | ||
875 | for (i = 0; i < 10; i++) { | ||
876 | val = cx24117_readreg(state, reg) & 0x01; | ||
877 | if (val != 0) | ||
878 | return 0; | ||
879 | msleep(30); | ||
880 | } | ||
881 | |||
882 | dev_warn(&state->priv->i2c->dev, "%s: demod%d LNB not ready\n", | ||
883 | KBUILD_MODNAME, state->demod); | ||
884 | |||
885 | return -ETIMEDOUT; /* -EBUSY ? */ | ||
886 | } | ||
887 | |||
888 | static int cx24117_set_voltage(struct dvb_frontend *fe, | ||
889 | fe_sec_voltage_t voltage) | ||
890 | { | ||
891 | struct cx24117_state *state = fe->demodulator_priv; | ||
892 | struct cx24117_cmd cmd; | ||
893 | int ret; | ||
894 | u8 reg = (state->demod == 0) ? 0x10 : 0x20; | ||
895 | |||
896 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d %s\n", | ||
897 | __func__, state->demod, | ||
898 | voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : | ||
899 | voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : | ||
900 | "SEC_VOLTAGE_OFF"); | ||
901 | |||
902 | /* CMD 32 */ | ||
903 | cmd.args[0] = 0x32; | ||
904 | cmd.args[1] = reg; | ||
905 | cmd.args[2] = reg; | ||
906 | cmd.len = 3; | ||
907 | ret = cx24117_cmd_execute(fe, &cmd); | ||
908 | if (ret) | ||
909 | return ret; | ||
910 | |||
911 | if ((voltage == SEC_VOLTAGE_13) || | ||
912 | (voltage == SEC_VOLTAGE_18)) { | ||
913 | /* CMD 33 */ | ||
914 | cmd.args[0] = 0x33; | ||
915 | cmd.args[1] = reg; | ||
916 | cmd.args[2] = reg; | ||
917 | cmd.len = 3; | ||
918 | ret = cx24117_cmd_execute(fe, &cmd); | ||
919 | if (ret != 0) | ||
920 | return ret; | ||
921 | |||
922 | ret = cx24117_wait_for_lnb(fe); | ||
923 | if (ret != 0) | ||
924 | return ret; | ||
925 | |||
926 | /* Wait for voltage/min repeat delay */ | ||
927 | msleep(100); | ||
928 | |||
929 | /* CMD 22 - CMD_LNBDCLEVEL */ | ||
930 | cmd.args[0] = CMD_LNBDCLEVEL; | ||
931 | cmd.args[1] = state->demod ? 0 : 1; | ||
932 | cmd.args[2] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00); | ||
933 | cmd.len = 3; | ||
934 | |||
935 | /* Min delay time before DiSEqC send */ | ||
936 | msleep(20); | ||
937 | } else { | ||
938 | cmd.args[0] = 0x33; | ||
939 | cmd.args[1] = 0x00; | ||
940 | cmd.args[2] = reg; | ||
941 | cmd.len = 3; | ||
942 | } | ||
943 | |||
944 | return cx24117_cmd_execute(fe, &cmd); | ||
945 | } | ||
946 | |||
947 | static int cx24117_set_tone(struct dvb_frontend *fe, | ||
948 | fe_sec_tone_mode_t tone) | ||
949 | { | ||
950 | struct cx24117_state *state = fe->demodulator_priv; | ||
951 | struct cx24117_cmd cmd; | ||
952 | int ret; | ||
953 | |||
954 | dev_dbg(&state->priv->i2c->dev, "%s(%d) demod%d\n", | ||
955 | __func__, state->demod, tone); | ||
956 | if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { | ||
957 | dev_warn(&state->priv->i2c->dev, "%s: demod%d invalid tone=%d\n", | ||
958 | KBUILD_MODNAME, state->demod, tone); | ||
959 | return -EINVAL; | ||
960 | } | ||
961 | |||
962 | /* Wait for LNB ready */ | ||
963 | ret = cx24117_wait_for_lnb(fe); | ||
964 | if (ret != 0) | ||
965 | return ret; | ||
966 | |||
967 | /* Min delay time after DiSEqC send */ | ||
968 | msleep(20); | ||
969 | |||
970 | /* Set the tone */ | ||
971 | /* CMD 23 - CMD_SET_TONE */ | ||
972 | cmd.args[0] = CMD_SET_TONE; | ||
973 | cmd.args[1] = (state->demod ? 0 : 1); | ||
974 | cmd.args[2] = 0x00; | ||
975 | cmd.args[3] = 0x00; | ||
976 | cmd.len = 5; | ||
977 | switch (tone) { | ||
978 | case SEC_TONE_ON: | ||
979 | cmd.args[4] = 0x01; | ||
980 | break; | ||
981 | case SEC_TONE_OFF: | ||
982 | cmd.args[4] = 0x00; | ||
983 | break; | ||
984 | } | ||
985 | |||
986 | msleep(20); | ||
987 | |||
988 | return cx24117_cmd_execute(fe, &cmd); | ||
989 | } | ||
990 | |||
991 | /* Initialise DiSEqC */ | ||
992 | static int cx24117_diseqc_init(struct dvb_frontend *fe) | ||
993 | { | ||
994 | struct cx24117_state *state = fe->demodulator_priv; | ||
995 | |||
996 | /* Prepare a DiSEqC command */ | ||
997 | state->dsec_cmd.args[0] = CMD_LNBSEND; | ||
998 | |||
999 | /* demod */ | ||
1000 | state->dsec_cmd.args[CX24117_DISEQC_DEMOD] = state->demod ? 0 : 1; | ||
1001 | |||
1002 | /* DiSEqC burst */ | ||
1003 | state->dsec_cmd.args[CX24117_DISEQC_BURST] = CX24117_DISEQC_MINI_A; | ||
1004 | |||
1005 | /* Unknown */ | ||
1006 | state->dsec_cmd.args[CX24117_DISEQC_ARG3_2] = 0x02; | ||
1007 | state->dsec_cmd.args[CX24117_DISEQC_ARG4_0] = 0x00; | ||
1008 | |||
1009 | /* Continuation flag? */ | ||
1010 | state->dsec_cmd.args[CX24117_DISEQC_ARG5_0] = 0x00; | ||
1011 | |||
1012 | /* DiSEqC message length */ | ||
1013 | state->dsec_cmd.args[CX24117_DISEQC_MSGLEN] = 0x00; | ||
1014 | |||
1015 | /* Command length */ | ||
1016 | state->dsec_cmd.len = 7; | ||
1017 | |||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | /* Send DiSEqC message */ | ||
1022 | static int cx24117_send_diseqc_msg(struct dvb_frontend *fe, | ||
1023 | struct dvb_diseqc_master_cmd *d) | ||
1024 | { | ||
1025 | struct cx24117_state *state = fe->demodulator_priv; | ||
1026 | int i, ret; | ||
1027 | |||
1028 | /* Dump DiSEqC message */ | ||
1029 | dev_dbg(&state->priv->i2c->dev, "%s: demod %d (", | ||
1030 | __func__, state->demod); | ||
1031 | for (i = 0; i < d->msg_len; i++) | ||
1032 | dev_dbg(&state->priv->i2c->dev, "0x%02x ", d->msg[i]); | ||
1033 | dev_dbg(&state->priv->i2c->dev, ")\n"); | ||
1034 | |||
1035 | /* Validate length */ | ||
1036 | if (d->msg_len > 15) | ||
1037 | return -EINVAL; | ||
1038 | |||
1039 | /* DiSEqC message */ | ||
1040 | for (i = 0; i < d->msg_len; i++) | ||
1041 | state->dsec_cmd.args[CX24117_DISEQC_MSGOFS + i] = d->msg[i]; | ||
1042 | |||
1043 | /* DiSEqC message length */ | ||
1044 | state->dsec_cmd.args[CX24117_DISEQC_MSGLEN] = d->msg_len; | ||
1045 | |||
1046 | /* Command length */ | ||
1047 | state->dsec_cmd.len = CX24117_DISEQC_MSGOFS + | ||
1048 | state->dsec_cmd.args[CX24117_DISEQC_MSGLEN]; | ||
1049 | |||
1050 | /* | ||
1051 | * Message is sent with derived else cached burst | ||
1052 | * | ||
1053 | * WRITE PORT GROUP COMMAND 38 | ||
1054 | * | ||
1055 | * 0/A/A: E0 10 38 F0..F3 | ||
1056 | * 1/B/B: E0 10 38 F4..F7 | ||
1057 | * 2/C/A: E0 10 38 F8..FB | ||
1058 | * 3/D/B: E0 10 38 FC..FF | ||
1059 | * | ||
1060 | * databyte[3]= 8421:8421 | ||
1061 | * ABCD:WXYZ | ||
1062 | * CLR :SET | ||
1063 | * | ||
1064 | * WX= PORT SELECT 0..3 (X=TONEBURST) | ||
1065 | * Y = VOLTAGE (0=13V, 1=18V) | ||
1066 | * Z = BAND (0=LOW, 1=HIGH(22K)) | ||
1067 | */ | ||
1068 | if (d->msg_len >= 4 && d->msg[2] == 0x38) | ||
1069 | state->dsec_cmd.args[CX24117_DISEQC_BURST] = | ||
1070 | ((d->msg[3] & 4) >> 2); | ||
1071 | |||
1072 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d burst=%d\n", | ||
1073 | __func__, state->demod, | ||
1074 | state->dsec_cmd.args[CX24117_DISEQC_BURST]); | ||
1075 | |||
1076 | /* Wait for LNB ready */ | ||
1077 | ret = cx24117_wait_for_lnb(fe); | ||
1078 | if (ret != 0) | ||
1079 | return ret; | ||
1080 | |||
1081 | /* Wait for voltage/min repeat delay */ | ||
1082 | msleep(100); | ||
1083 | |||
1084 | /* Command */ | ||
1085 | ret = cx24117_cmd_execute(fe, &state->dsec_cmd); | ||
1086 | if (ret != 0) | ||
1087 | return ret; | ||
1088 | /* | ||
1089 | * Wait for send | ||
1090 | * | ||
1091 | * Eutelsat spec: | ||
1092 | * >15ms delay + (XXX determine if FW does this, see set_tone) | ||
1093 | * 13.5ms per byte + | ||
1094 | * >15ms delay + | ||
1095 | * 12.5ms burst + | ||
1096 | * >15ms delay (XXX determine if FW does this, see set_tone) | ||
1097 | */ | ||
1098 | msleep((state->dsec_cmd.args[CX24117_DISEQC_MSGLEN] << 4) + 60); | ||
1099 | |||
1100 | return 0; | ||
1101 | } | ||
1102 | |||
1103 | /* Send DiSEqC burst */ | ||
1104 | static int cx24117_diseqc_send_burst(struct dvb_frontend *fe, | ||
1105 | fe_sec_mini_cmd_t burst) | ||
1106 | { | ||
1107 | struct cx24117_state *state = fe->demodulator_priv; | ||
1108 | |||
1109 | dev_dbg(&state->priv->i2c->dev, "%s(%d) demod=%d\n", | ||
1110 | __func__, burst, state->demod); | ||
1111 | |||
1112 | /* DiSEqC burst */ | ||
1113 | if (burst == SEC_MINI_A) | ||
1114 | state->dsec_cmd.args[CX24117_DISEQC_BURST] = | ||
1115 | CX24117_DISEQC_MINI_A; | ||
1116 | else if (burst == SEC_MINI_B) | ||
1117 | state->dsec_cmd.args[CX24117_DISEQC_BURST] = | ||
1118 | CX24117_DISEQC_MINI_B; | ||
1119 | else | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | static int cx24117_get_priv(struct cx24117_priv **priv, | ||
1126 | struct i2c_adapter *i2c, u8 client_address) | ||
1127 | { | ||
1128 | int ret; | ||
1129 | |||
1130 | mutex_lock(&cx24117_list_mutex); | ||
1131 | ret = hybrid_tuner_request_state(struct cx24117_priv, (*priv), | ||
1132 | hybrid_tuner_instance_list, i2c, client_address, "cx24117"); | ||
1133 | mutex_unlock(&cx24117_list_mutex); | ||
1134 | |||
1135 | return ret; | ||
1136 | } | ||
1137 | |||
1138 | static void cx24117_release_priv(struct cx24117_priv *priv) | ||
1139 | { | ||
1140 | mutex_lock(&cx24117_list_mutex); | ||
1141 | if (priv != NULL) | ||
1142 | hybrid_tuner_release_state(priv); | ||
1143 | mutex_unlock(&cx24117_list_mutex); | ||
1144 | } | ||
1145 | |||
1146 | static void cx24117_release(struct dvb_frontend *fe) | ||
1147 | { | ||
1148 | struct cx24117_state *state = fe->demodulator_priv; | ||
1149 | dev_dbg(&state->priv->i2c->dev, "%s demod%d\n", | ||
1150 | __func__, state->demod); | ||
1151 | cx24117_release_priv(state->priv); | ||
1152 | kfree(state); | ||
1153 | } | ||
1154 | |||
1155 | static struct dvb_frontend_ops cx24117_ops; | ||
1156 | |||
1157 | struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | ||
1158 | struct i2c_adapter *i2c) | ||
1159 | { | ||
1160 | struct cx24117_state *state = NULL; | ||
1161 | struct cx24117_priv *priv = NULL; | ||
1162 | int demod = 0; | ||
1163 | |||
1164 | /* get the common data struct for both demods */ | ||
1165 | demod = cx24117_get_priv(&priv, i2c, config->demod_address); | ||
1166 | |||
1167 | switch (demod) { | ||
1168 | case 0: | ||
1169 | dev_err(&state->priv->i2c->dev, | ||
1170 | "%s: Error attaching frontend %d\n", | ||
1171 | KBUILD_MODNAME, demod); | ||
1172 | goto error1; | ||
1173 | break; | ||
1174 | case 1: | ||
1175 | /* new priv instance */ | ||
1176 | priv->i2c = i2c; | ||
1177 | priv->demod_address = config->demod_address; | ||
1178 | mutex_init(&priv->fe_lock); | ||
1179 | break; | ||
1180 | default: | ||
1181 | /* existing priv instance */ | ||
1182 | break; | ||
1183 | } | ||
1184 | |||
1185 | /* allocate memory for the internal state */ | ||
1186 | state = kzalloc(sizeof(struct cx24117_state), GFP_KERNEL); | ||
1187 | if (state == NULL) | ||
1188 | goto error2; | ||
1189 | |||
1190 | state->demod = demod - 1; | ||
1191 | state->priv = priv; | ||
1192 | |||
1193 | /* test i2c bus for ack */ | ||
1194 | if (demod == 0) { | ||
1195 | if (cx24117_readreg(state, 0x00) < 0) | ||
1196 | goto error3; | ||
1197 | } | ||
1198 | |||
1199 | dev_info(&state->priv->i2c->dev, | ||
1200 | "%s: Attaching frontend %d\n", | ||
1201 | KBUILD_MODNAME, state->demod); | ||
1202 | |||
1203 | /* create dvb_frontend */ | ||
1204 | memcpy(&state->frontend.ops, &cx24117_ops, | ||
1205 | sizeof(struct dvb_frontend_ops)); | ||
1206 | state->frontend.demodulator_priv = state; | ||
1207 | return &state->frontend; | ||
1208 | |||
1209 | error3: | ||
1210 | kfree(state); | ||
1211 | error2: | ||
1212 | cx24117_release_priv(priv); | ||
1213 | error1: | ||
1214 | return NULL; | ||
1215 | } | ||
1216 | EXPORT_SYMBOL_GPL(cx24117_attach); | ||
1217 | |||
1218 | /* | ||
1219 | * Initialise or wake up device | ||
1220 | * | ||
1221 | * Power config will reset and load initial firmware if required | ||
1222 | */ | ||
1223 | static int cx24117_initfe(struct dvb_frontend *fe) | ||
1224 | { | ||
1225 | struct cx24117_state *state = fe->demodulator_priv; | ||
1226 | struct cx24117_cmd cmd; | ||
1227 | int ret; | ||
1228 | |||
1229 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", | ||
1230 | __func__, state->demod); | ||
1231 | |||
1232 | mutex_lock(&state->priv->fe_lock); | ||
1233 | |||
1234 | /* Firmware CMD 36: Power config */ | ||
1235 | cmd.args[0] = CMD_TUNERSLEEP; | ||
1236 | cmd.args[1] = (state->demod ? 1 : 0); | ||
1237 | cmd.args[2] = 0; | ||
1238 | cmd.len = 3; | ||
1239 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
1240 | if (ret != 0) | ||
1241 | goto exit; | ||
1242 | |||
1243 | ret = cx24117_diseqc_init(fe); | ||
1244 | if (ret != 0) | ||
1245 | goto exit; | ||
1246 | |||
1247 | /* CMD 3C */ | ||
1248 | cmd.args[0] = 0x3c; | ||
1249 | cmd.args[1] = (state->demod ? 1 : 0); | ||
1250 | cmd.args[2] = 0x10; | ||
1251 | cmd.args[3] = 0x10; | ||
1252 | cmd.len = 4; | ||
1253 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
1254 | if (ret != 0) | ||
1255 | goto exit; | ||
1256 | |||
1257 | /* CMD 34 */ | ||
1258 | cmd.args[0] = 0x34; | ||
1259 | cmd.args[1] = (state->demod ? 1 : 0); | ||
1260 | cmd.args[2] = CX24117_OCC; | ||
1261 | cmd.len = 3; | ||
1262 | ret = cx24117_cmd_execute_nolock(fe, &cmd); | ||
1263 | |||
1264 | exit: | ||
1265 | mutex_unlock(&state->priv->fe_lock); | ||
1266 | |||
1267 | return ret; | ||
1268 | } | ||
1269 | |||
1270 | /* | ||
1271 | * Put device to sleep | ||
1272 | */ | ||
1273 | static int cx24117_sleep(struct dvb_frontend *fe) | ||
1274 | { | ||
1275 | struct cx24117_state *state = fe->demodulator_priv; | ||
1276 | struct cx24117_cmd cmd; | ||
1277 | |||
1278 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", | ||
1279 | __func__, state->demod); | ||
1280 | |||
1281 | /* Firmware CMD 36: Power config */ | ||
1282 | cmd.args[0] = CMD_TUNERSLEEP; | ||
1283 | cmd.args[1] = (state->demod ? 1 : 0); | ||
1284 | cmd.args[2] = 1; | ||
1285 | cmd.len = 3; | ||
1286 | return cx24117_cmd_execute(fe, &cmd); | ||
1287 | } | ||
1288 | |||
1289 | /* dvb-core told us to tune, the tv property cache will be complete, | ||
1290 | * it's safe for is to pull values and use them for tuning purposes. | ||
1291 | */ | ||
1292 | static int cx24117_set_frontend(struct dvb_frontend *fe) | ||
1293 | { | ||
1294 | struct cx24117_state *state = fe->demodulator_priv; | ||
1295 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
1296 | struct cx24117_cmd cmd; | ||
1297 | fe_status_t tunerstat; | ||
1298 | int i, status, ret, retune = 1; | ||
1299 | u8 reg_clkdiv, reg_ratediv; | ||
1300 | |||
1301 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", | ||
1302 | __func__, state->demod); | ||
1303 | |||
1304 | switch (c->delivery_system) { | ||
1305 | case SYS_DVBS: | ||
1306 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d DVB-S\n", | ||
1307 | __func__, state->demod); | ||
1308 | |||
1309 | /* Only QPSK is supported for DVB-S */ | ||
1310 | if (c->modulation != QPSK) { | ||
1311 | dev_dbg(&state->priv->i2c->dev, | ||
1312 | "%s() demod%d unsupported modulation (%d)\n", | ||
1313 | __func__, state->demod, c->modulation); | ||
1314 | return -EINVAL; | ||
1315 | } | ||
1316 | |||
1317 | /* Pilot doesn't exist in DVB-S, turn bit off */ | ||
1318 | state->dnxt.pilot_val = CX24117_PILOT_OFF; | ||
1319 | |||
1320 | /* DVB-S only supports 0.35 */ | ||
1321 | state->dnxt.rolloff_val = CX24117_ROLLOFF_035; | ||
1322 | break; | ||
1323 | |||
1324 | case SYS_DVBS2: | ||
1325 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d DVB-S2\n", | ||
1326 | __func__, state->demod); | ||
1327 | |||
1328 | /* | ||
1329 | * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, | ||
1330 | * but not hardware auto detection | ||
1331 | */ | ||
1332 | if (c->modulation != PSK_8 && c->modulation != QPSK) { | ||
1333 | dev_dbg(&state->priv->i2c->dev, | ||
1334 | "%s() demod%d unsupported modulation (%d)\n", | ||
1335 | __func__, state->demod, c->modulation); | ||
1336 | return -EOPNOTSUPP; | ||
1337 | } | ||
1338 | |||
1339 | switch (c->pilot) { | ||
1340 | case PILOT_AUTO: | ||
1341 | state->dnxt.pilot_val = CX24117_PILOT_AUTO; | ||
1342 | break; | ||
1343 | case PILOT_OFF: | ||
1344 | state->dnxt.pilot_val = CX24117_PILOT_OFF; | ||
1345 | break; | ||
1346 | case PILOT_ON: | ||
1347 | state->dnxt.pilot_val = CX24117_PILOT_ON; | ||
1348 | break; | ||
1349 | default: | ||
1350 | dev_dbg(&state->priv->i2c->dev, | ||
1351 | "%s() demod%d unsupported pilot mode (%d)\n", | ||
1352 | __func__, state->demod, c->pilot); | ||
1353 | return -EOPNOTSUPP; | ||
1354 | } | ||
1355 | |||
1356 | switch (c->rolloff) { | ||
1357 | case ROLLOFF_20: | ||
1358 | state->dnxt.rolloff_val = CX24117_ROLLOFF_020; | ||
1359 | break; | ||
1360 | case ROLLOFF_25: | ||
1361 | state->dnxt.rolloff_val = CX24117_ROLLOFF_025; | ||
1362 | break; | ||
1363 | case ROLLOFF_35: | ||
1364 | state->dnxt.rolloff_val = CX24117_ROLLOFF_035; | ||
1365 | break; | ||
1366 | case ROLLOFF_AUTO: | ||
1367 | state->dnxt.rolloff_val = CX24117_ROLLOFF_035; | ||
1368 | /* soft-auto rolloff */ | ||
1369 | retune = 3; | ||
1370 | break; | ||
1371 | default: | ||
1372 | dev_warn(&state->priv->i2c->dev, | ||
1373 | "%s: demod%d unsupported rolloff (%d)\n", | ||
1374 | KBUILD_MODNAME, state->demod, c->rolloff); | ||
1375 | return -EOPNOTSUPP; | ||
1376 | } | ||
1377 | break; | ||
1378 | |||
1379 | default: | ||
1380 | dev_warn(&state->priv->i2c->dev, | ||
1381 | "%s: demod %d unsupported delivery system (%d)\n", | ||
1382 | KBUILD_MODNAME, state->demod, c->delivery_system); | ||
1383 | return -EINVAL; | ||
1384 | } | ||
1385 | |||
1386 | state->dnxt.delsys = c->delivery_system; | ||
1387 | state->dnxt.modulation = c->modulation; | ||
1388 | state->dnxt.frequency = c->frequency; | ||
1389 | state->dnxt.pilot = c->pilot; | ||
1390 | state->dnxt.rolloff = c->rolloff; | ||
1391 | |||
1392 | ret = cx24117_set_inversion(state, c->inversion); | ||
1393 | if (ret != 0) | ||
1394 | return ret; | ||
1395 | |||
1396 | ret = cx24117_set_fec(state, | ||
1397 | c->delivery_system, c->modulation, c->fec_inner); | ||
1398 | if (ret != 0) | ||
1399 | return ret; | ||
1400 | |||
1401 | ret = cx24117_set_symbolrate(state, c->symbol_rate); | ||
1402 | if (ret != 0) | ||
1403 | return ret; | ||
1404 | |||
1405 | /* discard the 'current' tuning parameters and prepare to tune */ | ||
1406 | cx24117_clone_params(fe); | ||
1407 | |||
1408 | dev_dbg(&state->priv->i2c->dev, | ||
1409 | "%s: delsys = %d\n", __func__, state->dcur.delsys); | ||
1410 | dev_dbg(&state->priv->i2c->dev, | ||
1411 | "%s: modulation = %d\n", __func__, state->dcur.modulation); | ||
1412 | dev_dbg(&state->priv->i2c->dev, | ||
1413 | "%s: frequency = %d\n", __func__, state->dcur.frequency); | ||
1414 | dev_dbg(&state->priv->i2c->dev, | ||
1415 | "%s: pilot = %d (val = 0x%02x)\n", __func__, | ||
1416 | state->dcur.pilot, state->dcur.pilot_val); | ||
1417 | dev_dbg(&state->priv->i2c->dev, | ||
1418 | "%s: retune = %d\n", __func__, retune); | ||
1419 | dev_dbg(&state->priv->i2c->dev, | ||
1420 | "%s: rolloff = %d (val = 0x%02x)\n", __func__, | ||
1421 | state->dcur.rolloff, state->dcur.rolloff_val); | ||
1422 | dev_dbg(&state->priv->i2c->dev, | ||
1423 | "%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); | ||
1424 | dev_dbg(&state->priv->i2c->dev, | ||
1425 | "%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, | ||
1426 | state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); | ||
1427 | dev_dbg(&state->priv->i2c->dev, | ||
1428 | "%s: Inversion = %d (val = 0x%02x)\n", __func__, | ||
1429 | state->dcur.inversion, state->dcur.inversion_val); | ||
1430 | |||
1431 | /* Prepare a tune request */ | ||
1432 | cmd.args[0] = CMD_TUNEREQUEST; | ||
1433 | |||
1434 | /* demod */ | ||
1435 | cmd.args[1] = state->demod; | ||
1436 | |||
1437 | /* Frequency */ | ||
1438 | cmd.args[2] = (state->dcur.frequency & 0xff0000) >> 16; | ||
1439 | cmd.args[3] = (state->dcur.frequency & 0x00ff00) >> 8; | ||
1440 | cmd.args[4] = (state->dcur.frequency & 0x0000ff); | ||
1441 | |||
1442 | /* Symbol Rate */ | ||
1443 | cmd.args[5] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; | ||
1444 | cmd.args[6] = ((state->dcur.symbol_rate / 1000) & 0x00ff); | ||
1445 | |||
1446 | /* Automatic Inversion */ | ||
1447 | cmd.args[7] = state->dcur.inversion_val; | ||
1448 | |||
1449 | /* Modulation / FEC / Pilot */ | ||
1450 | cmd.args[8] = state->dcur.fec_val | state->dcur.pilot_val; | ||
1451 | |||
1452 | cmd.args[9] = CX24117_SEARCH_RANGE_KHZ >> 8; | ||
1453 | cmd.args[10] = CX24117_SEARCH_RANGE_KHZ & 0xff; | ||
1454 | |||
1455 | cmd.args[11] = state->dcur.rolloff_val; | ||
1456 | cmd.args[12] = state->dcur.fec_mask; | ||
1457 | |||
1458 | if (state->dcur.symbol_rate > 30000000) { | ||
1459 | reg_ratediv = 0x04; | ||
1460 | reg_clkdiv = 0x02; | ||
1461 | } else if (state->dcur.symbol_rate > 10000000) { | ||
1462 | reg_ratediv = 0x06; | ||
1463 | reg_clkdiv = 0x03; | ||
1464 | } else { | ||
1465 | reg_ratediv = 0x0a; | ||
1466 | reg_clkdiv = 0x05; | ||
1467 | } | ||
1468 | |||
1469 | cmd.args[13] = reg_ratediv; | ||
1470 | cmd.args[14] = reg_clkdiv; | ||
1471 | |||
1472 | cx24117_writereg(state, (state->demod == 0) ? | ||
1473 | CX24117_REG_CLKDIV0 : CX24117_REG_CLKDIV1, reg_clkdiv); | ||
1474 | cx24117_writereg(state, (state->demod == 0) ? | ||
1475 | CX24117_REG_RATEDIV0 : CX24117_REG_RATEDIV1, reg_ratediv); | ||
1476 | |||
1477 | cmd.args[15] = CX24117_PNE; | ||
1478 | cmd.len = 16; | ||
1479 | |||
1480 | do { | ||
1481 | /* Reset status register */ | ||
1482 | status = cx24117_readreg(state, (state->demod == 0) ? | ||
1483 | CX24117_REG_SSTATUS0 : CX24117_REG_SSTATUS1) & | ||
1484 | CX24117_SIGNAL_MASK; | ||
1485 | |||
1486 | dev_dbg(&state->priv->i2c->dev, | ||
1487 | "%s() demod%d status_setfe = %02x\n", | ||
1488 | __func__, state->demod, status); | ||
1489 | |||
1490 | cx24117_writereg(state, (state->demod == 0) ? | ||
1491 | CX24117_REG_SSTATUS0 : CX24117_REG_SSTATUS1, status); | ||
1492 | |||
1493 | /* Tune */ | ||
1494 | ret = cx24117_cmd_execute(fe, &cmd); | ||
1495 | if (ret != 0) | ||
1496 | break; | ||
1497 | |||
1498 | /* | ||
1499 | * Wait for up to 500 ms before retrying | ||
1500 | * | ||
1501 | * If we are able to tune then generally it occurs within 100ms. | ||
1502 | * If it takes longer, try a different rolloff setting. | ||
1503 | */ | ||
1504 | for (i = 0; i < 50; i++) { | ||
1505 | cx24117_read_status(fe, &tunerstat); | ||
1506 | status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); | ||
1507 | if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { | ||
1508 | dev_dbg(&state->priv->i2c->dev, | ||
1509 | "%s() demod%d tuned\n", | ||
1510 | __func__, state->demod); | ||
1511 | return 0; | ||
1512 | } | ||
1513 | msleep(20); | ||
1514 | } | ||
1515 | |||
1516 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d not tuned\n", | ||
1517 | __func__, state->demod); | ||
1518 | |||
1519 | /* try next rolloff value */ | ||
1520 | if (state->dcur.rolloff == 3) | ||
1521 | cmd.args[11]--; | ||
1522 | |||
1523 | } while (--retune); | ||
1524 | return -EINVAL; | ||
1525 | } | ||
1526 | |||
1527 | static int cx24117_tune(struct dvb_frontend *fe, bool re_tune, | ||
1528 | unsigned int mode_flags, unsigned int *delay, fe_status_t *status) | ||
1529 | { | ||
1530 | struct cx24117_state *state = fe->demodulator_priv; | ||
1531 | |||
1532 | dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", | ||
1533 | __func__, state->demod); | ||
1534 | |||
1535 | *delay = HZ / 5; | ||
1536 | if (re_tune) { | ||
1537 | int ret = cx24117_set_frontend(fe); | ||
1538 | if (ret) | ||
1539 | return ret; | ||
1540 | } | ||
1541 | return cx24117_read_status(fe, status); | ||
1542 | } | ||
1543 | |||
1544 | static int cx24117_get_algo(struct dvb_frontend *fe) | ||
1545 | { | ||
1546 | return DVBFE_ALGO_HW; | ||
1547 | } | ||
1548 | |||
1549 | static int cx24117_get_frontend(struct dvb_frontend *fe) | ||
1550 | { | ||
1551 | struct cx24117_state *state = fe->demodulator_priv; | ||
1552 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
1553 | struct cx24117_cmd cmd; | ||
1554 | u8 reg, st, inv; | ||
1555 | int ret, idx; | ||
1556 | unsigned int freq; | ||
1557 | short srate_os, freq_os; | ||
1558 | |||
1559 | u8 buf[0x1f-4]; | ||
1560 | |||
1561 | cmd.args[0] = 0x1c; | ||
1562 | cmd.args[1] = (u8) state->demod; | ||
1563 | cmd.len = 2; | ||
1564 | ret = cx24117_cmd_execute(fe, &cmd); | ||
1565 | if (ret != 0) | ||
1566 | return ret; | ||
1567 | |||
1568 | /* read all required regs at once */ | ||
1569 | reg = (state->demod == 0) ? CX24117_REG_FREQ3_0 : CX24117_REG_FREQ3_1; | ||
1570 | ret = cx24117_readregN(state, reg, buf, 0x1f-4); | ||
1571 | if (ret != 0) | ||
1572 | return ret; | ||
1573 | |||
1574 | st = buf[5]; | ||
1575 | |||
1576 | /* get spectral inversion */ | ||
1577 | inv = (((state->demod == 0) ? ~st : st) >> 6) & 1; | ||
1578 | if (inv == 0) | ||
1579 | c->inversion = INVERSION_OFF; | ||
1580 | else | ||
1581 | c->inversion = INVERSION_ON; | ||
1582 | |||
1583 | /* modulation and fec */ | ||
1584 | idx = st & 0x3f; | ||
1585 | if (c->delivery_system == SYS_DVBS2) { | ||
1586 | if (idx > 11) | ||
1587 | idx += 9; | ||
1588 | else | ||
1589 | idx += 7; | ||
1590 | } | ||
1591 | |||
1592 | c->modulation = cx24117_modfec_modes[idx].modulation; | ||
1593 | c->fec_inner = cx24117_modfec_modes[idx].fec; | ||
1594 | |||
1595 | /* frequency */ | ||
1596 | freq = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | ||
1597 | freq_os = (buf[8] << 8) | buf[9]; | ||
1598 | c->frequency = freq + freq_os; | ||
1599 | |||
1600 | /* symbol rate */ | ||
1601 | srate_os = (buf[10] << 8) | buf[11]; | ||
1602 | c->symbol_rate = -1000 * srate_os + state->dcur.symbol_rate; | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static struct dvb_frontend_ops cx24117_ops = { | ||
1607 | .delsys = { SYS_DVBS, SYS_DVBS2 }, | ||
1608 | .info = { | ||
1609 | .name = "Conexant CX24117/CX24132", | ||
1610 | .frequency_min = 950000, | ||
1611 | .frequency_max = 2150000, | ||
1612 | .frequency_stepsize = 1011, /* kHz for QPSK frontends */ | ||
1613 | .frequency_tolerance = 5000, | ||
1614 | .symbol_rate_min = 1000000, | ||
1615 | .symbol_rate_max = 45000000, | ||
1616 | .caps = FE_CAN_INVERSION_AUTO | | ||
1617 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
1618 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | ||
1619 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
1620 | FE_CAN_2G_MODULATION | | ||
1621 | FE_CAN_QPSK | FE_CAN_RECOVER | ||
1622 | }, | ||
1623 | |||
1624 | .release = cx24117_release, | ||
1625 | |||
1626 | .init = cx24117_initfe, | ||
1627 | .sleep = cx24117_sleep, | ||
1628 | .read_status = cx24117_read_status, | ||
1629 | .read_ber = cx24117_read_ber, | ||
1630 | .read_signal_strength = cx24117_read_signal_strength, | ||
1631 | .read_snr = cx24117_read_snr, | ||
1632 | .read_ucblocks = cx24117_read_ucblocks, | ||
1633 | .set_tone = cx24117_set_tone, | ||
1634 | .set_voltage = cx24117_set_voltage, | ||
1635 | .diseqc_send_master_cmd = cx24117_send_diseqc_msg, | ||
1636 | .diseqc_send_burst = cx24117_diseqc_send_burst, | ||
1637 | .get_frontend_algo = cx24117_get_algo, | ||
1638 | .tune = cx24117_tune, | ||
1639 | |||
1640 | .set_frontend = cx24117_set_frontend, | ||
1641 | .get_frontend = cx24117_get_frontend, | ||
1642 | }; | ||
1643 | |||
1644 | |||
1645 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24117/cx24132 hardware"); | ||
1646 | MODULE_AUTHOR("Luis Alves (ljalvs@gmail.com)"); | ||
1647 | MODULE_LICENSE("GPL"); | ||
1648 | MODULE_VERSION("1.1"); | ||
1649 | MODULE_FIRMWARE(CX24117_DEFAULT_FIRMWARE); | ||
1650 | |||
diff --git a/drivers/media/dvb-frontends/cx24117.h b/drivers/media/dvb-frontends/cx24117.h new file mode 100644 index 000000000000..4e59e9574fa7 --- /dev/null +++ b/drivers/media/dvb-frontends/cx24117.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | Conexant cx24117/cx24132 - Dual DVBS/S2 Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2013 Luis Alves <ljalvs@gmail.com> | ||
5 | (based on cx24116.h by Steven Toth) | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef CX24117_H | ||
23 | #define CX24117_H | ||
24 | |||
25 | #include <linux/kconfig.h> | ||
26 | #include <linux/dvb/frontend.h> | ||
27 | |||
28 | struct cx24117_config { | ||
29 | /* the demodulator's i2c address */ | ||
30 | u8 demod_address; | ||
31 | }; | ||
32 | |||
33 | #if IS_ENABLED(CONFIG_DVB_CX24117) | ||
34 | extern struct dvb_frontend *cx24117_attach( | ||
35 | const struct cx24117_config *config, | ||
36 | struct i2c_adapter *i2c); | ||
37 | #else | ||
38 | static inline struct dvb_frontend *cx24117_attach( | ||
39 | const struct cx24117_config *config, | ||
40 | struct i2c_adapter *i2c) | ||
41 | { | ||
42 | dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); | ||
43 | return NULL; | ||
44 | } | ||
45 | #endif | ||
46 | |||
47 | #endif /* CX24117_H */ | ||
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index a771da3e9f99..72fb5838cae0 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c | |||
@@ -739,7 +739,7 @@ static int cx24123_set_voltage(struct dvb_frontend *fe, | |||
739 | return 0; | 739 | return 0; |
740 | default: | 740 | default: |
741 | return -EINVAL; | 741 | return -EINVAL; |
742 | }; | 742 | } |
743 | 743 | ||
744 | return 0; | 744 | return 0; |
745 | } | 745 | } |
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 7ca5c69dd200..d9eeeb1dfa96 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c | |||
@@ -31,7 +31,7 @@ static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, | |||
31 | { | 31 | { |
32 | .addr = i2c, | 32 | .addr = i2c, |
33 | .flags = 0, | 33 | .flags = 0, |
34 | .len = sizeof(buf), | 34 | .len = len + 1, |
35 | .buf = buf, | 35 | .buf = buf, |
36 | } | 36 | } |
37 | }; | 37 | }; |
@@ -65,7 +65,7 @@ static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, | |||
65 | }, { | 65 | }, { |
66 | .addr = i2c, | 66 | .addr = i2c, |
67 | .flags = I2C_M_RD, | 67 | .flags = I2C_M_RD, |
68 | .len = sizeof(buf), | 68 | .len = len, |
69 | .buf = buf, | 69 | .buf = buf, |
70 | } | 70 | } |
71 | }; | 71 | }; |
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 6201c59a78dd..e540cfb13bac 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c | |||
@@ -649,9 +649,9 @@ static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 si | |||
649 | b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */ | 649 | b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */ |
650 | if (*b == '~') { | 650 | if (*b == '~') { |
651 | b++; | 651 | b++; |
652 | dprintk(b); | 652 | dprintk("%s", b); |
653 | } else | 653 | } else |
654 | dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>"); | 654 | dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<empty>"); |
655 | return 1; | 655 | return 1; |
656 | } | 656 | } |
657 | 657 | ||
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 9a2134792cfa..959ae36403b8 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c | |||
@@ -46,10 +46,6 @@ | |||
46 | #define DRX_I2C_MODEFLAGS 0xC0 | 46 | #define DRX_I2C_MODEFLAGS 0xC0 |
47 | #define DRX_I2C_FLAGS 0xF0 | 47 | #define DRX_I2C_FLAGS 0xF0 |
48 | 48 | ||
49 | #ifndef SIZEOF_ARRAY | ||
50 | #define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0])) | ||
51 | #endif | ||
52 | |||
53 | #define DEFAULT_LOCK_TIMEOUT 1100 | 49 | #define DEFAULT_LOCK_TIMEOUT 1100 |
54 | 50 | ||
55 | #define DRX_CHANNEL_AUTO 0 | 51 | #define DRX_CHANNEL_AUTO 0 |
@@ -1018,7 +1014,7 @@ static int HI_CfgCommand(struct drxd_state *state) | |||
1018 | status = Write16(state, HI_RA_RAM_SRV_CMD__A, | 1014 | status = Write16(state, HI_RA_RAM_SRV_CMD__A, |
1019 | HI_RA_RAM_SRV_CMD_CONFIG, 0); | 1015 | HI_RA_RAM_SRV_CMD_CONFIG, 0); |
1020 | else | 1016 | else |
1021 | status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0); | 1017 | status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, NULL); |
1022 | mutex_unlock(&state->mutex); | 1018 | mutex_unlock(&state->mutex); |
1023 | return status; | 1019 | return status; |
1024 | } | 1020 | } |
@@ -1039,7 +1035,7 @@ static int HI_ResetCommand(struct drxd_state *state) | |||
1039 | status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A, | 1035 | status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A, |
1040 | HI_RA_RAM_SRV_RST_KEY_ACT, 0); | 1036 | HI_RA_RAM_SRV_RST_KEY_ACT, 0); |
1041 | if (status == 0) | 1037 | if (status == 0) |
1042 | status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0); | 1038 | status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, NULL); |
1043 | mutex_unlock(&state->mutex); | 1039 | mutex_unlock(&state->mutex); |
1044 | msleep(1); | 1040 | msleep(1); |
1045 | return status; | 1041 | return status; |
@@ -2837,7 +2833,7 @@ static int drxd_init(struct dvb_frontend *fe) | |||
2837 | int err = 0; | 2833 | int err = 0; |
2838 | 2834 | ||
2839 | /* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */ | 2835 | /* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */ |
2840 | return DRXD_init(state, 0, 0); | 2836 | return DRXD_init(state, NULL, 0); |
2841 | 2837 | ||
2842 | err = DRXD_init(state, state->fw->data, state->fw->size); | 2838 | err = DRXD_init(state, state->fw->data, state->fw->size); |
2843 | release_firmware(state->fw); | 2839 | release_firmware(state->fw); |
@@ -2973,7 +2969,7 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config, | |||
2973 | 2969 | ||
2974 | mutex_init(&state->mutex); | 2970 | mutex_init(&state->mutex); |
2975 | 2971 | ||
2976 | if (Read16(state, 0, 0, 0) < 0) | 2972 | if (Read16(state, 0, NULL, 0) < 0) |
2977 | goto error; | 2973 | goto error; |
2978 | 2974 | ||
2979 | state->frontend.ops = drxd_ops; | 2975 | state->frontend.ops = drxd_ops; |
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index 082014de6875..d416c15691da 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c | |||
@@ -1083,7 +1083,7 @@ static int hi_cfg_command(struct drxk_state *state) | |||
1083 | SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); | 1083 | SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); |
1084 | if (status < 0) | 1084 | if (status < 0) |
1085 | goto error; | 1085 | goto error; |
1086 | status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0); | 1086 | status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); |
1087 | if (status < 0) | 1087 | if (status < 0) |
1088 | goto error; | 1088 | goto error; |
1089 | 1089 | ||
@@ -2781,7 +2781,7 @@ static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) | |||
2781 | goto error; | 2781 | goto error; |
2782 | } | 2782 | } |
2783 | 2783 | ||
2784 | status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0); | 2784 | status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); |
2785 | 2785 | ||
2786 | error: | 2786 | error: |
2787 | if (status < 0) | 2787 | if (status < 0) |
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index facb84841518..a95dfe0a5ce3 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c | |||
@@ -489,6 +489,7 @@ static int rtl2832_init(struct dvb_frontend *fe) | |||
489 | init = rtl2832_tuner_init_e4000; | 489 | init = rtl2832_tuner_init_e4000; |
490 | break; | 490 | break; |
491 | case RTL2832_TUNER_R820T: | 491 | case RTL2832_TUNER_R820T: |
492 | case RTL2832_TUNER_R828D: | ||
492 | len = ARRAY_SIZE(rtl2832_tuner_init_r820t); | 493 | len = ARRAY_SIZE(rtl2832_tuner_init_r820t); |
493 | init = rtl2832_tuner_init_r820t; | 494 | init = rtl2832_tuner_init_r820t; |
494 | break; | 495 | break; |
diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h index 91b2dcf5a6ea..2cfbb6a97061 100644 --- a/drivers/media/dvb-frontends/rtl2832.h +++ b/drivers/media/dvb-frontends/rtl2832.h | |||
@@ -53,6 +53,7 @@ struct rtl2832_config { | |||
53 | #define RTL2832_TUNER_E4000 0x27 | 53 | #define RTL2832_TUNER_E4000 0x27 |
54 | #define RTL2832_TUNER_FC0013 0x29 | 54 | #define RTL2832_TUNER_FC0013 0x29 |
55 | #define RTL2832_TUNER_R820T 0x2a | 55 | #define RTL2832_TUNER_R820T 0x2a |
56 | #define RTL2832_TUNER_R828D 0x2b | ||
56 | u8 tuner; | 57 | u8 tuner; |
57 | }; | 58 | }; |
58 | 59 | ||
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c index 9d08350fe4b0..69e62f42e2e1 100644 --- a/drivers/media/dvb-frontends/tda8083.c +++ b/drivers/media/dvb-frontends/tda8083.c | |||
@@ -189,7 +189,7 @@ static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t ton | |||
189 | return tda8083_writereg (state, 0x29, 0x80); | 189 | return tda8083_writereg (state, 0x29, 0x80); |
190 | default: | 190 | default: |
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | }; | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
195 | static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) | 195 | static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) |
@@ -201,7 +201,7 @@ static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t vo | |||
201 | return tda8083_writereg (state, 0x20, 0x11); | 201 | return tda8083_writereg (state, 0x20, 0x11); |
202 | default: | 202 | default: |
203 | return -EINVAL; | 203 | return -EINVAL; |
204 | }; | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
207 | static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) | 207 | static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) |
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index ad7ad857ab2a..9aba044dabed 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c | |||
@@ -31,6 +31,7 @@ struct ts2020_priv { | |||
31 | struct i2c_adapter *i2c; | 31 | struct i2c_adapter *i2c; |
32 | u8 clk_out_div; | 32 | u8 clk_out_div; |
33 | u32 frequency; | 33 | u32 frequency; |
34 | u32 frequency_div; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | static int ts2020_release(struct dvb_frontend *fe) | 37 | static int ts2020_release(struct dvb_frontend *fe) |
@@ -193,7 +194,7 @@ static int ts2020_set_params(struct dvb_frontend *fe) | |||
193 | u8 lo = 0x01, div4 = 0x0; | 194 | u8 lo = 0x01, div4 = 0x0; |
194 | 195 | ||
195 | /* Calculate frequency divider */ | 196 | /* Calculate frequency divider */ |
196 | if (frequency < 1060000) { | 197 | if (frequency < priv->frequency_div) { |
197 | lo |= 0x10; | 198 | lo |= 0x10; |
198 | div4 = 0x1; | 199 | div4 = 0x1; |
199 | ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ; | 200 | ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ; |
@@ -340,8 +341,12 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, | |||
340 | priv->i2c_address = config->tuner_address; | 341 | priv->i2c_address = config->tuner_address; |
341 | priv->i2c = i2c; | 342 | priv->i2c = i2c; |
342 | priv->clk_out_div = config->clk_out_div; | 343 | priv->clk_out_div = config->clk_out_div; |
344 | priv->frequency_div = config->frequency_div; | ||
343 | fe->tuner_priv = priv; | 345 | fe->tuner_priv = priv; |
344 | 346 | ||
347 | if (!priv->frequency_div) | ||
348 | priv->frequency_div = 1060000; | ||
349 | |||
345 | /* Wake Up the tuner */ | 350 | /* Wake Up the tuner */ |
346 | if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) { | 351 | if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) { |
347 | ts2020_writereg(fe, 0x00, 0x01); | 352 | ts2020_writereg(fe, 0x00, 0x01); |
diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index 5bcb9a71ca80..b2fe6bb3a38b 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h | |||
@@ -28,6 +28,7 @@ | |||
28 | struct ts2020_config { | 28 | struct ts2020_config { |
29 | u8 tuner_address; | 29 | u8 tuner_address; |
30 | u8 clk_out_div; | 30 | u8 clk_out_div; |
31 | u32 frequency_div; | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | #if IS_ENABLED(CONFIG_DVB_TS2020) | 34 | #if IS_ENABLED(CONFIG_DVB_TS2020) |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index cbc9ee9bec2b..842654d33317 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
@@ -621,6 +621,15 @@ config VIDEO_AS3645A | |||
621 | This is a driver for the AS3645A and LM3555 flash controllers. It has | 621 | This is a driver for the AS3645A and LM3555 flash controllers. It has |
622 | build in control for flash, torch and indicator LEDs. | 622 | build in control for flash, torch and indicator LEDs. |
623 | 623 | ||
624 | config VIDEO_LM3560 | ||
625 | tristate "LM3560 dual flash driver support" | ||
626 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
627 | depends on MEDIA_CAMERA_SUPPORT | ||
628 | select REGMAP_I2C | ||
629 | ---help--- | ||
630 | This is a driver for the lm3560 dual flash controllers. It controls | ||
631 | flash, torch LEDs. | ||
632 | |||
624 | comment "Video improvement chips" | 633 | comment "Video improvement chips" |
625 | 634 | ||
626 | config VIDEO_UPD64031A | 635 | config VIDEO_UPD64031A |
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 9f462df77b4a..e03f1776f4f4 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile | |||
@@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o | |||
70 | obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ | 70 | obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ |
71 | obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o | 71 | obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o |
72 | obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o | 72 | obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o |
73 | obj-$(CONFIG_VIDEO_LM3560) += lm3560.o | ||
73 | obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o | 74 | obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o |
74 | obj-$(CONFIG_VIDEO_AK881X) += ak881x.o | 75 | obj-$(CONFIG_VIDEO_AK881X) += ak881x.o |
75 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | 76 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o |
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index aeb56c53e39f..d4e15a617c3b 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/of.h> | ||
28 | 29 | ||
29 | #include <media/adv7343.h> | 30 | #include <media/adv7343.h> |
30 | #include <media/v4l2-async.h> | 31 | #include <media/v4l2-async.h> |
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c new file mode 100644 index 000000000000..3317a9ae3961 --- /dev/null +++ b/drivers/media/i2c/lm3560.c | |||
@@ -0,0 +1,488 @@ | |||
1 | /* | ||
2 | * drivers/media/i2c/lm3560.c | ||
3 | * General device driver for TI lm3560, FLASH LED Driver | ||
4 | * | ||
5 | * Copyright (C) 2013 Texas Instruments | ||
6 | * | ||
7 | * Contact: Daniel Jeong <gshark.jeong@gmail.com> | ||
8 | * Ldd-Mlp <ldd-mlp@list.ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * version 2 as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/delay.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/regmap.h> | ||
32 | #include <linux/videodev2.h> | ||
33 | #include <media/lm3560.h> | ||
34 | #include <media/v4l2-ctrls.h> | ||
35 | #include <media/v4l2-device.h> | ||
36 | |||
37 | /* registers definitions */ | ||
38 | #define REG_ENABLE 0x10 | ||
39 | #define REG_TORCH_BR 0xa0 | ||
40 | #define REG_FLASH_BR 0xb0 | ||
41 | #define REG_FLASH_TOUT 0xc0 | ||
42 | #define REG_FLAG 0xd0 | ||
43 | #define REG_CONFIG1 0xe0 | ||
44 | |||
45 | /* Fault Mask */ | ||
46 | #define FAULT_TIMEOUT (1<<0) | ||
47 | #define FAULT_OVERTEMP (1<<1) | ||
48 | #define FAULT_SHORT_CIRCUIT (1<<2) | ||
49 | |||
50 | enum led_enable { | ||
51 | MODE_SHDN = 0x0, | ||
52 | MODE_TORCH = 0x2, | ||
53 | MODE_FLASH = 0x3, | ||
54 | }; | ||
55 | |||
56 | /* struct lm3560_flash | ||
57 | * | ||
58 | * @pdata: platform data | ||
59 | * @regmap: reg. map for i2c | ||
60 | * @lock: muxtex for serial access. | ||
61 | * @led_mode: V4L2 LED mode | ||
62 | * @ctrls_led: V4L2 contols | ||
63 | * @subdev_led: V4L2 subdev | ||
64 | */ | ||
65 | struct lm3560_flash { | ||
66 | struct device *dev; | ||
67 | struct lm3560_platform_data *pdata; | ||
68 | struct regmap *regmap; | ||
69 | struct mutex lock; | ||
70 | |||
71 | enum v4l2_flash_led_mode led_mode; | ||
72 | struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX]; | ||
73 | struct v4l2_subdev subdev_led[LM3560_LED_MAX]; | ||
74 | }; | ||
75 | |||
76 | #define to_lm3560_flash(_ctrl, _no) \ | ||
77 | container_of(_ctrl->handler, struct lm3560_flash, ctrls_led[_no]) | ||
78 | |||
79 | /* enable mode control */ | ||
80 | static int lm3560_mode_ctrl(struct lm3560_flash *flash) | ||
81 | { | ||
82 | int rval = -EINVAL; | ||
83 | |||
84 | switch (flash->led_mode) { | ||
85 | case V4L2_FLASH_LED_MODE_NONE: | ||
86 | rval = regmap_update_bits(flash->regmap, | ||
87 | REG_ENABLE, 0x03, MODE_SHDN); | ||
88 | break; | ||
89 | case V4L2_FLASH_LED_MODE_TORCH: | ||
90 | rval = regmap_update_bits(flash->regmap, | ||
91 | REG_ENABLE, 0x03, MODE_TORCH); | ||
92 | break; | ||
93 | case V4L2_FLASH_LED_MODE_FLASH: | ||
94 | rval = regmap_update_bits(flash->regmap, | ||
95 | REG_ENABLE, 0x03, MODE_FLASH); | ||
96 | break; | ||
97 | } | ||
98 | return rval; | ||
99 | } | ||
100 | |||
101 | /* led1/2 enable/disable */ | ||
102 | static int lm3560_enable_ctrl(struct lm3560_flash *flash, | ||
103 | enum lm3560_led_id led_no, bool on) | ||
104 | { | ||
105 | int rval; | ||
106 | |||
107 | if (led_no == LM3560_LED0) { | ||
108 | if (on == true) | ||
109 | rval = regmap_update_bits(flash->regmap, | ||
110 | REG_ENABLE, 0x08, 0x08); | ||
111 | else | ||
112 | rval = regmap_update_bits(flash->regmap, | ||
113 | REG_ENABLE, 0x08, 0x00); | ||
114 | } else { | ||
115 | if (on == true) | ||
116 | rval = regmap_update_bits(flash->regmap, | ||
117 | REG_ENABLE, 0x10, 0x10); | ||
118 | else | ||
119 | rval = regmap_update_bits(flash->regmap, | ||
120 | REG_ENABLE, 0x10, 0x00); | ||
121 | } | ||
122 | return rval; | ||
123 | } | ||
124 | |||
125 | /* torch1/2 brightness control */ | ||
126 | static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash, | ||
127 | enum lm3560_led_id led_no, unsigned int brt) | ||
128 | { | ||
129 | int rval; | ||
130 | u8 br_bits; | ||
131 | |||
132 | if (brt < LM3560_TORCH_BRT_MIN) | ||
133 | return lm3560_enable_ctrl(flash, led_no, false); | ||
134 | else | ||
135 | rval = lm3560_enable_ctrl(flash, led_no, true); | ||
136 | |||
137 | br_bits = LM3560_TORCH_BRT_uA_TO_REG(brt); | ||
138 | if (led_no == LM3560_LED0) | ||
139 | rval = regmap_update_bits(flash->regmap, | ||
140 | REG_TORCH_BR, 0x07, br_bits); | ||
141 | else | ||
142 | rval = regmap_update_bits(flash->regmap, | ||
143 | REG_TORCH_BR, 0x38, br_bits << 3); | ||
144 | |||
145 | return rval; | ||
146 | } | ||
147 | |||
148 | /* flash1/2 brightness control */ | ||
149 | static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash, | ||
150 | enum lm3560_led_id led_no, unsigned int brt) | ||
151 | { | ||
152 | int rval; | ||
153 | u8 br_bits; | ||
154 | |||
155 | if (brt < LM3560_FLASH_BRT_MIN) | ||
156 | return lm3560_enable_ctrl(flash, led_no, false); | ||
157 | else | ||
158 | rval = lm3560_enable_ctrl(flash, led_no, true); | ||
159 | |||
160 | br_bits = LM3560_FLASH_BRT_uA_TO_REG(brt); | ||
161 | if (led_no == LM3560_LED0) | ||
162 | rval = regmap_update_bits(flash->regmap, | ||
163 | REG_FLASH_BR, 0x0f, br_bits); | ||
164 | else | ||
165 | rval = regmap_update_bits(flash->regmap, | ||
166 | REG_FLASH_BR, 0xf0, br_bits << 4); | ||
167 | |||
168 | return rval; | ||
169 | } | ||
170 | |||
171 | /* V4L2 controls */ | ||
172 | static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) | ||
173 | { | ||
174 | struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); | ||
175 | |||
176 | mutex_lock(&flash->lock); | ||
177 | |||
178 | if (ctrl->id == V4L2_CID_FLASH_FAULT) { | ||
179 | int rval; | ||
180 | s32 fault = 0; | ||
181 | unsigned int reg_val; | ||
182 | rval = regmap_read(flash->regmap, REG_FLAG, ®_val); | ||
183 | if (rval < 0) | ||
184 | return rval; | ||
185 | if (rval & FAULT_SHORT_CIRCUIT) | ||
186 | fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; | ||
187 | if (rval & FAULT_OVERTEMP) | ||
188 | fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; | ||
189 | if (rval & FAULT_TIMEOUT) | ||
190 | fault |= V4L2_FLASH_FAULT_TIMEOUT; | ||
191 | ctrl->cur.val = fault; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | mutex_unlock(&flash->lock); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) | ||
200 | { | ||
201 | struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); | ||
202 | u8 tout_bits; | ||
203 | int rval = -EINVAL; | ||
204 | |||
205 | mutex_lock(&flash->lock); | ||
206 | |||
207 | switch (ctrl->id) { | ||
208 | case V4L2_CID_FLASH_LED_MODE: | ||
209 | flash->led_mode = ctrl->val; | ||
210 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
211 | rval = lm3560_mode_ctrl(flash); | ||
212 | break; | ||
213 | |||
214 | case V4L2_CID_FLASH_STROBE_SOURCE: | ||
215 | rval = regmap_update_bits(flash->regmap, | ||
216 | REG_CONFIG1, 0x04, (ctrl->val) << 2); | ||
217 | if (rval < 0) | ||
218 | goto err_out; | ||
219 | break; | ||
220 | |||
221 | case V4L2_CID_FLASH_STROBE: | ||
222 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
223 | return -EBUSY; | ||
224 | flash->led_mode = V4L2_FLASH_LED_MODE_FLASH; | ||
225 | rval = lm3560_mode_ctrl(flash); | ||
226 | break; | ||
227 | |||
228 | case V4L2_CID_FLASH_STROBE_STOP: | ||
229 | if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) | ||
230 | return -EBUSY; | ||
231 | flash->led_mode = V4L2_FLASH_LED_MODE_NONE; | ||
232 | rval = lm3560_mode_ctrl(flash); | ||
233 | break; | ||
234 | |||
235 | case V4L2_CID_FLASH_TIMEOUT: | ||
236 | tout_bits = LM3560_FLASH_TOUT_ms_TO_REG(ctrl->val); | ||
237 | rval = regmap_update_bits(flash->regmap, | ||
238 | REG_FLASH_TOUT, 0x1f, tout_bits); | ||
239 | break; | ||
240 | |||
241 | case V4L2_CID_FLASH_INTENSITY: | ||
242 | rval = lm3560_flash_brt_ctrl(flash, led_no, ctrl->val); | ||
243 | break; | ||
244 | |||
245 | case V4L2_CID_FLASH_TORCH_INTENSITY: | ||
246 | rval = lm3560_torch_brt_ctrl(flash, led_no, ctrl->val); | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | mutex_unlock(&flash->lock); | ||
251 | err_out: | ||
252 | return rval; | ||
253 | } | ||
254 | |||
255 | static int lm3560_led1_get_ctrl(struct v4l2_ctrl *ctrl) | ||
256 | { | ||
257 | return lm3560_get_ctrl(ctrl, LM3560_LED1); | ||
258 | } | ||
259 | |||
260 | static int lm3560_led1_set_ctrl(struct v4l2_ctrl *ctrl) | ||
261 | { | ||
262 | return lm3560_set_ctrl(ctrl, LM3560_LED1); | ||
263 | } | ||
264 | |||
265 | static int lm3560_led0_get_ctrl(struct v4l2_ctrl *ctrl) | ||
266 | { | ||
267 | return lm3560_get_ctrl(ctrl, LM3560_LED0); | ||
268 | } | ||
269 | |||
270 | static int lm3560_led0_set_ctrl(struct v4l2_ctrl *ctrl) | ||
271 | { | ||
272 | return lm3560_set_ctrl(ctrl, LM3560_LED0); | ||
273 | } | ||
274 | |||
275 | static const struct v4l2_ctrl_ops lm3560_led_ctrl_ops[LM3560_LED_MAX] = { | ||
276 | [LM3560_LED0] = { | ||
277 | .g_volatile_ctrl = lm3560_led0_get_ctrl, | ||
278 | .s_ctrl = lm3560_led0_set_ctrl, | ||
279 | }, | ||
280 | [LM3560_LED1] = { | ||
281 | .g_volatile_ctrl = lm3560_led1_get_ctrl, | ||
282 | .s_ctrl = lm3560_led1_set_ctrl, | ||
283 | } | ||
284 | }; | ||
285 | |||
286 | static int lm3560_init_controls(struct lm3560_flash *flash, | ||
287 | enum lm3560_led_id led_no) | ||
288 | { | ||
289 | struct v4l2_ctrl *fault; | ||
290 | u32 max_flash_brt = flash->pdata->max_flash_brt[led_no]; | ||
291 | u32 max_torch_brt = flash->pdata->max_torch_brt[led_no]; | ||
292 | struct v4l2_ctrl_handler *hdl = &flash->ctrls_led[led_no]; | ||
293 | const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no]; | ||
294 | |||
295 | v4l2_ctrl_handler_init(hdl, 8); | ||
296 | /* flash mode */ | ||
297 | v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE, | ||
298 | V4L2_FLASH_LED_MODE_TORCH, ~0x7, | ||
299 | V4L2_FLASH_LED_MODE_NONE); | ||
300 | flash->led_mode = V4L2_FLASH_LED_MODE_NONE; | ||
301 | |||
302 | /* flash source */ | ||
303 | v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE, | ||
304 | 0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE); | ||
305 | |||
306 | /* flash strobe */ | ||
307 | v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0); | ||
308 | /* flash strobe stop */ | ||
309 | v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0); | ||
310 | |||
311 | /* flash strobe timeout */ | ||
312 | v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT, | ||
313 | LM3560_FLASH_TOUT_MIN, | ||
314 | flash->pdata->max_flash_timeout, | ||
315 | LM3560_FLASH_TOUT_STEP, | ||
316 | flash->pdata->max_flash_timeout); | ||
317 | |||
318 | /* flash brt */ | ||
319 | v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, | ||
320 | LM3560_FLASH_BRT_MIN, max_flash_brt, | ||
321 | LM3560_FLASH_BRT_STEP, max_flash_brt); | ||
322 | |||
323 | /* torch brt */ | ||
324 | v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY, | ||
325 | LM3560_TORCH_BRT_MIN, max_torch_brt, | ||
326 | LM3560_TORCH_BRT_STEP, max_torch_brt); | ||
327 | |||
328 | /* fault */ | ||
329 | fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0, | ||
330 | V4L2_FLASH_FAULT_OVER_VOLTAGE | ||
331 | | V4L2_FLASH_FAULT_OVER_TEMPERATURE | ||
332 | | V4L2_FLASH_FAULT_SHORT_CIRCUIT | ||
333 | | V4L2_FLASH_FAULT_TIMEOUT, 0, 0); | ||
334 | if (fault != NULL) | ||
335 | fault->flags |= V4L2_CTRL_FLAG_VOLATILE; | ||
336 | |||
337 | if (hdl->error) | ||
338 | return hdl->error; | ||
339 | |||
340 | flash->subdev_led[led_no].ctrl_handler = hdl; | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | /* initialize device */ | ||
345 | static const struct v4l2_subdev_ops lm3560_ops = { | ||
346 | .core = NULL, | ||
347 | }; | ||
348 | |||
349 | static const struct regmap_config lm3560_regmap = { | ||
350 | .reg_bits = 8, | ||
351 | .val_bits = 8, | ||
352 | .max_register = 0xFF, | ||
353 | }; | ||
354 | |||
355 | static int lm3560_subdev_init(struct lm3560_flash *flash, | ||
356 | enum lm3560_led_id led_no, char *led_name) | ||
357 | { | ||
358 | struct i2c_client *client = to_i2c_client(flash->dev); | ||
359 | int rval; | ||
360 | |||
361 | v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops); | ||
362 | flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
363 | strcpy(flash->subdev_led[led_no].name, led_name); | ||
364 | rval = lm3560_init_controls(flash, led_no); | ||
365 | if (rval) | ||
366 | goto err_out; | ||
367 | rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0); | ||
368 | if (rval < 0) | ||
369 | goto err_out; | ||
370 | flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; | ||
371 | |||
372 | return rval; | ||
373 | |||
374 | err_out: | ||
375 | v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); | ||
376 | return rval; | ||
377 | } | ||
378 | |||
379 | static int lm3560_init_device(struct lm3560_flash *flash) | ||
380 | { | ||
381 | int rval; | ||
382 | unsigned int reg_val; | ||
383 | |||
384 | /* set peak current */ | ||
385 | rval = regmap_update_bits(flash->regmap, | ||
386 | REG_FLASH_TOUT, 0x60, flash->pdata->peak); | ||
387 | if (rval < 0) | ||
388 | return rval; | ||
389 | /* output disable */ | ||
390 | flash->led_mode = V4L2_FLASH_LED_MODE_NONE; | ||
391 | rval = lm3560_mode_ctrl(flash); | ||
392 | if (rval < 0) | ||
393 | return rval; | ||
394 | /* Reset faults */ | ||
395 | rval = regmap_read(flash->regmap, REG_FLAG, ®_val); | ||
396 | return rval; | ||
397 | } | ||
398 | |||
399 | static int lm3560_probe(struct i2c_client *client, | ||
400 | const struct i2c_device_id *devid) | ||
401 | { | ||
402 | struct lm3560_flash *flash; | ||
403 | struct lm3560_platform_data *pdata = dev_get_platdata(&client->dev); | ||
404 | int rval; | ||
405 | |||
406 | flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); | ||
407 | if (flash == NULL) | ||
408 | return -ENOMEM; | ||
409 | |||
410 | flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap); | ||
411 | if (IS_ERR(flash->regmap)) { | ||
412 | rval = PTR_ERR(flash->regmap); | ||
413 | return rval; | ||
414 | } | ||
415 | |||
416 | /* if there is no platform data, use chip default value */ | ||
417 | if (pdata == NULL) { | ||
418 | pdata = | ||
419 | kzalloc(sizeof(struct lm3560_platform_data), GFP_KERNEL); | ||
420 | if (pdata == NULL) | ||
421 | return -ENODEV; | ||
422 | pdata->peak = LM3560_PEAK_3600mA; | ||
423 | pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX; | ||
424 | /* led 1 */ | ||
425 | pdata->max_flash_brt[LM3560_LED0] = LM3560_FLASH_BRT_MAX; | ||
426 | pdata->max_torch_brt[LM3560_LED0] = LM3560_TORCH_BRT_MAX; | ||
427 | /* led 2 */ | ||
428 | pdata->max_flash_brt[LM3560_LED1] = LM3560_FLASH_BRT_MAX; | ||
429 | pdata->max_torch_brt[LM3560_LED1] = LM3560_TORCH_BRT_MAX; | ||
430 | } | ||
431 | flash->pdata = pdata; | ||
432 | flash->dev = &client->dev; | ||
433 | mutex_init(&flash->lock); | ||
434 | |||
435 | rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); | ||
436 | if (rval < 0) | ||
437 | return rval; | ||
438 | |||
439 | rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); | ||
440 | if (rval < 0) | ||
441 | return rval; | ||
442 | |||
443 | rval = lm3560_init_device(flash); | ||
444 | if (rval < 0) | ||
445 | return rval; | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int lm3560_remove(struct i2c_client *client) | ||
451 | { | ||
452 | struct v4l2_subdev *subdev = i2c_get_clientdata(client); | ||
453 | struct lm3560_flash *flash = container_of(subdev, struct lm3560_flash, | ||
454 | subdev_led[LM3560_LED_MAX]); | ||
455 | unsigned int i; | ||
456 | |||
457 | for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) { | ||
458 | v4l2_device_unregister_subdev(&flash->subdev_led[i]); | ||
459 | v4l2_ctrl_handler_free(&flash->ctrls_led[i]); | ||
460 | media_entity_cleanup(&flash->subdev_led[i].entity); | ||
461 | } | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static const struct i2c_device_id lm3560_id_table[] = { | ||
467 | {LM3560_NAME, 0}, | ||
468 | {} | ||
469 | }; | ||
470 | |||
471 | MODULE_DEVICE_TABLE(i2c, lm3560_id_table); | ||
472 | |||
473 | static struct i2c_driver lm3560_i2c_driver = { | ||
474 | .driver = { | ||
475 | .name = LM3560_NAME, | ||
476 | .pm = NULL, | ||
477 | }, | ||
478 | .probe = lm3560_probe, | ||
479 | .remove = lm3560_remove, | ||
480 | .id_table = lm3560_id_table, | ||
481 | }; | ||
482 | |||
483 | module_i2c_driver(lm3560_i2c_driver); | ||
484 | |||
485 | MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); | ||
486 | MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>"); | ||
487 | MODULE_DESCRIPTION("Texas Instruments LM3560 LED flash driver"); | ||
488 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index 1d384a371b41..5b915936c3f3 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c | |||
@@ -451,7 +451,9 @@ static int imx074_probe(struct i2c_client *client, | |||
451 | if (ret < 0) | 451 | if (ret < 0) |
452 | goto eprobe; | 452 | goto eprobe; |
453 | 453 | ||
454 | return v4l2_async_register_subdev(&priv->subdev); | 454 | ret = v4l2_async_register_subdev(&priv->subdev); |
455 | if (!ret) | ||
456 | return 0; | ||
455 | 457 | ||
456 | epwrinit: | 458 | epwrinit: |
457 | eprobe: | 459 | eprobe: |
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index e968c3fdbd9e..bc74224503e7 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c | |||
@@ -371,7 +371,7 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, | |||
371 | alt->com13 = OV9640_COM13_RGB_AVG; | 371 | alt->com13 = OV9640_COM13_RGB_AVG; |
372 | alt->com15 = OV9640_COM15_RGB_565; | 372 | alt->com15 = OV9640_COM15_RGB_565; |
373 | break; | 373 | break; |
374 | }; | 374 | } |
375 | } | 375 | } |
376 | 376 | ||
377 | /* Setup registers according to resolution and color encoding */ | 377 | /* Setup registers according to resolution and color encoding */ |
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index d9f65d7e3e58..04139eec8c4e 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | ||
22 | #include <linux/v4l2-dv-timings.h> | 23 | #include <linux/v4l2-dv-timings.h> |
23 | 24 | ||
24 | #include <media/v4l2-dv-timings.h> | 25 | #include <media/v4l2-dv-timings.h> |
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 91f3dd4cda1b..83d85df4853a 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/videodev2.h> | 35 | #include <linux/videodev2.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/v4l2-mediabus.h> | 37 | #include <linux/v4l2-mediabus.h> |
38 | #include <linux/of.h> | ||
38 | 39 | ||
39 | #include <media/v4l2-async.h> | 40 | #include <media/v4l2-async.h> |
40 | #include <media/v4l2-device.h> | 41 | #include <media/v4l2-device.h> |
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 24a08fa7e328..912e1cccdd1c 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/of.h> | ||
32 | #include <linux/v4l2-dv-timings.h> | 33 | #include <linux/v4l2-dv-timings.h> |
33 | #include <media/tvp7002.h> | 34 | #include <media/tvp7002.h> |
34 | #include <media/v4l2-async.h> | 35 | #include <media/v4l2-async.h> |
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c index 447afbd904a4..8b5e0b3a92a0 100644 --- a/drivers/media/pci/b2c2/flexcop-pci.c +++ b/drivers/media/pci/b2c2/flexcop-pci.c | |||
@@ -319,7 +319,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) | |||
319 | 319 | ||
320 | err_pci_iounmap: | 320 | err_pci_iounmap: |
321 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | 321 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); |
322 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
323 | err_pci_release_regions: | 322 | err_pci_release_regions: |
324 | pci_release_regions(fc_pci->pdev); | 323 | pci_release_regions(fc_pci->pdev); |
325 | err_pci_disable_device: | 324 | err_pci_disable_device: |
@@ -332,7 +331,6 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci) | |||
332 | if (fc_pci->init_state & FC_PCI_INIT) { | 331 | if (fc_pci->init_state & FC_PCI_INIT) { |
333 | free_irq(fc_pci->pdev->irq, fc_pci); | 332 | free_irq(fc_pci->pdev->irq, fc_pci); |
334 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | 333 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); |
335 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
336 | pci_release_regions(fc_pci->pdev); | 334 | pci_release_regions(fc_pci->pdev); |
337 | pci_disable_device(fc_pci->pdev); | 335 | pci_disable_device(fc_pci->pdev); |
338 | } | 336 | } |
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 66eb0baab0e9..d0c281f41a0a 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c | |||
@@ -488,8 +488,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) | |||
488 | btwrite(0, BT848_INT_MASK); | 488 | btwrite(0, BT848_INT_MASK); |
489 | 489 | ||
490 | result = request_irq(bt->irq, bt878_irq, | 490 | result = request_irq(bt->irq, bt878_irq, |
491 | IRQF_SHARED | IRQF_DISABLED, "bt878", | 491 | IRQF_SHARED, "bt878", (void *) bt); |
492 | (void *) bt); | ||
493 | if (result == -EINVAL) { | 492 | if (result == -EINVAL) { |
494 | printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", | 493 | printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", |
495 | bt878_num); | 494 | bt878_num); |
@@ -563,7 +562,6 @@ static void bt878_remove(struct pci_dev *pci_dev) | |||
563 | bt->shutdown = 1; | 562 | bt->shutdown = 1; |
564 | bt878_mem_free(bt); | 563 | bt878_mem_free(bt); |
565 | 564 | ||
566 | pci_set_drvdata(pci_dev, NULL); | ||
567 | pci_disable_device(pci_dev); | 565 | pci_disable_device(pci_dev); |
568 | return; | 566 | return; |
569 | } | 567 | } |
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index c6532de0eac7..a3b1ee9c00d7 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c | |||
@@ -4086,7 +4086,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) | |||
4086 | /* disable irqs, register irq handler */ | 4086 | /* disable irqs, register irq handler */ |
4087 | btwrite(0, BT848_INT_MASK); | 4087 | btwrite(0, BT848_INT_MASK); |
4088 | result = request_irq(btv->c.pci->irq, bttv_irq, | 4088 | result = request_irq(btv->c.pci->irq, bttv_irq, |
4089 | IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv); | 4089 | IRQF_SHARED, btv->c.v4l2_dev.name, (void *)btv); |
4090 | if (result < 0) { | 4090 | if (result < 0) { |
4091 | pr_err("%d: can't get IRQ %d\n", | 4091 | pr_err("%d: can't get IRQ %d\n", |
4092 | bttv_num, btv->c.pci->irq); | 4092 | bttv_num, btv->c.pci->irq); |
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 004d8ace5019..ff7232023f56 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c | |||
@@ -1031,8 +1031,7 @@ static int cx18_probe(struct pci_dev *pci_dev, | |||
1031 | 1031 | ||
1032 | /* Register IRQ */ | 1032 | /* Register IRQ */ |
1033 | retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, | 1033 | retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, |
1034 | IRQF_SHARED | IRQF_DISABLED, | 1034 | IRQF_SHARED, cx->v4l2_dev.name, (void *)cx); |
1035 | cx->v4l2_dev.name, (void *)cx); | ||
1036 | if (retval) { | 1035 | if (retval) { |
1037 | CX18_ERR("Failed to register irq %d\n", retval); | 1036 | CX18_ERR("Failed to register irq %d\n", retval); |
1038 | goto free_i2c; | 1037 | goto free_i2c; |
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index 5104c802f72f..d1dcb1d2e087 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig | |||
@@ -23,6 +23,7 @@ config VIDEO_CX23885 | |||
23 | select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT | 23 | select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT |
24 | select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT | 24 | select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT |
25 | select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT | 25 | select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT |
26 | select DVB_CX24117 if MEDIA_SUBDRV_AUTOSELECT | ||
26 | select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT | 27 | select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT |
27 | select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT | 28 | select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT |
28 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT | 29 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 6a71a965e757..79f20c8c842e 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c | |||
@@ -223,6 +223,39 @@ struct cx23885_board cx23885_boards[] = { | |||
223 | .name = "Leadtek Winfast PxDVR3200 H", | 223 | .name = "Leadtek Winfast PxDVR3200 H", |
224 | .portc = CX23885_MPEG_DVB, | 224 | .portc = CX23885_MPEG_DVB, |
225 | }, | 225 | }, |
226 | [CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200] = { | ||
227 | .name = "Leadtek Winfast PxPVR2200", | ||
228 | .porta = CX23885_ANALOG_VIDEO, | ||
229 | .tuner_type = TUNER_XC2028, | ||
230 | .tuner_addr = 0x61, | ||
231 | .tuner_bus = 1, | ||
232 | .input = {{ | ||
233 | .type = CX23885_VMUX_TELEVISION, | ||
234 | .vmux = CX25840_VIN2_CH1 | | ||
235 | CX25840_VIN5_CH2, | ||
236 | .amux = CX25840_AUDIO8, | ||
237 | .gpio0 = 0x704040, | ||
238 | }, { | ||
239 | .type = CX23885_VMUX_COMPOSITE1, | ||
240 | .vmux = CX25840_COMPOSITE1, | ||
241 | .amux = CX25840_AUDIO7, | ||
242 | .gpio0 = 0x704040, | ||
243 | }, { | ||
244 | .type = CX23885_VMUX_SVIDEO, | ||
245 | .vmux = CX25840_SVIDEO_LUMA3 | | ||
246 | CX25840_SVIDEO_CHROMA4, | ||
247 | .amux = CX25840_AUDIO7, | ||
248 | .gpio0 = 0x704040, | ||
249 | }, { | ||
250 | .type = CX23885_VMUX_COMPONENT, | ||
251 | .vmux = CX25840_VIN7_CH1 | | ||
252 | CX25840_VIN6_CH2 | | ||
253 | CX25840_VIN8_CH3 | | ||
254 | CX25840_COMPONENT_ON, | ||
255 | .amux = CX25840_AUDIO7, | ||
256 | .gpio0 = 0x704040, | ||
257 | } }, | ||
258 | }, | ||
226 | [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = { | 259 | [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = { |
227 | .name = "Leadtek Winfast PxDVR3200 H XC4000", | 260 | .name = "Leadtek Winfast PxDVR3200 H XC4000", |
228 | .porta = CX23885_ANALOG_VIDEO, | 261 | .porta = CX23885_ANALOG_VIDEO, |
@@ -259,6 +292,16 @@ struct cx23885_board cx23885_boards[] = { | |||
259 | .name = "TurboSight TBS 6920", | 292 | .name = "TurboSight TBS 6920", |
260 | .portb = CX23885_MPEG_DVB, | 293 | .portb = CX23885_MPEG_DVB, |
261 | }, | 294 | }, |
295 | [CX23885_BOARD_TBS_6980] = { | ||
296 | .name = "TurboSight TBS 6980", | ||
297 | .portb = CX23885_MPEG_DVB, | ||
298 | .portc = CX23885_MPEG_DVB, | ||
299 | }, | ||
300 | [CX23885_BOARD_TBS_6981] = { | ||
301 | .name = "TurboSight TBS 6981", | ||
302 | .portb = CX23885_MPEG_DVB, | ||
303 | .portc = CX23885_MPEG_DVB, | ||
304 | }, | ||
262 | [CX23885_BOARD_TEVII_S470] = { | 305 | [CX23885_BOARD_TEVII_S470] = { |
263 | .name = "TeVii S470", | 306 | .name = "TeVii S470", |
264 | .portb = CX23885_MPEG_DVB, | 307 | .portb = CX23885_MPEG_DVB, |
@@ -688,6 +731,10 @@ struct cx23885_subid cx23885_subids[] = { | |||
688 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, | 731 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, |
689 | }, { | 732 | }, { |
690 | .subvendor = 0x107d, | 733 | .subvendor = 0x107d, |
734 | .subdevice = 0x6f21, | ||
735 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200, | ||
736 | }, { | ||
737 | .subvendor = 0x107d, | ||
691 | .subdevice = 0x6f39, | 738 | .subdevice = 0x6f39, |
692 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000, | 739 | .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000, |
693 | }, { | 740 | }, { |
@@ -699,6 +746,14 @@ struct cx23885_subid cx23885_subids[] = { | |||
699 | .subdevice = 0x8888, | 746 | .subdevice = 0x8888, |
700 | .card = CX23885_BOARD_TBS_6920, | 747 | .card = CX23885_BOARD_TBS_6920, |
701 | }, { | 748 | }, { |
749 | .subvendor = 0x6980, | ||
750 | .subdevice = 0x8888, | ||
751 | .card = CX23885_BOARD_TBS_6980, | ||
752 | }, { | ||
753 | .subvendor = 0x6981, | ||
754 | .subdevice = 0x8888, | ||
755 | .card = CX23885_BOARD_TBS_6981, | ||
756 | }, { | ||
702 | .subvendor = 0xd470, | 757 | .subvendor = 0xd470, |
703 | .subdevice = 0x9022, | 758 | .subdevice = 0x9022, |
704 | .card = CX23885_BOARD_TEVII_S470, | 759 | .card = CX23885_BOARD_TEVII_S470, |
@@ -1023,6 +1078,35 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
1023 | dev->name, tv.model); | 1078 | dev->name, tv.model); |
1024 | } | 1079 | } |
1025 | 1080 | ||
1081 | /* Some TBS cards require initing a chip using a bitbanged SPI attached | ||
1082 | to the cx23885 gpio's. If this chip doesn't get init'ed the demod | ||
1083 | doesn't respond to any command. */ | ||
1084 | static void tbs_card_init(struct cx23885_dev *dev) | ||
1085 | { | ||
1086 | int i; | ||
1087 | const u8 buf[] = { | ||
1088 | 0xe0, 0x06, 0x66, 0x33, 0x65, | ||
1089 | 0x01, 0x17, 0x06, 0xde}; | ||
1090 | |||
1091 | switch (dev->board) { | ||
1092 | case CX23885_BOARD_TBS_6980: | ||
1093 | case CX23885_BOARD_TBS_6981: | ||
1094 | cx_set(GP0_IO, 0x00070007); | ||
1095 | usleep_range(1000, 10000); | ||
1096 | cx_clear(GP0_IO, 2); | ||
1097 | usleep_range(1000, 10000); | ||
1098 | for (i = 0; i < 9 * 8; i++) { | ||
1099 | cx_clear(GP0_IO, 7); | ||
1100 | usleep_range(1000, 10000); | ||
1101 | cx_set(GP0_IO, | ||
1102 | ((buf[i >> 3] >> (7 - (i & 7))) & 1) | 4); | ||
1103 | usleep_range(1000, 10000); | ||
1104 | } | ||
1105 | cx_set(GP0_IO, 7); | ||
1106 | break; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1026 | int cx23885_tuner_callback(void *priv, int component, int command, int arg) | 1110 | int cx23885_tuner_callback(void *priv, int component, int command, int arg) |
1027 | { | 1111 | { |
1028 | struct cx23885_tsport *port = priv; | 1112 | struct cx23885_tsport *port = priv; |
@@ -1043,6 +1127,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) | |||
1043 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 1127 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
1044 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 1128 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
1045 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 1129 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
1130 | case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200: | ||
1046 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: | 1131 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: |
1047 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 1132 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
1048 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: | 1133 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: |
@@ -1208,6 +1293,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1208 | cx_set(GP0_IO, 0x000f000f); | 1293 | cx_set(GP0_IO, 0x000f000f); |
1209 | break; | 1294 | break; |
1210 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 1295 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
1296 | case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200: | ||
1211 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: | 1297 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: |
1212 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 1298 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
1213 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: | 1299 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: |
@@ -1225,6 +1311,8 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1225 | cx_set(GP0_IO, 0x00040004); | 1311 | cx_set(GP0_IO, 0x00040004); |
1226 | break; | 1312 | break; |
1227 | case CX23885_BOARD_TBS_6920: | 1313 | case CX23885_BOARD_TBS_6920: |
1314 | case CX23885_BOARD_TBS_6980: | ||
1315 | case CX23885_BOARD_TBS_6981: | ||
1228 | case CX23885_BOARD_PROF_8000: | 1316 | case CX23885_BOARD_PROF_8000: |
1229 | cx_write(MC417_CTL, 0x00000036); | 1317 | cx_write(MC417_CTL, 0x00000036); |
1230 | cx_write(MC417_OEN, 0x00001000); | 1318 | cx_write(MC417_OEN, 0x00001000); |
@@ -1473,6 +1561,8 @@ int cx23885_ir_init(struct cx23885_dev *dev) | |||
1473 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: | 1561 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: |
1474 | case CX23885_BOARD_TEVII_S470: | 1562 | case CX23885_BOARD_TEVII_S470: |
1475 | case CX23885_BOARD_MYGICA_X8507: | 1563 | case CX23885_BOARD_MYGICA_X8507: |
1564 | case CX23885_BOARD_TBS_6980: | ||
1565 | case CX23885_BOARD_TBS_6981: | ||
1476 | if (!enable_885_ir) | 1566 | if (!enable_885_ir) |
1477 | break; | 1567 | break; |
1478 | dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); | 1568 | dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); |
@@ -1516,6 +1606,8 @@ void cx23885_ir_fini(struct cx23885_dev *dev) | |||
1516 | case CX23885_BOARD_TEVII_S470: | 1606 | case CX23885_BOARD_TEVII_S470: |
1517 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 1607 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
1518 | case CX23885_BOARD_MYGICA_X8507: | 1608 | case CX23885_BOARD_MYGICA_X8507: |
1609 | case CX23885_BOARD_TBS_6980: | ||
1610 | case CX23885_BOARD_TBS_6981: | ||
1519 | cx23885_irq_remove(dev, PCI_MSK_AV_CORE); | 1611 | cx23885_irq_remove(dev, PCI_MSK_AV_CORE); |
1520 | /* sd_ir is a duplicate pointer to the AV Core, just clear it */ | 1612 | /* sd_ir is a duplicate pointer to the AV Core, just clear it */ |
1521 | dev->sd_ir = NULL; | 1613 | dev->sd_ir = NULL; |
@@ -1561,6 +1653,8 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) | |||
1561 | case CX23885_BOARD_TEVII_S470: | 1653 | case CX23885_BOARD_TEVII_S470: |
1562 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 1654 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
1563 | case CX23885_BOARD_MYGICA_X8507: | 1655 | case CX23885_BOARD_MYGICA_X8507: |
1656 | case CX23885_BOARD_TBS_6980: | ||
1657 | case CX23885_BOARD_TBS_6981: | ||
1564 | if (dev->sd_ir) | 1658 | if (dev->sd_ir) |
1565 | cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); | 1659 | cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); |
1566 | break; | 1660 | break; |
@@ -1676,6 +1770,16 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1676 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 1770 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
1677 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 1771 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
1678 | break; | 1772 | break; |
1773 | case CX23885_BOARD_TBS_6980: | ||
1774 | case CX23885_BOARD_TBS_6981: | ||
1775 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | ||
1776 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
1777 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
1778 | ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | ||
1779 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
1780 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
1781 | tbs_card_init(dev); | ||
1782 | break; | ||
1679 | case CX23885_BOARD_MYGICA_X8506: | 1783 | case CX23885_BOARD_MYGICA_X8506: |
1680 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: | 1784 | case CX23885_BOARD_MAGICPRO_PROHDTVE2: |
1681 | case CX23885_BOARD_MYGICA_X8507: | 1785 | case CX23885_BOARD_MYGICA_X8507: |
@@ -1704,6 +1808,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1704 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | 1808 | case CX23885_BOARD_HAUPPAUGE_HVR1700: |
1705 | case CX23885_BOARD_HAUPPAUGE_HVR1400: | 1809 | case CX23885_BOARD_HAUPPAUGE_HVR1400: |
1706 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 1810 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
1811 | case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200: | ||
1707 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: | 1812 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: |
1708 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 1813 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
1709 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | 1814 | case CX23885_BOARD_HAUPPAUGE_HVR1270: |
@@ -1733,6 +1838,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1733 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: | 1838 | case CX23885_BOARD_HAUPPAUGE_HVR1800lp: |
1734 | case CX23885_BOARD_HAUPPAUGE_HVR1700: | 1839 | case CX23885_BOARD_HAUPPAUGE_HVR1700: |
1735 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: | 1840 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: |
1841 | case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200: | ||
1736 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: | 1842 | case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: |
1737 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: | 1843 | case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: |
1738 | case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: | 1844 | case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: |
@@ -1752,6 +1858,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1752 | case CX23885_BOARD_MYGICA_X8507: | 1858 | case CX23885_BOARD_MYGICA_X8507: |
1753 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: | 1859 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: |
1754 | case CX23885_BOARD_AVERMEDIA_HC81R: | 1860 | case CX23885_BOARD_AVERMEDIA_HC81R: |
1861 | case CX23885_BOARD_TBS_6980: | ||
1862 | case CX23885_BOARD_TBS_6981: | ||
1755 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1863 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1756 | &dev->i2c_bus[2].i2c_adap, | 1864 | &dev->i2c_bus[2].i2c_adap, |
1757 | "cx25840", 0x88 >> 1, NULL); | 1865 | "cx25840", 0x88 >> 1, NULL); |
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 9f63d93239ec..edcd79db1e4e 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -2129,7 +2129,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, | |||
2129 | } | 2129 | } |
2130 | 2130 | ||
2131 | err = request_irq(pci_dev->irq, cx23885_irq, | 2131 | err = request_irq(pci_dev->irq, cx23885_irq, |
2132 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); | 2132 | IRQF_SHARED, dev->name, dev); |
2133 | if (err < 0) { | 2133 | if (err < 0) { |
2134 | printk(KERN_ERR "%s: can't get IRQ %d\n", | 2134 | printk(KERN_ERR "%s: can't get IRQ %d\n", |
2135 | dev->name, pci_dev->irq); | 2135 | dev->name, pci_dev->irq); |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 971e4ff1b87f..05492053b473 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "stv6110.h" | 51 | #include "stv6110.h" |
52 | #include "lnbh24.h" | 52 | #include "lnbh24.h" |
53 | #include "cx24116.h" | 53 | #include "cx24116.h" |
54 | #include "cx24117.h" | ||
54 | #include "cimax2.h" | 55 | #include "cimax2.h" |
55 | #include "lgs8gxx.h" | 56 | #include "lgs8gxx.h" |
56 | #include "netup-eeprom.h" | 57 | #include "netup-eeprom.h" |
@@ -461,6 +462,10 @@ static struct cx24116_config tbs_cx24116_config = { | |||
461 | .demod_address = 0x55, | 462 | .demod_address = 0x55, |
462 | }; | 463 | }; |
463 | 464 | ||
465 | static struct cx24117_config tbs_cx24117_config = { | ||
466 | .demod_address = 0x55, | ||
467 | }; | ||
468 | |||
464 | static struct ds3000_config tevii_ds3000_config = { | 469 | static struct ds3000_config tevii_ds3000_config = { |
465 | .demod_address = 0x68, | 470 | .demod_address = 0x68, |
466 | }; | 471 | }; |
@@ -1044,6 +1049,25 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1044 | fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; | 1049 | fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; |
1045 | 1050 | ||
1046 | break; | 1051 | break; |
1052 | case CX23885_BOARD_TBS_6980: | ||
1053 | case CX23885_BOARD_TBS_6981: | ||
1054 | i2c_bus = &dev->i2c_bus[1]; | ||
1055 | |||
1056 | switch (port->nr) { | ||
1057 | /* PORT B */ | ||
1058 | case 1: | ||
1059 | fe0->dvb.frontend = dvb_attach(cx24117_attach, | ||
1060 | &tbs_cx24117_config, | ||
1061 | &i2c_bus->i2c_adap); | ||
1062 | break; | ||
1063 | /* PORT C */ | ||
1064 | case 2: | ||
1065 | fe0->dvb.frontend = dvb_attach(cx24117_attach, | ||
1066 | &tbs_cx24117_config, | ||
1067 | &i2c_bus->i2c_adap); | ||
1068 | break; | ||
1069 | } | ||
1070 | break; | ||
1047 | case CX23885_BOARD_TEVII_S470: | 1071 | case CX23885_BOARD_TEVII_S470: |
1048 | i2c_bus = &dev->i2c_bus[1]; | 1072 | i2c_bus = &dev->i2c_bus[1]; |
1049 | 1073 | ||
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 7875dfbe09ff..8a49e7c9eddd 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c | |||
@@ -90,6 +90,8 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) | |||
90 | case CX23885_BOARD_TEVII_S470: | 90 | case CX23885_BOARD_TEVII_S470: |
91 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 91 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
92 | case CX23885_BOARD_MYGICA_X8507: | 92 | case CX23885_BOARD_MYGICA_X8507: |
93 | case CX23885_BOARD_TBS_6980: | ||
94 | case CX23885_BOARD_TBS_6981: | ||
93 | /* | 95 | /* |
94 | * The only boards we handle right now. However other boards | 96 | * The only boards we handle right now. However other boards |
95 | * using the CX2388x integrated IR controller should be similar | 97 | * using the CX2388x integrated IR controller should be similar |
@@ -168,6 +170,8 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) | |||
168 | break; | 170 | break; |
169 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: | 171 | case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: |
170 | case CX23885_BOARD_TEVII_S470: | 172 | case CX23885_BOARD_TEVII_S470: |
173 | case CX23885_BOARD_TBS_6980: | ||
174 | case CX23885_BOARD_TBS_6981: | ||
171 | /* | 175 | /* |
172 | * The IR controller on this board only returns pulse widths. | 176 | * The IR controller on this board only returns pulse widths. |
173 | * Any other mode setting will fail to set up the device. | 177 | * Any other mode setting will fail to set up the device. |
@@ -298,6 +302,14 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
298 | /* A guess at the remote */ | 302 | /* A guess at the remote */ |
299 | rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; | 303 | rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; |
300 | break; | 304 | break; |
305 | case CX23885_BOARD_TBS_6980: | ||
306 | case CX23885_BOARD_TBS_6981: | ||
307 | /* Integrated CX23885 IR controller */ | ||
308 | driver_type = RC_DRIVER_IR_RAW; | ||
309 | allowed_protos = RC_BIT_ALL; | ||
310 | /* A guess at the remote */ | ||
311 | rc_map = RC_MAP_TBS_NEC; | ||
312 | break; | ||
301 | default: | 313 | default: |
302 | return -ENODEV; | 314 | return -ENODEV; |
303 | } | 315 | } |
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 161686832b20..7891f34157d1 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c | |||
@@ -1865,7 +1865,8 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1865 | 1865 | ||
1866 | v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); | 1866 | v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); |
1867 | 1867 | ||
1868 | if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) { | 1868 | if ((dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) || |
1869 | (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200)) { | ||
1869 | struct xc2028_ctrl ctrl = { | 1870 | struct xc2028_ctrl ctrl = { |
1870 | .fname = XC2028_DEFAULT_FIRMWARE, | 1871 | .fname = XC2028_DEFAULT_FIRMWARE, |
1871 | .max_len = 64 | 1872 | .max_len = 64 |
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 038caf53908b..0fa4048ab872 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h | |||
@@ -93,6 +93,9 @@ | |||
93 | #define CX23885_BOARD_PROF_8000 37 | 93 | #define CX23885_BOARD_PROF_8000 37 |
94 | #define CX23885_BOARD_HAUPPAUGE_HVR4400 38 | 94 | #define CX23885_BOARD_HAUPPAUGE_HVR4400 38 |
95 | #define CX23885_BOARD_AVERMEDIA_HC81R 39 | 95 | #define CX23885_BOARD_AVERMEDIA_HC81R 39 |
96 | #define CX23885_BOARD_TBS_6981 40 | ||
97 | #define CX23885_BOARD_TBS_6980 41 | ||
98 | #define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42 | ||
96 | 99 | ||
97 | #define GPIO_0 0x00000001 | 100 | #define GPIO_0 0x00000001 |
98 | #define GPIO_1 0x00000002 | 101 | #define GPIO_1 0x00000002 |
diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index 3b409feb03d8..f2ebc989b303 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c | |||
@@ -45,5 +45,3 @@ struct cx25821_board cx25821_boards[] = { | |||
45 | }, | 45 | }, |
46 | 46 | ||
47 | }; | 47 | }; |
48 | |||
49 | const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards); | ||
diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c index 22fa04415ccc..43bdfa4dfba1 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.c +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c | |||
@@ -438,7 +438,7 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, | |||
438 | decoder_count = decoder_select + 1; | 438 | decoder_count = decoder_select + 1; |
439 | } else { | 439 | } else { |
440 | decoder = 0; | 440 | decoder = 0; |
441 | decoder_count = _num_decoders; | 441 | decoder_count = dev->_max_num_decoders; |
442 | } | 442 | } |
443 | 443 | ||
444 | switch (width) { | 444 | switch (width) { |
@@ -506,8 +506,6 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, | |||
506 | break; | 506 | break; |
507 | } | 507 | } |
508 | 508 | ||
509 | _display_field_cnt[decoder] = duration; | ||
510 | |||
511 | /* update hardware */ | 509 | /* update hardware */ |
512 | fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); | 510 | fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); |
513 | 511 | ||
@@ -667,8 +665,6 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
667 | int ret_val = 0; | 665 | int ret_val = 0; |
668 | int i = 0; | 666 | int i = 0; |
669 | 667 | ||
670 | _num_decoders = dev->_max_num_decoders; | ||
671 | |||
672 | /* disable Auto source selection on all video decoders */ | 668 | /* disable Auto source selection on all video decoders */ |
673 | value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); | 669 | value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); |
674 | value &= 0xFFFFF0FF; | 670 | value &= 0xFFFFF0FF; |
@@ -685,8 +681,14 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
685 | if (ret_val < 0) | 681 | if (ret_val < 0) |
686 | goto error; | 682 | goto error; |
687 | 683 | ||
688 | for (i = 0; i < _num_decoders; i++) | 684 | /* |
689 | medusa_set_decoderduration(dev, i, _display_field_cnt[i]); | 685 | * FIXME: due to a coding bug the duration was always 0. It's |
686 | * likely that it really should be something else, but due to the | ||
687 | * lack of documentation I have no idea what it should be. For | ||
688 | * now just fill in 0 as the duration. | ||
689 | */ | ||
690 | for (i = 0; i < dev->_max_num_decoders; i++) | ||
691 | medusa_set_decoderduration(dev, i, 0); | ||
690 | 692 | ||
691 | /* Select monitor as DENC A input, power up the DAC */ | 693 | /* Select monitor as DENC A input, power up the DAC */ |
692 | value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); | 694 | value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); |
@@ -717,7 +719,7 @@ int medusa_video_init(struct cx25821_dev *dev) | |||
717 | /* Turn on all of the data out and control output pins. */ | 719 | /* Turn on all of the data out and control output pins. */ |
718 | value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); | 720 | value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); |
719 | value &= 0xFEF0FE00; | 721 | value &= 0xFEF0FE00; |
720 | if (_num_decoders == MAX_DECODERS) { | 722 | if (dev->_max_num_decoders == MAX_DECODERS) { |
721 | /* | 723 | /* |
722 | * Note: The octal board does not support control pins(bit16-19) | 724 | * Note: The octal board does not support control pins(bit16-19) |
723 | * These bits are ignored in the octal board. | 725 | * These bits are ignored in the octal board. |
diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.h b/drivers/media/pci/cx25821/cx25821-medusa-video.h index 6175e0961855..8bf602ff27b1 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.h +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.h | |||
@@ -40,10 +40,4 @@ | |||
40 | #define CONTRAST_DEFAULT 5000 | 40 | #define CONTRAST_DEFAULT 5000 |
41 | #define HUE_DEFAULT 5000 | 41 | #define HUE_DEFAULT 5000 |
42 | 42 | ||
43 | unsigned short _num_decoders; | ||
44 | unsigned short _num_cameras; | ||
45 | |||
46 | unsigned int _video_standard; | ||
47 | int _display_field_cnt[MAX_DECODERS]; | ||
48 | |||
49 | #endif | 43 | #endif |
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 88ffef410c50..1f43be0b04c8 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c | |||
@@ -159,10 +159,10 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32 | |||
159 | * For the upstream video channel, the risc engine will enable | 159 | * For the upstream video channel, the risc engine will enable |
160 | * the FIFO. */ | 160 | * the FIFO. */ |
161 | if (fifo_enable && line == 3) { | 161 | if (fifo_enable && line == 3) { |
162 | *(rp++) = RISC_WRITECR; | 162 | *(rp++) = cpu_to_le32(RISC_WRITECR); |
163 | *(rp++) = sram_ch->dma_ctl; | 163 | *(rp++) = cpu_to_le32(sram_ch->dma_ctl); |
164 | *(rp++) = FLD_VID_FIFO_EN; | 164 | *(rp++) = cpu_to_le32(FLD_VID_FIFO_EN); |
165 | *(rp++) = 0x00000001; | 165 | *(rp++) = cpu_to_le32(0x00000001); |
166 | } | 166 | } |
167 | } | 167 | } |
168 | 168 | ||
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index aba5b1c649e6..400eb1c42d3f 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c | |||
@@ -834,7 +834,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, | |||
834 | 834 | ||
835 | /* get irq */ | 835 | /* get irq */ |
836 | err = request_irq(chip->pci->irq, cx8801_irq, | 836 | err = request_irq(chip->pci->irq, cx8801_irq, |
837 | IRQF_SHARED | IRQF_DISABLED, chip->core->name, chip); | 837 | IRQF_SHARED, chip->core->name, chip); |
838 | if (err < 0) { | 838 | if (err < 0) { |
839 | dprintk(0, "%s: can't get IRQ %d\n", | 839 | dprintk(0, "%s: can't get IRQ %d\n", |
840 | chip->core->name, chip->pci->irq); | 840 | chip->core->name, chip->pci->irq); |
@@ -935,8 +935,6 @@ static void cx88_audio_finidev(struct pci_dev *pci) | |||
935 | 935 | ||
936 | snd_card_free((void *)card); | 936 | snd_card_free((void *)card); |
937 | 937 | ||
938 | pci_set_drvdata(pci, NULL); | ||
939 | |||
940 | devno--; | 938 | devno--; |
941 | } | 939 | } |
942 | 940 | ||
@@ -951,27 +949,4 @@ static struct pci_driver cx88_audio_pci_driver = { | |||
951 | .remove = cx88_audio_finidev, | 949 | .remove = cx88_audio_finidev, |
952 | }; | 950 | }; |
953 | 951 | ||
954 | /**************************************************************************** | 952 | module_pci_driver(cx88_audio_pci_driver); |
955 | LINUX MODULE INIT | ||
956 | ****************************************************************************/ | ||
957 | |||
958 | /* | ||
959 | * module init | ||
960 | */ | ||
961 | static int __init cx88_audio_init(void) | ||
962 | { | ||
963 | printk(KERN_INFO "cx2388x alsa driver version %s loaded\n", | ||
964 | CX88_VERSION); | ||
965 | return pci_register_driver(&cx88_audio_pci_driver); | ||
966 | } | ||
967 | |||
968 | /* | ||
969 | * module remove | ||
970 | */ | ||
971 | static void __exit cx88_audio_fini(void) | ||
972 | { | ||
973 | pci_unregister_driver(&cx88_audio_pci_driver); | ||
974 | } | ||
975 | |||
976 | module_init(cx88_audio_init); | ||
977 | module_exit(cx88_audio_fini); | ||
diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 2d3507eb4897..74b7b8614c23 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c | |||
@@ -499,7 +499,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) | |||
499 | 499 | ||
500 | /* get irq */ | 500 | /* get irq */ |
501 | err = request_irq(dev->pci->irq, cx8802_irq, | 501 | err = request_irq(dev->pci->irq, cx8802_irq, |
502 | IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev); | 502 | IRQF_SHARED, dev->core->name, dev); |
503 | if (err < 0) { | 503 | if (err < 0) { |
504 | printk(KERN_ERR "%s: can't get IRQ %d\n", | 504 | printk(KERN_ERR "%s: can't get IRQ %d\n", |
505 | dev->core->name, dev->pci->irq); | 505 | dev->core->name, dev->pci->irq); |
@@ -520,7 +520,6 @@ static void cx8802_fini_common(struct cx8802_dev *dev) | |||
520 | 520 | ||
521 | /* unregister stuff */ | 521 | /* unregister stuff */ |
522 | free_irq(dev->pci->irq, dev); | 522 | free_irq(dev->pci->irq, dev); |
523 | pci_set_drvdata(dev->pci, NULL); | ||
524 | 523 | ||
525 | /* free memory */ | 524 | /* free memory */ |
526 | btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); | 525 | btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); |
@@ -903,20 +902,8 @@ static struct pci_driver cx8802_pci_driver = { | |||
903 | .remove = cx8802_remove, | 902 | .remove = cx8802_remove, |
904 | }; | 903 | }; |
905 | 904 | ||
906 | static int __init cx8802_init(void) | 905 | module_pci_driver(cx8802_pci_driver); |
907 | { | ||
908 | printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %s loaded\n", | ||
909 | CX88_VERSION); | ||
910 | return pci_register_driver(&cx8802_pci_driver); | ||
911 | } | ||
912 | |||
913 | static void __exit cx8802_fini(void) | ||
914 | { | ||
915 | pci_unregister_driver(&cx8802_pci_driver); | ||
916 | } | ||
917 | 906 | ||
918 | module_init(cx8802_init); | ||
919 | module_exit(cx8802_fini); | ||
920 | EXPORT_SYMBOL(cx8802_buf_prepare); | 907 | EXPORT_SYMBOL(cx8802_buf_prepare); |
921 | EXPORT_SYMBOL(cx8802_buf_queue); | 908 | EXPORT_SYMBOL(cx8802_buf_queue); |
922 | EXPORT_SYMBOL(cx8802_cancel_buffers); | 909 | EXPORT_SYMBOL(cx8802_cancel_buffers); |
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index ecf21d9f1f34..ed8cb9037b6f 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c | |||
@@ -1738,7 +1738,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, | |||
1738 | 1738 | ||
1739 | /* get irq */ | 1739 | /* get irq */ |
1740 | err = request_irq(pci_dev->irq, cx8800_irq, | 1740 | err = request_irq(pci_dev->irq, cx8800_irq, |
1741 | IRQF_SHARED | IRQF_DISABLED, core->name, dev); | 1741 | IRQF_SHARED, core->name, dev); |
1742 | if (err < 0) { | 1742 | if (err < 0) { |
1743 | printk(KERN_ERR "%s/0: can't get IRQ %d\n", | 1743 | printk(KERN_ERR "%s/0: can't get IRQ %d\n", |
1744 | core->name,pci_dev->irq); | 1744 | core->name,pci_dev->irq); |
@@ -1922,7 +1922,6 @@ static void cx8800_finidev(struct pci_dev *pci_dev) | |||
1922 | 1922 | ||
1923 | free_irq(pci_dev->irq, dev); | 1923 | free_irq(pci_dev->irq, dev); |
1924 | cx8800_unregister_video(dev); | 1924 | cx8800_unregister_video(dev); |
1925 | pci_set_drvdata(pci_dev, NULL); | ||
1926 | 1925 | ||
1927 | /* free memory */ | 1926 | /* free memory */ |
1928 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); | 1927 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); |
@@ -2039,17 +2038,4 @@ static struct pci_driver cx8800_pci_driver = { | |||
2039 | #endif | 2038 | #endif |
2040 | }; | 2039 | }; |
2041 | 2040 | ||
2042 | static int __init cx8800_init(void) | 2041 | module_pci_driver(cx8800_pci_driver); |
2043 | { | ||
2044 | printk(KERN_INFO "cx88/0: cx2388x v4l2 driver version %s loaded\n", | ||
2045 | CX88_VERSION); | ||
2046 | return pci_register_driver(&cx8800_pci_driver); | ||
2047 | } | ||
2048 | |||
2049 | static void __exit cx8800_fini(void) | ||
2050 | { | ||
2051 | pci_unregister_driver(&cx8800_pci_driver); | ||
2052 | } | ||
2053 | |||
2054 | module_init(cx8800_init); | ||
2055 | module_exit(cx8800_fini); | ||
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 36e34522b9a8..9375f30d9a81 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c | |||
@@ -1544,7 +1544,7 @@ static void ddb_unmap(struct ddb *dev) | |||
1544 | 1544 | ||
1545 | static void ddb_remove(struct pci_dev *pdev) | 1545 | static void ddb_remove(struct pci_dev *pdev) |
1546 | { | 1546 | { |
1547 | struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); | 1547 | struct ddb *dev = pci_get_drvdata(pdev); |
1548 | 1548 | ||
1549 | ddb_ports_detach(dev); | 1549 | ddb_ports_detach(dev); |
1550 | ddb_i2c_release(dev); | 1550 | ddb_i2c_release(dev); |
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index ab797fe466d2..e60ac35fc10c 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c | |||
@@ -1178,7 +1178,6 @@ err_pci_release_regions: | |||
1178 | err_pci_disable_device: | 1178 | err_pci_disable_device: |
1179 | pci_disable_device(pdev); | 1179 | pci_disable_device(pdev); |
1180 | err_kfree: | 1180 | err_kfree: |
1181 | pci_set_drvdata(pdev, NULL); | ||
1182 | kfree(dev); | 1181 | kfree(dev); |
1183 | return ret; | 1182 | return ret; |
1184 | } | 1183 | } |
@@ -1202,8 +1201,7 @@ static void dm1105_remove(struct pci_dev *pdev) | |||
1202 | dvb_dmxdev_release(&dev->dmxdev); | 1201 | dvb_dmxdev_release(&dev->dmxdev); |
1203 | dvb_dmx_release(dvbdemux); | 1202 | dvb_dmx_release(dvbdemux); |
1204 | dvb_unregister_adapter(dvb_adapter); | 1203 | dvb_unregister_adapter(dvb_adapter); |
1205 | if (&dev->i2c_adap) | 1204 | i2c_del_adapter(&dev->i2c_adap); |
1206 | i2c_del_adapter(&dev->i2c_adap); | ||
1207 | 1205 | ||
1208 | dm1105_hw_exit(dev); | 1206 | dm1105_hw_exit(dev); |
1209 | synchronize_irq(pdev->irq); | 1207 | synchronize_irq(pdev->irq); |
@@ -1211,7 +1209,6 @@ static void dm1105_remove(struct pci_dev *pdev) | |||
1211 | pci_iounmap(pdev, dev->io_mem); | 1209 | pci_iounmap(pdev, dev->io_mem); |
1212 | pci_release_regions(pdev); | 1210 | pci_release_regions(pdev); |
1213 | pci_disable_device(pdev); | 1211 | pci_disable_device(pdev); |
1214 | pci_set_drvdata(pdev, NULL); | ||
1215 | dm1105_devcount--; | 1212 | dm1105_devcount--; |
1216 | kfree(dev); | 1213 | kfree(dev); |
1217 | } | 1214 | } |
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index c08ae3eb9554..802642d26643 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c | |||
@@ -1261,7 +1261,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
1261 | 1261 | ||
1262 | /* Register IRQ */ | 1262 | /* Register IRQ */ |
1263 | retval = request_irq(itv->pdev->irq, ivtv_irq_handler, | 1263 | retval = request_irq(itv->pdev->irq, ivtv_irq_handler, |
1264 | IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); | 1264 | IRQF_SHARED, itv->v4l2_dev.name, (void *)itv); |
1265 | if (retval) { | 1265 | if (retval) { |
1266 | IVTV_ERR("Failed to register irq %d\n", retval); | 1266 | IVTV_ERR("Failed to register irq %d\n", retval); |
1267 | goto free_i2c; | 1267 | goto free_i2c; |
diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c index a846036ea022..9e89e045213a 100644 --- a/drivers/media/pci/mantis/mantis_pci.c +++ b/drivers/media/pci/mantis/mantis_pci.c | |||
@@ -143,7 +143,6 @@ fail1: | |||
143 | 143 | ||
144 | fail0: | 144 | fail0: |
145 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); | 145 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); |
146 | pci_set_drvdata(pdev, NULL); | ||
147 | return ret; | 146 | return ret; |
148 | } | 147 | } |
149 | EXPORT_SYMBOL_GPL(mantis_pci_init); | 148 | EXPORT_SYMBOL_GPL(mantis_pci_init); |
@@ -161,7 +160,6 @@ void mantis_pci_exit(struct mantis_pci *mantis) | |||
161 | } | 160 | } |
162 | 161 | ||
163 | pci_disable_device(pdev); | 162 | pci_disable_device(pdev); |
164 | pci_set_drvdata(pdev, NULL); | ||
165 | } | 163 | } |
166 | EXPORT_SYMBOL_GPL(mantis_pci_exit); | 164 | EXPORT_SYMBOL_GPL(mantis_pci_exit); |
167 | 165 | ||
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 2381b05432e6..54d5c821007c 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c | |||
@@ -1698,7 +1698,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1698 | 1698 | ||
1699 | meye.mchip_irq = pcidev->irq; | 1699 | meye.mchip_irq = pcidev->irq; |
1700 | if (request_irq(meye.mchip_irq, meye_irq, | 1700 | if (request_irq(meye.mchip_irq, meye_irq, |
1701 | IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) { | 1701 | IRQF_SHARED, "meye", meye_irq)) { |
1702 | v4l2_err(v4l2_dev, "request_irq failed\n"); | 1702 | v4l2_err(v4l2_dev, "request_irq failed\n"); |
1703 | goto outreqirq; | 1703 | goto outreqirq; |
1704 | } | 1704 | } |
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 37ebc42392ad..970e83308525 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c | |||
@@ -1622,7 +1622,7 @@ static void ngene_unlink(struct ngene *dev) | |||
1622 | 1622 | ||
1623 | void ngene_shutdown(struct pci_dev *pdev) | 1623 | void ngene_shutdown(struct pci_dev *pdev) |
1624 | { | 1624 | { |
1625 | struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); | 1625 | struct ngene *dev = pci_get_drvdata(pdev); |
1626 | 1626 | ||
1627 | if (!dev || !shutdown_workaround) | 1627 | if (!dev || !shutdown_workaround) |
1628 | return; | 1628 | return; |
@@ -1648,7 +1648,6 @@ void ngene_remove(struct pci_dev *pdev) | |||
1648 | cxd_detach(dev); | 1648 | cxd_detach(dev); |
1649 | ngene_stop(dev); | 1649 | ngene_stop(dev); |
1650 | ngene_release_buffers(dev); | 1650 | ngene_release_buffers(dev); |
1651 | pci_set_drvdata(pdev, NULL); | ||
1652 | pci_disable_device(pdev); | 1651 | pci_disable_device(pdev); |
1653 | } | 1652 | } |
1654 | 1653 | ||
@@ -1702,6 +1701,5 @@ fail1: | |||
1702 | ngene_release_buffers(dev); | 1701 | ngene_release_buffers(dev); |
1703 | fail0: | 1702 | fail0: |
1704 | pci_disable_device(pci_dev); | 1703 | pci_disable_device(pci_dev); |
1705 | pci_set_drvdata(pci_dev, NULL); | ||
1706 | return stat; | 1704 | return stat; |
1707 | } | 1705 | } |
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c index 493828500055..8164d74b46a4 100644 --- a/drivers/media/pci/pluto2/pluto2.c +++ b/drivers/media/pci/pluto2/pluto2.c | |||
@@ -736,7 +736,6 @@ err_pci_release_regions: | |||
736 | err_pci_disable_device: | 736 | err_pci_disable_device: |
737 | pci_disable_device(pdev); | 737 | pci_disable_device(pdev); |
738 | err_kfree: | 738 | err_kfree: |
739 | pci_set_drvdata(pdev, NULL); | ||
740 | kfree(pluto); | 739 | kfree(pluto); |
741 | goto out; | 740 | goto out; |
742 | } | 741 | } |
@@ -765,7 +764,6 @@ static void pluto2_remove(struct pci_dev *pdev) | |||
765 | pci_iounmap(pdev, pluto->io_mem); | 764 | pci_iounmap(pdev, pluto->io_mem); |
766 | pci_release_regions(pdev); | 765 | pci_release_regions(pdev); |
767 | pci_disable_device(pdev); | 766 | pci_disable_device(pdev); |
768 | pci_set_drvdata(pdev, NULL); | ||
769 | kfree(pluto); | 767 | kfree(pluto); |
770 | } | 768 | } |
771 | 769 | ||
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index 75ce14229e03..db887b0c37b1 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c | |||
@@ -1076,7 +1076,6 @@ static void pt1_remove(struct pci_dev *pdev) | |||
1076 | pt1_update_power(pt1); | 1076 | pt1_update_power(pt1); |
1077 | pt1_cleanup_adapters(pt1); | 1077 | pt1_cleanup_adapters(pt1); |
1078 | i2c_del_adapter(&pt1->i2c_adap); | 1078 | i2c_del_adapter(&pt1->i2c_adap); |
1079 | pci_set_drvdata(pdev, NULL); | ||
1080 | kfree(pt1); | 1079 | kfree(pt1); |
1081 | pci_iounmap(pdev, regs); | 1080 | pci_iounmap(pdev, regs); |
1082 | pci_release_regions(pdev); | 1081 | pci_release_regions(pdev); |
@@ -1198,7 +1197,6 @@ err_i2c_del_adapter: | |||
1198 | err_pt1_cleanup_adapters: | 1197 | err_pt1_cleanup_adapters: |
1199 | pt1_cleanup_adapters(pt1); | 1198 | pt1_cleanup_adapters(pt1); |
1200 | err_kfree: | 1199 | err_kfree: |
1201 | pci_set_drvdata(pdev, NULL); | ||
1202 | kfree(pt1); | 1200 | kfree(pt1); |
1203 | err_pci_iounmap: | 1201 | err_pci_iounmap: |
1204 | pci_iounmap(pdev, regs); | 1202 | pci_iounmap(pdev, regs); |
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index dbcdfbf8aed0..dd67c8a400cc 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c | |||
@@ -1096,7 +1096,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) | |||
1096 | 1096 | ||
1097 | 1097 | ||
1098 | err = request_irq(dev->pci->irq, saa7134_alsa_irq, | 1098 | err = request_irq(dev->pci->irq, saa7134_alsa_irq, |
1099 | IRQF_SHARED | IRQF_DISABLED, dev->name, | 1099 | IRQF_SHARED, dev->name, |
1100 | (void*) &dev->dmasound); | 1100 | (void*) &dev->dmasound); |
1101 | 1101 | ||
1102 | if (err < 0) { | 1102 | if (err < 0) { |
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 45f0aca597ae..27d7ee709c58 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c | |||
@@ -992,7 +992,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, | |||
992 | 992 | ||
993 | /* get irq */ | 993 | /* get irq */ |
994 | err = request_irq(pci_dev->irq, saa7134_irq, | 994 | err = request_irq(pci_dev->irq, saa7134_irq, |
995 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); | 995 | IRQF_SHARED, dev->name, dev); |
996 | if (err < 0) { | 996 | if (err < 0) { |
997 | printk(KERN_ERR "%s: can't get IRQ %d\n", | 997 | printk(KERN_ERR "%s: can't get IRQ %d\n", |
998 | dev->name,pci_dev->irq); | 998 | dev->name,pci_dev->irq); |
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index d37ee37aaefe..57ef5456f1e8 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c | |||
@@ -1232,7 +1232,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev, | |||
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | err = request_irq(pci_dev->irq, saa7164_irq, | 1234 | err = request_irq(pci_dev->irq, saa7164_irq, |
1235 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); | 1235 | IRQF_SHARED, dev->name, dev); |
1236 | if (err < 0) { | 1236 | if (err < 0) { |
1237 | printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, | 1237 | printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name, |
1238 | pci_dev->irq); | 1238 | pci_dev->irq); |
@@ -1439,7 +1439,6 @@ static void saa7164_finidev(struct pci_dev *pci_dev) | |||
1439 | 1439 | ||
1440 | /* unregister stuff */ | 1440 | /* unregister stuff */ |
1441 | free_irq(pci_dev->irq, dev); | 1441 | free_irq(pci_dev->irq, dev); |
1442 | pci_set_drvdata(pci_dev, NULL); | ||
1443 | 1442 | ||
1444 | mutex_lock(&devlist); | 1443 | mutex_lock(&devlist); |
1445 | list_del(&dev->devlist); | 1444 | list_del(&dev->devlist); |
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c index 923d59a321f8..cec5b7553f28 100644 --- a/drivers/media/pci/zoran/zoran_card.c +++ b/drivers/media/pci/zoran/zoran_card.c | |||
@@ -1293,7 +1293,7 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | result = request_irq(zr->pci_dev->irq, zoran_irq, | 1295 | result = request_irq(zr->pci_dev->irq, zoran_irq, |
1296 | IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); | 1296 | IRQF_SHARED, ZR_DEVNAME(zr), zr); |
1297 | if (result < 0) { | 1297 | if (result < 0) { |
1298 | if (result == -EINVAL) { | 1298 | if (result == -EINVAL) { |
1299 | dprintk(1, | 1299 | dprintk(1, |
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index eb70dda8cbf3..d7f0249e4050 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
@@ -143,6 +143,7 @@ if V4L_MEM2MEM_DRIVERS | |||
143 | config VIDEO_CODA | 143 | config VIDEO_CODA |
144 | tristate "Chips&Media Coda multi-standard codec IP" | 144 | tristate "Chips&Media Coda multi-standard codec IP" |
145 | depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC | 145 | depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC |
146 | select SRAM | ||
146 | select VIDEOBUF2_DMA_CONTIG | 147 | select VIDEOBUF2_DMA_CONTIG |
147 | select V4L2_MEM2MEM_DEV | 148 | select V4L2_MEM2MEM_DEV |
148 | ---help--- | 149 | ---help--- |
@@ -212,7 +213,7 @@ config VIDEO_SH_VEU | |||
212 | 213 | ||
213 | config VIDEO_RENESAS_VSP1 | 214 | config VIDEO_RENESAS_VSP1 |
214 | tristate "Renesas VSP1 Video Processing Engine" | 215 | tristate "Renesas VSP1 Video Processing Engine" |
215 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 216 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA |
216 | select VIDEOBUF2_DMA_CONTIG | 217 | select VIDEOBUF2_DMA_CONTIG |
217 | ---help--- | 218 | ---help--- |
218 | This is a V4L2 driver for the Renesas VSP1 video processing engine. | 219 | This is a V4L2 driver for the Renesas VSP1 video processing engine. |
@@ -220,6 +221,22 @@ config VIDEO_RENESAS_VSP1 | |||
220 | To compile this driver as a module, choose M here: the module | 221 | To compile this driver as a module, choose M here: the module |
221 | will be called vsp1. | 222 | will be called vsp1. |
222 | 223 | ||
224 | config VIDEO_TI_VPE | ||
225 | tristate "TI VPE (Video Processing Engine) driver" | ||
226 | depends on VIDEO_DEV && VIDEO_V4L2 && SOC_DRA7XX | ||
227 | select VIDEOBUF2_DMA_CONTIG | ||
228 | select V4L2_MEM2MEM_DEV | ||
229 | default n | ||
230 | ---help--- | ||
231 | Support for the TI VPE(Video Processing Engine) block | ||
232 | found on DRA7XX SoC. | ||
233 | |||
234 | config VIDEO_TI_VPE_DEBUG | ||
235 | bool "VPE debug messages" | ||
236 | depends on VIDEO_TI_VPE | ||
237 | ---help--- | ||
238 | Enable debug messages on VPE driver. | ||
239 | |||
223 | endif # V4L_MEM2MEM_DRIVERS | 240 | endif # V4L_MEM2MEM_DRIVERS |
224 | 241 | ||
225 | menuconfig V4L_TEST_DRIVERS | 242 | menuconfig V4L_TEST_DRIVERS |
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 4e4da482c522..1348ba1faf92 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile | |||
@@ -22,6 +22,8 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o | |||
22 | 22 | ||
23 | obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o | 23 | obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o |
24 | 24 | ||
25 | obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/ | ||
26 | |||
25 | obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o | 27 | obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o |
26 | obj-$(CONFIG_VIDEO_CODA) += coda.o | 28 | obj-$(CONFIG_VIDEO_CODA) += coda.o |
27 | 29 | ||
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 4993610051ee..bd72fb97fea5 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define CODA_NAME "coda" | 40 | #define CODA_NAME "coda" |
41 | 41 | ||
42 | #define CODA_MAX_INSTANCES 4 | 42 | #define CODADX6_MAX_INSTANCES 4 |
43 | 43 | ||
44 | #define CODA_FMO_BUF_SIZE 32 | 44 | #define CODA_FMO_BUF_SIZE 32 |
45 | #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) | 45 | #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024) |
@@ -54,8 +54,6 @@ | |||
54 | 54 | ||
55 | #define CODA_MAX_FRAMEBUFFERS 8 | 55 | #define CODA_MAX_FRAMEBUFFERS 8 |
56 | 56 | ||
57 | #define MAX_W 8192 | ||
58 | #define MAX_H 8192 | ||
59 | #define CODA_MAX_FRAME_SIZE 0x100000 | 57 | #define CODA_MAX_FRAME_SIZE 0x100000 |
60 | #define FMO_SLICE_SAVE_BUF_SIZE (32) | 58 | #define FMO_SLICE_SAVE_BUF_SIZE (32) |
61 | #define CODA_DEFAULT_GAMMA 4096 | 59 | #define CODA_DEFAULT_GAMMA 4096 |
@@ -394,14 +392,57 @@ static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc, | |||
394 | return &codecs[k]; | 392 | return &codecs[k]; |
395 | } | 393 | } |
396 | 394 | ||
395 | static void coda_get_max_dimensions(struct coda_dev *dev, | ||
396 | struct coda_codec *codec, | ||
397 | int *max_w, int *max_h) | ||
398 | { | ||
399 | struct coda_codec *codecs = dev->devtype->codecs; | ||
400 | int num_codecs = dev->devtype->num_codecs; | ||
401 | unsigned int w, h; | ||
402 | int k; | ||
403 | |||
404 | if (codec) { | ||
405 | w = codec->max_w; | ||
406 | h = codec->max_h; | ||
407 | } else { | ||
408 | for (k = 0, w = 0, h = 0; k < num_codecs; k++) { | ||
409 | w = max(w, codecs[k].max_w); | ||
410 | h = max(h, codecs[k].max_h); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (max_w) | ||
415 | *max_w = w; | ||
416 | if (max_h) | ||
417 | *max_h = h; | ||
418 | } | ||
419 | |||
420 | static char *coda_product_name(int product) | ||
421 | { | ||
422 | static char buf[9]; | ||
423 | |||
424 | switch (product) { | ||
425 | case CODA_DX6: | ||
426 | return "CodaDx6"; | ||
427 | case CODA_7541: | ||
428 | return "CODA7541"; | ||
429 | default: | ||
430 | snprintf(buf, sizeof(buf), "(0x%04x)", product); | ||
431 | return buf; | ||
432 | } | ||
433 | } | ||
434 | |||
397 | /* | 435 | /* |
398 | * V4L2 ioctl() operations. | 436 | * V4L2 ioctl() operations. |
399 | */ | 437 | */ |
400 | static int vidioc_querycap(struct file *file, void *priv, | 438 | static int coda_querycap(struct file *file, void *priv, |
401 | struct v4l2_capability *cap) | 439 | struct v4l2_capability *cap) |
402 | { | 440 | { |
441 | struct coda_ctx *ctx = fh_to_ctx(priv); | ||
442 | |||
403 | strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); | 443 | strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver)); |
404 | strlcpy(cap->card, CODA_NAME, sizeof(cap->card)); | 444 | strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product), |
445 | sizeof(cap->card)); | ||
405 | strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); | 446 | strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); |
406 | /* | 447 | /* |
407 | * This is only a mem-to-mem video device. The capture and output | 448 | * This is only a mem-to-mem video device. The capture and output |
@@ -457,6 +498,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f, | |||
457 | fmt = &formats[i]; | 498 | fmt = &formats[i]; |
458 | strlcpy(f->description, fmt->name, sizeof(f->description)); | 499 | strlcpy(f->description, fmt->name, sizeof(f->description)); |
459 | f->pixelformat = fmt->fourcc; | 500 | f->pixelformat = fmt->fourcc; |
501 | if (!coda_format_is_yuv(fmt->fourcc)) | ||
502 | f->flags |= V4L2_FMT_FLAG_COMPRESSED; | ||
460 | return 0; | 503 | return 0; |
461 | } | 504 | } |
462 | 505 | ||
@@ -464,8 +507,8 @@ static int enum_fmt(void *priv, struct v4l2_fmtdesc *f, | |||
464 | return -EINVAL; | 507 | return -EINVAL; |
465 | } | 508 | } |
466 | 509 | ||
467 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 510 | static int coda_enum_fmt_vid_cap(struct file *file, void *priv, |
468 | struct v4l2_fmtdesc *f) | 511 | struct v4l2_fmtdesc *f) |
469 | { | 512 | { |
470 | struct coda_ctx *ctx = fh_to_ctx(priv); | 513 | struct coda_ctx *ctx = fh_to_ctx(priv); |
471 | struct vb2_queue *src_vq; | 514 | struct vb2_queue *src_vq; |
@@ -483,13 +526,14 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
483 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); | 526 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); |
484 | } | 527 | } |
485 | 528 | ||
486 | static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, | 529 | static int coda_enum_fmt_vid_out(struct file *file, void *priv, |
487 | struct v4l2_fmtdesc *f) | 530 | struct v4l2_fmtdesc *f) |
488 | { | 531 | { |
489 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); | 532 | return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0); |
490 | } | 533 | } |
491 | 534 | ||
492 | static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | 535 | static int coda_g_fmt(struct file *file, void *priv, |
536 | struct v4l2_format *f) | ||
493 | { | 537 | { |
494 | struct vb2_queue *vq; | 538 | struct vb2_queue *vq; |
495 | struct coda_q_data *q_data; | 539 | struct coda_q_data *q_data; |
@@ -516,8 +560,11 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
516 | return 0; | 560 | return 0; |
517 | } | 561 | } |
518 | 562 | ||
519 | static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f) | 563 | static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec, |
564 | struct v4l2_format *f) | ||
520 | { | 565 | { |
566 | struct coda_dev *dev = ctx->dev; | ||
567 | struct coda_q_data *q_data; | ||
521 | unsigned int max_w, max_h; | 568 | unsigned int max_w, max_h; |
522 | enum v4l2_field field; | 569 | enum v4l2_field field; |
523 | 570 | ||
@@ -531,32 +578,48 @@ static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f) | |||
531 | * if any of the dimensions is unsupported */ | 578 | * if any of the dimensions is unsupported */ |
532 | f->fmt.pix.field = field; | 579 | f->fmt.pix.field = field; |
533 | 580 | ||
534 | if (codec) { | 581 | coda_get_max_dimensions(dev, codec, &max_w, &max_h); |
535 | max_w = codec->max_w; | 582 | v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN, |
536 | max_h = codec->max_h; | 583 | &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, |
537 | } else { | 584 | S_ALIGN); |
538 | max_w = MAX_W; | 585 | |
539 | max_h = MAX_H; | 586 | switch (f->fmt.pix.pixelformat) { |
587 | case V4L2_PIX_FMT_YUV420: | ||
588 | case V4L2_PIX_FMT_YVU420: | ||
589 | case V4L2_PIX_FMT_H264: | ||
590 | case V4L2_PIX_FMT_MPEG4: | ||
591 | case V4L2_PIX_FMT_JPEG: | ||
592 | break; | ||
593 | default: | ||
594 | q_data = get_q_data(ctx, f->type); | ||
595 | f->fmt.pix.pixelformat = q_data->fourcc; | ||
540 | } | 596 | } |
541 | v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, | ||
542 | W_ALIGN, &f->fmt.pix.height, | ||
543 | MIN_H, max_h, H_ALIGN, S_ALIGN); | ||
544 | 597 | ||
545 | if (coda_format_is_yuv(f->fmt.pix.pixelformat)) { | 598 | switch (f->fmt.pix.pixelformat) { |
599 | case V4L2_PIX_FMT_YUV420: | ||
600 | case V4L2_PIX_FMT_YVU420: | ||
546 | /* Frame stride must be multiple of 8 */ | 601 | /* Frame stride must be multiple of 8 */ |
547 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8); | 602 | f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8); |
548 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * | 603 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * |
549 | f->fmt.pix.height * 3 / 2; | 604 | f->fmt.pix.height * 3 / 2; |
550 | } else { /*encoded formats h.264/mpeg4 */ | 605 | break; |
606 | case V4L2_PIX_FMT_H264: | ||
607 | case V4L2_PIX_FMT_MPEG4: | ||
608 | case V4L2_PIX_FMT_JPEG: | ||
551 | f->fmt.pix.bytesperline = 0; | 609 | f->fmt.pix.bytesperline = 0; |
552 | f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; | 610 | f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; |
611 | break; | ||
612 | default: | ||
613 | BUG(); | ||
553 | } | 614 | } |
554 | 615 | ||
616 | f->fmt.pix.priv = 0; | ||
617 | |||
555 | return 0; | 618 | return 0; |
556 | } | 619 | } |
557 | 620 | ||
558 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 621 | static int coda_try_fmt_vid_cap(struct file *file, void *priv, |
559 | struct v4l2_format *f) | 622 | struct v4l2_format *f) |
560 | { | 623 | { |
561 | struct coda_ctx *ctx = fh_to_ctx(priv); | 624 | struct coda_ctx *ctx = fh_to_ctx(priv); |
562 | struct coda_codec *codec; | 625 | struct coda_codec *codec; |
@@ -584,7 +647,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
584 | 647 | ||
585 | f->fmt.pix.colorspace = ctx->colorspace; | 648 | f->fmt.pix.colorspace = ctx->colorspace; |
586 | 649 | ||
587 | ret = vidioc_try_fmt(codec, f); | 650 | ret = coda_try_fmt(ctx, codec, f); |
588 | if (ret < 0) | 651 | if (ret < 0) |
589 | return ret; | 652 | return ret; |
590 | 653 | ||
@@ -600,8 +663,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
600 | return 0; | 663 | return 0; |
601 | } | 664 | } |
602 | 665 | ||
603 | static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | 666 | static int coda_try_fmt_vid_out(struct file *file, void *priv, |
604 | struct v4l2_format *f) | 667 | struct v4l2_format *f) |
605 | { | 668 | { |
606 | struct coda_ctx *ctx = fh_to_ctx(priv); | 669 | struct coda_ctx *ctx = fh_to_ctx(priv); |
607 | struct coda_codec *codec; | 670 | struct coda_codec *codec; |
@@ -613,10 +676,10 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | |||
613 | if (!f->fmt.pix.colorspace) | 676 | if (!f->fmt.pix.colorspace) |
614 | f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; | 677 | f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; |
615 | 678 | ||
616 | return vidioc_try_fmt(codec, f); | 679 | return coda_try_fmt(ctx, codec, f); |
617 | } | 680 | } |
618 | 681 | ||
619 | static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) | 682 | static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) |
620 | { | 683 | { |
621 | struct coda_q_data *q_data; | 684 | struct coda_q_data *q_data; |
622 | struct vb2_queue *vq; | 685 | struct vb2_queue *vq; |
@@ -646,61 +709,62 @@ static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f) | |||
646 | return 0; | 709 | return 0; |
647 | } | 710 | } |
648 | 711 | ||
649 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 712 | static int coda_s_fmt_vid_cap(struct file *file, void *priv, |
650 | struct v4l2_format *f) | 713 | struct v4l2_format *f) |
651 | { | 714 | { |
652 | struct coda_ctx *ctx = fh_to_ctx(priv); | 715 | struct coda_ctx *ctx = fh_to_ctx(priv); |
653 | int ret; | 716 | int ret; |
654 | 717 | ||
655 | ret = vidioc_try_fmt_vid_cap(file, priv, f); | 718 | ret = coda_try_fmt_vid_cap(file, priv, f); |
656 | if (ret) | 719 | if (ret) |
657 | return ret; | 720 | return ret; |
658 | 721 | ||
659 | return vidioc_s_fmt(ctx, f); | 722 | return coda_s_fmt(ctx, f); |
660 | } | 723 | } |
661 | 724 | ||
662 | static int vidioc_s_fmt_vid_out(struct file *file, void *priv, | 725 | static int coda_s_fmt_vid_out(struct file *file, void *priv, |
663 | struct v4l2_format *f) | 726 | struct v4l2_format *f) |
664 | { | 727 | { |
665 | struct coda_ctx *ctx = fh_to_ctx(priv); | 728 | struct coda_ctx *ctx = fh_to_ctx(priv); |
666 | int ret; | 729 | int ret; |
667 | 730 | ||
668 | ret = vidioc_try_fmt_vid_out(file, priv, f); | 731 | ret = coda_try_fmt_vid_out(file, priv, f); |
669 | if (ret) | 732 | if (ret) |
670 | return ret; | 733 | return ret; |
671 | 734 | ||
672 | ret = vidioc_s_fmt(ctx, f); | 735 | ret = coda_s_fmt(ctx, f); |
673 | if (ret) | 736 | if (ret) |
674 | ctx->colorspace = f->fmt.pix.colorspace; | 737 | ctx->colorspace = f->fmt.pix.colorspace; |
675 | 738 | ||
676 | return ret; | 739 | return ret; |
677 | } | 740 | } |
678 | 741 | ||
679 | static int vidioc_reqbufs(struct file *file, void *priv, | 742 | static int coda_reqbufs(struct file *file, void *priv, |
680 | struct v4l2_requestbuffers *reqbufs) | 743 | struct v4l2_requestbuffers *reqbufs) |
681 | { | 744 | { |
682 | struct coda_ctx *ctx = fh_to_ctx(priv); | 745 | struct coda_ctx *ctx = fh_to_ctx(priv); |
683 | 746 | ||
684 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | 747 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); |
685 | } | 748 | } |
686 | 749 | ||
687 | static int vidioc_querybuf(struct file *file, void *priv, | 750 | static int coda_querybuf(struct file *file, void *priv, |
688 | struct v4l2_buffer *buf) | 751 | struct v4l2_buffer *buf) |
689 | { | 752 | { |
690 | struct coda_ctx *ctx = fh_to_ctx(priv); | 753 | struct coda_ctx *ctx = fh_to_ctx(priv); |
691 | 754 | ||
692 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | 755 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); |
693 | } | 756 | } |
694 | 757 | ||
695 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | 758 | static int coda_qbuf(struct file *file, void *priv, |
759 | struct v4l2_buffer *buf) | ||
696 | { | 760 | { |
697 | struct coda_ctx *ctx = fh_to_ctx(priv); | 761 | struct coda_ctx *ctx = fh_to_ctx(priv); |
698 | 762 | ||
699 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | 763 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); |
700 | } | 764 | } |
701 | 765 | ||
702 | static int vidioc_expbuf(struct file *file, void *priv, | 766 | static int coda_expbuf(struct file *file, void *priv, |
703 | struct v4l2_exportbuffer *eb) | 767 | struct v4l2_exportbuffer *eb) |
704 | { | 768 | { |
705 | struct coda_ctx *ctx = fh_to_ctx(priv); | 769 | struct coda_ctx *ctx = fh_to_ctx(priv); |
706 | 770 | ||
@@ -718,7 +782,8 @@ static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx, | |||
718 | (buf->sequence == (ctx->qsequence - 1))); | 782 | (buf->sequence == (ctx->qsequence - 1))); |
719 | } | 783 | } |
720 | 784 | ||
721 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | 785 | static int coda_dqbuf(struct file *file, void *priv, |
786 | struct v4l2_buffer *buf) | ||
722 | { | 787 | { |
723 | struct coda_ctx *ctx = fh_to_ctx(priv); | 788 | struct coda_ctx *ctx = fh_to_ctx(priv); |
724 | int ret; | 789 | int ret; |
@@ -738,24 +803,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | |||
738 | return ret; | 803 | return ret; |
739 | } | 804 | } |
740 | 805 | ||
741 | static int vidioc_create_bufs(struct file *file, void *priv, | 806 | static int coda_create_bufs(struct file *file, void *priv, |
742 | struct v4l2_create_buffers *create) | 807 | struct v4l2_create_buffers *create) |
743 | { | 808 | { |
744 | struct coda_ctx *ctx = fh_to_ctx(priv); | 809 | struct coda_ctx *ctx = fh_to_ctx(priv); |
745 | 810 | ||
746 | return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); | 811 | return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); |
747 | } | 812 | } |
748 | 813 | ||
749 | static int vidioc_streamon(struct file *file, void *priv, | 814 | static int coda_streamon(struct file *file, void *priv, |
750 | enum v4l2_buf_type type) | 815 | enum v4l2_buf_type type) |
751 | { | 816 | { |
752 | struct coda_ctx *ctx = fh_to_ctx(priv); | 817 | struct coda_ctx *ctx = fh_to_ctx(priv); |
753 | 818 | ||
754 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | 819 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); |
755 | } | 820 | } |
756 | 821 | ||
757 | static int vidioc_streamoff(struct file *file, void *priv, | 822 | static int coda_streamoff(struct file *file, void *priv, |
758 | enum v4l2_buf_type type) | 823 | enum v4l2_buf_type type) |
759 | { | 824 | { |
760 | struct coda_ctx *ctx = fh_to_ctx(priv); | 825 | struct coda_ctx *ctx = fh_to_ctx(priv); |
761 | int ret; | 826 | int ret; |
@@ -772,23 +837,34 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
772 | return ret; | 837 | return ret; |
773 | } | 838 | } |
774 | 839 | ||
775 | static int vidioc_decoder_cmd(struct file *file, void *fh, | 840 | static int coda_try_decoder_cmd(struct file *file, void *fh, |
776 | struct v4l2_decoder_cmd *dc) | 841 | struct v4l2_decoder_cmd *dc) |
777 | { | 842 | { |
778 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
779 | |||
780 | if (dc->cmd != V4L2_DEC_CMD_STOP) | 843 | if (dc->cmd != V4L2_DEC_CMD_STOP) |
781 | return -EINVAL; | 844 | return -EINVAL; |
782 | 845 | ||
783 | if ((dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) || | 846 | if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) |
784 | (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)) | ||
785 | return -EINVAL; | 847 | return -EINVAL; |
786 | 848 | ||
787 | if (dc->stop.pts != 0) | 849 | if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0)) |
788 | return -EINVAL; | 850 | return -EINVAL; |
789 | 851 | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | static int coda_decoder_cmd(struct file *file, void *fh, | ||
856 | struct v4l2_decoder_cmd *dc) | ||
857 | { | ||
858 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
859 | int ret; | ||
860 | |||
861 | ret = coda_try_decoder_cmd(file, fh, dc); | ||
862 | if (ret < 0) | ||
863 | return ret; | ||
864 | |||
865 | /* Ignore decoder stop command silently in encoder context */ | ||
790 | if (ctx->inst_type != CODA_INST_DECODER) | 866 | if (ctx->inst_type != CODA_INST_DECODER) |
791 | return -EINVAL; | 867 | return 0; |
792 | 868 | ||
793 | /* Set the strem-end flag on this context */ | 869 | /* Set the strem-end flag on this context */ |
794 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; | 870 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; |
@@ -796,8 +872,8 @@ static int vidioc_decoder_cmd(struct file *file, void *fh, | |||
796 | return 0; | 872 | return 0; |
797 | } | 873 | } |
798 | 874 | ||
799 | static int vidioc_subscribe_event(struct v4l2_fh *fh, | 875 | static int coda_subscribe_event(struct v4l2_fh *fh, |
800 | const struct v4l2_event_subscription *sub) | 876 | const struct v4l2_event_subscription *sub) |
801 | { | 877 | { |
802 | switch (sub->type) { | 878 | switch (sub->type) { |
803 | case V4L2_EVENT_EOS: | 879 | case V4L2_EVENT_EOS: |
@@ -808,32 +884,33 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh, | |||
808 | } | 884 | } |
809 | 885 | ||
810 | static const struct v4l2_ioctl_ops coda_ioctl_ops = { | 886 | static const struct v4l2_ioctl_ops coda_ioctl_ops = { |
811 | .vidioc_querycap = vidioc_querycap, | 887 | .vidioc_querycap = coda_querycap, |
812 | 888 | ||
813 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | 889 | .vidioc_enum_fmt_vid_cap = coda_enum_fmt_vid_cap, |
814 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt, | 890 | .vidioc_g_fmt_vid_cap = coda_g_fmt, |
815 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 891 | .vidioc_try_fmt_vid_cap = coda_try_fmt_vid_cap, |
816 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 892 | .vidioc_s_fmt_vid_cap = coda_s_fmt_vid_cap, |
817 | 893 | ||
818 | .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, | 894 | .vidioc_enum_fmt_vid_out = coda_enum_fmt_vid_out, |
819 | .vidioc_g_fmt_vid_out = vidioc_g_fmt, | 895 | .vidioc_g_fmt_vid_out = coda_g_fmt, |
820 | .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, | 896 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, |
821 | .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, | 897 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, |
822 | 898 | ||
823 | .vidioc_reqbufs = vidioc_reqbufs, | 899 | .vidioc_reqbufs = coda_reqbufs, |
824 | .vidioc_querybuf = vidioc_querybuf, | 900 | .vidioc_querybuf = coda_querybuf, |
825 | 901 | ||
826 | .vidioc_qbuf = vidioc_qbuf, | 902 | .vidioc_qbuf = coda_qbuf, |
827 | .vidioc_expbuf = vidioc_expbuf, | 903 | .vidioc_expbuf = coda_expbuf, |
828 | .vidioc_dqbuf = vidioc_dqbuf, | 904 | .vidioc_dqbuf = coda_dqbuf, |
829 | .vidioc_create_bufs = vidioc_create_bufs, | 905 | .vidioc_create_bufs = coda_create_bufs, |
830 | 906 | ||
831 | .vidioc_streamon = vidioc_streamon, | 907 | .vidioc_streamon = coda_streamon, |
832 | .vidioc_streamoff = vidioc_streamoff, | 908 | .vidioc_streamoff = coda_streamoff, |
833 | 909 | ||
834 | .vidioc_decoder_cmd = vidioc_decoder_cmd, | 910 | .vidioc_try_decoder_cmd = coda_try_decoder_cmd, |
911 | .vidioc_decoder_cmd = coda_decoder_cmd, | ||
835 | 912 | ||
836 | .vidioc_subscribe_event = vidioc_subscribe_event, | 913 | .vidioc_subscribe_event = coda_subscribe_event, |
837 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | 914 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
838 | }; | 915 | }; |
839 | 916 | ||
@@ -1928,8 +2005,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
1928 | if (!(ctx->streamon_out & ctx->streamon_cap)) | 2005 | if (!(ctx->streamon_out & ctx->streamon_cap)) |
1929 | return 0; | 2006 | return 0; |
1930 | 2007 | ||
1931 | /* Allow device_run with no buffers queued and after streamoff */ | 2008 | /* Allow decoder device_run with no new buffers queued */ |
1932 | v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true); | 2009 | if (ctx->inst_type == CODA_INST_DECODER) |
2010 | v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true); | ||
1933 | 2011 | ||
1934 | ctx->gopcounter = ctx->params.gop_size - 1; | 2012 | ctx->gopcounter = ctx->params.gop_size - 1; |
1935 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); | 2013 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); |
@@ -2071,10 +2149,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
2071 | coda_setup_iram(ctx); | 2149 | coda_setup_iram(ctx); |
2072 | 2150 | ||
2073 | if (dst_fourcc == V4L2_PIX_FMT_H264) { | 2151 | if (dst_fourcc == V4L2_PIX_FMT_H264) { |
2074 | value = (FMO_SLICE_SAVE_BUF_SIZE << 7); | ||
2075 | value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET; | ||
2076 | value |= 0 & CODA_FMOPARAM_SLICENUM_MASK; | ||
2077 | if (dev->devtype->product == CODA_DX6) { | 2152 | if (dev->devtype->product == CODA_DX6) { |
2153 | value = FMO_SLICE_SAVE_BUF_SIZE << 7; | ||
2078 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); | 2154 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); |
2079 | } else { | 2155 | } else { |
2080 | coda_write(dev, ctx->iram_info.search_ram_paddr, | 2156 | coda_write(dev, ctx->iram_info.search_ram_paddr, |
@@ -2371,7 +2447,13 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq, | |||
2371 | 2447 | ||
2372 | static int coda_next_free_instance(struct coda_dev *dev) | 2448 | static int coda_next_free_instance(struct coda_dev *dev) |
2373 | { | 2449 | { |
2374 | return ffz(dev->instance_mask); | 2450 | int idx = ffz(dev->instance_mask); |
2451 | |||
2452 | if ((idx < 0) || | ||
2453 | (dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES)) | ||
2454 | return -EBUSY; | ||
2455 | |||
2456 | return idx; | ||
2375 | } | 2457 | } |
2376 | 2458 | ||
2377 | static int coda_open(struct file *file) | 2459 | static int coda_open(struct file *file) |
@@ -2386,8 +2468,8 @@ static int coda_open(struct file *file) | |||
2386 | return -ENOMEM; | 2468 | return -ENOMEM; |
2387 | 2469 | ||
2388 | idx = coda_next_free_instance(dev); | 2470 | idx = coda_next_free_instance(dev); |
2389 | if (idx >= CODA_MAX_INSTANCES) { | 2471 | if (idx < 0) { |
2390 | ret = -EBUSY; | 2472 | ret = idx; |
2391 | goto err_coda_max; | 2473 | goto err_coda_max; |
2392 | } | 2474 | } |
2393 | set_bit(idx, &dev->instance_mask); | 2475 | set_bit(idx, &dev->instance_mask); |
@@ -2719,7 +2801,6 @@ static void coda_finish_encode(struct coda_ctx *ctx) | |||
2719 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | 2801 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); |
2720 | 2802 | ||
2721 | /* Get results from the coda */ | 2803 | /* Get results from the coda */ |
2722 | coda_read(dev, CODA_RET_ENC_PIC_TYPE); | ||
2723 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); | 2804 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); |
2724 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | 2805 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); |
2725 | 2806 | ||
@@ -2739,7 +2820,7 @@ static void coda_finish_encode(struct coda_ctx *ctx) | |||
2739 | coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); | 2820 | coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM); |
2740 | coda_read(dev, CODA_RET_ENC_PIC_FLAG); | 2821 | coda_read(dev, CODA_RET_ENC_PIC_FLAG); |
2741 | 2822 | ||
2742 | if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { | 2823 | if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) { |
2743 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | 2824 | dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
2744 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; | 2825 | dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME; |
2745 | } else { | 2826 | } else { |
@@ -2861,21 +2942,6 @@ static bool coda_firmware_supported(u32 vernum) | |||
2861 | return false; | 2942 | return false; |
2862 | } | 2943 | } |
2863 | 2944 | ||
2864 | static char *coda_product_name(int product) | ||
2865 | { | ||
2866 | static char buf[9]; | ||
2867 | |||
2868 | switch (product) { | ||
2869 | case CODA_DX6: | ||
2870 | return "CodaDx6"; | ||
2871 | case CODA_7541: | ||
2872 | return "CODA7541"; | ||
2873 | default: | ||
2874 | snprintf(buf, sizeof(buf), "(0x%04x)", product); | ||
2875 | return buf; | ||
2876 | } | ||
2877 | } | ||
2878 | |||
2879 | static int coda_hw_init(struct coda_dev *dev) | 2945 | static int coda_hw_init(struct coda_dev *dev) |
2880 | { | 2946 | { |
2881 | u16 product, major, minor, release; | 2947 | u16 product, major, minor, release; |
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 04609cc6eba7..eac472b5ae83 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c | |||
@@ -1785,7 +1785,7 @@ static int vpbe_display_probe(struct platform_device *pdev) | |||
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | irq = res->start; | 1787 | irq = res->start; |
1788 | err = devm_request_irq(&pdev->dev, irq, venc_isr, IRQF_DISABLED, | 1788 | err = devm_request_irq(&pdev->dev, irq, venc_isr, 0, |
1789 | VPBE_DISPLAY_DRIVER, disp_dev); | 1789 | VPBE_DISPLAY_DRIVER, disp_dev); |
1790 | if (err) { | 1790 | if (err) { |
1791 | v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, | 1791 | v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, |
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 93609091cb23..d762246eabf5 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
@@ -688,7 +688,7 @@ static int vpfe_attach_irq(struct vpfe_device *vpfe_dev) | |||
688 | frame_format = ccdc_dev->hw_ops.get_frame_format(); | 688 | frame_format = ccdc_dev->hw_ops.get_frame_format(); |
689 | if (frame_format == CCDC_FRMFMT_PROGRESSIVE) { | 689 | if (frame_format == CCDC_FRMFMT_PROGRESSIVE) { |
690 | return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr, | 690 | return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr, |
691 | IRQF_DISABLED, "vpfe_capture1", | 691 | 0, "vpfe_capture1", |
692 | vpfe_dev); | 692 | vpfe_dev); |
693 | } | 693 | } |
694 | return 0; | 694 | return 0; |
@@ -1863,7 +1863,7 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1863 | } | 1863 | } |
1864 | vpfe_dev->ccdc_irq1 = res1->start; | 1864 | vpfe_dev->ccdc_irq1 = res1->start; |
1865 | 1865 | ||
1866 | ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, | 1866 | ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0, |
1867 | "vpfe_capture0", vpfe_dev); | 1867 | "vpfe_capture0", vpfe_dev); |
1868 | 1868 | ||
1869 | if (0 != ret) { | 1869 | if (0 != ret) { |
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 1089834a4efe..52ac5e6c8625 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -2154,7 +2154,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
2154 | 2154 | ||
2155 | if (!vpif_obj.sd[i]) { | 2155 | if (!vpif_obj.sd[i]) { |
2156 | vpif_err("Error registering v4l2 subdevice\n"); | 2156 | vpif_err("Error registering v4l2 subdevice\n"); |
2157 | err = -ENOMEM; | 2157 | err = -ENODEV; |
2158 | goto probe_subdev_out; | 2158 | goto probe_subdev_out; |
2159 | } | 2159 | } |
2160 | v4l2_info(&vpif_obj.v4l2_dev, | 2160 | v4l2_info(&vpif_obj.v4l2_dev, |
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 76435d3bf62d..ef0a6564cef9 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define GSC_DST_FMT (1 << 2) | 45 | #define GSC_DST_FMT (1 << 2) |
46 | #define GSC_CTX_M2M (1 << 3) | 46 | #define GSC_CTX_M2M (1 << 3) |
47 | #define GSC_CTX_STOP_REQ (1 << 6) | 47 | #define GSC_CTX_STOP_REQ (1 << 6) |
48 | #define GSC_CTX_ABORT (1 << 7) | ||
48 | 49 | ||
49 | enum gsc_dev_flags { | 50 | enum gsc_dev_flags { |
50 | /* for global */ | 51 | /* for global */ |
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index e576ff2de3de..810c3e13970c 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c | |||
@@ -46,6 +46,17 @@ static int gsc_m2m_ctx_stop_req(struct gsc_ctx *ctx) | |||
46 | return ret == 0 ? -ETIMEDOUT : ret; | 46 | return ret == 0 ? -ETIMEDOUT : ret; |
47 | } | 47 | } |
48 | 48 | ||
49 | static void __gsc_m2m_job_abort(struct gsc_ctx *ctx) | ||
50 | { | ||
51 | int ret; | ||
52 | |||
53 | ret = gsc_m2m_ctx_stop_req(ctx); | ||
54 | if ((ret == -ETIMEDOUT) || (ctx->state & GSC_CTX_ABORT)) { | ||
55 | gsc_ctx_state_lock_clear(GSC_CTX_STOP_REQ | GSC_CTX_ABORT, ctx); | ||
56 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
57 | } | ||
58 | } | ||
59 | |||
49 | static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) | 60 | static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) |
50 | { | 61 | { |
51 | struct gsc_ctx *ctx = q->drv_priv; | 62 | struct gsc_ctx *ctx = q->drv_priv; |
@@ -58,11 +69,8 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) | |||
58 | static int gsc_m2m_stop_streaming(struct vb2_queue *q) | 69 | static int gsc_m2m_stop_streaming(struct vb2_queue *q) |
59 | { | 70 | { |
60 | struct gsc_ctx *ctx = q->drv_priv; | 71 | struct gsc_ctx *ctx = q->drv_priv; |
61 | int ret; | ||
62 | 72 | ||
63 | ret = gsc_m2m_ctx_stop_req(ctx); | 73 | __gsc_m2m_job_abort(ctx); |
64 | if (ret == -ETIMEDOUT) | ||
65 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
66 | 74 | ||
67 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); | 75 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); |
68 | 76 | ||
@@ -91,15 +99,9 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state) | |||
91 | } | 99 | } |
92 | } | 100 | } |
93 | 101 | ||
94 | |||
95 | static void gsc_m2m_job_abort(void *priv) | 102 | static void gsc_m2m_job_abort(void *priv) |
96 | { | 103 | { |
97 | struct gsc_ctx *ctx = priv; | 104 | __gsc_m2m_job_abort((struct gsc_ctx *)priv); |
98 | int ret; | ||
99 | |||
100 | ret = gsc_m2m_ctx_stop_req(ctx); | ||
101 | if (ret == -ETIMEDOUT) | ||
102 | gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | ||
103 | } | 105 | } |
104 | 106 | ||
105 | static int gsc_get_bufs(struct gsc_ctx *ctx) | 107 | static int gsc_get_bufs(struct gsc_ctx *ctx) |
@@ -150,9 +152,10 @@ static void gsc_m2m_device_run(void *priv) | |||
150 | gsc->m2m.ctx = ctx; | 152 | gsc->m2m.ctx = ctx; |
151 | } | 153 | } |
152 | 154 | ||
153 | is_set = (ctx->state & GSC_CTX_STOP_REQ) ? 1 : 0; | 155 | is_set = ctx->state & GSC_CTX_STOP_REQ; |
154 | ctx->state &= ~GSC_CTX_STOP_REQ; | ||
155 | if (is_set) { | 156 | if (is_set) { |
157 | ctx->state &= ~GSC_CTX_STOP_REQ; | ||
158 | ctx->state |= GSC_CTX_ABORT; | ||
156 | wake_up(&gsc->irq_queue); | 159 | wake_up(&gsc->irq_queue); |
157 | goto put_device; | 160 | goto put_device; |
158 | } | 161 | } |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index d2e6cba3566d..f3c6136aa5b4 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c | |||
@@ -511,7 +511,7 @@ static int __ctrl_set_metering(struct fimc_is *is, unsigned int value) | |||
511 | break; | 511 | break; |
512 | default: | 512 | default: |
513 | return -EINVAL; | 513 | return -EINVAL; |
514 | }; | 514 | } |
515 | 515 | ||
516 | __is_set_isp_metering(is, IS_METERING_CONFIG_CMD, val); | 516 | __is_set_isp_metering(is, IS_METERING_CONFIG_CMD, val); |
517 | return 0; | 517 | return 0; |
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index 540516ca872c..36513e896413 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c | |||
@@ -1084,8 +1084,7 @@ free_dev: | |||
1084 | 1084 | ||
1085 | static int deinterlace_remove(struct platform_device *pdev) | 1085 | static int deinterlace_remove(struct platform_device *pdev) |
1086 | { | 1086 | { |
1087 | struct deinterlace_dev *pcdev = | 1087 | struct deinterlace_dev *pcdev = platform_get_drvdata(pdev); |
1088 | (struct deinterlace_dev *)platform_get_drvdata(pdev); | ||
1089 | 1088 | ||
1090 | v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); | 1089 | v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); |
1091 | v4l2_m2m_release(pcdev->m2m_dev); | 1090 | v4l2_m2m_release(pcdev->m2m_dev); |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 5184887b155c..32fab30a9105 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
@@ -1221,16 +1221,16 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) | |||
1221 | { | 1221 | { |
1222 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | 1222 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); |
1223 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | 1223 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); |
1224 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | 1224 | struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0); |
1225 | struct mcam_dma_desc *desc = mvb->dma_desc; | 1225 | struct mcam_dma_desc *desc = mvb->dma_desc; |
1226 | struct scatterlist *sg; | 1226 | struct scatterlist *sg; |
1227 | int i; | 1227 | int i; |
1228 | 1228 | ||
1229 | mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages, | 1229 | mvb->dma_desc_nent = dma_map_sg(cam->dev, sg_table->sgl, |
1230 | DMA_FROM_DEVICE); | 1230 | sg_table->nents, DMA_FROM_DEVICE); |
1231 | if (mvb->dma_desc_nent <= 0) | 1231 | if (mvb->dma_desc_nent <= 0) |
1232 | return -EIO; /* Not sure what's right here */ | 1232 | return -EIO; /* Not sure what's right here */ |
1233 | for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) { | 1233 | for_each_sg(sg_table->sgl, sg, mvb->dma_desc_nent, i) { |
1234 | desc->dma_addr = sg_dma_address(sg); | 1234 | desc->dma_addr = sg_dma_address(sg); |
1235 | desc->segment_len = sg_dma_len(sg); | 1235 | desc->segment_len = sg_dma_len(sg); |
1236 | desc++; | 1236 | desc++; |
@@ -1241,9 +1241,11 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) | |||
1241 | static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) | 1241 | static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) |
1242 | { | 1242 | { |
1243 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | 1243 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); |
1244 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | 1244 | struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0); |
1245 | 1245 | ||
1246 | dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE); | 1246 | if (sg_table) |
1247 | dma_unmap_sg(cam->dev, sg_table->sgl, | ||
1248 | sg_table->nents, DMA_FROM_DEVICE); | ||
1247 | return 0; | 1249 | return 0; |
1248 | } | 1250 | } |
1249 | 1251 | ||
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index b5a19af5c587..3458fa0e2fd5 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c | |||
@@ -481,7 +481,6 @@ static int mmpcam_remove(struct mmp_camera *cam) | |||
481 | struct mmp_camera_platform_data *pdata; | 481 | struct mmp_camera_platform_data *pdata; |
482 | 482 | ||
483 | mmpcam_remove_device(cam); | 483 | mmpcam_remove_device(cam); |
484 | free_irq(cam->irq, mcam); | ||
485 | mccic_shutdown(mcam); | 484 | mccic_shutdown(mcam); |
486 | mmpcam_power_down(mcam); | 485 | mmpcam_power_down(mcam); |
487 | pdata = cam->pdev->dev.platform_data; | 486 | pdata = cam->pdev->dev.platform_data; |
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c index 6a17676f9d72..8df5975b700a 100644 --- a/drivers/media/platform/mem2mem_testdev.c +++ b/drivers/media/platform/mem2mem_testdev.c | |||
@@ -1090,8 +1090,7 @@ unreg_dev: | |||
1090 | 1090 | ||
1091 | static int m2mtest_remove(struct platform_device *pdev) | 1091 | static int m2mtest_remove(struct platform_device *pdev) |
1092 | { | 1092 | { |
1093 | struct m2mtest_dev *dev = | 1093 | struct m2mtest_dev *dev = platform_get_drvdata(pdev); |
1094 | (struct m2mtest_dev *)platform_get_drvdata(pdev); | ||
1095 | 1094 | ||
1096 | v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); | 1095 | v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); |
1097 | v4l2_m2m_release(dev->m2m_dev); | 1096 | v4l2_m2m_release(dev->m2m_dev); |
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index fd6289d60cde..0b2948376aee 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c | |||
@@ -840,7 +840,7 @@ put_clk: | |||
840 | 840 | ||
841 | static int g2d_remove(struct platform_device *pdev) | 841 | static int g2d_remove(struct platform_device *pdev) |
842 | { | 842 | { |
843 | struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev); | 843 | struct g2d_dev *dev = platform_get_drvdata(pdev); |
844 | 844 | ||
845 | v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME); | 845 | v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME); |
846 | v4l2_m2m_release(dev->m2m_dev); | 846 | v4l2_m2m_release(dev->m2m_dev); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 084263dd126f..5f2c4ad6c2cb 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -404,7 +404,11 @@ leave_handle_frame: | |||
404 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | 404 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
405 | BUG(); | 405 | BUG(); |
406 | s5p_mfc_clock_off(); | 406 | s5p_mfc_clock_off(); |
407 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | 407 | /* if suspending, wake up device and do not try_run again*/ |
408 | if (test_bit(0, &dev->enter_suspend)) | ||
409 | wake_up_dev(dev, reason, err); | ||
410 | else | ||
411 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
408 | } | 412 | } |
409 | 413 | ||
410 | /* Error handling for interrupt */ | 414 | /* Error handling for interrupt */ |
@@ -1101,7 +1105,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
1101 | } | 1105 | } |
1102 | dev->irq = res->start; | 1106 | dev->irq = res->start; |
1103 | ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq, | 1107 | ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq, |
1104 | IRQF_DISABLED, pdev->name, dev); | 1108 | 0, pdev->name, dev); |
1105 | if (ret) { | 1109 | if (ret) { |
1106 | dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); | 1110 | dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); |
1107 | goto err_res; | 1111 | goto err_res; |
@@ -1286,9 +1290,7 @@ static int s5p_mfc_suspend(struct device *dev) | |||
1286 | /* Try and lock the HW */ | 1290 | /* Try and lock the HW */ |
1287 | /* Wait on the interrupt waitqueue */ | 1291 | /* Wait on the interrupt waitqueue */ |
1288 | ret = wait_event_interruptible_timeout(m_dev->queue, | 1292 | ret = wait_event_interruptible_timeout(m_dev->queue, |
1289 | m_dev->int_cond || m_dev->ctx[m_dev->curr_ctx]->int_cond, | 1293 | m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT)); |
1290 | msecs_to_jiffies(MFC_INT_TIMEOUT)); | ||
1291 | |||
1292 | if (ret == 0) { | 1294 | if (ret == 0) { |
1293 | mfc_err("Waiting for hardware to finish timed out\n"); | 1295 | mfc_err("Waiting for hardware to finish timed out\n"); |
1294 | return -EIO; | 1296 | return -EIO; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c index ad4f1df0a18e..9a6efd6c1329 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c | |||
@@ -111,7 +111,7 @@ static int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) | |||
111 | break; | 111 | break; |
112 | default: | 112 | default: |
113 | h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; | 113 | h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; |
114 | }; | 114 | } |
115 | h2r_args.arg[1] = 0; /* no crc & no pixelcache */ | 115 | h2r_args.arg[1] = 0; /* no crc & no pixelcache */ |
116 | h2r_args.arg[2] = ctx->ctx.ofs; | 116 | h2r_args.arg[2] = ctx->ctx.ofs; |
117 | h2r_args.arg[3] = ctx->ctx.size; | 117 | h2r_args.arg[3] = ctx->ctx.size; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c index db796c8e7874..ec1a5947ed7d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c | |||
@@ -113,7 +113,7 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) | |||
113 | break; | 113 | break; |
114 | default: | 114 | default: |
115 | codec_type = S5P_FIMV_CODEC_NONE_V6; | 115 | codec_type = S5P_FIMV_CODEC_NONE_V6; |
116 | }; | 116 | } |
117 | mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6); | 117 | mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6); |
118 | mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6); | 118 | mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6); |
119 | mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); | 119 | mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 41f5a3c10dbd..4ff3b6cd6842 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -113,7 +113,7 @@ static struct mfc_control controls[] = { | |||
113 | .minimum = 0, | 113 | .minimum = 0, |
114 | .maximum = (1 << 16) - 1, | 114 | .maximum = (1 << 16) - 1, |
115 | .step = 1, | 115 | .step = 1, |
116 | .default_value = 0, | 116 | .default_value = 12, |
117 | }, | 117 | }, |
118 | { | 118 | { |
119 | .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, | 119 | .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, |
@@ -356,7 +356,7 @@ static struct mfc_control controls[] = { | |||
356 | .minimum = 0, | 356 | .minimum = 0, |
357 | .maximum = 51, | 357 | .maximum = 51, |
358 | .step = 1, | 358 | .step = 1, |
359 | .default_value = 1, | 359 | .default_value = 51, |
360 | }, | 360 | }, |
361 | { | 361 | { |
362 | .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, | 362 | .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, |
@@ -399,7 +399,7 @@ static struct mfc_control controls[] = { | |||
399 | .minimum = 1, | 399 | .minimum = 1, |
400 | .maximum = 31, | 400 | .maximum = 31, |
401 | .step = 1, | 401 | .step = 1, |
402 | .default_value = 1, | 402 | .default_value = 31, |
403 | }, | 403 | }, |
404 | { | 404 | { |
405 | .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, | 405 | .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, |
@@ -444,7 +444,7 @@ static struct mfc_control controls[] = { | |||
444 | .minimum = 0, | 444 | .minimum = 0, |
445 | .maximum = 51, | 445 | .maximum = 51, |
446 | .step = 1, | 446 | .step = 1, |
447 | .default_value = 1, | 447 | .default_value = 51, |
448 | }, | 448 | }, |
449 | { | 449 | { |
450 | .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, | 450 | .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index 368582b091bf..58ec7bb26ebc 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | |||
@@ -1582,7 +1582,7 @@ static int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev) | |||
1582 | break; | 1582 | break; |
1583 | default: | 1583 | default: |
1584 | reason = S5P_MFC_R2H_CMD_EMPTY; | 1584 | reason = S5P_MFC_R2H_CMD_EMPTY; |
1585 | }; | 1585 | } |
1586 | return reason; | 1586 | return reason; |
1587 | } | 1587 | } |
1588 | 1588 | ||
diff --git a/drivers/media/platform/s5p-tv/mixer_grp_layer.c b/drivers/media/platform/s5p-tv/mixer_grp_layer.c index b93a21f5aa13..74344c764daa 100644 --- a/drivers/media/platform/s5p-tv/mixer_grp_layer.c +++ b/drivers/media/platform/s5p-tv/mixer_grp_layer.c | |||
@@ -226,7 +226,7 @@ static void mxr_graph_fix_geometry(struct mxr_layer *layer, | |||
226 | src->width + src->x_offset, 32767); | 226 | src->width + src->x_offset, 32767); |
227 | src->full_height = clamp_val(src->full_height, | 227 | src->full_height = clamp_val(src->full_height, |
228 | src->height + src->y_offset, 2047); | 228 | src->height + src->y_offset, 2047); |
229 | }; | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | /* PUBLIC API */ | 232 | /* PUBLIC API */ |
diff --git a/drivers/media/platform/s5p-tv/mixer_vp_layer.c b/drivers/media/platform/s5p-tv/mixer_vp_layer.c index 3d13a636877b..c9388c45ad75 100644 --- a/drivers/media/platform/s5p-tv/mixer_vp_layer.c +++ b/drivers/media/platform/s5p-tv/mixer_vp_layer.c | |||
@@ -197,7 +197,7 @@ static void mxr_vp_fix_geometry(struct mxr_layer *layer, | |||
197 | ALIGN(src->width + src->x_offset, 8), 8192U); | 197 | ALIGN(src->width + src->x_offset, 8), 8192U); |
198 | src->full_height = clamp(src->full_height, | 198 | src->full_height = clamp(src->full_height, |
199 | src->height + src->y_offset, 8192U); | 199 | src->height + src->y_offset, 8192U); |
200 | }; | 200 | } |
201 | } | 201 | } |
202 | 202 | ||
203 | /* PUBLIC API */ | 203 | /* PUBLIC API */ |
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index d02a7e0b773f..b21f777f55e7 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #define VIN_MAX_HEIGHT 2048 | 105 | #define VIN_MAX_HEIGHT 2048 |
106 | 106 | ||
107 | enum chip_id { | 107 | enum chip_id { |
108 | RCAR_H2, | ||
108 | RCAR_H1, | 109 | RCAR_H1, |
109 | RCAR_M1, | 110 | RCAR_M1, |
110 | RCAR_E1, | 111 | RCAR_E1, |
@@ -300,7 +301,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) | |||
300 | dmr = 0; | 301 | dmr = 0; |
301 | break; | 302 | break; |
302 | case V4L2_PIX_FMT_RGB32: | 303 | case V4L2_PIX_FMT_RGB32: |
303 | if (priv->chip == RCAR_H1 || priv->chip == RCAR_E1) { | 304 | if (priv->chip == RCAR_H2 || priv->chip == RCAR_H1 || |
305 | priv->chip == RCAR_E1) { | ||
304 | dmr = VNDMR_EXRGB; | 306 | dmr = VNDMR_EXRGB; |
305 | break; | 307 | break; |
306 | } | 308 | } |
@@ -1381,6 +1383,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { | |||
1381 | }; | 1383 | }; |
1382 | 1384 | ||
1383 | static struct platform_device_id rcar_vin_id_table[] = { | 1385 | static struct platform_device_id rcar_vin_id_table[] = { |
1386 | { "r8a7790-vin", RCAR_H2 }, | ||
1384 | { "r8a7779-vin", RCAR_H1 }, | 1387 | { "r8a7779-vin", RCAR_H1 }, |
1385 | { "r8a7778-vin", RCAR_M1 }, | 1388 | { "r8a7778-vin", RCAR_M1 }, |
1386 | { "uPD35004-vin", RCAR_E1 }, | 1389 | { "uPD35004-vin", RCAR_E1 }, |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 8df22f779175..150bd4df413c 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
@@ -1800,7 +1800,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1800 | 1800 | ||
1801 | /* request irq */ | 1801 | /* request irq */ |
1802 | err = devm_request_irq(&pdev->dev, pcdev->irq, sh_mobile_ceu_irq, | 1802 | err = devm_request_irq(&pdev->dev, pcdev->irq, sh_mobile_ceu_irq, |
1803 | IRQF_DISABLED, dev_name(&pdev->dev), pcdev); | 1803 | 0, dev_name(&pdev->dev), pcdev); |
1804 | if (err) { | 1804 | if (err) { |
1805 | dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); | 1805 | dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); |
1806 | goto exit_release_mem; | 1806 | goto exit_release_mem; |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 387a232d95a4..4b8c024fc487 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
@@ -71,13 +71,23 @@ static int video_dev_create(struct soc_camera_device *icd); | |||
71 | int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, | 71 | int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, |
72 | struct v4l2_clk *clk) | 72 | struct v4l2_clk *clk) |
73 | { | 73 | { |
74 | int ret = clk ? v4l2_clk_enable(clk) : 0; | 74 | int ret; |
75 | if (ret < 0) { | 75 | bool clock_toggle; |
76 | dev_err(dev, "Cannot enable clock: %d\n", ret); | 76 | |
77 | return ret; | 77 | if (clk && (!ssdd->unbalanced_power || |
78 | !test_and_set_bit(0, &ssdd->clock_state))) { | ||
79 | ret = v4l2_clk_enable(clk); | ||
80 | if (ret < 0) { | ||
81 | dev_err(dev, "Cannot enable clock: %d\n", ret); | ||
82 | return ret; | ||
83 | } | ||
84 | clock_toggle = true; | ||
85 | } else { | ||
86 | clock_toggle = false; | ||
78 | } | 87 | } |
79 | ret = regulator_bulk_enable(ssdd->num_regulators, | 88 | |
80 | ssdd->regulators); | 89 | ret = regulator_bulk_enable(ssdd->sd_pdata.num_regulators, |
90 | ssdd->sd_pdata.regulators); | ||
81 | if (ret < 0) { | 91 | if (ret < 0) { |
82 | dev_err(dev, "Cannot enable regulators\n"); | 92 | dev_err(dev, "Cannot enable regulators\n"); |
83 | goto eregenable; | 93 | goto eregenable; |
@@ -95,10 +105,10 @@ int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, | |||
95 | return 0; | 105 | return 0; |
96 | 106 | ||
97 | epwron: | 107 | epwron: |
98 | regulator_bulk_disable(ssdd->num_regulators, | 108 | regulator_bulk_disable(ssdd->sd_pdata.num_regulators, |
99 | ssdd->regulators); | 109 | ssdd->sd_pdata.regulators); |
100 | eregenable: | 110 | eregenable: |
101 | if (clk) | 111 | if (clock_toggle) |
102 | v4l2_clk_disable(clk); | 112 | v4l2_clk_disable(clk); |
103 | 113 | ||
104 | return ret; | 114 | return ret; |
@@ -120,14 +130,14 @@ int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd | |||
120 | } | 130 | } |
121 | } | 131 | } |
122 | 132 | ||
123 | err = regulator_bulk_disable(ssdd->num_regulators, | 133 | err = regulator_bulk_disable(ssdd->sd_pdata.num_regulators, |
124 | ssdd->regulators); | 134 | ssdd->sd_pdata.regulators); |
125 | if (err < 0) { | 135 | if (err < 0) { |
126 | dev_err(dev, "Cannot disable regulators\n"); | 136 | dev_err(dev, "Cannot disable regulators\n"); |
127 | ret = ret ? : err; | 137 | ret = ret ? : err; |
128 | } | 138 | } |
129 | 139 | ||
130 | if (clk) | 140 | if (clk && (!ssdd->unbalanced_power || test_and_clear_bit(0, &ssdd->clock_state))) |
131 | v4l2_clk_disable(clk); | 141 | v4l2_clk_disable(clk); |
132 | 142 | ||
133 | return ret; | 143 | return ret; |
@@ -137,8 +147,8 @@ EXPORT_SYMBOL(soc_camera_power_off); | |||
137 | int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) | 147 | int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) |
138 | { | 148 | { |
139 | /* Should not have any effect in synchronous case */ | 149 | /* Should not have any effect in synchronous case */ |
140 | return devm_regulator_bulk_get(dev, ssdd->num_regulators, | 150 | return devm_regulator_bulk_get(dev, ssdd->sd_pdata.num_regulators, |
141 | ssdd->regulators); | 151 | ssdd->sd_pdata.regulators); |
142 | } | 152 | } |
143 | EXPORT_SYMBOL(soc_camera_power_init); | 153 | EXPORT_SYMBOL(soc_camera_power_init); |
144 | 154 | ||
@@ -1346,8 +1356,8 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd, | |||
1346 | * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try | 1356 | * soc_camera_pdrv_probe(), make sure the subdevice driver doesn't try |
1347 | * to allocate them again. | 1357 | * to allocate them again. |
1348 | */ | 1358 | */ |
1349 | ssdd->num_regulators = 0; | 1359 | ssdd->sd_pdata.num_regulators = 0; |
1350 | ssdd->regulators = NULL; | 1360 | ssdd->sd_pdata.regulators = NULL; |
1351 | shd->board_info->platform_data = ssdd; | 1361 | shd->board_info->platform_data = ssdd; |
1352 | 1362 | ||
1353 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", | 1363 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", |
@@ -2020,8 +2030,8 @@ static int soc_camera_pdrv_probe(struct platform_device *pdev) | |||
2020 | * that case regulators are attached to the I2C device and not to the | 2030 | * that case regulators are attached to the I2C device and not to the |
2021 | * camera platform device. | 2031 | * camera platform device. |
2022 | */ | 2032 | */ |
2023 | ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators, | 2033 | ret = devm_regulator_bulk_get(&pdev->dev, ssdd->sd_pdata.num_regulators, |
2024 | ssdd->regulators); | 2034 | ssdd->sd_pdata.regulators); |
2025 | if (ret < 0) | 2035 | if (ret < 0) |
2026 | return ret; | 2036 | return ret; |
2027 | 2037 | ||
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile new file mode 100644 index 000000000000..cbf0a806ba1d --- /dev/null +++ b/drivers/media/platform/ti-vpe/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o | ||
2 | |||
3 | ti-vpe-y := vpe.o vpdma.o | ||
4 | |||
5 | ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG | ||
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c new file mode 100644 index 000000000000..af0a5ffcaa98 --- /dev/null +++ b/drivers/media/platform/ti-vpe/vpdma.c | |||
@@ -0,0 +1,846 @@ | |||
1 | /* | ||
2 | * VPDMA helper library | ||
3 | * | ||
4 | * Copyright (c) 2013 Texas Instruments Inc. | ||
5 | * | ||
6 | * David Griego, <dagriego@biglakesoftware.com> | ||
7 | * Dale Farnsworth, <dale@farnsworth.org> | ||
8 | * Archit Taneja, <archit@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/firmware.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/videodev2.h> | ||
25 | |||
26 | #include "vpdma.h" | ||
27 | #include "vpdma_priv.h" | ||
28 | |||
29 | #define VPDMA_FIRMWARE "vpdma-1b8.bin" | ||
30 | |||
31 | const struct vpdma_data_format vpdma_yuv_fmts[] = { | ||
32 | [VPDMA_DATA_FMT_Y444] = { | ||
33 | .data_type = DATA_TYPE_Y444, | ||
34 | .depth = 8, | ||
35 | }, | ||
36 | [VPDMA_DATA_FMT_Y422] = { | ||
37 | .data_type = DATA_TYPE_Y422, | ||
38 | .depth = 8, | ||
39 | }, | ||
40 | [VPDMA_DATA_FMT_Y420] = { | ||
41 | .data_type = DATA_TYPE_Y420, | ||
42 | .depth = 8, | ||
43 | }, | ||
44 | [VPDMA_DATA_FMT_C444] = { | ||
45 | .data_type = DATA_TYPE_C444, | ||
46 | .depth = 8, | ||
47 | }, | ||
48 | [VPDMA_DATA_FMT_C422] = { | ||
49 | .data_type = DATA_TYPE_C422, | ||
50 | .depth = 8, | ||
51 | }, | ||
52 | [VPDMA_DATA_FMT_C420] = { | ||
53 | .data_type = DATA_TYPE_C420, | ||
54 | .depth = 4, | ||
55 | }, | ||
56 | [VPDMA_DATA_FMT_YC422] = { | ||
57 | .data_type = DATA_TYPE_YC422, | ||
58 | .depth = 16, | ||
59 | }, | ||
60 | [VPDMA_DATA_FMT_YC444] = { | ||
61 | .data_type = DATA_TYPE_YC444, | ||
62 | .depth = 24, | ||
63 | }, | ||
64 | [VPDMA_DATA_FMT_CY422] = { | ||
65 | .data_type = DATA_TYPE_CY422, | ||
66 | .depth = 16, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | const struct vpdma_data_format vpdma_rgb_fmts[] = { | ||
71 | [VPDMA_DATA_FMT_RGB565] = { | ||
72 | .data_type = DATA_TYPE_RGB16_565, | ||
73 | .depth = 16, | ||
74 | }, | ||
75 | [VPDMA_DATA_FMT_ARGB16_1555] = { | ||
76 | .data_type = DATA_TYPE_ARGB_1555, | ||
77 | .depth = 16, | ||
78 | }, | ||
79 | [VPDMA_DATA_FMT_ARGB16] = { | ||
80 | .data_type = DATA_TYPE_ARGB_4444, | ||
81 | .depth = 16, | ||
82 | }, | ||
83 | [VPDMA_DATA_FMT_RGBA16_5551] = { | ||
84 | .data_type = DATA_TYPE_RGBA_5551, | ||
85 | .depth = 16, | ||
86 | }, | ||
87 | [VPDMA_DATA_FMT_RGBA16] = { | ||
88 | .data_type = DATA_TYPE_RGBA_4444, | ||
89 | .depth = 16, | ||
90 | }, | ||
91 | [VPDMA_DATA_FMT_ARGB24] = { | ||
92 | .data_type = DATA_TYPE_ARGB24_6666, | ||
93 | .depth = 24, | ||
94 | }, | ||
95 | [VPDMA_DATA_FMT_RGB24] = { | ||
96 | .data_type = DATA_TYPE_RGB24_888, | ||
97 | .depth = 24, | ||
98 | }, | ||
99 | [VPDMA_DATA_FMT_ARGB32] = { | ||
100 | .data_type = DATA_TYPE_ARGB32_8888, | ||
101 | .depth = 32, | ||
102 | }, | ||
103 | [VPDMA_DATA_FMT_RGBA24] = { | ||
104 | .data_type = DATA_TYPE_RGBA24_6666, | ||
105 | .depth = 24, | ||
106 | }, | ||
107 | [VPDMA_DATA_FMT_RGBA32] = { | ||
108 | .data_type = DATA_TYPE_RGBA32_8888, | ||
109 | .depth = 32, | ||
110 | }, | ||
111 | [VPDMA_DATA_FMT_BGR565] = { | ||
112 | .data_type = DATA_TYPE_BGR16_565, | ||
113 | .depth = 16, | ||
114 | }, | ||
115 | [VPDMA_DATA_FMT_ABGR16_1555] = { | ||
116 | .data_type = DATA_TYPE_ABGR_1555, | ||
117 | .depth = 16, | ||
118 | }, | ||
119 | [VPDMA_DATA_FMT_ABGR16] = { | ||
120 | .data_type = DATA_TYPE_ABGR_4444, | ||
121 | .depth = 16, | ||
122 | }, | ||
123 | [VPDMA_DATA_FMT_BGRA16_5551] = { | ||
124 | .data_type = DATA_TYPE_BGRA_5551, | ||
125 | .depth = 16, | ||
126 | }, | ||
127 | [VPDMA_DATA_FMT_BGRA16] = { | ||
128 | .data_type = DATA_TYPE_BGRA_4444, | ||
129 | .depth = 16, | ||
130 | }, | ||
131 | [VPDMA_DATA_FMT_ABGR24] = { | ||
132 | .data_type = DATA_TYPE_ABGR24_6666, | ||
133 | .depth = 24, | ||
134 | }, | ||
135 | [VPDMA_DATA_FMT_BGR24] = { | ||
136 | .data_type = DATA_TYPE_BGR24_888, | ||
137 | .depth = 24, | ||
138 | }, | ||
139 | [VPDMA_DATA_FMT_ABGR32] = { | ||
140 | .data_type = DATA_TYPE_ABGR32_8888, | ||
141 | .depth = 32, | ||
142 | }, | ||
143 | [VPDMA_DATA_FMT_BGRA24] = { | ||
144 | .data_type = DATA_TYPE_BGRA24_6666, | ||
145 | .depth = 24, | ||
146 | }, | ||
147 | [VPDMA_DATA_FMT_BGRA32] = { | ||
148 | .data_type = DATA_TYPE_BGRA32_8888, | ||
149 | .depth = 32, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | const struct vpdma_data_format vpdma_misc_fmts[] = { | ||
154 | [VPDMA_DATA_FMT_MV] = { | ||
155 | .data_type = DATA_TYPE_MV, | ||
156 | .depth = 4, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | struct vpdma_channel_info { | ||
161 | int num; /* VPDMA channel number */ | ||
162 | int cstat_offset; /* client CSTAT register offset */ | ||
163 | }; | ||
164 | |||
165 | static const struct vpdma_channel_info chan_info[] = { | ||
166 | [VPE_CHAN_LUMA1_IN] = { | ||
167 | .num = VPE_CHAN_NUM_LUMA1_IN, | ||
168 | .cstat_offset = VPDMA_DEI_LUMA1_CSTAT, | ||
169 | }, | ||
170 | [VPE_CHAN_CHROMA1_IN] = { | ||
171 | .num = VPE_CHAN_NUM_CHROMA1_IN, | ||
172 | .cstat_offset = VPDMA_DEI_CHROMA1_CSTAT, | ||
173 | }, | ||
174 | [VPE_CHAN_LUMA2_IN] = { | ||
175 | .num = VPE_CHAN_NUM_LUMA2_IN, | ||
176 | .cstat_offset = VPDMA_DEI_LUMA2_CSTAT, | ||
177 | }, | ||
178 | [VPE_CHAN_CHROMA2_IN] = { | ||
179 | .num = VPE_CHAN_NUM_CHROMA2_IN, | ||
180 | .cstat_offset = VPDMA_DEI_CHROMA2_CSTAT, | ||
181 | }, | ||
182 | [VPE_CHAN_LUMA3_IN] = { | ||
183 | .num = VPE_CHAN_NUM_LUMA3_IN, | ||
184 | .cstat_offset = VPDMA_DEI_LUMA3_CSTAT, | ||
185 | }, | ||
186 | [VPE_CHAN_CHROMA3_IN] = { | ||
187 | .num = VPE_CHAN_NUM_CHROMA3_IN, | ||
188 | .cstat_offset = VPDMA_DEI_CHROMA3_CSTAT, | ||
189 | }, | ||
190 | [VPE_CHAN_MV_IN] = { | ||
191 | .num = VPE_CHAN_NUM_MV_IN, | ||
192 | .cstat_offset = VPDMA_DEI_MV_IN_CSTAT, | ||
193 | }, | ||
194 | [VPE_CHAN_MV_OUT] = { | ||
195 | .num = VPE_CHAN_NUM_MV_OUT, | ||
196 | .cstat_offset = VPDMA_DEI_MV_OUT_CSTAT, | ||
197 | }, | ||
198 | [VPE_CHAN_LUMA_OUT] = { | ||
199 | .num = VPE_CHAN_NUM_LUMA_OUT, | ||
200 | .cstat_offset = VPDMA_VIP_UP_Y_CSTAT, | ||
201 | }, | ||
202 | [VPE_CHAN_CHROMA_OUT] = { | ||
203 | .num = VPE_CHAN_NUM_CHROMA_OUT, | ||
204 | .cstat_offset = VPDMA_VIP_UP_UV_CSTAT, | ||
205 | }, | ||
206 | [VPE_CHAN_RGB_OUT] = { | ||
207 | .num = VPE_CHAN_NUM_RGB_OUT, | ||
208 | .cstat_offset = VPDMA_VIP_UP_Y_CSTAT, | ||
209 | }, | ||
210 | }; | ||
211 | |||
212 | static u32 read_reg(struct vpdma_data *vpdma, int offset) | ||
213 | { | ||
214 | return ioread32(vpdma->base + offset); | ||
215 | } | ||
216 | |||
217 | static void write_reg(struct vpdma_data *vpdma, int offset, u32 value) | ||
218 | { | ||
219 | iowrite32(value, vpdma->base + offset); | ||
220 | } | ||
221 | |||
222 | static int read_field_reg(struct vpdma_data *vpdma, int offset, | ||
223 | u32 mask, int shift) | ||
224 | { | ||
225 | return (read_reg(vpdma, offset) & (mask << shift)) >> shift; | ||
226 | } | ||
227 | |||
228 | static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field, | ||
229 | u32 mask, int shift) | ||
230 | { | ||
231 | u32 val = read_reg(vpdma, offset); | ||
232 | |||
233 | val &= ~(mask << shift); | ||
234 | val |= (field & mask) << shift; | ||
235 | |||
236 | write_reg(vpdma, offset, val); | ||
237 | } | ||
238 | |||
239 | void vpdma_dump_regs(struct vpdma_data *vpdma) | ||
240 | { | ||
241 | struct device *dev = &vpdma->pdev->dev; | ||
242 | |||
243 | #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r)) | ||
244 | |||
245 | dev_dbg(dev, "VPDMA Registers:\n"); | ||
246 | |||
247 | DUMPREG(PID); | ||
248 | DUMPREG(LIST_ADDR); | ||
249 | DUMPREG(LIST_ATTR); | ||
250 | DUMPREG(LIST_STAT_SYNC); | ||
251 | DUMPREG(BG_RGB); | ||
252 | DUMPREG(BG_YUV); | ||
253 | DUMPREG(SETUP); | ||
254 | DUMPREG(MAX_SIZE1); | ||
255 | DUMPREG(MAX_SIZE2); | ||
256 | DUMPREG(MAX_SIZE3); | ||
257 | |||
258 | /* | ||
259 | * dumping registers of only group0 and group3, because VPE channels | ||
260 | * lie within group0 and group3 registers | ||
261 | */ | ||
262 | DUMPREG(INT_CHAN_STAT(0)); | ||
263 | DUMPREG(INT_CHAN_MASK(0)); | ||
264 | DUMPREG(INT_CHAN_STAT(3)); | ||
265 | DUMPREG(INT_CHAN_MASK(3)); | ||
266 | DUMPREG(INT_CLIENT0_STAT); | ||
267 | DUMPREG(INT_CLIENT0_MASK); | ||
268 | DUMPREG(INT_CLIENT1_STAT); | ||
269 | DUMPREG(INT_CLIENT1_MASK); | ||
270 | DUMPREG(INT_LIST0_STAT); | ||
271 | DUMPREG(INT_LIST0_MASK); | ||
272 | |||
273 | /* | ||
274 | * these are registers specific to VPE clients, we can make this | ||
275 | * function dump client registers specific to VPE or VIP based on | ||
276 | * who is using it | ||
277 | */ | ||
278 | DUMPREG(DEI_CHROMA1_CSTAT); | ||
279 | DUMPREG(DEI_LUMA1_CSTAT); | ||
280 | DUMPREG(DEI_CHROMA2_CSTAT); | ||
281 | DUMPREG(DEI_LUMA2_CSTAT); | ||
282 | DUMPREG(DEI_CHROMA3_CSTAT); | ||
283 | DUMPREG(DEI_LUMA3_CSTAT); | ||
284 | DUMPREG(DEI_MV_IN_CSTAT); | ||
285 | DUMPREG(DEI_MV_OUT_CSTAT); | ||
286 | DUMPREG(VIP_UP_Y_CSTAT); | ||
287 | DUMPREG(VIP_UP_UV_CSTAT); | ||
288 | DUMPREG(VPI_CTL_CSTAT); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Allocate a DMA buffer | ||
293 | */ | ||
294 | int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size) | ||
295 | { | ||
296 | buf->size = size; | ||
297 | buf->mapped = false; | ||
298 | buf->addr = kzalloc(size, GFP_KERNEL); | ||
299 | if (!buf->addr) | ||
300 | return -ENOMEM; | ||
301 | |||
302 | WARN_ON((u32) buf->addr & VPDMA_DESC_ALIGN); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | void vpdma_free_desc_buf(struct vpdma_buf *buf) | ||
308 | { | ||
309 | WARN_ON(buf->mapped); | ||
310 | kfree(buf->addr); | ||
311 | buf->addr = NULL; | ||
312 | buf->size = 0; | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * map descriptor/payload DMA buffer, enabling DMA access | ||
317 | */ | ||
318 | int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) | ||
319 | { | ||
320 | struct device *dev = &vpdma->pdev->dev; | ||
321 | |||
322 | WARN_ON(buf->mapped); | ||
323 | buf->dma_addr = dma_map_single(dev, buf->addr, buf->size, | ||
324 | DMA_TO_DEVICE); | ||
325 | if (dma_mapping_error(dev, buf->dma_addr)) { | ||
326 | dev_err(dev, "failed to map buffer\n"); | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | |||
330 | buf->mapped = true; | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * unmap descriptor/payload DMA buffer, disabling DMA access and | ||
337 | * allowing the main processor to acces the data | ||
338 | */ | ||
339 | void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) | ||
340 | { | ||
341 | struct device *dev = &vpdma->pdev->dev; | ||
342 | |||
343 | if (buf->mapped) | ||
344 | dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE); | ||
345 | |||
346 | buf->mapped = false; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * create a descriptor list, the user of this list will append configuration, | ||
351 | * control and data descriptors to this list, this list will be submitted to | ||
352 | * VPDMA. VPDMA's list parser will go through each descriptor and perform the | ||
353 | * required DMA operations | ||
354 | */ | ||
355 | int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type) | ||
356 | { | ||
357 | int r; | ||
358 | |||
359 | r = vpdma_alloc_desc_buf(&list->buf, size); | ||
360 | if (r) | ||
361 | return r; | ||
362 | |||
363 | list->next = list->buf.addr; | ||
364 | |||
365 | list->type = type; | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * once a descriptor list is parsed by VPDMA, we reset the list by emptying it, | ||
372 | * to allow new descriptors to be added to the list. | ||
373 | */ | ||
374 | void vpdma_reset_desc_list(struct vpdma_desc_list *list) | ||
375 | { | ||
376 | list->next = list->buf.addr; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * free the buffer allocated fot the VPDMA descriptor list, this should be | ||
381 | * called when the user doesn't want to use VPDMA any more. | ||
382 | */ | ||
383 | void vpdma_free_desc_list(struct vpdma_desc_list *list) | ||
384 | { | ||
385 | vpdma_free_desc_buf(&list->buf); | ||
386 | |||
387 | list->next = NULL; | ||
388 | } | ||
389 | |||
390 | static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num) | ||
391 | { | ||
392 | return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16); | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion | ||
397 | */ | ||
398 | int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list) | ||
399 | { | ||
400 | /* we always use the first list */ | ||
401 | int list_num = 0; | ||
402 | int list_size; | ||
403 | |||
404 | if (vpdma_list_busy(vpdma, list_num)) | ||
405 | return -EBUSY; | ||
406 | |||
407 | /* 16-byte granularity */ | ||
408 | list_size = (list->next - list->buf.addr) >> 4; | ||
409 | |||
410 | write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr); | ||
411 | |||
412 | write_reg(vpdma, VPDMA_LIST_ATTR, | ||
413 | (list_num << VPDMA_LIST_NUM_SHFT) | | ||
414 | (list->type << VPDMA_LIST_TYPE_SHFT) | | ||
415 | list_size); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static void dump_cfd(struct vpdma_cfd *cfd) | ||
421 | { | ||
422 | int class; | ||
423 | |||
424 | class = cfd_get_class(cfd); | ||
425 | |||
426 | pr_debug("config descriptor of payload class: %s\n", | ||
427 | class == CFD_CLS_BLOCK ? "simple block" : | ||
428 | "address data block"); | ||
429 | |||
430 | if (class == CFD_CLS_BLOCK) | ||
431 | pr_debug("word0: dst_addr_offset = 0x%08x\n", | ||
432 | cfd->dest_addr_offset); | ||
433 | |||
434 | if (class == CFD_CLS_BLOCK) | ||
435 | pr_debug("word1: num_data_wrds = %d\n", cfd->block_len); | ||
436 | |||
437 | pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr); | ||
438 | |||
439 | pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, " | ||
440 | "payload_len = %d\n", cfd_get_pkt_type(cfd), | ||
441 | cfd_get_direct(cfd), class, cfd_get_dest(cfd), | ||
442 | cfd_get_payload_len(cfd)); | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * append a configuration descriptor to the given descriptor list, where the | ||
447 | * payload is in the form of a simple data block specified in the descriptor | ||
448 | * header, this is used to upload scaler coefficients to the scaler module | ||
449 | */ | ||
450 | void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, | ||
451 | struct vpdma_buf *blk, u32 dest_offset) | ||
452 | { | ||
453 | struct vpdma_cfd *cfd; | ||
454 | int len = blk->size; | ||
455 | |||
456 | WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN); | ||
457 | |||
458 | cfd = list->next; | ||
459 | WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size)); | ||
460 | |||
461 | cfd->dest_addr_offset = dest_offset; | ||
462 | cfd->block_len = len; | ||
463 | cfd->payload_addr = (u32) blk->dma_addr; | ||
464 | cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK, | ||
465 | client, len >> 4); | ||
466 | |||
467 | list->next = cfd + 1; | ||
468 | |||
469 | dump_cfd(cfd); | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * append a configuration descriptor to the given descriptor list, where the | ||
474 | * payload is in the address data block format, this is used to a configure a | ||
475 | * discontiguous set of MMRs | ||
476 | */ | ||
477 | void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, | ||
478 | struct vpdma_buf *adb) | ||
479 | { | ||
480 | struct vpdma_cfd *cfd; | ||
481 | unsigned int len = adb->size; | ||
482 | |||
483 | WARN_ON(len & VPDMA_ADB_SIZE_ALIGN); | ||
484 | WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN); | ||
485 | |||
486 | cfd = list->next; | ||
487 | BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size)); | ||
488 | |||
489 | cfd->w0 = 0; | ||
490 | cfd->w1 = 0; | ||
491 | cfd->payload_addr = (u32) adb->dma_addr; | ||
492 | cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB, | ||
493 | client, len >> 4); | ||
494 | |||
495 | list->next = cfd + 1; | ||
496 | |||
497 | dump_cfd(cfd); | ||
498 | }; | ||
499 | |||
500 | /* | ||
501 | * control descriptor format change based on what type of control descriptor it | ||
502 | * is, we only use 'sync on channel' control descriptors for now, so assume it's | ||
503 | * that | ||
504 | */ | ||
505 | static void dump_ctd(struct vpdma_ctd *ctd) | ||
506 | { | ||
507 | pr_debug("control descriptor\n"); | ||
508 | |||
509 | pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n", | ||
510 | ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd)); | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * append a 'sync on channel' type control descriptor to the given descriptor | ||
515 | * list, this descriptor stalls the VPDMA list till the time DMA is completed | ||
516 | * on the specified channel | ||
517 | */ | ||
518 | void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, | ||
519 | enum vpdma_channel chan) | ||
520 | { | ||
521 | struct vpdma_ctd *ctd; | ||
522 | |||
523 | ctd = list->next; | ||
524 | WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size)); | ||
525 | |||
526 | ctd->w0 = 0; | ||
527 | ctd->w1 = 0; | ||
528 | ctd->w2 = 0; | ||
529 | ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num, | ||
530 | CTD_TYPE_SYNC_ON_CHANNEL); | ||
531 | |||
532 | list->next = ctd + 1; | ||
533 | |||
534 | dump_ctd(ctd); | ||
535 | } | ||
536 | |||
537 | static void dump_dtd(struct vpdma_dtd *dtd) | ||
538 | { | ||
539 | int dir, chan; | ||
540 | |||
541 | dir = dtd_get_dir(dtd); | ||
542 | chan = dtd_get_chan(dtd); | ||
543 | |||
544 | pr_debug("%s data transfer descriptor for channel %d\n", | ||
545 | dir == DTD_DIR_OUT ? "outbound" : "inbound", chan); | ||
546 | |||
547 | pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, " | ||
548 | "even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n", | ||
549 | dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd), | ||
550 | dtd_get_1d(dtd), dtd_get_even_line_skip(dtd), | ||
551 | dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd)); | ||
552 | |||
553 | if (dir == DTD_DIR_IN) | ||
554 | pr_debug("word1: line_length = %d, xfer_height = %d\n", | ||
555 | dtd_get_line_length(dtd), dtd_get_xfer_height(dtd)); | ||
556 | |||
557 | pr_debug("word2: start_addr = 0x%08x\n", dtd->start_addr); | ||
558 | |||
559 | pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, " | ||
560 | "pri = %d, next_chan = %d\n", dtd_get_pkt_type(dtd), | ||
561 | dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd), | ||
562 | dtd_get_next_chan(dtd)); | ||
563 | |||
564 | if (dir == DTD_DIR_IN) | ||
565 | pr_debug("word4: frame_width = %d, frame_height = %d\n", | ||
566 | dtd_get_frame_width(dtd), dtd_get_frame_height(dtd)); | ||
567 | else | ||
568 | pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, " | ||
569 | "drp_data = %d, use_desc_reg = %d\n", | ||
570 | dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd), | ||
571 | dtd_get_drop_data(dtd), dtd_get_use_desc(dtd)); | ||
572 | |||
573 | if (dir == DTD_DIR_IN) | ||
574 | pr_debug("word5: hor_start = %d, ver_start = %d\n", | ||
575 | dtd_get_h_start(dtd), dtd_get_v_start(dtd)); | ||
576 | else | ||
577 | pr_debug("word5: max_width %d, max_height %d\n", | ||
578 | dtd_get_max_width(dtd), dtd_get_max_height(dtd)); | ||
579 | |||
580 | pr_debug("word6: client specfic attr0 = 0x%08x\n", dtd->client_attr0); | ||
581 | pr_debug("word7: client specfic attr1 = 0x%08x\n", dtd->client_attr1); | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * append an outbound data transfer descriptor to the given descriptor list, | ||
586 | * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel | ||
587 | */ | ||
588 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | ||
589 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | ||
590 | enum vpdma_channel chan, u32 flags) | ||
591 | { | ||
592 | int priority = 0; | ||
593 | int field = 0; | ||
594 | int notify = 1; | ||
595 | int channel, next_chan; | ||
596 | int depth = fmt->depth; | ||
597 | int stride; | ||
598 | struct vpdma_dtd *dtd; | ||
599 | |||
600 | channel = next_chan = chan_info[chan].num; | ||
601 | |||
602 | if (fmt->data_type == DATA_TYPE_C420) | ||
603 | depth = 8; | ||
604 | |||
605 | stride = (depth * c_rect->width) >> 3; | ||
606 | dma_addr += (c_rect->left * depth) >> 3; | ||
607 | |||
608 | dtd = list->next; | ||
609 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); | ||
610 | |||
611 | dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type, | ||
612 | notify, | ||
613 | field, | ||
614 | !!(flags & VPDMA_DATA_FRAME_1D), | ||
615 | !!(flags & VPDMA_DATA_EVEN_LINE_SKIP), | ||
616 | !!(flags & VPDMA_DATA_ODD_LINE_SKIP), | ||
617 | stride); | ||
618 | dtd->w1 = 0; | ||
619 | dtd->start_addr = (u32) dma_addr; | ||
620 | dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), | ||
621 | DTD_DIR_OUT, channel, priority, next_chan); | ||
622 | dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0); | ||
623 | dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920, | ||
624 | MAX_OUT_HEIGHT_1080); | ||
625 | dtd->client_attr0 = 0; | ||
626 | dtd->client_attr1 = 0; | ||
627 | |||
628 | list->next = dtd + 1; | ||
629 | |||
630 | dump_dtd(dtd); | ||
631 | } | ||
632 | |||
633 | /* | ||
634 | * append an inbound data transfer descriptor to the given descriptor list, | ||
635 | * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel | ||
636 | */ | ||
637 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, | ||
638 | int frame_height, struct v4l2_rect *c_rect, | ||
639 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | ||
640 | enum vpdma_channel chan, int field, u32 flags) | ||
641 | { | ||
642 | int priority = 0; | ||
643 | int notify = 1; | ||
644 | int depth = fmt->depth; | ||
645 | int channel, next_chan; | ||
646 | int stride; | ||
647 | int height = c_rect->height; | ||
648 | struct vpdma_dtd *dtd; | ||
649 | |||
650 | channel = next_chan = chan_info[chan].num; | ||
651 | |||
652 | if (fmt->data_type == DATA_TYPE_C420) { | ||
653 | height >>= 1; | ||
654 | frame_height >>= 1; | ||
655 | depth = 8; | ||
656 | } | ||
657 | |||
658 | stride = (depth * c_rect->width) >> 3; | ||
659 | dma_addr += (c_rect->left * depth) >> 3; | ||
660 | |||
661 | dtd = list->next; | ||
662 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); | ||
663 | |||
664 | dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type, | ||
665 | notify, | ||
666 | field, | ||
667 | !!(flags & VPDMA_DATA_FRAME_1D), | ||
668 | !!(flags & VPDMA_DATA_EVEN_LINE_SKIP), | ||
669 | !!(flags & VPDMA_DATA_ODD_LINE_SKIP), | ||
670 | stride); | ||
671 | |||
672 | dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height); | ||
673 | dtd->start_addr = (u32) dma_addr; | ||
674 | dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), | ||
675 | DTD_DIR_IN, channel, priority, next_chan); | ||
676 | dtd->frame_width_height = dtd_frame_width_height(frame_width, | ||
677 | frame_height); | ||
678 | dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top); | ||
679 | dtd->client_attr0 = 0; | ||
680 | dtd->client_attr1 = 0; | ||
681 | |||
682 | list->next = dtd + 1; | ||
683 | |||
684 | dump_dtd(dtd); | ||
685 | } | ||
686 | |||
687 | /* set or clear the mask for list complete interrupt */ | ||
688 | void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, | ||
689 | bool enable) | ||
690 | { | ||
691 | u32 val; | ||
692 | |||
693 | val = read_reg(vpdma, VPDMA_INT_LIST0_MASK); | ||
694 | if (enable) | ||
695 | val |= (1 << (list_num * 2)); | ||
696 | else | ||
697 | val &= ~(1 << (list_num * 2)); | ||
698 | write_reg(vpdma, VPDMA_INT_LIST0_MASK, val); | ||
699 | } | ||
700 | |||
701 | /* clear previosuly occured list intterupts in the LIST_STAT register */ | ||
702 | void vpdma_clear_list_stat(struct vpdma_data *vpdma) | ||
703 | { | ||
704 | write_reg(vpdma, VPDMA_INT_LIST0_STAT, | ||
705 | read_reg(vpdma, VPDMA_INT_LIST0_STAT)); | ||
706 | } | ||
707 | |||
708 | /* | ||
709 | * configures the output mode of the line buffer for the given client, the | ||
710 | * line buffer content can either be mirrored(each line repeated twice) or | ||
711 | * passed to the client as is | ||
712 | */ | ||
713 | void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, | ||
714 | enum vpdma_channel chan) | ||
715 | { | ||
716 | int client_cstat = chan_info[chan].cstat_offset; | ||
717 | |||
718 | write_field_reg(vpdma, client_cstat, line_mode, | ||
719 | VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT); | ||
720 | } | ||
721 | |||
722 | /* | ||
723 | * configures the event which should trigger VPDMA transfer for the given | ||
724 | * client | ||
725 | */ | ||
726 | void vpdma_set_frame_start_event(struct vpdma_data *vpdma, | ||
727 | enum vpdma_frame_start_event fs_event, | ||
728 | enum vpdma_channel chan) | ||
729 | { | ||
730 | int client_cstat = chan_info[chan].cstat_offset; | ||
731 | |||
732 | write_field_reg(vpdma, client_cstat, fs_event, | ||
733 | VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT); | ||
734 | } | ||
735 | |||
736 | static void vpdma_firmware_cb(const struct firmware *f, void *context) | ||
737 | { | ||
738 | struct vpdma_data *vpdma = context; | ||
739 | struct vpdma_buf fw_dma_buf; | ||
740 | int i, r; | ||
741 | |||
742 | dev_dbg(&vpdma->pdev->dev, "firmware callback\n"); | ||
743 | |||
744 | if (!f || !f->data) { | ||
745 | dev_err(&vpdma->pdev->dev, "couldn't get firmware\n"); | ||
746 | return; | ||
747 | } | ||
748 | |||
749 | /* already initialized */ | ||
750 | if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, | ||
751 | VPDMA_LIST_RDY_SHFT)) { | ||
752 | vpdma->ready = true; | ||
753 | return; | ||
754 | } | ||
755 | |||
756 | r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size); | ||
757 | if (r) { | ||
758 | dev_err(&vpdma->pdev->dev, | ||
759 | "failed to allocate dma buffer for firmware\n"); | ||
760 | goto rel_fw; | ||
761 | } | ||
762 | |||
763 | memcpy(fw_dma_buf.addr, f->data, f->size); | ||
764 | |||
765 | vpdma_map_desc_buf(vpdma, &fw_dma_buf); | ||
766 | |||
767 | write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr); | ||
768 | |||
769 | for (i = 0; i < 100; i++) { /* max 1 second */ | ||
770 | msleep_interruptible(10); | ||
771 | |||
772 | if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, | ||
773 | VPDMA_LIST_RDY_SHFT)) | ||
774 | break; | ||
775 | } | ||
776 | |||
777 | if (i == 100) { | ||
778 | dev_err(&vpdma->pdev->dev, "firmware upload failed\n"); | ||
779 | goto free_buf; | ||
780 | } | ||
781 | |||
782 | vpdma->ready = true; | ||
783 | |||
784 | free_buf: | ||
785 | vpdma_unmap_desc_buf(vpdma, &fw_dma_buf); | ||
786 | |||
787 | vpdma_free_desc_buf(&fw_dma_buf); | ||
788 | rel_fw: | ||
789 | release_firmware(f); | ||
790 | } | ||
791 | |||
792 | static int vpdma_load_firmware(struct vpdma_data *vpdma) | ||
793 | { | ||
794 | int r; | ||
795 | struct device *dev = &vpdma->pdev->dev; | ||
796 | |||
797 | r = request_firmware_nowait(THIS_MODULE, 1, | ||
798 | (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma, | ||
799 | vpdma_firmware_cb); | ||
800 | if (r) { | ||
801 | dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE); | ||
802 | return r; | ||
803 | } else { | ||
804 | dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE); | ||
805 | } | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | struct vpdma_data *vpdma_create(struct platform_device *pdev) | ||
811 | { | ||
812 | struct resource *res; | ||
813 | struct vpdma_data *vpdma; | ||
814 | int r; | ||
815 | |||
816 | dev_dbg(&pdev->dev, "vpdma_create\n"); | ||
817 | |||
818 | vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL); | ||
819 | if (!vpdma) { | ||
820 | dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n"); | ||
821 | return ERR_PTR(-ENOMEM); | ||
822 | } | ||
823 | |||
824 | vpdma->pdev = pdev; | ||
825 | |||
826 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); | ||
827 | if (res == NULL) { | ||
828 | dev_err(&pdev->dev, "missing platform resources data\n"); | ||
829 | return ERR_PTR(-ENODEV); | ||
830 | } | ||
831 | |||
832 | vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
833 | if (!vpdma->base) { | ||
834 | dev_err(&pdev->dev, "failed to ioremap\n"); | ||
835 | return ERR_PTR(-ENOMEM); | ||
836 | } | ||
837 | |||
838 | r = vpdma_load_firmware(vpdma); | ||
839 | if (r) { | ||
840 | pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE); | ||
841 | return ERR_PTR(r); | ||
842 | } | ||
843 | |||
844 | return vpdma; | ||
845 | } | ||
846 | MODULE_FIRMWARE(VPDMA_FIRMWARE); | ||
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h new file mode 100644 index 000000000000..eaa2a71a5db9 --- /dev/null +++ b/drivers/media/platform/ti-vpe/vpdma.h | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Texas Instruments Inc. | ||
3 | * | ||
4 | * David Griego, <dagriego@biglakesoftware.com> | ||
5 | * Dale Farnsworth, <dale@farnsworth.org> | ||
6 | * Archit Taneja, <archit@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __TI_VPDMA_H_ | ||
14 | #define __TI_VPDMA_H_ | ||
15 | |||
16 | /* | ||
17 | * A vpdma_buf tracks the size, DMA address and mapping status of each | ||
18 | * driver DMA area. | ||
19 | */ | ||
20 | struct vpdma_buf { | ||
21 | void *addr; | ||
22 | dma_addr_t dma_addr; | ||
23 | size_t size; | ||
24 | bool mapped; | ||
25 | }; | ||
26 | |||
27 | struct vpdma_desc_list { | ||
28 | struct vpdma_buf buf; | ||
29 | void *next; | ||
30 | int type; | ||
31 | }; | ||
32 | |||
33 | struct vpdma_data { | ||
34 | void __iomem *base; | ||
35 | |||
36 | struct platform_device *pdev; | ||
37 | |||
38 | /* tells whether vpdma firmware is loaded or not */ | ||
39 | bool ready; | ||
40 | }; | ||
41 | |||
42 | struct vpdma_data_format { | ||
43 | int data_type; | ||
44 | u8 depth; | ||
45 | }; | ||
46 | |||
47 | #define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */ | ||
48 | |||
49 | #define VPDMA_DTD_DESC_SIZE 32 /* 8 words */ | ||
50 | #define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */ | ||
51 | |||
52 | #define VPDMA_LIST_TYPE_NORMAL 0 | ||
53 | #define VPDMA_LIST_TYPE_SELF_MODIFYING 1 | ||
54 | #define VPDMA_LIST_TYPE_DOORBELL 2 | ||
55 | |||
56 | enum vpdma_yuv_formats { | ||
57 | VPDMA_DATA_FMT_Y444 = 0, | ||
58 | VPDMA_DATA_FMT_Y422, | ||
59 | VPDMA_DATA_FMT_Y420, | ||
60 | VPDMA_DATA_FMT_C444, | ||
61 | VPDMA_DATA_FMT_C422, | ||
62 | VPDMA_DATA_FMT_C420, | ||
63 | VPDMA_DATA_FMT_YC422, | ||
64 | VPDMA_DATA_FMT_YC444, | ||
65 | VPDMA_DATA_FMT_CY422, | ||
66 | }; | ||
67 | |||
68 | enum vpdma_rgb_formats { | ||
69 | VPDMA_DATA_FMT_RGB565 = 0, | ||
70 | VPDMA_DATA_FMT_ARGB16_1555, | ||
71 | VPDMA_DATA_FMT_ARGB16, | ||
72 | VPDMA_DATA_FMT_RGBA16_5551, | ||
73 | VPDMA_DATA_FMT_RGBA16, | ||
74 | VPDMA_DATA_FMT_ARGB24, | ||
75 | VPDMA_DATA_FMT_RGB24, | ||
76 | VPDMA_DATA_FMT_ARGB32, | ||
77 | VPDMA_DATA_FMT_RGBA24, | ||
78 | VPDMA_DATA_FMT_RGBA32, | ||
79 | VPDMA_DATA_FMT_BGR565, | ||
80 | VPDMA_DATA_FMT_ABGR16_1555, | ||
81 | VPDMA_DATA_FMT_ABGR16, | ||
82 | VPDMA_DATA_FMT_BGRA16_5551, | ||
83 | VPDMA_DATA_FMT_BGRA16, | ||
84 | VPDMA_DATA_FMT_ABGR24, | ||
85 | VPDMA_DATA_FMT_BGR24, | ||
86 | VPDMA_DATA_FMT_ABGR32, | ||
87 | VPDMA_DATA_FMT_BGRA24, | ||
88 | VPDMA_DATA_FMT_BGRA32, | ||
89 | }; | ||
90 | |||
91 | enum vpdma_misc_formats { | ||
92 | VPDMA_DATA_FMT_MV = 0, | ||
93 | }; | ||
94 | |||
95 | extern const struct vpdma_data_format vpdma_yuv_fmts[]; | ||
96 | extern const struct vpdma_data_format vpdma_rgb_fmts[]; | ||
97 | extern const struct vpdma_data_format vpdma_misc_fmts[]; | ||
98 | |||
99 | enum vpdma_frame_start_event { | ||
100 | VPDMA_FSEVENT_HDMI_FID = 0, | ||
101 | VPDMA_FSEVENT_DVO2_FID, | ||
102 | VPDMA_FSEVENT_HDCOMP_FID, | ||
103 | VPDMA_FSEVENT_SD_FID, | ||
104 | VPDMA_FSEVENT_LM_FID0, | ||
105 | VPDMA_FSEVENT_LM_FID1, | ||
106 | VPDMA_FSEVENT_LM_FID2, | ||
107 | VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
108 | }; | ||
109 | |||
110 | /* | ||
111 | * VPDMA channel numbers | ||
112 | */ | ||
113 | enum vpdma_channel { | ||
114 | VPE_CHAN_LUMA1_IN, | ||
115 | VPE_CHAN_CHROMA1_IN, | ||
116 | VPE_CHAN_LUMA2_IN, | ||
117 | VPE_CHAN_CHROMA2_IN, | ||
118 | VPE_CHAN_LUMA3_IN, | ||
119 | VPE_CHAN_CHROMA3_IN, | ||
120 | VPE_CHAN_MV_IN, | ||
121 | VPE_CHAN_MV_OUT, | ||
122 | VPE_CHAN_LUMA_OUT, | ||
123 | VPE_CHAN_CHROMA_OUT, | ||
124 | VPE_CHAN_RGB_OUT, | ||
125 | }; | ||
126 | |||
127 | /* flags for VPDMA data descriptors */ | ||
128 | #define VPDMA_DATA_ODD_LINE_SKIP (1 << 0) | ||
129 | #define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1) | ||
130 | #define VPDMA_DATA_FRAME_1D (1 << 2) | ||
131 | #define VPDMA_DATA_MODE_TILED (1 << 3) | ||
132 | |||
133 | /* | ||
134 | * client identifiers used for configuration descriptors | ||
135 | */ | ||
136 | #define CFD_MMR_CLIENT 0 | ||
137 | #define CFD_SC_CLIENT 4 | ||
138 | |||
139 | /* Address data block header format */ | ||
140 | struct vpdma_adb_hdr { | ||
141 | u32 offset; | ||
142 | u32 nwords; | ||
143 | u32 reserved0; | ||
144 | u32 reserved1; | ||
145 | }; | ||
146 | |||
147 | /* helpers for creating ADB headers for config descriptors MMRs as client */ | ||
148 | #define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld)) | ||
149 | #define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld) | ||
150 | |||
151 | #define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \ | ||
152 | do { \ | ||
153 | struct vpdma_adb_hdr *h; \ | ||
154 | struct str *adb = NULL; \ | ||
155 | h = MMR_ADB_ADDR(buf, str, hdr); \ | ||
156 | h->offset = (offset_a); \ | ||
157 | h->nwords = sizeof(adb->regs) >> 2; \ | ||
158 | } while (0) | ||
159 | |||
160 | /* vpdma descriptor buffer allocation and management */ | ||
161 | int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size); | ||
162 | void vpdma_free_desc_buf(struct vpdma_buf *buf); | ||
163 | int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf); | ||
164 | void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf); | ||
165 | |||
166 | /* vpdma descriptor list funcs */ | ||
167 | int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type); | ||
168 | void vpdma_reset_desc_list(struct vpdma_desc_list *list); | ||
169 | void vpdma_free_desc_list(struct vpdma_desc_list *list); | ||
170 | int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list); | ||
171 | |||
172 | /* helpers for creating vpdma descriptors */ | ||
173 | void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, | ||
174 | struct vpdma_buf *blk, u32 dest_offset); | ||
175 | void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, | ||
176 | struct vpdma_buf *adb); | ||
177 | void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, | ||
178 | enum vpdma_channel chan); | ||
179 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | ||
180 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | ||
181 | enum vpdma_channel chan, u32 flags); | ||
182 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, | ||
183 | int frame_height, struct v4l2_rect *c_rect, | ||
184 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | ||
185 | enum vpdma_channel chan, int field, u32 flags); | ||
186 | |||
187 | /* vpdma list interrupt management */ | ||
188 | void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, | ||
189 | bool enable); | ||
190 | void vpdma_clear_list_stat(struct vpdma_data *vpdma); | ||
191 | |||
192 | /* vpdma client configuration */ | ||
193 | void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, | ||
194 | enum vpdma_channel chan); | ||
195 | void vpdma_set_frame_start_event(struct vpdma_data *vpdma, | ||
196 | enum vpdma_frame_start_event fs_event, enum vpdma_channel chan); | ||
197 | |||
198 | void vpdma_dump_regs(struct vpdma_data *vpdma); | ||
199 | |||
200 | /* initialize vpdma, passed with VPE's platform device pointer */ | ||
201 | struct vpdma_data *vpdma_create(struct platform_device *pdev); | ||
202 | |||
203 | #endif | ||
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h new file mode 100644 index 000000000000..f0e9a8038c1b --- /dev/null +++ b/drivers/media/platform/ti-vpe/vpdma_priv.h | |||
@@ -0,0 +1,641 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Texas Instruments Inc. | ||
3 | * | ||
4 | * David Griego, <dagriego@biglakesoftware.com> | ||
5 | * Dale Farnsworth, <dale@farnsworth.org> | ||
6 | * Archit Taneja, <archit@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef _TI_VPDMA_PRIV_H_ | ||
14 | #define _TI_VPDMA_PRIV_H_ | ||
15 | |||
16 | /* | ||
17 | * VPDMA Register offsets | ||
18 | */ | ||
19 | |||
20 | /* Top level */ | ||
21 | #define VPDMA_PID 0x00 | ||
22 | #define VPDMA_LIST_ADDR 0x04 | ||
23 | #define VPDMA_LIST_ATTR 0x08 | ||
24 | #define VPDMA_LIST_STAT_SYNC 0x0c | ||
25 | #define VPDMA_BG_RGB 0x18 | ||
26 | #define VPDMA_BG_YUV 0x1c | ||
27 | #define VPDMA_SETUP 0x30 | ||
28 | #define VPDMA_MAX_SIZE1 0x34 | ||
29 | #define VPDMA_MAX_SIZE2 0x38 | ||
30 | #define VPDMA_MAX_SIZE3 0x3c | ||
31 | |||
32 | /* Interrupts */ | ||
33 | #define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8) | ||
34 | #define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4) | ||
35 | #define VPDMA_INT_CLIENT0_STAT 0x78 | ||
36 | #define VPDMA_INT_CLIENT0_MASK 0x7c | ||
37 | #define VPDMA_INT_CLIENT1_STAT 0x80 | ||
38 | #define VPDMA_INT_CLIENT1_MASK 0x84 | ||
39 | #define VPDMA_INT_LIST0_STAT 0x88 | ||
40 | #define VPDMA_INT_LIST0_MASK 0x8c | ||
41 | |||
42 | #define VPDMA_PERFMON(i) (0x200 + i * 4) | ||
43 | |||
44 | /* VPE specific client registers */ | ||
45 | #define VPDMA_DEI_CHROMA1_CSTAT 0x0300 | ||
46 | #define VPDMA_DEI_LUMA1_CSTAT 0x0304 | ||
47 | #define VPDMA_DEI_LUMA2_CSTAT 0x0308 | ||
48 | #define VPDMA_DEI_CHROMA2_CSTAT 0x030c | ||
49 | #define VPDMA_DEI_LUMA3_CSTAT 0x0310 | ||
50 | #define VPDMA_DEI_CHROMA3_CSTAT 0x0314 | ||
51 | #define VPDMA_DEI_MV_IN_CSTAT 0x0330 | ||
52 | #define VPDMA_DEI_MV_OUT_CSTAT 0x033c | ||
53 | #define VPDMA_VIP_UP_Y_CSTAT 0x0390 | ||
54 | #define VPDMA_VIP_UP_UV_CSTAT 0x0394 | ||
55 | #define VPDMA_VPI_CTL_CSTAT 0x03d0 | ||
56 | |||
57 | /* Reg field info for VPDMA_CLIENT_CSTAT registers */ | ||
58 | #define VPDMA_CSTAT_LINE_MODE_MASK 0x03 | ||
59 | #define VPDMA_CSTAT_LINE_MODE_SHIFT 8 | ||
60 | #define VPDMA_CSTAT_FRAME_START_MASK 0xf | ||
61 | #define VPDMA_CSTAT_FRAME_START_SHIFT 10 | ||
62 | |||
63 | #define VPDMA_LIST_NUM_MASK 0x07 | ||
64 | #define VPDMA_LIST_NUM_SHFT 24 | ||
65 | #define VPDMA_LIST_STOP_SHFT 20 | ||
66 | #define VPDMA_LIST_RDY_MASK 0x01 | ||
67 | #define VPDMA_LIST_RDY_SHFT 19 | ||
68 | #define VPDMA_LIST_TYPE_MASK 0x03 | ||
69 | #define VPDMA_LIST_TYPE_SHFT 16 | ||
70 | #define VPDMA_LIST_SIZE_MASK 0xffff | ||
71 | |||
72 | /* VPDMA data type values for data formats */ | ||
73 | #define DATA_TYPE_Y444 0x0 | ||
74 | #define DATA_TYPE_Y422 0x1 | ||
75 | #define DATA_TYPE_Y420 0x2 | ||
76 | #define DATA_TYPE_C444 0x4 | ||
77 | #define DATA_TYPE_C422 0x5 | ||
78 | #define DATA_TYPE_C420 0x6 | ||
79 | #define DATA_TYPE_YC422 0x7 | ||
80 | #define DATA_TYPE_YC444 0x8 | ||
81 | #define DATA_TYPE_CY422 0x23 | ||
82 | |||
83 | #define DATA_TYPE_RGB16_565 0x0 | ||
84 | #define DATA_TYPE_ARGB_1555 0x1 | ||
85 | #define DATA_TYPE_ARGB_4444 0x2 | ||
86 | #define DATA_TYPE_RGBA_5551 0x3 | ||
87 | #define DATA_TYPE_RGBA_4444 0x4 | ||
88 | #define DATA_TYPE_ARGB24_6666 0x5 | ||
89 | #define DATA_TYPE_RGB24_888 0x6 | ||
90 | #define DATA_TYPE_ARGB32_8888 0x7 | ||
91 | #define DATA_TYPE_RGBA24_6666 0x8 | ||
92 | #define DATA_TYPE_RGBA32_8888 0x9 | ||
93 | #define DATA_TYPE_BGR16_565 0x10 | ||
94 | #define DATA_TYPE_ABGR_1555 0x11 | ||
95 | #define DATA_TYPE_ABGR_4444 0x12 | ||
96 | #define DATA_TYPE_BGRA_5551 0x13 | ||
97 | #define DATA_TYPE_BGRA_4444 0x14 | ||
98 | #define DATA_TYPE_ABGR24_6666 0x15 | ||
99 | #define DATA_TYPE_BGR24_888 0x16 | ||
100 | #define DATA_TYPE_ABGR32_8888 0x17 | ||
101 | #define DATA_TYPE_BGRA24_6666 0x18 | ||
102 | #define DATA_TYPE_BGRA32_8888 0x19 | ||
103 | |||
104 | #define DATA_TYPE_MV 0x3 | ||
105 | |||
106 | /* VPDMA channel numbers(only VPE channels for now) */ | ||
107 | #define VPE_CHAN_NUM_LUMA1_IN 0 | ||
108 | #define VPE_CHAN_NUM_CHROMA1_IN 1 | ||
109 | #define VPE_CHAN_NUM_LUMA2_IN 2 | ||
110 | #define VPE_CHAN_NUM_CHROMA2_IN 3 | ||
111 | #define VPE_CHAN_NUM_LUMA3_IN 4 | ||
112 | #define VPE_CHAN_NUM_CHROMA3_IN 5 | ||
113 | #define VPE_CHAN_NUM_MV_IN 12 | ||
114 | #define VPE_CHAN_NUM_MV_OUT 15 | ||
115 | #define VPE_CHAN_NUM_LUMA_OUT 102 | ||
116 | #define VPE_CHAN_NUM_CHROMA_OUT 103 | ||
117 | #define VPE_CHAN_NUM_RGB_OUT 106 | ||
118 | |||
119 | /* | ||
120 | * a VPDMA address data block payload for a configuration descriptor needs to | ||
121 | * have each sub block length as a multiple of 16 bytes. Therefore, the overall | ||
122 | * size of the payload also needs to be a multiple of 16 bytes. The sub block | ||
123 | * lengths should be ensured to be aligned by the VPDMA user. | ||
124 | */ | ||
125 | #define VPDMA_ADB_SIZE_ALIGN 0x0f | ||
126 | |||
127 | /* | ||
128 | * data transfer descriptor | ||
129 | */ | ||
130 | struct vpdma_dtd { | ||
131 | u32 type_ctl_stride; | ||
132 | union { | ||
133 | u32 xfer_length_height; | ||
134 | u32 w1; | ||
135 | }; | ||
136 | dma_addr_t start_addr; | ||
137 | u32 pkt_ctl; | ||
138 | union { | ||
139 | u32 frame_width_height; /* inbound */ | ||
140 | dma_addr_t desc_write_addr; /* outbound */ | ||
141 | }; | ||
142 | union { | ||
143 | u32 start_h_v; /* inbound */ | ||
144 | u32 max_width_height; /* outbound */ | ||
145 | }; | ||
146 | u32 client_attr0; | ||
147 | u32 client_attr1; | ||
148 | }; | ||
149 | |||
150 | /* Data Transfer Descriptor specifics */ | ||
151 | #define DTD_NO_NOTIFY 0 | ||
152 | #define DTD_NOTIFY 1 | ||
153 | |||
154 | #define DTD_PKT_TYPE 0xa | ||
155 | #define DTD_DIR_IN 0 | ||
156 | #define DTD_DIR_OUT 1 | ||
157 | |||
158 | /* type_ctl_stride */ | ||
159 | #define DTD_DATA_TYPE_MASK 0x3f | ||
160 | #define DTD_DATA_TYPE_SHFT 26 | ||
161 | #define DTD_NOTIFY_MASK 0x01 | ||
162 | #define DTD_NOTIFY_SHFT 25 | ||
163 | #define DTD_FIELD_MASK 0x01 | ||
164 | #define DTD_FIELD_SHFT 24 | ||
165 | #define DTD_1D_MASK 0x01 | ||
166 | #define DTD_1D_SHFT 23 | ||
167 | #define DTD_EVEN_LINE_SKIP_MASK 0x01 | ||
168 | #define DTD_EVEN_LINE_SKIP_SHFT 20 | ||
169 | #define DTD_ODD_LINE_SKIP_MASK 0x01 | ||
170 | #define DTD_ODD_LINE_SKIP_SHFT 16 | ||
171 | #define DTD_LINE_STRIDE_MASK 0xffff | ||
172 | #define DTD_LINE_STRIDE_SHFT 0 | ||
173 | |||
174 | /* xfer_length_height */ | ||
175 | #define DTD_LINE_LENGTH_MASK 0xffff | ||
176 | #define DTD_LINE_LENGTH_SHFT 16 | ||
177 | #define DTD_XFER_HEIGHT_MASK 0xffff | ||
178 | #define DTD_XFER_HEIGHT_SHFT 0 | ||
179 | |||
180 | /* pkt_ctl */ | ||
181 | #define DTD_PKT_TYPE_MASK 0x1f | ||
182 | #define DTD_PKT_TYPE_SHFT 27 | ||
183 | #define DTD_MODE_MASK 0x01 | ||
184 | #define DTD_MODE_SHFT 26 | ||
185 | #define DTD_DIR_MASK 0x01 | ||
186 | #define DTD_DIR_SHFT 25 | ||
187 | #define DTD_CHAN_MASK 0x01ff | ||
188 | #define DTD_CHAN_SHFT 16 | ||
189 | #define DTD_PRI_MASK 0x0f | ||
190 | #define DTD_PRI_SHFT 9 | ||
191 | #define DTD_NEXT_CHAN_MASK 0x01ff | ||
192 | #define DTD_NEXT_CHAN_SHFT 0 | ||
193 | |||
194 | /* frame_width_height */ | ||
195 | #define DTD_FRAME_WIDTH_MASK 0xffff | ||
196 | #define DTD_FRAME_WIDTH_SHFT 16 | ||
197 | #define DTD_FRAME_HEIGHT_MASK 0xffff | ||
198 | #define DTD_FRAME_HEIGHT_SHFT 0 | ||
199 | |||
200 | /* start_h_v */ | ||
201 | #define DTD_H_START_MASK 0xffff | ||
202 | #define DTD_H_START_SHFT 16 | ||
203 | #define DTD_V_START_MASK 0xffff | ||
204 | #define DTD_V_START_SHFT 0 | ||
205 | |||
206 | #define DTD_DESC_START_SHIFT 5 | ||
207 | #define DTD_WRITE_DESC_MASK 0x01 | ||
208 | #define DTD_WRITE_DESC_SHIFT 2 | ||
209 | #define DTD_DROP_DATA_MASK 0x01 | ||
210 | #define DTD_DROP_DATA_SHIFT 1 | ||
211 | #define DTD_USE_DESC_MASK 0x01 | ||
212 | #define DTD_USE_DESC_SHIFT 0 | ||
213 | |||
214 | /* max_width_height */ | ||
215 | #define DTD_MAX_WIDTH_MASK 0x07 | ||
216 | #define DTD_MAX_WIDTH_SHFT 4 | ||
217 | #define DTD_MAX_HEIGHT_MASK 0x07 | ||
218 | #define DTD_MAX_HEIGHT_SHFT 0 | ||
219 | |||
220 | /* max width configurations */ | ||
221 | /* unlimited width */ | ||
222 | #define MAX_OUT_WIDTH_UNLIMITED 0 | ||
223 | /* as specified in max_size1 reg */ | ||
224 | #define MAX_OUT_WIDTH_REG1 1 | ||
225 | /* as specified in max_size2 reg */ | ||
226 | #define MAX_OUT_WIDTH_REG2 2 | ||
227 | /* as specified in max_size3 reg */ | ||
228 | #define MAX_OUT_WIDTH_REG3 3 | ||
229 | /* maximum of 352 pixels as width */ | ||
230 | #define MAX_OUT_WIDTH_352 4 | ||
231 | /* maximum of 768 pixels as width */ | ||
232 | #define MAX_OUT_WIDTH_768 5 | ||
233 | /* maximum of 1280 pixels width */ | ||
234 | #define MAX_OUT_WIDTH_1280 6 | ||
235 | /* maximum of 1920 pixels as width */ | ||
236 | #define MAX_OUT_WIDTH_1920 7 | ||
237 | |||
238 | /* max height configurations */ | ||
239 | /* unlimited height */ | ||
240 | #define MAX_OUT_HEIGHT_UNLIMITED 0 | ||
241 | /* as specified in max_size1 reg */ | ||
242 | #define MAX_OUT_HEIGHT_REG1 1 | ||
243 | /* as specified in max_size2 reg */ | ||
244 | #define MAX_OUT_HEIGHT_REG2 2 | ||
245 | /* as specified in max_size3 reg */ | ||
246 | #define MAX_OUT_HEIGHT_REG3 3 | ||
247 | /* maximum of 288 lines as height */ | ||
248 | #define MAX_OUT_HEIGHT_288 4 | ||
249 | /* maximum of 576 lines as height */ | ||
250 | #define MAX_OUT_HEIGHT_576 5 | ||
251 | /* maximum of 720 lines as height */ | ||
252 | #define MAX_OUT_HEIGHT_720 6 | ||
253 | /* maximum of 1080 lines as height */ | ||
254 | #define MAX_OUT_HEIGHT_1080 7 | ||
255 | |||
256 | static inline u32 dtd_type_ctl_stride(int type, bool notify, int field, | ||
257 | bool one_d, bool even_line_skip, bool odd_line_skip, | ||
258 | int line_stride) | ||
259 | { | ||
260 | return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) | | ||
261 | (field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) | | ||
262 | (even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) | | ||
263 | (odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) | | ||
264 | line_stride; | ||
265 | } | ||
266 | |||
267 | static inline u32 dtd_xfer_length_height(int line_length, int xfer_height) | ||
268 | { | ||
269 | return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height; | ||
270 | } | ||
271 | |||
272 | static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri, | ||
273 | int next_chan) | ||
274 | { | ||
275 | return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) | | ||
276 | (dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) | | ||
277 | (pri << DTD_PRI_SHFT) | next_chan; | ||
278 | } | ||
279 | |||
280 | static inline u32 dtd_frame_width_height(int width, int height) | ||
281 | { | ||
282 | return (width << DTD_FRAME_WIDTH_SHFT) | height; | ||
283 | } | ||
284 | |||
285 | static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc, | ||
286 | bool drop_data, bool use_desc) | ||
287 | { | ||
288 | return (addr << DTD_DESC_START_SHIFT) | | ||
289 | (write_desc << DTD_WRITE_DESC_SHIFT) | | ||
290 | (drop_data << DTD_DROP_DATA_SHIFT) | | ||
291 | use_desc; | ||
292 | } | ||
293 | |||
294 | static inline u32 dtd_start_h_v(int h_start, int v_start) | ||
295 | { | ||
296 | return (h_start << DTD_H_START_SHFT) | v_start; | ||
297 | } | ||
298 | |||
299 | static inline u32 dtd_max_width_height(int max_width, int max_height) | ||
300 | { | ||
301 | return (max_width << DTD_MAX_WIDTH_SHFT) | max_height; | ||
302 | } | ||
303 | |||
304 | static inline int dtd_get_data_type(struct vpdma_dtd *dtd) | ||
305 | { | ||
306 | return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT; | ||
307 | } | ||
308 | |||
309 | static inline bool dtd_get_notify(struct vpdma_dtd *dtd) | ||
310 | { | ||
311 | return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK; | ||
312 | } | ||
313 | |||
314 | static inline int dtd_get_field(struct vpdma_dtd *dtd) | ||
315 | { | ||
316 | return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK; | ||
317 | } | ||
318 | |||
319 | static inline bool dtd_get_1d(struct vpdma_dtd *dtd) | ||
320 | { | ||
321 | return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK; | ||
322 | } | ||
323 | |||
324 | static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd) | ||
325 | { | ||
326 | return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT) | ||
327 | & DTD_EVEN_LINE_SKIP_MASK; | ||
328 | } | ||
329 | |||
330 | static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd) | ||
331 | { | ||
332 | return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT) | ||
333 | & DTD_ODD_LINE_SKIP_MASK; | ||
334 | } | ||
335 | |||
336 | static inline int dtd_get_line_stride(struct vpdma_dtd *dtd) | ||
337 | { | ||
338 | return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK; | ||
339 | } | ||
340 | |||
341 | static inline int dtd_get_line_length(struct vpdma_dtd *dtd) | ||
342 | { | ||
343 | return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT; | ||
344 | } | ||
345 | |||
346 | static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd) | ||
347 | { | ||
348 | return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK; | ||
349 | } | ||
350 | |||
351 | static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd) | ||
352 | { | ||
353 | return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT; | ||
354 | } | ||
355 | |||
356 | static inline bool dtd_get_mode(struct vpdma_dtd *dtd) | ||
357 | { | ||
358 | return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK; | ||
359 | } | ||
360 | |||
361 | static inline bool dtd_get_dir(struct vpdma_dtd *dtd) | ||
362 | { | ||
363 | return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK; | ||
364 | } | ||
365 | |||
366 | static inline int dtd_get_chan(struct vpdma_dtd *dtd) | ||
367 | { | ||
368 | return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK; | ||
369 | } | ||
370 | |||
371 | static inline int dtd_get_priority(struct vpdma_dtd *dtd) | ||
372 | { | ||
373 | return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK; | ||
374 | } | ||
375 | |||
376 | static inline int dtd_get_next_chan(struct vpdma_dtd *dtd) | ||
377 | { | ||
378 | return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK; | ||
379 | } | ||
380 | |||
381 | static inline int dtd_get_frame_width(struct vpdma_dtd *dtd) | ||
382 | { | ||
383 | return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT; | ||
384 | } | ||
385 | |||
386 | static inline int dtd_get_frame_height(struct vpdma_dtd *dtd) | ||
387 | { | ||
388 | return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK; | ||
389 | } | ||
390 | |||
391 | static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd) | ||
392 | { | ||
393 | return dtd->desc_write_addr >> DTD_DESC_START_SHIFT; | ||
394 | } | ||
395 | |||
396 | static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd) | ||
397 | { | ||
398 | return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) & | ||
399 | DTD_WRITE_DESC_MASK; | ||
400 | } | ||
401 | |||
402 | static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd) | ||
403 | { | ||
404 | return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) & | ||
405 | DTD_DROP_DATA_MASK; | ||
406 | } | ||
407 | |||
408 | static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd) | ||
409 | { | ||
410 | return dtd->desc_write_addr & DTD_USE_DESC_MASK; | ||
411 | } | ||
412 | |||
413 | static inline int dtd_get_h_start(struct vpdma_dtd *dtd) | ||
414 | { | ||
415 | return dtd->start_h_v >> DTD_H_START_SHFT; | ||
416 | } | ||
417 | |||
418 | static inline int dtd_get_v_start(struct vpdma_dtd *dtd) | ||
419 | { | ||
420 | return dtd->start_h_v & DTD_V_START_MASK; | ||
421 | } | ||
422 | |||
423 | static inline int dtd_get_max_width(struct vpdma_dtd *dtd) | ||
424 | { | ||
425 | return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) & | ||
426 | DTD_MAX_WIDTH_MASK; | ||
427 | } | ||
428 | |||
429 | static inline int dtd_get_max_height(struct vpdma_dtd *dtd) | ||
430 | { | ||
431 | return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) & | ||
432 | DTD_MAX_HEIGHT_MASK; | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * configuration descriptor | ||
437 | */ | ||
438 | struct vpdma_cfd { | ||
439 | union { | ||
440 | u32 dest_addr_offset; | ||
441 | u32 w0; | ||
442 | }; | ||
443 | union { | ||
444 | u32 block_len; /* in words */ | ||
445 | u32 w1; | ||
446 | }; | ||
447 | u32 payload_addr; | ||
448 | u32 ctl_payload_len; /* in words */ | ||
449 | }; | ||
450 | |||
451 | /* Configuration descriptor specifics */ | ||
452 | |||
453 | #define CFD_PKT_TYPE 0xb | ||
454 | |||
455 | #define CFD_DIRECT 1 | ||
456 | #define CFD_INDIRECT 0 | ||
457 | #define CFD_CLS_ADB 0 | ||
458 | #define CFD_CLS_BLOCK 1 | ||
459 | |||
460 | /* block_len */ | ||
461 | #define CFD__BLOCK_LEN_MASK 0xffff | ||
462 | #define CFD__BLOCK_LEN_SHFT 0 | ||
463 | |||
464 | /* ctl_payload_len */ | ||
465 | #define CFD_PKT_TYPE_MASK 0x1f | ||
466 | #define CFD_PKT_TYPE_SHFT 27 | ||
467 | #define CFD_DIRECT_MASK 0x01 | ||
468 | #define CFD_DIRECT_SHFT 26 | ||
469 | #define CFD_CLASS_MASK 0x03 | ||
470 | #define CFD_CLASS_SHFT 24 | ||
471 | #define CFD_DEST_MASK 0xff | ||
472 | #define CFD_DEST_SHFT 16 | ||
473 | #define CFD_PAYLOAD_LEN_MASK 0xffff | ||
474 | #define CFD_PAYLOAD_LEN_SHFT 0 | ||
475 | |||
476 | static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest, | ||
477 | int payload_len) | ||
478 | { | ||
479 | return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) | | ||
480 | (direct << CFD_DIRECT_SHFT) | | ||
481 | (cls << CFD_CLASS_SHFT) | | ||
482 | (dest << CFD_DEST_SHFT) | | ||
483 | payload_len; | ||
484 | } | ||
485 | |||
486 | static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd) | ||
487 | { | ||
488 | return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT; | ||
489 | } | ||
490 | |||
491 | static inline bool cfd_get_direct(struct vpdma_cfd *cfd) | ||
492 | { | ||
493 | return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK; | ||
494 | } | ||
495 | |||
496 | static inline bool cfd_get_class(struct vpdma_cfd *cfd) | ||
497 | { | ||
498 | return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK; | ||
499 | } | ||
500 | |||
501 | static inline int cfd_get_dest(struct vpdma_cfd *cfd) | ||
502 | { | ||
503 | return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK; | ||
504 | } | ||
505 | |||
506 | static inline int cfd_get_payload_len(struct vpdma_cfd *cfd) | ||
507 | { | ||
508 | return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * control descriptor | ||
513 | */ | ||
514 | struct vpdma_ctd { | ||
515 | union { | ||
516 | u32 timer_value; | ||
517 | u32 list_addr; | ||
518 | u32 w0; | ||
519 | }; | ||
520 | union { | ||
521 | u32 pixel_line_count; | ||
522 | u32 list_size; | ||
523 | u32 w1; | ||
524 | }; | ||
525 | union { | ||
526 | u32 event; | ||
527 | u32 fid_ctl; | ||
528 | u32 w2; | ||
529 | }; | ||
530 | u32 type_source_ctl; | ||
531 | }; | ||
532 | |||
533 | /* control descriptor types */ | ||
534 | #define CTD_TYPE_SYNC_ON_CLIENT 0 | ||
535 | #define CTD_TYPE_SYNC_ON_LIST 1 | ||
536 | #define CTD_TYPE_SYNC_ON_EXT 2 | ||
537 | #define CTD_TYPE_SYNC_ON_LM_TIMER 3 | ||
538 | #define CTD_TYPE_SYNC_ON_CHANNEL 4 | ||
539 | #define CTD_TYPE_CHNG_CLIENT_IRQ 5 | ||
540 | #define CTD_TYPE_SEND_IRQ 6 | ||
541 | #define CTD_TYPE_RELOAD_LIST 7 | ||
542 | #define CTD_TYPE_ABORT_CHANNEL 8 | ||
543 | |||
544 | #define CTD_PKT_TYPE 0xc | ||
545 | |||
546 | /* timer_value */ | ||
547 | #define CTD_TIMER_VALUE_MASK 0xffff | ||
548 | #define CTD_TIMER_VALUE_SHFT 0 | ||
549 | |||
550 | /* pixel_line_count */ | ||
551 | #define CTD_PIXEL_COUNT_MASK 0xffff | ||
552 | #define CTD_PIXEL_COUNT_SHFT 16 | ||
553 | #define CTD_LINE_COUNT_MASK 0xffff | ||
554 | #define CTD_LINE_COUNT_SHFT 0 | ||
555 | |||
556 | /* list_size */ | ||
557 | #define CTD_LIST_SIZE_MASK 0xffff | ||
558 | #define CTD_LIST_SIZE_SHFT 0 | ||
559 | |||
560 | /* event */ | ||
561 | #define CTD_EVENT_MASK 0x0f | ||
562 | #define CTD_EVENT_SHFT 0 | ||
563 | |||
564 | /* fid_ctl */ | ||
565 | #define CTD_FID2_MASK 0x03 | ||
566 | #define CTD_FID2_SHFT 4 | ||
567 | #define CTD_FID1_MASK 0x03 | ||
568 | #define CTD_FID1_SHFT 2 | ||
569 | #define CTD_FID0_MASK 0x03 | ||
570 | #define CTD_FID0_SHFT 0 | ||
571 | |||
572 | /* type_source_ctl */ | ||
573 | #define CTD_PKT_TYPE_MASK 0x1f | ||
574 | #define CTD_PKT_TYPE_SHFT 27 | ||
575 | #define CTD_SOURCE_MASK 0xff | ||
576 | #define CTD_SOURCE_SHFT 16 | ||
577 | #define CTD_CONTROL_MASK 0x0f | ||
578 | #define CTD_CONTROL_SHFT 0 | ||
579 | |||
580 | static inline u32 ctd_pixel_line_count(int pixel_count, int line_count) | ||
581 | { | ||
582 | return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count; | ||
583 | } | ||
584 | |||
585 | static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2) | ||
586 | { | ||
587 | return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0; | ||
588 | } | ||
589 | |||
590 | static inline u32 ctd_type_source_ctl(int source, int control) | ||
591 | { | ||
592 | return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) | | ||
593 | (source << CTD_SOURCE_SHFT) | control; | ||
594 | } | ||
595 | |||
596 | static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd) | ||
597 | { | ||
598 | return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT; | ||
599 | } | ||
600 | |||
601 | static inline int ctd_get_line_count(struct vpdma_ctd *ctd) | ||
602 | { | ||
603 | return ctd->pixel_line_count & CTD_LINE_COUNT_MASK; | ||
604 | } | ||
605 | |||
606 | static inline int ctd_get_event(struct vpdma_ctd *ctd) | ||
607 | { | ||
608 | return ctd->event & CTD_EVENT_MASK; | ||
609 | } | ||
610 | |||
611 | static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd) | ||
612 | { | ||
613 | return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK; | ||
614 | } | ||
615 | |||
616 | static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd) | ||
617 | { | ||
618 | return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK; | ||
619 | } | ||
620 | |||
621 | static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd) | ||
622 | { | ||
623 | return ctd->fid_ctl & CTD_FID2_MASK; | ||
624 | } | ||
625 | |||
626 | static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd) | ||
627 | { | ||
628 | return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT; | ||
629 | } | ||
630 | |||
631 | static inline int ctd_get_source(struct vpdma_ctd *ctd) | ||
632 | { | ||
633 | return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK; | ||
634 | } | ||
635 | |||
636 | static inline int ctd_get_ctl(struct vpdma_ctd *ctd) | ||
637 | { | ||
638 | return ctd->type_source_ctl & CTD_CONTROL_MASK; | ||
639 | } | ||
640 | |||
641 | #endif | ||
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c new file mode 100644 index 000000000000..4e58069e24ff --- /dev/null +++ b/drivers/media/platform/ti-vpe/vpe.c | |||
@@ -0,0 +1,2099 @@ | |||
1 | /* | ||
2 | * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver | ||
3 | * | ||
4 | * Copyright (c) 2013 Texas Instruments Inc. | ||
5 | * David Griego, <dagriego@biglakesoftware.com> | ||
6 | * Dale Farnsworth, <dale@farnsworth.org> | ||
7 | * Archit Taneja, <archit@ti.com> | ||
8 | * | ||
9 | * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. | ||
10 | * Pawel Osciak, <pawel@osciak.com> | ||
11 | * Marek Szyprowski, <m.szyprowski@samsung.com> | ||
12 | * | ||
13 | * Based on the virtual v4l2-mem2mem example device | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License version 2 as published by | ||
17 | * the Free Software Foundation | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/ioctl.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/pm_runtime.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/videodev2.h> | ||
33 | |||
34 | #include <media/v4l2-common.h> | ||
35 | #include <media/v4l2-ctrls.h> | ||
36 | #include <media/v4l2-device.h> | ||
37 | #include <media/v4l2-event.h> | ||
38 | #include <media/v4l2-ioctl.h> | ||
39 | #include <media/v4l2-mem2mem.h> | ||
40 | #include <media/videobuf2-core.h> | ||
41 | #include <media/videobuf2-dma-contig.h> | ||
42 | |||
43 | #include "vpdma.h" | ||
44 | #include "vpe_regs.h" | ||
45 | |||
46 | #define VPE_MODULE_NAME "vpe" | ||
47 | |||
48 | /* minimum and maximum frame sizes */ | ||
49 | #define MIN_W 128 | ||
50 | #define MIN_H 128 | ||
51 | #define MAX_W 1920 | ||
52 | #define MAX_H 1080 | ||
53 | |||
54 | /* required alignments */ | ||
55 | #define S_ALIGN 0 /* multiple of 1 */ | ||
56 | #define H_ALIGN 1 /* multiple of 2 */ | ||
57 | #define W_ALIGN 1 /* multiple of 2 */ | ||
58 | |||
59 | /* multiple of 128 bits, line stride, 16 bytes */ | ||
60 | #define L_ALIGN 4 | ||
61 | |||
62 | /* flags that indicate a format can be used for capture/output */ | ||
63 | #define VPE_FMT_TYPE_CAPTURE (1 << 0) | ||
64 | #define VPE_FMT_TYPE_OUTPUT (1 << 1) | ||
65 | |||
66 | /* used as plane indices */ | ||
67 | #define VPE_MAX_PLANES 2 | ||
68 | #define VPE_LUMA 0 | ||
69 | #define VPE_CHROMA 1 | ||
70 | |||
71 | /* per m2m context info */ | ||
72 | #define VPE_MAX_SRC_BUFS 3 /* need 3 src fields to de-interlace */ | ||
73 | |||
74 | #define VPE_DEF_BUFS_PER_JOB 1 /* default one buffer per batch job */ | ||
75 | |||
76 | /* | ||
77 | * each VPE context can need up to 3 config desciptors, 7 input descriptors, | ||
78 | * 3 output descriptors, and 10 control descriptors | ||
79 | */ | ||
80 | #define VPE_DESC_LIST_SIZE (10 * VPDMA_DTD_DESC_SIZE + \ | ||
81 | 13 * VPDMA_CFD_CTD_DESC_SIZE) | ||
82 | |||
83 | #define vpe_dbg(vpedev, fmt, arg...) \ | ||
84 | dev_dbg((vpedev)->v4l2_dev.dev, fmt, ##arg) | ||
85 | #define vpe_err(vpedev, fmt, arg...) \ | ||
86 | dev_err((vpedev)->v4l2_dev.dev, fmt, ##arg) | ||
87 | |||
88 | struct vpe_us_coeffs { | ||
89 | unsigned short anchor_fid0_c0; | ||
90 | unsigned short anchor_fid0_c1; | ||
91 | unsigned short anchor_fid0_c2; | ||
92 | unsigned short anchor_fid0_c3; | ||
93 | unsigned short interp_fid0_c0; | ||
94 | unsigned short interp_fid0_c1; | ||
95 | unsigned short interp_fid0_c2; | ||
96 | unsigned short interp_fid0_c3; | ||
97 | unsigned short anchor_fid1_c0; | ||
98 | unsigned short anchor_fid1_c1; | ||
99 | unsigned short anchor_fid1_c2; | ||
100 | unsigned short anchor_fid1_c3; | ||
101 | unsigned short interp_fid1_c0; | ||
102 | unsigned short interp_fid1_c1; | ||
103 | unsigned short interp_fid1_c2; | ||
104 | unsigned short interp_fid1_c3; | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Default upsampler coefficients | ||
109 | */ | ||
110 | static const struct vpe_us_coeffs us_coeffs[] = { | ||
111 | { | ||
112 | /* Coefficients for progressive input */ | ||
113 | 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8, | ||
114 | 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8, | ||
115 | }, | ||
116 | { | ||
117 | /* Coefficients for Top Field Interlaced input */ | ||
118 | 0x0051, 0x03D5, 0x3FE3, 0x3FF7, 0x3FB5, 0x02E9, 0x018F, 0x3FD3, | ||
119 | /* Coefficients for Bottom Field Interlaced input */ | ||
120 | 0x016B, 0x0247, 0x00B1, 0x3F9D, 0x3FCF, 0x03DB, 0x005D, 0x3FF9, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | /* | ||
125 | * the following registers are for configuring some of the parameters of the | ||
126 | * motion and edge detection blocks inside DEI, these generally remain the same, | ||
127 | * these could be passed later via userspace if some one needs to tweak these. | ||
128 | */ | ||
129 | struct vpe_dei_regs { | ||
130 | unsigned long mdt_spacial_freq_thr_reg; /* VPE_DEI_REG2 */ | ||
131 | unsigned long edi_config_reg; /* VPE_DEI_REG3 */ | ||
132 | unsigned long edi_lut_reg0; /* VPE_DEI_REG4 */ | ||
133 | unsigned long edi_lut_reg1; /* VPE_DEI_REG5 */ | ||
134 | unsigned long edi_lut_reg2; /* VPE_DEI_REG6 */ | ||
135 | unsigned long edi_lut_reg3; /* VPE_DEI_REG7 */ | ||
136 | }; | ||
137 | |||
138 | /* | ||
139 | * default expert DEI register values, unlikely to be modified. | ||
140 | */ | ||
141 | static const struct vpe_dei_regs dei_regs = { | ||
142 | 0x020C0804u, | ||
143 | 0x0118100Fu, | ||
144 | 0x08040200u, | ||
145 | 0x1010100Cu, | ||
146 | 0x10101010u, | ||
147 | 0x10101010u, | ||
148 | }; | ||
149 | |||
150 | /* | ||
151 | * The port_data structure contains per-port data. | ||
152 | */ | ||
153 | struct vpe_port_data { | ||
154 | enum vpdma_channel channel; /* VPDMA channel */ | ||
155 | u8 vb_index; /* input frame f, f-1, f-2 index */ | ||
156 | u8 vb_part; /* plane index for co-panar formats */ | ||
157 | }; | ||
158 | |||
159 | /* | ||
160 | * Define indices into the port_data tables | ||
161 | */ | ||
162 | #define VPE_PORT_LUMA1_IN 0 | ||
163 | #define VPE_PORT_CHROMA1_IN 1 | ||
164 | #define VPE_PORT_LUMA2_IN 2 | ||
165 | #define VPE_PORT_CHROMA2_IN 3 | ||
166 | #define VPE_PORT_LUMA3_IN 4 | ||
167 | #define VPE_PORT_CHROMA3_IN 5 | ||
168 | #define VPE_PORT_MV_IN 6 | ||
169 | #define VPE_PORT_MV_OUT 7 | ||
170 | #define VPE_PORT_LUMA_OUT 8 | ||
171 | #define VPE_PORT_CHROMA_OUT 9 | ||
172 | #define VPE_PORT_RGB_OUT 10 | ||
173 | |||
174 | static const struct vpe_port_data port_data[11] = { | ||
175 | [VPE_PORT_LUMA1_IN] = { | ||
176 | .channel = VPE_CHAN_LUMA1_IN, | ||
177 | .vb_index = 0, | ||
178 | .vb_part = VPE_LUMA, | ||
179 | }, | ||
180 | [VPE_PORT_CHROMA1_IN] = { | ||
181 | .channel = VPE_CHAN_CHROMA1_IN, | ||
182 | .vb_index = 0, | ||
183 | .vb_part = VPE_CHROMA, | ||
184 | }, | ||
185 | [VPE_PORT_LUMA2_IN] = { | ||
186 | .channel = VPE_CHAN_LUMA2_IN, | ||
187 | .vb_index = 1, | ||
188 | .vb_part = VPE_LUMA, | ||
189 | }, | ||
190 | [VPE_PORT_CHROMA2_IN] = { | ||
191 | .channel = VPE_CHAN_CHROMA2_IN, | ||
192 | .vb_index = 1, | ||
193 | .vb_part = VPE_CHROMA, | ||
194 | }, | ||
195 | [VPE_PORT_LUMA3_IN] = { | ||
196 | .channel = VPE_CHAN_LUMA3_IN, | ||
197 | .vb_index = 2, | ||
198 | .vb_part = VPE_LUMA, | ||
199 | }, | ||
200 | [VPE_PORT_CHROMA3_IN] = { | ||
201 | .channel = VPE_CHAN_CHROMA3_IN, | ||
202 | .vb_index = 2, | ||
203 | .vb_part = VPE_CHROMA, | ||
204 | }, | ||
205 | [VPE_PORT_MV_IN] = { | ||
206 | .channel = VPE_CHAN_MV_IN, | ||
207 | }, | ||
208 | [VPE_PORT_MV_OUT] = { | ||
209 | .channel = VPE_CHAN_MV_OUT, | ||
210 | }, | ||
211 | [VPE_PORT_LUMA_OUT] = { | ||
212 | .channel = VPE_CHAN_LUMA_OUT, | ||
213 | .vb_part = VPE_LUMA, | ||
214 | }, | ||
215 | [VPE_PORT_CHROMA_OUT] = { | ||
216 | .channel = VPE_CHAN_CHROMA_OUT, | ||
217 | .vb_part = VPE_CHROMA, | ||
218 | }, | ||
219 | [VPE_PORT_RGB_OUT] = { | ||
220 | .channel = VPE_CHAN_RGB_OUT, | ||
221 | .vb_part = VPE_LUMA, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | |||
226 | /* driver info for each of the supported video formats */ | ||
227 | struct vpe_fmt { | ||
228 | char *name; /* human-readable name */ | ||
229 | u32 fourcc; /* standard format identifier */ | ||
230 | u8 types; /* CAPTURE and/or OUTPUT */ | ||
231 | u8 coplanar; /* set for unpacked Luma and Chroma */ | ||
232 | /* vpdma format info for each plane */ | ||
233 | struct vpdma_data_format const *vpdma_fmt[VPE_MAX_PLANES]; | ||
234 | }; | ||
235 | |||
236 | static struct vpe_fmt vpe_formats[] = { | ||
237 | { | ||
238 | .name = "YUV 422 co-planar", | ||
239 | .fourcc = V4L2_PIX_FMT_NV16, | ||
240 | .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, | ||
241 | .coplanar = 1, | ||
242 | .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y444], | ||
243 | &vpdma_yuv_fmts[VPDMA_DATA_FMT_C444], | ||
244 | }, | ||
245 | }, | ||
246 | { | ||
247 | .name = "YUV 420 co-planar", | ||
248 | .fourcc = V4L2_PIX_FMT_NV12, | ||
249 | .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, | ||
250 | .coplanar = 1, | ||
251 | .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420], | ||
252 | &vpdma_yuv_fmts[VPDMA_DATA_FMT_C420], | ||
253 | }, | ||
254 | }, | ||
255 | { | ||
256 | .name = "YUYV 422 packed", | ||
257 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
258 | .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, | ||
259 | .coplanar = 0, | ||
260 | .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YC422], | ||
261 | }, | ||
262 | }, | ||
263 | { | ||
264 | .name = "UYVY 422 packed", | ||
265 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
266 | .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, | ||
267 | .coplanar = 0, | ||
268 | .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422], | ||
269 | }, | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | /* | ||
274 | * per-queue, driver-specific private data. | ||
275 | * there is one source queue and one destination queue for each m2m context. | ||
276 | */ | ||
277 | struct vpe_q_data { | ||
278 | unsigned int width; /* frame width */ | ||
279 | unsigned int height; /* frame height */ | ||
280 | unsigned int bytesperline[VPE_MAX_PLANES]; /* bytes per line in memory */ | ||
281 | enum v4l2_colorspace colorspace; | ||
282 | enum v4l2_field field; /* supported field value */ | ||
283 | unsigned int flags; | ||
284 | unsigned int sizeimage[VPE_MAX_PLANES]; /* image size in memory */ | ||
285 | struct v4l2_rect c_rect; /* crop/compose rectangle */ | ||
286 | struct vpe_fmt *fmt; /* format info */ | ||
287 | }; | ||
288 | |||
289 | /* vpe_q_data flag bits */ | ||
290 | #define Q_DATA_FRAME_1D (1 << 0) | ||
291 | #define Q_DATA_MODE_TILED (1 << 1) | ||
292 | #define Q_DATA_INTERLACED (1 << 2) | ||
293 | |||
294 | enum { | ||
295 | Q_DATA_SRC = 0, | ||
296 | Q_DATA_DST = 1, | ||
297 | }; | ||
298 | |||
299 | /* find our format description corresponding to the passed v4l2_format */ | ||
300 | static struct vpe_fmt *find_format(struct v4l2_format *f) | ||
301 | { | ||
302 | struct vpe_fmt *fmt; | ||
303 | unsigned int k; | ||
304 | |||
305 | for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) { | ||
306 | fmt = &vpe_formats[k]; | ||
307 | if (fmt->fourcc == f->fmt.pix.pixelformat) | ||
308 | return fmt; | ||
309 | } | ||
310 | |||
311 | return NULL; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * there is one vpe_dev structure in the driver, it is shared by | ||
316 | * all instances. | ||
317 | */ | ||
318 | struct vpe_dev { | ||
319 | struct v4l2_device v4l2_dev; | ||
320 | struct video_device vfd; | ||
321 | struct v4l2_m2m_dev *m2m_dev; | ||
322 | |||
323 | atomic_t num_instances; /* count of driver instances */ | ||
324 | dma_addr_t loaded_mmrs; /* shadow mmrs in device */ | ||
325 | struct mutex dev_mutex; | ||
326 | spinlock_t lock; | ||
327 | |||
328 | int irq; | ||
329 | void __iomem *base; | ||
330 | |||
331 | struct vb2_alloc_ctx *alloc_ctx; | ||
332 | struct vpdma_data *vpdma; /* vpdma data handle */ | ||
333 | }; | ||
334 | |||
335 | /* | ||
336 | * There is one vpe_ctx structure for each m2m context. | ||
337 | */ | ||
338 | struct vpe_ctx { | ||
339 | struct v4l2_fh fh; | ||
340 | struct vpe_dev *dev; | ||
341 | struct v4l2_m2m_ctx *m2m_ctx; | ||
342 | struct v4l2_ctrl_handler hdl; | ||
343 | |||
344 | unsigned int field; /* current field */ | ||
345 | unsigned int sequence; /* current frame/field seq */ | ||
346 | unsigned int aborting; /* abort after next irq */ | ||
347 | |||
348 | unsigned int bufs_per_job; /* input buffers per batch */ | ||
349 | unsigned int bufs_completed; /* bufs done in this batch */ | ||
350 | |||
351 | struct vpe_q_data q_data[2]; /* src & dst queue data */ | ||
352 | struct vb2_buffer *src_vbs[VPE_MAX_SRC_BUFS]; | ||
353 | struct vb2_buffer *dst_vb; | ||
354 | |||
355 | dma_addr_t mv_buf_dma[2]; /* dma addrs of motion vector in/out bufs */ | ||
356 | void *mv_buf[2]; /* virtual addrs of motion vector bufs */ | ||
357 | size_t mv_buf_size; /* current motion vector buffer size */ | ||
358 | struct vpdma_buf mmr_adb; /* shadow reg addr/data block */ | ||
359 | struct vpdma_desc_list desc_list; /* DMA descriptor list */ | ||
360 | |||
361 | bool deinterlacing; /* using de-interlacer */ | ||
362 | bool load_mmrs; /* have new shadow reg values */ | ||
363 | |||
364 | unsigned int src_mv_buf_selector; | ||
365 | }; | ||
366 | |||
367 | |||
368 | /* | ||
369 | * M2M devices get 2 queues. | ||
370 | * Return the queue given the type. | ||
371 | */ | ||
372 | static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx, | ||
373 | enum v4l2_buf_type type) | ||
374 | { | ||
375 | switch (type) { | ||
376 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | ||
377 | return &ctx->q_data[Q_DATA_SRC]; | ||
378 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | ||
379 | return &ctx->q_data[Q_DATA_DST]; | ||
380 | default: | ||
381 | BUG(); | ||
382 | } | ||
383 | return NULL; | ||
384 | } | ||
385 | |||
386 | static u32 read_reg(struct vpe_dev *dev, int offset) | ||
387 | { | ||
388 | return ioread32(dev->base + offset); | ||
389 | } | ||
390 | |||
391 | static void write_reg(struct vpe_dev *dev, int offset, u32 value) | ||
392 | { | ||
393 | iowrite32(value, dev->base + offset); | ||
394 | } | ||
395 | |||
396 | /* register field read/write helpers */ | ||
397 | static int get_field(u32 value, u32 mask, int shift) | ||
398 | { | ||
399 | return (value & (mask << shift)) >> shift; | ||
400 | } | ||
401 | |||
402 | static int read_field_reg(struct vpe_dev *dev, int offset, u32 mask, int shift) | ||
403 | { | ||
404 | return get_field(read_reg(dev, offset), mask, shift); | ||
405 | } | ||
406 | |||
407 | static void write_field(u32 *valp, u32 field, u32 mask, int shift) | ||
408 | { | ||
409 | u32 val = *valp; | ||
410 | |||
411 | val &= ~(mask << shift); | ||
412 | val |= (field & mask) << shift; | ||
413 | *valp = val; | ||
414 | } | ||
415 | |||
416 | static void write_field_reg(struct vpe_dev *dev, int offset, u32 field, | ||
417 | u32 mask, int shift) | ||
418 | { | ||
419 | u32 val = read_reg(dev, offset); | ||
420 | |||
421 | write_field(&val, field, mask, shift); | ||
422 | |||
423 | write_reg(dev, offset, val); | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * DMA address/data block for the shadow registers | ||
428 | */ | ||
429 | struct vpe_mmr_adb { | ||
430 | struct vpdma_adb_hdr out_fmt_hdr; | ||
431 | u32 out_fmt_reg[1]; | ||
432 | u32 out_fmt_pad[3]; | ||
433 | struct vpdma_adb_hdr us1_hdr; | ||
434 | u32 us1_regs[8]; | ||
435 | struct vpdma_adb_hdr us2_hdr; | ||
436 | u32 us2_regs[8]; | ||
437 | struct vpdma_adb_hdr us3_hdr; | ||
438 | u32 us3_regs[8]; | ||
439 | struct vpdma_adb_hdr dei_hdr; | ||
440 | u32 dei_regs[8]; | ||
441 | struct vpdma_adb_hdr sc_hdr; | ||
442 | u32 sc_regs[1]; | ||
443 | u32 sc_pad[3]; | ||
444 | struct vpdma_adb_hdr csc_hdr; | ||
445 | u32 csc_regs[6]; | ||
446 | u32 csc_pad[2]; | ||
447 | }; | ||
448 | |||
449 | #define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a) \ | ||
450 | VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a) | ||
451 | /* | ||
452 | * Set the headers for all of the address/data block structures. | ||
453 | */ | ||
454 | static void init_adb_hdrs(struct vpe_ctx *ctx) | ||
455 | { | ||
456 | VPE_SET_MMR_ADB_HDR(ctx, out_fmt_hdr, out_fmt_reg, VPE_CLK_FORMAT_SELECT); | ||
457 | VPE_SET_MMR_ADB_HDR(ctx, us1_hdr, us1_regs, VPE_US1_R0); | ||
458 | VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0); | ||
459 | VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0); | ||
460 | VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE); | ||
461 | VPE_SET_MMR_ADB_HDR(ctx, sc_hdr, sc_regs, VPE_SC_MP_SC0); | ||
462 | VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs, VPE_CSC_CSC00); | ||
463 | }; | ||
464 | |||
465 | /* | ||
466 | * Allocate or re-allocate the motion vector DMA buffers | ||
467 | * There are two buffers, one for input and one for output. | ||
468 | * However, the roles are reversed after each field is processed. | ||
469 | * In other words, after each field is processed, the previous | ||
470 | * output (dst) MV buffer becomes the new input (src) MV buffer. | ||
471 | */ | ||
472 | static int realloc_mv_buffers(struct vpe_ctx *ctx, size_t size) | ||
473 | { | ||
474 | struct device *dev = ctx->dev->v4l2_dev.dev; | ||
475 | |||
476 | if (ctx->mv_buf_size == size) | ||
477 | return 0; | ||
478 | |||
479 | if (ctx->mv_buf[0]) | ||
480 | dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[0], | ||
481 | ctx->mv_buf_dma[0]); | ||
482 | |||
483 | if (ctx->mv_buf[1]) | ||
484 | dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[1], | ||
485 | ctx->mv_buf_dma[1]); | ||
486 | |||
487 | if (size == 0) | ||
488 | return 0; | ||
489 | |||
490 | ctx->mv_buf[0] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[0], | ||
491 | GFP_KERNEL); | ||
492 | if (!ctx->mv_buf[0]) { | ||
493 | vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); | ||
494 | return -ENOMEM; | ||
495 | } | ||
496 | |||
497 | ctx->mv_buf[1] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[1], | ||
498 | GFP_KERNEL); | ||
499 | if (!ctx->mv_buf[1]) { | ||
500 | vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); | ||
501 | dma_free_coherent(dev, size, ctx->mv_buf[0], | ||
502 | ctx->mv_buf_dma[0]); | ||
503 | |||
504 | return -ENOMEM; | ||
505 | } | ||
506 | |||
507 | ctx->mv_buf_size = size; | ||
508 | ctx->src_mv_buf_selector = 0; | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static void free_mv_buffers(struct vpe_ctx *ctx) | ||
514 | { | ||
515 | realloc_mv_buffers(ctx, 0); | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * While de-interlacing, we keep the two most recent input buffers | ||
520 | * around. This function frees those two buffers when we have | ||
521 | * finished processing the current stream. | ||
522 | */ | ||
523 | static void free_vbs(struct vpe_ctx *ctx) | ||
524 | { | ||
525 | struct vpe_dev *dev = ctx->dev; | ||
526 | unsigned long flags; | ||
527 | |||
528 | if (ctx->src_vbs[2] == NULL) | ||
529 | return; | ||
530 | |||
531 | spin_lock_irqsave(&dev->lock, flags); | ||
532 | if (ctx->src_vbs[2]) { | ||
533 | v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE); | ||
534 | v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE); | ||
535 | } | ||
536 | spin_unlock_irqrestore(&dev->lock, flags); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Enable or disable the VPE clocks | ||
541 | */ | ||
542 | static void vpe_set_clock_enable(struct vpe_dev *dev, bool on) | ||
543 | { | ||
544 | u32 val = 0; | ||
545 | |||
546 | if (on) | ||
547 | val = VPE_DATA_PATH_CLK_ENABLE | VPE_VPEDMA_CLK_ENABLE; | ||
548 | write_reg(dev, VPE_CLK_ENABLE, val); | ||
549 | } | ||
550 | |||
551 | static void vpe_top_reset(struct vpe_dev *dev) | ||
552 | { | ||
553 | |||
554 | write_field_reg(dev, VPE_CLK_RESET, 1, VPE_DATA_PATH_CLK_RESET_MASK, | ||
555 | VPE_DATA_PATH_CLK_RESET_SHIFT); | ||
556 | |||
557 | usleep_range(100, 150); | ||
558 | |||
559 | write_field_reg(dev, VPE_CLK_RESET, 0, VPE_DATA_PATH_CLK_RESET_MASK, | ||
560 | VPE_DATA_PATH_CLK_RESET_SHIFT); | ||
561 | } | ||
562 | |||
563 | static void vpe_top_vpdma_reset(struct vpe_dev *dev) | ||
564 | { | ||
565 | write_field_reg(dev, VPE_CLK_RESET, 1, VPE_VPDMA_CLK_RESET_MASK, | ||
566 | VPE_VPDMA_CLK_RESET_SHIFT); | ||
567 | |||
568 | usleep_range(100, 150); | ||
569 | |||
570 | write_field_reg(dev, VPE_CLK_RESET, 0, VPE_VPDMA_CLK_RESET_MASK, | ||
571 | VPE_VPDMA_CLK_RESET_SHIFT); | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * Load the correct of upsampler coefficients into the shadow MMRs | ||
576 | */ | ||
577 | static void set_us_coefficients(struct vpe_ctx *ctx) | ||
578 | { | ||
579 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
580 | struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; | ||
581 | u32 *us1_reg = &mmr_adb->us1_regs[0]; | ||
582 | u32 *us2_reg = &mmr_adb->us2_regs[0]; | ||
583 | u32 *us3_reg = &mmr_adb->us3_regs[0]; | ||
584 | const unsigned short *cp, *end_cp; | ||
585 | |||
586 | cp = &us_coeffs[0].anchor_fid0_c0; | ||
587 | |||
588 | if (s_q_data->flags & Q_DATA_INTERLACED) /* interlaced */ | ||
589 | cp += sizeof(us_coeffs[0]) / sizeof(*cp); | ||
590 | |||
591 | end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp); | ||
592 | |||
593 | while (cp < end_cp) { | ||
594 | write_field(us1_reg, *cp++, VPE_US_C0_MASK, VPE_US_C0_SHIFT); | ||
595 | write_field(us1_reg, *cp++, VPE_US_C1_MASK, VPE_US_C1_SHIFT); | ||
596 | *us2_reg++ = *us1_reg; | ||
597 | *us3_reg++ = *us1_reg++; | ||
598 | } | ||
599 | ctx->load_mmrs = true; | ||
600 | } | ||
601 | |||
602 | /* | ||
603 | * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs. | ||
604 | */ | ||
605 | static void set_cfg_and_line_modes(struct vpe_ctx *ctx) | ||
606 | { | ||
607 | struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; | ||
608 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
609 | u32 *us1_reg0 = &mmr_adb->us1_regs[0]; | ||
610 | u32 *us2_reg0 = &mmr_adb->us2_regs[0]; | ||
611 | u32 *us3_reg0 = &mmr_adb->us3_regs[0]; | ||
612 | int line_mode = 1; | ||
613 | int cfg_mode = 1; | ||
614 | |||
615 | /* | ||
616 | * Cfg Mode 0: YUV420 source, enable upsampler, DEI is de-interlacing. | ||
617 | * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing. | ||
618 | */ | ||
619 | |||
620 | if (fmt->fourcc == V4L2_PIX_FMT_NV12) { | ||
621 | cfg_mode = 0; | ||
622 | line_mode = 0; /* double lines to line buffer */ | ||
623 | } | ||
624 | |||
625 | write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); | ||
626 | write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); | ||
627 | write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); | ||
628 | |||
629 | /* regs for now */ | ||
630 | vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN); | ||
631 | vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN); | ||
632 | vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA3_IN); | ||
633 | |||
634 | /* frame start for input luma */ | ||
635 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
636 | VPE_CHAN_LUMA1_IN); | ||
637 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
638 | VPE_CHAN_LUMA2_IN); | ||
639 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
640 | VPE_CHAN_LUMA3_IN); | ||
641 | |||
642 | /* frame start for input chroma */ | ||
643 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
644 | VPE_CHAN_CHROMA1_IN); | ||
645 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
646 | VPE_CHAN_CHROMA2_IN); | ||
647 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
648 | VPE_CHAN_CHROMA3_IN); | ||
649 | |||
650 | /* frame start for MV in client */ | ||
651 | vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, | ||
652 | VPE_CHAN_MV_IN); | ||
653 | |||
654 | ctx->load_mmrs = true; | ||
655 | } | ||
656 | |||
657 | /* | ||
658 | * Set the shadow registers that are modified when the source | ||
659 | * format changes. | ||
660 | */ | ||
661 | static void set_src_registers(struct vpe_ctx *ctx) | ||
662 | { | ||
663 | set_us_coefficients(ctx); | ||
664 | } | ||
665 | |||
666 | /* | ||
667 | * Set the shadow registers that are modified when the destination | ||
668 | * format changes. | ||
669 | */ | ||
670 | static void set_dst_registers(struct vpe_ctx *ctx) | ||
671 | { | ||
672 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
673 | struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; | ||
674 | u32 val = 0; | ||
675 | |||
676 | /* select RGB path when color space conversion is supported in future */ | ||
677 | if (fmt->fourcc == V4L2_PIX_FMT_RGB24) | ||
678 | val |= VPE_RGB_OUT_SELECT | VPE_CSC_SRC_DEI_SCALER; | ||
679 | else if (fmt->fourcc == V4L2_PIX_FMT_NV16) | ||
680 | val |= VPE_COLOR_SEPARATE_422; | ||
681 | |||
682 | /* The source of CHR_DS is always the scaler, whether it's used or not */ | ||
683 | val |= VPE_DS_SRC_DEI_SCALER; | ||
684 | |||
685 | if (fmt->fourcc != V4L2_PIX_FMT_NV12) | ||
686 | val |= VPE_DS_BYPASS; | ||
687 | |||
688 | mmr_adb->out_fmt_reg[0] = val; | ||
689 | |||
690 | ctx->load_mmrs = true; | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * Set the de-interlacer shadow register values | ||
695 | */ | ||
696 | static void set_dei_regs(struct vpe_ctx *ctx) | ||
697 | { | ||
698 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
699 | struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; | ||
700 | unsigned int src_h = s_q_data->c_rect.height; | ||
701 | unsigned int src_w = s_q_data->c_rect.width; | ||
702 | u32 *dei_mmr0 = &mmr_adb->dei_regs[0]; | ||
703 | bool deinterlace = true; | ||
704 | u32 val = 0; | ||
705 | |||
706 | /* | ||
707 | * according to TRM, we should set DEI in progressive bypass mode when | ||
708 | * the input content is progressive, however, DEI is bypassed correctly | ||
709 | * for both progressive and interlace content in interlace bypass mode. | ||
710 | * It has been recommended not to use progressive bypass mode. | ||
711 | */ | ||
712 | if ((!ctx->deinterlacing && (s_q_data->flags & Q_DATA_INTERLACED)) || | ||
713 | !(s_q_data->flags & Q_DATA_INTERLACED)) { | ||
714 | deinterlace = false; | ||
715 | val = VPE_DEI_INTERLACE_BYPASS; | ||
716 | } | ||
717 | |||
718 | src_h = deinterlace ? src_h * 2 : src_h; | ||
719 | |||
720 | val |= (src_h << VPE_DEI_HEIGHT_SHIFT) | | ||
721 | (src_w << VPE_DEI_WIDTH_SHIFT) | | ||
722 | VPE_DEI_FIELD_FLUSH; | ||
723 | |||
724 | *dei_mmr0 = val; | ||
725 | |||
726 | ctx->load_mmrs = true; | ||
727 | } | ||
728 | |||
729 | static void set_dei_shadow_registers(struct vpe_ctx *ctx) | ||
730 | { | ||
731 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
732 | u32 *dei_mmr = &mmr_adb->dei_regs[0]; | ||
733 | const struct vpe_dei_regs *cur = &dei_regs; | ||
734 | |||
735 | dei_mmr[2] = cur->mdt_spacial_freq_thr_reg; | ||
736 | dei_mmr[3] = cur->edi_config_reg; | ||
737 | dei_mmr[4] = cur->edi_lut_reg0; | ||
738 | dei_mmr[5] = cur->edi_lut_reg1; | ||
739 | dei_mmr[6] = cur->edi_lut_reg2; | ||
740 | dei_mmr[7] = cur->edi_lut_reg3; | ||
741 | |||
742 | ctx->load_mmrs = true; | ||
743 | } | ||
744 | |||
745 | static void set_csc_coeff_bypass(struct vpe_ctx *ctx) | ||
746 | { | ||
747 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
748 | u32 *shadow_csc_reg5 = &mmr_adb->csc_regs[5]; | ||
749 | |||
750 | *shadow_csc_reg5 |= VPE_CSC_BYPASS; | ||
751 | |||
752 | ctx->load_mmrs = true; | ||
753 | } | ||
754 | |||
755 | static void set_sc_regs_bypass(struct vpe_ctx *ctx) | ||
756 | { | ||
757 | struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; | ||
758 | u32 *sc_reg0 = &mmr_adb->sc_regs[0]; | ||
759 | u32 val = 0; | ||
760 | |||
761 | val |= VPE_SC_BYPASS; | ||
762 | *sc_reg0 = val; | ||
763 | |||
764 | ctx->load_mmrs = true; | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * Set the shadow registers whose values are modified when either the | ||
769 | * source or destination format is changed. | ||
770 | */ | ||
771 | static int set_srcdst_params(struct vpe_ctx *ctx) | ||
772 | { | ||
773 | struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; | ||
774 | struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; | ||
775 | size_t mv_buf_size; | ||
776 | int ret; | ||
777 | |||
778 | ctx->sequence = 0; | ||
779 | ctx->field = V4L2_FIELD_TOP; | ||
780 | |||
781 | if ((s_q_data->flags & Q_DATA_INTERLACED) && | ||
782 | !(d_q_data->flags & Q_DATA_INTERLACED)) { | ||
783 | const struct vpdma_data_format *mv = | ||
784 | &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; | ||
785 | |||
786 | ctx->deinterlacing = 1; | ||
787 | mv_buf_size = | ||
788 | (s_q_data->width * s_q_data->height * mv->depth) >> 3; | ||
789 | } else { | ||
790 | ctx->deinterlacing = 0; | ||
791 | mv_buf_size = 0; | ||
792 | } | ||
793 | |||
794 | free_vbs(ctx); | ||
795 | |||
796 | ret = realloc_mv_buffers(ctx, mv_buf_size); | ||
797 | if (ret) | ||
798 | return ret; | ||
799 | |||
800 | set_cfg_and_line_modes(ctx); | ||
801 | set_dei_regs(ctx); | ||
802 | set_csc_coeff_bypass(ctx); | ||
803 | set_sc_regs_bypass(ctx); | ||
804 | |||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | /* | ||
809 | * Return the vpe_ctx structure for a given struct file | ||
810 | */ | ||
811 | static struct vpe_ctx *file2ctx(struct file *file) | ||
812 | { | ||
813 | return container_of(file->private_data, struct vpe_ctx, fh); | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * mem2mem callbacks | ||
818 | */ | ||
819 | |||
820 | /** | ||
821 | * job_ready() - check whether an instance is ready to be scheduled to run | ||
822 | */ | ||
823 | static int job_ready(void *priv) | ||
824 | { | ||
825 | struct vpe_ctx *ctx = priv; | ||
826 | int needed = ctx->bufs_per_job; | ||
827 | |||
828 | if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) | ||
829 | needed += 2; /* need additional two most recent fields */ | ||
830 | |||
831 | if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < needed) | ||
832 | return 0; | ||
833 | |||
834 | return 1; | ||
835 | } | ||
836 | |||
837 | static void job_abort(void *priv) | ||
838 | { | ||
839 | struct vpe_ctx *ctx = priv; | ||
840 | |||
841 | /* Will cancel the transaction in the next interrupt handler */ | ||
842 | ctx->aborting = 1; | ||
843 | } | ||
844 | |||
845 | /* | ||
846 | * Lock access to the device | ||
847 | */ | ||
848 | static void vpe_lock(void *priv) | ||
849 | { | ||
850 | struct vpe_ctx *ctx = priv; | ||
851 | struct vpe_dev *dev = ctx->dev; | ||
852 | mutex_lock(&dev->dev_mutex); | ||
853 | } | ||
854 | |||
855 | static void vpe_unlock(void *priv) | ||
856 | { | ||
857 | struct vpe_ctx *ctx = priv; | ||
858 | struct vpe_dev *dev = ctx->dev; | ||
859 | mutex_unlock(&dev->dev_mutex); | ||
860 | } | ||
861 | |||
862 | static void vpe_dump_regs(struct vpe_dev *dev) | ||
863 | { | ||
864 | #define DUMPREG(r) vpe_dbg(dev, "%-35s %08x\n", #r, read_reg(dev, VPE_##r)) | ||
865 | |||
866 | vpe_dbg(dev, "VPE Registers:\n"); | ||
867 | |||
868 | DUMPREG(PID); | ||
869 | DUMPREG(SYSCONFIG); | ||
870 | DUMPREG(INT0_STATUS0_RAW); | ||
871 | DUMPREG(INT0_STATUS0); | ||
872 | DUMPREG(INT0_ENABLE0); | ||
873 | DUMPREG(INT0_STATUS1_RAW); | ||
874 | DUMPREG(INT0_STATUS1); | ||
875 | DUMPREG(INT0_ENABLE1); | ||
876 | DUMPREG(CLK_ENABLE); | ||
877 | DUMPREG(CLK_RESET); | ||
878 | DUMPREG(CLK_FORMAT_SELECT); | ||
879 | DUMPREG(CLK_RANGE_MAP); | ||
880 | DUMPREG(US1_R0); | ||
881 | DUMPREG(US1_R1); | ||
882 | DUMPREG(US1_R2); | ||
883 | DUMPREG(US1_R3); | ||
884 | DUMPREG(US1_R4); | ||
885 | DUMPREG(US1_R5); | ||
886 | DUMPREG(US1_R6); | ||
887 | DUMPREG(US1_R7); | ||
888 | DUMPREG(US2_R0); | ||
889 | DUMPREG(US2_R1); | ||
890 | DUMPREG(US2_R2); | ||
891 | DUMPREG(US2_R3); | ||
892 | DUMPREG(US2_R4); | ||
893 | DUMPREG(US2_R5); | ||
894 | DUMPREG(US2_R6); | ||
895 | DUMPREG(US2_R7); | ||
896 | DUMPREG(US3_R0); | ||
897 | DUMPREG(US3_R1); | ||
898 | DUMPREG(US3_R2); | ||
899 | DUMPREG(US3_R3); | ||
900 | DUMPREG(US3_R4); | ||
901 | DUMPREG(US3_R5); | ||
902 | DUMPREG(US3_R6); | ||
903 | DUMPREG(US3_R7); | ||
904 | DUMPREG(DEI_FRAME_SIZE); | ||
905 | DUMPREG(MDT_BYPASS); | ||
906 | DUMPREG(MDT_SF_THRESHOLD); | ||
907 | DUMPREG(EDI_CONFIG); | ||
908 | DUMPREG(DEI_EDI_LUT_R0); | ||
909 | DUMPREG(DEI_EDI_LUT_R1); | ||
910 | DUMPREG(DEI_EDI_LUT_R2); | ||
911 | DUMPREG(DEI_EDI_LUT_R3); | ||
912 | DUMPREG(DEI_FMD_WINDOW_R0); | ||
913 | DUMPREG(DEI_FMD_WINDOW_R1); | ||
914 | DUMPREG(DEI_FMD_CONTROL_R0); | ||
915 | DUMPREG(DEI_FMD_CONTROL_R1); | ||
916 | DUMPREG(DEI_FMD_STATUS_R0); | ||
917 | DUMPREG(DEI_FMD_STATUS_R1); | ||
918 | DUMPREG(DEI_FMD_STATUS_R2); | ||
919 | DUMPREG(SC_MP_SC0); | ||
920 | DUMPREG(SC_MP_SC1); | ||
921 | DUMPREG(SC_MP_SC2); | ||
922 | DUMPREG(SC_MP_SC3); | ||
923 | DUMPREG(SC_MP_SC4); | ||
924 | DUMPREG(SC_MP_SC5); | ||
925 | DUMPREG(SC_MP_SC6); | ||
926 | DUMPREG(SC_MP_SC8); | ||
927 | DUMPREG(SC_MP_SC9); | ||
928 | DUMPREG(SC_MP_SC10); | ||
929 | DUMPREG(SC_MP_SC11); | ||
930 | DUMPREG(SC_MP_SC12); | ||
931 | DUMPREG(SC_MP_SC13); | ||
932 | DUMPREG(SC_MP_SC17); | ||
933 | DUMPREG(SC_MP_SC18); | ||
934 | DUMPREG(SC_MP_SC19); | ||
935 | DUMPREG(SC_MP_SC20); | ||
936 | DUMPREG(SC_MP_SC21); | ||
937 | DUMPREG(SC_MP_SC22); | ||
938 | DUMPREG(SC_MP_SC23); | ||
939 | DUMPREG(SC_MP_SC24); | ||
940 | DUMPREG(SC_MP_SC25); | ||
941 | DUMPREG(CSC_CSC00); | ||
942 | DUMPREG(CSC_CSC01); | ||
943 | DUMPREG(CSC_CSC02); | ||
944 | DUMPREG(CSC_CSC03); | ||
945 | DUMPREG(CSC_CSC04); | ||
946 | DUMPREG(CSC_CSC05); | ||
947 | #undef DUMPREG | ||
948 | } | ||
949 | |||
950 | static void add_out_dtd(struct vpe_ctx *ctx, int port) | ||
951 | { | ||
952 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; | ||
953 | const struct vpe_port_data *p_data = &port_data[port]; | ||
954 | struct vb2_buffer *vb = ctx->dst_vb; | ||
955 | struct v4l2_rect *c_rect = &q_data->c_rect; | ||
956 | struct vpe_fmt *fmt = q_data->fmt; | ||
957 | const struct vpdma_data_format *vpdma_fmt; | ||
958 | int mv_buf_selector = !ctx->src_mv_buf_selector; | ||
959 | dma_addr_t dma_addr; | ||
960 | u32 flags = 0; | ||
961 | |||
962 | if (port == VPE_PORT_MV_OUT) { | ||
963 | vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; | ||
964 | dma_addr = ctx->mv_buf_dma[mv_buf_selector]; | ||
965 | } else { | ||
966 | /* to incorporate interleaved formats */ | ||
967 | int plane = fmt->coplanar ? p_data->vb_part : 0; | ||
968 | |||
969 | vpdma_fmt = fmt->vpdma_fmt[plane]; | ||
970 | dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); | ||
971 | if (!dma_addr) { | ||
972 | vpe_err(ctx->dev, | ||
973 | "acquiring output buffer(%d) dma_addr failed\n", | ||
974 | port); | ||
975 | return; | ||
976 | } | ||
977 | } | ||
978 | |||
979 | if (q_data->flags & Q_DATA_FRAME_1D) | ||
980 | flags |= VPDMA_DATA_FRAME_1D; | ||
981 | if (q_data->flags & Q_DATA_MODE_TILED) | ||
982 | flags |= VPDMA_DATA_MODE_TILED; | ||
983 | |||
984 | vpdma_add_out_dtd(&ctx->desc_list, c_rect, vpdma_fmt, dma_addr, | ||
985 | p_data->channel, flags); | ||
986 | } | ||
987 | |||
988 | static void add_in_dtd(struct vpe_ctx *ctx, int port) | ||
989 | { | ||
990 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; | ||
991 | const struct vpe_port_data *p_data = &port_data[port]; | ||
992 | struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index]; | ||
993 | struct v4l2_rect *c_rect = &q_data->c_rect; | ||
994 | struct vpe_fmt *fmt = q_data->fmt; | ||
995 | const struct vpdma_data_format *vpdma_fmt; | ||
996 | int mv_buf_selector = ctx->src_mv_buf_selector; | ||
997 | int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM; | ||
998 | dma_addr_t dma_addr; | ||
999 | u32 flags = 0; | ||
1000 | |||
1001 | if (port == VPE_PORT_MV_IN) { | ||
1002 | vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; | ||
1003 | dma_addr = ctx->mv_buf_dma[mv_buf_selector]; | ||
1004 | } else { | ||
1005 | /* to incorporate interleaved formats */ | ||
1006 | int plane = fmt->coplanar ? p_data->vb_part : 0; | ||
1007 | |||
1008 | vpdma_fmt = fmt->vpdma_fmt[plane]; | ||
1009 | |||
1010 | dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); | ||
1011 | if (!dma_addr) { | ||
1012 | vpe_err(ctx->dev, | ||
1013 | "acquiring input buffer(%d) dma_addr failed\n", | ||
1014 | port); | ||
1015 | return; | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | if (q_data->flags & Q_DATA_FRAME_1D) | ||
1020 | flags |= VPDMA_DATA_FRAME_1D; | ||
1021 | if (q_data->flags & Q_DATA_MODE_TILED) | ||
1022 | flags |= VPDMA_DATA_MODE_TILED; | ||
1023 | |||
1024 | vpdma_add_in_dtd(&ctx->desc_list, q_data->width, q_data->height, | ||
1025 | c_rect, vpdma_fmt, dma_addr, p_data->channel, field, flags); | ||
1026 | } | ||
1027 | |||
1028 | /* | ||
1029 | * Enable the expected IRQ sources | ||
1030 | */ | ||
1031 | static void enable_irqs(struct vpe_ctx *ctx) | ||
1032 | { | ||
1033 | write_reg(ctx->dev, VPE_INT0_ENABLE0_SET, VPE_INT0_LIST0_COMPLETE); | ||
1034 | write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT | | ||
1035 | VPE_DS1_UV_ERROR_INT); | ||
1036 | |||
1037 | vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, true); | ||
1038 | } | ||
1039 | |||
1040 | static void disable_irqs(struct vpe_ctx *ctx) | ||
1041 | { | ||
1042 | write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff); | ||
1043 | write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff); | ||
1044 | |||
1045 | vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, false); | ||
1046 | } | ||
1047 | |||
1048 | /* device_run() - prepares and starts the device | ||
1049 | * | ||
1050 | * This function is only called when both the source and destination | ||
1051 | * buffers are in place. | ||
1052 | */ | ||
1053 | static void device_run(void *priv) | ||
1054 | { | ||
1055 | struct vpe_ctx *ctx = priv; | ||
1056 | struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; | ||
1057 | |||
1058 | if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) { | ||
1059 | ctx->src_vbs[2] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); | ||
1060 | WARN_ON(ctx->src_vbs[2] == NULL); | ||
1061 | ctx->src_vbs[1] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); | ||
1062 | WARN_ON(ctx->src_vbs[1] == NULL); | ||
1063 | } | ||
1064 | |||
1065 | ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); | ||
1066 | WARN_ON(ctx->src_vbs[0] == NULL); | ||
1067 | ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | ||
1068 | WARN_ON(ctx->dst_vb == NULL); | ||
1069 | |||
1070 | /* config descriptors */ | ||
1071 | if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) { | ||
1072 | vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb); | ||
1073 | vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb); | ||
1074 | ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr; | ||
1075 | ctx->load_mmrs = false; | ||
1076 | } | ||
1077 | |||
1078 | /* output data descriptors */ | ||
1079 | if (ctx->deinterlacing) | ||
1080 | add_out_dtd(ctx, VPE_PORT_MV_OUT); | ||
1081 | |||
1082 | add_out_dtd(ctx, VPE_PORT_LUMA_OUT); | ||
1083 | if (d_q_data->fmt->coplanar) | ||
1084 | add_out_dtd(ctx, VPE_PORT_CHROMA_OUT); | ||
1085 | |||
1086 | /* input data descriptors */ | ||
1087 | if (ctx->deinterlacing) { | ||
1088 | add_in_dtd(ctx, VPE_PORT_LUMA3_IN); | ||
1089 | add_in_dtd(ctx, VPE_PORT_CHROMA3_IN); | ||
1090 | |||
1091 | add_in_dtd(ctx, VPE_PORT_LUMA2_IN); | ||
1092 | add_in_dtd(ctx, VPE_PORT_CHROMA2_IN); | ||
1093 | } | ||
1094 | |||
1095 | add_in_dtd(ctx, VPE_PORT_LUMA1_IN); | ||
1096 | add_in_dtd(ctx, VPE_PORT_CHROMA1_IN); | ||
1097 | |||
1098 | if (ctx->deinterlacing) | ||
1099 | add_in_dtd(ctx, VPE_PORT_MV_IN); | ||
1100 | |||
1101 | /* sync on channel control descriptors for input ports */ | ||
1102 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA1_IN); | ||
1103 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA1_IN); | ||
1104 | |||
1105 | if (ctx->deinterlacing) { | ||
1106 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, | ||
1107 | VPE_CHAN_LUMA2_IN); | ||
1108 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, | ||
1109 | VPE_CHAN_CHROMA2_IN); | ||
1110 | |||
1111 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, | ||
1112 | VPE_CHAN_LUMA3_IN); | ||
1113 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, | ||
1114 | VPE_CHAN_CHROMA3_IN); | ||
1115 | |||
1116 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_IN); | ||
1117 | } | ||
1118 | |||
1119 | /* sync on channel control descriptors for output ports */ | ||
1120 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA_OUT); | ||
1121 | if (d_q_data->fmt->coplanar) | ||
1122 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA_OUT); | ||
1123 | |||
1124 | if (ctx->deinterlacing) | ||
1125 | vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT); | ||
1126 | |||
1127 | enable_irqs(ctx); | ||
1128 | |||
1129 | vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf); | ||
1130 | vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list); | ||
1131 | } | ||
1132 | |||
1133 | static void dei_error(struct vpe_ctx *ctx) | ||
1134 | { | ||
1135 | dev_warn(ctx->dev->v4l2_dev.dev, | ||
1136 | "received DEI error interrupt\n"); | ||
1137 | } | ||
1138 | |||
1139 | static void ds1_uv_error(struct vpe_ctx *ctx) | ||
1140 | { | ||
1141 | dev_warn(ctx->dev->v4l2_dev.dev, | ||
1142 | "received downsampler error interrupt\n"); | ||
1143 | } | ||
1144 | |||
1145 | static irqreturn_t vpe_irq(int irq_vpe, void *data) | ||
1146 | { | ||
1147 | struct vpe_dev *dev = (struct vpe_dev *)data; | ||
1148 | struct vpe_ctx *ctx; | ||
1149 | struct vpe_q_data *d_q_data; | ||
1150 | struct vb2_buffer *s_vb, *d_vb; | ||
1151 | struct v4l2_buffer *s_buf, *d_buf; | ||
1152 | unsigned long flags; | ||
1153 | u32 irqst0, irqst1; | ||
1154 | |||
1155 | irqst0 = read_reg(dev, VPE_INT0_STATUS0); | ||
1156 | if (irqst0) { | ||
1157 | write_reg(dev, VPE_INT0_STATUS0_CLR, irqst0); | ||
1158 | vpe_dbg(dev, "INT0_STATUS0 = 0x%08x\n", irqst0); | ||
1159 | } | ||
1160 | |||
1161 | irqst1 = read_reg(dev, VPE_INT0_STATUS1); | ||
1162 | if (irqst1) { | ||
1163 | write_reg(dev, VPE_INT0_STATUS1_CLR, irqst1); | ||
1164 | vpe_dbg(dev, "INT0_STATUS1 = 0x%08x\n", irqst1); | ||
1165 | } | ||
1166 | |||
1167 | ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); | ||
1168 | if (!ctx) { | ||
1169 | vpe_err(dev, "instance released before end of transaction\n"); | ||
1170 | goto handled; | ||
1171 | } | ||
1172 | |||
1173 | if (irqst1) { | ||
1174 | if (irqst1 & VPE_DEI_ERROR_INT) { | ||
1175 | irqst1 &= ~VPE_DEI_ERROR_INT; | ||
1176 | dei_error(ctx); | ||
1177 | } | ||
1178 | if (irqst1 & VPE_DS1_UV_ERROR_INT) { | ||
1179 | irqst1 &= ~VPE_DS1_UV_ERROR_INT; | ||
1180 | ds1_uv_error(ctx); | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1184 | if (irqst0) { | ||
1185 | if (irqst0 & VPE_INT0_LIST0_COMPLETE) | ||
1186 | vpdma_clear_list_stat(ctx->dev->vpdma); | ||
1187 | |||
1188 | irqst0 &= ~(VPE_INT0_LIST0_COMPLETE); | ||
1189 | } | ||
1190 | |||
1191 | if (irqst0 | irqst1) { | ||
1192 | dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: " | ||
1193 | "INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n", | ||
1194 | irqst0, irqst1); | ||
1195 | } | ||
1196 | |||
1197 | disable_irqs(ctx); | ||
1198 | |||
1199 | vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); | ||
1200 | vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); | ||
1201 | |||
1202 | vpdma_reset_desc_list(&ctx->desc_list); | ||
1203 | |||
1204 | /* the previous dst mv buffer becomes the next src mv buffer */ | ||
1205 | ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector; | ||
1206 | |||
1207 | if (ctx->aborting) | ||
1208 | goto finished; | ||
1209 | |||
1210 | s_vb = ctx->src_vbs[0]; | ||
1211 | d_vb = ctx->dst_vb; | ||
1212 | s_buf = &s_vb->v4l2_buf; | ||
1213 | d_buf = &d_vb->v4l2_buf; | ||
1214 | |||
1215 | d_buf->timestamp = s_buf->timestamp; | ||
1216 | if (s_buf->flags & V4L2_BUF_FLAG_TIMECODE) { | ||
1217 | d_buf->flags |= V4L2_BUF_FLAG_TIMECODE; | ||
1218 | d_buf->timecode = s_buf->timecode; | ||
1219 | } | ||
1220 | d_buf->sequence = ctx->sequence; | ||
1221 | d_buf->field = ctx->field; | ||
1222 | |||
1223 | d_q_data = &ctx->q_data[Q_DATA_DST]; | ||
1224 | if (d_q_data->flags & Q_DATA_INTERLACED) { | ||
1225 | if (ctx->field == V4L2_FIELD_BOTTOM) { | ||
1226 | ctx->sequence++; | ||
1227 | ctx->field = V4L2_FIELD_TOP; | ||
1228 | } else { | ||
1229 | WARN_ON(ctx->field != V4L2_FIELD_TOP); | ||
1230 | ctx->field = V4L2_FIELD_BOTTOM; | ||
1231 | } | ||
1232 | } else { | ||
1233 | ctx->sequence++; | ||
1234 | } | ||
1235 | |||
1236 | if (ctx->deinterlacing) | ||
1237 | s_vb = ctx->src_vbs[2]; | ||
1238 | |||
1239 | spin_lock_irqsave(&dev->lock, flags); | ||
1240 | v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE); | ||
1241 | v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE); | ||
1242 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1243 | |||
1244 | if (ctx->deinterlacing) { | ||
1245 | ctx->src_vbs[2] = ctx->src_vbs[1]; | ||
1246 | ctx->src_vbs[1] = ctx->src_vbs[0]; | ||
1247 | } | ||
1248 | |||
1249 | ctx->bufs_completed++; | ||
1250 | if (ctx->bufs_completed < ctx->bufs_per_job) { | ||
1251 | device_run(ctx); | ||
1252 | goto handled; | ||
1253 | } | ||
1254 | |||
1255 | finished: | ||
1256 | vpe_dbg(ctx->dev, "finishing transaction\n"); | ||
1257 | ctx->bufs_completed = 0; | ||
1258 | v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); | ||
1259 | handled: | ||
1260 | return IRQ_HANDLED; | ||
1261 | } | ||
1262 | |||
1263 | /* | ||
1264 | * video ioctls | ||
1265 | */ | ||
1266 | static int vpe_querycap(struct file *file, void *priv, | ||
1267 | struct v4l2_capability *cap) | ||
1268 | { | ||
1269 | strncpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver) - 1); | ||
1270 | strncpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card) - 1); | ||
1271 | strlcpy(cap->bus_info, VPE_MODULE_NAME, sizeof(cap->bus_info)); | ||
1272 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | ||
1273 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1274 | return 0; | ||
1275 | } | ||
1276 | |||
1277 | static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type) | ||
1278 | { | ||
1279 | int i, index; | ||
1280 | struct vpe_fmt *fmt = NULL; | ||
1281 | |||
1282 | index = 0; | ||
1283 | for (i = 0; i < ARRAY_SIZE(vpe_formats); ++i) { | ||
1284 | if (vpe_formats[i].types & type) { | ||
1285 | if (index == f->index) { | ||
1286 | fmt = &vpe_formats[i]; | ||
1287 | break; | ||
1288 | } | ||
1289 | index++; | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | if (!fmt) | ||
1294 | return -EINVAL; | ||
1295 | |||
1296 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | ||
1297 | f->pixelformat = fmt->fourcc; | ||
1298 | return 0; | ||
1299 | } | ||
1300 | |||
1301 | static int vpe_enum_fmt(struct file *file, void *priv, | ||
1302 | struct v4l2_fmtdesc *f) | ||
1303 | { | ||
1304 | if (V4L2_TYPE_IS_OUTPUT(f->type)) | ||
1305 | return __enum_fmt(f, VPE_FMT_TYPE_OUTPUT); | ||
1306 | |||
1307 | return __enum_fmt(f, VPE_FMT_TYPE_CAPTURE); | ||
1308 | } | ||
1309 | |||
1310 | static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | ||
1311 | { | ||
1312 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; | ||
1313 | struct vpe_ctx *ctx = file2ctx(file); | ||
1314 | struct vb2_queue *vq; | ||
1315 | struct vpe_q_data *q_data; | ||
1316 | int i; | ||
1317 | |||
1318 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | ||
1319 | if (!vq) | ||
1320 | return -EINVAL; | ||
1321 | |||
1322 | q_data = get_q_data(ctx, f->type); | ||
1323 | |||
1324 | pix->width = q_data->width; | ||
1325 | pix->height = q_data->height; | ||
1326 | pix->pixelformat = q_data->fmt->fourcc; | ||
1327 | pix->field = q_data->field; | ||
1328 | |||
1329 | if (V4L2_TYPE_IS_OUTPUT(f->type)) { | ||
1330 | pix->colorspace = q_data->colorspace; | ||
1331 | } else { | ||
1332 | struct vpe_q_data *s_q_data; | ||
1333 | |||
1334 | /* get colorspace from the source queue */ | ||
1335 | s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); | ||
1336 | |||
1337 | pix->colorspace = s_q_data->colorspace; | ||
1338 | } | ||
1339 | |||
1340 | pix->num_planes = q_data->fmt->coplanar ? 2 : 1; | ||
1341 | |||
1342 | for (i = 0; i < pix->num_planes; i++) { | ||
1343 | pix->plane_fmt[i].bytesperline = q_data->bytesperline[i]; | ||
1344 | pix->plane_fmt[i].sizeimage = q_data->sizeimage[i]; | ||
1345 | } | ||
1346 | |||
1347 | return 0; | ||
1348 | } | ||
1349 | |||
1350 | static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, | ||
1351 | struct vpe_fmt *fmt, int type) | ||
1352 | { | ||
1353 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; | ||
1354 | struct v4l2_plane_pix_format *plane_fmt; | ||
1355 | int i; | ||
1356 | |||
1357 | if (!fmt || !(fmt->types & type)) { | ||
1358 | vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", | ||
1359 | pix->pixelformat); | ||
1360 | return -EINVAL; | ||
1361 | } | ||
1362 | |||
1363 | if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE) | ||
1364 | pix->field = V4L2_FIELD_NONE; | ||
1365 | |||
1366 | v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN, | ||
1367 | &pix->height, MIN_H, MAX_H, H_ALIGN, | ||
1368 | S_ALIGN); | ||
1369 | |||
1370 | pix->num_planes = fmt->coplanar ? 2 : 1; | ||
1371 | pix->pixelformat = fmt->fourcc; | ||
1372 | |||
1373 | if (type == VPE_FMT_TYPE_CAPTURE) { | ||
1374 | struct vpe_q_data *s_q_data; | ||
1375 | |||
1376 | /* get colorspace from the source queue */ | ||
1377 | s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); | ||
1378 | |||
1379 | pix->colorspace = s_q_data->colorspace; | ||
1380 | } else { | ||
1381 | if (!pix->colorspace) | ||
1382 | pix->colorspace = V4L2_COLORSPACE_SMPTE240M; | ||
1383 | } | ||
1384 | |||
1385 | for (i = 0; i < pix->num_planes; i++) { | ||
1386 | int depth; | ||
1387 | |||
1388 | plane_fmt = &pix->plane_fmt[i]; | ||
1389 | depth = fmt->vpdma_fmt[i]->depth; | ||
1390 | |||
1391 | if (i == VPE_LUMA) | ||
1392 | plane_fmt->bytesperline = | ||
1393 | round_up((pix->width * depth) >> 3, | ||
1394 | 1 << L_ALIGN); | ||
1395 | else | ||
1396 | plane_fmt->bytesperline = pix->width; | ||
1397 | |||
1398 | plane_fmt->sizeimage = | ||
1399 | (pix->height * pix->width * depth) >> 3; | ||
1400 | } | ||
1401 | |||
1402 | return 0; | ||
1403 | } | ||
1404 | |||
1405 | static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | ||
1406 | { | ||
1407 | struct vpe_ctx *ctx = file2ctx(file); | ||
1408 | struct vpe_fmt *fmt = find_format(f); | ||
1409 | |||
1410 | if (V4L2_TYPE_IS_OUTPUT(f->type)) | ||
1411 | return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_OUTPUT); | ||
1412 | else | ||
1413 | return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_CAPTURE); | ||
1414 | } | ||
1415 | |||
1416 | static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f) | ||
1417 | { | ||
1418 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; | ||
1419 | struct v4l2_plane_pix_format *plane_fmt; | ||
1420 | struct vpe_q_data *q_data; | ||
1421 | struct vb2_queue *vq; | ||
1422 | int i; | ||
1423 | |||
1424 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | ||
1425 | if (!vq) | ||
1426 | return -EINVAL; | ||
1427 | |||
1428 | if (vb2_is_busy(vq)) { | ||
1429 | vpe_err(ctx->dev, "queue busy\n"); | ||
1430 | return -EBUSY; | ||
1431 | } | ||
1432 | |||
1433 | q_data = get_q_data(ctx, f->type); | ||
1434 | if (!q_data) | ||
1435 | return -EINVAL; | ||
1436 | |||
1437 | q_data->fmt = find_format(f); | ||
1438 | q_data->width = pix->width; | ||
1439 | q_data->height = pix->height; | ||
1440 | q_data->colorspace = pix->colorspace; | ||
1441 | q_data->field = pix->field; | ||
1442 | |||
1443 | for (i = 0; i < pix->num_planes; i++) { | ||
1444 | plane_fmt = &pix->plane_fmt[i]; | ||
1445 | |||
1446 | q_data->bytesperline[i] = plane_fmt->bytesperline; | ||
1447 | q_data->sizeimage[i] = plane_fmt->sizeimage; | ||
1448 | } | ||
1449 | |||
1450 | q_data->c_rect.left = 0; | ||
1451 | q_data->c_rect.top = 0; | ||
1452 | q_data->c_rect.width = q_data->width; | ||
1453 | q_data->c_rect.height = q_data->height; | ||
1454 | |||
1455 | if (q_data->field == V4L2_FIELD_ALTERNATE) | ||
1456 | q_data->flags |= Q_DATA_INTERLACED; | ||
1457 | else | ||
1458 | q_data->flags &= ~Q_DATA_INTERLACED; | ||
1459 | |||
1460 | vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d", | ||
1461 | f->type, q_data->width, q_data->height, q_data->fmt->fourcc, | ||
1462 | q_data->bytesperline[VPE_LUMA]); | ||
1463 | if (q_data->fmt->coplanar) | ||
1464 | vpe_dbg(ctx->dev, " bpl_uv %d\n", | ||
1465 | q_data->bytesperline[VPE_CHROMA]); | ||
1466 | |||
1467 | return 0; | ||
1468 | } | ||
1469 | |||
1470 | static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | ||
1471 | { | ||
1472 | int ret; | ||
1473 | struct vpe_ctx *ctx = file2ctx(file); | ||
1474 | |||
1475 | ret = vpe_try_fmt(file, priv, f); | ||
1476 | if (ret) | ||
1477 | return ret; | ||
1478 | |||
1479 | ret = __vpe_s_fmt(ctx, f); | ||
1480 | if (ret) | ||
1481 | return ret; | ||
1482 | |||
1483 | if (V4L2_TYPE_IS_OUTPUT(f->type)) | ||
1484 | set_src_registers(ctx); | ||
1485 | else | ||
1486 | set_dst_registers(ctx); | ||
1487 | |||
1488 | return set_srcdst_params(ctx); | ||
1489 | } | ||
1490 | |||
1491 | static int vpe_reqbufs(struct file *file, void *priv, | ||
1492 | struct v4l2_requestbuffers *reqbufs) | ||
1493 | { | ||
1494 | struct vpe_ctx *ctx = file2ctx(file); | ||
1495 | |||
1496 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | ||
1497 | } | ||
1498 | |||
1499 | static int vpe_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
1500 | { | ||
1501 | struct vpe_ctx *ctx = file2ctx(file); | ||
1502 | |||
1503 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | ||
1504 | } | ||
1505 | |||
1506 | static int vpe_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
1507 | { | ||
1508 | struct vpe_ctx *ctx = file2ctx(file); | ||
1509 | |||
1510 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | ||
1511 | } | ||
1512 | |||
1513 | static int vpe_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
1514 | { | ||
1515 | struct vpe_ctx *ctx = file2ctx(file); | ||
1516 | |||
1517 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); | ||
1518 | } | ||
1519 | |||
1520 | static int vpe_streamon(struct file *file, void *priv, enum v4l2_buf_type type) | ||
1521 | { | ||
1522 | struct vpe_ctx *ctx = file2ctx(file); | ||
1523 | |||
1524 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | ||
1525 | } | ||
1526 | |||
1527 | static int vpe_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) | ||
1528 | { | ||
1529 | struct vpe_ctx *ctx = file2ctx(file); | ||
1530 | |||
1531 | vpe_dump_regs(ctx->dev); | ||
1532 | vpdma_dump_regs(ctx->dev->vpdma); | ||
1533 | |||
1534 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); | ||
1535 | } | ||
1536 | |||
1537 | /* | ||
1538 | * defines number of buffers/frames a context can process with VPE before | ||
1539 | * switching to a different context. default value is 1 buffer per context | ||
1540 | */ | ||
1541 | #define V4L2_CID_VPE_BUFS_PER_JOB (V4L2_CID_USER_TI_VPE_BASE + 0) | ||
1542 | |||
1543 | static int vpe_s_ctrl(struct v4l2_ctrl *ctrl) | ||
1544 | { | ||
1545 | struct vpe_ctx *ctx = | ||
1546 | container_of(ctrl->handler, struct vpe_ctx, hdl); | ||
1547 | |||
1548 | switch (ctrl->id) { | ||
1549 | case V4L2_CID_VPE_BUFS_PER_JOB: | ||
1550 | ctx->bufs_per_job = ctrl->val; | ||
1551 | break; | ||
1552 | |||
1553 | default: | ||
1554 | vpe_err(ctx->dev, "Invalid control\n"); | ||
1555 | return -EINVAL; | ||
1556 | } | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | static const struct v4l2_ctrl_ops vpe_ctrl_ops = { | ||
1562 | .s_ctrl = vpe_s_ctrl, | ||
1563 | }; | ||
1564 | |||
1565 | static const struct v4l2_ioctl_ops vpe_ioctl_ops = { | ||
1566 | .vidioc_querycap = vpe_querycap, | ||
1567 | |||
1568 | .vidioc_enum_fmt_vid_cap_mplane = vpe_enum_fmt, | ||
1569 | .vidioc_g_fmt_vid_cap_mplane = vpe_g_fmt, | ||
1570 | .vidioc_try_fmt_vid_cap_mplane = vpe_try_fmt, | ||
1571 | .vidioc_s_fmt_vid_cap_mplane = vpe_s_fmt, | ||
1572 | |||
1573 | .vidioc_enum_fmt_vid_out_mplane = vpe_enum_fmt, | ||
1574 | .vidioc_g_fmt_vid_out_mplane = vpe_g_fmt, | ||
1575 | .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt, | ||
1576 | .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt, | ||
1577 | |||
1578 | .vidioc_reqbufs = vpe_reqbufs, | ||
1579 | .vidioc_querybuf = vpe_querybuf, | ||
1580 | |||
1581 | .vidioc_qbuf = vpe_qbuf, | ||
1582 | .vidioc_dqbuf = vpe_dqbuf, | ||
1583 | |||
1584 | .vidioc_streamon = vpe_streamon, | ||
1585 | .vidioc_streamoff = vpe_streamoff, | ||
1586 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1587 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1588 | }; | ||
1589 | |||
1590 | /* | ||
1591 | * Queue operations | ||
1592 | */ | ||
1593 | static int vpe_queue_setup(struct vb2_queue *vq, | ||
1594 | const struct v4l2_format *fmt, | ||
1595 | unsigned int *nbuffers, unsigned int *nplanes, | ||
1596 | unsigned int sizes[], void *alloc_ctxs[]) | ||
1597 | { | ||
1598 | int i; | ||
1599 | struct vpe_ctx *ctx = vb2_get_drv_priv(vq); | ||
1600 | struct vpe_q_data *q_data; | ||
1601 | |||
1602 | q_data = get_q_data(ctx, vq->type); | ||
1603 | |||
1604 | *nplanes = q_data->fmt->coplanar ? 2 : 1; | ||
1605 | |||
1606 | for (i = 0; i < *nplanes; i++) { | ||
1607 | sizes[i] = q_data->sizeimage[i]; | ||
1608 | alloc_ctxs[i] = ctx->dev->alloc_ctx; | ||
1609 | } | ||
1610 | |||
1611 | vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers, | ||
1612 | sizes[VPE_LUMA]); | ||
1613 | if (q_data->fmt->coplanar) | ||
1614 | vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]); | ||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static int vpe_buf_prepare(struct vb2_buffer *vb) | ||
1620 | { | ||
1621 | struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
1622 | struct vpe_q_data *q_data; | ||
1623 | int i, num_planes; | ||
1624 | |||
1625 | vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type); | ||
1626 | |||
1627 | q_data = get_q_data(ctx, vb->vb2_queue->type); | ||
1628 | num_planes = q_data->fmt->coplanar ? 2 : 1; | ||
1629 | |||
1630 | for (i = 0; i < num_planes; i++) { | ||
1631 | if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { | ||
1632 | vpe_err(ctx->dev, | ||
1633 | "data will not fit into plane (%lu < %lu)\n", | ||
1634 | vb2_plane_size(vb, i), | ||
1635 | (long) q_data->sizeimage[i]); | ||
1636 | return -EINVAL; | ||
1637 | } | ||
1638 | } | ||
1639 | |||
1640 | for (i = 0; i < num_planes; i++) | ||
1641 | vb2_set_plane_payload(vb, i, q_data->sizeimage[i]); | ||
1642 | |||
1643 | return 0; | ||
1644 | } | ||
1645 | |||
1646 | static void vpe_buf_queue(struct vb2_buffer *vb) | ||
1647 | { | ||
1648 | struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
1649 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); | ||
1650 | } | ||
1651 | |||
1652 | static void vpe_wait_prepare(struct vb2_queue *q) | ||
1653 | { | ||
1654 | struct vpe_ctx *ctx = vb2_get_drv_priv(q); | ||
1655 | vpe_unlock(ctx); | ||
1656 | } | ||
1657 | |||
1658 | static void vpe_wait_finish(struct vb2_queue *q) | ||
1659 | { | ||
1660 | struct vpe_ctx *ctx = vb2_get_drv_priv(q); | ||
1661 | vpe_lock(ctx); | ||
1662 | } | ||
1663 | |||
1664 | static struct vb2_ops vpe_qops = { | ||
1665 | .queue_setup = vpe_queue_setup, | ||
1666 | .buf_prepare = vpe_buf_prepare, | ||
1667 | .buf_queue = vpe_buf_queue, | ||
1668 | .wait_prepare = vpe_wait_prepare, | ||
1669 | .wait_finish = vpe_wait_finish, | ||
1670 | }; | ||
1671 | |||
1672 | static int queue_init(void *priv, struct vb2_queue *src_vq, | ||
1673 | struct vb2_queue *dst_vq) | ||
1674 | { | ||
1675 | struct vpe_ctx *ctx = priv; | ||
1676 | int ret; | ||
1677 | |||
1678 | memset(src_vq, 0, sizeof(*src_vq)); | ||
1679 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | ||
1680 | src_vq->io_modes = VB2_MMAP; | ||
1681 | src_vq->drv_priv = ctx; | ||
1682 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
1683 | src_vq->ops = &vpe_qops; | ||
1684 | src_vq->mem_ops = &vb2_dma_contig_memops; | ||
1685 | src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; | ||
1686 | |||
1687 | ret = vb2_queue_init(src_vq); | ||
1688 | if (ret) | ||
1689 | return ret; | ||
1690 | |||
1691 | memset(dst_vq, 0, sizeof(*dst_vq)); | ||
1692 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||
1693 | dst_vq->io_modes = VB2_MMAP; | ||
1694 | dst_vq->drv_priv = ctx; | ||
1695 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
1696 | dst_vq->ops = &vpe_qops; | ||
1697 | dst_vq->mem_ops = &vb2_dma_contig_memops; | ||
1698 | dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; | ||
1699 | |||
1700 | return vb2_queue_init(dst_vq); | ||
1701 | } | ||
1702 | |||
1703 | static const struct v4l2_ctrl_config vpe_bufs_per_job = { | ||
1704 | .ops = &vpe_ctrl_ops, | ||
1705 | .id = V4L2_CID_VPE_BUFS_PER_JOB, | ||
1706 | .name = "Buffers Per Transaction", | ||
1707 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1708 | .def = VPE_DEF_BUFS_PER_JOB, | ||
1709 | .min = 1, | ||
1710 | .max = VIDEO_MAX_FRAME, | ||
1711 | .step = 1, | ||
1712 | }; | ||
1713 | |||
1714 | /* | ||
1715 | * File operations | ||
1716 | */ | ||
1717 | static int vpe_open(struct file *file) | ||
1718 | { | ||
1719 | struct vpe_dev *dev = video_drvdata(file); | ||
1720 | struct vpe_ctx *ctx = NULL; | ||
1721 | struct vpe_q_data *s_q_data; | ||
1722 | struct v4l2_ctrl_handler *hdl; | ||
1723 | int ret; | ||
1724 | |||
1725 | vpe_dbg(dev, "vpe_open\n"); | ||
1726 | |||
1727 | if (!dev->vpdma->ready) { | ||
1728 | vpe_err(dev, "vpdma firmware not loaded\n"); | ||
1729 | return -ENODEV; | ||
1730 | } | ||
1731 | |||
1732 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
1733 | if (!ctx) | ||
1734 | return -ENOMEM; | ||
1735 | |||
1736 | ctx->dev = dev; | ||
1737 | |||
1738 | if (mutex_lock_interruptible(&dev->dev_mutex)) { | ||
1739 | ret = -ERESTARTSYS; | ||
1740 | goto free_ctx; | ||
1741 | } | ||
1742 | |||
1743 | ret = vpdma_create_desc_list(&ctx->desc_list, VPE_DESC_LIST_SIZE, | ||
1744 | VPDMA_LIST_TYPE_NORMAL); | ||
1745 | if (ret != 0) | ||
1746 | goto unlock; | ||
1747 | |||
1748 | ret = vpdma_alloc_desc_buf(&ctx->mmr_adb, sizeof(struct vpe_mmr_adb)); | ||
1749 | if (ret != 0) | ||
1750 | goto free_desc_list; | ||
1751 | |||
1752 | init_adb_hdrs(ctx); | ||
1753 | |||
1754 | v4l2_fh_init(&ctx->fh, video_devdata(file)); | ||
1755 | file->private_data = &ctx->fh; | ||
1756 | |||
1757 | hdl = &ctx->hdl; | ||
1758 | v4l2_ctrl_handler_init(hdl, 1); | ||
1759 | v4l2_ctrl_new_custom(hdl, &vpe_bufs_per_job, NULL); | ||
1760 | if (hdl->error) { | ||
1761 | ret = hdl->error; | ||
1762 | goto exit_fh; | ||
1763 | } | ||
1764 | ctx->fh.ctrl_handler = hdl; | ||
1765 | v4l2_ctrl_handler_setup(hdl); | ||
1766 | |||
1767 | s_q_data = &ctx->q_data[Q_DATA_SRC]; | ||
1768 | s_q_data->fmt = &vpe_formats[2]; | ||
1769 | s_q_data->width = 1920; | ||
1770 | s_q_data->height = 1080; | ||
1771 | s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height * | ||
1772 | s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; | ||
1773 | s_q_data->colorspace = V4L2_COLORSPACE_SMPTE240M; | ||
1774 | s_q_data->field = V4L2_FIELD_NONE; | ||
1775 | s_q_data->c_rect.left = 0; | ||
1776 | s_q_data->c_rect.top = 0; | ||
1777 | s_q_data->c_rect.width = s_q_data->width; | ||
1778 | s_q_data->c_rect.height = s_q_data->height; | ||
1779 | s_q_data->flags = 0; | ||
1780 | |||
1781 | ctx->q_data[Q_DATA_DST] = *s_q_data; | ||
1782 | |||
1783 | set_dei_shadow_registers(ctx); | ||
1784 | set_src_registers(ctx); | ||
1785 | set_dst_registers(ctx); | ||
1786 | ret = set_srcdst_params(ctx); | ||
1787 | if (ret) | ||
1788 | goto exit_fh; | ||
1789 | |||
1790 | ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); | ||
1791 | |||
1792 | if (IS_ERR(ctx->m2m_ctx)) { | ||
1793 | ret = PTR_ERR(ctx->m2m_ctx); | ||
1794 | goto exit_fh; | ||
1795 | } | ||
1796 | |||
1797 | v4l2_fh_add(&ctx->fh); | ||
1798 | |||
1799 | /* | ||
1800 | * for now, just report the creation of the first instance, we can later | ||
1801 | * optimize the driver to enable or disable clocks when the first | ||
1802 | * instance is created or the last instance released | ||
1803 | */ | ||
1804 | if (atomic_inc_return(&dev->num_instances) == 1) | ||
1805 | vpe_dbg(dev, "first instance created\n"); | ||
1806 | |||
1807 | ctx->bufs_per_job = VPE_DEF_BUFS_PER_JOB; | ||
1808 | |||
1809 | ctx->load_mmrs = true; | ||
1810 | |||
1811 | vpe_dbg(dev, "created instance %p, m2m_ctx: %p\n", | ||
1812 | ctx, ctx->m2m_ctx); | ||
1813 | |||
1814 | mutex_unlock(&dev->dev_mutex); | ||
1815 | |||
1816 | return 0; | ||
1817 | exit_fh: | ||
1818 | v4l2_ctrl_handler_free(hdl); | ||
1819 | v4l2_fh_exit(&ctx->fh); | ||
1820 | vpdma_free_desc_buf(&ctx->mmr_adb); | ||
1821 | free_desc_list: | ||
1822 | vpdma_free_desc_list(&ctx->desc_list); | ||
1823 | unlock: | ||
1824 | mutex_unlock(&dev->dev_mutex); | ||
1825 | free_ctx: | ||
1826 | kfree(ctx); | ||
1827 | return ret; | ||
1828 | } | ||
1829 | |||
1830 | static int vpe_release(struct file *file) | ||
1831 | { | ||
1832 | struct vpe_dev *dev = video_drvdata(file); | ||
1833 | struct vpe_ctx *ctx = file2ctx(file); | ||
1834 | |||
1835 | vpe_dbg(dev, "releasing instance %p\n", ctx); | ||
1836 | |||
1837 | mutex_lock(&dev->dev_mutex); | ||
1838 | free_vbs(ctx); | ||
1839 | free_mv_buffers(ctx); | ||
1840 | vpdma_free_desc_list(&ctx->desc_list); | ||
1841 | vpdma_free_desc_buf(&ctx->mmr_adb); | ||
1842 | |||
1843 | v4l2_fh_del(&ctx->fh); | ||
1844 | v4l2_fh_exit(&ctx->fh); | ||
1845 | v4l2_ctrl_handler_free(&ctx->hdl); | ||
1846 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | ||
1847 | |||
1848 | kfree(ctx); | ||
1849 | |||
1850 | /* | ||
1851 | * for now, just report the release of the last instance, we can later | ||
1852 | * optimize the driver to enable or disable clocks when the first | ||
1853 | * instance is created or the last instance released | ||
1854 | */ | ||
1855 | if (atomic_dec_return(&dev->num_instances) == 0) | ||
1856 | vpe_dbg(dev, "last instance released\n"); | ||
1857 | |||
1858 | mutex_unlock(&dev->dev_mutex); | ||
1859 | |||
1860 | return 0; | ||
1861 | } | ||
1862 | |||
1863 | static unsigned int vpe_poll(struct file *file, | ||
1864 | struct poll_table_struct *wait) | ||
1865 | { | ||
1866 | struct vpe_ctx *ctx = file2ctx(file); | ||
1867 | struct vpe_dev *dev = ctx->dev; | ||
1868 | int ret; | ||
1869 | |||
1870 | mutex_lock(&dev->dev_mutex); | ||
1871 | ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait); | ||
1872 | mutex_unlock(&dev->dev_mutex); | ||
1873 | return ret; | ||
1874 | } | ||
1875 | |||
1876 | static int vpe_mmap(struct file *file, struct vm_area_struct *vma) | ||
1877 | { | ||
1878 | struct vpe_ctx *ctx = file2ctx(file); | ||
1879 | struct vpe_dev *dev = ctx->dev; | ||
1880 | int ret; | ||
1881 | |||
1882 | if (mutex_lock_interruptible(&dev->dev_mutex)) | ||
1883 | return -ERESTARTSYS; | ||
1884 | ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); | ||
1885 | mutex_unlock(&dev->dev_mutex); | ||
1886 | return ret; | ||
1887 | } | ||
1888 | |||
1889 | static const struct v4l2_file_operations vpe_fops = { | ||
1890 | .owner = THIS_MODULE, | ||
1891 | .open = vpe_open, | ||
1892 | .release = vpe_release, | ||
1893 | .poll = vpe_poll, | ||
1894 | .unlocked_ioctl = video_ioctl2, | ||
1895 | .mmap = vpe_mmap, | ||
1896 | }; | ||
1897 | |||
1898 | static struct video_device vpe_videodev = { | ||
1899 | .name = VPE_MODULE_NAME, | ||
1900 | .fops = &vpe_fops, | ||
1901 | .ioctl_ops = &vpe_ioctl_ops, | ||
1902 | .minor = -1, | ||
1903 | .release = video_device_release, | ||
1904 | .vfl_dir = VFL_DIR_M2M, | ||
1905 | }; | ||
1906 | |||
1907 | static struct v4l2_m2m_ops m2m_ops = { | ||
1908 | .device_run = device_run, | ||
1909 | .job_ready = job_ready, | ||
1910 | .job_abort = job_abort, | ||
1911 | .lock = vpe_lock, | ||
1912 | .unlock = vpe_unlock, | ||
1913 | }; | ||
1914 | |||
1915 | static int vpe_runtime_get(struct platform_device *pdev) | ||
1916 | { | ||
1917 | int r; | ||
1918 | |||
1919 | dev_dbg(&pdev->dev, "vpe_runtime_get\n"); | ||
1920 | |||
1921 | r = pm_runtime_get_sync(&pdev->dev); | ||
1922 | WARN_ON(r < 0); | ||
1923 | return r < 0 ? r : 0; | ||
1924 | } | ||
1925 | |||
1926 | static void vpe_runtime_put(struct platform_device *pdev) | ||
1927 | { | ||
1928 | |||
1929 | int r; | ||
1930 | |||
1931 | dev_dbg(&pdev->dev, "vpe_runtime_put\n"); | ||
1932 | |||
1933 | r = pm_runtime_put_sync(&pdev->dev); | ||
1934 | WARN_ON(r < 0 && r != -ENOSYS); | ||
1935 | } | ||
1936 | |||
1937 | static int vpe_probe(struct platform_device *pdev) | ||
1938 | { | ||
1939 | struct vpe_dev *dev; | ||
1940 | struct video_device *vfd; | ||
1941 | struct resource *res; | ||
1942 | int ret, irq, func; | ||
1943 | |||
1944 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | ||
1945 | if (IS_ERR(dev)) | ||
1946 | return PTR_ERR(dev); | ||
1947 | |||
1948 | spin_lock_init(&dev->lock); | ||
1949 | |||
1950 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); | ||
1951 | if (ret) | ||
1952 | return ret; | ||
1953 | |||
1954 | atomic_set(&dev->num_instances, 0); | ||
1955 | mutex_init(&dev->dev_mutex); | ||
1956 | |||
1957 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpe_top"); | ||
1958 | /* | ||
1959 | * HACK: we get resource info from device tree in the form of a list of | ||
1960 | * VPE sub blocks, the driver currently uses only the base of vpe_top | ||
1961 | * for register access, the driver should be changed later to access | ||
1962 | * registers based on the sub block base addresses | ||
1963 | */ | ||
1964 | dev->base = devm_ioremap(&pdev->dev, res->start, SZ_32K); | ||
1965 | if (IS_ERR(dev->base)) { | ||
1966 | ret = PTR_ERR(dev->base); | ||
1967 | goto v4l2_dev_unreg; | ||
1968 | } | ||
1969 | |||
1970 | irq = platform_get_irq(pdev, 0); | ||
1971 | ret = devm_request_irq(&pdev->dev, irq, vpe_irq, 0, VPE_MODULE_NAME, | ||
1972 | dev); | ||
1973 | if (ret) | ||
1974 | goto v4l2_dev_unreg; | ||
1975 | |||
1976 | platform_set_drvdata(pdev, dev); | ||
1977 | |||
1978 | dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | ||
1979 | if (IS_ERR(dev->alloc_ctx)) { | ||
1980 | vpe_err(dev, "Failed to alloc vb2 context\n"); | ||
1981 | ret = PTR_ERR(dev->alloc_ctx); | ||
1982 | goto v4l2_dev_unreg; | ||
1983 | } | ||
1984 | |||
1985 | dev->m2m_dev = v4l2_m2m_init(&m2m_ops); | ||
1986 | if (IS_ERR(dev->m2m_dev)) { | ||
1987 | vpe_err(dev, "Failed to init mem2mem device\n"); | ||
1988 | ret = PTR_ERR(dev->m2m_dev); | ||
1989 | goto rel_ctx; | ||
1990 | } | ||
1991 | |||
1992 | pm_runtime_enable(&pdev->dev); | ||
1993 | |||
1994 | ret = vpe_runtime_get(pdev); | ||
1995 | if (ret) | ||
1996 | goto rel_m2m; | ||
1997 | |||
1998 | /* Perform clk enable followed by reset */ | ||
1999 | vpe_set_clock_enable(dev, 1); | ||
2000 | |||
2001 | vpe_top_reset(dev); | ||
2002 | |||
2003 | func = read_field_reg(dev, VPE_PID, VPE_PID_FUNC_MASK, | ||
2004 | VPE_PID_FUNC_SHIFT); | ||
2005 | vpe_dbg(dev, "VPE PID function %x\n", func); | ||
2006 | |||
2007 | vpe_top_vpdma_reset(dev); | ||
2008 | |||
2009 | dev->vpdma = vpdma_create(pdev); | ||
2010 | if (IS_ERR(dev->vpdma)) | ||
2011 | goto runtime_put; | ||
2012 | |||
2013 | vfd = &dev->vfd; | ||
2014 | *vfd = vpe_videodev; | ||
2015 | vfd->lock = &dev->dev_mutex; | ||
2016 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
2017 | |||
2018 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
2019 | if (ret) { | ||
2020 | vpe_err(dev, "Failed to register video device\n"); | ||
2021 | goto runtime_put; | ||
2022 | } | ||
2023 | |||
2024 | video_set_drvdata(vfd, dev); | ||
2025 | snprintf(vfd->name, sizeof(vfd->name), "%s", vpe_videodev.name); | ||
2026 | dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n", | ||
2027 | vfd->num); | ||
2028 | |||
2029 | return 0; | ||
2030 | |||
2031 | runtime_put: | ||
2032 | vpe_runtime_put(pdev); | ||
2033 | rel_m2m: | ||
2034 | pm_runtime_disable(&pdev->dev); | ||
2035 | v4l2_m2m_release(dev->m2m_dev); | ||
2036 | rel_ctx: | ||
2037 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | ||
2038 | v4l2_dev_unreg: | ||
2039 | v4l2_device_unregister(&dev->v4l2_dev); | ||
2040 | |||
2041 | return ret; | ||
2042 | } | ||
2043 | |||
2044 | static int vpe_remove(struct platform_device *pdev) | ||
2045 | { | ||
2046 | struct vpe_dev *dev = | ||
2047 | (struct vpe_dev *) platform_get_drvdata(pdev); | ||
2048 | |||
2049 | v4l2_info(&dev->v4l2_dev, "Removing " VPE_MODULE_NAME); | ||
2050 | |||
2051 | v4l2_m2m_release(dev->m2m_dev); | ||
2052 | video_unregister_device(&dev->vfd); | ||
2053 | v4l2_device_unregister(&dev->v4l2_dev); | ||
2054 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | ||
2055 | |||
2056 | vpe_set_clock_enable(dev, 0); | ||
2057 | vpe_runtime_put(pdev); | ||
2058 | pm_runtime_disable(&pdev->dev); | ||
2059 | |||
2060 | return 0; | ||
2061 | } | ||
2062 | |||
2063 | #if defined(CONFIG_OF) | ||
2064 | static const struct of_device_id vpe_of_match[] = { | ||
2065 | { | ||
2066 | .compatible = "ti,vpe", | ||
2067 | }, | ||
2068 | {}, | ||
2069 | }; | ||
2070 | #else | ||
2071 | #define vpe_of_match NULL | ||
2072 | #endif | ||
2073 | |||
2074 | static struct platform_driver vpe_pdrv = { | ||
2075 | .probe = vpe_probe, | ||
2076 | .remove = vpe_remove, | ||
2077 | .driver = { | ||
2078 | .name = VPE_MODULE_NAME, | ||
2079 | .owner = THIS_MODULE, | ||
2080 | .of_match_table = vpe_of_match, | ||
2081 | }, | ||
2082 | }; | ||
2083 | |||
2084 | static void __exit vpe_exit(void) | ||
2085 | { | ||
2086 | platform_driver_unregister(&vpe_pdrv); | ||
2087 | } | ||
2088 | |||
2089 | static int __init vpe_init(void) | ||
2090 | { | ||
2091 | return platform_driver_register(&vpe_pdrv); | ||
2092 | } | ||
2093 | |||
2094 | module_init(vpe_init); | ||
2095 | module_exit(vpe_exit); | ||
2096 | |||
2097 | MODULE_DESCRIPTION("TI VPE driver"); | ||
2098 | MODULE_AUTHOR("Dale Farnsworth, <dale@farnsworth.org>"); | ||
2099 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti-vpe/vpe_regs.h new file mode 100644 index 000000000000..ed214e828398 --- /dev/null +++ b/drivers/media/platform/ti-vpe/vpe_regs.h | |||
@@ -0,0 +1,496 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Texas Instruments Inc. | ||
3 | * | ||
4 | * David Griego, <dagriego@biglakesoftware.com> | ||
5 | * Dale Farnsworth, <dale@farnsworth.org> | ||
6 | * Archit Taneja, <archit@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published by | ||
10 | * the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __TI_VPE_REGS_H | ||
14 | #define __TI_VPE_REGS_H | ||
15 | |||
16 | /* VPE register offsets and field selectors */ | ||
17 | |||
18 | /* VPE top level regs */ | ||
19 | #define VPE_PID 0x0000 | ||
20 | #define VPE_PID_MINOR_MASK 0x3f | ||
21 | #define VPE_PID_MINOR_SHIFT 0 | ||
22 | #define VPE_PID_CUSTOM_MASK 0x03 | ||
23 | #define VPE_PID_CUSTOM_SHIFT 6 | ||
24 | #define VPE_PID_MAJOR_MASK 0x07 | ||
25 | #define VPE_PID_MAJOR_SHIFT 8 | ||
26 | #define VPE_PID_RTL_MASK 0x1f | ||
27 | #define VPE_PID_RTL_SHIFT 11 | ||
28 | #define VPE_PID_FUNC_MASK 0xfff | ||
29 | #define VPE_PID_FUNC_SHIFT 16 | ||
30 | #define VPE_PID_SCHEME_MASK 0x03 | ||
31 | #define VPE_PID_SCHEME_SHIFT 30 | ||
32 | |||
33 | #define VPE_SYSCONFIG 0x0010 | ||
34 | #define VPE_SYSCONFIG_IDLE_MASK 0x03 | ||
35 | #define VPE_SYSCONFIG_IDLE_SHIFT 2 | ||
36 | #define VPE_SYSCONFIG_STANDBY_MASK 0x03 | ||
37 | #define VPE_SYSCONFIG_STANDBY_SHIFT 4 | ||
38 | #define VPE_FORCE_IDLE_MODE 0 | ||
39 | #define VPE_NO_IDLE_MODE 1 | ||
40 | #define VPE_SMART_IDLE_MODE 2 | ||
41 | #define VPE_SMART_IDLE_WAKEUP_MODE 3 | ||
42 | #define VPE_FORCE_STANDBY_MODE 0 | ||
43 | #define VPE_NO_STANDBY_MODE 1 | ||
44 | #define VPE_SMART_STANDBY_MODE 2 | ||
45 | #define VPE_SMART_STANDBY_WAKEUP_MODE 3 | ||
46 | |||
47 | #define VPE_INT0_STATUS0_RAW_SET 0x0020 | ||
48 | #define VPE_INT0_STATUS0_RAW VPE_INT0_STATUS0_RAW_SET | ||
49 | #define VPE_INT0_STATUS0_CLR 0x0028 | ||
50 | #define VPE_INT0_STATUS0 VPE_INT0_STATUS0_CLR | ||
51 | #define VPE_INT0_ENABLE0_SET 0x0030 | ||
52 | #define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET | ||
53 | #define VPE_INT0_ENABLE0_CLR 0x0038 | ||
54 | #define VPE_INT0_LIST0_COMPLETE (1 << 0) | ||
55 | #define VPE_INT0_LIST0_NOTIFY (1 << 1) | ||
56 | #define VPE_INT0_LIST1_COMPLETE (1 << 2) | ||
57 | #define VPE_INT0_LIST1_NOTIFY (1 << 3) | ||
58 | #define VPE_INT0_LIST2_COMPLETE (1 << 4) | ||
59 | #define VPE_INT0_LIST2_NOTIFY (1 << 5) | ||
60 | #define VPE_INT0_LIST3_COMPLETE (1 << 6) | ||
61 | #define VPE_INT0_LIST3_NOTIFY (1 << 7) | ||
62 | #define VPE_INT0_LIST4_COMPLETE (1 << 8) | ||
63 | #define VPE_INT0_LIST4_NOTIFY (1 << 9) | ||
64 | #define VPE_INT0_LIST5_COMPLETE (1 << 10) | ||
65 | #define VPE_INT0_LIST5_NOTIFY (1 << 11) | ||
66 | #define VPE_INT0_LIST6_COMPLETE (1 << 12) | ||
67 | #define VPE_INT0_LIST6_NOTIFY (1 << 13) | ||
68 | #define VPE_INT0_LIST7_COMPLETE (1 << 14) | ||
69 | #define VPE_INT0_LIST7_NOTIFY (1 << 15) | ||
70 | #define VPE_INT0_DESCRIPTOR (1 << 16) | ||
71 | #define VPE_DEI_FMD_INT (1 << 18) | ||
72 | |||
73 | #define VPE_INT0_STATUS1_RAW_SET 0x0024 | ||
74 | #define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET | ||
75 | #define VPE_INT0_STATUS1_CLR 0x002c | ||
76 | #define VPE_INT0_STATUS1 VPE_INT0_STATUS1_CLR | ||
77 | #define VPE_INT0_ENABLE1_SET 0x0034 | ||
78 | #define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET | ||
79 | #define VPE_INT0_ENABLE1_CLR 0x003c | ||
80 | #define VPE_INT0_CHANNEL_GROUP0 (1 << 0) | ||
81 | #define VPE_INT0_CHANNEL_GROUP1 (1 << 1) | ||
82 | #define VPE_INT0_CHANNEL_GROUP2 (1 << 2) | ||
83 | #define VPE_INT0_CHANNEL_GROUP3 (1 << 3) | ||
84 | #define VPE_INT0_CHANNEL_GROUP4 (1 << 4) | ||
85 | #define VPE_INT0_CHANNEL_GROUP5 (1 << 5) | ||
86 | #define VPE_INT0_CLIENT (1 << 7) | ||
87 | #define VPE_DEI_ERROR_INT (1 << 16) | ||
88 | #define VPE_DS1_UV_ERROR_INT (1 << 22) | ||
89 | |||
90 | #define VPE_INTC_EOI 0x00a0 | ||
91 | |||
92 | #define VPE_CLK_ENABLE 0x0100 | ||
93 | #define VPE_VPEDMA_CLK_ENABLE (1 << 0) | ||
94 | #define VPE_DATA_PATH_CLK_ENABLE (1 << 1) | ||
95 | |||
96 | #define VPE_CLK_RESET 0x0104 | ||
97 | #define VPE_VPDMA_CLK_RESET_MASK 0x1 | ||
98 | #define VPE_VPDMA_CLK_RESET_SHIFT 0 | ||
99 | #define VPE_DATA_PATH_CLK_RESET_MASK 0x1 | ||
100 | #define VPE_DATA_PATH_CLK_RESET_SHIFT 1 | ||
101 | #define VPE_MAIN_RESET_MASK 0x1 | ||
102 | #define VPE_MAIN_RESET_SHIFT 31 | ||
103 | |||
104 | #define VPE_CLK_FORMAT_SELECT 0x010c | ||
105 | #define VPE_CSC_SRC_SELECT_MASK 0x03 | ||
106 | #define VPE_CSC_SRC_SELECT_SHIFT 0 | ||
107 | #define VPE_RGB_OUT_SELECT (1 << 8) | ||
108 | #define VPE_DS_SRC_SELECT_MASK 0x07 | ||
109 | #define VPE_DS_SRC_SELECT_SHIFT 9 | ||
110 | #define VPE_DS_BYPASS (1 << 16) | ||
111 | #define VPE_COLOR_SEPARATE_422 (1 << 18) | ||
112 | |||
113 | #define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT) | ||
114 | #define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT) | ||
115 | |||
116 | #define VPE_CLK_RANGE_MAP 0x011c | ||
117 | #define VPE_RANGE_RANGE_MAP_Y_MASK 0x07 | ||
118 | #define VPE_RANGE_RANGE_MAP_Y_SHIFT 0 | ||
119 | #define VPE_RANGE_RANGE_MAP_UV_MASK 0x07 | ||
120 | #define VPE_RANGE_RANGE_MAP_UV_SHIFT 3 | ||
121 | #define VPE_RANGE_MAP_ON (1 << 6) | ||
122 | #define VPE_RANGE_REDUCTION_ON (1 << 28) | ||
123 | |||
124 | /* VPE chrominance upsampler regs */ | ||
125 | #define VPE_US1_R0 0x0304 | ||
126 | #define VPE_US2_R0 0x0404 | ||
127 | #define VPE_US3_R0 0x0504 | ||
128 | #define VPE_US_C1_MASK 0x3fff | ||
129 | #define VPE_US_C1_SHIFT 2 | ||
130 | #define VPE_US_C0_MASK 0x3fff | ||
131 | #define VPE_US_C0_SHIFT 18 | ||
132 | #define VPE_US_MODE_MASK 0x03 | ||
133 | #define VPE_US_MODE_SHIFT 16 | ||
134 | #define VPE_ANCHOR_FID0_C1_MASK 0x3fff | ||
135 | #define VPE_ANCHOR_FID0_C1_SHIFT 2 | ||
136 | #define VPE_ANCHOR_FID0_C0_MASK 0x3fff | ||
137 | #define VPE_ANCHOR_FID0_C0_SHIFT 18 | ||
138 | |||
139 | #define VPE_US1_R1 0x0308 | ||
140 | #define VPE_US2_R1 0x0408 | ||
141 | #define VPE_US3_R1 0x0508 | ||
142 | #define VPE_ANCHOR_FID0_C3_MASK 0x3fff | ||
143 | #define VPE_ANCHOR_FID0_C3_SHIFT 2 | ||
144 | #define VPE_ANCHOR_FID0_C2_MASK 0x3fff | ||
145 | #define VPE_ANCHOR_FID0_C2_SHIFT 18 | ||
146 | |||
147 | #define VPE_US1_R2 0x030c | ||
148 | #define VPE_US2_R2 0x040c | ||
149 | #define VPE_US3_R2 0x050c | ||
150 | #define VPE_INTERP_FID0_C1_MASK 0x3fff | ||
151 | #define VPE_INTERP_FID0_C1_SHIFT 2 | ||
152 | #define VPE_INTERP_FID0_C0_MASK 0x3fff | ||
153 | #define VPE_INTERP_FID0_C0_SHIFT 18 | ||
154 | |||
155 | #define VPE_US1_R3 0x0310 | ||
156 | #define VPE_US2_R3 0x0410 | ||
157 | #define VPE_US3_R3 0x0510 | ||
158 | #define VPE_INTERP_FID0_C3_MASK 0x3fff | ||
159 | #define VPE_INTERP_FID0_C3_SHIFT 2 | ||
160 | #define VPE_INTERP_FID0_C2_MASK 0x3fff | ||
161 | #define VPE_INTERP_FID0_C2_SHIFT 18 | ||
162 | |||
163 | #define VPE_US1_R4 0x0314 | ||
164 | #define VPE_US2_R4 0x0414 | ||
165 | #define VPE_US3_R4 0x0514 | ||
166 | #define VPE_ANCHOR_FID1_C1_MASK 0x3fff | ||
167 | #define VPE_ANCHOR_FID1_C1_SHIFT 2 | ||
168 | #define VPE_ANCHOR_FID1_C0_MASK 0x3fff | ||
169 | #define VPE_ANCHOR_FID1_C0_SHIFT 18 | ||
170 | |||
171 | #define VPE_US1_R5 0x0318 | ||
172 | #define VPE_US2_R5 0x0418 | ||
173 | #define VPE_US3_R5 0x0518 | ||
174 | #define VPE_ANCHOR_FID1_C3_MASK 0x3fff | ||
175 | #define VPE_ANCHOR_FID1_C3_SHIFT 2 | ||
176 | #define VPE_ANCHOR_FID1_C2_MASK 0x3fff | ||
177 | #define VPE_ANCHOR_FID1_C2_SHIFT 18 | ||
178 | |||
179 | #define VPE_US1_R6 0x031c | ||
180 | #define VPE_US2_R6 0x041c | ||
181 | #define VPE_US3_R6 0x051c | ||
182 | #define VPE_INTERP_FID1_C1_MASK 0x3fff | ||
183 | #define VPE_INTERP_FID1_C1_SHIFT 2 | ||
184 | #define VPE_INTERP_FID1_C0_MASK 0x3fff | ||
185 | #define VPE_INTERP_FID1_C0_SHIFT 18 | ||
186 | |||
187 | #define VPE_US1_R7 0x0320 | ||
188 | #define VPE_US2_R7 0x0420 | ||
189 | #define VPE_US3_R7 0x0520 | ||
190 | #define VPE_INTERP_FID0_C3_MASK 0x3fff | ||
191 | #define VPE_INTERP_FID0_C3_SHIFT 2 | ||
192 | #define VPE_INTERP_FID0_C2_MASK 0x3fff | ||
193 | #define VPE_INTERP_FID0_C2_SHIFT 18 | ||
194 | |||
195 | /* VPE de-interlacer regs */ | ||
196 | #define VPE_DEI_FRAME_SIZE 0x0600 | ||
197 | #define VPE_DEI_WIDTH_MASK 0x07ff | ||
198 | #define VPE_DEI_WIDTH_SHIFT 0 | ||
199 | #define VPE_DEI_HEIGHT_MASK 0x07ff | ||
200 | #define VPE_DEI_HEIGHT_SHIFT 16 | ||
201 | #define VPE_DEI_INTERLACE_BYPASS (1 << 29) | ||
202 | #define VPE_DEI_FIELD_FLUSH (1 << 30) | ||
203 | #define VPE_DEI_PROGRESSIVE (1 << 31) | ||
204 | |||
205 | #define VPE_MDT_BYPASS 0x0604 | ||
206 | #define VPE_MDT_TEMPMAX_BYPASS (1 << 0) | ||
207 | #define VPE_MDT_SPATMAX_BYPASS (1 << 1) | ||
208 | |||
209 | #define VPE_MDT_SF_THRESHOLD 0x0608 | ||
210 | #define VPE_MDT_SF_SC_THR1_MASK 0xff | ||
211 | #define VPE_MDT_SF_SC_THR1_SHIFT 0 | ||
212 | #define VPE_MDT_SF_SC_THR2_MASK 0xff | ||
213 | #define VPE_MDT_SF_SC_THR2_SHIFT 0 | ||
214 | #define VPE_MDT_SF_SC_THR3_MASK 0xff | ||
215 | #define VPE_MDT_SF_SC_THR3_SHIFT 0 | ||
216 | |||
217 | #define VPE_EDI_CONFIG 0x060c | ||
218 | #define VPE_EDI_INP_MODE_MASK 0x03 | ||
219 | #define VPE_EDI_INP_MODE_SHIFT 0 | ||
220 | #define VPE_EDI_ENABLE_3D (1 << 2) | ||
221 | #define VPE_EDI_ENABLE_CHROMA_3D (1 << 3) | ||
222 | #define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff | ||
223 | #define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8 | ||
224 | #define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff | ||
225 | #define VPE_EDI_DIR_COR_LOWER_THR_SHIFT 16 | ||
226 | #define VPE_EDI_COR_SCALE_FACTOR_MASK 0xff | ||
227 | #define VPE_EDI_COR_SCALE_FACTOR_SHIFT 23 | ||
228 | |||
229 | #define VPE_DEI_EDI_LUT_R0 0x0610 | ||
230 | #define VPE_EDI_LUT0_MASK 0x1f | ||
231 | #define VPE_EDI_LUT0_SHIFT 0 | ||
232 | #define VPE_EDI_LUT1_MASK 0x1f | ||
233 | #define VPE_EDI_LUT1_SHIFT 8 | ||
234 | #define VPE_EDI_LUT2_MASK 0x1f | ||
235 | #define VPE_EDI_LUT2_SHIFT 16 | ||
236 | #define VPE_EDI_LUT3_MASK 0x1f | ||
237 | #define VPE_EDI_LUT3_SHIFT 24 | ||
238 | |||
239 | #define VPE_DEI_EDI_LUT_R1 0x0614 | ||
240 | #define VPE_EDI_LUT0_MASK 0x1f | ||
241 | #define VPE_EDI_LUT0_SHIFT 0 | ||
242 | #define VPE_EDI_LUT1_MASK 0x1f | ||
243 | #define VPE_EDI_LUT1_SHIFT 8 | ||
244 | #define VPE_EDI_LUT2_MASK 0x1f | ||
245 | #define VPE_EDI_LUT2_SHIFT 16 | ||
246 | #define VPE_EDI_LUT3_MASK 0x1f | ||
247 | #define VPE_EDI_LUT3_SHIFT 24 | ||
248 | |||
249 | #define VPE_DEI_EDI_LUT_R2 0x0618 | ||
250 | #define VPE_EDI_LUT4_MASK 0x1f | ||
251 | #define VPE_EDI_LUT4_SHIFT 0 | ||
252 | #define VPE_EDI_LUT5_MASK 0x1f | ||
253 | #define VPE_EDI_LUT5_SHIFT 8 | ||
254 | #define VPE_EDI_LUT6_MASK 0x1f | ||
255 | #define VPE_EDI_LUT6_SHIFT 16 | ||
256 | #define VPE_EDI_LUT7_MASK 0x1f | ||
257 | #define VPE_EDI_LUT7_SHIFT 24 | ||
258 | |||
259 | #define VPE_DEI_EDI_LUT_R3 0x061c | ||
260 | #define VPE_EDI_LUT8_MASK 0x1f | ||
261 | #define VPE_EDI_LUT8_SHIFT 0 | ||
262 | #define VPE_EDI_LUT9_MASK 0x1f | ||
263 | #define VPE_EDI_LUT9_SHIFT 8 | ||
264 | #define VPE_EDI_LUT10_MASK 0x1f | ||
265 | #define VPE_EDI_LUT10_SHIFT 16 | ||
266 | #define VPE_EDI_LUT11_MASK 0x1f | ||
267 | #define VPE_EDI_LUT11_SHIFT 24 | ||
268 | |||
269 | #define VPE_DEI_FMD_WINDOW_R0 0x0620 | ||
270 | #define VPE_FMD_WINDOW_MINX_MASK 0x07ff | ||
271 | #define VPE_FMD_WINDOW_MINX_SHIFT 0 | ||
272 | #define VPE_FMD_WINDOW_MAXX_MASK 0x07ff | ||
273 | #define VPE_FMD_WINDOW_MAXX_SHIFT 16 | ||
274 | #define VPE_FMD_WINDOW_ENABLE (1 << 31) | ||
275 | |||
276 | #define VPE_DEI_FMD_WINDOW_R1 0x0624 | ||
277 | #define VPE_FMD_WINDOW_MINY_MASK 0x07ff | ||
278 | #define VPE_FMD_WINDOW_MINY_SHIFT 0 | ||
279 | #define VPE_FMD_WINDOW_MAXY_MASK 0x07ff | ||
280 | #define VPE_FMD_WINDOW_MAXY_SHIFT 16 | ||
281 | |||
282 | #define VPE_DEI_FMD_CONTROL_R0 0x0628 | ||
283 | #define VPE_FMD_ENABLE (1 << 0) | ||
284 | #define VPE_FMD_LOCK (1 << 1) | ||
285 | #define VPE_FMD_JAM_DIR (1 << 2) | ||
286 | #define VPE_FMD_BED_ENABLE (1 << 3) | ||
287 | #define VPE_FMD_CAF_FIELD_THR_MASK 0xff | ||
288 | #define VPE_FMD_CAF_FIELD_THR_SHIFT 16 | ||
289 | #define VPE_FMD_CAF_LINE_THR_MASK 0xff | ||
290 | #define VPE_FMD_CAF_LINE_THR_SHIFT 24 | ||
291 | |||
292 | #define VPE_DEI_FMD_CONTROL_R1 0x062c | ||
293 | #define VPE_FMD_CAF_THR_MASK 0x000fffff | ||
294 | #define VPE_FMD_CAF_THR_SHIFT 0 | ||
295 | |||
296 | #define VPE_DEI_FMD_STATUS_R0 0x0630 | ||
297 | #define VPE_FMD_CAF_MASK 0x000fffff | ||
298 | #define VPE_FMD_CAF_SHIFT 0 | ||
299 | #define VPE_FMD_RESET (1 << 24) | ||
300 | |||
301 | #define VPE_DEI_FMD_STATUS_R1 0x0634 | ||
302 | #define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff | ||
303 | #define VPE_FMD_FIELD_DIFF_SHIFT 0 | ||
304 | |||
305 | #define VPE_DEI_FMD_STATUS_R2 0x0638 | ||
306 | #define VPE_FMD_FRAME_DIFF_MASK 0x000fffff | ||
307 | #define VPE_FMD_FRAME_DIFF_SHIFT 0 | ||
308 | |||
309 | /* VPE scaler regs */ | ||
310 | #define VPE_SC_MP_SC0 0x0700 | ||
311 | #define VPE_INTERLACE_O (1 << 0) | ||
312 | #define VPE_LINEAR (1 << 1) | ||
313 | #define VPE_SC_BYPASS (1 << 2) | ||
314 | #define VPE_INVT_FID (1 << 3) | ||
315 | #define VPE_USE_RAV (1 << 4) | ||
316 | #define VPE_ENABLE_EV (1 << 5) | ||
317 | #define VPE_AUTO_HS (1 << 6) | ||
318 | #define VPE_DCM_2X (1 << 7) | ||
319 | #define VPE_DCM_4X (1 << 8) | ||
320 | #define VPE_HP_BYPASS (1 << 9) | ||
321 | #define VPE_INTERLACE_I (1 << 10) | ||
322 | #define VPE_ENABLE_SIN2_VER_INTP (1 << 11) | ||
323 | #define VPE_Y_PK_EN (1 << 14) | ||
324 | #define VPE_TRIM (1 << 15) | ||
325 | #define VPE_SELFGEN_FID (1 << 16) | ||
326 | |||
327 | #define VPE_SC_MP_SC1 0x0704 | ||
328 | #define VPE_ROW_ACC_INC_MASK 0x07ffffff | ||
329 | #define VPE_ROW_ACC_INC_SHIFT 0 | ||
330 | |||
331 | #define VPE_SC_MP_SC2 0x0708 | ||
332 | #define VPE_ROW_ACC_OFFSET_MASK 0x0fffffff | ||
333 | #define VPE_ROW_ACC_OFFSET_SHIFT 0 | ||
334 | |||
335 | #define VPE_SC_MP_SC3 0x070c | ||
336 | #define VPE_ROW_ACC_OFFSET_B_MASK 0x0fffffff | ||
337 | #define VPE_ROW_ACC_OFFSET_B_SHIFT 0 | ||
338 | |||
339 | #define VPE_SC_MP_SC4 0x0710 | ||
340 | #define VPE_TAR_H_MASK 0x07ff | ||
341 | #define VPE_TAR_H_SHIFT 0 | ||
342 | #define VPE_TAR_W_MASK 0x07ff | ||
343 | #define VPE_TAR_W_SHIFT 12 | ||
344 | #define VPE_LIN_ACC_INC_U_MASK 0x07 | ||
345 | #define VPE_LIN_ACC_INC_U_SHIFT 24 | ||
346 | #define VPE_NLIN_ACC_INIT_U_MASK 0x07 | ||
347 | #define VPE_NLIN_ACC_INIT_U_SHIFT 28 | ||
348 | |||
349 | #define VPE_SC_MP_SC5 0x0714 | ||
350 | #define VPE_SRC_H_MASK 0x07ff | ||
351 | #define VPE_SRC_H_SHIFT 0 | ||
352 | #define VPE_SRC_W_MASK 0x07ff | ||
353 | #define VPE_SRC_W_SHIFT 12 | ||
354 | #define VPE_NLIN_ACC_INC_U_MASK 0x07 | ||
355 | #define VPE_NLIN_ACC_INC_U_SHIFT 24 | ||
356 | |||
357 | #define VPE_SC_MP_SC6 0x0718 | ||
358 | #define VPE_ROW_ACC_INIT_RAV_MASK 0x03ff | ||
359 | #define VPE_ROW_ACC_INIT_RAV_SHIFT 0 | ||
360 | #define VPE_ROW_ACC_INIT_RAV_B_MASK 0x03ff | ||
361 | #define VPE_ROW_ACC_INIT_RAV_B_SHIFT 10 | ||
362 | |||
363 | #define VPE_SC_MP_SC8 0x0720 | ||
364 | #define VPE_NLIN_LEFT_MASK 0x07ff | ||
365 | #define VPE_NLIN_LEFT_SHIFT 0 | ||
366 | #define VPE_NLIN_RIGHT_MASK 0x07ff | ||
367 | #define VPE_NLIN_RIGHT_SHIFT 12 | ||
368 | |||
369 | #define VPE_SC_MP_SC9 0x0724 | ||
370 | #define VPE_LIN_ACC_INC VPE_SC_MP_SC9 | ||
371 | |||
372 | #define VPE_SC_MP_SC10 0x0728 | ||
373 | #define VPE_NLIN_ACC_INIT VPE_SC_MP_SC10 | ||
374 | |||
375 | #define VPE_SC_MP_SC11 0x072c | ||
376 | #define VPE_NLIN_ACC_INC VPE_SC_MP_SC11 | ||
377 | |||
378 | #define VPE_SC_MP_SC12 0x0730 | ||
379 | #define VPE_COL_ACC_OFFSET_MASK 0x01ffffff | ||
380 | #define VPE_COL_ACC_OFFSET_SHIFT 0 | ||
381 | |||
382 | #define VPE_SC_MP_SC13 0x0734 | ||
383 | #define VPE_SC_FACTOR_RAV_MASK 0x03ff | ||
384 | #define VPE_SC_FACTOR_RAV_SHIFT 0 | ||
385 | #define VPE_CHROMA_INTP_THR_MASK 0x03ff | ||
386 | #define VPE_CHROMA_INTP_THR_SHIFT 12 | ||
387 | #define VPE_DELTA_CHROMA_THR_MASK 0x0f | ||
388 | #define VPE_DELTA_CHROMA_THR_SHIFT 24 | ||
389 | |||
390 | #define VPE_SC_MP_SC17 0x0744 | ||
391 | #define VPE_EV_THR_MASK 0x03ff | ||
392 | #define VPE_EV_THR_SHIFT 12 | ||
393 | #define VPE_DELTA_LUMA_THR_MASK 0x0f | ||
394 | #define VPE_DELTA_LUMA_THR_SHIFT 24 | ||
395 | #define VPE_DELTA_EV_THR_MASK 0x0f | ||
396 | #define VPE_DELTA_EV_THR_SHIFT 28 | ||
397 | |||
398 | #define VPE_SC_MP_SC18 0x0748 | ||
399 | #define VPE_HS_FACTOR_MASK 0x03ff | ||
400 | #define VPE_HS_FACTOR_SHIFT 0 | ||
401 | #define VPE_CONF_DEFAULT_MASK 0x01ff | ||
402 | #define VPE_CONF_DEFAULT_SHIFT 16 | ||
403 | |||
404 | #define VPE_SC_MP_SC19 0x074c | ||
405 | #define VPE_HPF_COEFF0_MASK 0xff | ||
406 | #define VPE_HPF_COEFF0_SHIFT 0 | ||
407 | #define VPE_HPF_COEFF1_MASK 0xff | ||
408 | #define VPE_HPF_COEFF1_SHIFT 8 | ||
409 | #define VPE_HPF_COEFF2_MASK 0xff | ||
410 | #define VPE_HPF_COEFF2_SHIFT 16 | ||
411 | #define VPE_HPF_COEFF3_MASK 0xff | ||
412 | #define VPE_HPF_COEFF3_SHIFT 23 | ||
413 | |||
414 | #define VPE_SC_MP_SC20 0x0750 | ||
415 | #define VPE_HPF_COEFF4_MASK 0xff | ||
416 | #define VPE_HPF_COEFF4_SHIFT 0 | ||
417 | #define VPE_HPF_COEFF5_MASK 0xff | ||
418 | #define VPE_HPF_COEFF5_SHIFT 8 | ||
419 | #define VPE_HPF_NORM_SHIFT_MASK 0x07 | ||
420 | #define VPE_HPF_NORM_SHIFT_SHIFT 16 | ||
421 | #define VPE_NL_LIMIT_MASK 0x1ff | ||
422 | #define VPE_NL_LIMIT_SHIFT 20 | ||
423 | |||
424 | #define VPE_SC_MP_SC21 0x0754 | ||
425 | #define VPE_NL_LO_THR_MASK 0x01ff | ||
426 | #define VPE_NL_LO_THR_SHIFT 0 | ||
427 | #define VPE_NL_LO_SLOPE_MASK 0xff | ||
428 | #define VPE_NL_LO_SLOPE_SHIFT 16 | ||
429 | |||
430 | #define VPE_SC_MP_SC22 0x0758 | ||
431 | #define VPE_NL_HI_THR_MASK 0x01ff | ||
432 | #define VPE_NL_HI_THR_SHIFT 0 | ||
433 | #define VPE_NL_HI_SLOPE_SH_MASK 0x07 | ||
434 | #define VPE_NL_HI_SLOPE_SH_SHIFT 16 | ||
435 | |||
436 | #define VPE_SC_MP_SC23 0x075c | ||
437 | #define VPE_GRADIENT_THR_MASK 0x07ff | ||
438 | #define VPE_GRADIENT_THR_SHIFT 0 | ||
439 | #define VPE_GRADIENT_THR_RANGE_MASK 0x0f | ||
440 | #define VPE_GRADIENT_THR_RANGE_SHIFT 12 | ||
441 | #define VPE_MIN_GY_THR_MASK 0xff | ||
442 | #define VPE_MIN_GY_THR_SHIFT 16 | ||
443 | #define VPE_MIN_GY_THR_RANGE_MASK 0x0f | ||
444 | #define VPE_MIN_GY_THR_RANGE_SHIFT 28 | ||
445 | |||
446 | #define VPE_SC_MP_SC24 0x0760 | ||
447 | #define VPE_ORG_H_MASK 0x07ff | ||
448 | #define VPE_ORG_H_SHIFT 0 | ||
449 | #define VPE_ORG_W_MASK 0x07ff | ||
450 | #define VPE_ORG_W_SHIFT 16 | ||
451 | |||
452 | #define VPE_SC_MP_SC25 0x0764 | ||
453 | #define VPE_OFF_H_MASK 0x07ff | ||
454 | #define VPE_OFF_H_SHIFT 0 | ||
455 | #define VPE_OFF_W_MASK 0x07ff | ||
456 | #define VPE_OFF_W_SHIFT 16 | ||
457 | |||
458 | /* VPE color space converter regs */ | ||
459 | #define VPE_CSC_CSC00 0x5700 | ||
460 | #define VPE_CSC_A0_MASK 0x1fff | ||
461 | #define VPE_CSC_A0_SHIFT 0 | ||
462 | #define VPE_CSC_B0_MASK 0x1fff | ||
463 | #define VPE_CSC_B0_SHIFT 16 | ||
464 | |||
465 | #define VPE_CSC_CSC01 0x5704 | ||
466 | #define VPE_CSC_C0_MASK 0x1fff | ||
467 | #define VPE_CSC_C0_SHIFT 0 | ||
468 | #define VPE_CSC_A1_MASK 0x1fff | ||
469 | #define VPE_CSC_A1_SHIFT 16 | ||
470 | |||
471 | #define VPE_CSC_CSC02 0x5708 | ||
472 | #define VPE_CSC_B1_MASK 0x1fff | ||
473 | #define VPE_CSC_B1_SHIFT 0 | ||
474 | #define VPE_CSC_C1_MASK 0x1fff | ||
475 | #define VPE_CSC_C1_SHIFT 16 | ||
476 | |||
477 | #define VPE_CSC_CSC03 0x570c | ||
478 | #define VPE_CSC_A2_MASK 0x1fff | ||
479 | #define VPE_CSC_A2_SHIFT 0 | ||
480 | #define VPE_CSC_B2_MASK 0x1fff | ||
481 | #define VPE_CSC_B2_SHIFT 16 | ||
482 | |||
483 | #define VPE_CSC_CSC04 0x5710 | ||
484 | #define VPE_CSC_C2_MASK 0x1fff | ||
485 | #define VPE_CSC_C2_SHIFT 0 | ||
486 | #define VPE_CSC_D0_MASK 0x0fff | ||
487 | #define VPE_CSC_D0_SHIFT 16 | ||
488 | |||
489 | #define VPE_CSC_CSC05 0x5714 | ||
490 | #define VPE_CSC_D1_MASK 0x0fff | ||
491 | #define VPE_CSC_D1_SHIFT 0 | ||
492 | #define VPE_CSC_D2_MASK 0x0fff | ||
493 | #define VPE_CSC_D2_SHIFT 16 | ||
494 | #define VPE_CSC_BYPASS (1 << 28) | ||
495 | |||
496 | #endif | ||
diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c index b557caf5b1a4..6a74ce040d28 100644 --- a/drivers/media/platform/timblogiw.c +++ b/drivers/media/platform/timblogiw.c | |||
@@ -403,7 +403,7 @@ static int timblogiw_s_input(struct file *file, void *priv, unsigned int input) | |||
403 | return 0; | 403 | return 0; |
404 | } | 404 | } |
405 | 405 | ||
406 | static int timblogiw_streamon(struct file *file, void *priv, unsigned int type) | 406 | static int timblogiw_streamon(struct file *file, void *priv, enum v4l2_buf_type type) |
407 | { | 407 | { |
408 | struct video_device *vdev = video_devdata(file); | 408 | struct video_device *vdev = video_devdata(file); |
409 | struct timblogiw_fh *fh = priv; | 409 | struct timblogiw_fh *fh = priv; |
@@ -420,7 +420,7 @@ static int timblogiw_streamon(struct file *file, void *priv, unsigned int type) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | static int timblogiw_streamoff(struct file *file, void *priv, | 422 | static int timblogiw_streamoff(struct file *file, void *priv, |
423 | unsigned int type) | 423 | enum v4l2_buf_type type) |
424 | { | 424 | { |
425 | struct video_device *vdev = video_devdata(file); | 425 | struct video_device *vdev = video_devdata(file); |
426 | struct timblogiw_fh *fh = priv; | 426 | struct timblogiw_fh *fh = priv; |
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index 21db23b196be..fa3964022b96 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c | |||
@@ -123,7 +123,7 @@ static int keene_cmd_set(struct keene_device *radio) | |||
123 | /* If bit 0 is set, then transmit mono, otherwise stereo. | 123 | /* If bit 0 is set, then transmit mono, otherwise stereo. |
124 | If bit 2 is set, then enable 75 us preemphasis, otherwise | 124 | If bit 2 is set, then enable 75 us preemphasis, otherwise |
125 | it is 50 us. */ | 125 | it is 50 us. */ |
126 | radio->buffer[3] = (!radio->stereo) | (radio->preemph_75_us ? 4 : 0); | 126 | radio->buffer[3] = (radio->stereo ? 0 : 1) | (radio->preemph_75_us ? 4 : 0); |
127 | radio->buffer[4] = 0x00; | 127 | radio->buffer[4] = 0x00; |
128 | radio->buffer[5] = 0x00; | 128 | radio->buffer[5] = 0x00; |
129 | radio->buffer[6] = 0x00; | 129 | radio->buffer[6] = 0x00; |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index f1e3714b5f16..93d864eb8306 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -74,8 +74,8 @@ static u8 fmr2_tea575x_get_pins(struct snd_tea575x *tea) | |||
74 | struct fmr2 *fmr2 = tea->private_data; | 74 | struct fmr2 *fmr2 = tea->private_data; |
75 | u8 bits = inb(fmr2->io); | 75 | u8 bits = inb(fmr2->io); |
76 | 76 | ||
77 | return (bits & STR_DATA) ? TEA575X_DATA : 0 | | 77 | return ((bits & STR_DATA) ? TEA575X_DATA : 0) | |
78 | (bits & STR_MOST) ? TEA575X_MOST : 0; | 78 | ((bits & STR_MOST) ? TEA575X_MOST : 0); |
79 | } | 79 | } |
80 | 80 | ||
81 | static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output) | 81 | static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
@@ -295,7 +295,6 @@ static void fmr2_remove(struct fmr2 *fmr2) | |||
295 | static int fmr2_isa_remove(struct device *pdev, unsigned int ndev) | 295 | static int fmr2_isa_remove(struct device *pdev, unsigned int ndev) |
296 | { | 296 | { |
297 | fmr2_remove(dev_get_drvdata(pdev)); | 297 | fmr2_remove(dev_get_drvdata(pdev)); |
298 | dev_set_drvdata(pdev, NULL); | ||
299 | 298 | ||
300 | return 0; | 299 | return 0; |
301 | } | 300 | } |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 0bd250068285..0e750aef656a 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -254,7 +254,7 @@ static unsigned int si470x_get_step(struct si470x_device *radio) | |||
254 | /* 2: 50 kHz */ | 254 | /* 2: 50 kHz */ |
255 | default: | 255 | default: |
256 | return 50 * 16; | 256 | return 50 * 16; |
257 | }; | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | 260 | ||
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index fe160882ee10..9ec48ccbcf0b 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c | |||
@@ -1456,7 +1456,7 @@ static int si4713_probe(struct i2c_client *client, | |||
1456 | 1456 | ||
1457 | if (client->irq) { | 1457 | if (client->irq) { |
1458 | rval = request_irq(client->irq, | 1458 | rval = request_irq(client->irq, |
1459 | si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, | 1459 | si4713_handler, IRQF_TRIGGER_FALLING, |
1460 | client->name, sdev); | 1460 | client->name, sdev); |
1461 | if (rval < 0) { | 1461 | if (rval < 0) { |
1462 | v4l2_err(&sdev->sd, "Could not request IRQ\n"); | 1462 | v4l2_err(&sdev->sd, "Could not request IRQ\n"); |
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 253f307f0b37..4b2e9e8298e1 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c | |||
@@ -175,7 +175,7 @@ static int_handler_prototype int_handler_table[] = { | |||
175 | fm_irq_handle_intmsk_cmd_resp | 175 | fm_irq_handle_intmsk_cmd_resp |
176 | }; | 176 | }; |
177 | 177 | ||
178 | long (*g_st_write) (struct sk_buff *skb); | 178 | static long (*g_st_write) (struct sk_buff *skb); |
179 | static struct completion wait_for_fmdrv_reg_comp; | 179 | static struct completion wait_for_fmdrv_reg_comp; |
180 | 180 | ||
181 | static inline void fm_irq_call(struct fmdev *fmdev) | 181 | static inline void fm_irq_call(struct fmdev *fmdev) |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 11e84bcc23a1..904f11367c29 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -322,4 +322,14 @@ config IR_GPIO_CIR | |||
322 | To compile this driver as a module, choose M here: the module will | 322 | To compile this driver as a module, choose M here: the module will |
323 | be called gpio-ir-recv. | 323 | be called gpio-ir-recv. |
324 | 324 | ||
325 | config RC_ST | ||
326 | tristate "ST remote control receiver" | ||
327 | depends on ARCH_STI && RC_CORE | ||
328 | help | ||
329 | Say Y here if you want support for ST remote control driver | ||
330 | which allows both IR and UHF RX. | ||
331 | The driver passes raw pulse and space information to the LIRC decoder. | ||
332 | |||
333 | If you're not sure, select N here. | ||
334 | |||
325 | endif #RC_DEVICES | 335 | endif #RC_DEVICES |
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 56bacf07b361..f4eb32c0a455 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile | |||
@@ -30,3 +30,4 @@ obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o | |||
30 | obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o | 30 | obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o |
31 | obj-$(CONFIG_IR_IGUANA) += iguanair.o | 31 | obj-$(CONFIG_IR_IGUANA) += iguanair.o |
32 | obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o | 32 | obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o |
33 | obj-$(CONFIG_RC_ST) += st_rc.o | ||
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 07aacfa5903d..80c611c2e8c2 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/of.h> | ||
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c index 31b955bf7664..b1e19a26208d 100644 --- a/drivers/media/rc/ir-rx51.c +++ b/drivers/media/rc/ir-rx51.c | |||
@@ -201,8 +201,7 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51) | |||
201 | 201 | ||
202 | lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer); | 202 | lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer); |
203 | retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler, | 203 | retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler, |
204 | IRQF_DISABLED | IRQF_SHARED, | 204 | IRQF_SHARED, "lirc_pulse_timer", lirc_rx51); |
205 | "lirc_pulse_timer", lirc_rx51); | ||
206 | if (retval) { | 205 | if (retval) { |
207 | dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n"); | 206 | dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n"); |
208 | goto err2; | 207 | goto err2; |
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c new file mode 100644 index 000000000000..65120c2d47ad --- /dev/null +++ b/drivers/media/rc/st_rc.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 STMicroelectronics Limited | ||
3 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/clk.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <media/rc-core.h> | ||
17 | #include <linux/pinctrl/consumer.h> | ||
18 | |||
19 | struct st_rc_device { | ||
20 | struct device *dev; | ||
21 | int irq; | ||
22 | int irq_wake; | ||
23 | struct clk *sys_clock; | ||
24 | void *base; /* Register base address */ | ||
25 | void *rx_base;/* RX Register base address */ | ||
26 | struct rc_dev *rdev; | ||
27 | bool overclocking; | ||
28 | int sample_mult; | ||
29 | int sample_div; | ||
30 | bool rxuhfmode; | ||
31 | }; | ||
32 | |||
33 | /* Registers */ | ||
34 | #define IRB_SAMPLE_RATE_COMM 0x64 /* sample freq divisor*/ | ||
35 | #define IRB_CLOCK_SEL 0x70 /* clock select */ | ||
36 | #define IRB_CLOCK_SEL_STATUS 0x74 /* clock status */ | ||
37 | /* IRB IR/UHF receiver registers */ | ||
38 | #define IRB_RX_ON 0x40 /* pulse time capture */ | ||
39 | #define IRB_RX_SYS 0X44 /* sym period capture */ | ||
40 | #define IRB_RX_INT_EN 0x48 /* IRQ enable (R/W) */ | ||
41 | #define IRB_RX_INT_STATUS 0x4c /* IRQ status (R/W) */ | ||
42 | #define IRB_RX_EN 0x50 /* Receive enable */ | ||
43 | #define IRB_MAX_SYM_PERIOD 0x54 /* max sym value */ | ||
44 | #define IRB_RX_INT_CLEAR 0x58 /* overrun status */ | ||
45 | #define IRB_RX_STATUS 0x6c /* receive status */ | ||
46 | #define IRB_RX_NOISE_SUPPR 0x5c /* noise suppression */ | ||
47 | #define IRB_RX_POLARITY_INV 0x68 /* polarity inverter */ | ||
48 | |||
49 | /** | ||
50 | * IRQ set: Enable full FIFO 1 -> bit 3; | ||
51 | * Enable overrun IRQ 1 -> bit 2; | ||
52 | * Enable last symbol IRQ 1 -> bit 1: | ||
53 | * Enable RX interrupt 1 -> bit 0; | ||
54 | */ | ||
55 | #define IRB_RX_INTS 0x0f | ||
56 | #define IRB_RX_OVERRUN_INT 0x04 | ||
57 | /* maximum symbol period (microsecs),timeout to detect end of symbol train */ | ||
58 | #define MAX_SYMB_TIME 0x5000 | ||
59 | #define IRB_SAMPLE_FREQ 10000000 | ||
60 | #define IRB_FIFO_NOT_EMPTY 0xff00 | ||
61 | #define IRB_OVERFLOW 0x4 | ||
62 | #define IRB_TIMEOUT 0xffff | ||
63 | #define IR_ST_NAME "st-rc" | ||
64 | |||
65 | static void st_rc_send_lirc_timeout(struct rc_dev *rdev) | ||
66 | { | ||
67 | DEFINE_IR_RAW_EVENT(ev); | ||
68 | ev.timeout = true; | ||
69 | ir_raw_event_store(rdev, &ev); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * RX graphical example to better understand the difference between ST IR block | ||
74 | * output and standard definition used by LIRC (and most of the world!) | ||
75 | * | ||
76 | * mark mark | ||
77 | * |-IRB_RX_ON-| |-IRB_RX_ON-| | ||
78 | * ___ ___ ___ ___ ___ ___ _ | ||
79 | * | | | | | | | | | | | | | | ||
80 | * | | | | | | space 0 | | | | | | space 1 | | ||
81 | * _____| |__| |__| |____________________________| |__| |__| |_____________| | ||
82 | * | ||
83 | * |--------------- IRB_RX_SYS -------------|------ IRB_RX_SYS -------| | ||
84 | * | ||
85 | * |------------- encoding bit 0 -----------|---- encoding bit 1 -----| | ||
86 | * | ||
87 | * ST hardware returns mark (IRB_RX_ON) and total symbol time (IRB_RX_SYS), so | ||
88 | * convert to standard mark/space we have to calculate space=(IRB_RX_SYS-mark) | ||
89 | * The mark time represents the amount of time the carrier (usually 36-40kHz) | ||
90 | * is detected.The above examples shows Pulse Width Modulation encoding where | ||
91 | * bit 0 is represented by space>mark. | ||
92 | */ | ||
93 | |||
94 | static irqreturn_t st_rc_rx_interrupt(int irq, void *data) | ||
95 | { | ||
96 | unsigned int symbol, mark = 0; | ||
97 | struct st_rc_device *dev = data; | ||
98 | int last_symbol = 0; | ||
99 | u32 status; | ||
100 | DEFINE_IR_RAW_EVENT(ev); | ||
101 | |||
102 | if (dev->irq_wake) | ||
103 | pm_wakeup_event(dev->dev, 0); | ||
104 | |||
105 | status = readl(dev->rx_base + IRB_RX_STATUS); | ||
106 | |||
107 | while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) { | ||
108 | u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS); | ||
109 | if (unlikely(int_status & IRB_RX_OVERRUN_INT)) { | ||
110 | /* discard the entire collection in case of errors! */ | ||
111 | ir_raw_event_reset(dev->rdev); | ||
112 | dev_info(dev->dev, "IR RX overrun\n"); | ||
113 | writel(IRB_RX_OVERRUN_INT, | ||
114 | dev->rx_base + IRB_RX_INT_CLEAR); | ||
115 | continue; | ||
116 | } | ||
117 | |||
118 | symbol = readl(dev->rx_base + IRB_RX_SYS); | ||
119 | mark = readl(dev->rx_base + IRB_RX_ON); | ||
120 | |||
121 | if (symbol == IRB_TIMEOUT) | ||
122 | last_symbol = 1; | ||
123 | |||
124 | /* Ignore any noise */ | ||
125 | if ((mark > 2) && (symbol > 1)) { | ||
126 | symbol -= mark; | ||
127 | if (dev->overclocking) { /* adjustments to timings */ | ||
128 | symbol *= dev->sample_mult; | ||
129 | symbol /= dev->sample_div; | ||
130 | mark *= dev->sample_mult; | ||
131 | mark /= dev->sample_div; | ||
132 | } | ||
133 | |||
134 | ev.duration = US_TO_NS(mark); | ||
135 | ev.pulse = true; | ||
136 | ir_raw_event_store(dev->rdev, &ev); | ||
137 | |||
138 | if (!last_symbol) { | ||
139 | ev.duration = US_TO_NS(symbol); | ||
140 | ev.pulse = false; | ||
141 | ir_raw_event_store(dev->rdev, &ev); | ||
142 | } else { | ||
143 | st_rc_send_lirc_timeout(dev->rdev); | ||
144 | } | ||
145 | |||
146 | } | ||
147 | last_symbol = 0; | ||
148 | status = readl(dev->rx_base + IRB_RX_STATUS); | ||
149 | } | ||
150 | |||
151 | writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR); | ||
152 | |||
153 | /* Empty software fifo */ | ||
154 | ir_raw_event_handle(dev->rdev); | ||
155 | return IRQ_HANDLED; | ||
156 | } | ||
157 | |||
158 | static void st_rc_hardware_init(struct st_rc_device *dev) | ||
159 | { | ||
160 | int baseclock, freqdiff; | ||
161 | unsigned int rx_max_symbol_per = MAX_SYMB_TIME; | ||
162 | unsigned int rx_sampling_freq_div; | ||
163 | |||
164 | clk_prepare_enable(dev->sys_clock); | ||
165 | baseclock = clk_get_rate(dev->sys_clock); | ||
166 | |||
167 | /* IRB input pins are inverted internally from high to low. */ | ||
168 | writel(1, dev->rx_base + IRB_RX_POLARITY_INV); | ||
169 | |||
170 | rx_sampling_freq_div = baseclock / IRB_SAMPLE_FREQ; | ||
171 | writel(rx_sampling_freq_div, dev->base + IRB_SAMPLE_RATE_COMM); | ||
172 | |||
173 | freqdiff = baseclock - (rx_sampling_freq_div * IRB_SAMPLE_FREQ); | ||
174 | if (freqdiff) { /* over clocking, workout the adjustment factors */ | ||
175 | dev->overclocking = true; | ||
176 | dev->sample_mult = 1000; | ||
177 | dev->sample_div = baseclock / (10000 * rx_sampling_freq_div); | ||
178 | rx_max_symbol_per = (rx_max_symbol_per * 1000)/dev->sample_div; | ||
179 | } | ||
180 | |||
181 | writel(rx_max_symbol_per, dev->rx_base + IRB_MAX_SYM_PERIOD); | ||
182 | } | ||
183 | |||
184 | static int st_rc_remove(struct platform_device *pdev) | ||
185 | { | ||
186 | struct st_rc_device *rc_dev = platform_get_drvdata(pdev); | ||
187 | clk_disable_unprepare(rc_dev->sys_clock); | ||
188 | rc_unregister_device(rc_dev->rdev); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int st_rc_open(struct rc_dev *rdev) | ||
193 | { | ||
194 | struct st_rc_device *dev = rdev->priv; | ||
195 | unsigned long flags; | ||
196 | local_irq_save(flags); | ||
197 | /* enable interrupts and receiver */ | ||
198 | writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_EN); | ||
199 | writel(0x01, dev->rx_base + IRB_RX_EN); | ||
200 | local_irq_restore(flags); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static void st_rc_close(struct rc_dev *rdev) | ||
206 | { | ||
207 | struct st_rc_device *dev = rdev->priv; | ||
208 | /* disable interrupts and receiver */ | ||
209 | writel(0x00, dev->rx_base + IRB_RX_EN); | ||
210 | writel(0x00, dev->rx_base + IRB_RX_INT_EN); | ||
211 | } | ||
212 | |||
213 | static int st_rc_probe(struct platform_device *pdev) | ||
214 | { | ||
215 | int ret = -EINVAL; | ||
216 | struct rc_dev *rdev; | ||
217 | struct device *dev = &pdev->dev; | ||
218 | struct resource *res; | ||
219 | struct st_rc_device *rc_dev; | ||
220 | struct device_node *np = pdev->dev.of_node; | ||
221 | const char *rx_mode; | ||
222 | |||
223 | rc_dev = devm_kzalloc(dev, sizeof(struct st_rc_device), GFP_KERNEL); | ||
224 | |||
225 | if (!rc_dev) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | rdev = rc_allocate_device(); | ||
229 | |||
230 | if (!rdev) | ||
231 | return -ENOMEM; | ||
232 | |||
233 | if (np && !of_property_read_string(np, "rx-mode", &rx_mode)) { | ||
234 | |||
235 | if (!strcmp(rx_mode, "uhf")) { | ||
236 | rc_dev->rxuhfmode = true; | ||
237 | } else if (!strcmp(rx_mode, "infrared")) { | ||
238 | rc_dev->rxuhfmode = false; | ||
239 | } else { | ||
240 | dev_err(dev, "Unsupported rx mode [%s]\n", rx_mode); | ||
241 | goto err; | ||
242 | } | ||
243 | |||
244 | } else { | ||
245 | goto err; | ||
246 | } | ||
247 | |||
248 | rc_dev->sys_clock = devm_clk_get(dev, NULL); | ||
249 | if (IS_ERR(rc_dev->sys_clock)) { | ||
250 | dev_err(dev, "System clock not found\n"); | ||
251 | ret = PTR_ERR(rc_dev->sys_clock); | ||
252 | goto err; | ||
253 | } | ||
254 | |||
255 | rc_dev->irq = platform_get_irq(pdev, 0); | ||
256 | if (rc_dev->irq < 0) { | ||
257 | ret = rc_dev->irq; | ||
258 | goto err; | ||
259 | } | ||
260 | |||
261 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
262 | |||
263 | rc_dev->base = devm_ioremap_resource(dev, res); | ||
264 | if (IS_ERR(rc_dev->base)) { | ||
265 | ret = PTR_ERR(rc_dev->base); | ||
266 | goto err; | ||
267 | } | ||
268 | |||
269 | if (rc_dev->rxuhfmode) | ||
270 | rc_dev->rx_base = rc_dev->base + 0x40; | ||
271 | else | ||
272 | rc_dev->rx_base = rc_dev->base; | ||
273 | |||
274 | rc_dev->dev = dev; | ||
275 | platform_set_drvdata(pdev, rc_dev); | ||
276 | st_rc_hardware_init(rc_dev); | ||
277 | |||
278 | rdev->driver_type = RC_DRIVER_IR_RAW; | ||
279 | rdev->allowed_protos = RC_BIT_ALL; | ||
280 | /* rx sampling rate is 10Mhz */ | ||
281 | rdev->rx_resolution = 100; | ||
282 | rdev->timeout = US_TO_NS(MAX_SYMB_TIME); | ||
283 | rdev->priv = rc_dev; | ||
284 | rdev->open = st_rc_open; | ||
285 | rdev->close = st_rc_close; | ||
286 | rdev->driver_name = IR_ST_NAME; | ||
287 | rdev->map_name = RC_MAP_LIRC; | ||
288 | rdev->input_name = "ST Remote Control Receiver"; | ||
289 | |||
290 | /* enable wake via this device */ | ||
291 | device_set_wakeup_capable(dev, true); | ||
292 | device_set_wakeup_enable(dev, true); | ||
293 | |||
294 | ret = rc_register_device(rdev); | ||
295 | if (ret < 0) | ||
296 | goto clkerr; | ||
297 | |||
298 | rc_dev->rdev = rdev; | ||
299 | if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt, | ||
300 | IRQF_NO_SUSPEND, IR_ST_NAME, rc_dev) < 0) { | ||
301 | dev_err(dev, "IRQ %d register failed\n", rc_dev->irq); | ||
302 | ret = -EINVAL; | ||
303 | goto rcerr; | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW | ||
308 | * lircd expects a long space first before a signal train to sync. | ||
309 | */ | ||
310 | st_rc_send_lirc_timeout(rdev); | ||
311 | |||
312 | dev_info(dev, "setup in %s mode\n", rc_dev->rxuhfmode ? "UHF" : "IR"); | ||
313 | |||
314 | return ret; | ||
315 | rcerr: | ||
316 | rc_unregister_device(rdev); | ||
317 | rdev = NULL; | ||
318 | clkerr: | ||
319 | clk_disable_unprepare(rc_dev->sys_clock); | ||
320 | err: | ||
321 | rc_free_device(rdev); | ||
322 | dev_err(dev, "Unable to register device (%d)\n", ret); | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | #ifdef CONFIG_PM | ||
327 | static int st_rc_suspend(struct device *dev) | ||
328 | { | ||
329 | struct st_rc_device *rc_dev = dev_get_drvdata(dev); | ||
330 | |||
331 | if (device_may_wakeup(dev)) { | ||
332 | if (!enable_irq_wake(rc_dev->irq)) | ||
333 | rc_dev->irq_wake = 1; | ||
334 | else | ||
335 | return -EINVAL; | ||
336 | } else { | ||
337 | pinctrl_pm_select_sleep_state(dev); | ||
338 | writel(0x00, rc_dev->rx_base + IRB_RX_EN); | ||
339 | writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN); | ||
340 | clk_disable_unprepare(rc_dev->sys_clock); | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int st_rc_resume(struct device *dev) | ||
347 | { | ||
348 | struct st_rc_device *rc_dev = dev_get_drvdata(dev); | ||
349 | struct rc_dev *rdev = rc_dev->rdev; | ||
350 | |||
351 | if (rc_dev->irq_wake) { | ||
352 | disable_irq_wake(rc_dev->irq); | ||
353 | rc_dev->irq_wake = 0; | ||
354 | } else { | ||
355 | pinctrl_pm_select_default_state(dev); | ||
356 | st_rc_hardware_init(rc_dev); | ||
357 | if (rdev->users) { | ||
358 | writel(IRB_RX_INTS, rc_dev->rx_base + IRB_RX_INT_EN); | ||
359 | writel(0x01, rc_dev->rx_base + IRB_RX_EN); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static SIMPLE_DEV_PM_OPS(st_rc_pm_ops, st_rc_suspend, st_rc_resume); | ||
367 | #endif | ||
368 | |||
369 | #ifdef CONFIG_OF | ||
370 | static struct of_device_id st_rc_match[] = { | ||
371 | { .compatible = "st,comms-irb", }, | ||
372 | {}, | ||
373 | }; | ||
374 | |||
375 | MODULE_DEVICE_TABLE(of, st_rc_match); | ||
376 | #endif | ||
377 | |||
378 | static struct platform_driver st_rc_driver = { | ||
379 | .driver = { | ||
380 | .name = IR_ST_NAME, | ||
381 | .owner = THIS_MODULE, | ||
382 | .of_match_table = of_match_ptr(st_rc_match), | ||
383 | #ifdef CONFIG_PM | ||
384 | .pm = &st_rc_pm_ops, | ||
385 | #endif | ||
386 | }, | ||
387 | .probe = st_rc_probe, | ||
388 | .remove = st_rc_remove, | ||
389 | }; | ||
390 | |||
391 | module_platform_driver(st_rc_driver); | ||
392 | |||
393 | MODULE_DESCRIPTION("RC Transceiver driver for STMicroelectronics platforms"); | ||
394 | MODULE_AUTHOR("STMicroelectronics (R&D) Ltd"); | ||
395 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 98bd4960c75e..904baf4eec28 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c | |||
@@ -1110,7 +1110,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) | |||
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | err = request_irq(data->irq, wbcir_irq_handler, | 1112 | err = request_irq(data->irq, wbcir_irq_handler, |
1113 | IRQF_DISABLED, DRVNAME, device); | 1113 | 0, DRVNAME, device); |
1114 | if (err) { | 1114 | if (err) { |
1115 | dev_err(dev, "Failed to claim IRQ %u\n", data->irq); | 1115 | dev_err(dev, "Failed to claim IRQ %u\n", data->irq); |
1116 | err = -EBUSY; | 1116 | err = -EBUSY; |
diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index f4d0e797a6cc..d74e92056810 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c | |||
@@ -139,7 +139,7 @@ static int fc0012_set_params(struct dvb_frontend *fe) | |||
139 | unsigned char reg[7], am, pm, multi, tmp; | 139 | unsigned char reg[7], am, pm, multi, tmp; |
140 | unsigned long f_vco; | 140 | unsigned long f_vco; |
141 | unsigned short xtal_freq_khz_2, xin, xdiv; | 141 | unsigned short xtal_freq_khz_2, xin, xdiv; |
142 | int vco_select = false; | 142 | bool vco_select = false; |
143 | 143 | ||
144 | if (fe->callback) { | 144 | if (fe->callback) { |
145 | ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, | 145 | ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, |
diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index bd8f0f1e8f3b..b4162315773d 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c | |||
@@ -233,7 +233,7 @@ static int fc0013_set_params(struct dvb_frontend *fe) | |||
233 | unsigned char reg[7], am, pm, multi, tmp; | 233 | unsigned char reg[7], am, pm, multi, tmp; |
234 | unsigned long f_vco; | 234 | unsigned long f_vco; |
235 | unsigned short xtal_freq_khz_2, xin, xdiv; | 235 | unsigned short xtal_freq_khz_2, xin, xdiv; |
236 | int vco_select = false; | 236 | bool vco_select = false; |
237 | 237 | ||
238 | if (fe->callback) { | 238 | if (fe->callback) { |
239 | ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, | 239 | ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, |
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index 1c23666468cf..d9ee43fae62d 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c | |||
@@ -612,10 +612,19 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type, | |||
612 | 612 | ||
613 | vco_fine_tune = (data[4] & 0x30) >> 4; | 613 | vco_fine_tune = (data[4] & 0x30) >> 4; |
614 | 614 | ||
615 | if (vco_fine_tune > VCO_POWER_REF) | 615 | tuner_dbg("mix_div=%d div_num=%d vco_fine_tune=%d\n", |
616 | div_num = div_num - 1; | 616 | mix_div, div_num, vco_fine_tune); |
617 | else if (vco_fine_tune < VCO_POWER_REF) | 617 | |
618 | div_num = div_num + 1; | 618 | /* |
619 | * XXX: R828D/16MHz seems to have always vco_fine_tune=1. | ||
620 | * Due to that, this calculation goes wrong. | ||
621 | */ | ||
622 | if (priv->cfg->rafael_chip != CHIP_R828D) { | ||
623 | if (vco_fine_tune > VCO_POWER_REF) | ||
624 | div_num = div_num - 1; | ||
625 | else if (vco_fine_tune < VCO_POWER_REF) | ||
626 | div_num = div_num + 1; | ||
627 | } | ||
619 | 628 | ||
620 | rc = r820t_write_reg_mask(priv, 0x10, div_num << 5, 0xe0); | 629 | rc = r820t_write_reg_mask(priv, 0x10, div_num << 5, 0xe0); |
621 | if (rc < 0) | 630 | if (rc < 0) |
@@ -637,11 +646,6 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type, | |||
637 | vco_fra = pll_ref * 129 / 128; | 646 | vco_fra = pll_ref * 129 / 128; |
638 | } | 647 | } |
639 | 648 | ||
640 | if (nint > 63) { | ||
641 | tuner_info("No valid PLL values for %u kHz!\n", freq); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | |||
645 | ni = (nint - 13) / 4; | 649 | ni = (nint - 13) / 4; |
646 | si = nint - 4 * ni - 13; | 650 | si = nint - 4 * ni - 13; |
647 | 651 | ||
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 878d2c4d9e8e..e287a7417319 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c | |||
@@ -572,7 +572,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, | |||
572 | return -EINVAL; | 572 | return -EINVAL; |
573 | } | 573 | } |
574 | 574 | ||
575 | size = le16_to_cpu(*(__u16 *) p); | 575 | size = le16_to_cpu(*(__le16 *) p); |
576 | p += sizeof(size); | 576 | p += sizeof(size); |
577 | 577 | ||
578 | if (size == 0xffff) | 578 | if (size == 0xffff) |
@@ -683,7 +683,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, | |||
683 | /* 16 SCODE entries per file; each SCODE entry is 12 bytes and | 683 | /* 16 SCODE entries per file; each SCODE entry is 12 bytes and |
684 | * has a 2-byte size header in the firmware format. */ | 684 | * has a 2-byte size header in the firmware format. */ |
685 | if (priv->firm[pos].size != 14 * 16 || scode >= 16 || | 685 | if (priv->firm[pos].size != 14 * 16 || scode >= 16 || |
686 | le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12) | 686 | le16_to_cpu(*(__le16 *)(p + 14 * scode)) != 12) |
687 | return -EINVAL; | 687 | return -EINVAL; |
688 | p += 14 * scode + 2; | 688 | p += 14 * scode + 2; |
689 | } | 689 | } |
diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c index 8b6275f85908..0bd969063392 100644 --- a/drivers/media/usb/b2c2/flexcop-usb.c +++ b/drivers/media/usb/b2c2/flexcop-usb.c | |||
@@ -390,7 +390,7 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) | |||
390 | } | 390 | } |
391 | 391 | ||
392 | if (fc_usb->iso_buffer != NULL) | 392 | if (fc_usb->iso_buffer != NULL) |
393 | pci_free_consistent(NULL, | 393 | usb_free_coherent(fc_usb->udev, |
394 | fc_usb->buffer_size, fc_usb->iso_buffer, | 394 | fc_usb->buffer_size, fc_usb->iso_buffer, |
395 | fc_usb->dma_addr); | 395 | fc_usb->dma_addr); |
396 | } | 396 | } |
@@ -407,8 +407,8 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | |||
407 | "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, | 407 | "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, |
408 | B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); | 408 | B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); |
409 | 409 | ||
410 | fc_usb->iso_buffer = pci_alloc_consistent(NULL, | 410 | fc_usb->iso_buffer = usb_alloc_coherent(fc_usb->udev, |
411 | bufsize, &fc_usb->dma_addr); | 411 | bufsize, GFP_KERNEL, &fc_usb->dma_addr); |
412 | if (fc_usb->iso_buffer == NULL) | 412 | if (fc_usb->iso_buffer == NULL) |
413 | return -ENOMEM; | 413 | return -ENOMEM; |
414 | 414 | ||
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index be1719283609..351a78a84c3d 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c | |||
@@ -209,7 +209,7 @@ static void cpia2_usb_complete(struct urb *urb) | |||
209 | { | 209 | { |
210 | int i; | 210 | int i; |
211 | unsigned char *cdata; | 211 | unsigned char *cdata; |
212 | static int frame_ready = false; | 212 | static bool frame_ready = false; |
213 | struct camera_data *cam = (struct camera_data *) urb->context; | 213 | struct camera_data *cam = (struct camera_data *) urb->context; |
214 | 214 | ||
215 | if (urb->status!=0) { | 215 | if (urb->status!=0) { |
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index a384f80f595e..e9d017bea377 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
@@ -978,7 +978,6 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
978 | int minor) | 978 | int minor) |
979 | { | 979 | { |
980 | int retval = -ENOMEM; | 980 | int retval = -ENOMEM; |
981 | int errCode; | ||
982 | unsigned int maxh, maxw; | 981 | unsigned int maxh, maxw; |
983 | 982 | ||
984 | dev->udev = udev; | 983 | dev->udev = udev; |
@@ -1014,8 +1013,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1014 | /* Cx231xx pre card setup */ | 1013 | /* Cx231xx pre card setup */ |
1015 | cx231xx_pre_card_setup(dev); | 1014 | cx231xx_pre_card_setup(dev); |
1016 | 1015 | ||
1017 | errCode = cx231xx_config(dev); | 1016 | retval = cx231xx_config(dev); |
1018 | if (errCode) { | 1017 | if (retval) { |
1019 | cx231xx_errdev("error configuring device\n"); | 1018 | cx231xx_errdev("error configuring device\n"); |
1020 | return -ENOMEM; | 1019 | return -ENOMEM; |
1021 | } | 1020 | } |
@@ -1024,12 +1023,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1024 | dev->norm = dev->board.norm; | 1023 | dev->norm = dev->board.norm; |
1025 | 1024 | ||
1026 | /* register i2c bus */ | 1025 | /* register i2c bus */ |
1027 | errCode = cx231xx_dev_init(dev); | 1026 | retval = cx231xx_dev_init(dev); |
1028 | if (errCode < 0) { | 1027 | if (retval) { |
1029 | cx231xx_dev_uninit(dev); | ||
1030 | cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", | 1028 | cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", |
1031 | __func__, errCode); | 1029 | __func__, retval); |
1032 | return errCode; | 1030 | goto err_dev_init; |
1033 | } | 1031 | } |
1034 | 1032 | ||
1035 | /* Do board specific init */ | 1033 | /* Do board specific init */ |
@@ -1047,11 +1045,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1047 | dev->interlaced = 0; | 1045 | dev->interlaced = 0; |
1048 | dev->video_input = 0; | 1046 | dev->video_input = 0; |
1049 | 1047 | ||
1050 | errCode = cx231xx_config(dev); | 1048 | retval = cx231xx_config(dev); |
1051 | if (errCode < 0) { | 1049 | if (retval) { |
1052 | cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", | 1050 | cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", |
1053 | __func__, errCode); | 1051 | __func__, retval); |
1054 | return errCode; | 1052 | goto err_dev_init; |
1055 | } | 1053 | } |
1056 | 1054 | ||
1057 | /* init video dma queues */ | 1055 | /* init video dma queues */ |
@@ -1075,9 +1073,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1075 | } | 1073 | } |
1076 | 1074 | ||
1077 | retval = cx231xx_register_analog_devices(dev); | 1075 | retval = cx231xx_register_analog_devices(dev); |
1078 | if (retval < 0) { | 1076 | if (retval) { |
1079 | cx231xx_release_resources(dev); | 1077 | cx231xx_release_analog_resources(dev); |
1080 | return retval; | 1078 | goto err_analog; |
1081 | } | 1079 | } |
1082 | 1080 | ||
1083 | cx231xx_ir_init(dev); | 1081 | cx231xx_ir_init(dev); |
@@ -1085,6 +1083,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1085 | cx231xx_init_extension(dev); | 1083 | cx231xx_init_extension(dev); |
1086 | 1084 | ||
1087 | return 0; | 1085 | return 0; |
1086 | err_analog: | ||
1087 | cx231xx_remove_from_devlist(dev); | ||
1088 | err_dev_init: | ||
1089 | cx231xx_dev_uninit(dev); | ||
1090 | return retval; | ||
1088 | } | 1091 | } |
1089 | 1092 | ||
1090 | #if defined(CONFIG_MODULES) && defined(MODULE) | 1093 | #if defined(CONFIG_MODULES) && defined(MODULE) |
@@ -1132,7 +1135,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1132 | char *speed; | 1135 | char *speed; |
1133 | struct usb_interface_assoc_descriptor *assoc_desc; | 1136 | struct usb_interface_assoc_descriptor *assoc_desc; |
1134 | 1137 | ||
1135 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
1136 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | 1138 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; |
1137 | 1139 | ||
1138 | /* | 1140 | /* |
@@ -1161,6 +1163,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1161 | return -ENOMEM; | 1163 | return -ENOMEM; |
1162 | } | 1164 | } |
1163 | 1165 | ||
1166 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
1167 | |||
1164 | snprintf(dev->name, 29, "cx231xx #%d", nr); | 1168 | snprintf(dev->name, 29, "cx231xx #%d", nr); |
1165 | dev->devno = nr; | 1169 | dev->devno = nr; |
1166 | dev->model = id->driver_info; | 1170 | dev->model = id->driver_info; |
@@ -1223,10 +1227,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1223 | if (assoc_desc->bFirstInterface != ifnum) { | 1227 | if (assoc_desc->bFirstInterface != ifnum) { |
1224 | cx231xx_err(DRIVER_NAME ": Not found " | 1228 | cx231xx_err(DRIVER_NAME ": Not found " |
1225 | "matching IAD interface\n"); | 1229 | "matching IAD interface\n"); |
1226 | clear_bit(dev->devno, &cx231xx_devused); | 1230 | retval = -ENODEV; |
1227 | kfree(dev); | 1231 | goto err_if; |
1228 | dev = NULL; | ||
1229 | return -ENODEV; | ||
1230 | } | 1232 | } |
1231 | 1233 | ||
1232 | cx231xx_info("registering interface %d\n", ifnum); | 1234 | cx231xx_info("registering interface %d\n", ifnum); |
@@ -1242,22 +1244,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1242 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | 1244 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); |
1243 | if (retval) { | 1245 | if (retval) { |
1244 | cx231xx_errdev("v4l2_device_register failed\n"); | 1246 | cx231xx_errdev("v4l2_device_register failed\n"); |
1245 | clear_bit(dev->devno, &cx231xx_devused); | 1247 | retval = -EIO; |
1246 | kfree(dev); | 1248 | goto err_v4l2; |
1247 | dev = NULL; | ||
1248 | return -EIO; | ||
1249 | } | 1249 | } |
1250 | /* allocate device struct */ | 1250 | /* allocate device struct */ |
1251 | retval = cx231xx_init_dev(dev, udev, nr); | 1251 | retval = cx231xx_init_dev(dev, udev, nr); |
1252 | if (retval) { | 1252 | if (retval) |
1253 | clear_bit(dev->devno, &cx231xx_devused); | 1253 | goto err_init; |
1254 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1255 | kfree(dev); | ||
1256 | dev = NULL; | ||
1257 | usb_set_intfdata(interface, NULL); | ||
1258 | |||
1259 | return retval; | ||
1260 | } | ||
1261 | 1254 | ||
1262 | /* compute alternate max packet sizes for video */ | 1255 | /* compute alternate max packet sizes for video */ |
1263 | uif = udev->actconfig->interface[dev->current_pcb_config. | 1256 | uif = udev->actconfig->interface[dev->current_pcb_config. |
@@ -1275,11 +1268,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1275 | 1268 | ||
1276 | if (dev->video_mode.alt_max_pkt_size == NULL) { | 1269 | if (dev->video_mode.alt_max_pkt_size == NULL) { |
1277 | cx231xx_errdev("out of memory!\n"); | 1270 | cx231xx_errdev("out of memory!\n"); |
1278 | clear_bit(dev->devno, &cx231xx_devused); | 1271 | retval = -ENOMEM; |
1279 | v4l2_device_unregister(&dev->v4l2_dev); | 1272 | goto err_video_alt; |
1280 | kfree(dev); | ||
1281 | dev = NULL; | ||
1282 | return -ENOMEM; | ||
1283 | } | 1273 | } |
1284 | 1274 | ||
1285 | for (i = 0; i < dev->video_mode.num_alt; i++) { | 1275 | for (i = 0; i < dev->video_mode.num_alt; i++) { |
@@ -1309,11 +1299,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1309 | 1299 | ||
1310 | if (dev->vbi_mode.alt_max_pkt_size == NULL) { | 1300 | if (dev->vbi_mode.alt_max_pkt_size == NULL) { |
1311 | cx231xx_errdev("out of memory!\n"); | 1301 | cx231xx_errdev("out of memory!\n"); |
1312 | clear_bit(dev->devno, &cx231xx_devused); | 1302 | retval = -ENOMEM; |
1313 | v4l2_device_unregister(&dev->v4l2_dev); | 1303 | goto err_vbi_alt; |
1314 | kfree(dev); | ||
1315 | dev = NULL; | ||
1316 | return -ENOMEM; | ||
1317 | } | 1304 | } |
1318 | 1305 | ||
1319 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { | 1306 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { |
@@ -1344,11 +1331,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1344 | 1331 | ||
1345 | if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { | 1332 | if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { |
1346 | cx231xx_errdev("out of memory!\n"); | 1333 | cx231xx_errdev("out of memory!\n"); |
1347 | clear_bit(dev->devno, &cx231xx_devused); | 1334 | retval = -ENOMEM; |
1348 | v4l2_device_unregister(&dev->v4l2_dev); | 1335 | goto err_sliced_cc_alt; |
1349 | kfree(dev); | ||
1350 | dev = NULL; | ||
1351 | return -ENOMEM; | ||
1352 | } | 1336 | } |
1353 | 1337 | ||
1354 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { | 1338 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { |
@@ -1380,11 +1364,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1380 | 1364 | ||
1381 | if (dev->ts1_mode.alt_max_pkt_size == NULL) { | 1365 | if (dev->ts1_mode.alt_max_pkt_size == NULL) { |
1382 | cx231xx_errdev("out of memory!\n"); | 1366 | cx231xx_errdev("out of memory!\n"); |
1383 | clear_bit(dev->devno, &cx231xx_devused); | 1367 | retval = -ENOMEM; |
1384 | v4l2_device_unregister(&dev->v4l2_dev); | 1368 | goto err_ts1_alt; |
1385 | kfree(dev); | ||
1386 | dev = NULL; | ||
1387 | return -ENOMEM; | ||
1388 | } | 1369 | } |
1389 | 1370 | ||
1390 | for (i = 0; i < dev->ts1_mode.num_alt; i++) { | 1371 | for (i = 0; i < dev->ts1_mode.num_alt; i++) { |
@@ -1411,6 +1392,29 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1411 | request_modules(dev); | 1392 | request_modules(dev); |
1412 | 1393 | ||
1413 | return 0; | 1394 | return 0; |
1395 | err_ts1_alt: | ||
1396 | kfree(dev->sliced_cc_mode.alt_max_pkt_size); | ||
1397 | err_sliced_cc_alt: | ||
1398 | kfree(dev->vbi_mode.alt_max_pkt_size); | ||
1399 | err_vbi_alt: | ||
1400 | kfree(dev->video_mode.alt_max_pkt_size); | ||
1401 | err_video_alt: | ||
1402 | /* cx231xx_uninit_dev: */ | ||
1403 | cx231xx_close_extension(dev); | ||
1404 | cx231xx_ir_exit(dev); | ||
1405 | cx231xx_release_analog_resources(dev); | ||
1406 | cx231xx_417_unregister(dev); | ||
1407 | cx231xx_remove_from_devlist(dev); | ||
1408 | cx231xx_dev_uninit(dev); | ||
1409 | err_init: | ||
1410 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1411 | err_v4l2: | ||
1412 | usb_set_intfdata(interface, NULL); | ||
1413 | err_if: | ||
1414 | usb_put_dev(udev); | ||
1415 | kfree(dev); | ||
1416 | clear_bit(dev->devno, &cx231xx_devused); | ||
1417 | return retval; | ||
1414 | } | 1418 | } |
1415 | 1419 | ||
1416 | /* | 1420 | /* |
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index d7308ab7a90f..2a34ceee4802 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | |||
@@ -28,7 +28,7 @@ MODULE_PARM_DESC(pcb_debug, "enable pcb config debug messages [video]"); | |||
28 | 28 | ||
29 | /******************************************************************************/ | 29 | /******************************************************************************/ |
30 | 30 | ||
31 | struct pcb_config cx231xx_Scenario[] = { | 31 | static struct pcb_config cx231xx_Scenario[] = { |
32 | { | 32 | { |
33 | INDEX_SELFPOWER_DIGITAL_ONLY, /* index */ | 33 | INDEX_SELFPOWER_DIGITAL_ONLY, /* index */ |
34 | USB_SELF_POWER, /* power_type */ | 34 | USB_SELF_POWER, /* power_type */ |
@@ -672,7 +672,7 @@ u32 initialize_cx231xx(struct cx231xx *dev) | |||
672 | pcb config it is related to */ | 672 | pcb config it is related to */ |
673 | cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4); | 673 | cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4); |
674 | 674 | ||
675 | config_info = le32_to_cpu(*((u32 *) data)); | 675 | config_info = le32_to_cpu(*((__le32 *)data)); |
676 | usb_speed = (u8) (config_info & 0x1); | 676 | usb_speed = (u8) (config_info & 0x1); |
677 | 677 | ||
678 | /* Verify this device belongs to Bus power or Self power device */ | 678 | /* Verify this device belongs to Bus power or Self power device */ |
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index c0cd0848631b..ecca03667f98 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -377,6 +377,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) | |||
377 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; | 377 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; |
378 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; | 378 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; |
379 | struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; | 379 | struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; |
380 | struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; | ||
380 | 381 | ||
381 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 382 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
382 | 383 | ||
@@ -489,6 +490,15 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) | |||
489 | goto found; | 490 | goto found; |
490 | } | 491 | } |
491 | 492 | ||
493 | /* check R828D ID register; reg=00 val=69 */ | ||
494 | ret = rtl28xxu_ctrl_msg(d, &req_r828d); | ||
495 | if (ret == 0 && buf[0] == 0x69) { | ||
496 | priv->tuner = TUNER_RTL2832_R828D; | ||
497 | priv->tuner_name = "R828D"; | ||
498 | goto found; | ||
499 | } | ||
500 | |||
501 | |||
492 | found: | 502 | found: |
493 | dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); | 503 | dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); |
494 | 504 | ||
@@ -745,6 +755,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) | |||
745 | rtl2832_config = &rtl28xxu_rtl2832_e4000_config; | 755 | rtl2832_config = &rtl28xxu_rtl2832_e4000_config; |
746 | break; | 756 | break; |
747 | case TUNER_RTL2832_R820T: | 757 | case TUNER_RTL2832_R820T: |
758 | case TUNER_RTL2832_R828D: | ||
748 | rtl2832_config = &rtl28xxu_rtl2832_r820t_config; | 759 | rtl2832_config = &rtl28xxu_rtl2832_r820t_config; |
749 | break; | 760 | break; |
750 | default: | 761 | default: |
@@ -866,6 +877,13 @@ static const struct r820t_config rtl2832u_r820t_config = { | |||
866 | .rafael_chip = CHIP_R820T, | 877 | .rafael_chip = CHIP_R820T, |
867 | }; | 878 | }; |
868 | 879 | ||
880 | static const struct r820t_config rtl2832u_r828d_config = { | ||
881 | .i2c_addr = 0x3a, | ||
882 | .xtal = 16000000, | ||
883 | .max_i2c_msg_len = 2, | ||
884 | .rafael_chip = CHIP_R828D, | ||
885 | }; | ||
886 | |||
869 | static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | 887 | static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) |
870 | { | 888 | { |
871 | int ret; | 889 | int ret; |
@@ -923,6 +941,27 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
923 | adap->fe[0]->ops.read_signal_strength = | 941 | adap->fe[0]->ops.read_signal_strength = |
924 | adap->fe[0]->ops.tuner_ops.get_rf_strength; | 942 | adap->fe[0]->ops.tuner_ops.get_rf_strength; |
925 | break; | 943 | break; |
944 | case TUNER_RTL2832_R828D: | ||
945 | /* power off mn88472 demod on GPIO0 */ | ||
946 | ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01); | ||
947 | if (ret) | ||
948 | goto err; | ||
949 | |||
950 | ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01); | ||
951 | if (ret) | ||
952 | goto err; | ||
953 | |||
954 | ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01); | ||
955 | if (ret) | ||
956 | goto err; | ||
957 | |||
958 | fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap, | ||
959 | &rtl2832u_r828d_config); | ||
960 | |||
961 | /* Use tuner to get the signal strength */ | ||
962 | adap->fe[0]->ops.read_signal_strength = | ||
963 | adap->fe[0]->ops.tuner_ops.get_rf_strength; | ||
964 | break; | ||
926 | default: | 965 | default: |
927 | fe = NULL; | 966 | fe = NULL; |
928 | dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, | 967 | dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, |
@@ -1388,6 +1427,9 @@ static const struct usb_device_id rtl28xxu_id_table[] = { | |||
1388 | &rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) }, | 1427 | &rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) }, |
1389 | { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A, | 1428 | { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A, |
1390 | &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) }, | 1429 | &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) }, |
1430 | |||
1431 | { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, | ||
1432 | &rtl2832u_props, "Astrometa DVB-T2", NULL) }, | ||
1391 | { } | 1433 | { } |
1392 | }; | 1434 | }; |
1393 | MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); | 1435 | MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); |
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index 729b3540c2f9..2142bcb41b41 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h | |||
@@ -83,6 +83,7 @@ enum rtl28xxu_tuner { | |||
83 | TUNER_RTL2832_TDA18272, | 83 | TUNER_RTL2832_TDA18272, |
84 | TUNER_RTL2832_FC0013, | 84 | TUNER_RTL2832_FC0013, |
85 | TUNER_RTL2832_R820T, | 85 | TUNER_RTL2832_R820T, |
86 | TUNER_RTL2832_R828D, | ||
86 | }; | 87 | }; |
87 | 88 | ||
88 | struct rtl28xxu_req { | 89 | struct rtl28xxu_req { |
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index ea2d5ee86576..c11138ebf6fb 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c | |||
@@ -254,7 +254,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { | |||
254 | 254 | ||
255 | 255 | ||
256 | 256 | ||
257 | struct stb0899_config az6027_stb0899_config = { | 257 | static struct stb0899_config az6027_stb0899_config = { |
258 | .init_dev = az6027_stb0899_s1_init_1, | 258 | .init_dev = az6027_stb0899_s1_init_1, |
259 | .init_s2_demod = stb0899_s2_init_2, | 259 | .init_s2_demod = stb0899_s2_init_2, |
260 | .init_s1_demod = az6027_stb0899_s1_init_3, | 260 | .init_s1_demod = az6027_stb0899_s1_init_3, |
@@ -291,7 +291,7 @@ struct stb0899_config az6027_stb0899_config = { | |||
291 | .tuner_set_rfsiggain = NULL, | 291 | .tuner_set_rfsiggain = NULL, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | struct stb6100_config az6027_stb6100_config = { | 294 | static struct stb6100_config az6027_stb6100_config = { |
295 | .tuner_address = 0xc0, | 295 | .tuner_address = 0xc0, |
296 | .refclock = 27000000, | 296 | .refclock = 27000000, |
297 | }; | 297 | }; |
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 6e237b6dd0a8..6136a2c7dbfd 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c | |||
@@ -955,9 +955,10 @@ static struct ds3000_config dw2104_ds3000_config = { | |||
955 | .demod_address = 0x68, | 955 | .demod_address = 0x68, |
956 | }; | 956 | }; |
957 | 957 | ||
958 | static struct ts2020_config dw2104_ts2020_config = { | 958 | static struct ts2020_config dw2104_ts2020_config = { |
959 | .tuner_address = 0x60, | 959 | .tuner_address = 0x60, |
960 | .clk_out_div = 1, | 960 | .clk_out_div = 1, |
961 | .frequency_div = 1060000, | ||
961 | }; | 962 | }; |
962 | 963 | ||
963 | static struct ds3000_config s660_ds3000_config = { | 964 | static struct ds3000_config s660_ds3000_config = { |
@@ -966,6 +967,12 @@ static struct ds3000_config s660_ds3000_config = { | |||
966 | .set_lock_led = dw210x_led_ctrl, | 967 | .set_lock_led = dw210x_led_ctrl, |
967 | }; | 968 | }; |
968 | 969 | ||
970 | static struct ts2020_config s660_ts2020_config = { | ||
971 | .tuner_address = 0x60, | ||
972 | .clk_out_div = 1, | ||
973 | .frequency_div = 1146000, | ||
974 | }; | ||
975 | |||
969 | static struct stv0900_config dw2104a_stv0900_config = { | 976 | static struct stv0900_config dw2104a_stv0900_config = { |
970 | .demod_address = 0x6a, | 977 | .demod_address = 0x6a, |
971 | .demod_mode = 0, | 978 | .demod_mode = 0, |
@@ -1205,7 +1212,7 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) | |||
1205 | if (d->fe_adap[0].fe == NULL) | 1212 | if (d->fe_adap[0].fe == NULL) |
1206 | return -EIO; | 1213 | return -EIO; |
1207 | 1214 | ||
1208 | dvb_attach(ts2020_attach, d->fe_adap[0].fe, &dw2104_ts2020_config, | 1215 | dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config, |
1209 | &d->dev->i2c_adap); | 1216 | &d->dev->i2c_adap); |
1210 | 1217 | ||
1211 | st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; | 1218 | st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; |
@@ -1213,7 +1220,7 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) | |||
1213 | 1220 | ||
1214 | dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | 1221 | dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); |
1215 | 1222 | ||
1216 | info("Attached ds3000+ds2020!\n"); | 1223 | info("Attached ds3000+ts2020!\n"); |
1217 | 1224 | ||
1218 | return 0; | 1225 | return 0; |
1219 | } | 1226 | } |
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 73cc50afa5e1..d666741797d4 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <media/soc_camera.h> | 23 | #include <media/soc_camera.h> |
24 | #include <media/mt9v011.h> | 24 | #include <media/mt9v011.h> |
25 | #include <media/v4l2-clk.h> | ||
25 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
26 | 27 | ||
27 | #include "em28xx.h" | 28 | #include "em28xx.h" |
@@ -47,6 +48,7 @@ static struct soc_camera_link camlink = { | |||
47 | .bus_id = 0, | 48 | .bus_id = 0, |
48 | .flags = 0, | 49 | .flags = 0, |
49 | .module_name = "em28xx", | 50 | .module_name = "em28xx", |
51 | .unbalanced_power = true, | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | 54 | ||
@@ -325,13 +327,24 @@ int em28xx_detect_sensor(struct em28xx *dev) | |||
325 | 327 | ||
326 | int em28xx_init_camera(struct em28xx *dev) | 328 | int em28xx_init_camera(struct em28xx *dev) |
327 | { | 329 | { |
330 | char clk_name[V4L2_SUBDEV_NAME_SIZE]; | ||
331 | struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; | ||
332 | struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; | ||
333 | int ret = 0; | ||
334 | |||
335 | v4l2_clk_name_i2c(clk_name, sizeof(clk_name), | ||
336 | i2c_adapter_id(adap), client->addr); | ||
337 | dev->clk = v4l2_clk_register_fixed(clk_name, "mclk", -EINVAL); | ||
338 | if (IS_ERR(dev->clk)) | ||
339 | return PTR_ERR(dev->clk); | ||
340 | |||
328 | switch (dev->em28xx_sensor) { | 341 | switch (dev->em28xx_sensor) { |
329 | case EM28XX_MT9V011: | 342 | case EM28XX_MT9V011: |
330 | { | 343 | { |
331 | struct mt9v011_platform_data pdata; | 344 | struct mt9v011_platform_data pdata; |
332 | struct i2c_board_info mt9v011_info = { | 345 | struct i2c_board_info mt9v011_info = { |
333 | .type = "mt9v011", | 346 | .type = "mt9v011", |
334 | .addr = dev->i2c_client[dev->def_i2c_bus].addr, | 347 | .addr = client->addr, |
335 | .platform_data = &pdata, | 348 | .platform_data = &pdata, |
336 | }; | 349 | }; |
337 | 350 | ||
@@ -352,10 +365,11 @@ int em28xx_init_camera(struct em28xx *dev) | |||
352 | dev->sensor_xtal = 4300000; | 365 | dev->sensor_xtal = 4300000; |
353 | pdata.xtal = dev->sensor_xtal; | 366 | pdata.xtal = dev->sensor_xtal; |
354 | if (NULL == | 367 | if (NULL == |
355 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, | 368 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap, |
356 | &dev->i2c_adap[dev->def_i2c_bus], | 369 | &mt9v011_info, NULL)) { |
357 | &mt9v011_info, NULL)) | 370 | ret = -ENODEV; |
358 | return -ENODEV; | 371 | break; |
372 | } | ||
359 | /* probably means GRGB 16 bit bayer */ | 373 | /* probably means GRGB 16 bit bayer */ |
360 | dev->vinmode = 0x0d; | 374 | dev->vinmode = 0x0d; |
361 | dev->vinctl = 0x00; | 375 | dev->vinctl = 0x00; |
@@ -391,7 +405,7 @@ int em28xx_init_camera(struct em28xx *dev) | |||
391 | struct i2c_board_info ov2640_info = { | 405 | struct i2c_board_info ov2640_info = { |
392 | .type = "ov2640", | 406 | .type = "ov2640", |
393 | .flags = I2C_CLIENT_SCCB, | 407 | .flags = I2C_CLIENT_SCCB, |
394 | .addr = dev->i2c_client[dev->def_i2c_bus].addr, | 408 | .addr = client->addr, |
395 | .platform_data = &camlink, | 409 | .platform_data = &camlink, |
396 | }; | 410 | }; |
397 | struct v4l2_mbus_framefmt fmt; | 411 | struct v4l2_mbus_framefmt fmt; |
@@ -408,9 +422,12 @@ int em28xx_init_camera(struct em28xx *dev) | |||
408 | dev->sensor_yres = 480; | 422 | dev->sensor_yres = 480; |
409 | 423 | ||
410 | subdev = | 424 | subdev = |
411 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, | 425 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap, |
412 | &dev->i2c_adap[dev->def_i2c_bus], | ||
413 | &ov2640_info, NULL); | 426 | &ov2640_info, NULL); |
427 | if (NULL == subdev) { | ||
428 | ret = -ENODEV; | ||
429 | break; | ||
430 | } | ||
414 | 431 | ||
415 | fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; | 432 | fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; |
416 | fmt.width = 640; | 433 | fmt.width = 640; |
@@ -427,8 +444,13 @@ int em28xx_init_camera(struct em28xx *dev) | |||
427 | } | 444 | } |
428 | case EM28XX_NOSENSOR: | 445 | case EM28XX_NOSENSOR: |
429 | default: | 446 | default: |
430 | return -EINVAL; | 447 | ret = -EINVAL; |
431 | } | 448 | } |
432 | 449 | ||
433 | return 0; | 450 | if (ret < 0) { |
451 | v4l2_clk_unregister_fixed(dev->clk); | ||
452 | dev->clk = NULL; | ||
453 | } | ||
454 | |||
455 | return ret; | ||
434 | } | 456 | } |
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index dc65742c4bbc..a5196697627f 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <media/tvaudio.h> | 36 | #include <media/tvaudio.h> |
37 | #include <media/i2c-addr.h> | 37 | #include <media/i2c-addr.h> |
38 | #include <media/tveeprom.h> | 38 | #include <media/tveeprom.h> |
39 | #include <media/v4l2-clk.h> | ||
39 | #include <media/v4l2-common.h> | 40 | #include <media/v4l2-common.h> |
40 | 41 | ||
41 | #include "em28xx.h" | 42 | #include "em28xx.h" |
@@ -95,8 +96,8 @@ static struct em28xx_reg_seq default_digital[] = { | |||
95 | /* Board Hauppauge WinTV HVR 900 analog */ | 96 | /* Board Hauppauge WinTV HVR 900 analog */ |
96 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | 97 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { |
97 | {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10}, | 98 | {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10}, |
98 | {0x05, 0xff, 0x10, 10}, | 99 | { 0x05, 0xff, 0x10, 10}, |
99 | { -1, -1, -1, -1}, | 100 | { -1, -1, -1, -1}, |
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* Board Hauppauge WinTV HVR 900 digital */ | 103 | /* Board Hauppauge WinTV HVR 900 digital */ |
@@ -104,20 +105,20 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | |||
104 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, | 105 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, |
105 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | 106 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, |
106 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | 107 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, |
107 | { -1, -1, -1, -1}, | 108 | { -1, -1, -1, -1}, |
108 | }; | 109 | }; |
109 | 110 | ||
110 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ | 111 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ |
111 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { | 112 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { |
112 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, | 113 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, |
113 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | 114 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, |
114 | { -1, -1, -1, -1}, | 115 | { -1, -1, -1, -1}, |
115 | }; | 116 | }; |
116 | 117 | ||
117 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | 118 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ |
118 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | 119 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { |
119 | {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10}, | 120 | {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10}, |
120 | { -1, -1, -1, -1}, | 121 | { -1, -1, -1, -1}, |
121 | }; | 122 | }; |
122 | 123 | ||
123 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | 124 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ |
@@ -132,7 +133,7 @@ static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | |||
132 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | 133 | {EM2880_R04_GPO, 0x04, 0xff, 10}, |
133 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | 134 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, |
134 | {EM2820_R08_GPIO_CTRL, 0x7e, 0xff, 10}, | 135 | {EM2820_R08_GPIO_CTRL, 0x7e, 0xff, 10}, |
135 | { -1, -1, -1, -1}, | 136 | { -1, -1, -1, -1}, |
136 | }; | 137 | }; |
137 | 138 | ||
138 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | 139 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { |
@@ -140,19 +141,19 @@ static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | |||
140 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | 141 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, |
141 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 142 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
142 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | 143 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, |
143 | { -1, -1, -1, -1}, | 144 | { -1, -1, -1, -1}, |
144 | }; | 145 | }; |
145 | 146 | ||
146 | static struct em28xx_reg_seq kworld_330u_analog[] = { | 147 | static struct em28xx_reg_seq kworld_330u_analog[] = { |
147 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 148 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
148 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 149 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
149 | { -1, -1, -1, -1}, | 150 | { -1, -1, -1, -1}, |
150 | }; | 151 | }; |
151 | 152 | ||
152 | static struct em28xx_reg_seq kworld_330u_digital[] = { | 153 | static struct em28xx_reg_seq kworld_330u_digital[] = { |
153 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 154 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
154 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 155 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
155 | { -1, -1, -1, -1}, | 156 | { -1, -1, -1, -1}, |
156 | }; | 157 | }; |
157 | 158 | ||
158 | /* Evga inDtube | 159 | /* Evga inDtube |
@@ -170,11 +171,11 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { | |||
170 | {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1}, | 171 | {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1}, |
171 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | 172 | {EM2880_R04_GPO, 0x04, 0xff, 10}, |
172 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | 173 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, |
173 | { -1, -1, -1, -1}, | 174 | { -1, -1, -1, -1}, |
174 | }; | 175 | }; |
175 | 176 | ||
176 | /* | 177 | /* |
177 | * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map: | 178 | * KWorld PlusTV 340U, UB435-Q and UB435-Q V2 (ATSC) GPIOs map: |
178 | * EM_GPIO_0 - currently unknown | 179 | * EM_GPIO_0 - currently unknown |
179 | * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on) | 180 | * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on) |
180 | * EM_GPIO_2 - currently unknown | 181 | * EM_GPIO_2 - currently unknown |
@@ -185,8 +186,8 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { | |||
185 | * EM_GPIO_7 - currently unknown | 186 | * EM_GPIO_7 - currently unknown |
186 | */ | 187 | */ |
187 | static struct em28xx_reg_seq kworld_a340_digital[] = { | 188 | static struct em28xx_reg_seq kworld_a340_digital[] = { |
188 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 189 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
189 | { -1, -1, -1, -1}, | 190 | { -1, -1, -1, -1}, |
190 | }; | 191 | }; |
191 | 192 | ||
192 | /* Pinnacle Hybrid Pro eb1a:2881 */ | 193 | /* Pinnacle Hybrid Pro eb1a:2881 */ |
@@ -205,13 +206,13 @@ static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | |||
205 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { | 206 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { |
206 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 207 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
207 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 208 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
208 | { -1, -1, -1, -1}, | 209 | { -1, -1, -1, -1}, |
209 | }; | 210 | }; |
210 | 211 | ||
211 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { | 212 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { |
212 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 213 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
213 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 214 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
214 | { -1, -1, -1, -1}, | 215 | { -1, -1, -1, -1}, |
215 | }; | 216 | }; |
216 | 217 | ||
217 | /* eb1a:2868 Reddo DVB-C USB TV Box | 218 | /* eb1a:2868 Reddo DVB-C USB TV Box |
@@ -225,7 +226,7 @@ static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | |||
225 | {EM2820_R08_GPIO_CTRL, 0x7f, 0xff, 10}, | 226 | {EM2820_R08_GPIO_CTRL, 0x7f, 0xff, 10}, |
226 | {EM2820_R08_GPIO_CTRL, 0x6f, 0xff, 10}, | 227 | {EM2820_R08_GPIO_CTRL, 0x6f, 0xff, 10}, |
227 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, | 228 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, |
228 | {-1, -1, -1, -1}, | 229 | { -1, -1, -1, -1}, |
229 | }; | 230 | }; |
230 | 231 | ||
231 | /* Callback for the most boards */ | 232 | /* Callback for the most boards */ |
@@ -233,23 +234,23 @@ static struct em28xx_reg_seq default_tuner_gpio[] = { | |||
233 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, | 234 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, |
234 | {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10}, | 235 | {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10}, |
235 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, | 236 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, |
236 | { -1, -1, -1, -1}, | 237 | { -1, -1, -1, -1}, |
237 | }; | 238 | }; |
238 | 239 | ||
239 | /* Mute/unmute */ | 240 | /* Mute/unmute */ |
240 | static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { | 241 | static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { |
241 | {EM2820_R08_GPIO_CTRL, 5, 7, 10}, | 242 | {EM2820_R08_GPIO_CTRL, 5, 7, 10}, |
242 | { -1, -1, -1, -1}, | 243 | { -1, -1, -1, -1}, |
243 | }; | 244 | }; |
244 | 245 | ||
245 | static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { | 246 | static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { |
246 | {EM2820_R08_GPIO_CTRL, 4, 7, 10}, | 247 | {EM2820_R08_GPIO_CTRL, 4, 7, 10}, |
247 | { -1, -1, -1, -1}, | 248 | { -1, -1, -1, -1}, |
248 | }; | 249 | }; |
249 | 250 | ||
250 | static struct em28xx_reg_seq compro_mute_gpio[] = { | 251 | static struct em28xx_reg_seq compro_mute_gpio[] = { |
251 | {EM2820_R08_GPIO_CTRL, 6, 7, 10}, | 252 | {EM2820_R08_GPIO_CTRL, 6, 7, 10}, |
252 | { -1, -1, -1, -1}, | 253 | { -1, -1, -1, -1}, |
253 | }; | 254 | }; |
254 | 255 | ||
255 | /* Terratec AV350 */ | 256 | /* Terratec AV350 */ |
@@ -279,21 +280,21 @@ static struct em28xx_reg_seq vc211a_enable[] = { | |||
279 | static struct em28xx_reg_seq dikom_dk300_digital[] = { | 280 | static struct em28xx_reg_seq dikom_dk300_digital[] = { |
280 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 281 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
281 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 282 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
282 | { -1, -1, -1, -1}, | 283 | { -1, -1, -1, -1}, |
283 | }; | 284 | }; |
284 | 285 | ||
285 | 286 | ||
286 | /* Reset for the most [digital] boards */ | 287 | /* Reset for the most [digital] boards */ |
287 | static struct em28xx_reg_seq leadership_digital[] = { | 288 | static struct em28xx_reg_seq leadership_digital[] = { |
288 | {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, | 289 | {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, |
289 | { -1, -1, -1, -1}, | 290 | { -1, -1, -1, -1}, |
290 | }; | 291 | }; |
291 | 292 | ||
292 | static struct em28xx_reg_seq leadership_reset[] = { | 293 | static struct em28xx_reg_seq leadership_reset[] = { |
293 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, | 294 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, |
294 | {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10}, | 295 | {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10}, |
295 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, | 296 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, |
296 | { -1, -1, -1, -1}, | 297 | { -1, -1, -1, -1}, |
297 | }; | 298 | }; |
298 | 299 | ||
299 | /* 2013:024f PCTV nanoStick T2 290e | 300 | /* 2013:024f PCTV nanoStick T2 290e |
@@ -304,7 +305,7 @@ static struct em28xx_reg_seq pctv_290e[] = { | |||
304 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80}, | 305 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80}, |
305 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ | 306 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ |
306 | {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ | 307 | {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ |
307 | {-1, -1, -1, -1}, | 308 | { -1, -1, -1, -1}, |
308 | }; | 309 | }; |
309 | 310 | ||
310 | #if 0 | 311 | #if 0 |
@@ -313,14 +314,14 @@ static struct em28xx_reg_seq terratec_h5_gpio[] = { | |||
313 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 314 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
314 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, | 315 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, |
315 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50}, | 316 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50}, |
316 | { -1, -1, -1, -1}, | 317 | { -1, -1, -1, -1}, |
317 | }; | 318 | }; |
318 | 319 | ||
319 | static struct em28xx_reg_seq terratec_h5_digital[] = { | 320 | static struct em28xx_reg_seq terratec_h5_digital[] = { |
320 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, | 321 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, |
321 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 322 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
322 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, | 323 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, |
323 | { -1, -1, -1, -1}, | 324 | { -1, -1, -1, -1}, |
324 | }; | 325 | }; |
325 | #endif | 326 | #endif |
326 | 327 | ||
@@ -335,12 +336,12 @@ static struct em28xx_reg_seq terratec_h5_digital[] = { | |||
335 | * GPIO_7 - LED (green LED) | 336 | * GPIO_7 - LED (green LED) |
336 | */ | 337 | */ |
337 | static struct em28xx_reg_seq pctv_460e[] = { | 338 | static struct em28xx_reg_seq pctv_460e[] = { |
338 | {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50}, | 339 | {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50}, |
339 | {0x0d, 0xff, 0xff, 50}, | 340 | { 0x0d, 0xff, 0xff, 50}, |
340 | {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */ | 341 | {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */ |
341 | {0x0d, 0x42, 0xff, 50}, | 342 | { 0x0d, 0x42, 0xff, 50}, |
342 | {EM2874_R80_GPIO_P0_CTRL, 0x61, 0xff, 50}, /* GPIO_5=1 */ | 343 | {EM2874_R80_GPIO_P0_CTRL, 0x61, 0xff, 50}, /* GPIO_5=1 */ |
343 | { -1, -1, -1, -1}, | 344 | { -1, -1, -1, -1}, |
344 | }; | 345 | }; |
345 | 346 | ||
346 | static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { | 347 | static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { |
@@ -352,7 +353,7 @@ static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { | |||
352 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 10}, | 353 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 10}, |
353 | {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 10}, | 354 | {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 10}, |
354 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 20}, | 355 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 20}, |
355 | { -1, -1, -1, -1}, | 356 | { -1, -1, -1, -1}, |
356 | }; | 357 | }; |
357 | 358 | ||
358 | #if 0 | 359 | #if 0 |
@@ -361,14 +362,14 @@ static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | |||
361 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */ | 362 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */ |
362 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, | 363 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, |
363 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, | 364 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, |
364 | { -1, -1, -1, -1}, | 365 | { -1, -1, -1, -1}, |
365 | }; | 366 | }; |
366 | 367 | ||
367 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | 368 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { |
368 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, | 369 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, |
369 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 370 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
370 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, | 371 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, |
371 | { -1, -1, -1, -1}, | 372 | { -1, -1, -1, -1}, |
372 | }; | 373 | }; |
373 | #endif | 374 | #endif |
374 | 375 | ||
@@ -378,10 +379,10 @@ static struct em28xx_reg_seq hauppauge_930c_digital[] = { | |||
378 | * GPIO_7 - LED, 0=active | 379 | * GPIO_7 - LED, 0=active |
379 | */ | 380 | */ |
380 | static struct em28xx_reg_seq maxmedia_ub425_tc[] = { | 381 | static struct em28xx_reg_seq maxmedia_ub425_tc[] = { |
381 | {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100}, | 382 | {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100}, |
382 | {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ | 383 | {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ |
383 | {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ | 384 | {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ |
384 | {-1, -1, -1, -1}, | 385 | { -1, -1, -1, -1}, |
385 | }; | 386 | }; |
386 | 387 | ||
387 | /* 2304:0242 PCTV QuatroStick (510e) | 388 | /* 2304:0242 PCTV QuatroStick (510e) |
@@ -391,10 +392,10 @@ static struct em28xx_reg_seq maxmedia_ub425_tc[] = { | |||
391 | * GPIO_7: LED, 1=active | 392 | * GPIO_7: LED, 1=active |
392 | */ | 393 | */ |
393 | static struct em28xx_reg_seq pctv_510e[] = { | 394 | static struct em28xx_reg_seq pctv_510e[] = { |
394 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, | 395 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, |
395 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | 396 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ |
396 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | 397 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ |
397 | { -1, -1, -1, -1}, | 398 | { -1, -1, -1, -1}, |
398 | }; | 399 | }; |
399 | 400 | ||
400 | /* 2013:0251 PCTV QuatroStick nano (520e) | 401 | /* 2013:0251 PCTV QuatroStick nano (520e) |
@@ -404,11 +405,11 @@ static struct em28xx_reg_seq pctv_510e[] = { | |||
404 | * GPIO_7: LED, 1=active | 405 | * GPIO_7: LED, 1=active |
405 | */ | 406 | */ |
406 | static struct em28xx_reg_seq pctv_520e[] = { | 407 | static struct em28xx_reg_seq pctv_520e[] = { |
407 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, | 408 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, |
408 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | 409 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ |
409 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | 410 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ |
410 | {EM2874_R80_GPIO_P0_CTRL, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */ | 411 | {EM2874_R80_GPIO_P0_CTRL, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */ |
411 | { -1, -1, -1, -1}, | 412 | { -1, -1, -1, -1}, |
412 | }; | 413 | }; |
413 | 414 | ||
414 | /* | 415 | /* |
@@ -2030,6 +2031,18 @@ struct em28xx_board em28xx_boards[] = { | |||
2030 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 2031 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2031 | EM28XX_I2C_FREQ_400_KHZ, | 2032 | EM28XX_I2C_FREQ_400_KHZ, |
2032 | }, | 2033 | }, |
2034 | /* | ||
2035 | * 1b80:e346 KWorld USB ATSC TV Stick UB435-Q V2 | ||
2036 | * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2 | ||
2037 | */ | ||
2038 | [EM2874_BOARD_KWORLD_UB435Q_V2] = { | ||
2039 | .name = "KWorld USB ATSC TV Stick UB435-Q V2", | ||
2040 | .tuner_type = TUNER_ABSENT, | ||
2041 | .has_dvb = 1, | ||
2042 | .dvb_gpio = kworld_a340_digital, | ||
2043 | .tuner_gpio = default_tuner_gpio, | ||
2044 | .def_i2c_bus = 1, | ||
2045 | }, | ||
2033 | }; | 2046 | }; |
2034 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 2047 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
2035 | 2048 | ||
@@ -2173,6 +2186,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
2173 | .driver_info = EM2860_BOARD_GADMEI_UTV330 }, | 2186 | .driver_info = EM2860_BOARD_GADMEI_UTV330 }, |
2174 | { USB_DEVICE(0x1b80, 0xa340), | 2187 | { USB_DEVICE(0x1b80, 0xa340), |
2175 | .driver_info = EM2870_BOARD_KWORLD_A340 }, | 2188 | .driver_info = EM2870_BOARD_KWORLD_A340 }, |
2189 | { USB_DEVICE(0x1b80, 0xe346), | ||
2190 | .driver_info = EM2874_BOARD_KWORLD_UB435Q_V2 }, | ||
2176 | { USB_DEVICE(0x2013, 0x024f), | 2191 | { USB_DEVICE(0x2013, 0x024f), |
2177 | .driver_info = EM28174_BOARD_PCTV_290E }, | 2192 | .driver_info = EM28174_BOARD_PCTV_290E }, |
2178 | { USB_DEVICE(0x2013, 0x024c), | 2193 | { USB_DEVICE(0x2013, 0x024c), |
@@ -2857,6 +2872,8 @@ void em28xx_release_resources(struct em28xx *dev) | |||
2857 | if (dev->def_i2c_bus) | 2872 | if (dev->def_i2c_bus) |
2858 | em28xx_i2c_unregister(dev, 1); | 2873 | em28xx_i2c_unregister(dev, 1); |
2859 | em28xx_i2c_unregister(dev, 0); | 2874 | em28xx_i2c_unregister(dev, 0); |
2875 | if (dev->clk) | ||
2876 | v4l2_clk_unregister_fixed(dev->clk); | ||
2860 | 2877 | ||
2861 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 2878 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
2862 | 2879 | ||
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index bb1e8dca80cd..344042bb845c 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
@@ -298,6 +298,18 @@ static struct lgdt3305_config em2870_lgdt3304_dev = { | |||
298 | .qam_if_khz = 4000, | 298 | .qam_if_khz = 4000, |
299 | }; | 299 | }; |
300 | 300 | ||
301 | static struct lgdt3305_config em2874_lgdt3305_dev = { | ||
302 | .i2c_addr = 0x0e, | ||
303 | .demod_chip = LGDT3305, | ||
304 | .spectral_inversion = 1, | ||
305 | .deny_i2c_rptr = 0, | ||
306 | .mpeg_mode = LGDT3305_MPEG_SERIAL, | ||
307 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
308 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
309 | .vsb_if_khz = 3250, | ||
310 | .qam_if_khz = 4000, | ||
311 | }; | ||
312 | |||
301 | static struct s921_config sharp_isdbt = { | 313 | static struct s921_config sharp_isdbt = { |
302 | .demod_address = 0x30 >> 1 | 314 | .demod_address = 0x30 >> 1 |
303 | }; | 315 | }; |
@@ -329,6 +341,11 @@ static struct tda18271_config kworld_a340_config = { | |||
329 | .std_map = &kworld_a340_std_map, | 341 | .std_map = &kworld_a340_std_map, |
330 | }; | 342 | }; |
331 | 343 | ||
344 | static struct tda18271_config kworld_ub435q_v2_config = { | ||
345 | .std_map = &kworld_a340_std_map, | ||
346 | .gate = TDA18271_GATE_DIGITAL, | ||
347 | }; | ||
348 | |||
332 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { | 349 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { |
333 | .demod_address = (0x1e >> 1), | 350 | .demod_address = (0x1e >> 1), |
334 | .no_tuner = 1, | 351 | .no_tuner = 1, |
@@ -384,7 +401,10 @@ static struct drxk_config maxmedia_ub425_tc_drxk = { | |||
384 | .adr = 0x29, | 401 | .adr = 0x29, |
385 | .single_master = 1, | 402 | .single_master = 1, |
386 | .no_i2c_bridge = 1, | 403 | .no_i2c_bridge = 1, |
404 | .microcode_name = "dvb-demod-drxk-01.fw", | ||
405 | .chunk_size = 62, | ||
387 | .load_firmware_sync = true, | 406 | .load_firmware_sync = true, |
407 | .qam_demod_parameter_count = 2, | ||
388 | }; | 408 | }; |
389 | 409 | ||
390 | static struct drxk_config pctv_520e_drxk = { | 410 | static struct drxk_config pctv_520e_drxk = { |
@@ -424,7 +444,7 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) | |||
424 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0x65}, | 444 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0x65}, |
425 | {EM2874_R80_GPIO_P0_CTRL, 0xfb, 0xff, 0x32}, | 445 | {EM2874_R80_GPIO_P0_CTRL, 0xfb, 0xff, 0x32}, |
426 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0xb8}, | 446 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0xb8}, |
427 | { -1, -1, -1, -1}, | 447 | { -1, -1, -1, -1}, |
428 | }; | 448 | }; |
429 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { | 449 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { |
430 | {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x01}, | 450 | {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x01}, |
@@ -439,7 +459,7 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) | |||
439 | {EM2874_R80_GPIO_P0_CTRL, 0xcf, 0xff, 0x0b}, | 459 | {EM2874_R80_GPIO_P0_CTRL, 0xcf, 0xff, 0x0b}, |
440 | {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x65}, | 460 | {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x65}, |
441 | 461 | ||
442 | { -1, -1, -1, -1}, | 462 | { -1, -1, -1, -1}, |
443 | }; | 463 | }; |
444 | 464 | ||
445 | struct { | 465 | struct { |
@@ -491,13 +511,13 @@ static void terratec_h5_init(struct em28xx *dev) | |||
491 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 511 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
492 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, | 512 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, |
493 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 513 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
494 | { -1, -1, -1, -1}, | 514 | { -1, -1, -1, -1}, |
495 | }; | 515 | }; |
496 | struct em28xx_reg_seq terratec_h5_end[] = { | 516 | struct em28xx_reg_seq terratec_h5_end[] = { |
497 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 517 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
498 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, | 518 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, |
499 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 519 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
500 | { -1, -1, -1, -1}, | 520 | { -1, -1, -1, -1}, |
501 | }; | 521 | }; |
502 | struct { | 522 | struct { |
503 | unsigned char r[4]; | 523 | unsigned char r[4]; |
@@ -547,12 +567,12 @@ static void terratec_htc_stick_init(struct em28xx *dev) | |||
547 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 567 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
548 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 50}, | 568 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 50}, |
549 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 569 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
550 | { -1, -1, -1, -1}, | 570 | { -1, -1, -1, -1}, |
551 | }; | 571 | }; |
552 | struct em28xx_reg_seq terratec_htc_stick_end[] = { | 572 | struct em28xx_reg_seq terratec_htc_stick_end[] = { |
553 | {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, | 573 | {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, |
554 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50}, | 574 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50}, |
555 | { -1, -1, -1, -1}, | 575 | { -1, -1, -1, -1}, |
556 | }; | 576 | }; |
557 | 577 | ||
558 | /* | 578 | /* |
@@ -594,13 +614,13 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) | |||
594 | {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 100}, | 614 | {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 100}, |
595 | {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 50}, | 615 | {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 50}, |
596 | {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, | 616 | {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, |
597 | { -1, -1, -1, -1}, | 617 | { -1, -1, -1, -1}, |
598 | }; | 618 | }; |
599 | struct em28xx_reg_seq terratec_htc_usb_xs_end[] = { | 619 | struct em28xx_reg_seq terratec_htc_usb_xs_end[] = { |
600 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 100}, | 620 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 100}, |
601 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, | 621 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, |
602 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 622 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
603 | { -1, -1, -1, -1}, | 623 | { -1, -1, -1, -1}, |
604 | }; | 624 | }; |
605 | 625 | ||
606 | /* | 626 | /* |
@@ -1227,18 +1247,14 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1227 | dvb->fe[0]->ops.i2c_gate_ctrl = NULL; | 1247 | dvb->fe[0]->ops.i2c_gate_ctrl = NULL; |
1228 | 1248 | ||
1229 | /* attach tuner */ | 1249 | /* attach tuner */ |
1230 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], | 1250 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, |
1231 | &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { | 1251 | &dev->i2c_adap[dev->def_i2c_bus], |
1252 | &em28xx_cxd2820r_tda18271_config)) { | ||
1232 | dvb_frontend_detach(dvb->fe[0]); | 1253 | dvb_frontend_detach(dvb->fe[0]); |
1233 | result = -EINVAL; | 1254 | result = -EINVAL; |
1234 | goto out_free; | 1255 | goto out_free; |
1235 | } | 1256 | } |
1236 | } | 1257 | } |
1237 | |||
1238 | /* TODO: we need drx-3913k firmware in order to support DVB-T */ | ||
1239 | em28xx_info("MaxMedia UB425-TC/Delock 61959: only DVB-C " \ | ||
1240 | "supported by that driver version\n"); | ||
1241 | |||
1242 | break; | 1258 | break; |
1243 | case EM2884_BOARD_PCTV_510E: | 1259 | case EM2884_BOARD_PCTV_510E: |
1244 | case EM2884_BOARD_PCTV_520E: | 1260 | case EM2884_BOARD_PCTV_520E: |
@@ -1297,6 +1313,23 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1297 | goto out_free; | 1313 | goto out_free; |
1298 | } | 1314 | } |
1299 | break; | 1315 | break; |
1316 | case EM2874_BOARD_KWORLD_UB435Q_V2: | ||
1317 | dvb->fe[0] = dvb_attach(lgdt3305_attach, | ||
1318 | &em2874_lgdt3305_dev, | ||
1319 | &dev->i2c_adap[dev->def_i2c_bus]); | ||
1320 | if (!dvb->fe[0]) { | ||
1321 | result = -EINVAL; | ||
1322 | goto out_free; | ||
1323 | } | ||
1324 | |||
1325 | /* Attach the demodulator. */ | ||
1326 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
1327 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1328 | &kworld_ub435q_v2_config)) { | ||
1329 | result = -EINVAL; | ||
1330 | goto out_free; | ||
1331 | } | ||
1332 | break; | ||
1300 | default: | 1333 | default: |
1301 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" | 1334 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" |
1302 | " isn't supported yet\n"); | 1335 | " isn't supported yet\n"); |
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 9d103344f34a..fc5d60efd4ab 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -638,7 +638,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
638 | if (rc) | 638 | if (rc) |
639 | return rc; | 639 | return rc; |
640 | 640 | ||
641 | if (dev->streaming_users++ == 0) { | 641 | if (dev->streaming_users == 0) { |
642 | /* First active streaming user, so allocate all the URBs */ | 642 | /* First active streaming user, so allocate all the URBs */ |
643 | 643 | ||
644 | /* Allocate the USB bandwidth */ | 644 | /* Allocate the USB bandwidth */ |
@@ -657,7 +657,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
657 | dev->packet_multiplier, | 657 | dev->packet_multiplier, |
658 | em28xx_urb_data_copy); | 658 | em28xx_urb_data_copy); |
659 | if (rc < 0) | 659 | if (rc < 0) |
660 | goto fail; | 660 | return rc; |
661 | 661 | ||
662 | /* | 662 | /* |
663 | * djh: it's not clear whether this code is still needed. I'm | 663 | * djh: it's not clear whether this code is still needed. I'm |
@@ -675,7 +675,8 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
675 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 675 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); |
676 | } | 676 | } |
677 | 677 | ||
678 | fail: | 678 | dev->streaming_users++; |
679 | |||
679 | return rc; | 680 | return rc; |
680 | } | 681 | } |
681 | 682 | ||
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 205e9038b1c0..f8726ad5d0a8 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
@@ -131,6 +131,7 @@ | |||
131 | #define EM2884_BOARD_TERRATEC_HTC_USB_XS 87 | 131 | #define EM2884_BOARD_TERRATEC_HTC_USB_XS 87 |
132 | #define EM2884_BOARD_C3TECH_DIGITAL_DUO 88 | 132 | #define EM2884_BOARD_C3TECH_DIGITAL_DUO 88 |
133 | #define EM2874_BOARD_DELOCK_61959 89 | 133 | #define EM2874_BOARD_DELOCK_61959 89 |
134 | #define EM2874_BOARD_KWORLD_UB435Q_V2 90 | ||
134 | 135 | ||
135 | /* Limits minimum and default number of buffers */ | 136 | /* Limits minimum and default number of buffers */ |
136 | #define EM28XX_MIN_BUF 4 | 137 | #define EM28XX_MIN_BUF 4 |
@@ -492,6 +493,7 @@ struct em28xx { | |||
492 | 493 | ||
493 | struct v4l2_device v4l2_dev; | 494 | struct v4l2_device v4l2_dev; |
494 | struct v4l2_ctrl_handler ctrl_handler; | 495 | struct v4l2_ctrl_handler ctrl_handler; |
496 | struct v4l2_clk *clk; | ||
495 | struct em28xx_board board; | 497 | struct em28xx_board board; |
496 | 498 | ||
497 | /* Webcam specific fields */ | 499 | /* Webcam specific fields */ |
diff --git a/drivers/media/usb/gspca/conex.c b/drivers/media/usb/gspca/conex.c index 38714df31ac4..2e15c80d6e3d 100644 --- a/drivers/media/usb/gspca/conex.c +++ b/drivers/media/usb/gspca/conex.c | |||
@@ -783,7 +783,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
783 | struct sd *sd = (struct sd *) gspca_dev; | 783 | struct sd *sd = (struct sd *) gspca_dev; |
784 | 784 | ||
785 | /* create the JPEG header */ | 785 | /* create the JPEG header */ |
786 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 786 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
787 | gspca_dev->pixfmt.width, | ||
787 | 0x22); /* JPEG 411 */ | 788 | 0x22); /* JPEG 411 */ |
788 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); | 789 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
789 | 790 | ||
diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c index 064b53043b15..f23df4a9d8c5 100644 --- a/drivers/media/usb/gspca/cpia1.c +++ b/drivers/media/usb/gspca/cpia1.c | |||
@@ -1553,9 +1553,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1553 | sd->params.format.videoSize = VIDEOSIZE_CIF; | 1553 | sd->params.format.videoSize = VIDEOSIZE_CIF; |
1554 | 1554 | ||
1555 | sd->params.roi.colEnd = sd->params.roi.colStart + | 1555 | sd->params.roi.colEnd = sd->params.roi.colStart + |
1556 | (gspca_dev->width >> 3); | 1556 | (gspca_dev->pixfmt.width >> 3); |
1557 | sd->params.roi.rowEnd = sd->params.roi.rowStart + | 1557 | sd->params.roi.rowEnd = sd->params.roi.rowStart + |
1558 | (gspca_dev->height >> 2); | 1558 | (gspca_dev->pixfmt.height >> 2); |
1559 | 1559 | ||
1560 | /* And now set the camera to a known state */ | 1560 | /* And now set the camera to a known state */ |
1561 | ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode, | 1561 | ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode, |
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 048507b27bb2..f3a7ace0fac9 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c | |||
@@ -504,8 +504,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file, | |||
504 | unsigned int frsz; | 504 | unsigned int frsz; |
505 | int i; | 505 | int i; |
506 | 506 | ||
507 | i = gspca_dev->curr_mode; | 507 | frsz = gspca_dev->pixfmt.sizeimage; |
508 | frsz = gspca_dev->cam.cam_mode[i].sizeimage; | ||
509 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); | 508 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); |
510 | frsz = PAGE_ALIGN(frsz); | 509 | frsz = PAGE_ALIGN(frsz); |
511 | if (count >= GSPCA_MAX_FRAMES) | 510 | if (count >= GSPCA_MAX_FRAMES) |
@@ -627,16 +626,14 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, | |||
627 | static u32 which_bandwidth(struct gspca_dev *gspca_dev) | 626 | static u32 which_bandwidth(struct gspca_dev *gspca_dev) |
628 | { | 627 | { |
629 | u32 bandwidth; | 628 | u32 bandwidth; |
630 | int i; | ||
631 | 629 | ||
632 | /* get the (max) image size */ | 630 | /* get the (max) image size */ |
633 | i = gspca_dev->curr_mode; | 631 | bandwidth = gspca_dev->pixfmt.sizeimage; |
634 | bandwidth = gspca_dev->cam.cam_mode[i].sizeimage; | ||
635 | 632 | ||
636 | /* if the image is compressed, estimate its mean size */ | 633 | /* if the image is compressed, estimate its mean size */ |
637 | if (!gspca_dev->cam.needs_full_bandwidth && | 634 | if (!gspca_dev->cam.needs_full_bandwidth && |
638 | bandwidth < gspca_dev->cam.cam_mode[i].width * | 635 | bandwidth < gspca_dev->pixfmt.width * |
639 | gspca_dev->cam.cam_mode[i].height) | 636 | gspca_dev->pixfmt.height) |
640 | bandwidth = bandwidth * 3 / 8; /* 0.375 */ | 637 | bandwidth = bandwidth * 3 / 8; /* 0.375 */ |
641 | 638 | ||
642 | /* estimate the frame rate */ | 639 | /* estimate the frame rate */ |
@@ -650,7 +647,7 @@ static u32 which_bandwidth(struct gspca_dev *gspca_dev) | |||
650 | 647 | ||
651 | /* don't hope more than 15 fps with USB 1.1 and | 648 | /* don't hope more than 15 fps with USB 1.1 and |
652 | * image resolution >= 640x480 */ | 649 | * image resolution >= 640x480 */ |
653 | if (gspca_dev->width >= 640 | 650 | if (gspca_dev->pixfmt.width >= 640 |
654 | && gspca_dev->dev->speed == USB_SPEED_FULL) | 651 | && gspca_dev->dev->speed == USB_SPEED_FULL) |
655 | bandwidth *= 15; /* 15 fps */ | 652 | bandwidth *= 15; /* 15 fps */ |
656 | else | 653 | else |
@@ -982,9 +979,7 @@ static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | |||
982 | 979 | ||
983 | i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ | 980 | i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ |
984 | gspca_dev->curr_mode = i; | 981 | gspca_dev->curr_mode = i; |
985 | gspca_dev->width = gspca_dev->cam.cam_mode[i].width; | 982 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i]; |
986 | gspca_dev->height = gspca_dev->cam.cam_mode[i].height; | ||
987 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; | ||
988 | 983 | ||
989 | /* does nothing if ctrl_handler == NULL */ | 984 | /* does nothing if ctrl_handler == NULL */ |
990 | v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); | 985 | v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler); |
@@ -1105,10 +1100,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1105 | struct v4l2_format *fmt) | 1100 | struct v4l2_format *fmt) |
1106 | { | 1101 | { |
1107 | struct gspca_dev *gspca_dev = video_drvdata(file); | 1102 | struct gspca_dev *gspca_dev = video_drvdata(file); |
1108 | int mode; | ||
1109 | 1103 | ||
1110 | mode = gspca_dev->curr_mode; | 1104 | fmt->fmt.pix = gspca_dev->pixfmt; |
1111 | fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; | ||
1112 | /* some drivers use priv internally, zero it before giving it to | 1105 | /* some drivers use priv internally, zero it before giving it to |
1113 | userspace */ | 1106 | userspace */ |
1114 | fmt->fmt.pix.priv = 0; | 1107 | fmt->fmt.pix.priv = 0; |
@@ -1140,6 +1133,12 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | |||
1140 | mode = mode2; | 1133 | mode = mode2; |
1141 | } | 1134 | } |
1142 | fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; | 1135 | fmt->fmt.pix = gspca_dev->cam.cam_mode[mode]; |
1136 | if (gspca_dev->sd_desc->try_fmt) { | ||
1137 | /* pass original resolution to subdriver try_fmt */ | ||
1138 | fmt->fmt.pix.width = w; | ||
1139 | fmt->fmt.pix.height = h; | ||
1140 | gspca_dev->sd_desc->try_fmt(gspca_dev, fmt); | ||
1141 | } | ||
1143 | /* some drivers use priv internally, zero it before giving it to | 1142 | /* some drivers use priv internally, zero it before giving it to |
1144 | userspace */ | 1143 | userspace */ |
1145 | fmt->fmt.pix.priv = 0; | 1144 | fmt->fmt.pix.priv = 0; |
@@ -1178,19 +1177,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1178 | goto out; | 1177 | goto out; |
1179 | } | 1178 | } |
1180 | 1179 | ||
1181 | if (ret == gspca_dev->curr_mode) { | ||
1182 | ret = 0; | ||
1183 | goto out; /* same mode */ | ||
1184 | } | ||
1185 | |||
1186 | if (gspca_dev->streaming) { | 1180 | if (gspca_dev->streaming) { |
1187 | ret = -EBUSY; | 1181 | ret = -EBUSY; |
1188 | goto out; | 1182 | goto out; |
1189 | } | 1183 | } |
1190 | gspca_dev->width = fmt->fmt.pix.width; | ||
1191 | gspca_dev->height = fmt->fmt.pix.height; | ||
1192 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; | ||
1193 | gspca_dev->curr_mode = ret; | 1184 | gspca_dev->curr_mode = ret; |
1185 | if (gspca_dev->sd_desc->try_fmt) | ||
1186 | /* subdriver try_fmt can modify format parameters */ | ||
1187 | gspca_dev->pixfmt = fmt->fmt.pix; | ||
1188 | else | ||
1189 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[ret]; | ||
1194 | 1190 | ||
1195 | ret = 0; | 1191 | ret = 0; |
1196 | out: | 1192 | out: |
@@ -1205,6 +1201,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, | |||
1205 | int i; | 1201 | int i; |
1206 | __u32 index = 0; | 1202 | __u32 index = 0; |
1207 | 1203 | ||
1204 | if (gspca_dev->sd_desc->enum_framesizes) | ||
1205 | return gspca_dev->sd_desc->enum_framesizes(gspca_dev, fsize); | ||
1206 | |||
1208 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { | 1207 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { |
1209 | if (fsize->pixel_format != | 1208 | if (fsize->pixel_format != |
1210 | gspca_dev->cam.cam_mode[i].pixelformat) | 1209 | gspca_dev->cam.cam_mode[i].pixelformat) |
@@ -1471,8 +1470,9 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1471 | if (ret < 0) | 1470 | if (ret < 0) |
1472 | goto out; | 1471 | goto out; |
1473 | } | 1472 | } |
1474 | PDEBUG_MODE(gspca_dev, D_STREAM, "stream on OK", gspca_dev->pixfmt, | 1473 | PDEBUG_MODE(gspca_dev, D_STREAM, "stream on OK", |
1475 | gspca_dev->width, gspca_dev->height); | 1474 | gspca_dev->pixfmt.pixelformat, |
1475 | gspca_dev->pixfmt.width, gspca_dev->pixfmt.height); | ||
1476 | ret = 0; | 1476 | ret = 0; |
1477 | out: | 1477 | out: |
1478 | mutex_unlock(&gspca_dev->queue_lock); | 1478 | mutex_unlock(&gspca_dev->queue_lock); |
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index ac0b11f46f50..300642dc1a17 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h | |||
@@ -88,6 +88,10 @@ typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, | |||
88 | typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev, | 88 | typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev, |
89 | u8 *data, | 89 | u8 *data, |
90 | int len); | 90 | int len); |
91 | typedef void (*cam_format_op) (struct gspca_dev *gspca_dev, | ||
92 | struct v4l2_format *fmt); | ||
93 | typedef int (*cam_frmsize_op) (struct gspca_dev *gspca_dev, | ||
94 | struct v4l2_frmsizeenum *fsize); | ||
91 | 95 | ||
92 | /* subdriver description */ | 96 | /* subdriver description */ |
93 | struct sd_desc { | 97 | struct sd_desc { |
@@ -109,6 +113,8 @@ struct sd_desc { | |||
109 | cam_set_jpg_op set_jcomp; | 113 | cam_set_jpg_op set_jcomp; |
110 | cam_streamparm_op get_streamparm; | 114 | cam_streamparm_op get_streamparm; |
111 | cam_streamparm_op set_streamparm; | 115 | cam_streamparm_op set_streamparm; |
116 | cam_format_op try_fmt; | ||
117 | cam_frmsize_op enum_framesizes; | ||
112 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 118 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
113 | cam_set_reg_op set_register; | 119 | cam_set_reg_op set_register; |
114 | cam_get_reg_op get_register; | 120 | cam_get_reg_op get_register; |
@@ -183,9 +189,7 @@ struct gspca_dev { | |||
183 | __u8 streaming; /* protected by both mutexes (*) */ | 189 | __u8 streaming; /* protected by both mutexes (*) */ |
184 | 190 | ||
185 | __u8 curr_mode; /* current camera mode */ | 191 | __u8 curr_mode; /* current camera mode */ |
186 | __u32 pixfmt; /* current mode parameters */ | 192 | struct v4l2_pix_format pixfmt; /* current mode parameters */ |
187 | __u16 width; | ||
188 | __u16 height; | ||
189 | __u32 sequence; /* frame sequence number */ | 193 | __u32 sequence; /* frame sequence number */ |
190 | 194 | ||
191 | wait_queue_head_t wq; /* wait queue */ | 195 | wait_queue_head_t wq; /* wait queue */ |
diff --git a/drivers/media/usb/gspca/jeilinj.c b/drivers/media/usb/gspca/jeilinj.c index 8da3dde38385..19736e237b37 100644 --- a/drivers/media/usb/gspca/jeilinj.c +++ b/drivers/media/usb/gspca/jeilinj.c | |||
@@ -378,11 +378,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
378 | struct sd *dev = (struct sd *) gspca_dev; | 378 | struct sd *dev = (struct sd *) gspca_dev; |
379 | 379 | ||
380 | /* create the JPEG header */ | 380 | /* create the JPEG header */ |
381 | jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 381 | jpeg_define(dev->jpeg_hdr, gspca_dev->pixfmt.height, |
382 | gspca_dev->pixfmt.width, | ||
382 | 0x21); /* JPEG 422 */ | 383 | 0x21); /* JPEG 422 */ |
383 | jpeg_set_qual(dev->jpeg_hdr, dev->quality); | 384 | jpeg_set_qual(dev->jpeg_hdr, dev->quality); |
384 | PDEBUG(D_STREAM, "Start streaming at %dx%d", | 385 | PDEBUG(D_STREAM, "Start streaming at %dx%d", |
385 | gspca_dev->height, gspca_dev->width); | 386 | gspca_dev->pixfmt.height, gspca_dev->pixfmt.width); |
386 | jlj_start(gspca_dev); | 387 | jlj_start(gspca_dev); |
387 | return gspca_dev->usb_err; | 388 | return gspca_dev->usb_err; |
388 | } | 389 | } |
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c index fdaeeb14453f..5b481fa43099 100644 --- a/drivers/media/usb/gspca/jl2005bcd.c +++ b/drivers/media/usb/gspca/jl2005bcd.c | |||
@@ -455,7 +455,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
455 | struct sd *sd = (struct sd *) gspca_dev; | 455 | struct sd *sd = (struct sd *) gspca_dev; |
456 | sd->cap_mode = gspca_dev->cam.cam_mode; | 456 | sd->cap_mode = gspca_dev->cam.cam_mode; |
457 | 457 | ||
458 | switch (gspca_dev->width) { | 458 | switch (gspca_dev->pixfmt.width) { |
459 | case 640: | 459 | case 640: |
460 | PDEBUG(D_STREAM, "Start streaming at vga resolution"); | 460 | PDEBUG(D_STREAM, "Start streaming at vga resolution"); |
461 | jl2005c_stream_start_vga_lg(gspca_dev); | 461 | jl2005c_stream_start_vga_lg(gspca_dev); |
diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c index cfa4663f8934..27fcef11aef4 100644 --- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c | |||
@@ -266,7 +266,7 @@ static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev) | |||
266 | return err; | 266 | return err; |
267 | 267 | ||
268 | data[0] = MT9M111_RMB_OVER_SIZED; | 268 | data[0] = MT9M111_RMB_OVER_SIZED; |
269 | if (gspca_dev->width == 640) { | 269 | if (gspca_dev->pixfmt.width == 640) { |
270 | data[1] = MT9M111_RMB_ROW_SKIP_2X | | 270 | data[1] = MT9M111_RMB_ROW_SKIP_2X | |
271 | MT9M111_RMB_COLUMN_SKIP_2X | | 271 | MT9M111_RMB_COLUMN_SKIP_2X | |
272 | (hflip << 1) | vflip; | 272 | (hflip << 1) | vflip; |
diff --git a/drivers/media/usb/gspca/mars.c b/drivers/media/usb/gspca/mars.c index ff2c5abf115b..779a8785f421 100644 --- a/drivers/media/usb/gspca/mars.c +++ b/drivers/media/usb/gspca/mars.c | |||
@@ -254,7 +254,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
254 | int i; | 254 | int i; |
255 | 255 | ||
256 | /* create the JPEG header */ | 256 | /* create the JPEG header */ |
257 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 257 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
258 | gspca_dev->pixfmt.width, | ||
258 | 0x21); /* JPEG 422 */ | 259 | 0x21); /* JPEG 422 */ |
259 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); | 260 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
260 | 261 | ||
@@ -270,8 +271,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
270 | data[0] = 0x00; /* address */ | 271 | data[0] = 0x00; /* address */ |
271 | data[1] = 0x0c | 0x01; /* reg 0 */ | 272 | data[1] = 0x0c | 0x01; /* reg 0 */ |
272 | data[2] = 0x01; /* reg 1 */ | 273 | data[2] = 0x01; /* reg 1 */ |
273 | data[3] = gspca_dev->width / 8; /* h_size , reg 2 */ | 274 | data[3] = gspca_dev->pixfmt.width / 8; /* h_size , reg 2 */ |
274 | data[4] = gspca_dev->height / 8; /* v_size , reg 3 */ | 275 | data[4] = gspca_dev->pixfmt.height / 8; /* v_size , reg 3 */ |
275 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | 276 | data[5] = 0x30; /* reg 4, MI, PAS5101 : |
276 | * 0x30 for 24mhz , 0x28 for 12mhz */ | 277 | * 0x30 for 24mhz , 0x28 for 12mhz */ |
277 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ | 278 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ |
diff --git a/drivers/media/usb/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c index 68bb2f359666..f006e29ca019 100644 --- a/drivers/media/usb/gspca/mr97310a.c +++ b/drivers/media/usb/gspca/mr97310a.c | |||
@@ -521,7 +521,7 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) | |||
521 | if (sd->sensor_type) | 521 | if (sd->sensor_type) |
522 | data[5] = 0xbb; | 522 | data[5] = 0xbb; |
523 | 523 | ||
524 | switch (gspca_dev->width) { | 524 | switch (gspca_dev->pixfmt.width) { |
525 | case 160: | 525 | case 160: |
526 | data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */ | 526 | data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */ |
527 | /* fall thru */ | 527 | /* fall thru */ |
@@ -618,7 +618,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev) | |||
618 | data[10] = 0x18; | 618 | data[10] = 0x18; |
619 | } | 619 | } |
620 | 620 | ||
621 | switch (gspca_dev->width) { | 621 | switch (gspca_dev->pixfmt.width) { |
622 | case 160: | 622 | case 160: |
623 | data[9] |= 0x0c; /* reg 8, 4:1 scale down */ | 623 | data[9] |= 0x0c; /* reg 8, 4:1 scale down */ |
624 | /* fall thru */ | 624 | /* fall thru */ |
@@ -847,7 +847,7 @@ static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv) | |||
847 | u8 clockdiv = (60 * expo + 7999) / 8000; | 847 | u8 clockdiv = (60 * expo + 7999) / 8000; |
848 | 848 | ||
849 | /* Limit framerate to not exceed usb bandwidth */ | 849 | /* Limit framerate to not exceed usb bandwidth */ |
850 | if (clockdiv < min_clockdiv && gspca_dev->width >= 320) | 850 | if (clockdiv < min_clockdiv && gspca_dev->pixfmt.width >= 320) |
851 | clockdiv = min_clockdiv; | 851 | clockdiv = min_clockdiv; |
852 | else if (clockdiv < 2) | 852 | else if (clockdiv < 2) |
853 | clockdiv = 2; | 853 | clockdiv = 2; |
diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c index 44c9964b1b3e..599f755e75b8 100644 --- a/drivers/media/usb/gspca/nw80x.c +++ b/drivers/media/usb/gspca/nw80x.c | |||
@@ -1708,7 +1708,7 @@ static void setautogain(struct gspca_dev *gspca_dev, s32 val) | |||
1708 | 1708 | ||
1709 | reg_r(gspca_dev, 0x1004, 1); | 1709 | reg_r(gspca_dev, 0x1004, 1); |
1710 | if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */ | 1710 | if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */ |
1711 | sd->ae_res = gspca_dev->width * gspca_dev->height; | 1711 | sd->ae_res = gspca_dev->pixfmt.width * gspca_dev->pixfmt.height; |
1712 | } else { /* get the AE window size */ | 1712 | } else { /* get the AE window size */ |
1713 | reg_r(gspca_dev, 0x1011, 8); | 1713 | reg_r(gspca_dev, 0x1011, 8); |
1714 | w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0] | 1714 | w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0] |
@@ -1717,7 +1717,8 @@ static void setautogain(struct gspca_dev *gspca_dev, s32 val) | |||
1717 | - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6]; | 1717 | - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6]; |
1718 | sd->ae_res = h * w; | 1718 | sd->ae_res = h * w; |
1719 | if (sd->ae_res == 0) | 1719 | if (sd->ae_res == 0) |
1720 | sd->ae_res = gspca_dev->width * gspca_dev->height; | 1720 | sd->ae_res = gspca_dev->pixfmt.width * |
1721 | gspca_dev->pixfmt.height; | ||
1721 | } | 1722 | } |
1722 | } | 1723 | } |
1723 | 1724 | ||
@@ -1856,21 +1857,21 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1856 | reg_w_buf(gspca_dev, cmd); | 1857 | reg_w_buf(gspca_dev, cmd); |
1857 | switch (sd->webcam) { | 1858 | switch (sd->webcam) { |
1858 | case P35u: | 1859 | case P35u: |
1859 | if (gspca_dev->width == 320) | 1860 | if (gspca_dev->pixfmt.width == 320) |
1860 | reg_w_buf(gspca_dev, nw801_start_qvga); | 1861 | reg_w_buf(gspca_dev, nw801_start_qvga); |
1861 | else | 1862 | else |
1862 | reg_w_buf(gspca_dev, nw801_start_vga); | 1863 | reg_w_buf(gspca_dev, nw801_start_vga); |
1863 | reg_w_buf(gspca_dev, nw801_start_2); | 1864 | reg_w_buf(gspca_dev, nw801_start_2); |
1864 | break; | 1865 | break; |
1865 | case Kr651us: | 1866 | case Kr651us: |
1866 | if (gspca_dev->width == 320) | 1867 | if (gspca_dev->pixfmt.width == 320) |
1867 | reg_w_buf(gspca_dev, kr651_start_qvga); | 1868 | reg_w_buf(gspca_dev, kr651_start_qvga); |
1868 | else | 1869 | else |
1869 | reg_w_buf(gspca_dev, kr651_start_vga); | 1870 | reg_w_buf(gspca_dev, kr651_start_vga); |
1870 | reg_w_buf(gspca_dev, kr651_start_2); | 1871 | reg_w_buf(gspca_dev, kr651_start_2); |
1871 | break; | 1872 | break; |
1872 | case Proscope: | 1873 | case Proscope: |
1873 | if (gspca_dev->width == 320) | 1874 | if (gspca_dev->pixfmt.width == 320) |
1874 | reg_w_buf(gspca_dev, proscope_start_qvga); | 1875 | reg_w_buf(gspca_dev, proscope_start_qvga); |
1875 | else | 1876 | else |
1876 | reg_w_buf(gspca_dev, proscope_start_vga); | 1877 | reg_w_buf(gspca_dev, proscope_start_vga); |
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index 8937d79fd176..c95f32a0c02b 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c | |||
@@ -3468,7 +3468,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) | |||
3468 | 3468 | ||
3469 | switch (sd->bridge) { | 3469 | switch (sd->bridge) { |
3470 | case BRIDGE_OVFX2: | 3470 | case BRIDGE_OVFX2: |
3471 | if (gspca_dev->width != 800) | 3471 | if (gspca_dev->pixfmt.width != 800) |
3472 | gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE; | 3472 | gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE; |
3473 | else | 3473 | else |
3474 | gspca_dev->cam.bulk_size = 7 * 4096; | 3474 | gspca_dev->cam.bulk_size = 7 * 4096; |
@@ -3507,8 +3507,8 @@ static void ov511_mode_init_regs(struct sd *sd) | |||
3507 | /* Here I'm assuming that snapshot size == image size. | 3507 | /* Here I'm assuming that snapshot size == image size. |
3508 | * I hope that's always true. --claudio | 3508 | * I hope that's always true. --claudio |
3509 | */ | 3509 | */ |
3510 | hsegs = (sd->gspca_dev.width >> 3) - 1; | 3510 | hsegs = (sd->gspca_dev.pixfmt.width >> 3) - 1; |
3511 | vsegs = (sd->gspca_dev.height >> 3) - 1; | 3511 | vsegs = (sd->gspca_dev.pixfmt.height >> 3) - 1; |
3512 | 3512 | ||
3513 | reg_w(sd, R511_CAM_PXCNT, hsegs); | 3513 | reg_w(sd, R511_CAM_PXCNT, hsegs); |
3514 | reg_w(sd, R511_CAM_LNCNT, vsegs); | 3514 | reg_w(sd, R511_CAM_LNCNT, vsegs); |
@@ -3541,7 +3541,7 @@ static void ov511_mode_init_regs(struct sd *sd) | |||
3541 | case SEN_OV7640: | 3541 | case SEN_OV7640: |
3542 | case SEN_OV7648: | 3542 | case SEN_OV7648: |
3543 | case SEN_OV76BE: | 3543 | case SEN_OV76BE: |
3544 | if (sd->gspca_dev.width == 320) | 3544 | if (sd->gspca_dev.pixfmt.width == 320) |
3545 | interlaced = 1; | 3545 | interlaced = 1; |
3546 | /* Fall through */ | 3546 | /* Fall through */ |
3547 | case SEN_OV6630: | 3547 | case SEN_OV6630: |
@@ -3551,7 +3551,7 @@ static void ov511_mode_init_regs(struct sd *sd) | |||
3551 | case 30: | 3551 | case 30: |
3552 | case 25: | 3552 | case 25: |
3553 | /* Not enough bandwidth to do 640x480 @ 30 fps */ | 3553 | /* Not enough bandwidth to do 640x480 @ 30 fps */ |
3554 | if (sd->gspca_dev.width != 640) { | 3554 | if (sd->gspca_dev.pixfmt.width != 640) { |
3555 | sd->clockdiv = 0; | 3555 | sd->clockdiv = 0; |
3556 | break; | 3556 | break; |
3557 | } | 3557 | } |
@@ -3584,7 +3584,8 @@ static void ov511_mode_init_regs(struct sd *sd) | |||
3584 | 3584 | ||
3585 | /* Check if we have enough bandwidth to disable compression */ | 3585 | /* Check if we have enough bandwidth to disable compression */ |
3586 | fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1; | 3586 | fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1; |
3587 | needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2; | 3587 | needed = fps * sd->gspca_dev.pixfmt.width * |
3588 | sd->gspca_dev.pixfmt.height * 3 / 2; | ||
3588 | /* 1000 isoc packets/sec */ | 3589 | /* 1000 isoc packets/sec */ |
3589 | if (needed > 1000 * packet_size) { | 3590 | if (needed > 1000 * packet_size) { |
3590 | /* Enable Y and UV quantization and compression */ | 3591 | /* Enable Y and UV quantization and compression */ |
@@ -3646,8 +3647,8 @@ static void ov518_mode_init_regs(struct sd *sd) | |||
3646 | reg_w(sd, 0x38, 0x80); | 3647 | reg_w(sd, 0x38, 0x80); |
3647 | } | 3648 | } |
3648 | 3649 | ||
3649 | hsegs = sd->gspca_dev.width / 16; | 3650 | hsegs = sd->gspca_dev.pixfmt.width / 16; |
3650 | vsegs = sd->gspca_dev.height / 4; | 3651 | vsegs = sd->gspca_dev.pixfmt.height / 4; |
3651 | 3652 | ||
3652 | reg_w(sd, 0x29, hsegs); | 3653 | reg_w(sd, 0x29, hsegs); |
3653 | reg_w(sd, 0x2a, vsegs); | 3654 | reg_w(sd, 0x2a, vsegs); |
@@ -3686,7 +3687,8 @@ static void ov518_mode_init_regs(struct sd *sd) | |||
3686 | * happened to be with revision < 2 cams using an | 3687 | * happened to be with revision < 2 cams using an |
3687 | * OV7620 and revision 2 cams using an OV7620AE. | 3688 | * OV7620 and revision 2 cams using an OV7620AE. |
3688 | */ | 3689 | */ |
3689 | if (sd->revision > 0 && sd->gspca_dev.width == 640) { | 3690 | if (sd->revision > 0 && |
3691 | sd->gspca_dev.pixfmt.width == 640) { | ||
3690 | reg_w(sd, 0x20, 0x60); | 3692 | reg_w(sd, 0x20, 0x60); |
3691 | reg_w(sd, 0x21, 0x1f); | 3693 | reg_w(sd, 0x21, 0x1f); |
3692 | } else { | 3694 | } else { |
@@ -3812,8 +3814,8 @@ static void ov519_mode_init_regs(struct sd *sd) | |||
3812 | break; | 3814 | break; |
3813 | } | 3815 | } |
3814 | 3816 | ||
3815 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); | 3817 | reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.pixfmt.width >> 4); |
3816 | reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3); | 3818 | reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.pixfmt.height >> 3); |
3817 | if (sd->sensor == SEN_OV7670 && | 3819 | if (sd->sensor == SEN_OV7670 && |
3818 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) | 3820 | sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) |
3819 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); | 3821 | reg_w(sd, OV519_R12_X_OFFSETL, 0x04); |
@@ -3947,14 +3949,16 @@ static void mode_init_ov_sensor_regs(struct sd *sd) | |||
3947 | } | 3949 | } |
3948 | case SEN_OV3610: | 3950 | case SEN_OV3610: |
3949 | if (qvga) { | 3951 | if (qvga) { |
3950 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); | 3952 | xstart = (1040 - gspca_dev->pixfmt.width) / 2 + |
3951 | ystart = (776 - gspca_dev->height) / 2; | 3953 | (0x1f << 4); |
3954 | ystart = (776 - gspca_dev->pixfmt.height) / 2; | ||
3952 | } else { | 3955 | } else { |
3953 | xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4); | 3956 | xstart = (2076 - gspca_dev->pixfmt.width) / 2 + |
3954 | ystart = (1544 - gspca_dev->height) / 2; | 3957 | (0x10 << 4); |
3958 | ystart = (1544 - gspca_dev->pixfmt.height) / 2; | ||
3955 | } | 3959 | } |
3956 | xend = xstart + gspca_dev->width; | 3960 | xend = xstart + gspca_dev->pixfmt.width; |
3957 | yend = ystart + gspca_dev->height; | 3961 | yend = ystart + gspca_dev->pixfmt.height; |
3958 | /* Writing to the COMH register resets the other windowing regs | 3962 | /* Writing to the COMH register resets the other windowing regs |
3959 | to their default values, so we must do this first. */ | 3963 | to their default values, so we must do this first. */ |
3960 | i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0); | 3964 | i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0); |
@@ -4229,8 +4233,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
4229 | struct sd *sd = (struct sd *) gspca_dev; | 4233 | struct sd *sd = (struct sd *) gspca_dev; |
4230 | 4234 | ||
4231 | /* Default for most bridges, allow bridge_mode_init_regs to override */ | 4235 | /* Default for most bridges, allow bridge_mode_init_regs to override */ |
4232 | sd->sensor_width = sd->gspca_dev.width; | 4236 | sd->sensor_width = sd->gspca_dev.pixfmt.width; |
4233 | sd->sensor_height = sd->gspca_dev.height; | 4237 | sd->sensor_height = sd->gspca_dev.pixfmt.height; |
4234 | 4238 | ||
4235 | switch (sd->bridge) { | 4239 | switch (sd->bridge) { |
4236 | case BRIDGE_OV511: | 4240 | case BRIDGE_OV511: |
@@ -4345,12 +4349,13 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | |||
4345 | ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1); | 4349 | ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1); |
4346 | if (in[8] & 0x80) { | 4350 | if (in[8] & 0x80) { |
4347 | /* Frame end */ | 4351 | /* Frame end */ |
4348 | if ((in[9] + 1) * 8 != gspca_dev->width || | 4352 | if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width || |
4349 | (in[10] + 1) * 8 != gspca_dev->height) { | 4353 | (in[10] + 1) * 8 != gspca_dev->pixfmt.height) { |
4350 | PERR("Invalid frame size, got: %dx%d," | 4354 | PERR("Invalid frame size, got: %dx%d," |
4351 | " requested: %dx%d\n", | 4355 | " requested: %dx%d\n", |
4352 | (in[9] + 1) * 8, (in[10] + 1) * 8, | 4356 | (in[9] + 1) * 8, (in[10] + 1) * 8, |
4353 | gspca_dev->width, gspca_dev->height); | 4357 | gspca_dev->pixfmt.width, |
4358 | gspca_dev->pixfmt.height); | ||
4354 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4359 | gspca_dev->last_packet_type = DISCARD_PACKET; |
4355 | return; | 4360 | return; |
4356 | } | 4361 | } |
@@ -4470,7 +4475,8 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, | |||
4470 | if (sd->first_frame) { | 4475 | if (sd->first_frame) { |
4471 | sd->first_frame--; | 4476 | sd->first_frame--; |
4472 | if (gspca_dev->image_len < | 4477 | if (gspca_dev->image_len < |
4473 | sd->gspca_dev.width * sd->gspca_dev.height) | 4478 | sd->gspca_dev.pixfmt.width * |
4479 | sd->gspca_dev.pixfmt.height) | ||
4474 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4480 | gspca_dev->last_packet_type = DISCARD_PACKET; |
4475 | } | 4481 | } |
4476 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | 4482 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c index 03a33c46ca2c..90f0d637cd9d 100644 --- a/drivers/media/usb/gspca/ov534.c +++ b/drivers/media/usb/gspca/ov534.c | |||
@@ -1440,9 +1440,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1440 | /* If this packet is marked as EOF, end the frame */ | 1440 | /* If this packet is marked as EOF, end the frame */ |
1441 | } else if (data[1] & UVC_STREAM_EOF) { | 1441 | } else if (data[1] & UVC_STREAM_EOF) { |
1442 | sd->last_pts = 0; | 1442 | sd->last_pts = 0; |
1443 | if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV | 1443 | if (gspca_dev->pixfmt.pixelformat == V4L2_PIX_FMT_YUYV |
1444 | && gspca_dev->image_len + len - 12 != | 1444 | && gspca_dev->image_len + len - 12 != |
1445 | gspca_dev->width * gspca_dev->height * 2) { | 1445 | gspca_dev->pixfmt.width * |
1446 | gspca_dev->pixfmt.height * 2) { | ||
1446 | PDEBUG(D_PACK, "wrong sized frame"); | 1447 | PDEBUG(D_PACK, "wrong sized frame"); |
1447 | goto discard; | 1448 | goto discard; |
1448 | } | 1449 | } |
diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c index c4cd028fe0b4..47085cf2d723 100644 --- a/drivers/media/usb/gspca/ov534_9.c +++ b/drivers/media/usb/gspca/ov534_9.c | |||
@@ -59,6 +59,7 @@ enum sensors { | |||
59 | SENSOR_OV965x, /* ov9657 */ | 59 | SENSOR_OV965x, /* ov9657 */ |
60 | SENSOR_OV971x, /* ov9712 */ | 60 | SENSOR_OV971x, /* ov9712 */ |
61 | SENSOR_OV562x, /* ov5621 */ | 61 | SENSOR_OV562x, /* ov5621 */ |
62 | SENSOR_OV361x, /* ov3610 */ | ||
62 | NSENSORS | 63 | NSENSORS |
63 | }; | 64 | }; |
64 | 65 | ||
@@ -106,6 +107,274 @@ static const struct v4l2_pix_format ov562x_mode[] = { | |||
106 | } | 107 | } |
107 | }; | 108 | }; |
108 | 109 | ||
110 | enum ov361x { | ||
111 | ov361x_2048 = 0, | ||
112 | ov361x_1600, | ||
113 | ov361x_1024, | ||
114 | ov361x_640, | ||
115 | ov361x_320, | ||
116 | ov361x_160, | ||
117 | ov361x_last | ||
118 | }; | ||
119 | |||
120 | static const struct v4l2_pix_format ov361x_mode[] = { | ||
121 | {0x800, 0x600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
122 | .bytesperline = 0x800, | ||
123 | .sizeimage = 0x800 * 0x600, | ||
124 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
125 | {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
126 | .bytesperline = 1600, | ||
127 | .sizeimage = 1600 * 1200, | ||
128 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
129 | {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
130 | .bytesperline = 768, | ||
131 | .sizeimage = 1024 * 768, | ||
132 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
133 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
134 | .bytesperline = 640, | ||
135 | .sizeimage = 640 * 480, | ||
136 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
137 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
138 | .bytesperline = 320, | ||
139 | .sizeimage = 320 * 240, | ||
140 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
141 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
142 | .bytesperline = 160, | ||
143 | .sizeimage = 160 * 120, | ||
144 | .colorspace = V4L2_COLORSPACE_SRGB} | ||
145 | }; | ||
146 | |||
147 | static const u8 ov361x_start_2048[][2] = { | ||
148 | {0x12, 0x80}, | ||
149 | {0x13, 0xcf}, | ||
150 | {0x14, 0x40}, | ||
151 | {0x15, 0x00}, | ||
152 | {0x01, 0x80}, | ||
153 | {0x02, 0x80}, | ||
154 | {0x04, 0x70}, | ||
155 | {0x0d, 0x40}, | ||
156 | {0x0f, 0x47}, | ||
157 | {0x11, 0x81}, | ||
158 | {0x32, 0x36}, | ||
159 | {0x33, 0x0c}, | ||
160 | {0x34, 0x00}, | ||
161 | {0x35, 0x90}, | ||
162 | {0x12, 0x00}, | ||
163 | {0x17, 0x10}, | ||
164 | {0x18, 0x90}, | ||
165 | {0x19, 0x00}, | ||
166 | {0x1a, 0xc0}, | ||
167 | }; | ||
168 | static const u8 ov361x_bridge_start_2048[][2] = { | ||
169 | {0xf1, 0x60}, | ||
170 | {0x88, 0x00}, | ||
171 | {0x89, 0x08}, | ||
172 | {0x8a, 0x00}, | ||
173 | {0x8b, 0x06}, | ||
174 | {0x8c, 0x01}, | ||
175 | {0x8d, 0x10}, | ||
176 | {0x1c, 0x00}, | ||
177 | {0x1d, 0x48}, | ||
178 | {0x1d, 0x00}, | ||
179 | {0x1d, 0xff}, | ||
180 | {0x1c, 0x0a}, | ||
181 | {0x1d, 0x2e}, | ||
182 | {0x1d, 0x1e}, | ||
183 | }; | ||
184 | |||
185 | static const u8 ov361x_start_1600[][2] = { | ||
186 | {0x12, 0x80}, | ||
187 | {0x13, 0xcf}, | ||
188 | {0x14, 0x40}, | ||
189 | {0x15, 0x00}, | ||
190 | {0x01, 0x80}, | ||
191 | {0x02, 0x80}, | ||
192 | {0x04, 0x70}, | ||
193 | {0x0d, 0x40}, | ||
194 | {0x0f, 0x47}, | ||
195 | {0x11, 0x81}, | ||
196 | {0x32, 0x36}, | ||
197 | {0x33, 0x0C}, | ||
198 | {0x34, 0x00}, | ||
199 | {0x35, 0x90}, | ||
200 | {0x12, 0x00}, | ||
201 | {0x17, 0x10}, | ||
202 | {0x18, 0x90}, | ||
203 | {0x19, 0x00}, | ||
204 | {0x1a, 0xc0}, | ||
205 | }; | ||
206 | static const u8 ov361x_bridge_start_1600[][2] = { | ||
207 | {0xf1, 0x60}, /* Hsize[7:0] */ | ||
208 | {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ | ||
209 | {0x89, 0x08}, /* Vsize[7:0] */ | ||
210 | {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ | ||
211 | {0x8b, 0x06}, /* for Iso */ | ||
212 | {0x8c, 0x01}, /* RAW input */ | ||
213 | {0x8d, 0x10}, | ||
214 | {0x1c, 0x00}, /* RAW output, Iso transfer */ | ||
215 | {0x1d, 0x48}, | ||
216 | {0x1d, 0x00}, | ||
217 | {0x1d, 0xff}, | ||
218 | {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ | ||
219 | {0x1d, 0x2e}, /* for Iso */ | ||
220 | {0x1d, 0x1e}, | ||
221 | }; | ||
222 | |||
223 | static const u8 ov361x_start_1024[][2] = { | ||
224 | {0x12, 0x80}, | ||
225 | {0x13, 0xcf}, | ||
226 | {0x14, 0x40}, | ||
227 | {0x15, 0x00}, | ||
228 | {0x01, 0x80}, | ||
229 | {0x02, 0x80}, | ||
230 | {0x04, 0x70}, | ||
231 | {0x0d, 0x40}, | ||
232 | {0x0f, 0x47}, | ||
233 | {0x11, 0x81}, | ||
234 | {0x32, 0x36}, | ||
235 | {0x33, 0x0C}, | ||
236 | {0x34, 0x00}, | ||
237 | {0x35, 0x90}, | ||
238 | {0x12, 0x40}, | ||
239 | {0x17, 0x1f}, | ||
240 | {0x18, 0x5f}, | ||
241 | {0x19, 0x00}, | ||
242 | {0x1a, 0x68}, | ||
243 | }; | ||
244 | static const u8 ov361x_bridge_start_1024[][2] = { | ||
245 | {0xf1, 0x60}, /* Hsize[7:0] */ | ||
246 | {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ | ||
247 | {0x89, 0x04}, /* Vsize[7:0] */ | ||
248 | {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ | ||
249 | {0x8b, 0x03}, /* for Iso */ | ||
250 | {0x8c, 0x01}, /* RAW input */ | ||
251 | {0x8d, 0x10}, | ||
252 | {0x1c, 0x00}, /* RAW output, Iso transfer */ | ||
253 | {0x1d, 0x48}, | ||
254 | {0x1d, 0x00}, | ||
255 | {0x1d, 0xff}, | ||
256 | {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ | ||
257 | {0x1d, 0x2e}, /* for Iso */ | ||
258 | {0x1d, 0x1e}, | ||
259 | }; | ||
260 | |||
261 | static const u8 ov361x_start_640[][2] = { | ||
262 | {0x12, 0x80}, | ||
263 | {0x13, 0xcf}, | ||
264 | {0x14, 0x40}, | ||
265 | {0x15, 0x00}, | ||
266 | {0x01, 0x80}, | ||
267 | {0x02, 0x80}, | ||
268 | {0x04, 0x70}, | ||
269 | {0x0d, 0x40}, | ||
270 | {0x0f, 0x47}, | ||
271 | {0x11, 0x81}, | ||
272 | {0x32, 0x36}, | ||
273 | {0x33, 0x0C}, | ||
274 | {0x34, 0x00}, | ||
275 | {0x35, 0x90}, | ||
276 | {0x12, 0x40}, | ||
277 | {0x17, 0x1f}, | ||
278 | {0x18, 0x5f}, | ||
279 | {0x19, 0x00}, | ||
280 | {0x1a, 0x68}, | ||
281 | }; | ||
282 | |||
283 | static const u8 ov361x_bridge_start_640[][2] = { | ||
284 | {0xf1, 0x60}, /* Hsize[7:0]*/ | ||
285 | {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ | ||
286 | {0x89, 0x04}, /* Vsize[7:0] */ | ||
287 | {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ | ||
288 | {0x8b, 0x03}, /* for Iso */ | ||
289 | {0x8c, 0x01}, /* RAW input */ | ||
290 | {0x8d, 0x10}, | ||
291 | {0x1c, 0x00}, /* RAW output, Iso transfer */ | ||
292 | {0x1d, 0x48}, | ||
293 | {0x1d, 0x00}, | ||
294 | {0x1d, 0xff}, | ||
295 | {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ | ||
296 | {0x1d, 0x2e}, /* for Iso */ | ||
297 | {0x1d, 0x1e}, | ||
298 | }; | ||
299 | |||
300 | static const u8 ov361x_start_320[][2] = { | ||
301 | {0x12, 0x80}, | ||
302 | {0x13, 0xcf}, | ||
303 | {0x14, 0x40}, | ||
304 | {0x15, 0x00}, | ||
305 | {0x01, 0x80}, | ||
306 | {0x02, 0x80}, | ||
307 | {0x04, 0x70}, | ||
308 | {0x0d, 0x40}, | ||
309 | {0x0f, 0x47}, | ||
310 | {0x11, 0x81}, | ||
311 | {0x32, 0x36}, | ||
312 | {0x33, 0x0C}, | ||
313 | {0x34, 0x00}, | ||
314 | {0x35, 0x90}, | ||
315 | {0x12, 0x40}, | ||
316 | {0x17, 0x1f}, | ||
317 | {0x18, 0x5f}, | ||
318 | {0x19, 0x00}, | ||
319 | {0x1a, 0x68}, | ||
320 | }; | ||
321 | |||
322 | static const u8 ov361x_bridge_start_320[][2] = { | ||
323 | {0xf1, 0x60}, /* Hsize[7:0] */ | ||
324 | {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ | ||
325 | {0x89, 0x04}, /* Vsize[7:0] */ | ||
326 | {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ | ||
327 | {0x8b, 0x03}, /* for Iso */ | ||
328 | {0x8c, 0x01}, /* RAW input */ | ||
329 | {0x8d, 0x10}, | ||
330 | {0x1c, 0x00}, /* RAW output, Iso transfer; */ | ||
331 | {0x1d, 0x48}, | ||
332 | {0x1d, 0x00}, | ||
333 | {0x1d, 0xff}, | ||
334 | {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ | ||
335 | {0x1d, 0x2e}, /* for Iso */ | ||
336 | {0x1d, 0x1e}, | ||
337 | }; | ||
338 | |||
339 | static const u8 ov361x_start_160[][2] = { | ||
340 | {0x12, 0x80}, | ||
341 | {0x13, 0xcf}, | ||
342 | {0x14, 0x40}, | ||
343 | {0x15, 0x00}, | ||
344 | {0x01, 0x80}, | ||
345 | {0x02, 0x80}, | ||
346 | {0x04, 0x70}, | ||
347 | {0x0d, 0x40}, | ||
348 | {0x0f, 0x47}, | ||
349 | {0x11, 0x81}, | ||
350 | {0x32, 0x36}, | ||
351 | {0x33, 0x0C}, | ||
352 | {0x34, 0x00}, | ||
353 | {0x35, 0x90}, | ||
354 | {0x12, 0x40}, | ||
355 | {0x17, 0x1f}, | ||
356 | {0x18, 0x5f}, | ||
357 | {0x19, 0x00}, | ||
358 | {0x1a, 0x68}, | ||
359 | }; | ||
360 | |||
361 | static const u8 ov361x_bridge_start_160[][2] = { | ||
362 | {0xf1, 0x60}, /* Hsize[7:0] */ | ||
363 | {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ | ||
364 | {0x89, 0x04}, /* Vsize[7:0] */ | ||
365 | {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ | ||
366 | {0x8b, 0x03}, /* for Iso */ | ||
367 | {0x8c, 0x01}, /* RAW input */ | ||
368 | {0x8d, 0x10}, | ||
369 | {0x1c, 0x00}, /* RAW output, Iso transfer */ | ||
370 | {0x1d, 0x48}, | ||
371 | {0x1d, 0x00}, | ||
372 | {0x1d, 0xff}, | ||
373 | {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ | ||
374 | {0x1d, 0x2e}, /* for Iso */ | ||
375 | {0x1d, 0x1e}, | ||
376 | }; | ||
377 | |||
109 | static const u8 bridge_init[][2] = { | 378 | static const u8 bridge_init[][2] = { |
110 | {0x88, 0xf8}, | 379 | {0x88, 0xf8}, |
111 | {0x89, 0xff}, | 380 | {0x89, 0xff}, |
@@ -898,7 +1167,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) | |||
898 | int i; | 1167 | int i; |
899 | 1168 | ||
900 | for (i = 0; i < 5; i++) { | 1169 | for (i = 0; i < 5; i++) { |
901 | msleep(10); | 1170 | msleep(20); |
902 | data = reg_r(gspca_dev, OV534_REG_STATUS); | 1171 | data = reg_r(gspca_dev, OV534_REG_STATUS); |
903 | 1172 | ||
904 | switch (data) { | 1173 | switch (data) { |
@@ -1221,6 +1490,13 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1221 | sccb_w_array(gspca_dev, ov562x_init_2, | 1490 | sccb_w_array(gspca_dev, ov562x_init_2, |
1222 | ARRAY_SIZE(ov562x_init_2)); | 1491 | ARRAY_SIZE(ov562x_init_2)); |
1223 | reg_w(gspca_dev, 0xe0, 0x00); | 1492 | reg_w(gspca_dev, 0xe0, 0x00); |
1493 | } else if ((sensor_id & 0xfff0) == 0x3610) { | ||
1494 | sd->sensor = SENSOR_OV361x; | ||
1495 | gspca_dev->cam.cam_mode = ov361x_mode; | ||
1496 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov361x_mode); | ||
1497 | reg_w(gspca_dev, 0xe7, 0x3a); | ||
1498 | reg_w(gspca_dev, 0xf1, 0x60); | ||
1499 | sccb_write(gspca_dev, 0x12, 0x80); | ||
1224 | } else { | 1500 | } else { |
1225 | pr_err("Unknown sensor %04x", sensor_id); | 1501 | pr_err("Unknown sensor %04x", sensor_id); |
1226 | return -EINVAL; | 1502 | return -EINVAL; |
@@ -1229,6 +1505,53 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1229 | return gspca_dev->usb_err; | 1505 | return gspca_dev->usb_err; |
1230 | } | 1506 | } |
1231 | 1507 | ||
1508 | static int sd_start_ov361x(struct gspca_dev *gspca_dev) | ||
1509 | { | ||
1510 | sccb_write(gspca_dev, 0x12, 0x80); | ||
1511 | msleep(20); | ||
1512 | switch (gspca_dev->curr_mode % (ov361x_last)) { | ||
1513 | case ov361x_2048: | ||
1514 | reg_w_array(gspca_dev, ov361x_bridge_start_2048, | ||
1515 | ARRAY_SIZE(ov361x_bridge_start_2048)); | ||
1516 | sccb_w_array(gspca_dev, ov361x_start_2048, | ||
1517 | ARRAY_SIZE(ov361x_start_2048)); | ||
1518 | break; | ||
1519 | case ov361x_1600: | ||
1520 | reg_w_array(gspca_dev, ov361x_bridge_start_1600, | ||
1521 | ARRAY_SIZE(ov361x_bridge_start_1600)); | ||
1522 | sccb_w_array(gspca_dev, ov361x_start_1600, | ||
1523 | ARRAY_SIZE(ov361x_start_1600)); | ||
1524 | break; | ||
1525 | case ov361x_1024: | ||
1526 | reg_w_array(gspca_dev, ov361x_bridge_start_1024, | ||
1527 | ARRAY_SIZE(ov361x_bridge_start_1024)); | ||
1528 | sccb_w_array(gspca_dev, ov361x_start_1024, | ||
1529 | ARRAY_SIZE(ov361x_start_1024)); | ||
1530 | break; | ||
1531 | case ov361x_640: | ||
1532 | reg_w_array(gspca_dev, ov361x_bridge_start_640, | ||
1533 | ARRAY_SIZE(ov361x_bridge_start_640)); | ||
1534 | sccb_w_array(gspca_dev, ov361x_start_640, | ||
1535 | ARRAY_SIZE(ov361x_start_640)); | ||
1536 | break; | ||
1537 | case ov361x_320: | ||
1538 | reg_w_array(gspca_dev, ov361x_bridge_start_320, | ||
1539 | ARRAY_SIZE(ov361x_bridge_start_320)); | ||
1540 | sccb_w_array(gspca_dev, ov361x_start_320, | ||
1541 | ARRAY_SIZE(ov361x_start_320)); | ||
1542 | break; | ||
1543 | case ov361x_160: | ||
1544 | reg_w_array(gspca_dev, ov361x_bridge_start_160, | ||
1545 | ARRAY_SIZE(ov361x_bridge_start_160)); | ||
1546 | sccb_w_array(gspca_dev, ov361x_start_160, | ||
1547 | ARRAY_SIZE(ov361x_start_160)); | ||
1548 | break; | ||
1549 | } | ||
1550 | reg_w(gspca_dev, 0xe0, 0x00); /* start transfer */ | ||
1551 | |||
1552 | return gspca_dev->usb_err; | ||
1553 | } | ||
1554 | |||
1232 | static int sd_start(struct gspca_dev *gspca_dev) | 1555 | static int sd_start(struct gspca_dev *gspca_dev) |
1233 | { | 1556 | { |
1234 | struct sd *sd = (struct sd *) gspca_dev; | 1557 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1237,6 +1560,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1237 | return gspca_dev->usb_err; | 1560 | return gspca_dev->usb_err; |
1238 | if (sd->sensor == SENSOR_OV562x) | 1561 | if (sd->sensor == SENSOR_OV562x) |
1239 | return gspca_dev->usb_err; | 1562 | return gspca_dev->usb_err; |
1563 | if (sd->sensor == SENSOR_OV361x) | ||
1564 | return sd_start_ov361x(gspca_dev); | ||
1240 | 1565 | ||
1241 | switch (gspca_dev->curr_mode) { | 1566 | switch (gspca_dev->curr_mode) { |
1242 | case QVGA_MODE: /* 320x240 */ | 1567 | case QVGA_MODE: /* 320x240 */ |
@@ -1290,6 +1615,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1290 | 1615 | ||
1291 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1616 | static void sd_stopN(struct gspca_dev *gspca_dev) |
1292 | { | 1617 | { |
1618 | if (((struct sd *)gspca_dev)->sensor == SENSOR_OV361x) { | ||
1619 | reg_w(gspca_dev, 0xe0, 0x01); /* stop transfer */ | ||
1620 | /* reg_w(gspca_dev, 0x31, 0x09); */ | ||
1621 | return; | ||
1622 | } | ||
1293 | reg_w(gspca_dev, 0xe0, 0x01); | 1623 | reg_w(gspca_dev, 0xe0, 0x01); |
1294 | set_led(gspca_dev, 0); | 1624 | set_led(gspca_dev, 0); |
1295 | reg_w(gspca_dev, 0xe0, 0x00); | 1625 | reg_w(gspca_dev, 0xe0, 0x00); |
@@ -1425,6 +1755,8 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) | |||
1425 | 1755 | ||
1426 | if (sd->sensor == SENSOR_OV971x) | 1756 | if (sd->sensor == SENSOR_OV971x) |
1427 | return 0; | 1757 | return 0; |
1758 | if (sd->sensor == SENSOR_OV361x) | ||
1759 | return 0; | ||
1428 | gspca_dev->vdev.ctrl_handler = hdl; | 1760 | gspca_dev->vdev.ctrl_handler = hdl; |
1429 | v4l2_ctrl_handler_init(hdl, 7); | 1761 | v4l2_ctrl_handler_init(hdl, 7); |
1430 | if (sd->sensor == SENSOR_OV562x) { | 1762 | if (sd->sensor == SENSOR_OV562x) { |
diff --git a/drivers/media/usb/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c index 83519be94e58..cd79c180f67b 100644 --- a/drivers/media/usb/gspca/pac207.c +++ b/drivers/media/usb/gspca/pac207.c | |||
@@ -299,7 +299,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
299 | pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8); | 299 | pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8); |
300 | 300 | ||
301 | /* Compression Balance */ | 301 | /* Compression Balance */ |
302 | if (gspca_dev->width == 176) | 302 | if (gspca_dev->pixfmt.width == 176) |
303 | pac207_write_reg(gspca_dev, 0x4a, 0xff); | 303 | pac207_write_reg(gspca_dev, 0x4a, 0xff); |
304 | else | 304 | else |
305 | pac207_write_reg(gspca_dev, 0x4a, 0x30); | 305 | pac207_write_reg(gspca_dev, 0x4a, 0x30); |
@@ -317,7 +317,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
317 | mode = 0x00; | 317 | mode = 0x00; |
318 | else | 318 | else |
319 | mode = 0x02; | 319 | mode = 0x02; |
320 | if (gspca_dev->width == 176) { /* 176x144 */ | 320 | if (gspca_dev->pixfmt.width == 176) { /* 176x144 */ |
321 | mode |= 0x01; | 321 | mode |= 0x01; |
322 | PDEBUG(D_STREAM, "pac207_start mode 176x144"); | 322 | PDEBUG(D_STREAM, "pac207_start mode 176x144"); |
323 | } else { /* 352x288 */ | 323 | } else { /* 352x288 */ |
diff --git a/drivers/media/usb/gspca/pac7311.c b/drivers/media/usb/gspca/pac7311.c index 1a5bdc853a80..25f86b1e74a8 100644 --- a/drivers/media/usb/gspca/pac7311.c +++ b/drivers/media/usb/gspca/pac7311.c | |||
@@ -326,7 +326,7 @@ static void setexposure(struct gspca_dev *gspca_dev, s32 val) | |||
326 | * 640x480 mode and page 4 reg 2 <= 3 then it must be 9 | 326 | * 640x480 mode and page 4 reg 2 <= 3 then it must be 9 |
327 | */ | 327 | */ |
328 | reg_w(gspca_dev, 0xff, 0x01); | 328 | reg_w(gspca_dev, 0xff, 0x01); |
329 | if (gspca_dev->width != 640 && val <= 3) | 329 | if (gspca_dev->pixfmt.width != 640 && val <= 3) |
330 | reg_w(gspca_dev, 0x08, 0x09); | 330 | reg_w(gspca_dev, 0x08, 0x09); |
331 | else | 331 | else |
332 | reg_w(gspca_dev, 0x08, 0x08); | 332 | reg_w(gspca_dev, 0x08, 0x08); |
@@ -337,7 +337,7 @@ static void setexposure(struct gspca_dev *gspca_dev, s32 val) | |||
337 | * camera to use higher compression or we may run out of | 337 | * camera to use higher compression or we may run out of |
338 | * bandwidth. | 338 | * bandwidth. |
339 | */ | 339 | */ |
340 | if (gspca_dev->width == 640 && val == 2) | 340 | if (gspca_dev->pixfmt.width == 640 && val == 2) |
341 | reg_w(gspca_dev, 0x80, 0x01); | 341 | reg_w(gspca_dev, 0x80, 0x01); |
342 | else | 342 | else |
343 | reg_w(gspca_dev, 0x80, 0x1c); | 343 | reg_w(gspca_dev, 0x80, 0x1c); |
@@ -615,7 +615,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
615 | 615 | ||
616 | /* Start the new frame with the jpeg header */ | 616 | /* Start the new frame with the jpeg header */ |
617 | pac_start_frame(gspca_dev, | 617 | pac_start_frame(gspca_dev, |
618 | gspca_dev->height, gspca_dev->width); | 618 | gspca_dev->pixfmt.height, gspca_dev->pixfmt.width); |
619 | } | 619 | } |
620 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 620 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
621 | } | 621 | } |
diff --git a/drivers/media/usb/gspca/se401.c b/drivers/media/usb/gspca/se401.c index 5f729b8aa2bd..5102cea50471 100644 --- a/drivers/media/usb/gspca/se401.c +++ b/drivers/media/usb/gspca/se401.c | |||
@@ -354,9 +354,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
354 | 354 | ||
355 | /* set size + mode */ | 355 | /* set size + mode */ |
356 | se401_write_req(gspca_dev, SE401_REQ_SET_WIDTH, | 356 | se401_write_req(gspca_dev, SE401_REQ_SET_WIDTH, |
357 | gspca_dev->width * mult, 0); | 357 | gspca_dev->pixfmt.width * mult, 0); |
358 | se401_write_req(gspca_dev, SE401_REQ_SET_HEIGHT, | 358 | se401_write_req(gspca_dev, SE401_REQ_SET_HEIGHT, |
359 | gspca_dev->height * mult, 0); | 359 | gspca_dev->pixfmt.height * mult, 0); |
360 | /* | 360 | /* |
361 | * HDG: disabled this as it does not seem to do anything | 361 | * HDG: disabled this as it does not seem to do anything |
362 | * se401_write_req(gspca_dev, SE401_REQ_SET_OUTPUT_MODE, | 362 | * se401_write_req(gspca_dev, SE401_REQ_SET_OUTPUT_MODE, |
@@ -480,7 +480,7 @@ static void sd_complete_frame(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
480 | static void sd_pkt_scan_janggu(struct gspca_dev *gspca_dev, u8 *data, int len) | 480 | static void sd_pkt_scan_janggu(struct gspca_dev *gspca_dev, u8 *data, int len) |
481 | { | 481 | { |
482 | struct sd *sd = (struct sd *)gspca_dev; | 482 | struct sd *sd = (struct sd *)gspca_dev; |
483 | int imagesize = gspca_dev->width * gspca_dev->height; | 483 | int imagesize = gspca_dev->pixfmt.width * gspca_dev->pixfmt.height; |
484 | int i, plen, bits, pixels, info, count; | 484 | int i, plen, bits, pixels, info, count; |
485 | 485 | ||
486 | if (sd->restart_stream) | 486 | if (sd->restart_stream) |
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c index f4453d52801b..2a38621cf718 100644 --- a/drivers/media/usb/gspca/sn9c20x.c +++ b/drivers/media/usb/gspca/sn9c20x.c | |||
@@ -1955,7 +1955,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) | |||
1955 | return 0; | 1955 | return 0; |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | switch (gspca_dev->width) { | 1958 | switch (gspca_dev->pixfmt.width) { |
1959 | case 160: /* 160x120 */ | 1959 | case 160: /* 160x120 */ |
1960 | gspca_dev->alt = 2; | 1960 | gspca_dev->alt = 2; |
1961 | break; | 1961 | break; |
@@ -1985,8 +1985,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1985 | { | 1985 | { |
1986 | struct sd *sd = (struct sd *) gspca_dev; | 1986 | struct sd *sd = (struct sd *) gspca_dev; |
1987 | int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 1987 | int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; |
1988 | int width = gspca_dev->width; | 1988 | int width = gspca_dev->pixfmt.width; |
1989 | int height = gspca_dev->height; | 1989 | int height = gspca_dev->pixfmt.height; |
1990 | u8 fmt, scale = 0; | 1990 | u8 fmt, scale = 0; |
1991 | 1991 | ||
1992 | jpeg_define(sd->jpeg_hdr, height, width, | 1992 | jpeg_define(sd->jpeg_hdr, height, width, |
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index d7ff3b9687c5..7277dbd2afcd 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c | |||
@@ -513,10 +513,7 @@ static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buf) | |||
513 | if (gspca_dev->usb_buf[0] & 0x04) { | 513 | if (gspca_dev->usb_buf[0] & 0x04) { |
514 | if (gspca_dev->usb_buf[0] & 0x08) { | 514 | if (gspca_dev->usb_buf[0] & 0x08) { |
515 | dev_err(gspca_dev->v4l2_dev.dev, | 515 | dev_err(gspca_dev->v4l2_dev.dev, |
516 | "i2c error writing %02x %02x %02x %02x" | 516 | "i2c error writing %8ph\n", buf); |
517 | " %02x %02x %02x %02x\n", | ||
518 | buf[0], buf[1], buf[2], buf[3], | ||
519 | buf[4], buf[5], buf[6], buf[7]); | ||
520 | gspca_dev->usb_err = -EIO; | 517 | gspca_dev->usb_err = -EIO; |
521 | } | 518 | } |
522 | return; | 519 | return; |
@@ -753,7 +750,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
753 | /* In 640x480, if the reg11 has less than 4, the image is | 750 | /* In 640x480, if the reg11 has less than 4, the image is |
754 | unstable (the bridge goes into a higher compression mode | 751 | unstable (the bridge goes into a higher compression mode |
755 | which we have not reverse engineered yet). */ | 752 | which we have not reverse engineered yet). */ |
756 | if (gspca_dev->width == 640 && reg11 < 4) | 753 | if (gspca_dev->pixfmt.width == 640 && reg11 < 4) |
757 | reg11 = 4; | 754 | reg11 = 4; |
758 | 755 | ||
759 | /* frame exposure time in ms = 1000 * reg11 / 30 -> | 756 | /* frame exposure time in ms = 1000 * reg11 / 30 -> |
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index 3b5ccb1c4cdf..c69b45d7cfbf 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c | |||
@@ -2204,7 +2204,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2204 | { 0x14, 0xe7, 0x1e, 0xdd }; | 2204 | { 0x14, 0xe7, 0x1e, 0xdd }; |
2205 | 2205 | ||
2206 | /* create the JPEG header */ | 2206 | /* create the JPEG header */ |
2207 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 2207 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
2208 | gspca_dev->pixfmt.width, | ||
2208 | 0x21); /* JPEG 422 */ | 2209 | 0x21); /* JPEG 422 */ |
2209 | 2210 | ||
2210 | /* initialize the bridge */ | 2211 | /* initialize the bridge */ |
diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c index 688592b289ea..f38fd8949609 100644 --- a/drivers/media/usb/gspca/spca1528.c +++ b/drivers/media/usb/gspca/spca1528.c | |||
@@ -255,7 +255,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
255 | struct sd *sd = (struct sd *) gspca_dev; | 255 | struct sd *sd = (struct sd *) gspca_dev; |
256 | 256 | ||
257 | /* initialize the JPEG header */ | 257 | /* initialize the JPEG header */ |
258 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 258 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
259 | gspca_dev->pixfmt.width, | ||
259 | 0x22); /* JPEG 411 */ | 260 | 0x22); /* JPEG 411 */ |
260 | 261 | ||
261 | /* the JPEG quality shall be 85% */ | 262 | /* the JPEG quality shall be 85% */ |
diff --git a/drivers/media/usb/gspca/spca500.c b/drivers/media/usb/gspca/spca500.c index 9f8bf51fd64b..f011a309dd65 100644 --- a/drivers/media/usb/gspca/spca500.c +++ b/drivers/media/usb/gspca/spca500.c | |||
@@ -608,7 +608,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
608 | __u8 xmult, ymult; | 608 | __u8 xmult, ymult; |
609 | 609 | ||
610 | /* create the JPEG header */ | 610 | /* create the JPEG header */ |
611 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 611 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
612 | gspca_dev->pixfmt.width, | ||
612 | 0x22); /* JPEG 411 */ | 613 | 0x22); /* JPEG 411 */ |
613 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); | 614 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
614 | 615 | ||
diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c index acb19fb9a3df..aa21edc9502d 100644 --- a/drivers/media/usb/gspca/sq905c.c +++ b/drivers/media/usb/gspca/sq905c.c | |||
@@ -272,7 +272,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
272 | 272 | ||
273 | dev->cap_mode = gspca_dev->cam.cam_mode; | 273 | dev->cap_mode = gspca_dev->cam.cam_mode; |
274 | /* "Open the shutter" and set size, to start capture */ | 274 | /* "Open the shutter" and set size, to start capture */ |
275 | switch (gspca_dev->width) { | 275 | switch (gspca_dev->pixfmt.width) { |
276 | case 640: | 276 | case 640: |
277 | PDEBUG(D_STREAM, "Start streaming at high resolution"); | 277 | PDEBUG(D_STREAM, "Start streaming at high resolution"); |
278 | dev->cap_mode++; | 278 | dev->cap_mode++; |
diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c index b10d0821111c..e274cf19a3ea 100644 --- a/drivers/media/usb/gspca/sq930x.c +++ b/drivers/media/usb/gspca/sq930x.c | |||
@@ -906,7 +906,8 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) | |||
906 | 906 | ||
907 | gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */ | 907 | gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */ |
908 | sd->do_ctrl = 0; | 908 | sd->do_ctrl = 0; |
909 | gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8; | 909 | gspca_dev->cam.bulk_size = gspca_dev->pixfmt.width * |
910 | gspca_dev->pixfmt.height + 8; | ||
910 | return 0; | 911 | return 0; |
911 | } | 912 | } |
912 | 913 | ||
diff --git a/drivers/media/usb/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c index 8c0982607f25..b0c70fea760b 100644 --- a/drivers/media/usb/gspca/stk014.c +++ b/drivers/media/usb/gspca/stk014.c | |||
@@ -250,7 +250,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
250 | int ret, value; | 250 | int ret, value; |
251 | 251 | ||
252 | /* create the JPEG header */ | 252 | /* create the JPEG header */ |
253 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 253 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
254 | gspca_dev->pixfmt.width, | ||
254 | 0x22); /* JPEG 411 */ | 255 | 0x22); /* JPEG 411 */ |
255 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); | 256 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
256 | 257 | ||
@@ -261,7 +262,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
261 | set_par(gspca_dev, 0x00000000); | 262 | set_par(gspca_dev, 0x00000000); |
262 | set_par(gspca_dev, 0x8002e001); | 263 | set_par(gspca_dev, 0x8002e001); |
263 | set_par(gspca_dev, 0x14000000); | 264 | set_par(gspca_dev, 0x14000000); |
264 | if (gspca_dev->width > 320) | 265 | if (gspca_dev->pixfmt.width > 320) |
265 | value = 0x8002e001; /* 640x480 */ | 266 | value = 0x8002e001; /* 640x480 */ |
266 | else | 267 | else |
267 | value = 0x4001f000; /* 320x240 */ | 268 | value = 0x4001f000; /* 320x240 */ |
diff --git a/drivers/media/usb/gspca/stk1135.c b/drivers/media/usb/gspca/stk1135.c index 585868835ace..1fc80af2a189 100644 --- a/drivers/media/usb/gspca/stk1135.c +++ b/drivers/media/usb/gspca/stk1135.c | |||
@@ -48,42 +48,11 @@ struct sd { | |||
48 | }; | 48 | }; |
49 | 49 | ||
50 | static const struct v4l2_pix_format stk1135_modes[] = { | 50 | static const struct v4l2_pix_format stk1135_modes[] = { |
51 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 51 | /* default mode (this driver supports variable resolution) */ |
52 | .bytesperline = 160, | ||
53 | .sizeimage = 160 * 120, | ||
54 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
55 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
56 | .bytesperline = 176, | ||
57 | .sizeimage = 176 * 144, | ||
58 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
59 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
60 | .bytesperline = 320, | ||
61 | .sizeimage = 320 * 240, | ||
62 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
63 | {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
64 | .bytesperline = 352, | ||
65 | .sizeimage = 352 * 288, | ||
66 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
67 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | 52 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, |
68 | .bytesperline = 640, | 53 | .bytesperline = 640, |
69 | .sizeimage = 640 * 480, | 54 | .sizeimage = 640 * 480, |
70 | .colorspace = V4L2_COLORSPACE_SRGB}, | 55 | .colorspace = V4L2_COLORSPACE_SRGB}, |
71 | {720, 576, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
72 | .bytesperline = 720, | ||
73 | .sizeimage = 720 * 576, | ||
74 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
75 | {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
76 | .bytesperline = 800, | ||
77 | .sizeimage = 800 * 600, | ||
78 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
79 | {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
80 | .bytesperline = 1024, | ||
81 | .sizeimage = 1024 * 768, | ||
82 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
83 | {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
84 | .bytesperline = 1280, | ||
85 | .sizeimage = 1280 * 1024, | ||
86 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
87 | }; | 56 | }; |
88 | 57 | ||
89 | /* -- read a register -- */ | 58 | /* -- read a register -- */ |
@@ -347,16 +316,16 @@ static void stk1135_configure_mt9m112(struct gspca_dev *gspca_dev) | |||
347 | sensor_write(gspca_dev, cfg[i].reg, cfg[i].val); | 316 | sensor_write(gspca_dev, cfg[i].reg, cfg[i].val); |
348 | 317 | ||
349 | /* set output size */ | 318 | /* set output size */ |
350 | width = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].width; | 319 | width = gspca_dev->pixfmt.width; |
351 | height = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].height; | 320 | height = gspca_dev->pixfmt.height; |
352 | if (width <= 640) { /* use context A (half readout speed by default) */ | 321 | if (width <= 640 && height <= 512) { /* context A (half readout speed)*/ |
353 | sensor_write(gspca_dev, 0x1a7, width); | 322 | sensor_write(gspca_dev, 0x1a7, width); |
354 | sensor_write(gspca_dev, 0x1aa, height); | 323 | sensor_write(gspca_dev, 0x1aa, height); |
355 | /* set read mode context A */ | 324 | /* set read mode context A */ |
356 | sensor_write(gspca_dev, 0x0c8, 0x0000); | 325 | sensor_write(gspca_dev, 0x0c8, 0x0000); |
357 | /* set resize, read mode, vblank, hblank context A */ | 326 | /* set resize, read mode, vblank, hblank context A */ |
358 | sensor_write(gspca_dev, 0x2c8, 0x0000); | 327 | sensor_write(gspca_dev, 0x2c8, 0x0000); |
359 | } else { /* use context B (full readout speed by default) */ | 328 | } else { /* context B (full readout speed) */ |
360 | sensor_write(gspca_dev, 0x1a1, width); | 329 | sensor_write(gspca_dev, 0x1a1, width); |
361 | sensor_write(gspca_dev, 0x1a4, height); | 330 | sensor_write(gspca_dev, 0x1a4, height); |
362 | /* set read mode context B */ | 331 | /* set read mode context B */ |
@@ -484,8 +453,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
484 | reg_w(gspca_dev, STK1135_REG_CISPO + 3, 0x00); | 453 | reg_w(gspca_dev, STK1135_REG_CISPO + 3, 0x00); |
485 | 454 | ||
486 | /* set capture end position */ | 455 | /* set capture end position */ |
487 | width = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].width; | 456 | width = gspca_dev->pixfmt.width; |
488 | height = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].height; | 457 | height = gspca_dev->pixfmt.height; |
489 | reg_w(gspca_dev, STK1135_REG_CIEPO + 0, width & 0xff); | 458 | reg_w(gspca_dev, STK1135_REG_CIEPO + 0, width & 0xff); |
490 | reg_w(gspca_dev, STK1135_REG_CIEPO + 1, width >> 8); | 459 | reg_w(gspca_dev, STK1135_REG_CIEPO + 1, width >> 8); |
491 | reg_w(gspca_dev, STK1135_REG_CIEPO + 2, height & 0xff); | 460 | reg_w(gspca_dev, STK1135_REG_CIEPO + 2, height & 0xff); |
@@ -643,6 +612,35 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) | |||
643 | return 0; | 612 | return 0; |
644 | } | 613 | } |
645 | 614 | ||
615 | static void stk1135_try_fmt(struct gspca_dev *gspca_dev, struct v4l2_format *fmt) | ||
616 | { | ||
617 | fmt->fmt.pix.width = clamp(fmt->fmt.pix.width, 32U, 1280U); | ||
618 | fmt->fmt.pix.height = clamp(fmt->fmt.pix.height, 32U, 1024U); | ||
619 | /* round up to even numbers */ | ||
620 | fmt->fmt.pix.width += (fmt->fmt.pix.width & 1); | ||
621 | fmt->fmt.pix.height += (fmt->fmt.pix.height & 1); | ||
622 | |||
623 | fmt->fmt.pix.bytesperline = fmt->fmt.pix.width; | ||
624 | fmt->fmt.pix.sizeimage = fmt->fmt.pix.width * fmt->fmt.pix.height; | ||
625 | } | ||
626 | |||
627 | static int stk1135_enum_framesizes(struct gspca_dev *gspca_dev, | ||
628 | struct v4l2_frmsizeenum *fsize) | ||
629 | { | ||
630 | if (fsize->index != 0 || fsize->pixel_format != V4L2_PIX_FMT_SBGGR8) | ||
631 | return -EINVAL; | ||
632 | |||
633 | fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; | ||
634 | fsize->stepwise.min_width = 32; | ||
635 | fsize->stepwise.min_height = 32; | ||
636 | fsize->stepwise.max_width = 1280; | ||
637 | fsize->stepwise.max_height = 1024; | ||
638 | fsize->stepwise.step_width = 2; | ||
639 | fsize->stepwise.step_height = 2; | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
646 | /* sub-driver description */ | 644 | /* sub-driver description */ |
647 | static const struct sd_desc sd_desc = { | 645 | static const struct sd_desc sd_desc = { |
648 | .name = MODULE_NAME, | 646 | .name = MODULE_NAME, |
@@ -653,6 +651,8 @@ static const struct sd_desc sd_desc = { | |||
653 | .stopN = sd_stopN, | 651 | .stopN = sd_stopN, |
654 | .pkt_scan = sd_pkt_scan, | 652 | .pkt_scan = sd_pkt_scan, |
655 | .dq_callback = stk1135_dq_callback, | 653 | .dq_callback = stk1135_dq_callback, |
654 | .try_fmt = stk1135_try_fmt, | ||
655 | .enum_framesizes = stk1135_enum_framesizes, | ||
656 | }; | 656 | }; |
657 | 657 | ||
658 | /* -- module initialisation -- */ | 658 | /* -- module initialisation -- */ |
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 55ee7a61c67f..49d209bbf9ee 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c | |||
@@ -452,7 +452,7 @@ frame_data: | |||
452 | NULL, 0); | 452 | NULL, 0); |
453 | 453 | ||
454 | if (sd->bridge == BRIDGE_ST6422) | 454 | if (sd->bridge == BRIDGE_ST6422) |
455 | sd->to_skip = gspca_dev->width * 4; | 455 | sd->to_skip = gspca_dev->pixfmt.width * 4; |
456 | 456 | ||
457 | if (chunk_len) | 457 | if (chunk_len) |
458 | PERR("Chunk length is " | 458 | PERR("Chunk length is " |
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c index 8206b7743300..8d785edcccf2 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c | |||
@@ -421,7 +421,7 @@ static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val) | |||
421 | 421 | ||
422 | /* Number of pixels counted by the sensor when subsampling the pixels. | 422 | /* Number of pixels counted by the sensor when subsampling the pixels. |
423 | * Slightly larger than the real value to avoid oscillation */ | 423 | * Slightly larger than the real value to avoid oscillation */ |
424 | totalpixels = gspca_dev->width * gspca_dev->height; | 424 | totalpixels = gspca_dev->pixfmt.width * gspca_dev->pixfmt.height; |
425 | totalpixels = totalpixels/(8*8) + totalpixels/(64*64); | 425 | totalpixels = totalpixels/(8*8) + totalpixels/(64*64); |
426 | 426 | ||
427 | brightpixels = (totalpixels * val) >> 8; | 427 | brightpixels = (totalpixels * val) >> 8; |
diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index af8767a9bd4c..a517d185febe 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c | |||
@@ -715,7 +715,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
715 | int enable; | 715 | int enable; |
716 | 716 | ||
717 | /* create the JPEG header */ | 717 | /* create the JPEG header */ |
718 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 718 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
719 | gspca_dev->pixfmt.width, | ||
719 | 0x22); /* JPEG 411 */ | 720 | 0x22); /* JPEG 411 */ |
720 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); | 721 | jpeg_set_qual(sd->jpeg_hdr, QUALITY); |
721 | 722 | ||
diff --git a/drivers/media/usb/gspca/topro.c b/drivers/media/usb/gspca/topro.c index 4cb511ccc5f6..640c2fe760b3 100644 --- a/drivers/media/usb/gspca/topro.c +++ b/drivers/media/usb/gspca/topro.c | |||
@@ -3856,7 +3856,7 @@ static void setsharpness(struct gspca_dev *gspca_dev, s32 val) | |||
3856 | 3856 | ||
3857 | if (sd->bridge == BRIDGE_TP6800) { | 3857 | if (sd->bridge == BRIDGE_TP6800) { |
3858 | val |= 0x08; /* grid compensation enable */ | 3858 | val |= 0x08; /* grid compensation enable */ |
3859 | if (gspca_dev->width == 640) | 3859 | if (gspca_dev->pixfmt.width == 640) |
3860 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ | 3860 | reg_w(gspca_dev, TP6800_R78_FORMAT, 0x00); /* vga */ |
3861 | else | 3861 | else |
3862 | val |= 0x04; /* scaling down enable */ | 3862 | val |= 0x04; /* scaling down enable */ |
@@ -3880,7 +3880,7 @@ static void set_resolution(struct gspca_dev *gspca_dev) | |||
3880 | struct sd *sd = (struct sd *) gspca_dev; | 3880 | struct sd *sd = (struct sd *) gspca_dev; |
3881 | 3881 | ||
3882 | reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); | 3882 | reg_w(gspca_dev, TP6800_R21_ENDP_1_CTL, 0x00); |
3883 | if (gspca_dev->width == 320) { | 3883 | if (gspca_dev->pixfmt.width == 320) { |
3884 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06); | 3884 | reg_w(gspca_dev, TP6800_R3F_FRAME_RATE, 0x06); |
3885 | msleep(100); | 3885 | msleep(100); |
3886 | i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); | 3886 | i2c_w(gspca_dev, CX0342_AUTO_ADC_CALIB, 0x01); |
@@ -3924,7 +3924,7 @@ static int get_fr_idx(struct gspca_dev *gspca_dev) | |||
3924 | 3924 | ||
3925 | /* 640x480 * 30 fps does not work */ | 3925 | /* 640x480 * 30 fps does not work */ |
3926 | if (i == 6 /* if 30 fps */ | 3926 | if (i == 6 /* if 30 fps */ |
3927 | && gspca_dev->width == 640) | 3927 | && gspca_dev->pixfmt.width == 640) |
3928 | i = 0x05; /* 15 fps */ | 3928 | i = 0x05; /* 15 fps */ |
3929 | } else { | 3929 | } else { |
3930 | for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { | 3930 | for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) { |
@@ -3935,7 +3935,7 @@ static int get_fr_idx(struct gspca_dev *gspca_dev) | |||
3935 | 3935 | ||
3936 | /* 640x480 * 30 fps does not work */ | 3936 | /* 640x480 * 30 fps does not work */ |
3937 | if (i == 7 /* if 30 fps */ | 3937 | if (i == 7 /* if 30 fps */ |
3938 | && gspca_dev->width == 640) | 3938 | && gspca_dev->pixfmt.width == 640) |
3939 | i = 6; /* 15 fps */ | 3939 | i = 6; /* 15 fps */ |
3940 | i |= 0x80; /* clock * 1 */ | 3940 | i |= 0x80; /* clock * 1 */ |
3941 | } | 3941 | } |
@@ -4554,7 +4554,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
4554 | { | 4554 | { |
4555 | struct sd *sd = (struct sd *) gspca_dev; | 4555 | struct sd *sd = (struct sd *) gspca_dev; |
4556 | 4556 | ||
4557 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width); | 4557 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
4558 | gspca_dev->pixfmt.width); | ||
4558 | set_dqt(gspca_dev, sd->quality); | 4559 | set_dqt(gspca_dev, sd->quality); |
4559 | if (sd->bridge == BRIDGE_TP6800) { | 4560 | if (sd->bridge == BRIDGE_TP6800) { |
4560 | if (sd->sensor == SENSOR_CX0342) | 4561 | if (sd->sensor == SENSOR_CX0342) |
@@ -4737,7 +4738,7 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) | |||
4737 | (gspca_dev->usb_buf[26] << 8) + gspca_dev->usb_buf[25] + | 4738 | (gspca_dev->usb_buf[26] << 8) + gspca_dev->usb_buf[25] + |
4738 | (gspca_dev->usb_buf[29] << 8) + gspca_dev->usb_buf[28]) | 4739 | (gspca_dev->usb_buf[29] << 8) + gspca_dev->usb_buf[28]) |
4739 | / 8; | 4740 | / 8; |
4740 | if (gspca_dev->width == 640) | 4741 | if (gspca_dev->pixfmt.width == 640) |
4741 | luma /= 4; | 4742 | luma /= 4; |
4742 | reg_w(gspca_dev, 0x7d, 0x00); | 4743 | reg_w(gspca_dev, 0x7d, 0x00); |
4743 | 4744 | ||
diff --git a/drivers/media/usb/gspca/tv8532.c b/drivers/media/usb/gspca/tv8532.c index 8591324a53e1..d497ba38af0d 100644 --- a/drivers/media/usb/gspca/tv8532.c +++ b/drivers/media/usb/gspca/tv8532.c | |||
@@ -268,7 +268,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
268 | packet_type0 = packet_type1 = INTER_PACKET; | 268 | packet_type0 = packet_type1 = INTER_PACKET; |
269 | if (gspca_dev->empty_packet) { | 269 | if (gspca_dev->empty_packet) { |
270 | gspca_dev->empty_packet = 0; | 270 | gspca_dev->empty_packet = 0; |
271 | sd->packet = gspca_dev->height / 2; | 271 | sd->packet = gspca_dev->pixfmt.height / 2; |
272 | packet_type0 = FIRST_PACKET; | 272 | packet_type0 = FIRST_PACKET; |
273 | } else if (sd->packet == 0) | 273 | } else if (sd->packet == 0) |
274 | return; /* 2 more lines in 352x288 ! */ | 274 | return; /* 2 more lines in 352x288 ! */ |
@@ -284,9 +284,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
284 | * - 4 bytes | 284 | * - 4 bytes |
285 | */ | 285 | */ |
286 | gspca_frame_add(gspca_dev, packet_type0, | 286 | gspca_frame_add(gspca_dev, packet_type0, |
287 | data + 2, gspca_dev->width); | 287 | data + 2, gspca_dev->pixfmt.width); |
288 | gspca_frame_add(gspca_dev, packet_type1, | 288 | gspca_frame_add(gspca_dev, packet_type1, |
289 | data + gspca_dev->width + 5, gspca_dev->width); | 289 | data + gspca_dev->pixfmt.width + 5, |
290 | gspca_dev->pixfmt.width); | ||
290 | } | 291 | } |
291 | 292 | ||
292 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | 293 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) |
diff --git a/drivers/media/usb/gspca/vicam.c b/drivers/media/usb/gspca/vicam.c index a2275cfe0b81..103f6c4236b0 100644 --- a/drivers/media/usb/gspca/vicam.c +++ b/drivers/media/usb/gspca/vicam.c | |||
@@ -121,13 +121,13 @@ static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size) | |||
121 | 121 | ||
122 | memset(req_data, 0, 16); | 122 | memset(req_data, 0, 16); |
123 | req_data[0] = gain; | 123 | req_data[0] = gain; |
124 | if (gspca_dev->width == 256) | 124 | if (gspca_dev->pixfmt.width == 256) |
125 | req_data[1] |= 0x01; /* low nibble x-scale */ | 125 | req_data[1] |= 0x01; /* low nibble x-scale */ |
126 | if (gspca_dev->height <= 122) { | 126 | if (gspca_dev->pixfmt.height <= 122) { |
127 | req_data[1] |= 0x10; /* high nibble y-scale */ | 127 | req_data[1] |= 0x10; /* high nibble y-scale */ |
128 | unscaled_height = gspca_dev->height * 2; | 128 | unscaled_height = gspca_dev->pixfmt.height * 2; |
129 | } else | 129 | } else |
130 | unscaled_height = gspca_dev->height; | 130 | unscaled_height = gspca_dev->pixfmt.height; |
131 | req_data[2] = 0x90; /* unknown, does not seem to do anything */ | 131 | req_data[2] = 0x90; /* unknown, does not seem to do anything */ |
132 | if (unscaled_height <= 200) | 132 | if (unscaled_height <= 200) |
133 | req_data[3] = 0x06; /* vend? */ | 133 | req_data[3] = 0x06; /* vend? */ |
diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c index 2165da0c7ce1..fb9fe2ef3a6f 100644 --- a/drivers/media/usb/gspca/w996Xcf.c +++ b/drivers/media/usb/gspca/w996Xcf.c | |||
@@ -430,11 +430,11 @@ static void w9968cf_set_crop_window(struct sd *sd) | |||
430 | #define SC(x) ((x) << 10) | 430 | #define SC(x) ((x) << 10) |
431 | 431 | ||
432 | /* Scaling factors */ | 432 | /* Scaling factors */ |
433 | fw = SC(sd->gspca_dev.width) / max_width; | 433 | fw = SC(sd->gspca_dev.pixfmt.width) / max_width; |
434 | fh = SC(sd->gspca_dev.height) / max_height; | 434 | fh = SC(sd->gspca_dev.pixfmt.height) / max_height; |
435 | 435 | ||
436 | cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh; | 436 | cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.pixfmt.width) / fh; |
437 | ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height; | 437 | ch = (fw >= fh) ? SC(sd->gspca_dev.pixfmt.height) / fw : max_height; |
438 | 438 | ||
439 | sd->sensor_width = max_width; | 439 | sd->sensor_width = max_width; |
440 | sd->sensor_height = max_height; | 440 | sd->sensor_height = max_height; |
@@ -454,34 +454,34 @@ static void w9968cf_mode_init_regs(struct sd *sd) | |||
454 | 454 | ||
455 | w9968cf_set_crop_window(sd); | 455 | w9968cf_set_crop_window(sd); |
456 | 456 | ||
457 | reg_w(sd, 0x14, sd->gspca_dev.width); | 457 | reg_w(sd, 0x14, sd->gspca_dev.pixfmt.width); |
458 | reg_w(sd, 0x15, sd->gspca_dev.height); | 458 | reg_w(sd, 0x15, sd->gspca_dev.pixfmt.height); |
459 | 459 | ||
460 | /* JPEG width & height */ | 460 | /* JPEG width & height */ |
461 | reg_w(sd, 0x30, sd->gspca_dev.width); | 461 | reg_w(sd, 0x30, sd->gspca_dev.pixfmt.width); |
462 | reg_w(sd, 0x31, sd->gspca_dev.height); | 462 | reg_w(sd, 0x31, sd->gspca_dev.pixfmt.height); |
463 | 463 | ||
464 | /* Y & UV frame buffer strides (in WORD) */ | 464 | /* Y & UV frame buffer strides (in WORD) */ |
465 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == | 465 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == |
466 | V4L2_PIX_FMT_JPEG) { | 466 | V4L2_PIX_FMT_JPEG) { |
467 | reg_w(sd, 0x2c, sd->gspca_dev.width / 2); | 467 | reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width / 2); |
468 | reg_w(sd, 0x2d, sd->gspca_dev.width / 4); | 468 | reg_w(sd, 0x2d, sd->gspca_dev.pixfmt.width / 4); |
469 | } else | 469 | } else |
470 | reg_w(sd, 0x2c, sd->gspca_dev.width); | 470 | reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width); |
471 | 471 | ||
472 | reg_w(sd, 0x00, 0xbf17); /* reset everything */ | 472 | reg_w(sd, 0x00, 0xbf17); /* reset everything */ |
473 | reg_w(sd, 0x00, 0xbf10); /* normal operation */ | 473 | reg_w(sd, 0x00, 0xbf10); /* normal operation */ |
474 | 474 | ||
475 | /* Transfer size in WORDS (for UYVY format only) */ | 475 | /* Transfer size in WORDS (for UYVY format only) */ |
476 | val = sd->gspca_dev.width * sd->gspca_dev.height; | 476 | val = sd->gspca_dev.pixfmt.width * sd->gspca_dev.pixfmt.height; |
477 | reg_w(sd, 0x3d, val & 0xffff); /* low bits */ | 477 | reg_w(sd, 0x3d, val & 0xffff); /* low bits */ |
478 | reg_w(sd, 0x3e, val >> 16); /* high bits */ | 478 | reg_w(sd, 0x3e, val >> 16); /* high bits */ |
479 | 479 | ||
480 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == | 480 | if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat == |
481 | V4L2_PIX_FMT_JPEG) { | 481 | V4L2_PIX_FMT_JPEG) { |
482 | /* We may get called multiple times (usb isoc bw negotiat.) */ | 482 | /* We may get called multiple times (usb isoc bw negotiat.) */ |
483 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, | 483 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.pixfmt.height, |
484 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ | 484 | sd->gspca_dev.pixfmt.width, 0x22); /* JPEG 420 */ |
485 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); | 485 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); |
486 | w9968cf_upload_quantizationtables(sd); | 486 | w9968cf_upload_quantizationtables(sd); |
487 | v4l2_ctrl_grab(sd->jpegqual, true); | 487 | v4l2_ctrl_grab(sd->jpegqual, true); |
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c index 7eaf64eb867c..a41aa7817c54 100644 --- a/drivers/media/usb/gspca/xirlink_cit.c +++ b/drivers/media/usb/gspca/xirlink_cit.c | |||
@@ -1471,14 +1471,14 @@ static int cit_get_clock_div(struct gspca_dev *gspca_dev) | |||
1471 | 1471 | ||
1472 | while (clock_div > 3 && | 1472 | while (clock_div > 3 && |
1473 | 1000 * packet_size > | 1473 | 1000 * packet_size > |
1474 | gspca_dev->width * gspca_dev->height * | 1474 | gspca_dev->pixfmt.width * gspca_dev->pixfmt.height * |
1475 | fps[clock_div - 1] * 3 / 2) | 1475 | fps[clock_div - 1] * 3 / 2) |
1476 | clock_div--; | 1476 | clock_div--; |
1477 | 1477 | ||
1478 | PDEBUG(D_PROBE, | 1478 | PDEBUG(D_PROBE, |
1479 | "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)", | 1479 | "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)", |
1480 | packet_size, gspca_dev->width, gspca_dev->height, clock_div, | 1480 | packet_size, gspca_dev->pixfmt.width, gspca_dev->pixfmt.height, |
1481 | fps[clock_div]); | 1481 | clock_div, fps[clock_div]); |
1482 | 1482 | ||
1483 | return clock_div; | 1483 | return clock_div; |
1484 | } | 1484 | } |
@@ -1502,7 +1502,7 @@ static int cit_start_model0(struct gspca_dev *gspca_dev) | |||
1502 | cit_write_reg(gspca_dev, 0x0002, 0x0426); | 1502 | cit_write_reg(gspca_dev, 0x0002, 0x0426); |
1503 | cit_write_reg(gspca_dev, 0x0014, 0x0427); | 1503 | cit_write_reg(gspca_dev, 0x0014, 0x0427); |
1504 | 1504 | ||
1505 | switch (gspca_dev->width) { | 1505 | switch (gspca_dev->pixfmt.width) { |
1506 | case 160: /* 160x120 */ | 1506 | case 160: /* 160x120 */ |
1507 | cit_write_reg(gspca_dev, 0x0004, 0x010b); | 1507 | cit_write_reg(gspca_dev, 0x0004, 0x010b); |
1508 | cit_write_reg(gspca_dev, 0x0001, 0x010a); | 1508 | cit_write_reg(gspca_dev, 0x0001, 0x010a); |
@@ -1643,7 +1643,7 @@ static int cit_start_model1(struct gspca_dev *gspca_dev) | |||
1643 | cit_write_reg(gspca_dev, 0x00, 0x0101); | 1643 | cit_write_reg(gspca_dev, 0x00, 0x0101); |
1644 | cit_write_reg(gspca_dev, 0x00, 0x010a); | 1644 | cit_write_reg(gspca_dev, 0x00, 0x010a); |
1645 | 1645 | ||
1646 | switch (gspca_dev->width) { | 1646 | switch (gspca_dev->pixfmt.width) { |
1647 | case 128: /* 128x96 */ | 1647 | case 128: /* 128x96 */ |
1648 | cit_write_reg(gspca_dev, 0x80, 0x0103); | 1648 | cit_write_reg(gspca_dev, 0x80, 0x0103); |
1649 | cit_write_reg(gspca_dev, 0x60, 0x0105); | 1649 | cit_write_reg(gspca_dev, 0x60, 0x0105); |
@@ -1700,7 +1700,7 @@ static int cit_start_model1(struct gspca_dev *gspca_dev) | |||
1700 | } | 1700 | } |
1701 | 1701 | ||
1702 | /* Assorted init */ | 1702 | /* Assorted init */ |
1703 | switch (gspca_dev->width) { | 1703 | switch (gspca_dev->pixfmt.width) { |
1704 | case 128: /* 128x96 */ | 1704 | case 128: /* 128x96 */ |
1705 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); | 1705 | cit_Packet_Format1(gspca_dev, 0x2b, 0x1e); |
1706 | cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ | 1706 | cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */ |
@@ -1753,7 +1753,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1753 | cit_write_reg(gspca_dev, 0x0000, 0x0108); | 1753 | cit_write_reg(gspca_dev, 0x0000, 0x0108); |
1754 | cit_write_reg(gspca_dev, 0x0001, 0x0133); | 1754 | cit_write_reg(gspca_dev, 0x0001, 0x0133); |
1755 | cit_write_reg(gspca_dev, 0x0001, 0x0102); | 1755 | cit_write_reg(gspca_dev, 0x0001, 0x0102); |
1756 | switch (gspca_dev->width) { | 1756 | switch (gspca_dev->pixfmt.width) { |
1757 | case 176: /* 176x144 */ | 1757 | case 176: /* 176x144 */ |
1758 | cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ | 1758 | cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */ |
1759 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ | 1759 | cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */ |
@@ -1792,7 +1792,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1792 | 1792 | ||
1793 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ | 1793 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */ |
1794 | 1794 | ||
1795 | switch (gspca_dev->width) { | 1795 | switch (gspca_dev->pixfmt.width) { |
1796 | case 176: /* 176x144 */ | 1796 | case 176: /* 176x144 */ |
1797 | cit_write_reg(gspca_dev, 0x0050, 0x0111); | 1797 | cit_write_reg(gspca_dev, 0x0050, 0x0111); |
1798 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | 1798 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); |
@@ -1840,7 +1840,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1840 | * Magic control of CMOS sensor. Only lower values like | 1840 | * Magic control of CMOS sensor. Only lower values like |
1841 | * 0-3 work, and picture shifts left or right. Don't change. | 1841 | * 0-3 work, and picture shifts left or right. Don't change. |
1842 | */ | 1842 | */ |
1843 | switch (gspca_dev->width) { | 1843 | switch (gspca_dev->pixfmt.width) { |
1844 | case 176: /* 176x144 */ | 1844 | case 176: /* 176x144 */ |
1845 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0002); | 1845 | cit_model2_Packet1(gspca_dev, 0x0014, 0x0002); |
1846 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ | 1846 | cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */ |
@@ -1899,7 +1899,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1899 | * does not allow arbitrary values and apparently is a bit mask, to | 1899 | * does not allow arbitrary values and apparently is a bit mask, to |
1900 | * be activated only at appropriate time. Don't change it randomly! | 1900 | * be activated only at appropriate time. Don't change it randomly! |
1901 | */ | 1901 | */ |
1902 | switch (gspca_dev->width) { | 1902 | switch (gspca_dev->pixfmt.width) { |
1903 | case 176: /* 176x144 */ | 1903 | case 176: /* 176x144 */ |
1904 | cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2); | 1904 | cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2); |
1905 | break; | 1905 | break; |
@@ -2023,7 +2023,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2023 | cit_model3_Packet1(gspca_dev, 0x009e, 0x0096); | 2023 | cit_model3_Packet1(gspca_dev, 0x009e, 0x0096); |
2024 | cit_model3_Packet1(gspca_dev, 0x009f, 0x000a); | 2024 | cit_model3_Packet1(gspca_dev, 0x009f, 0x000a); |
2025 | 2025 | ||
2026 | switch (gspca_dev->width) { | 2026 | switch (gspca_dev->pixfmt.width) { |
2027 | case 160: | 2027 | case 160: |
2028 | cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ | 2028 | cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */ |
2029 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ | 2029 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */ |
@@ -2134,7 +2134,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2134 | like with the IBM netcam pro). */ | 2134 | like with the IBM netcam pro). */ |
2135 | cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */ | 2135 | cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */ |
2136 | 2136 | ||
2137 | switch (gspca_dev->width) { | 2137 | switch (gspca_dev->pixfmt.width) { |
2138 | case 160: | 2138 | case 160: |
2139 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ | 2139 | cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */ |
2140 | cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ | 2140 | cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */ |
@@ -2211,7 +2211,7 @@ static int cit_start_model4(struct gspca_dev *gspca_dev) | |||
2211 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); | 2211 | cit_write_reg(gspca_dev, 0xfffa, 0x0124); |
2212 | cit_model4_Packet1(gspca_dev, 0x0034, 0x0000); | 2212 | cit_model4_Packet1(gspca_dev, 0x0034, 0x0000); |
2213 | 2213 | ||
2214 | switch (gspca_dev->width) { | 2214 | switch (gspca_dev->pixfmt.width) { |
2215 | case 128: /* 128x96 */ | 2215 | case 128: /* 128x96 */ |
2216 | cit_write_reg(gspca_dev, 0x0070, 0x0119); | 2216 | cit_write_reg(gspca_dev, 0x0070, 0x0119); |
2217 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); | 2217 | cit_write_reg(gspca_dev, 0x00d0, 0x0111); |
@@ -2531,7 +2531,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2531 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ | 2531 | cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */ |
2532 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | 2532 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ |
2533 | 2533 | ||
2534 | switch (gspca_dev->width) { | 2534 | switch (gspca_dev->pixfmt.width) { |
2535 | case 160: /* 160x120 */ | 2535 | case 160: /* 160x120 */ |
2536 | cit_write_reg(gspca_dev, 0x0024, 0x010b); | 2536 | cit_write_reg(gspca_dev, 0x0024, 0x010b); |
2537 | cit_write_reg(gspca_dev, 0x0089, 0x0119); | 2537 | cit_write_reg(gspca_dev, 0x0089, 0x0119); |
@@ -2635,7 +2635,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) | |||
2635 | struct usb_host_interface *alt; | 2635 | struct usb_host_interface *alt; |
2636 | int max_packet_size; | 2636 | int max_packet_size; |
2637 | 2637 | ||
2638 | switch (gspca_dev->width) { | 2638 | switch (gspca_dev->pixfmt.width) { |
2639 | case 160: | 2639 | case 160: |
2640 | max_packet_size = 450; | 2640 | max_packet_size = 450; |
2641 | break; | 2641 | break; |
@@ -2659,7 +2659,7 @@ static int sd_isoc_nego(struct gspca_dev *gspca_dev) | |||
2659 | int ret, packet_size, min_packet_size; | 2659 | int ret, packet_size, min_packet_size; |
2660 | struct usb_host_interface *alt; | 2660 | struct usb_host_interface *alt; |
2661 | 2661 | ||
2662 | switch (gspca_dev->width) { | 2662 | switch (gspca_dev->pixfmt.width) { |
2663 | case 160: | 2663 | case 160: |
2664 | min_packet_size = 200; | 2664 | min_packet_size = 200; |
2665 | break; | 2665 | break; |
@@ -2780,7 +2780,7 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
2780 | case CIT_MODEL1: | 2780 | case CIT_MODEL1: |
2781 | case CIT_MODEL3: | 2781 | case CIT_MODEL3: |
2782 | case CIT_IBM_NETCAM_PRO: | 2782 | case CIT_IBM_NETCAM_PRO: |
2783 | switch (gspca_dev->width) { | 2783 | switch (gspca_dev->pixfmt.width) { |
2784 | case 160: /* 160x120 */ | 2784 | case 160: /* 160x120 */ |
2785 | byte3 = 0x02; | 2785 | byte3 = 0x02; |
2786 | byte4 = 0x0a; | 2786 | byte4 = 0x0a; |
@@ -2864,20 +2864,16 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
2864 | if (data[i] == 0xff) { | 2864 | if (data[i] == 0xff) { |
2865 | if (i >= 4) | 2865 | if (i >= 4) |
2866 | PDEBUG(D_FRAM, | 2866 | PDEBUG(D_FRAM, |
2867 | "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n", | 2867 | "header found at offset: %d: %02x %02x 00 %3ph\n", |
2868 | i - 1, | 2868 | i - 1, |
2869 | data[i - 4], | 2869 | data[i - 4], |
2870 | data[i - 3], | 2870 | data[i - 3], |
2871 | data[i], | 2871 | &data[i]); |
2872 | data[i + 1], | ||
2873 | data[i + 2]); | ||
2874 | else | 2872 | else |
2875 | PDEBUG(D_FRAM, | 2873 | PDEBUG(D_FRAM, |
2876 | "header found at offset: %d: 00 %02x %02x %02x\n", | 2874 | "header found at offset: %d: 00 %3ph\n", |
2877 | i - 1, | 2875 | i - 1, |
2878 | data[i], | 2876 | &data[i]); |
2879 | data[i + 1], | ||
2880 | data[i + 2]); | ||
2881 | return data + i + (sd->sof_len - 1); | 2877 | return data + i + (sd->sof_len - 1); |
2882 | } | 2878 | } |
2883 | break; | 2879 | break; |
diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c index cbfc2f921427..7b95d8e88a20 100644 --- a/drivers/media/usb/gspca/zc3xx.c +++ b/drivers/media/usb/gspca/zc3xx.c | |||
@@ -6700,7 +6700,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6700 | }; | 6700 | }; |
6701 | 6701 | ||
6702 | /* create the JPEG header */ | 6702 | /* create the JPEG header */ |
6703 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 6703 | jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height, |
6704 | gspca_dev->pixfmt.width, | ||
6704 | 0x21); /* JPEG 422 */ | 6705 | 0x21); /* JPEG 422 */ |
6705 | 6706 | ||
6706 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 6707 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 6e5070774dc2..2f0c89cbac76 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c | |||
@@ -78,7 +78,8 @@ void hdpvr_delete(struct hdpvr_device *dev) | |||
78 | 78 | ||
79 | static void challenge(u8 *bytes) | 79 | static void challenge(u8 *bytes) |
80 | { | 80 | { |
81 | u64 *i64P, tmp64; | 81 | __le64 *i64P; |
82 | u64 tmp64; | ||
82 | uint i, idx; | 83 | uint i, idx; |
83 | 84 | ||
84 | for (idx = 0; idx < 32; ++idx) { | 85 | for (idx = 0; idx < 32; ++idx) { |
@@ -106,10 +107,10 @@ static void challenge(u8 *bytes) | |||
106 | for (i = 0; i < 3; i++) | 107 | for (i = 0; i < 3; i++) |
107 | bytes[1] *= bytes[6] + 1; | 108 | bytes[1] *= bytes[6] + 1; |
108 | for (i = 0; i < 3; i++) { | 109 | for (i = 0; i < 3; i++) { |
109 | i64P = (u64 *)bytes; | 110 | i64P = (__le64 *)bytes; |
110 | tmp64 = le64_to_cpup(i64P); | 111 | tmp64 = le64_to_cpup(i64P); |
111 | tmp64 <<= bytes[7] & 0x0f; | 112 | tmp64 = tmp64 + (tmp64 << (bytes[7] & 0x0f)); |
112 | *i64P += cpu_to_le64(tmp64); | 113 | *i64P = cpu_to_le64(tmp64); |
113 | } | 114 | } |
114 | break; | 115 | break; |
115 | } | 116 | } |
@@ -301,8 +302,6 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
301 | goto error; | 302 | goto error; |
302 | } | 303 | } |
303 | 304 | ||
304 | dev->workqueue = 0; | ||
305 | |||
306 | /* init video transfer queues first of all */ | 305 | /* init video transfer queues first of all */ |
307 | /* to prevent oops in hdpvr_delete() on error paths */ | 306 | /* to prevent oops in hdpvr_delete() on error paths */ |
308 | INIT_LIST_HEAD(&dev->free_buff_list); | 307 | INIT_LIST_HEAD(&dev->free_buff_list); |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index c4d51d78f837..ea05f678b559 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c | |||
@@ -2868,7 +2868,7 @@ static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id, | |||
2868 | pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ | 2868 | pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ |
2869 | } | 2869 | } |
2870 | 2870 | ||
2871 | v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw) | 2871 | static v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw) |
2872 | { | 2872 | { |
2873 | v4l2_std_id std; | 2873 | v4l2_std_id std; |
2874 | std = (v4l2_std_id)hdw->std_mask_avail; | 2874 | std = (v4l2_std_id)hdw->std_mask_avail; |
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 03761c6f472f..05bd91a60c09 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c | |||
@@ -209,8 +209,10 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) | |||
209 | struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer; | 209 | struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer; |
210 | int dummy; | 210 | int dummy; |
211 | 211 | ||
212 | if (dev->state != SMSUSB_ACTIVE) | 212 | if (dev->state != SMSUSB_ACTIVE) { |
213 | sms_debug("Device not active yet"); | ||
213 | return -ENOENT; | 214 | return -ENOENT; |
215 | } | ||
214 | 216 | ||
215 | sms_debug("sending %s(%d) size: %d", | 217 | sms_debug("sending %s(%d) size: %d", |
216 | smscore_translate_msg(phdr->msg_type), phdr->msg_type, | 218 | smscore_translate_msg(phdr->msg_type), phdr->msg_type, |
@@ -243,6 +245,9 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) | |||
243 | int rc, dummy; | 245 | int rc, dummy; |
244 | char *fw_filename; | 246 | char *fw_filename; |
245 | 247 | ||
248 | if (id < 0) | ||
249 | id = sms_get_board(board_id)->default_mode; | ||
250 | |||
246 | if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { | 251 | if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { |
247 | sms_err("invalid firmware id specified %d", id); | 252 | sms_err("invalid firmware id specified %d", id); |
248 | return -EINVAL; | 253 | return -EINVAL; |
@@ -445,14 +450,15 @@ static int smsusb_probe(struct usb_interface *intf, | |||
445 | char devpath[32]; | 450 | char devpath[32]; |
446 | int i, rc; | 451 | int i, rc; |
447 | 452 | ||
448 | sms_info("interface number %d", | 453 | sms_info("board id=%lu, interface number %d", |
454 | id->driver_info, | ||
449 | intf->cur_altsetting->desc.bInterfaceNumber); | 455 | intf->cur_altsetting->desc.bInterfaceNumber); |
450 | 456 | ||
451 | if (sms_get_board(id->driver_info)->intf_num != | 457 | if (sms_get_board(id->driver_info)->intf_num != |
452 | intf->cur_altsetting->desc.bInterfaceNumber) { | 458 | intf->cur_altsetting->desc.bInterfaceNumber) { |
453 | sms_err("interface number is %d expecting %d", | 459 | sms_debug("interface %d won't be used. Expecting interface %d to popup", |
454 | sms_get_board(id->driver_info)->intf_num, | 460 | intf->cur_altsetting->desc.bInterfaceNumber, |
455 | intf->cur_altsetting->desc.bInterfaceNumber); | 461 | sms_get_board(id->driver_info)->intf_num); |
456 | return -ENODEV; | 462 | return -ENODEV; |
457 | } | 463 | } |
458 | 464 | ||
@@ -483,22 +489,32 @@ static int smsusb_probe(struct usb_interface *intf, | |||
483 | } | 489 | } |
484 | if ((udev->actconfig->desc.bNumInterfaces == 2) && | 490 | if ((udev->actconfig->desc.bNumInterfaces == 2) && |
485 | (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { | 491 | (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { |
486 | sms_err("rom interface 0 is not used"); | 492 | sms_debug("rom interface 0 is not used"); |
487 | return -ENODEV; | 493 | return -ENODEV; |
488 | } | 494 | } |
489 | 495 | ||
490 | if (id->driver_info == SMS1XXX_BOARD_SIANO_STELLAR_ROM) { | 496 | if (id->driver_info == SMS1XXX_BOARD_SIANO_STELLAR_ROM) { |
491 | sms_info("stellar device was found."); | 497 | /* Detected a Siano Stellar uninitialized */ |
498 | |||
492 | snprintf(devpath, sizeof(devpath), "usb\\%d-%s", | 499 | snprintf(devpath, sizeof(devpath), "usb\\%d-%s", |
493 | udev->bus->busnum, udev->devpath); | 500 | udev->bus->busnum, udev->devpath); |
494 | sms_info("stellar device was found."); | 501 | sms_info("stellar device in cold state was found at %s.", devpath); |
495 | return smsusb1_load_firmware( | 502 | rc = smsusb1_load_firmware( |
496 | udev, smscore_registry_getmode(devpath), | 503 | udev, smscore_registry_getmode(devpath), |
497 | id->driver_info); | 504 | id->driver_info); |
505 | |||
506 | /* This device will reset and gain another USB ID */ | ||
507 | if (!rc) | ||
508 | sms_info("stellar device now in warm state"); | ||
509 | else | ||
510 | sms_err("Failed to put stellar in warm state. Error: %d", rc); | ||
511 | |||
512 | return rc; | ||
513 | } else { | ||
514 | rc = smsusb_init_device(intf, id->driver_info); | ||
498 | } | 515 | } |
499 | 516 | ||
500 | rc = smsusb_init_device(intf, id->driver_info); | 517 | sms_info("Device initialized with return code %d", rc); |
501 | sms_info("rc %d", rc); | ||
502 | sms_board_load_modules(id->driver_info); | 518 | sms_board_load_modules(id->driver_info); |
503 | return rc; | 519 | return rc; |
504 | } | 520 | } |
@@ -550,10 +566,13 @@ static int smsusb_resume(struct usb_interface *intf) | |||
550 | } | 566 | } |
551 | 567 | ||
552 | static const struct usb_device_id smsusb_id_table[] = { | 568 | static const struct usb_device_id smsusb_id_table[] = { |
569 | /* This device is only present before firmware load */ | ||
553 | { USB_DEVICE(0x187f, 0x0010), | 570 | { USB_DEVICE(0x187f, 0x0010), |
554 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 571 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR_ROM }, |
572 | /* This device pops up after firmware load */ | ||
555 | { USB_DEVICE(0x187f, 0x0100), | 573 | { USB_DEVICE(0x187f, 0x0100), |
556 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 574 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
575 | |||
557 | { USB_DEVICE(0x187f, 0x0200), | 576 | { USB_DEVICE(0x187f, 0x0200), |
558 | .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, | 577 | .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, |
559 | { USB_DEVICE(0x187f, 0x0201), | 578 | { USB_DEVICE(0x187f, 0x0201), |
diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c index 95f94e5aa66d..3316caa4733b 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/media/usb/tlg2300/pd-main.c | |||
@@ -232,7 +232,7 @@ static int firmware_download(struct usb_device *udev) | |||
232 | goto out; | 232 | goto out; |
233 | } | 233 | } |
234 | 234 | ||
235 | max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize; | 235 | max_packet_size = le16_to_cpu(udev->ep_out[0x1]->desc.wMaxPacketSize); |
236 | log("\t\t download size : %d", (int)max_packet_size); | 236 | log("\t\t download size : %d", (int)max_packet_size); |
237 | 237 | ||
238 | for (offset = 0; offset < fwlength; offset += max_packet_size) { | 238 | for (offset = 0; offset < fwlength; offset += max_packet_size) { |
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index e52c3b97f304..29724af9b9ab 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c | |||
@@ -366,7 +366,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, | |||
366 | } | 366 | } |
367 | return 0; | 367 | return 0; |
368 | } else { | 368 | } else { |
369 | return -1; | 369 | return -ENOENT; |
370 | } | 370 | } |
371 | } | 371 | } |
372 | 372 | ||
@@ -1241,6 +1241,8 @@ static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) | |||
1241 | 1241 | ||
1242 | static int ttusb_dec_init_usb(struct ttusb_dec *dec) | 1242 | static int ttusb_dec_init_usb(struct ttusb_dec *dec) |
1243 | { | 1243 | { |
1244 | int result; | ||
1245 | |||
1244 | dprintk("%s\n", __func__); | 1246 | dprintk("%s\n", __func__); |
1245 | 1247 | ||
1246 | mutex_init(&dec->usb_mutex); | 1248 | mutex_init(&dec->usb_mutex); |
@@ -1258,7 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) | |||
1258 | return -ENOMEM; | 1260 | return -ENOMEM; |
1259 | } | 1261 | } |
1260 | dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE, | 1262 | dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE, |
1261 | GFP_ATOMIC, &dec->irq_dma_handle); | 1263 | GFP_KERNEL, &dec->irq_dma_handle); |
1262 | if(!dec->irq_buffer) { | 1264 | if(!dec->irq_buffer) { |
1263 | usb_free_urb(dec->irq_urb); | 1265 | usb_free_urb(dec->irq_urb); |
1264 | return -ENOMEM; | 1266 | return -ENOMEM; |
@@ -1270,7 +1272,13 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) | |||
1270 | dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1272 | dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1271 | } | 1273 | } |
1272 | 1274 | ||
1273 | return ttusb_dec_alloc_iso_urbs(dec); | 1275 | result = ttusb_dec_alloc_iso_urbs(dec); |
1276 | if (result) { | ||
1277 | usb_free_urb(dec->irq_urb); | ||
1278 | usb_free_coherent(dec->udev, IRQ_PACKET_SIZE, | ||
1279 | dec->irq_buffer, dec->irq_dma_handle); | ||
1280 | } | ||
1281 | return result; | ||
1274 | } | 1282 | } |
1275 | 1283 | ||
1276 | static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | 1284 | static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) |
@@ -1293,10 +1301,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | |||
1293 | 1301 | ||
1294 | dprintk("%s\n", __func__); | 1302 | dprintk("%s\n", __func__); |
1295 | 1303 | ||
1296 | if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { | 1304 | result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev); |
1305 | if (result) { | ||
1297 | printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", | 1306 | printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", |
1298 | __func__, dec->firmware_name); | 1307 | __func__, dec->firmware_name); |
1299 | return 1; | 1308 | return result; |
1300 | } | 1309 | } |
1301 | 1310 | ||
1302 | firmware = fw_entry->data; | 1311 | firmware = fw_entry->data; |
@@ -1306,7 +1315,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | |||
1306 | printk("%s: firmware size too small for DSP code (%zu < 60).\n", | 1315 | printk("%s: firmware size too small for DSP code (%zu < 60).\n", |
1307 | __func__, firmware_size); | 1316 | __func__, firmware_size); |
1308 | release_firmware(fw_entry); | 1317 | release_firmware(fw_entry); |
1309 | return -1; | 1318 | return -ENOENT; |
1310 | } | 1319 | } |
1311 | 1320 | ||
1312 | /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored | 1321 | /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored |
@@ -1320,7 +1329,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | |||
1320 | "0x%08x != 0x%08x in file), file invalid.\n", | 1329 | "0x%08x != 0x%08x in file), file invalid.\n", |
1321 | __func__, crc32_csum, crc32_check); | 1330 | __func__, crc32_csum, crc32_check); |
1322 | release_firmware(fw_entry); | 1331 | release_firmware(fw_entry); |
1323 | return -1; | 1332 | return -ENOENT; |
1324 | } | 1333 | } |
1325 | memcpy(idstring, &firmware[36], 20); | 1334 | memcpy(idstring, &firmware[36], 20); |
1326 | idstring[20] = '\0'; | 1335 | idstring[20] = '\0'; |
@@ -1389,55 +1398,48 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) | |||
1389 | dprintk("%s\n", __func__); | 1398 | dprintk("%s\n", __func__); |
1390 | 1399 | ||
1391 | result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); | 1400 | result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); |
1401 | if (result) | ||
1402 | return result; | ||
1392 | 1403 | ||
1393 | if (!result) { | 1404 | if (!mode) { |
1394 | if (!mode) { | 1405 | if (version == 0xABCDEFAB) |
1395 | if (version == 0xABCDEFAB) | 1406 | printk(KERN_INFO "ttusb_dec: no version " |
1396 | printk(KERN_INFO "ttusb_dec: no version " | 1407 | "info in Firmware\n"); |
1397 | "info in Firmware\n"); | 1408 | else |
1398 | else | 1409 | printk(KERN_INFO "ttusb_dec: Firmware " |
1399 | printk(KERN_INFO "ttusb_dec: Firmware " | 1410 | "%x.%02x%c%c\n", |
1400 | "%x.%02x%c%c\n", | 1411 | version >> 24, (version >> 16) & 0xff, |
1401 | version >> 24, (version >> 16) & 0xff, | 1412 | (version >> 8) & 0xff, version & 0xff); |
1402 | (version >> 8) & 0xff, version & 0xff); | ||
1403 | |||
1404 | result = ttusb_dec_boot_dsp(dec); | ||
1405 | if (result) | ||
1406 | return result; | ||
1407 | else | ||
1408 | return 1; | ||
1409 | } else { | ||
1410 | /* We can't trust the USB IDs that some firmwares | ||
1411 | give the box */ | ||
1412 | switch (model) { | ||
1413 | case 0x00070001: | ||
1414 | case 0x00070008: | ||
1415 | case 0x0007000c: | ||
1416 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); | ||
1417 | break; | ||
1418 | case 0x00070009: | ||
1419 | case 0x00070013: | ||
1420 | ttusb_dec_set_model(dec, TTUSB_DEC2000T); | ||
1421 | break; | ||
1422 | case 0x00070011: | ||
1423 | ttusb_dec_set_model(dec, TTUSB_DEC2540T); | ||
1424 | break; | ||
1425 | default: | ||
1426 | printk(KERN_ERR "%s: unknown model returned " | ||
1427 | "by firmware (%08x) - please report\n", | ||
1428 | __func__, model); | ||
1429 | return -1; | ||
1430 | break; | ||
1431 | } | ||
1432 | 1413 | ||
1414 | result = ttusb_dec_boot_dsp(dec); | ||
1415 | if (result) | ||
1416 | return result; | ||
1417 | } else { | ||
1418 | /* We can't trust the USB IDs that some firmwares | ||
1419 | give the box */ | ||
1420 | switch (model) { | ||
1421 | case 0x00070001: | ||
1422 | case 0x00070008: | ||
1423 | case 0x0007000c: | ||
1424 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); | ||
1425 | break; | ||
1426 | case 0x00070009: | ||
1427 | case 0x00070013: | ||
1428 | ttusb_dec_set_model(dec, TTUSB_DEC2000T); | ||
1429 | break; | ||
1430 | case 0x00070011: | ||
1431 | ttusb_dec_set_model(dec, TTUSB_DEC2540T); | ||
1432 | break; | ||
1433 | default: | ||
1434 | printk(KERN_ERR "%s: unknown model returned " | ||
1435 | "by firmware (%08x) - please report\n", | ||
1436 | __func__, model); | ||
1437 | return -ENOENT; | ||
1438 | } | ||
1433 | if (version >= 0x01770000) | 1439 | if (version >= 0x01770000) |
1434 | dec->can_playback = 1; | 1440 | dec->can_playback = 1; |
1435 | |||
1436 | return 0; | ||
1437 | } | ||
1438 | } | 1441 | } |
1439 | else | 1442 | return 0; |
1440 | return result; | ||
1441 | } | 1443 | } |
1442 | 1444 | ||
1443 | static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | 1445 | static int ttusb_dec_init_dvb(struct ttusb_dec *dec) |
@@ -1539,19 +1541,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) | |||
1539 | 1541 | ||
1540 | static void ttusb_dec_exit_rc(struct ttusb_dec *dec) | 1542 | static void ttusb_dec_exit_rc(struct ttusb_dec *dec) |
1541 | { | 1543 | { |
1542 | |||
1543 | dprintk("%s\n", __func__); | 1544 | dprintk("%s\n", __func__); |
1544 | /* we have to check whether the irq URB is already submitted. | ||
1545 | * As the irq is submitted after the interface is changed, | ||
1546 | * this is the best method i figured out. | ||
1547 | * Any others?*/ | ||
1548 | if (dec->interface == TTUSB_DEC_INTERFACE_IN) | ||
1549 | usb_kill_urb(dec->irq_urb); | ||
1550 | |||
1551 | usb_free_urb(dec->irq_urb); | ||
1552 | |||
1553 | usb_free_coherent(dec->udev,IRQ_PACKET_SIZE, | ||
1554 | dec->irq_buffer, dec->irq_dma_handle); | ||
1555 | 1545 | ||
1556 | if (dec->rc_input_dev) { | 1546 | if (dec->rc_input_dev) { |
1557 | input_unregister_device(dec->rc_input_dev); | 1547 | input_unregister_device(dec->rc_input_dev); |
@@ -1566,6 +1556,20 @@ static void ttusb_dec_exit_usb(struct ttusb_dec *dec) | |||
1566 | 1556 | ||
1567 | dprintk("%s\n", __func__); | 1557 | dprintk("%s\n", __func__); |
1568 | 1558 | ||
1559 | if (enable_rc) { | ||
1560 | /* we have to check whether the irq URB is already submitted. | ||
1561 | * As the irq is submitted after the interface is changed, | ||
1562 | * this is the best method i figured out. | ||
1563 | * Any others?*/ | ||
1564 | if (dec->interface == TTUSB_DEC_INTERFACE_IN) | ||
1565 | usb_kill_urb(dec->irq_urb); | ||
1566 | |||
1567 | usb_free_urb(dec->irq_urb); | ||
1568 | |||
1569 | usb_free_coherent(dec->udev, IRQ_PACKET_SIZE, | ||
1570 | dec->irq_buffer, dec->irq_dma_handle); | ||
1571 | } | ||
1572 | |||
1569 | dec->iso_stream_count = 0; | 1573 | dec->iso_stream_count = 0; |
1570 | 1574 | ||
1571 | for (i = 0; i < ISO_BUF_COUNT; i++) | 1575 | for (i = 0; i < ISO_BUF_COUNT; i++) |
@@ -1623,6 +1627,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1623 | { | 1627 | { |
1624 | struct usb_device *udev; | 1628 | struct usb_device *udev; |
1625 | struct ttusb_dec *dec; | 1629 | struct ttusb_dec *dec; |
1630 | int result; | ||
1626 | 1631 | ||
1627 | dprintk("%s\n", __func__); | 1632 | dprintk("%s\n", __func__); |
1628 | 1633 | ||
@@ -1651,13 +1656,15 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1651 | 1656 | ||
1652 | dec->udev = udev; | 1657 | dec->udev = udev; |
1653 | 1658 | ||
1654 | if (ttusb_dec_init_usb(dec)) | 1659 | result = ttusb_dec_init_usb(dec); |
1655 | return 0; | 1660 | if (result) |
1656 | if (ttusb_dec_init_stb(dec)) { | 1661 | goto err_usb; |
1657 | ttusb_dec_exit_usb(dec); | 1662 | result = ttusb_dec_init_stb(dec); |
1658 | return 0; | 1663 | if (result) |
1659 | } | 1664 | goto err_stb; |
1660 | ttusb_dec_init_dvb(dec); | 1665 | result = ttusb_dec_init_dvb(dec); |
1666 | if (result) | ||
1667 | goto err_stb; | ||
1661 | 1668 | ||
1662 | dec->adapter.priv = dec; | 1669 | dec->adapter.priv = dec; |
1663 | switch (id->idProduct) { | 1670 | switch (id->idProduct) { |
@@ -1696,6 +1703,11 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1696 | ttusb_init_rc(dec); | 1703 | ttusb_init_rc(dec); |
1697 | 1704 | ||
1698 | return 0; | 1705 | return 0; |
1706 | err_stb: | ||
1707 | ttusb_dec_exit_usb(dec); | ||
1708 | err_usb: | ||
1709 | kfree(dec); | ||
1710 | return result; | ||
1699 | } | 1711 | } |
1700 | 1712 | ||
1701 | static void ttusb_dec_disconnect(struct usb_interface *intf) | 1713 | static void ttusb_dec_disconnect(struct usb_interface *intf) |
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index a2f4501c23ca..0eb82106d2ff 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c | |||
@@ -664,7 +664,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
664 | .size = 32, | 664 | .size = 32, |
665 | .offset = 0, | 665 | .offset = 0, |
666 | .v4l2_type = V4L2_CTRL_TYPE_INTEGER, | 666 | .v4l2_type = V4L2_CTRL_TYPE_INTEGER, |
667 | .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, | 667 | .data_type = UVC_CTRL_DATA_TYPE_SIGNED, |
668 | }, | 668 | }, |
669 | { | 669 | { |
670 | .id = V4L2_CID_TILT_ABSOLUTE, | 670 | .id = V4L2_CID_TILT_ABSOLUTE, |
@@ -674,7 +674,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
674 | .size = 32, | 674 | .size = 32, |
675 | .offset = 32, | 675 | .offset = 32, |
676 | .v4l2_type = V4L2_CTRL_TYPE_INTEGER, | 676 | .v4l2_type = V4L2_CTRL_TYPE_INTEGER, |
677 | .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, | 677 | .data_type = UVC_CTRL_DATA_TYPE_SIGNED, |
678 | }, | 678 | }, |
679 | { | 679 | { |
680 | .id = V4L2_CID_PRIVACY, | 680 | .id = V4L2_CID_PRIVACY, |
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index ddc9379eb276..4b8a9a39d7f4 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c | |||
@@ -247,7 +247,7 @@ static const struct analog_demod_ops tuner_analog_ops = { | |||
247 | /** | 247 | /** |
248 | * set_type - Sets the tuner type for a given device | 248 | * set_type - Sets the tuner type for a given device |
249 | * | 249 | * |
250 | * @c: i2c_client descriptoy | 250 | * @c: i2c_client descriptor |
251 | * @type: type of the tuner (e. g. tuner number) | 251 | * @type: type of the tuner (e. g. tuner number) |
252 | * @new_mode_mask: Indicates if tuner supports TV and/or Radio | 252 | * @new_mode_mask: Indicates if tuner supports TV and/or Radio |
253 | * @new_config: an optional parameter used by a few tuners to adjust | 253 | * @new_config: an optional parameter used by a few tuners to adjust |
diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index b67de8642b5a..e18cc0469cf8 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c | |||
@@ -240,3 +240,42 @@ void v4l2_clk_unregister(struct v4l2_clk *clk) | |||
240 | kfree(clk); | 240 | kfree(clk); |
241 | } | 241 | } |
242 | EXPORT_SYMBOL(v4l2_clk_unregister); | 242 | EXPORT_SYMBOL(v4l2_clk_unregister); |
243 | |||
244 | struct v4l2_clk_fixed { | ||
245 | unsigned long rate; | ||
246 | struct v4l2_clk_ops ops; | ||
247 | }; | ||
248 | |||
249 | static unsigned long fixed_get_rate(struct v4l2_clk *clk) | ||
250 | { | ||
251 | struct v4l2_clk_fixed *priv = clk->priv; | ||
252 | return priv->rate; | ||
253 | } | ||
254 | |||
255 | struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, | ||
256 | const char *id, unsigned long rate, struct module *owner) | ||
257 | { | ||
258 | struct v4l2_clk *clk; | ||
259 | struct v4l2_clk_fixed *priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
260 | |||
261 | if (!priv) | ||
262 | return ERR_PTR(-ENOMEM); | ||
263 | |||
264 | priv->rate = rate; | ||
265 | priv->ops.get_rate = fixed_get_rate; | ||
266 | priv->ops.owner = owner; | ||
267 | |||
268 | clk = v4l2_clk_register(&priv->ops, dev_id, id, priv); | ||
269 | if (IS_ERR(clk)) | ||
270 | kfree(priv); | ||
271 | |||
272 | return clk; | ||
273 | } | ||
274 | EXPORT_SYMBOL(__v4l2_clk_register_fixed); | ||
275 | |||
276 | void v4l2_clk_unregister_fixed(struct v4l2_clk *clk) | ||
277 | { | ||
278 | kfree(clk->priv); | ||
279 | v4l2_clk_unregister(clk); | ||
280 | } | ||
281 | EXPORT_SYMBOL(v4l2_clk_unregister_fixed); | ||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index c3f080388684..60dcc0f3b32e 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
@@ -565,13 +565,13 @@ EXPORT_SYMBOL(v4l2_ctrl_get_menu); | |||
565 | * Returns NULL or an s64 type array containing the menu for given | 565 | * Returns NULL or an s64 type array containing the menu for given |
566 | * control ID. The total number of the menu items is returned in @len. | 566 | * control ID. The total number of the menu items is returned in @len. |
567 | */ | 567 | */ |
568 | const s64 const *v4l2_ctrl_get_int_menu(u32 id, u32 *len) | 568 | const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len) |
569 | { | 569 | { |
570 | static const s64 const qmenu_int_vpx_num_partitions[] = { | 570 | static const s64 qmenu_int_vpx_num_partitions[] = { |
571 | 1, 2, 4, 8, | 571 | 1, 2, 4, 8, |
572 | }; | 572 | }; |
573 | 573 | ||
574 | static const s64 const qmenu_int_vpx_num_ref_frames[] = { | 574 | static const s64 qmenu_int_vpx_num_ref_frames[] = { |
575 | 1, 2, 3, | 575 | 1, 2, 3, |
576 | }; | 576 | }; |
577 | 577 | ||
@@ -583,7 +583,7 @@ const s64 const *v4l2_ctrl_get_int_menu(u32 id, u32 *len) | |||
583 | default: | 583 | default: |
584 | *len = 0; | 584 | *len = 0; |
585 | return NULL; | 585 | return NULL; |
586 | }; | 586 | } |
587 | } | 587 | } |
588 | EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); | 588 | EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); |
589 | 589 | ||
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 7c4371288215..73035ee0f4de 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | |||
@@ -41,6 +41,8 @@ module_param(debug, bool, 0644); | |||
41 | #define TRANS_QUEUED (1 << 0) | 41 | #define TRANS_QUEUED (1 << 0) |
42 | /* Instance is currently running in hardware */ | 42 | /* Instance is currently running in hardware */ |
43 | #define TRANS_RUNNING (1 << 1) | 43 | #define TRANS_RUNNING (1 << 1) |
44 | /* Instance is currently aborting */ | ||
45 | #define TRANS_ABORT (1 << 2) | ||
44 | 46 | ||
45 | 47 | ||
46 | /* Offset base for buffers on the destination queue - used to distinguish | 48 | /* Offset base for buffers on the destination queue - used to distinguish |
@@ -221,6 +223,14 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) | |||
221 | } | 223 | } |
222 | 224 | ||
223 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); | 225 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); |
226 | |||
227 | /* If the context is aborted then don't schedule it */ | ||
228 | if (m2m_ctx->job_flags & TRANS_ABORT) { | ||
229 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | ||
230 | dprintk("Aborted context\n"); | ||
231 | return; | ||
232 | } | ||
233 | |||
224 | if (m2m_ctx->job_flags & TRANS_QUEUED) { | 234 | if (m2m_ctx->job_flags & TRANS_QUEUED) { |
225 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | 235 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); |
226 | dprintk("On job queue already\n"); | 236 | dprintk("On job queue already\n"); |
@@ -280,6 +290,8 @@ static void v4l2_m2m_cancel_job(struct v4l2_m2m_ctx *m2m_ctx) | |||
280 | 290 | ||
281 | m2m_dev = m2m_ctx->m2m_dev; | 291 | m2m_dev = m2m_ctx->m2m_dev; |
282 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | 292 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags); |
293 | |||
294 | m2m_ctx->job_flags |= TRANS_ABORT; | ||
283 | if (m2m_ctx->job_flags & TRANS_RUNNING) { | 295 | if (m2m_ctx->job_flags & TRANS_RUNNING) { |
284 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | 296 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); |
285 | m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); | 297 | m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); |
@@ -480,13 +492,15 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
480 | m2m_dev = m2m_ctx->m2m_dev; | 492 | m2m_dev = m2m_ctx->m2m_dev; |
481 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); | 493 | spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job); |
482 | /* We should not be scheduled anymore, since we're dropping a queue. */ | 494 | /* We should not be scheduled anymore, since we're dropping a queue. */ |
483 | INIT_LIST_HEAD(&m2m_ctx->queue); | 495 | if (m2m_ctx->job_flags & TRANS_QUEUED) |
496 | list_del(&m2m_ctx->queue); | ||
484 | m2m_ctx->job_flags = 0; | 497 | m2m_ctx->job_flags = 0; |
485 | 498 | ||
486 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); | 499 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); |
487 | /* Drop queue, since streamoff returns device to the same state as after | 500 | /* Drop queue, since streamoff returns device to the same state as after |
488 | * calling reqbufs. */ | 501 | * calling reqbufs. */ |
489 | INIT_LIST_HEAD(&q_ctx->rdy_queue); | 502 | INIT_LIST_HEAD(&q_ctx->rdy_queue); |
503 | q_ctx->num_rdy = 0; | ||
490 | spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags); | 504 | spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags); |
491 | 505 | ||
492 | if (m2m_dev->curr_ctx == m2m_ctx) { | 506 | if (m2m_dev->curr_ctx == m2m_ctx) { |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index de0e87f0b2c3..b19b306c8f7f 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -241,7 +241,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
241 | q->bufs[q->num_buffers + buffer] = vb; | 241 | q->bufs[q->num_buffers + buffer] = vb; |
242 | } | 242 | } |
243 | 243 | ||
244 | __setup_offsets(q, buffer); | 244 | if (memory == V4L2_MEMORY_MMAP) |
245 | __setup_offsets(q, buffer); | ||
245 | 246 | ||
246 | dprintk(1, "Allocated %d buffers, %d plane(s) each\n", | 247 | dprintk(1, "Allocated %d buffers, %d plane(s) each\n", |
247 | buffer, num_planes); | 248 | buffer, num_planes); |
@@ -1015,6 +1016,10 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
1015 | 1016 | ||
1016 | /* Check if the provided plane buffer is large enough */ | 1017 | /* Check if the provided plane buffer is large enough */ |
1017 | if (planes[plane].length < q->plane_sizes[plane]) { | 1018 | if (planes[plane].length < q->plane_sizes[plane]) { |
1019 | dprintk(1, "qbuf: provided buffer size %u is less than " | ||
1020 | "setup size %u for plane %d\n", | ||
1021 | planes[plane].length, | ||
1022 | q->plane_sizes[plane], plane); | ||
1018 | ret = -EINVAL; | 1023 | ret = -EINVAL; |
1019 | goto err; | 1024 | goto err; |
1020 | } | 1025 | } |
@@ -1205,8 +1210,11 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
1205 | int ret; | 1210 | int ret; |
1206 | 1211 | ||
1207 | ret = __verify_length(vb, b); | 1212 | ret = __verify_length(vb, b); |
1208 | if (ret < 0) | 1213 | if (ret < 0) { |
1214 | dprintk(1, "%s(): plane parameters verification failed: %d\n", | ||
1215 | __func__, ret); | ||
1209 | return ret; | 1216 | return ret; |
1217 | } | ||
1210 | 1218 | ||
1211 | switch (q->memory) { | 1219 | switch (q->memory) { |
1212 | case V4L2_MEMORY_MMAP: | 1220 | case V4L2_MEMORY_MMAP: |
@@ -2469,10 +2477,11 @@ size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, | |||
2469 | } | 2477 | } |
2470 | EXPORT_SYMBOL_GPL(vb2_read); | 2478 | EXPORT_SYMBOL_GPL(vb2_read); |
2471 | 2479 | ||
2472 | size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count, | 2480 | size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, |
2473 | loff_t *ppos, int nonblocking) | 2481 | loff_t *ppos, int nonblocking) |
2474 | { | 2482 | { |
2475 | return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0); | 2483 | return __vb2_perform_fileio(q, (char __user *) data, count, |
2484 | ppos, nonblocking, 0); | ||
2476 | } | 2485 | } |
2477 | EXPORT_SYMBOL_GPL(vb2_write); | 2486 | EXPORT_SYMBOL_GPL(vb2_write); |
2478 | 2487 | ||
@@ -2633,7 +2642,7 @@ int vb2_fop_release(struct file *file) | |||
2633 | } | 2642 | } |
2634 | EXPORT_SYMBOL_GPL(vb2_fop_release); | 2643 | EXPORT_SYMBOL_GPL(vb2_fop_release); |
2635 | 2644 | ||
2636 | ssize_t vb2_fop_write(struct file *file, char __user *buf, | 2645 | ssize_t vb2_fop_write(struct file *file, const char __user *buf, |
2637 | size_t count, loff_t *ppos) | 2646 | size_t count, loff_t *ppos) |
2638 | { | 2647 | { |
2639 | struct video_device *vdev = video_devdata(file); | 2648 | struct video_device *vdev = video_devdata(file); |
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 16ae3dcc7e29..2f860543912c 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c | |||
@@ -35,17 +35,61 @@ struct vb2_dma_sg_buf { | |||
35 | struct page **pages; | 35 | struct page **pages; |
36 | int write; | 36 | int write; |
37 | int offset; | 37 | int offset; |
38 | struct vb2_dma_sg_desc sg_desc; | 38 | struct sg_table sg_table; |
39 | size_t size; | ||
40 | unsigned int num_pages; | ||
39 | atomic_t refcount; | 41 | atomic_t refcount; |
40 | struct vb2_vmarea_handler handler; | 42 | struct vb2_vmarea_handler handler; |
41 | }; | 43 | }; |
42 | 44 | ||
43 | static void vb2_dma_sg_put(void *buf_priv); | 45 | static void vb2_dma_sg_put(void *buf_priv); |
44 | 46 | ||
47 | static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, | ||
48 | gfp_t gfp_flags) | ||
49 | { | ||
50 | unsigned int last_page = 0; | ||
51 | int size = buf->size; | ||
52 | |||
53 | while (size > 0) { | ||
54 | struct page *pages; | ||
55 | int order; | ||
56 | int i; | ||
57 | |||
58 | order = get_order(size); | ||
59 | /* Dont over allocate*/ | ||
60 | if ((PAGE_SIZE << order) > size) | ||
61 | order--; | ||
62 | |||
63 | pages = NULL; | ||
64 | while (!pages) { | ||
65 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO | | ||
66 | __GFP_NOWARN | gfp_flags, order); | ||
67 | if (pages) | ||
68 | break; | ||
69 | |||
70 | if (order == 0) { | ||
71 | while (last_page--) | ||
72 | __free_page(buf->pages[last_page]); | ||
73 | return -ENOMEM; | ||
74 | } | ||
75 | order--; | ||
76 | } | ||
77 | |||
78 | split_page(pages, order); | ||
79 | for (i = 0; i < (1 << order); i++) | ||
80 | buf->pages[last_page++] = &pages[i]; | ||
81 | |||
82 | size -= PAGE_SIZE << order; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
45 | static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) | 88 | static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) |
46 | { | 89 | { |
47 | struct vb2_dma_sg_buf *buf; | 90 | struct vb2_dma_sg_buf *buf; |
48 | int i; | 91 | int ret; |
92 | int num_pages; | ||
49 | 93 | ||
50 | buf = kzalloc(sizeof *buf, GFP_KERNEL); | 94 | buf = kzalloc(sizeof *buf, GFP_KERNEL); |
51 | if (!buf) | 95 | if (!buf) |
@@ -54,29 +98,23 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla | |||
54 | buf->vaddr = NULL; | 98 | buf->vaddr = NULL; |
55 | buf->write = 0; | 99 | buf->write = 0; |
56 | buf->offset = 0; | 100 | buf->offset = 0; |
57 | buf->sg_desc.size = size; | 101 | buf->size = size; |
58 | /* size is already page aligned */ | 102 | /* size is already page aligned */ |
59 | buf->sg_desc.num_pages = size >> PAGE_SHIFT; | 103 | buf->num_pages = size >> PAGE_SHIFT; |
60 | 104 | ||
61 | buf->sg_desc.sglist = vzalloc(buf->sg_desc.num_pages * | 105 | buf->pages = kzalloc(buf->num_pages * sizeof(struct page *), |
62 | sizeof(*buf->sg_desc.sglist)); | ||
63 | if (!buf->sg_desc.sglist) | ||
64 | goto fail_sglist_alloc; | ||
65 | sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages); | ||
66 | |||
67 | buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *), | ||
68 | GFP_KERNEL); | 106 | GFP_KERNEL); |
69 | if (!buf->pages) | 107 | if (!buf->pages) |
70 | goto fail_pages_array_alloc; | 108 | goto fail_pages_array_alloc; |
71 | 109 | ||
72 | for (i = 0; i < buf->sg_desc.num_pages; ++i) { | 110 | ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags); |
73 | buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | | 111 | if (ret) |
74 | __GFP_NOWARN | gfp_flags); | 112 | goto fail_pages_alloc; |
75 | if (NULL == buf->pages[i]) | 113 | |
76 | goto fail_pages_alloc; | 114 | ret = sg_alloc_table_from_pages(&buf->sg_table, buf->pages, |
77 | sg_set_page(&buf->sg_desc.sglist[i], | 115 | buf->num_pages, 0, size, gfp_flags); |
78 | buf->pages[i], PAGE_SIZE, 0); | 116 | if (ret) |
79 | } | 117 | goto fail_table_alloc; |
80 | 118 | ||
81 | buf->handler.refcount = &buf->refcount; | 119 | buf->handler.refcount = &buf->refcount; |
82 | buf->handler.put = vb2_dma_sg_put; | 120 | buf->handler.put = vb2_dma_sg_put; |
@@ -85,18 +123,16 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla | |||
85 | atomic_inc(&buf->refcount); | 123 | atomic_inc(&buf->refcount); |
86 | 124 | ||
87 | dprintk(1, "%s: Allocated buffer of %d pages\n", | 125 | dprintk(1, "%s: Allocated buffer of %d pages\n", |
88 | __func__, buf->sg_desc.num_pages); | 126 | __func__, buf->num_pages); |
89 | return buf; | 127 | return buf; |
90 | 128 | ||
129 | fail_table_alloc: | ||
130 | num_pages = buf->num_pages; | ||
131 | while (num_pages--) | ||
132 | __free_page(buf->pages[num_pages]); | ||
91 | fail_pages_alloc: | 133 | fail_pages_alloc: |
92 | while (--i >= 0) | ||
93 | __free_page(buf->pages[i]); | ||
94 | kfree(buf->pages); | 134 | kfree(buf->pages); |
95 | |||
96 | fail_pages_array_alloc: | 135 | fail_pages_array_alloc: |
97 | vfree(buf->sg_desc.sglist); | ||
98 | |||
99 | fail_sglist_alloc: | ||
100 | kfree(buf); | 136 | kfree(buf); |
101 | return NULL; | 137 | return NULL; |
102 | } | 138 | } |
@@ -104,14 +140,14 @@ fail_sglist_alloc: | |||
104 | static void vb2_dma_sg_put(void *buf_priv) | 140 | static void vb2_dma_sg_put(void *buf_priv) |
105 | { | 141 | { |
106 | struct vb2_dma_sg_buf *buf = buf_priv; | 142 | struct vb2_dma_sg_buf *buf = buf_priv; |
107 | int i = buf->sg_desc.num_pages; | 143 | int i = buf->num_pages; |
108 | 144 | ||
109 | if (atomic_dec_and_test(&buf->refcount)) { | 145 | if (atomic_dec_and_test(&buf->refcount)) { |
110 | dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, | 146 | dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, |
111 | buf->sg_desc.num_pages); | 147 | buf->num_pages); |
112 | if (buf->vaddr) | 148 | if (buf->vaddr) |
113 | vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages); | 149 | vm_unmap_ram(buf->vaddr, buf->num_pages); |
114 | vfree(buf->sg_desc.sglist); | 150 | sg_free_table(&buf->sg_table); |
115 | while (--i >= 0) | 151 | while (--i >= 0) |
116 | __free_page(buf->pages[i]); | 152 | __free_page(buf->pages[i]); |
117 | kfree(buf->pages); | 153 | kfree(buf->pages); |
@@ -124,7 +160,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, | |||
124 | { | 160 | { |
125 | struct vb2_dma_sg_buf *buf; | 161 | struct vb2_dma_sg_buf *buf; |
126 | unsigned long first, last; | 162 | unsigned long first, last; |
127 | int num_pages_from_user, i; | 163 | int num_pages_from_user; |
128 | 164 | ||
129 | buf = kzalloc(sizeof *buf, GFP_KERNEL); | 165 | buf = kzalloc(sizeof *buf, GFP_KERNEL); |
130 | if (!buf) | 166 | if (!buf) |
@@ -133,56 +169,41 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, | |||
133 | buf->vaddr = NULL; | 169 | buf->vaddr = NULL; |
134 | buf->write = write; | 170 | buf->write = write; |
135 | buf->offset = vaddr & ~PAGE_MASK; | 171 | buf->offset = vaddr & ~PAGE_MASK; |
136 | buf->sg_desc.size = size; | 172 | buf->size = size; |
137 | 173 | ||
138 | first = (vaddr & PAGE_MASK) >> PAGE_SHIFT; | 174 | first = (vaddr & PAGE_MASK) >> PAGE_SHIFT; |
139 | last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT; | 175 | last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT; |
140 | buf->sg_desc.num_pages = last - first + 1; | 176 | buf->num_pages = last - first + 1; |
141 | |||
142 | buf->sg_desc.sglist = vzalloc( | ||
143 | buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist)); | ||
144 | if (!buf->sg_desc.sglist) | ||
145 | goto userptr_fail_sglist_alloc; | ||
146 | |||
147 | sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages); | ||
148 | 177 | ||
149 | buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *), | 178 | buf->pages = kzalloc(buf->num_pages * sizeof(struct page *), |
150 | GFP_KERNEL); | 179 | GFP_KERNEL); |
151 | if (!buf->pages) | 180 | if (!buf->pages) |
152 | goto userptr_fail_pages_array_alloc; | 181 | return NULL; |
153 | 182 | ||
154 | num_pages_from_user = get_user_pages(current, current->mm, | 183 | num_pages_from_user = get_user_pages(current, current->mm, |
155 | vaddr & PAGE_MASK, | 184 | vaddr & PAGE_MASK, |
156 | buf->sg_desc.num_pages, | 185 | buf->num_pages, |
157 | write, | 186 | write, |
158 | 1, /* force */ | 187 | 1, /* force */ |
159 | buf->pages, | 188 | buf->pages, |
160 | NULL); | 189 | NULL); |
161 | 190 | ||
162 | if (num_pages_from_user != buf->sg_desc.num_pages) | 191 | if (num_pages_from_user != buf->num_pages) |
163 | goto userptr_fail_get_user_pages; | 192 | goto userptr_fail_get_user_pages; |
164 | 193 | ||
165 | sg_set_page(&buf->sg_desc.sglist[0], buf->pages[0], | 194 | if (sg_alloc_table_from_pages(&buf->sg_table, buf->pages, |
166 | PAGE_SIZE - buf->offset, buf->offset); | 195 | buf->num_pages, buf->offset, size, 0)) |
167 | size -= PAGE_SIZE - buf->offset; | 196 | goto userptr_fail_alloc_table_from_pages; |
168 | for (i = 1; i < buf->sg_desc.num_pages; ++i) { | 197 | |
169 | sg_set_page(&buf->sg_desc.sglist[i], buf->pages[i], | ||
170 | min_t(size_t, PAGE_SIZE, size), 0); | ||
171 | size -= min_t(size_t, PAGE_SIZE, size); | ||
172 | } | ||
173 | return buf; | 198 | return buf; |
174 | 199 | ||
200 | userptr_fail_alloc_table_from_pages: | ||
175 | userptr_fail_get_user_pages: | 201 | userptr_fail_get_user_pages: |
176 | dprintk(1, "get_user_pages requested/got: %d/%d]\n", | 202 | dprintk(1, "get_user_pages requested/got: %d/%d]\n", |
177 | num_pages_from_user, buf->sg_desc.num_pages); | 203 | num_pages_from_user, buf->num_pages); |
178 | while (--num_pages_from_user >= 0) | 204 | while (--num_pages_from_user >= 0) |
179 | put_page(buf->pages[num_pages_from_user]); | 205 | put_page(buf->pages[num_pages_from_user]); |
180 | kfree(buf->pages); | 206 | kfree(buf->pages); |
181 | |||
182 | userptr_fail_pages_array_alloc: | ||
183 | vfree(buf->sg_desc.sglist); | ||
184 | |||
185 | userptr_fail_sglist_alloc: | ||
186 | kfree(buf); | 207 | kfree(buf); |
187 | return NULL; | 208 | return NULL; |
188 | } | 209 | } |
@@ -194,18 +215,18 @@ userptr_fail_sglist_alloc: | |||
194 | static void vb2_dma_sg_put_userptr(void *buf_priv) | 215 | static void vb2_dma_sg_put_userptr(void *buf_priv) |
195 | { | 216 | { |
196 | struct vb2_dma_sg_buf *buf = buf_priv; | 217 | struct vb2_dma_sg_buf *buf = buf_priv; |
197 | int i = buf->sg_desc.num_pages; | 218 | int i = buf->num_pages; |
198 | 219 | ||
199 | dprintk(1, "%s: Releasing userspace buffer of %d pages\n", | 220 | dprintk(1, "%s: Releasing userspace buffer of %d pages\n", |
200 | __func__, buf->sg_desc.num_pages); | 221 | __func__, buf->num_pages); |
201 | if (buf->vaddr) | 222 | if (buf->vaddr) |
202 | vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages); | 223 | vm_unmap_ram(buf->vaddr, buf->num_pages); |
224 | sg_free_table(&buf->sg_table); | ||
203 | while (--i >= 0) { | 225 | while (--i >= 0) { |
204 | if (buf->write) | 226 | if (buf->write) |
205 | set_page_dirty_lock(buf->pages[i]); | 227 | set_page_dirty_lock(buf->pages[i]); |
206 | put_page(buf->pages[i]); | 228 | put_page(buf->pages[i]); |
207 | } | 229 | } |
208 | vfree(buf->sg_desc.sglist); | ||
209 | kfree(buf->pages); | 230 | kfree(buf->pages); |
210 | kfree(buf); | 231 | kfree(buf); |
211 | } | 232 | } |
@@ -218,7 +239,7 @@ static void *vb2_dma_sg_vaddr(void *buf_priv) | |||
218 | 239 | ||
219 | if (!buf->vaddr) | 240 | if (!buf->vaddr) |
220 | buf->vaddr = vm_map_ram(buf->pages, | 241 | buf->vaddr = vm_map_ram(buf->pages, |
221 | buf->sg_desc.num_pages, | 242 | buf->num_pages, |
222 | -1, | 243 | -1, |
223 | PAGE_KERNEL); | 244 | PAGE_KERNEL); |
224 | 245 | ||
@@ -274,7 +295,7 @@ static void *vb2_dma_sg_cookie(void *buf_priv) | |||
274 | { | 295 | { |
275 | struct vb2_dma_sg_buf *buf = buf_priv; | 296 | struct vb2_dma_sg_buf *buf = buf_priv; |
276 | 297 | ||
277 | return &buf->sg_desc; | 298 | return &buf->sg_table; |
278 | } | 299 | } |
279 | 300 | ||
280 | const struct vb2_mem_ops vb2_dma_sg_memops = { | 301 | const struct vb2_mem_ops vb2_dma_sg_memops = { |
diff --git a/drivers/staging/media/lirc/TODO b/drivers/staging/media/lirc/TODO index b6cb593f55c6..cbea5d84fed3 100644 --- a/drivers/staging/media/lirc/TODO +++ b/drivers/staging/media/lirc/TODO | |||
@@ -2,6 +2,11 @@ | |||
2 | (see drivers/media/IR/mceusb.c vs. lirc_mceusb.c in lirc cvs for an | 2 | (see drivers/media/IR/mceusb.c vs. lirc_mceusb.c in lirc cvs for an |
3 | example of a previously completed port). | 3 | example of a previously completed port). |
4 | 4 | ||
5 | - lirc_bt829 uses registers on a Mach64 VT, which has a separate kernel | ||
6 | framebuffer driver (atyfb) and userland X driver (mach64). It can't | ||
7 | simply be converted to a normal PCI driver, but ideally it should be | ||
8 | coordinated with the other drivers. | ||
9 | |||
5 | Please send patches to: | 10 | Please send patches to: |
6 | Jarod Wilson <jarod@wilsonet.com> | 11 | Jarod Wilson <jarod@wilsonet.com> |
7 | Greg Kroah-Hartman <greg@kroah.com> | 12 | Greg Kroah-Hartman <greg@kroah.com> |
diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c index fbbdce4c119f..30edc740ac25 100644 --- a/drivers/staging/media/lirc/lirc_bt829.c +++ b/drivers/staging/media/lirc/lirc_bt829.c | |||
@@ -63,7 +63,7 @@ static bool debug; | |||
63 | } while (0) | 63 | } while (0) |
64 | 64 | ||
65 | static int atir_minor; | 65 | static int atir_minor; |
66 | static unsigned long pci_addr_phys; | 66 | static phys_addr_t pci_addr_phys; |
67 | static unsigned char *pci_addr_lin; | 67 | static unsigned char *pci_addr_lin; |
68 | 68 | ||
69 | static struct lirc_driver atir_driver; | 69 | static struct lirc_driver atir_driver; |
@@ -78,11 +78,11 @@ static struct pci_dev *do_pci_probe(void) | |||
78 | pci_addr_phys = 0; | 78 | pci_addr_phys = 0; |
79 | if (my_dev->resource[0].flags & IORESOURCE_MEM) { | 79 | if (my_dev->resource[0].flags & IORESOURCE_MEM) { |
80 | pci_addr_phys = my_dev->resource[0].start; | 80 | pci_addr_phys = my_dev->resource[0].start; |
81 | pr_info("memory at 0x%08X\n", | 81 | pr_info("memory at %pa\n", &pci_addr_phys); |
82 | (unsigned int)pci_addr_phys); | ||
83 | } | 82 | } |
84 | if (pci_addr_phys == 0) { | 83 | if (pci_addr_phys == 0) { |
85 | pr_err("no memory resource ?\n"); | 84 | pr_err("no memory resource ?\n"); |
85 | pci_dev_put(my_dev); | ||
86 | return NULL; | 86 | return NULL; |
87 | } | 87 | } |
88 | } else { | 88 | } else { |
@@ -120,13 +120,20 @@ static void atir_set_use_dec(void *data) | |||
120 | int init_module(void) | 120 | int init_module(void) |
121 | { | 121 | { |
122 | struct pci_dev *pdev; | 122 | struct pci_dev *pdev; |
123 | int rc; | ||
123 | 124 | ||
124 | pdev = do_pci_probe(); | 125 | pdev = do_pci_probe(); |
125 | if (pdev == NULL) | 126 | if (pdev == NULL) |
126 | return -ENODEV; | 127 | return -ENODEV; |
127 | 128 | ||
128 | if (!atir_init_start()) | 129 | rc = pci_enable_device(pdev); |
129 | return -ENODEV; | 130 | if (rc) |
131 | goto err_put_dev; | ||
132 | |||
133 | if (!atir_init_start()) { | ||
134 | rc = -ENODEV; | ||
135 | goto err_disable; | ||
136 | } | ||
130 | 137 | ||
131 | strcpy(atir_driver.name, "ATIR"); | 138 | strcpy(atir_driver.name, "ATIR"); |
132 | atir_driver.minor = -1; | 139 | atir_driver.minor = -1; |
@@ -142,17 +149,31 @@ int init_module(void) | |||
142 | atir_minor = lirc_register_driver(&atir_driver); | 149 | atir_minor = lirc_register_driver(&atir_driver); |
143 | if (atir_minor < 0) { | 150 | if (atir_minor < 0) { |
144 | pr_err("failed to register driver!\n"); | 151 | pr_err("failed to register driver!\n"); |
145 | return atir_minor; | 152 | rc = atir_minor; |
153 | goto err_unmap; | ||
146 | } | 154 | } |
147 | dprintk("driver is registered on minor %d\n", atir_minor); | 155 | dprintk("driver is registered on minor %d\n", atir_minor); |
148 | 156 | ||
149 | return 0; | 157 | return 0; |
158 | |||
159 | err_unmap: | ||
160 | iounmap(pci_addr_lin); | ||
161 | err_disable: | ||
162 | pci_disable_device(pdev); | ||
163 | err_put_dev: | ||
164 | pci_dev_put(pdev); | ||
165 | return rc; | ||
150 | } | 166 | } |
151 | 167 | ||
152 | 168 | ||
153 | void cleanup_module(void) | 169 | void cleanup_module(void) |
154 | { | 170 | { |
171 | struct pci_dev *pdev = to_pci_dev(atir_driver.dev); | ||
172 | |||
155 | lirc_unregister_driver(atir_minor); | 173 | lirc_unregister_driver(atir_minor); |
174 | iounmap(pci_addr_lin); | ||
175 | pci_disable_device(pdev); | ||
176 | pci_dev_put(pdev); | ||
156 | } | 177 | } |
157 | 178 | ||
158 | 179 | ||
diff --git a/drivers/staging/media/msi3101/Kconfig b/drivers/staging/media/msi3101/Kconfig index 76d5bbd4d93c..0c349c8595e4 100644 --- a/drivers/staging/media/msi3101/Kconfig +++ b/drivers/staging/media/msi3101/Kconfig | |||
@@ -1,4 +1,5 @@ | |||
1 | config USB_MSI3101 | 1 | config USB_MSI3101 |
2 | tristate "Mirics MSi3101 SDR Dongle" | 2 | tristate "Mirics MSi3101 SDR Dongle" |
3 | depends on USB && VIDEO_DEV && VIDEO_V4L2 | 3 | depends on USB && VIDEO_DEV && VIDEO_V4L2 |
4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_CORE |
5 | select VIDEOBUF2_VMALLOC | ||
diff --git a/drivers/staging/media/solo6x10/solo6x10-disp.c b/drivers/staging/media/solo6x10/solo6x10-disp.c index 32d9953bc36e..145295a5db72 100644 --- a/drivers/staging/media/solo6x10/solo6x10-disp.c +++ b/drivers/staging/media/solo6x10/solo6x10-disp.c | |||
@@ -176,18 +176,27 @@ static void solo_vout_config(struct solo_dev *solo_dev) | |||
176 | static int solo_dma_vin_region(struct solo_dev *solo_dev, u32 off, | 176 | static int solo_dma_vin_region(struct solo_dev *solo_dev, u32 off, |
177 | u16 val, int reg_size) | 177 | u16 val, int reg_size) |
178 | { | 178 | { |
179 | u16 buf[64]; | 179 | u16 *buf; |
180 | int i; | 180 | const int n = 64, size = n * sizeof(*buf); |
181 | int ret = 0; | 181 | int i, ret = 0; |
182 | |||
183 | buf = kmalloc(size, GFP_KERNEL); | ||
184 | if (!buf) | ||
185 | return -ENOMEM; | ||
182 | 186 | ||
183 | for (i = 0; i < sizeof(buf) >> 1; i++) | 187 | for (i = 0; i < n; i++) |
184 | buf[i] = cpu_to_le16(val); | 188 | buf[i] = cpu_to_le16(val); |
185 | 189 | ||
186 | for (i = 0; i < reg_size; i += sizeof(buf)) | 190 | for (i = 0; i < reg_size; i += size) { |
187 | ret |= solo_p2m_dma(solo_dev, 1, buf, | 191 | ret = solo_p2m_dma(solo_dev, 1, buf, |
188 | SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, | 192 | SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, |
189 | sizeof(buf), 0, 0); | 193 | size, 0, 0); |
194 | |||
195 | if (ret) | ||
196 | break; | ||
197 | } | ||
190 | 198 | ||
199 | kfree(buf); | ||
191 | return ret; | 200 | return ret; |
192 | } | 201 | } |
193 | 202 | ||
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c index a4c589604b02..d582c5b84c14 100644 --- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c | |||
@@ -95,38 +95,11 @@ static unsigned char vop_6110_pal_cif[] = { | |||
95 | 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00, | 95 | 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | struct vop_header { | 98 | typedef __le32 vop_header[16]; |
99 | /* VE_STATUS0 */ | ||
100 | u32 mpeg_size:20, sad_motion_flag:1, video_motion_flag:1, vop_type:2, | ||
101 | channel:5, source_fl:1, interlace:1, progressive:1; | ||
102 | |||
103 | /* VE_STATUS1 */ | ||
104 | u32 vsize:8, hsize:8, last_queue:4, nop0:8, scale:4; | ||
105 | |||
106 | /* VE_STATUS2 */ | ||
107 | u32 mpeg_off; | ||
108 | |||
109 | /* VE_STATUS3 */ | ||
110 | u32 jpeg_off; | ||
111 | |||
112 | /* VE_STATUS4 */ | ||
113 | u32 jpeg_size:20, interval:10, nop1:2; | ||
114 | |||
115 | /* VE_STATUS5/6 */ | ||
116 | u32 sec, usec; | ||
117 | |||
118 | /* VE_STATUS7/8/9 */ | ||
119 | u32 nop2[3]; | ||
120 | |||
121 | /* VE_STATUS10 */ | ||
122 | u32 mpeg_size_alt:20, nop3:12; | ||
123 | |||
124 | u32 end_nops[5]; | ||
125 | } __packed; | ||
126 | 99 | ||
127 | struct solo_enc_buf { | 100 | struct solo_enc_buf { |
128 | enum solo_enc_types type; | 101 | enum solo_enc_types type; |
129 | struct vop_header *vh; | 102 | const vop_header *vh; |
130 | int motion; | 103 | int motion; |
131 | }; | 104 | }; |
132 | 105 | ||
@@ -346,7 +319,7 @@ static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, | |||
346 | /* Build a descriptor queue out of an SG list and send it to the P2M for | 319 | /* Build a descriptor queue out of an SG list and send it to the P2M for |
347 | * processing. */ | 320 | * processing. */ |
348 | static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | 321 | static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, |
349 | struct vb2_dma_sg_desc *vbuf, int off, int size, | 322 | struct sg_table *vbuf, int off, int size, |
350 | unsigned int base, unsigned int base_size) | 323 | unsigned int base, unsigned int base_size) |
351 | { | 324 | { |
352 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 325 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
@@ -359,7 +332,7 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | |||
359 | 332 | ||
360 | solo_enc->desc_count = 1; | 333 | solo_enc->desc_count = 1; |
361 | 334 | ||
362 | for_each_sg(vbuf->sglist, sg, vbuf->num_pages, i) { | 335 | for_each_sg(vbuf->sgl, sg, vbuf->nents, i) { |
363 | struct solo_p2m_desc *desc; | 336 | struct solo_p2m_desc *desc; |
364 | dma_addr_t dma; | 337 | dma_addr_t dma; |
365 | int len; | 338 | int len; |
@@ -430,84 +403,145 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | |||
430 | solo_enc->desc_count - 1); | 403 | solo_enc->desc_count - 1); |
431 | } | 404 | } |
432 | 405 | ||
406 | /* Extract values from VOP header - VE_STATUSxx */ | ||
407 | static inline int vop_interlaced(const vop_header *vh) | ||
408 | { | ||
409 | return (__le32_to_cpu((*vh)[0]) >> 30) & 1; | ||
410 | } | ||
411 | |||
412 | static inline u8 vop_channel(const vop_header *vh) | ||
413 | { | ||
414 | return (__le32_to_cpu((*vh)[0]) >> 24) & 0x1F; | ||
415 | } | ||
416 | |||
417 | static inline u8 vop_type(const vop_header *vh) | ||
418 | { | ||
419 | return (__le32_to_cpu((*vh)[0]) >> 22) & 3; | ||
420 | } | ||
421 | |||
422 | static inline u32 vop_mpeg_size(const vop_header *vh) | ||
423 | { | ||
424 | return __le32_to_cpu((*vh)[0]) & 0xFFFFF; | ||
425 | } | ||
426 | |||
427 | static inline u8 vop_hsize(const vop_header *vh) | ||
428 | { | ||
429 | return (__le32_to_cpu((*vh)[1]) >> 8) & 0xFF; | ||
430 | } | ||
431 | |||
432 | static inline u8 vop_vsize(const vop_header *vh) | ||
433 | { | ||
434 | return __le32_to_cpu((*vh)[1]) & 0xFF; | ||
435 | } | ||
436 | |||
437 | static inline u32 vop_mpeg_offset(const vop_header *vh) | ||
438 | { | ||
439 | return __le32_to_cpu((*vh)[2]); | ||
440 | } | ||
441 | |||
442 | static inline u32 vop_jpeg_offset(const vop_header *vh) | ||
443 | { | ||
444 | return __le32_to_cpu((*vh)[3]); | ||
445 | } | ||
446 | |||
447 | static inline u32 vop_jpeg_size(const vop_header *vh) | ||
448 | { | ||
449 | return __le32_to_cpu((*vh)[4]) & 0xFFFFF; | ||
450 | } | ||
451 | |||
452 | static inline u32 vop_sec(const vop_header *vh) | ||
453 | { | ||
454 | return __le32_to_cpu((*vh)[5]); | ||
455 | } | ||
456 | |||
457 | static inline u32 vop_usec(const vop_header *vh) | ||
458 | { | ||
459 | return __le32_to_cpu((*vh)[6]); | ||
460 | } | ||
461 | |||
433 | static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, | 462 | static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, |
434 | struct vb2_buffer *vb, struct vop_header *vh) | 463 | struct vb2_buffer *vb, const vop_header *vh) |
435 | { | 464 | { |
436 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 465 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
437 | struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); | 466 | struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); |
438 | int frame_size; | 467 | int frame_size; |
439 | int ret; | 468 | int ret; |
440 | 469 | ||
441 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | 470 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
442 | 471 | ||
443 | if (vb2_plane_size(vb, 0) < vh->jpeg_size + solo_enc->jpeg_len) | 472 | if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len) |
444 | return -EIO; | 473 | return -EIO; |
445 | 474 | ||
446 | sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, | 475 | frame_size = (vop_jpeg_size(vh) + solo_enc->jpeg_len + (DMA_ALIGN - 1)) |
447 | solo_enc->jpeg_header, | ||
448 | solo_enc->jpeg_len); | ||
449 | |||
450 | frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) | ||
451 | & ~(DMA_ALIGN - 1); | 476 | & ~(DMA_ALIGN - 1); |
452 | vb2_set_plane_payload(vb, 0, vh->jpeg_size + solo_enc->jpeg_len); | 477 | vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); |
453 | 478 | ||
454 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | 479 | /* may discard all previous data in vbuf->sgl */ |
480 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | ||
455 | DMA_FROM_DEVICE); | 481 | DMA_FROM_DEVICE); |
456 | ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off, | 482 | ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, |
457 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), | 483 | vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), |
458 | SOLO_JPEG_EXT_SIZE(solo_dev)); | 484 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), |
459 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | 485 | SOLO_JPEG_EXT_SIZE(solo_dev)); |
486 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | ||
460 | DMA_FROM_DEVICE); | 487 | DMA_FROM_DEVICE); |
488 | |||
489 | /* add the header only after dma_unmap_sg() */ | ||
490 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
491 | solo_enc->jpeg_header, solo_enc->jpeg_len); | ||
492 | |||
461 | return ret; | 493 | return ret; |
462 | } | 494 | } |
463 | 495 | ||
464 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, | 496 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, |
465 | struct vb2_buffer *vb, struct vop_header *vh) | 497 | struct vb2_buffer *vb, const vop_header *vh) |
466 | { | 498 | { |
467 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 499 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
468 | struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); | 500 | struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); |
469 | int frame_off, frame_size; | 501 | int frame_off, frame_size; |
470 | int skip = 0; | 502 | int skip = 0; |
471 | int ret; | 503 | int ret; |
472 | 504 | ||
473 | if (vb2_plane_size(vb, 0) < vh->mpeg_size) | 505 | if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh)) |
474 | return -EIO; | 506 | return -EIO; |
475 | 507 | ||
476 | /* If this is a key frame, add extra header */ | 508 | /* If this is a key frame, add extra header */ |
477 | if (!vh->vop_type) { | 509 | vb->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME); |
478 | sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, | 510 | if (!vop_type(vh)) { |
479 | solo_enc->vop, | ||
480 | solo_enc->vop_len); | ||
481 | |||
482 | skip = solo_enc->vop_len; | 511 | skip = solo_enc->vop_len; |
483 | |||
484 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | 512 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
485 | vb2_set_plane_payload(vb, 0, vh->mpeg_size + solo_enc->vop_len); | 513 | vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh) + solo_enc->vop_len); |
486 | } else { | 514 | } else { |
487 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; | 515 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; |
488 | vb2_set_plane_payload(vb, 0, vh->mpeg_size); | 516 | vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh)); |
489 | } | 517 | } |
490 | 518 | ||
491 | /* Now get the actual mpeg payload */ | 519 | /* Now get the actual mpeg payload */ |
492 | frame_off = (vh->mpeg_off + sizeof(*vh)) | 520 | frame_off = (vop_mpeg_offset(vh) - SOLO_MP4E_EXT_ADDR(solo_dev) + sizeof(*vh)) |
493 | % SOLO_MP4E_EXT_SIZE(solo_dev); | 521 | % SOLO_MP4E_EXT_SIZE(solo_dev); |
494 | frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) | 522 | frame_size = (vop_mpeg_size(vh) + skip + (DMA_ALIGN - 1)) |
495 | & ~(DMA_ALIGN - 1); | 523 | & ~(DMA_ALIGN - 1); |
496 | 524 | ||
497 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | 525 | /* may discard all previous data in vbuf->sgl */ |
526 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | ||
498 | DMA_FROM_DEVICE); | 527 | DMA_FROM_DEVICE); |
499 | ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, | 528 | ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, |
500 | SOLO_MP4E_EXT_ADDR(solo_dev), | 529 | SOLO_MP4E_EXT_ADDR(solo_dev), |
501 | SOLO_MP4E_EXT_SIZE(solo_dev)); | 530 | SOLO_MP4E_EXT_SIZE(solo_dev)); |
502 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | 531 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, |
503 | DMA_FROM_DEVICE); | 532 | DMA_FROM_DEVICE); |
533 | |||
534 | /* add the header only after dma_unmap_sg() */ | ||
535 | if (!vop_type(vh)) | ||
536 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
537 | solo_enc->vop, solo_enc->vop_len); | ||
504 | return ret; | 538 | return ret; |
505 | } | 539 | } |
506 | 540 | ||
507 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, | 541 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, |
508 | struct vb2_buffer *vb, struct solo_enc_buf *enc_buf) | 542 | struct vb2_buffer *vb, struct solo_enc_buf *enc_buf) |
509 | { | 543 | { |
510 | struct vop_header *vh = enc_buf->vh; | 544 | const vop_header *vh = enc_buf->vh; |
511 | int ret; | 545 | int ret; |
512 | 546 | ||
513 | /* Check for motion flags */ | 547 | /* Check for motion flags */ |
@@ -531,8 +565,8 @@ static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, | |||
531 | 565 | ||
532 | if (!ret) { | 566 | if (!ret) { |
533 | vb->v4l2_buf.sequence = solo_enc->sequence++; | 567 | vb->v4l2_buf.sequence = solo_enc->sequence++; |
534 | vb->v4l2_buf.timestamp.tv_sec = vh->sec; | 568 | vb->v4l2_buf.timestamp.tv_sec = vop_sec(vh); |
535 | vb->v4l2_buf.timestamp.tv_usec = vh->usec; | 569 | vb->v4l2_buf.timestamp.tv_usec = vop_usec(vh); |
536 | } | 570 | } |
537 | 571 | ||
538 | vb2_buffer_done(vb, ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); | 572 | vb2_buffer_done(vb, ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); |
@@ -605,15 +639,13 @@ static void solo_handle_ring(struct solo_dev *solo_dev) | |||
605 | 639 | ||
606 | /* FAIL... */ | 640 | /* FAIL... */ |
607 | if (enc_get_mpeg_dma(solo_dev, solo_dev->vh_dma, off, | 641 | if (enc_get_mpeg_dma(solo_dev, solo_dev->vh_dma, off, |
608 | sizeof(struct vop_header))) | 642 | sizeof(vop_header))) |
609 | continue; | 643 | continue; |
610 | 644 | ||
611 | enc_buf.vh = (struct vop_header *)solo_dev->vh_buf; | 645 | enc_buf.vh = solo_dev->vh_buf; |
612 | enc_buf.vh->mpeg_off -= SOLO_MP4E_EXT_ADDR(solo_dev); | ||
613 | enc_buf.vh->jpeg_off -= SOLO_JPEG_EXT_ADDR(solo_dev); | ||
614 | 646 | ||
615 | /* Sanity check */ | 647 | /* Sanity check */ |
616 | if (enc_buf.vh->mpeg_off != off) | 648 | if (vop_mpeg_offset(enc_buf.vh) != SOLO_MP4E_EXT_ADDR(solo_dev) + off) |
617 | continue; | 649 | continue; |
618 | 650 | ||
619 | if (solo_motion_detected(solo_enc)) | 651 | if (solo_motion_detected(solo_enc)) |
@@ -1329,7 +1361,7 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr) | |||
1329 | 1361 | ||
1330 | init_waitqueue_head(&solo_dev->ring_thread_wait); | 1362 | init_waitqueue_head(&solo_dev->ring_thread_wait); |
1331 | 1363 | ||
1332 | solo_dev->vh_size = sizeof(struct vop_header); | 1364 | solo_dev->vh_size = sizeof(vop_header); |
1333 | solo_dev->vh_buf = pci_alloc_consistent(solo_dev->pdev, | 1365 | solo_dev->vh_buf = pci_alloc_consistent(solo_dev->pdev, |
1334 | solo_dev->vh_size, | 1366 | solo_dev->vh_size, |
1335 | &solo_dev->vh_dma); | 1367 | &solo_dev->vh_dma); |
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h index 6f91d2e34b2a..f1bbb8cb74e6 100644 --- a/drivers/staging/media/solo6x10/solo6x10.h +++ b/drivers/staging/media/solo6x10/solo6x10.h | |||
@@ -94,7 +94,6 @@ | |||
94 | #define SOLO_ENC_MODE_HD1 1 | 94 | #define SOLO_ENC_MODE_HD1 1 |
95 | #define SOLO_ENC_MODE_D1 9 | 95 | #define SOLO_ENC_MODE_D1 9 |
96 | 96 | ||
97 | #define SOLO_DEFAULT_GOP 30 | ||
98 | #define SOLO_DEFAULT_QP 3 | 97 | #define SOLO_DEFAULT_QP 3 |
99 | 98 | ||
100 | #ifndef V4L2_BUF_FLAG_MOTION_ON | 99 | #ifndef V4L2_BUF_FLAG_MOTION_ON |