aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/pata_atiixp.c4
-rw-r--r--drivers/ata/pata_via.c11
-rw-r--r--drivers/gpio/pca953x.c24
-rw-r--r--drivers/gpio/pcf857x.c36
-rw-r--r--drivers/hwmon/f75375s.c29
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c5
-rw-r--r--drivers/i2c/busses/i2c-piix4.c10
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c14
-rw-r--r--drivers/i2c/busses/i2c-sis630.c2
-rw-r--r--drivers/i2c/busses/i2c-stub.c2
-rw-r--r--drivers/i2c/busses/i2c-taos-evm.c3
-rw-r--r--drivers/i2c/chips/ds1682.c10
-rw-r--r--drivers/i2c/chips/menelaus.c10
-rw-r--r--drivers/i2c/chips/tps65010.c34
-rw-r--r--drivers/i2c/chips/tsl2550.c10
-rw-r--r--drivers/i2c/i2c-core.c51
-rw-r--r--drivers/ide/pci/alim15x3.c10
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c18
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h21
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c167
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.h2
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c2
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.h3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c60
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h5
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c11
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c35
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c36
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c26
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_user.h10
-rw-r--r--drivers/infiniband/hw/nes/Kconfig1
-rw-r--r--drivers/infiniband/hw/nes/nes.c4
-rw-r--r--drivers/infiniband/hw/nes/nes.h5
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c8
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c371
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h19
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c180
-rw-r--r--drivers/infiniband/hw/nes/nes_utils.c10
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h7
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c45
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c39
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c3
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c4
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h7
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c9
-rw-r--r--drivers/media/Kconfig172
-rw-r--r--drivers/media/Makefile10
-rw-r--r--drivers/media/common/tuners/Kconfig146
-rw-r--r--drivers/media/common/tuners/Makefile25
-rw-r--r--drivers/media/common/tuners/mt2060.c (renamed from drivers/media/dvb/frontends/mt2060.c)0
-rw-r--r--drivers/media/common/tuners/mt2060.h (renamed from drivers/media/dvb/frontends/mt2060.h)4
-rw-r--r--drivers/media/common/tuners/mt2060_priv.h (renamed from drivers/media/dvb/frontends/mt2060_priv.h)0
-rw-r--r--drivers/media/common/tuners/mt20xx.c (renamed from drivers/media/video/mt20xx.c)0
-rw-r--r--drivers/media/common/tuners/mt20xx.h (renamed from drivers/media/video/mt20xx.h)2
-rw-r--r--drivers/media/common/tuners/mt2131.c (renamed from drivers/media/dvb/frontends/mt2131.c)0
-rw-r--r--drivers/media/common/tuners/mt2131.h (renamed from drivers/media/dvb/frontends/mt2131.h)4
-rw-r--r--drivers/media/common/tuners/mt2131_priv.h (renamed from drivers/media/dvb/frontends/mt2131_priv.h)0
-rw-r--r--drivers/media/common/tuners/mt2266.c (renamed from drivers/media/dvb/frontends/mt2266.c)0
-rw-r--r--drivers/media/common/tuners/mt2266.h (renamed from drivers/media/dvb/frontends/mt2266.h)4
-rw-r--r--drivers/media/common/tuners/qt1010.c (renamed from drivers/media/dvb/frontends/qt1010.c)0
-rw-r--r--drivers/media/common/tuners/qt1010.h (renamed from drivers/media/dvb/frontends/qt1010.h)4
-rw-r--r--drivers/media/common/tuners/qt1010_priv.h (renamed from drivers/media/dvb/frontends/qt1010_priv.h)0
-rw-r--r--drivers/media/common/tuners/tda18271-common.c (renamed from drivers/media/dvb/frontends/tda18271-common.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c (renamed from drivers/media/dvb/frontends/tda18271-fe.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c (renamed from drivers/media/dvb/frontends/tda18271-tables.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h (renamed from drivers/media/dvb/frontends/tda18271-priv.h)0
-rw-r--r--drivers/media/common/tuners/tda18271.h (renamed from drivers/media/dvb/frontends/tda18271.h)2
-rw-r--r--drivers/media/common/tuners/tda827x.c (renamed from drivers/media/dvb/frontends/tda827x.c)0
-rw-r--r--drivers/media/common/tuners/tda827x.h (renamed from drivers/media/dvb/frontends/tda827x.h)4
-rw-r--r--drivers/media/common/tuners/tda8290.c (renamed from drivers/media/video/tda8290.c)8
-rw-r--r--drivers/media/common/tuners/tda8290.h (renamed from drivers/media/video/tda8290.h)2
-rw-r--r--drivers/media/common/tuners/tda9887.c (renamed from drivers/media/video/tda9887.c)0
-rw-r--r--drivers/media/common/tuners/tda9887.h (renamed from drivers/media/video/tda9887.h)2
-rw-r--r--drivers/media/common/tuners/tea5761.c (renamed from drivers/media/video/tea5761.c)0
-rw-r--r--drivers/media/common/tuners/tea5761.h (renamed from drivers/media/video/tea5761.h)2
-rw-r--r--drivers/media/common/tuners/tea5767.c (renamed from drivers/media/video/tea5767.c)0
-rw-r--r--drivers/media/common/tuners/tea5767.h (renamed from drivers/media/video/tea5767.h)2
-rw-r--r--drivers/media/common/tuners/tuner-i2c.h (renamed from drivers/media/video/tuner-i2c.h)0
-rw-r--r--drivers/media/common/tuners/tuner-simple.c (renamed from drivers/media/video/tuner-simple.c)0
-rw-r--r--drivers/media/common/tuners/tuner-simple.h (renamed from drivers/media/video/tuner-simple.h)2
-rw-r--r--drivers/media/common/tuners/tuner-types.c (renamed from drivers/media/video/tuner-types.c)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028-types.h (renamed from drivers/media/video/tuner-xc2028-types.h)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c (renamed from drivers/media/video/tuner-xc2028.c)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.h (renamed from drivers/media/video/tuner-xc2028.h)2
-rw-r--r--drivers/media/common/tuners/xc5000.c (renamed from drivers/media/dvb/frontends/xc5000.c)0
-rw-r--r--drivers/media/common/tuners/xc5000.h (renamed from drivers/media/dvb/frontends/xc5000.h)6
-rw-r--r--drivers/media/common/tuners/xc5000_priv.h (renamed from drivers/media/dvb/frontends/xc5000_priv.h)0
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/b2c2/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig34
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig26
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--drivers/media/dvb/frontends/Kconfig121
-rw-r--r--drivers/media/dvb/frontends/Makefile11
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c2
-rw-r--r--drivers/media/video/Kconfig50
-rw-r--r--drivers/media/video/Makefile14
-rw-r--r--drivers/media/video/au0828/Kconfig2
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/bt8xx/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/Makefile1
-rw-r--r--drivers/media/video/cs5345.c3
-rw-r--r--drivers/media/video/cs53l32a.c3
-rw-r--r--drivers/media/video/cx18/Kconfig20
-rw-r--r--drivers/media/video/cx18/Makefile11
-rw-r--r--drivers/media/video/cx18/cx18-audio.c73
-rw-r--r--drivers/media/video/cx18/cx18-audio.h26
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c361
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c879
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h318
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c120
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c413
-rw-r--r--drivers/media/video/cx18/cx18-cards.c277
-rw-r--r--drivers/media/video/cx18/cx18-cards.h170
-rw-r--r--drivers/media/video/cx18/cx18-controls.c306
-rw-r--r--drivers/media/video/cx18/cx18-controls.h24
-rw-r--r--drivers/media/video/cx18/cx18-driver.c971
-rw-r--r--drivers/media/video/cx18/cx18-driver.h500
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c288
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c711
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h45
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c373
-rw-r--r--drivers/media/video/cx18/cx18-firmware.h25
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c74
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h24
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c431
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h33
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c851
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h30
-rw-r--r--drivers/media/video/cx18/cx18-irq.c179
-rw-r--r--drivers/media/video/cx18/cx18-irq.h37
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c372
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h73
-rw-r--r--drivers/media/video/cx18/cx18-queue.c282
-rw-r--r--drivers/media/video/cx18/cx18-queue.h59
-rw-r--r--drivers/media/video/cx18/cx18-scb.c121
-rw-r--r--drivers/media/video/cx18/cx18-scb.h285
-rw-r--r--drivers/media/video/cx18/cx18-streams.c566
-rw-r--r--drivers/media/video/cx18/cx18-streams.h33
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c208
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h26
-rw-r--r--drivers/media/video/cx18/cx18-version.h34
-rw-r--r--drivers/media/video/cx18/cx18-video.c45
-rw-r--r--drivers/media/video/cx18/cx18-video.h22
-rw-r--r--drivers/media/video/cx18/cx23418.h458
-rw-r--r--drivers/media/video/cx23885/Kconfig12
-rw-r--r--drivers/media/video/cx23885/Makefile1
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c3
-rw-r--r--drivers/media/video/cx88/Kconfig4
-rw-r--r--drivers/media/video/cx88/Makefile1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c50
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c30
-rw-r--r--drivers/media/video/em28xx/Kconfig2
-rw-r--r--drivers/media/video/em28xx/Makefile1
-rw-r--r--drivers/media/video/ivtv/Kconfig2
-rw-r--r--drivers/media/video/ivtv/Makefile1
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c98
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h5
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c43
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c44
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/video/m52790.c3
-rw-r--r--drivers/media/video/msp3400-driver.c2
-rw-r--r--drivers/media/video/mt9m001.c12
-rw-r--r--drivers/media/video/mt9v022.c12
-rw-r--r--drivers/media/video/pvrusb2/Kconfig55
-rw-r--r--drivers/media/video/pvrusb2/Makefile1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debug.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c42
-rw-r--r--drivers/media/video/saa7115.c3
-rw-r--r--drivers/media/video/saa7127.c3
-rw-r--r--drivers/media/video/saa7134/Kconfig6
-rw-r--r--drivers/media/video/saa7134/Makefile1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c260
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c42
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa717x.c3
-rw-r--r--drivers/media/video/tcm825x.c3
-rw-r--r--drivers/media/video/tlv320aic23b.c3
-rw-r--r--drivers/media/video/tuner-core.c127
-rw-r--r--drivers/media/video/tvaudio.c2
-rw-r--r--drivers/media/video/upd64031a.c3
-rw-r--r--drivers/media/video/upd64083.c3
-rw-r--r--drivers/media/video/usbvision/Kconfig2
-rw-r--r--drivers/media/video/usbvision/Makefile1
-rw-r--r--drivers/media/video/v4l2-common.c5
-rw-r--r--drivers/media/video/vp27smpx.c3
-rw-r--r--drivers/media/video/wm8739.c3
-rw-r--r--drivers/media/video/wm8775.c3
-rw-r--r--drivers/mfd/htc-pasic3.c9
-rw-r--r--drivers/mmc/host/mmci.c4
-rw-r--r--drivers/net/arm/am79c961a.c10
-rw-r--r--drivers/net/cxgb3/version.h2
-rw-r--r--drivers/net/mlx4/cq.c4
-rw-r--r--drivers/net/mlx4/mr.c6
-rw-r--r--drivers/rtc/rtc-ds1307.c66
-rw-r--r--drivers/rtc/rtc-ds1374.c10
-rw-r--r--drivers/rtc/rtc-isl1208.c9
-rw-r--r--drivers/rtc/rtc-m41t80.c81
-rw-r--r--drivers/rtc/rtc-pcf8563.c10
-rw-r--r--drivers/rtc/rtc-rs5c372.c27
-rw-r--r--drivers/rtc/rtc-s35390a.c10
-rw-r--r--drivers/rtc/rtc-x1205.c10
-rw-r--r--drivers/serial/s3c2410.c7
231 files changed, 12214 insertions, 1290 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7c4f886f1f16..8cace9aa9c03 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -358,7 +358,7 @@ static const struct ata_port_info ahci_port_info[] = {
358 /* board_ahci_sb600 */ 358 /* board_ahci_sb600 */
359 { 359 {
360 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | 360 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
361 AHCI_HFLAG_32BIT_ONLY | 361 AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
362 AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), 362 AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
363 .flags = AHCI_FLAG_COMMON, 363 .flags = AHCI_FLAG_COMMON,
364 .pio_mask = 0x1f, /* pio0-4 */ 364 .pio_mask = 0x1f, /* pio0-4 */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 51b7d2fad36a..3bc488538204 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3933,6 +3933,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
3933 3933
3934 /* Devices which get the IVB wrong */ 3934 /* Devices which get the IVB wrong */
3935 { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, }, 3935 { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
3936 /* Maybe we should just blacklist TSSTcorp... */
3937 { "TSSTcorp CDDVDW SH-S202H", "SB00", ATA_HORKAGE_IVB, },
3938 { "TSSTcorp CDDVDW SH-S202H", "SB01", ATA_HORKAGE_IVB, },
3936 { "TSSTcorp CDDVDW SH-S202J", "SB00", ATA_HORKAGE_IVB, }, 3939 { "TSSTcorp CDDVDW SH-S202J", "SB00", ATA_HORKAGE_IVB, },
3937 { "TSSTcorp CDDVDW SH-S202J", "SB01", ATA_HORKAGE_IVB, }, 3940 { "TSSTcorp CDDVDW SH-S202J", "SB01", ATA_HORKAGE_IVB, },
3938 { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, }, 3941 { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, },
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 78738fb4223b..d7de7baf58a8 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -88,8 +88,8 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev,
88 pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data); 88 pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
89 89
90 pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); 90 pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
91 pio_mode_data &= ~(0xFF << timing_shift); 91 pio_timing_data &= ~(0xFF << timing_shift);
92 pio_mode_data |= (pio_timings[pio] << timing_shift); 92 pio_timing_data |= (pio_timings[pio] << timing_shift);
93 pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); 93 pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
94} 94}
95 95
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index d4840748fb5c..2fea6cbe7755 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -464,11 +464,12 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
464 } 464 }
465 pci_dev_put(isa); 465 pci_dev_put(isa);
466 466
467 /* 0x40 low bits indicate enabled channels */ 467 if (!(config->flags & VIA_NO_ENABLES)) {
468 pci_read_config_byte(pdev, 0x40 , &enable); 468 /* 0x40 low bits indicate enabled channels */
469 enable &= 3; 469 pci_read_config_byte(pdev, 0x40 , &enable);
470 if (enable == 0) { 470 enable &= 3;
471 return -ENODEV; 471 if (enable == 0)
472 return -ENODEV;
472 } 473 }
473 474
474 /* Initialise the FIFO for the enabled channels. */ 475 /* Initialise the FIFO for the enabled channels. */
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index e0e0af536108..5a99e81d2784 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -23,13 +23,7 @@
23#define PCA953X_INVERT 2 23#define PCA953X_INVERT 2
24#define PCA953X_DIRECTION 3 24#define PCA953X_DIRECTION 3
25 25
26/* This is temporary - in 2.6.26 i2c_driver_data should replace it. */ 26static const struct i2c_device_id pca953x_id[] = {
27struct pca953x_desc {
28 char name[I2C_NAME_SIZE];
29 unsigned long driver_data;
30};
31
32static const struct pca953x_desc pca953x_descs[] = {
33 { "pca9534", 8, }, 27 { "pca9534", 8, },
34 { "pca9535", 16, }, 28 { "pca9535", 16, },
35 { "pca9536", 4, }, 29 { "pca9536", 4, },
@@ -37,7 +31,9 @@ static const struct pca953x_desc pca953x_descs[] = {
37 { "pca9538", 8, }, 31 { "pca9538", 8, },
38 { "pca9539", 16, }, 32 { "pca9539", 16, },
39 /* REVISIT several pca955x parts should work here too */ 33 /* REVISIT several pca955x parts should work here too */
34 { }
40}; 35};
36MODULE_DEVICE_TABLE(i2c, pca953x_id);
41 37
42struct pca953x_chip { 38struct pca953x_chip {
43 unsigned gpio_start; 39 unsigned gpio_start;
@@ -192,26 +188,17 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
192 gc->owner = THIS_MODULE; 188 gc->owner = THIS_MODULE;
193} 189}
194 190
195static int __devinit pca953x_probe(struct i2c_client *client) 191static int __devinit pca953x_probe(struct i2c_client *client,
192 const struct i2c_device_id *id)
196{ 193{
197 struct pca953x_platform_data *pdata; 194 struct pca953x_platform_data *pdata;
198 struct pca953x_chip *chip; 195 struct pca953x_chip *chip;
199 int ret, i; 196 int ret, i;
200 const struct pca953x_desc *id = NULL;
201 197
202 pdata = client->dev.platform_data; 198 pdata = client->dev.platform_data;
203 if (pdata == NULL) 199 if (pdata == NULL)
204 return -ENODEV; 200 return -ENODEV;
205 201
206 /* this loop vanishes when we get i2c_device_id */
207 for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++)
208 if (!strcmp(pca953x_descs[i].name, client->name)) {
209 id = pca953x_descs + i;
210 break;
211 }
212 if (!id)
213 return -ENODEV;
214
215 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 202 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
216 if (chip == NULL) 203 if (chip == NULL)
217 return -ENOMEM; 204 return -ENOMEM;
@@ -291,6 +278,7 @@ static struct i2c_driver pca953x_driver = {
291 }, 278 },
292 .probe = pca953x_probe, 279 .probe = pca953x_probe,
293 .remove = pca953x_remove, 280 .remove = pca953x_remove,
281 .id_table = pca953x_id,
294}; 282};
295 283
296static int __init pca953x_init(void) 284static int __init pca953x_init(void)
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c
index 1106aa15ac79..aa6cc8b2a2bc 100644
--- a/drivers/gpio/pcf857x.c
+++ b/drivers/gpio/pcf857x.c
@@ -26,6 +26,21 @@
26#include <asm/gpio.h> 26#include <asm/gpio.h>
27 27
28 28
29static const struct i2c_device_id pcf857x_id[] = {
30 { "pcf8574", 8 },
31 { "pca8574", 8 },
32 { "pca9670", 8 },
33 { "pca9672", 8 },
34 { "pca9674", 8 },
35 { "pcf8575", 16 },
36 { "pca8575", 16 },
37 { "pca9671", 16 },
38 { "pca9673", 16 },
39 { "pca9675", 16 },
40 { }
41};
42MODULE_DEVICE_TABLE(i2c, pcf857x_id);
43
29/* 44/*
30 * The pcf857x, pca857x, and pca967x chips only expose one read and one 45 * The pcf857x, pca857x, and pca967x chips only expose one read and one
31 * write register. Writing a "one" bit (to match the reset state) lets 46 * write register. Writing a "one" bit (to match the reset state) lets
@@ -142,7 +157,8 @@ static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value)
142 157
143/*-------------------------------------------------------------------------*/ 158/*-------------------------------------------------------------------------*/
144 159
145static int pcf857x_probe(struct i2c_client *client) 160static int pcf857x_probe(struct i2c_client *client,
161 const struct i2c_device_id *id)
146{ 162{
147 struct pcf857x_platform_data *pdata; 163 struct pcf857x_platform_data *pdata;
148 struct pcf857x *gpio; 164 struct pcf857x *gpio;
@@ -172,13 +188,8 @@ static int pcf857x_probe(struct i2c_client *client)
172 * 188 *
173 * NOTE: we don't distinguish here between *4 and *4a parts. 189 * NOTE: we don't distinguish here between *4 and *4a parts.
174 */ 190 */
175 if (strcmp(client->name, "pcf8574") == 0 191 gpio->chip.ngpio = id->driver_data;
176 || strcmp(client->name, "pca8574") == 0 192 if (gpio->chip.ngpio == 8) {
177 || strcmp(client->name, "pca9670") == 0
178 || strcmp(client->name, "pca9672") == 0
179 || strcmp(client->name, "pca9674") == 0
180 ) {
181 gpio->chip.ngpio = 8;
182 gpio->chip.direction_input = pcf857x_input8; 193 gpio->chip.direction_input = pcf857x_input8;
183 gpio->chip.get = pcf857x_get8; 194 gpio->chip.get = pcf857x_get8;
184 gpio->chip.direction_output = pcf857x_output8; 195 gpio->chip.direction_output = pcf857x_output8;
@@ -198,13 +209,7 @@ static int pcf857x_probe(struct i2c_client *client)
198 * 209 *
199 * NOTE: we don't distinguish here between '75 and '75c parts. 210 * NOTE: we don't distinguish here between '75 and '75c parts.
200 */ 211 */
201 } else if (strcmp(client->name, "pcf8575") == 0 212 } else if (gpio->chip.ngpio == 16) {
202 || strcmp(client->name, "pca8575") == 0
203 || strcmp(client->name, "pca9671") == 0
204 || strcmp(client->name, "pca9673") == 0
205 || strcmp(client->name, "pca9675") == 0
206 ) {
207 gpio->chip.ngpio = 16;
208 gpio->chip.direction_input = pcf857x_input16; 213 gpio->chip.direction_input = pcf857x_input16;
209 gpio->chip.get = pcf857x_get16; 214 gpio->chip.get = pcf857x_get16;
210 gpio->chip.direction_output = pcf857x_output16; 215 gpio->chip.direction_output = pcf857x_output16;
@@ -313,6 +318,7 @@ static struct i2c_driver pcf857x_driver = {
313 }, 318 },
314 .probe = pcf857x_probe, 319 .probe = pcf857x_probe,
315 .remove = pcf857x_remove, 320 .remove = pcf857x_remove,
321 .id_table = pcf857x_id,
316}; 322};
317 323
318static int __init pcf857x_init(void) 324static int __init pcf857x_init(void)
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 1464338e4e11..dc1f30e432ea 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -117,7 +117,8 @@ struct f75375_data {
117static int f75375_attach_adapter(struct i2c_adapter *adapter); 117static int f75375_attach_adapter(struct i2c_adapter *adapter);
118static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); 118static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
119static int f75375_detach_client(struct i2c_client *client); 119static int f75375_detach_client(struct i2c_client *client);
120static int f75375_probe(struct i2c_client *client); 120static int f75375_probe(struct i2c_client *client,
121 const struct i2c_device_id *id);
121static int f75375_remove(struct i2c_client *client); 122static int f75375_remove(struct i2c_client *client);
122 123
123static struct i2c_driver f75375_legacy_driver = { 124static struct i2c_driver f75375_legacy_driver = {
@@ -128,12 +129,20 @@ static struct i2c_driver f75375_legacy_driver = {
128 .detach_client = f75375_detach_client, 129 .detach_client = f75375_detach_client,
129}; 130};
130 131
132static const struct i2c_device_id f75375_id[] = {
133 { "f75373", f75373 },
134 { "f75375", f75375 },
135 { }
136};
137MODULE_DEVICE_TABLE(i2c, f75375_id);
138
131static struct i2c_driver f75375_driver = { 139static struct i2c_driver f75375_driver = {
132 .driver = { 140 .driver = {
133 .name = "f75375", 141 .name = "f75375",
134 }, 142 },
135 .probe = f75375_probe, 143 .probe = f75375_probe,
136 .remove = f75375_remove, 144 .remove = f75375_remove,
145 .id_table = f75375_id,
137}; 146};
138 147
139static inline int f75375_read8(struct i2c_client *client, u8 reg) 148static inline int f75375_read8(struct i2c_client *client, u8 reg)
@@ -628,7 +637,8 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
628 637
629} 638}
630 639
631static int f75375_probe(struct i2c_client *client) 640static int f75375_probe(struct i2c_client *client,
641 const struct i2c_device_id *id)
632{ 642{
633 struct f75375_data *data = i2c_get_clientdata(client); 643 struct f75375_data *data = i2c_get_clientdata(client);
634 struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data; 644 struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
@@ -643,15 +653,7 @@ static int f75375_probe(struct i2c_client *client)
643 i2c_set_clientdata(client, data); 653 i2c_set_clientdata(client, data);
644 data->client = client; 654 data->client = client;
645 mutex_init(&data->update_lock); 655 mutex_init(&data->update_lock);
646 656 data->kind = id->driver_data;
647 if (strcmp(client->name, "f75375") == 0)
648 data->kind = f75375;
649 else if (strcmp(client->name, "f75373") == 0)
650 data->kind = f75373;
651 else {
652 dev_err(&client->dev, "Unsupported device: %s\n", client->name);
653 return -ENODEV;
654 }
655 657
656 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) 658 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
657 goto exit_free; 659 goto exit_free;
@@ -712,6 +714,7 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
712 u8 version = 0; 714 u8 version = 0;
713 int err = 0; 715 int err = 0;
714 const char *name = ""; 716 const char *name = "";
717 struct i2c_device_id id;
715 718
716 if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) { 719 if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
717 err = -ENOMEM; 720 err = -ENOMEM;
@@ -748,7 +751,9 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
748 if ((err = i2c_attach_client(client))) 751 if ((err = i2c_attach_client(client)))
749 goto exit_free; 752 goto exit_free;
750 753
751 if ((err = f75375_probe(client)) < 0) 754 strlcpy(id.name, name, I2C_NAME_SIZE);
755 id.driver_data = kind;
756 if ((err = f75375_probe(client, &id)) < 0)
752 goto exit_detach; 757 goto exit_detach;
753 758
754 return 0; 759 return 0;
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index e5e96c817566..c38a0a112208 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * i2c-amd756-s4882.c - i2c-amd756 extras for the Tyan S4882 motherboard 2 * i2c-amd756-s4882.c - i2c-amd756 extras for the Tyan S4882 motherboard
3 * 3 *
4 * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2004, 2008 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -231,7 +231,8 @@ ERROR2:
231 kfree(s4882_adapter); 231 kfree(s4882_adapter);
232 s4882_adapter = NULL; 232 s4882_adapter = NULL;
233ERROR1: 233ERROR1:
234 i2c_del_adapter(&amd756_smbus); 234 /* Restore physical bus */
235 i2c_add_adapter(&amd756_smbus);
235ERROR0: 236ERROR0:
236 return error; 237 return error;
237} 238}
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 9bbe96cef719..fdc9ad805e35 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -38,7 +38,6 @@
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/apm_bios.h>
42#include <linux/dmi.h> 41#include <linux/dmi.h>
43#include <asm/io.h> 42#include <asm/io.h>
44 43
@@ -223,7 +222,7 @@ static int piix4_transaction(void)
223 dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp); 222 dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
224 return -1; 223 return -1;
225 } else { 224 } else {
226 dev_dbg(&piix4_adapter.dev, "Successfull!\n"); 225 dev_dbg(&piix4_adapter.dev, "Successful!\n");
227 } 226 }
228 } 227 }
229 228
@@ -343,12 +342,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
343 342
344 343
345 switch (size) { 344 switch (size) {
346 case PIIX4_BYTE: /* Where is the result put? I assume here it is in 345 case PIIX4_BYTE:
347 SMBHSTDAT0 but it might just as well be in the
348 SMBHSTCMD. No clue in the docs */
349
350 data->byte = inb_p(SMBHSTDAT0);
351 break;
352 case PIIX4_BYTE_DATA: 346 case PIIX4_BYTE_DATA:
353 data->byte = inb_p(SMBHSTDAT0); 347 data->byte = inb_p(SMBHSTDAT0);
354 break; 348 break;
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 283769cecee2..9ca8f9155f95 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -238,7 +238,7 @@ static int sis5595_transaction(struct i2c_adapter *adap)
238 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); 238 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
239 return -1; 239 return -1;
240 } else { 240 } else {
241 dev_dbg(&adap->dev, "Successfull!\n"); 241 dev_dbg(&adap->dev, "Successful!\n");
242 } 242 }
243 } 243 }
244 244
@@ -316,14 +316,8 @@ static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
316 } 316 }
317 size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA; 317 size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
318 break; 318 break;
319/*
320 case I2C_SMBUS_BLOCK_DATA:
321 printk(KERN_WARNING "sis5595.o: Block data not yet implemented!\n");
322 return -1;
323 break;
324*/
325 default: 319 default:
326 printk(KERN_WARNING "sis5595.o: Unsupported transaction %d\n", size); 320 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
327 return -1; 321 return -1;
328 } 322 }
329 323
@@ -338,9 +332,7 @@ static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
338 332
339 333
340 switch (size) { 334 switch (size) {
341 case SIS5595_BYTE: /* Where is the result put? I assume here it is in 335 case SIS5595_BYTE:
342 SMB_DATA but it might just as well be in the
343 SMB_CMD. No clue in the docs */
344 case SIS5595_BYTE_DATA: 336 case SIS5595_BYTE_DATA:
345 data->byte = sis5595_read(SMB_BYTE); 337 data->byte = sis5595_read(SMB_BYTE);
346 break; 338 break;
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 5fd734f99ee9..3765dd7f450f 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -136,7 +136,7 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc
136 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); 136 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
137 return -1; 137 return -1;
138 } else { 138 } else {
139 dev_dbg(&adap->dev, "Successfull!\n"); 139 dev_dbg(&adap->dev, "Successful!\n");
140 } 140 }
141 } 141 }
142 142
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c
index c2a9f8c94f5e..d08eeec53913 100644
--- a/drivers/i2c/busses/i2c-stub.c
+++ b/drivers/i2c/busses/i2c-stub.c
@@ -33,7 +33,7 @@
33static unsigned short chip_addr[MAX_CHIPS]; 33static unsigned short chip_addr[MAX_CHIPS];
34module_param_array(chip_addr, ushort, NULL, S_IRUGO); 34module_param_array(chip_addr, ushort, NULL, S_IRUGO);
35MODULE_PARM_DESC(chip_addr, 35MODULE_PARM_DESC(chip_addr,
36 "Chip addresses (up to 10, between 0x03 and 0x77)\n"); 36 "Chip addresses (up to 10, between 0x03 and 0x77)");
37 37
38struct stub_chip { 38struct stub_chip {
39 u8 pointer; 39 u8 pointer;
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
index 1b0cfd5472fd..de9db49e54d9 100644
--- a/drivers/i2c/busses/i2c-taos-evm.c
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -51,7 +51,6 @@ struct taos_data {
51/* TAOS TSL2550 EVM */ 51/* TAOS TSL2550 EVM */
52static struct i2c_board_info tsl2550_info = { 52static struct i2c_board_info tsl2550_info = {
53 I2C_BOARD_INFO("tsl2550", 0x39), 53 I2C_BOARD_INFO("tsl2550", 0x39),
54 .type = "tsl2550",
55}; 54};
56 55
57/* Instantiate i2c devices based on the adapter name */ 56/* Instantiate i2c devices based on the adapter name */
@@ -59,7 +58,7 @@ static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
59{ 58{
60 if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) { 59 if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
61 dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n", 60 dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
62 tsl2550_info.driver_name, tsl2550_info.addr); 61 tsl2550_info.type, tsl2550_info.addr);
63 return i2c_new_device(adapter, &tsl2550_info); 62 return i2c_new_device(adapter, &tsl2550_info);
64 } 63 }
65 64
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 9e94542c18a2..23be4d42cb02 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eeprom_attr = {
200/* 200/*
201 * Called when a ds1682 device is matched with this driver 201 * Called when a ds1682 device is matched with this driver
202 */ 202 */
203static int ds1682_probe(struct i2c_client *client) 203static int ds1682_probe(struct i2c_client *client,
204 const struct i2c_device_id *id)
204{ 205{
205 int rc; 206 int rc;
206 207
@@ -234,12 +235,19 @@ static int ds1682_remove(struct i2c_client *client)
234 return 0; 235 return 0;
235} 236}
236 237
238static const struct i2c_device_id ds1682_id[] = {
239 { "ds1682", 0 },
240 { }
241};
242MODULE_DEVICE_TABLE(i2c, ds1682_id);
243
237static struct i2c_driver ds1682_driver = { 244static struct i2c_driver ds1682_driver = {
238 .driver = { 245 .driver = {
239 .name = "ds1682", 246 .name = "ds1682",
240 }, 247 },
241 .probe = ds1682_probe, 248 .probe = ds1682_probe,
242 .remove = ds1682_remove, 249 .remove = ds1682_remove,
250 .id_table = ds1682_id,
243}; 251};
244 252
245static int __init ds1682_init(void) 253static int __init ds1682_init(void)
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 2dea0123a958..b36db1797c11 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
1149 1149
1150static struct i2c_driver menelaus_i2c_driver; 1150static struct i2c_driver menelaus_i2c_driver;
1151 1151
1152static int menelaus_probe(struct i2c_client *client) 1152static int menelaus_probe(struct i2c_client *client,
1153 const struct i2c_device_id *id)
1153{ 1154{
1154 struct menelaus_chip *menelaus; 1155 struct menelaus_chip *menelaus;
1155 int rev = 0, val; 1156 int rev = 0, val;
@@ -1242,12 +1243,19 @@ static int __exit menelaus_remove(struct i2c_client *client)
1242 return 0; 1243 return 0;
1243} 1244}
1244 1245
1246static const struct i2c_device_id menelaus_id[] = {
1247 { "menelaus", 0 },
1248 { }
1249};
1250MODULE_DEVICE_TABLE(i2c, menelaus_id);
1251
1245static struct i2c_driver menelaus_i2c_driver = { 1252static struct i2c_driver menelaus_i2c_driver = {
1246 .driver = { 1253 .driver = {
1247 .name = DRIVER_NAME, 1254 .name = DRIVER_NAME,
1248 }, 1255 },
1249 .probe = menelaus_probe, 1256 .probe = menelaus_probe,
1250 .remove = __exit_p(menelaus_remove), 1257 .remove = __exit_p(menelaus_remove),
1258 .id_table = menelaus_id,
1251}; 1259};
1252 1260
1253static int __init menelaus_init(void) 1261static int __init menelaus_init(void)
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index b67f69c2e7f3..85949685191b 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -64,7 +64,6 @@ static struct i2c_driver tps65010_driver;
64 * as part of board setup by a bootloader. 64 * as part of board setup by a bootloader.
65 */ 65 */
66enum tps_model { 66enum tps_model {
67 TPS_UNKNOWN = 0,
68 TPS65010, 67 TPS65010,
69 TPS65011, 68 TPS65011,
70 TPS65012, 69 TPS65012,
@@ -527,11 +526,13 @@ static int __exit tps65010_remove(struct i2c_client *client)
527 flush_scheduled_work(); 526 flush_scheduled_work();
528 debugfs_remove(tps->file); 527 debugfs_remove(tps->file);
529 kfree(tps); 528 kfree(tps);
529 i2c_set_clientdata(client, NULL);
530 the_tps = NULL; 530 the_tps = NULL;
531 return 0; 531 return 0;
532} 532}
533 533
534static int tps65010_probe(struct i2c_client *client) 534static int tps65010_probe(struct i2c_client *client,
535 const struct i2c_device_id *id)
535{ 536{
536 struct tps65010 *tps; 537 struct tps65010 *tps;
537 int status; 538 int status;
@@ -552,20 +553,7 @@ static int tps65010_probe(struct i2c_client *client)
552 mutex_init(&tps->lock); 553 mutex_init(&tps->lock);
553 INIT_DELAYED_WORK(&tps->work, tps65010_work); 554 INIT_DELAYED_WORK(&tps->work, tps65010_work);
554 tps->client = client; 555 tps->client = client;
555 556 tps->model = id->driver_data;
556 if (strcmp(client->name, "tps65010") == 0)
557 tps->model = TPS65010;
558 else if (strcmp(client->name, "tps65011") == 0)
559 tps->model = TPS65011;
560 else if (strcmp(client->name, "tps65012") == 0)
561 tps->model = TPS65012;
562 else if (strcmp(client->name, "tps65013") == 0)
563 tps->model = TPS65013;
564 else {
565 dev_warn(&client->dev, "unknown chip '%s'\n", client->name);
566 status = -ENODEV;
567 goto fail1;
568 }
569 557
570 /* the IRQ is active low, but many gpio lines can't support that 558 /* the IRQ is active low, but many gpio lines can't support that
571 * so this driver uses falling-edge triggers instead. 559 * so this driver uses falling-edge triggers instead.
@@ -594,9 +582,6 @@ static int tps65010_probe(struct i2c_client *client)
594 case TPS65012: 582 case TPS65012:
595 tps->por = 1; 583 tps->por = 1;
596 break; 584 break;
597 case TPS_UNKNOWN:
598 printk(KERN_WARNING "%s: unknown TPS chip\n", DRIVER_NAME);
599 break;
600 /* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */ 585 /* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
601 } 586 }
602 tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG); 587 tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG);
@@ -615,6 +600,7 @@ static int tps65010_probe(struct i2c_client *client)
615 i2c_smbus_read_byte_data(client, TPS_DEFGPIO), 600 i2c_smbus_read_byte_data(client, TPS_DEFGPIO),
616 i2c_smbus_read_byte_data(client, TPS_MASK3)); 601 i2c_smbus_read_byte_data(client, TPS_MASK3));
617 602
603 i2c_set_clientdata(client, tps);
618 the_tps = tps; 604 the_tps = tps;
619 605
620#if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG) 606#if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG)
@@ -682,12 +668,22 @@ fail1:
682 return status; 668 return status;
683} 669}
684 670
671static const struct i2c_device_id tps65010_id[] = {
672 { "tps65010", TPS65010 },
673 { "tps65011", TPS65011 },
674 { "tps65012", TPS65012 },
675 { "tps65013", TPS65013 },
676 { }
677};
678MODULE_DEVICE_TABLE(i2c, tps65010_id);
679
685static struct i2c_driver tps65010_driver = { 680static struct i2c_driver tps65010_driver = {
686 .driver = { 681 .driver = {
687 .name = "tps65010", 682 .name = "tps65010",
688 }, 683 },
689 .probe = tps65010_probe, 684 .probe = tps65010_probe,
690 .remove = __exit_p(tps65010_remove), 685 .remove = __exit_p(tps65010_remove),
686 .id_table = tps65010_id,
691}; 687};
692 688
693/*-------------------------------------------------------------------------*/ 689/*-------------------------------------------------------------------------*/
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index a10fd2791a69..1a9cc135219f 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2c_client *client)
364 */ 364 */
365 365
366static struct i2c_driver tsl2550_driver; 366static struct i2c_driver tsl2550_driver;
367static int __devinit tsl2550_probe(struct i2c_client *client) 367static int __devinit tsl2550_probe(struct i2c_client *client,
368 const struct i2c_device_id *id)
368{ 369{
369 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 370 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
370 struct tsl2550_data *data; 371 struct tsl2550_data *data;
@@ -451,6 +452,12 @@ static int tsl2550_resume(struct i2c_client *client)
451 452
452#endif /* CONFIG_PM */ 453#endif /* CONFIG_PM */
453 454
455static const struct i2c_device_id tsl2550_id[] = {
456 { "tsl2550", 0 },
457 { }
458};
459MODULE_DEVICE_TABLE(i2c, tsl2550_id);
460
454static struct i2c_driver tsl2550_driver = { 461static struct i2c_driver tsl2550_driver = {
455 .driver = { 462 .driver = {
456 .name = TSL2550_DRV_NAME, 463 .name = TSL2550_DRV_NAME,
@@ -460,6 +467,7 @@ static struct i2c_driver tsl2550_driver = {
460 .resume = tsl2550_resume, 467 .resume = tsl2550_resume,
461 .probe = tsl2550_probe, 468 .probe = tsl2550_probe,
462 .remove = __devexit_p(tsl2550_remove), 469 .remove = __devexit_p(tsl2550_remove),
470 .id_table = tsl2550_id,
463}; 471};
464 472
465static int __init tsl2550_init(void) 473static int __init tsl2550_init(void)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 6c7fa8d53c0e..26384daccb96 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr);
48 48
49/* ------------------------------------------------------------------------- */ 49/* ------------------------------------------------------------------------- */
50 50
51static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
52 const struct i2c_client *client)
53{
54 while (id->name[0]) {
55 if (strcmp(client->name, id->name) == 0)
56 return id;
57 id++;
58 }
59 return NULL;
60}
61
51static int i2c_device_match(struct device *dev, struct device_driver *drv) 62static int i2c_device_match(struct device *dev, struct device_driver *drv)
52{ 63{
53 struct i2c_client *client = to_i2c_client(dev); 64 struct i2c_client *client = to_i2c_client(dev);
@@ -59,6 +70,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
59 if (!is_newstyle_driver(driver)) 70 if (!is_newstyle_driver(driver))
60 return 0; 71 return 0;
61 72
73 /* match on an id table if there is one */
74 if (driver->id_table)
75 return i2c_match_id(driver->id_table, client) != NULL;
76
62 /* new style drivers use the same kind of driver matching policy 77 /* new style drivers use the same kind of driver matching policy
63 * as platform devices or SPI: compare device and driver IDs. 78 * as platform devices or SPI: compare device and driver IDs.
64 */ 79 */
@@ -73,11 +88,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
73 struct i2c_client *client = to_i2c_client(dev); 88 struct i2c_client *client = to_i2c_client(dev);
74 89
75 /* by definition, legacy drivers can't hotplug */ 90 /* by definition, legacy drivers can't hotplug */
76 if (dev->driver || !client->driver_name) 91 if (dev->driver)
77 return 0; 92 return 0;
78 93
79 if (add_uevent_var(env, "MODALIAS=%s", client->driver_name)) 94 if (client->driver_name[0]) {
80 return -ENOMEM; 95 if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
96 return -ENOMEM;
97 } else {
98 if (add_uevent_var(env, "MODALIAS=%s%s",
99 I2C_MODULE_PREFIX, client->name))
100 return -ENOMEM;
101 }
81 dev_dbg(dev, "uevent\n"); 102 dev_dbg(dev, "uevent\n");
82 return 0; 103 return 0;
83} 104}
@@ -90,13 +111,19 @@ static int i2c_device_probe(struct device *dev)
90{ 111{
91 struct i2c_client *client = to_i2c_client(dev); 112 struct i2c_client *client = to_i2c_client(dev);
92 struct i2c_driver *driver = to_i2c_driver(dev->driver); 113 struct i2c_driver *driver = to_i2c_driver(dev->driver);
114 const struct i2c_device_id *id;
93 int status; 115 int status;
94 116
95 if (!driver->probe) 117 if (!driver->probe)
96 return -ENODEV; 118 return -ENODEV;
97 client->driver = driver; 119 client->driver = driver;
98 dev_dbg(dev, "probe\n"); 120 dev_dbg(dev, "probe\n");
99 status = driver->probe(client); 121
122 if (driver->id_table)
123 id = i2c_match_id(driver->id_table, client);
124 else
125 id = NULL;
126 status = driver->probe(client, id);
100 if (status) 127 if (status)
101 client->driver = NULL; 128 client->driver = NULL;
102 return status; 129 return status;
@@ -179,9 +206,9 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att
179static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) 206static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
180{ 207{
181 struct i2c_client *client = to_i2c_client(dev); 208 struct i2c_client *client = to_i2c_client(dev);
182 return client->driver_name 209 return client->driver_name[0]
183 ? sprintf(buf, "%s\n", client->driver_name) 210 ? sprintf(buf, "%s\n", client->driver_name)
184 : 0; 211 : sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
185} 212}
186 213
187static struct device_attribute i2c_dev_attrs[] = { 214static struct device_attribute i2c_dev_attrs[] = {
@@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_client *client)
300EXPORT_SYMBOL_GPL(i2c_unregister_device); 327EXPORT_SYMBOL_GPL(i2c_unregister_device);
301 328
302 329
303static int dummy_nop(struct i2c_client *client) 330static int dummy_probe(struct i2c_client *client,
331 const struct i2c_device_id *id)
332{
333 return 0;
334}
335
336static int dummy_remove(struct i2c_client *client)
304{ 337{
305 return 0; 338 return 0;
306} 339}
307 340
308static struct i2c_driver dummy_driver = { 341static struct i2c_driver dummy_driver = {
309 .driver.name = "dummy", 342 .driver.name = "dummy",
310 .probe = dummy_nop, 343 .probe = dummy_probe,
311 .remove = dummy_nop, 344 .remove = dummy_remove,
312}; 345};
313 346
314/** 347/**
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index b36a22b8c213..c1922f9cfe80 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -412,14 +412,14 @@ static u8 __devinit ali_cable_detect(ide_hwif_t *hwif)
412 return cbl; 412 return cbl;
413} 413}
414 414
415#ifndef CONFIG_SPARC64 415#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC)
416/** 416/**
417 * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff 417 * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
418 * @hwif: interface to configure 418 * @hwif: interface to configure
419 * 419 *
420 * Obtain the IRQ tables for an ALi based IDE solution on the PC 420 * Obtain the IRQ tables for an ALi based IDE solution on the PC
421 * class platforms. This part of the code isn't applicable to the 421 * class platforms. This part of the code isn't applicable to the
422 * Sparc systems 422 * Sparc and PowerPC systems.
423 */ 423 */
424 424
425static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) 425static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
@@ -463,7 +463,9 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
463 hwif->irq = irq; 463 hwif->irq = irq;
464 } 464 }
465} 465}
466#endif 466#else
467#define init_hwif_ali15x3 NULL
468#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */
467 469
468/** 470/**
469 * init_dma_ali15x3 - set up DMA on ALi15x3 471 * init_dma_ali15x3 - set up DMA on ALi15x3
@@ -517,9 +519,7 @@ static const struct ide_dma_ops ali_dma_ops = {
517static const struct ide_port_info ali15x3_chipset __devinitdata = { 519static const struct ide_port_info ali15x3_chipset __devinitdata = {
518 .name = "ALI15X3", 520 .name = "ALI15X3",
519 .init_chipset = init_chipset_ali15x3, 521 .init_chipset = init_chipset_ali15x3,
520#ifndef CONFIG_SPARC64
521 .init_hwif = init_hwif_ali15x3, 522 .init_hwif = init_hwif_ali15x3,
522#endif
523 .init_dma = init_dma_ali15x3, 523 .init_dma = init_dma_ali15x3,
524 .port_ops = &ali_port_ops, 524 .port_ops = &ali_port_ops,
525 .pio_mask = ATA_PIO5, 525 .pio_mask = ATA_PIO5,
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 4cf8fc54aa2a..0006b9e58567 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -737,8 +737,15 @@ static const struct ide_port_ops sil_sata_port_ops = {
737 .cable_detect = sil_cable_detect, 737 .cable_detect = sil_cable_detect,
738}; 738};
739 739
740static struct ide_dma_ops sil_dma_ops = { 740static const struct ide_dma_ops sil_dma_ops = {
741 .dma_host_set = ide_dma_host_set,
742 .dma_setup = ide_dma_setup,
743 .dma_exec_cmd = ide_dma_exec_cmd,
744 .dma_start = ide_dma_start,
745 .dma_end = __ide_dma_end,
741 .dma_test_irq = siimage_dma_test_irq, 746 .dma_test_irq = siimage_dma_test_irq,
747 .dma_timeout = ide_dma_timeout,
748 .dma_lost_irq = ide_dma_lost_irq,
742}; 749};
743 750
744#define DECLARE_SII_DEV(name_str, p_ops) \ 751#define DECLARE_SII_DEV(name_str, p_ops) \
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 66eb7030aea8..ed2ee4ba4b7c 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -456,7 +456,8 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count)
456 ptr = cq->sw_rptr; 456 ptr = cq->sw_rptr;
457 while (!Q_EMPTY(ptr, cq->sw_wptr)) { 457 while (!Q_EMPTY(ptr, cq->sw_wptr)) {
458 cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2)); 458 cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2));
459 if ((SQ_TYPE(*cqe) || (CQE_OPCODE(*cqe) == T3_READ_RESP)) && 459 if ((SQ_TYPE(*cqe) ||
460 ((CQE_OPCODE(*cqe) == T3_READ_RESP) && wq->oldest_read)) &&
460 (CQE_QPID(*cqe) == wq->qpid)) 461 (CQE_QPID(*cqe) == wq->qpid))
461 (*count)++; 462 (*count)++;
462 ptr++; 463 ptr++;
@@ -829,7 +830,8 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
829 wqe->mpaattrs = attr->mpaattrs; 830 wqe->mpaattrs = attr->mpaattrs;
830 wqe->qpcaps = attr->qpcaps; 831 wqe->qpcaps = attr->qpcaps;
831 wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss); 832 wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss);
832 wqe->flags = cpu_to_be32(attr->flags); 833 wqe->rqe_count = cpu_to_be16(attr->rqe_count);
834 wqe->flags_rtr_type = cpu_to_be16(attr->flags|V_RTR_TYPE(attr->rtr_type));
833 wqe->ord = cpu_to_be32(attr->ord); 835 wqe->ord = cpu_to_be32(attr->ord);
834 wqe->ird = cpu_to_be32(attr->ird); 836 wqe->ird = cpu_to_be32(attr->ird);
835 wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr); 837 wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr);
@@ -1135,6 +1137,18 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
1135 if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) { 1137 if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) {
1136 1138
1137 /* 1139 /*
1140 * If this is an unsolicited read response, then the read
1141 * was generated by the kernel driver as part of peer-2-peer
1142 * connection setup. So ignore the completion.
1143 */
1144 if (!wq->oldest_read) {
1145 if (CQE_STATUS(*hw_cqe))
1146 wq->error = 1;
1147 ret = -1;
1148 goto skip_cqe;
1149 }
1150
1151 /*
1138 * Don't write to the HWCQ, so create a new read req CQE 1152 * Don't write to the HWCQ, so create a new read req CQE
1139 * in local memory. 1153 * in local memory.
1140 */ 1154 */
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 99543d634704..2bcff7f5046e 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -53,6 +53,7 @@
53#define T3_MAX_PBL_SIZE 256 53#define T3_MAX_PBL_SIZE 256
54#define T3_MAX_RQ_SIZE 1024 54#define T3_MAX_RQ_SIZE 1024
55#define T3_MAX_NUM_STAG (1<<15) 55#define T3_MAX_NUM_STAG (1<<15)
56#define T3_MAX_MR_SIZE 0x100000000ULL
56 57
57#define T3_STAG_UNSET 0xffffffff 58#define T3_STAG_UNSET 0xffffffff
58 59
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 969d4d928455..f1a25a821a45 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -278,6 +278,17 @@ enum t3_qp_caps {
278 uP_RI_QP_STAG0_ENABLE = 0x10 278 uP_RI_QP_STAG0_ENABLE = 0x10
279} __attribute__ ((packed)); 279} __attribute__ ((packed));
280 280
281enum rdma_init_rtr_types {
282 RTR_READ = 1,
283 RTR_WRITE = 2,
284 RTR_SEND = 3,
285};
286
287#define S_RTR_TYPE 2
288#define M_RTR_TYPE 0x3
289#define V_RTR_TYPE(x) ((x) << S_RTR_TYPE)
290#define G_RTR_TYPE(x) ((((x) >> S_RTR_TYPE)) & M_RTR_TYPE)
291
281struct t3_rdma_init_attr { 292struct t3_rdma_init_attr {
282 u32 tid; 293 u32 tid;
283 u32 qpid; 294 u32 qpid;
@@ -293,7 +304,9 @@ struct t3_rdma_init_attr {
293 u32 ird; 304 u32 ird;
294 u64 qp_dma_addr; 305 u64 qp_dma_addr;
295 u32 qp_dma_size; 306 u32 qp_dma_size;
296 u32 flags; 307 enum rdma_init_rtr_types rtr_type;
308 u16 flags;
309 u16 rqe_count;
297 u32 irs; 310 u32 irs;
298}; 311};
299 312
@@ -309,8 +322,8 @@ struct t3_rdma_init_wr {
309 u8 mpaattrs; /* 5 */ 322 u8 mpaattrs; /* 5 */
310 u8 qpcaps; 323 u8 qpcaps;
311 __be16 ulpdu_size; 324 __be16 ulpdu_size;
312 __be32 flags; /* bits 31-1 - reservered */ 325 __be16 flags_rtr_type;
313 /* bit 0 - set if RECV posted */ 326 __be16 rqe_count;
314 __be32 ord; /* 6 */ 327 __be32 ord; /* 6 */
315 __be32 ird; 328 __be32 ird;
316 __be64 qp_dma_addr; /* 7 */ 329 __be64 qp_dma_addr; /* 7 */
@@ -324,7 +337,7 @@ struct t3_genbit {
324}; 337};
325 338
326enum rdma_init_wr_flags { 339enum rdma_init_wr_flags {
327 RECVS_POSTED = (1<<0), 340 MPA_INITIATOR = (1<<0),
328 PRIV_QP = (1<<1), 341 PRIV_QP = (1<<1),
329}; 342};
330 343
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 6ba4138c8ec3..71554eacb13c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -83,6 +83,7 @@ static void rnic_init(struct iwch_dev *rnicp)
83 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; 83 rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
84 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; 84 rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
85 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ 85 rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */
86 rnicp->attr.max_mr_size = T3_MAX_MR_SIZE;
86 rnicp->attr.can_resize_wq = 0; 87 rnicp->attr.can_resize_wq = 0;
87 rnicp->attr.max_rdma_reads_per_qp = 8; 88 rnicp->attr.max_rdma_reads_per_qp = 8;
88 rnicp->attr.max_rdma_read_resources = 89 rnicp->attr.max_rdma_read_resources =
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 9ad9b1e7c8c1..d2409a505e8d 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -66,6 +66,7 @@ struct iwch_rnic_attributes {
66 * size (4k)^i. Phys block list mode unsupported. 66 * size (4k)^i. Phys block list mode unsupported.
67 */ 67 */
68 u32 mem_pgsizes_bitmask; 68 u32 mem_pgsizes_bitmask;
69 u64 max_mr_size;
69 u8 can_resize_wq; 70 u8 can_resize_wq;
70 71
71 /* 72 /*
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 72ca360c3dbc..d44a6df9ad8c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -63,6 +63,10 @@ static char *states[] = {
63 NULL, 63 NULL,
64}; 64};
65 65
66int peer2peer = 0;
67module_param(peer2peer, int, 0644);
68MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)");
69
66static int ep_timeout_secs = 10; 70static int ep_timeout_secs = 10;
67module_param(ep_timeout_secs, int, 0644); 71module_param(ep_timeout_secs, int, 0644);
68MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " 72MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "
@@ -125,6 +129,12 @@ static void start_ep_timer(struct iwch_ep *ep)
125static void stop_ep_timer(struct iwch_ep *ep) 129static void stop_ep_timer(struct iwch_ep *ep)
126{ 130{
127 PDBG("%s ep %p\n", __func__, ep); 131 PDBG("%s ep %p\n", __func__, ep);
132 if (!timer_pending(&ep->timer)) {
133 printk(KERN_ERR "%s timer stopped when its not running! ep %p state %u\n",
134 __func__, ep, ep->com.state);
135 WARN_ON(1);
136 return;
137 }
128 del_timer_sync(&ep->timer); 138 del_timer_sync(&ep->timer);
129 put_ep(&ep->com); 139 put_ep(&ep->com);
130} 140}
@@ -508,7 +518,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
508 skb_reset_transport_header(skb); 518 skb_reset_transport_header(skb);
509 len = skb->len; 519 len = skb->len;
510 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); 520 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req));
511 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); 521 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL);
512 req->wr_lo = htonl(V_WR_TID(ep->hwtid)); 522 req->wr_lo = htonl(V_WR_TID(ep->hwtid));
513 req->len = htonl(len); 523 req->len = htonl(len);
514 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | 524 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
@@ -559,7 +569,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
559 set_arp_failure_handler(skb, arp_failure_discard); 569 set_arp_failure_handler(skb, arp_failure_discard);
560 skb_reset_transport_header(skb); 570 skb_reset_transport_header(skb);
561 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); 571 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req));
562 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); 572 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL);
563 req->wr_lo = htonl(V_WR_TID(ep->hwtid)); 573 req->wr_lo = htonl(V_WR_TID(ep->hwtid));
564 req->len = htonl(mpalen); 574 req->len = htonl(mpalen);
565 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | 575 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
@@ -611,7 +621,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
611 skb_reset_transport_header(skb); 621 skb_reset_transport_header(skb);
612 len = skb->len; 622 len = skb->len;
613 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); 623 req = (struct tx_data_wr *) skb_push(skb, sizeof(*req));
614 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); 624 req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL);
615 req->wr_lo = htonl(V_WR_TID(ep->hwtid)); 625 req->wr_lo = htonl(V_WR_TID(ep->hwtid));
616 req->len = htonl(len); 626 req->len = htonl(len);
617 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | 627 req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
@@ -879,6 +889,7 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb)
879 * the MPA header is valid. 889 * the MPA header is valid.
880 */ 890 */
881 state_set(&ep->com, FPDU_MODE); 891 state_set(&ep->com, FPDU_MODE);
892 ep->mpa_attr.initiator = 1;
882 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; 893 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
883 ep->mpa_attr.recv_marker_enabled = markers_enabled; 894 ep->mpa_attr.recv_marker_enabled = markers_enabled;
884 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; 895 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
@@ -901,8 +912,14 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb)
901 /* bind QP and TID with INIT_WR */ 912 /* bind QP and TID with INIT_WR */
902 err = iwch_modify_qp(ep->com.qp->rhp, 913 err = iwch_modify_qp(ep->com.qp->rhp,
903 ep->com.qp, mask, &attrs, 1); 914 ep->com.qp, mask, &attrs, 1);
904 if (!err) 915 if (err)
905 goto out; 916 goto err;
917
918 if (peer2peer && iwch_rqes_posted(ep->com.qp) == 0) {
919 iwch_post_zb_read(ep->com.qp);
920 }
921
922 goto out;
906err: 923err:
907 abort_connection(ep, skb, GFP_KERNEL); 924 abort_connection(ep, skb, GFP_KERNEL);
908out: 925out:
@@ -995,6 +1012,7 @@ static void process_mpa_request(struct iwch_ep *ep, struct sk_buff *skb)
995 * If we get here we have accumulated the entire mpa 1012 * If we get here we have accumulated the entire mpa
996 * start reply message including private data. 1013 * start reply message including private data.
997 */ 1014 */
1015 ep->mpa_attr.initiator = 0;
998 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; 1016 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
999 ep->mpa_attr.recv_marker_enabled = markers_enabled; 1017 ep->mpa_attr.recv_marker_enabled = markers_enabled;
1000 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; 1018 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
@@ -1065,17 +1083,33 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1065 1083
1066 PDBG("%s ep %p credits %u\n", __func__, ep, credits); 1084 PDBG("%s ep %p credits %u\n", __func__, ep, credits);
1067 1085
1068 if (credits == 0) 1086 if (credits == 0) {
1087 PDBG(KERN_ERR "%s 0 credit ack ep %p state %u\n",
1088 __func__, ep, state_read(&ep->com));
1069 return CPL_RET_BUF_DONE; 1089 return CPL_RET_BUF_DONE;
1090 }
1091
1070 BUG_ON(credits != 1); 1092 BUG_ON(credits != 1);
1071 BUG_ON(ep->mpa_skb == NULL);
1072 kfree_skb(ep->mpa_skb);
1073 ep->mpa_skb = NULL;
1074 dst_confirm(ep->dst); 1093 dst_confirm(ep->dst);
1075 if (state_read(&ep->com) == MPA_REP_SENT) { 1094 if (!ep->mpa_skb) {
1076 ep->com.rpl_done = 1; 1095 PDBG("%s rdma_init wr_ack ep %p state %u\n",
1077 PDBG("waking up ep %p\n", ep); 1096 __func__, ep, state_read(&ep->com));
1078 wake_up(&ep->com.waitq); 1097 if (ep->mpa_attr.initiator) {
1098 PDBG("%s initiator ep %p state %u\n",
1099 __func__, ep, state_read(&ep->com));
1100 if (peer2peer)
1101 iwch_post_zb_read(ep->com.qp);
1102 } else {
1103 PDBG("%s responder ep %p state %u\n",
1104 __func__, ep, state_read(&ep->com));
1105 ep->com.rpl_done = 1;
1106 wake_up(&ep->com.waitq);
1107 }
1108 } else {
1109 PDBG("%s lsm ack ep %p state %u freeing skb\n",
1110 __func__, ep, state_read(&ep->com));
1111 kfree_skb(ep->mpa_skb);
1112 ep->mpa_skb = NULL;
1079 } 1113 }
1080 return CPL_RET_BUF_DONE; 1114 return CPL_RET_BUF_DONE;
1081} 1115}
@@ -1083,8 +1117,11 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1083static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) 1117static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1084{ 1118{
1085 struct iwch_ep *ep = ctx; 1119 struct iwch_ep *ep = ctx;
1120 unsigned long flags;
1121 int release = 0;
1086 1122
1087 PDBG("%s ep %p\n", __func__, ep); 1123 PDBG("%s ep %p\n", __func__, ep);
1124 BUG_ON(!ep);
1088 1125
1089 /* 1126 /*
1090 * We get 2 abort replies from the HW. The first one must 1127 * We get 2 abort replies from the HW. The first one must
@@ -1095,9 +1132,22 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1095 return CPL_RET_BUF_DONE; 1132 return CPL_RET_BUF_DONE;
1096 } 1133 }
1097 1134
1098 close_complete_upcall(ep); 1135 spin_lock_irqsave(&ep->com.lock, flags);
1099 state_set(&ep->com, DEAD); 1136 switch (ep->com.state) {
1100 release_ep_resources(ep); 1137 case ABORTING:
1138 close_complete_upcall(ep);
1139 __state_set(&ep->com, DEAD);
1140 release = 1;
1141 break;
1142 default:
1143 printk(KERN_ERR "%s ep %p state %d\n",
1144 __func__, ep, ep->com.state);
1145 break;
1146 }
1147 spin_unlock_irqrestore(&ep->com.lock, flags);
1148
1149 if (release)
1150 release_ep_resources(ep);
1101 return CPL_RET_BUF_DONE; 1151 return CPL_RET_BUF_DONE;
1102} 1152}
1103 1153
@@ -1470,7 +1520,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1470 struct sk_buff *rpl_skb; 1520 struct sk_buff *rpl_skb;
1471 struct iwch_qp_attributes attrs; 1521 struct iwch_qp_attributes attrs;
1472 int ret; 1522 int ret;
1473 int state; 1523 int release = 0;
1524 unsigned long flags;
1474 1525
1475 if (is_neg_adv_abort(req->status)) { 1526 if (is_neg_adv_abort(req->status)) {
1476 PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, 1527 PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep,
@@ -1488,9 +1539,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1488 return CPL_RET_BUF_DONE; 1539 return CPL_RET_BUF_DONE;
1489 } 1540 }
1490 1541
1491 state = state_read(&ep->com); 1542 spin_lock_irqsave(&ep->com.lock, flags);
1492 PDBG("%s ep %p state %u\n", __func__, ep, state); 1543 PDBG("%s ep %p state %u\n", __func__, ep, ep->com.state);
1493 switch (state) { 1544 switch (ep->com.state) {
1494 case CONNECTING: 1545 case CONNECTING:
1495 break; 1546 break;
1496 case MPA_REQ_WAIT: 1547 case MPA_REQ_WAIT:
@@ -1536,21 +1587,25 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1536 break; 1587 break;
1537 case DEAD: 1588 case DEAD:
1538 PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); 1589 PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__);
1590 spin_unlock_irqrestore(&ep->com.lock, flags);
1539 return CPL_RET_BUF_DONE; 1591 return CPL_RET_BUF_DONE;
1540 default: 1592 default:
1541 BUG_ON(1); 1593 BUG_ON(1);
1542 break; 1594 break;
1543 } 1595 }
1544 dst_confirm(ep->dst); 1596 dst_confirm(ep->dst);
1597 if (ep->com.state != ABORTING) {
1598 __state_set(&ep->com, DEAD);
1599 release = 1;
1600 }
1601 spin_unlock_irqrestore(&ep->com.lock, flags);
1545 1602
1546 rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); 1603 rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL);
1547 if (!rpl_skb) { 1604 if (!rpl_skb) {
1548 printk(KERN_ERR MOD "%s - cannot allocate skb!\n", 1605 printk(KERN_ERR MOD "%s - cannot allocate skb!\n",
1549 __func__); 1606 __func__);
1550 dst_release(ep->dst); 1607 release = 1;
1551 l2t_release(L2DATA(ep->com.tdev), ep->l2t); 1608 goto out;
1552 put_ep(&ep->com);
1553 return CPL_RET_BUF_DONE;
1554 } 1609 }
1555 rpl_skb->priority = CPL_PRIORITY_DATA; 1610 rpl_skb->priority = CPL_PRIORITY_DATA;
1556 rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); 1611 rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl));
@@ -1559,10 +1614,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1559 OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); 1614 OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
1560 rpl->cmd = CPL_ABORT_NO_RST; 1615 rpl->cmd = CPL_ABORT_NO_RST;
1561 cxgb3_ofld_send(ep->com.tdev, rpl_skb); 1616 cxgb3_ofld_send(ep->com.tdev, rpl_skb);
1562 if (state != ABORTING) { 1617out:
1563 state_set(&ep->com, DEAD); 1618 if (release)
1564 release_ep_resources(ep); 1619 release_ep_resources(ep);
1565 }
1566 return CPL_RET_BUF_DONE; 1620 return CPL_RET_BUF_DONE;
1567} 1621}
1568 1622
@@ -1661,15 +1715,18 @@ static void ep_timeout(unsigned long arg)
1661 struct iwch_ep *ep = (struct iwch_ep *)arg; 1715 struct iwch_ep *ep = (struct iwch_ep *)arg;
1662 struct iwch_qp_attributes attrs; 1716 struct iwch_qp_attributes attrs;
1663 unsigned long flags; 1717 unsigned long flags;
1718 int abort = 1;
1664 1719
1665 spin_lock_irqsave(&ep->com.lock, flags); 1720 spin_lock_irqsave(&ep->com.lock, flags);
1666 PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, 1721 PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid,
1667 ep->com.state); 1722 ep->com.state);
1668 switch (ep->com.state) { 1723 switch (ep->com.state) {
1669 case MPA_REQ_SENT: 1724 case MPA_REQ_SENT:
1725 __state_set(&ep->com, ABORTING);
1670 connect_reply_upcall(ep, -ETIMEDOUT); 1726 connect_reply_upcall(ep, -ETIMEDOUT);
1671 break; 1727 break;
1672 case MPA_REQ_WAIT: 1728 case MPA_REQ_WAIT:
1729 __state_set(&ep->com, ABORTING);
1673 break; 1730 break;
1674 case CLOSING: 1731 case CLOSING:
1675 case MORIBUND: 1732 case MORIBUND:
@@ -1679,13 +1736,17 @@ static void ep_timeout(unsigned long arg)
1679 ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, 1736 ep->com.qp, IWCH_QP_ATTR_NEXT_STATE,
1680 &attrs, 1); 1737 &attrs, 1);
1681 } 1738 }
1739 __state_set(&ep->com, ABORTING);
1682 break; 1740 break;
1683 default: 1741 default:
1684 BUG(); 1742 printk(KERN_ERR "%s unexpected state ep %p state %u\n",
1743 __func__, ep, ep->com.state);
1744 WARN_ON(1);
1745 abort = 0;
1685 } 1746 }
1686 __state_set(&ep->com, CLOSING);
1687 spin_unlock_irqrestore(&ep->com.lock, flags); 1747 spin_unlock_irqrestore(&ep->com.lock, flags);
1688 abort_connection(ep, NULL, GFP_ATOMIC); 1748 if (abort)
1749 abort_connection(ep, NULL, GFP_ATOMIC);
1689 put_ep(&ep->com); 1750 put_ep(&ep->com);
1690} 1751}
1691 1752
@@ -1762,16 +1823,19 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
1762 if (err) 1823 if (err)
1763 goto err; 1824 goto err;
1764 1825
1826 /* if needed, wait for wr_ack */
1827 if (iwch_rqes_posted(qp)) {
1828 wait_event(ep->com.waitq, ep->com.rpl_done);
1829 err = ep->com.rpl_err;
1830 if (err)
1831 goto err;
1832 }
1833
1765 err = send_mpa_reply(ep, conn_param->private_data, 1834 err = send_mpa_reply(ep, conn_param->private_data,
1766 conn_param->private_data_len); 1835 conn_param->private_data_len);
1767 if (err) 1836 if (err)
1768 goto err; 1837 goto err;
1769 1838
1770 /* wait for wr_ack */
1771 wait_event(ep->com.waitq, ep->com.rpl_done);
1772 err = ep->com.rpl_err;
1773 if (err)
1774 goto err;
1775 1839
1776 state_set(&ep->com, FPDU_MODE); 1840 state_set(&ep->com, FPDU_MODE);
1777 established_upcall(ep); 1841 established_upcall(ep);
@@ -1968,40 +2032,39 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
1968 PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, 2032 PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
1969 states[ep->com.state], abrupt); 2033 states[ep->com.state], abrupt);
1970 2034
1971 if (ep->com.state == DEAD) {
1972 PDBG("%s already dead ep %p\n", __func__, ep);
1973 goto out;
1974 }
1975
1976 if (abrupt) {
1977 if (ep->com.state != ABORTING) {
1978 ep->com.state = ABORTING;
1979 close = 1;
1980 }
1981 goto out;
1982 }
1983
1984 switch (ep->com.state) { 2035 switch (ep->com.state) {
1985 case MPA_REQ_WAIT: 2036 case MPA_REQ_WAIT:
1986 case MPA_REQ_SENT: 2037 case MPA_REQ_SENT:
1987 case MPA_REQ_RCVD: 2038 case MPA_REQ_RCVD:
1988 case MPA_REP_SENT: 2039 case MPA_REP_SENT:
1989 case FPDU_MODE: 2040 case FPDU_MODE:
1990 start_ep_timer(ep);
1991 ep->com.state = CLOSING;
1992 close = 1; 2041 close = 1;
2042 if (abrupt)
2043 ep->com.state = ABORTING;
2044 else {
2045 ep->com.state = CLOSING;
2046 start_ep_timer(ep);
2047 }
1993 break; 2048 break;
1994 case CLOSING: 2049 case CLOSING:
1995 ep->com.state = MORIBUND;
1996 close = 1; 2050 close = 1;
2051 if (abrupt) {
2052 stop_ep_timer(ep);
2053 ep->com.state = ABORTING;
2054 } else
2055 ep->com.state = MORIBUND;
1997 break; 2056 break;
1998 case MORIBUND: 2057 case MORIBUND:
2058 case ABORTING:
2059 case DEAD:
2060 PDBG("%s ignoring disconnect ep %p state %u\n",
2061 __func__, ep, ep->com.state);
1999 break; 2062 break;
2000 default: 2063 default:
2001 BUG(); 2064 BUG();
2002 break; 2065 break;
2003 } 2066 }
2004out: 2067
2005 spin_unlock_irqrestore(&ep->com.lock, flags); 2068 spin_unlock_irqrestore(&ep->com.lock, flags);
2006 if (close) { 2069 if (close) {
2007 if (abrupt) 2070 if (abrupt)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index 2bb7fbdb3ff4..d7c7e09f0996 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -56,6 +56,7 @@
56#define put_ep(ep) { \ 56#define put_ep(ep) { \
57 PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ 57 PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \
58 ep, atomic_read(&((ep)->kref.refcount))); \ 58 ep, atomic_read(&((ep)->kref.refcount))); \
59 WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \
59 kref_put(&((ep)->kref), __free_ep); \ 60 kref_put(&((ep)->kref), __free_ep); \
60} 61}
61 62
@@ -225,5 +226,6 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, st
225 226
226int __init iwch_cm_init(void); 227int __init iwch_cm_init(void);
227void __exit iwch_cm_term(void); 228void __exit iwch_cm_term(void);
229extern int peer2peer;
228 230
229#endif /* _IWCH_CM_H_ */ 231#endif /* _IWCH_CM_H_ */
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index e343e9e64844..d07d3a377b5f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -998,7 +998,7 @@ static int iwch_query_device(struct ib_device *ibdev,
998 props->device_cap_flags = dev->device_cap_flags; 998 props->device_cap_flags = dev->device_cap_flags;
999 props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; 999 props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor;
1000 props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; 1000 props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device;
1001 props->max_mr_size = ~0ull; 1001 props->max_mr_size = dev->attr.max_mr_size;
1002 props->max_qp = dev->attr.max_qps; 1002 props->max_qp = dev->attr.max_qps;
1003 props->max_qp_wr = dev->attr.max_wrs; 1003 props->max_qp_wr = dev->attr.max_wrs;
1004 props->max_sge = dev->attr.max_sge_per_wr; 1004 props->max_sge = dev->attr.max_sge_per_wr;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index 61356f91109d..db5100d27ca2 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -118,6 +118,7 @@ enum IWCH_QP_FLAGS {
118}; 118};
119 119
120struct iwch_mpa_attributes { 120struct iwch_mpa_attributes {
121 u8 initiator;
121 u8 recv_marker_enabled; 122 u8 recv_marker_enabled;
122 u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */ 123 u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */
123 u8 crc_enabled; 124 u8 crc_enabled;
@@ -322,6 +323,7 @@ enum iwch_qp_query_flags {
322 IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */ 323 IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */
323}; 324};
324 325
326u16 iwch_rqes_posted(struct iwch_qp *qhp);
325int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 327int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
326 struct ib_send_wr **bad_wr); 328 struct ib_send_wr **bad_wr);
327int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, 329int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
@@ -331,6 +333,7 @@ int iwch_bind_mw(struct ib_qp *qp,
331 struct ib_mw_bind *mw_bind); 333 struct ib_mw_bind *mw_bind);
332int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); 334int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
333int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg); 335int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg);
336int iwch_post_zb_read(struct iwch_qp *qhp);
334int iwch_register_device(struct iwch_dev *dev); 337int iwch_register_device(struct iwch_dev *dev);
335void iwch_unregister_device(struct iwch_dev *dev); 338void iwch_unregister_device(struct iwch_dev *dev);
336int iwch_quiesce_qps(struct iwch_cq *chp); 339int iwch_quiesce_qps(struct iwch_cq *chp);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 8891c3b0a3d5..9b4be889c58e 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -586,6 +586,36 @@ static inline void build_term_codes(struct respQ_msg_t *rsp_msg,
586 } 586 }
587} 587}
588 588
589int iwch_post_zb_read(struct iwch_qp *qhp)
590{
591 union t3_wr *wqe;
592 struct sk_buff *skb;
593 u8 flit_cnt = sizeof(struct t3_rdma_read_wr) >> 3;
594
595 PDBG("%s enter\n", __func__);
596 skb = alloc_skb(40, GFP_KERNEL);
597 if (!skb) {
598 printk(KERN_ERR "%s cannot send zb_read!!\n", __func__);
599 return -ENOMEM;
600 }
601 wqe = (union t3_wr *)skb_put(skb, sizeof(struct t3_rdma_read_wr));
602 memset(wqe, 0, sizeof(struct t3_rdma_read_wr));
603 wqe->read.rdmaop = T3_READ_REQ;
604 wqe->read.reserved[0] = 0;
605 wqe->read.reserved[1] = 0;
606 wqe->read.reserved[2] = 0;
607 wqe->read.rem_stag = cpu_to_be32(1);
608 wqe->read.rem_to = cpu_to_be64(1);
609 wqe->read.local_stag = cpu_to_be32(1);
610 wqe->read.local_len = cpu_to_be32(0);
611 wqe->read.local_to = cpu_to_be64(1);
612 wqe->send.wrh.op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(T3_WR_READ));
613 wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
614 V_FW_RIWR_LEN(flit_cnt));
615 skb->priority = CPL_PRIORITY_DATA;
616 return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
617}
618
589/* 619/*
590 * This posts a TERMINATE with layer=RDMA, type=catastrophic. 620 * This posts a TERMINATE with layer=RDMA, type=catastrophic.
591 */ 621 */
@@ -671,11 +701,18 @@ static void flush_qp(struct iwch_qp *qhp, unsigned long *flag)
671 701
672 702
673/* 703/*
674 * Return non zero if at least one RECV was pre-posted. 704 * Return count of RECV WRs posted
675 */ 705 */
676static int rqes_posted(struct iwch_qp *qhp) 706u16 iwch_rqes_posted(struct iwch_qp *qhp)
677{ 707{
678 return fw_riwrh_opcode((struct fw_riwrh *)qhp->wq.queue) == T3_WR_RCV; 708 union t3_wr *wqe = qhp->wq.queue;
709 u16 count = 0;
710 while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) {
711 count++;
712 wqe++;
713 }
714 PDBG("%s qhp %p count %u\n", __func__, qhp, count);
715 return count;
679} 716}
680 717
681static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, 718static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp,
@@ -716,8 +753,17 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp,
716 init_attr.ird = qhp->attr.max_ird; 753 init_attr.ird = qhp->attr.max_ird;
717 init_attr.qp_dma_addr = qhp->wq.dma_addr; 754 init_attr.qp_dma_addr = qhp->wq.dma_addr;
718 init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); 755 init_attr.qp_dma_size = (1UL << qhp->wq.size_log2);
719 init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0; 756 init_attr.rqe_count = iwch_rqes_posted(qhp);
757 init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0;
720 init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; 758 init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0;
759 if (peer2peer) {
760 init_attr.rtr_type = RTR_READ;
761 if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator)
762 init_attr.ord = 1;
763 if (init_attr.ird == 0 && !qhp->attr.mpa_attr.initiator)
764 init_attr.ird = 1;
765 } else
766 init_attr.rtr_type = 0;
721 init_attr.irs = qhp->ep->rcv_seq; 767 init_attr.irs = qhp->ep->rcv_seq;
722 PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " 768 PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d "
723 "flags 0x%x qpcaps 0x%x\n", __func__, 769 "flags 0x%x qpcaps 0x%x\n", __func__,
@@ -832,6 +878,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
832 abort=0; 878 abort=0;
833 disconnect = 1; 879 disconnect = 1;
834 ep = qhp->ep; 880 ep = qhp->ep;
881 get_ep(&ep->com);
835 } 882 }
836 flush_qp(qhp, &flag); 883 flush_qp(qhp, &flag);
837 break; 884 break;
@@ -848,6 +895,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
848 abort=1; 895 abort=1;
849 disconnect = 1; 896 disconnect = 1;
850 ep = qhp->ep; 897 ep = qhp->ep;
898 get_ep(&ep->com);
851 } 899 }
852 goto err; 900 goto err;
853 break; 901 break;
@@ -929,8 +977,10 @@ out:
929 * on the EP. This can be a normal close (RTS->CLOSING) or 977 * on the EP. This can be a normal close (RTS->CLOSING) or
930 * an abnormal close (RTS/CLOSING->ERROR). 978 * an abnormal close (RTS/CLOSING->ERROR).
931 */ 979 */
932 if (disconnect) 980 if (disconnect) {
933 iwch_ep_disconnect(ep, abort, GFP_KERNEL); 981 iwch_ep_disconnect(ep, abort, GFP_KERNEL);
982 put_ep(&ep->com);
983 }
934 984
935 /* 985 /*
936 * If free is 1, then we've disassociated the EP from the QP 986 * If free is 1, then we've disassociated the EP from the QP
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 3d6d9461c31d..00bab60f6de4 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -66,6 +66,7 @@ struct ehca_av;
66#include "ehca_irq.h" 66#include "ehca_irq.h"
67 67
68#define EHCA_EQE_CACHE_SIZE 20 68#define EHCA_EQE_CACHE_SIZE 20
69#define EHCA_MAX_NUM_QUEUES 0xffff
69 70
70struct ehca_eqe_cache_entry { 71struct ehca_eqe_cache_entry {
71 struct ehca_eqe *eqe; 72 struct ehca_eqe *eqe;
@@ -127,6 +128,8 @@ struct ehca_shca {
127 /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ 128 /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
128 u32 hca_cap_mr_pgsize; 129 u32 hca_cap_mr_pgsize;
129 int max_mtu; 130 int max_mtu;
131 atomic_t num_cqs;
132 atomic_t num_qps;
130}; 133};
131 134
132struct ehca_pd { 135struct ehca_pd {
@@ -344,6 +347,8 @@ extern int ehca_use_hp_mr;
344extern int ehca_scaling_code; 347extern int ehca_scaling_code;
345extern int ehca_lock_hcalls; 348extern int ehca_lock_hcalls;
346extern int ehca_nr_ports; 349extern int ehca_nr_ports;
350extern int ehca_max_cq;
351extern int ehca_max_qp;
347 352
348struct ipzu_queue_resp { 353struct ipzu_queue_resp {
349 u32 qe_size; /* queue entry size */ 354 u32 qe_size; /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index ec0cfcf3073f..5540b276a33c 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -132,10 +132,19 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
132 if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) 132 if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
133 return ERR_PTR(-EINVAL); 133 return ERR_PTR(-EINVAL);
134 134
135 if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) {
136 ehca_err(device, "Unable to create CQ, max number of %i "
137 "CQs reached.", ehca_max_cq);
138 ehca_err(device, "To increase the maximum number of CQs "
139 "use the number_of_cqs module parameter.\n");
140 return ERR_PTR(-ENOSPC);
141 }
142
135 my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); 143 my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL);
136 if (!my_cq) { 144 if (!my_cq) {
137 ehca_err(device, "Out of memory for ehca_cq struct device=%p", 145 ehca_err(device, "Out of memory for ehca_cq struct device=%p",
138 device); 146 device);
147 atomic_dec(&shca->num_cqs);
139 return ERR_PTR(-ENOMEM); 148 return ERR_PTR(-ENOMEM);
140 } 149 }
141 150
@@ -305,6 +314,7 @@ create_cq_exit2:
305create_cq_exit1: 314create_cq_exit1:
306 kmem_cache_free(cq_cache, my_cq); 315 kmem_cache_free(cq_cache, my_cq);
307 316
317 atomic_dec(&shca->num_cqs);
308 return cq; 318 return cq;
309} 319}
310 320
@@ -359,6 +369,7 @@ int ehca_destroy_cq(struct ib_cq *cq)
359 ipz_queue_dtor(NULL, &my_cq->ipz_queue); 369 ipz_queue_dtor(NULL, &my_cq->ipz_queue);
360 kmem_cache_free(cq_cache, my_cq); 370 kmem_cache_free(cq_cache, my_cq);
361 371
372 atomic_dec(&shca->num_cqs);
362 return 0; 373 return 0;
363} 374}
364 375
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index b4ac617a70e6..49660dfa1867 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -54,7 +54,8 @@ int ehca_create_eq(struct ehca_shca *shca,
54 struct ehca_eq *eq, 54 struct ehca_eq *eq,
55 const enum ehca_eq_type type, const u32 length) 55 const enum ehca_eq_type type, const u32 length)
56{ 56{
57 u64 ret; 57 int ret;
58 u64 h_ret;
58 u32 nr_pages; 59 u32 nr_pages;
59 u32 i; 60 u32 i;
60 void *vpage; 61 void *vpage;
@@ -73,15 +74,15 @@ int ehca_create_eq(struct ehca_shca *shca,
73 return -EINVAL; 74 return -EINVAL;
74 } 75 }
75 76
76 ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle, 77 h_ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle,
77 &eq->pf, 78 &eq->pf,
78 type, 79 type,
79 length, 80 length,
80 &eq->ipz_eq_handle, 81 &eq->ipz_eq_handle,
81 &eq->length, 82 &eq->length,
82 &nr_pages, &eq->ist); 83 &nr_pages, &eq->ist);
83 84
84 if (ret != H_SUCCESS) { 85 if (h_ret != H_SUCCESS) {
85 ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq); 86 ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq);
86 return -EINVAL; 87 return -EINVAL;
87 } 88 }
@@ -97,24 +98,22 @@ int ehca_create_eq(struct ehca_shca *shca,
97 u64 rpage; 98 u64 rpage;
98 99
99 vpage = ipz_qpageit_get_inc(&eq->ipz_queue); 100 vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
100 if (!vpage) { 101 if (!vpage)
101 ret = H_RESOURCE;
102 goto create_eq_exit2; 102 goto create_eq_exit2;
103 }
104 103
105 rpage = virt_to_abs(vpage); 104 rpage = virt_to_abs(vpage);
106 ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, 105 h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
107 eq->ipz_eq_handle, 106 eq->ipz_eq_handle,
108 &eq->pf, 107 &eq->pf,
109 0, 0, rpage, 1); 108 0, 0, rpage, 1);
110 109
111 if (i == (nr_pages - 1)) { 110 if (i == (nr_pages - 1)) {
112 /* last page */ 111 /* last page */
113 vpage = ipz_qpageit_get_inc(&eq->ipz_queue); 112 vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
114 if (ret != H_SUCCESS || vpage) 113 if (h_ret != H_SUCCESS || vpage)
115 goto create_eq_exit2; 114 goto create_eq_exit2;
116 } else { 115 } else {
117 if (ret != H_PAGE_REGISTERED || !vpage) 116 if (h_ret != H_PAGE_REGISTERED || !vpage)
118 goto create_eq_exit2; 117 goto create_eq_exit2;
119 } 118 }
120 } 119 }
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 65048976198c..482103eb6eac 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -68,6 +68,8 @@ int ehca_port_act_time = 30;
68int ehca_static_rate = -1; 68int ehca_static_rate = -1;
69int ehca_scaling_code = 0; 69int ehca_scaling_code = 0;
70int ehca_lock_hcalls = -1; 70int ehca_lock_hcalls = -1;
71int ehca_max_cq = -1;
72int ehca_max_qp = -1;
71 73
72module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); 74module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO);
73module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); 75module_param_named(debug_level, ehca_debug_level, int, S_IRUGO);
@@ -79,6 +81,8 @@ module_param_named(poll_all_eqs, ehca_poll_all_eqs, bool, S_IRUGO);
79module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); 81module_param_named(static_rate, ehca_static_rate, int, S_IRUGO);
80module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); 82module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO);
81module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); 83module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO);
84module_param_named(number_of_cqs, ehca_max_cq, int, S_IRUGO);
85module_param_named(number_of_qps, ehca_max_qp, int, S_IRUGO);
82 86
83MODULE_PARM_DESC(open_aqp1, 87MODULE_PARM_DESC(open_aqp1,
84 "Open AQP1 on startup (default: no)"); 88 "Open AQP1 on startup (default: no)");
@@ -104,6 +108,12 @@ MODULE_PARM_DESC(scaling_code,
104MODULE_PARM_DESC(lock_hcalls, 108MODULE_PARM_DESC(lock_hcalls,
105 "Serialize all hCalls made by the driver " 109 "Serialize all hCalls made by the driver "
106 "(default: autodetect)"); 110 "(default: autodetect)");
111MODULE_PARM_DESC(number_of_cqs,
112 "Max number of CQs which can be allocated "
113 "(default: autodetect)");
114MODULE_PARM_DESC(number_of_qps,
115 "Max number of QPs which can be allocated "
116 "(default: autodetect)");
107 117
108DEFINE_RWLOCK(ehca_qp_idr_lock); 118DEFINE_RWLOCK(ehca_qp_idr_lock);
109DEFINE_RWLOCK(ehca_cq_idr_lock); 119DEFINE_RWLOCK(ehca_cq_idr_lock);
@@ -355,6 +365,25 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
355 if (rblock->memory_page_size_supported & pgsize_map[i]) 365 if (rblock->memory_page_size_supported & pgsize_map[i])
356 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; 366 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
357 367
368 /* Set maximum number of CQs and QPs to calculate EQ size */
369 if (ehca_max_qp == -1)
370 ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES);
371 else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) {
372 ehca_gen_err("Requested number of QPs is out of range (1 - %i) "
373 "specified by HW", rblock->max_qp);
374 ret = -EINVAL;
375 goto sense_attributes1;
376 }
377
378 if (ehca_max_cq == -1)
379 ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES);
380 else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) {
381 ehca_gen_err("Requested number of CQs is out of range (1 - %i) "
382 "specified by HW", rblock->max_cq);
383 ret = -EINVAL;
384 goto sense_attributes1;
385 }
386
358 /* query max MTU from first port -- it's the same for all ports */ 387 /* query max MTU from first port -- it's the same for all ports */
359 port = (struct hipz_query_port *)rblock; 388 port = (struct hipz_query_port *)rblock;
360 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); 389 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
@@ -684,7 +713,7 @@ static int __devinit ehca_probe(struct of_device *dev,
684 struct ehca_shca *shca; 713 struct ehca_shca *shca;
685 const u64 *handle; 714 const u64 *handle;
686 struct ib_pd *ibpd; 715 struct ib_pd *ibpd;
687 int ret, i; 716 int ret, i, eq_size;
688 717
689 handle = of_get_property(dev->node, "ibm,hca-handle", NULL); 718 handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
690 if (!handle) { 719 if (!handle) {
@@ -705,6 +734,8 @@ static int __devinit ehca_probe(struct of_device *dev,
705 return -ENOMEM; 734 return -ENOMEM;
706 } 735 }
707 mutex_init(&shca->modify_mutex); 736 mutex_init(&shca->modify_mutex);
737 atomic_set(&shca->num_cqs, 0);
738 atomic_set(&shca->num_qps, 0);
708 for (i = 0; i < ARRAY_SIZE(shca->sport); i++) 739 for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
709 spin_lock_init(&shca->sport[i].mod_sqp_lock); 740 spin_lock_init(&shca->sport[i].mod_sqp_lock);
710 741
@@ -724,8 +755,9 @@ static int __devinit ehca_probe(struct of_device *dev,
724 goto probe1; 755 goto probe1;
725 } 756 }
726 757
758 eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp;
727 /* create event queues */ 759 /* create event queues */
728 ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); 760 ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
729 if (ret) { 761 if (ret) {
730 ehca_err(&shca->ib_device, "Cannot create EQ."); 762 ehca_err(&shca->ib_device, "Cannot create EQ.");
731 goto probe1; 763 goto probe1;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 57bef1152cc2..18fba92fa7ae 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -421,8 +421,18 @@ static struct ehca_qp *internal_create_qp(
421 u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; 421 u32 swqe_size = 0, rwqe_size = 0, ib_qp_num;
422 unsigned long flags; 422 unsigned long flags;
423 423
424 if (init_attr->create_flags) 424 if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) {
425 ehca_err(pd->device, "Unable to create QP, max number of %i "
426 "QPs reached.", ehca_max_qp);
427 ehca_err(pd->device, "To increase the maximum number of QPs "
428 "use the number_of_qps module parameter.\n");
429 return ERR_PTR(-ENOSPC);
430 }
431
432 if (init_attr->create_flags) {
433 atomic_dec(&shca->num_qps);
425 return ERR_PTR(-EINVAL); 434 return ERR_PTR(-EINVAL);
435 }
426 436
427 memset(&parms, 0, sizeof(parms)); 437 memset(&parms, 0, sizeof(parms));
428 qp_type = init_attr->qp_type; 438 qp_type = init_attr->qp_type;
@@ -431,6 +441,7 @@ static struct ehca_qp *internal_create_qp(
431 init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { 441 init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) {
432 ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", 442 ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed",
433 init_attr->sq_sig_type); 443 init_attr->sq_sig_type);
444 atomic_dec(&shca->num_qps);
434 return ERR_PTR(-EINVAL); 445 return ERR_PTR(-EINVAL);
435 } 446 }
436 447
@@ -455,6 +466,7 @@ static struct ehca_qp *internal_create_qp(
455 466
456 if (is_llqp && has_srq) { 467 if (is_llqp && has_srq) {
457 ehca_err(pd->device, "LLQPs can't have an SRQ"); 468 ehca_err(pd->device, "LLQPs can't have an SRQ");
469 atomic_dec(&shca->num_qps);
458 return ERR_PTR(-EINVAL); 470 return ERR_PTR(-EINVAL);
459 } 471 }
460 472
@@ -466,6 +478,7 @@ static struct ehca_qp *internal_create_qp(
466 ehca_err(pd->device, "no more than three SGEs " 478 ehca_err(pd->device, "no more than three SGEs "
467 "supported for SRQ pd=%p max_sge=%x", 479 "supported for SRQ pd=%p max_sge=%x",
468 pd, init_attr->cap.max_recv_sge); 480 pd, init_attr->cap.max_recv_sge);
481 atomic_dec(&shca->num_qps);
469 return ERR_PTR(-EINVAL); 482 return ERR_PTR(-EINVAL);
470 } 483 }
471 } 484 }
@@ -477,6 +490,7 @@ static struct ehca_qp *internal_create_qp(
477 qp_type != IB_QPT_SMI && 490 qp_type != IB_QPT_SMI &&
478 qp_type != IB_QPT_GSI) { 491 qp_type != IB_QPT_GSI) {
479 ehca_err(pd->device, "wrong QP Type=%x", qp_type); 492 ehca_err(pd->device, "wrong QP Type=%x", qp_type);
493 atomic_dec(&shca->num_qps);
480 return ERR_PTR(-EINVAL); 494 return ERR_PTR(-EINVAL);
481 } 495 }
482 496
@@ -490,6 +504,7 @@ static struct ehca_qp *internal_create_qp(
490 "or max_rq_wr=%x for RC LLQP", 504 "or max_rq_wr=%x for RC LLQP",
491 init_attr->cap.max_send_wr, 505 init_attr->cap.max_send_wr,
492 init_attr->cap.max_recv_wr); 506 init_attr->cap.max_recv_wr);
507 atomic_dec(&shca->num_qps);
493 return ERR_PTR(-EINVAL); 508 return ERR_PTR(-EINVAL);
494 } 509 }
495 break; 510 break;
@@ -497,6 +512,7 @@ static struct ehca_qp *internal_create_qp(
497 if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { 512 if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) {
498 ehca_err(pd->device, "UD LLQP not supported " 513 ehca_err(pd->device, "UD LLQP not supported "
499 "by this adapter"); 514 "by this adapter");
515 atomic_dec(&shca->num_qps);
500 return ERR_PTR(-ENOSYS); 516 return ERR_PTR(-ENOSYS);
501 } 517 }
502 if (!(init_attr->cap.max_send_sge <= 5 518 if (!(init_attr->cap.max_send_sge <= 5
@@ -508,20 +524,22 @@ static struct ehca_qp *internal_create_qp(
508 "or max_recv_sge=%x for UD LLQP", 524 "or max_recv_sge=%x for UD LLQP",
509 init_attr->cap.max_send_sge, 525 init_attr->cap.max_send_sge,
510 init_attr->cap.max_recv_sge); 526 init_attr->cap.max_recv_sge);
527 atomic_dec(&shca->num_qps);
511 return ERR_PTR(-EINVAL); 528 return ERR_PTR(-EINVAL);
512 } else if (init_attr->cap.max_send_wr > 255) { 529 } else if (init_attr->cap.max_send_wr > 255) {
513 ehca_err(pd->device, 530 ehca_err(pd->device,
514 "Invalid Number of " 531 "Invalid Number of "
515 "max_send_wr=%x for UD QP_TYPE=%x", 532 "max_send_wr=%x for UD QP_TYPE=%x",
516 init_attr->cap.max_send_wr, qp_type); 533 init_attr->cap.max_send_wr, qp_type);
534 atomic_dec(&shca->num_qps);
517 return ERR_PTR(-EINVAL); 535 return ERR_PTR(-EINVAL);
518 } 536 }
519 break; 537 break;
520 default: 538 default:
521 ehca_err(pd->device, "unsupported LL QP Type=%x", 539 ehca_err(pd->device, "unsupported LL QP Type=%x",
522 qp_type); 540 qp_type);
541 atomic_dec(&shca->num_qps);
523 return ERR_PTR(-EINVAL); 542 return ERR_PTR(-EINVAL);
524 break;
525 } 543 }
526 } else { 544 } else {
527 int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI 545 int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI
@@ -533,6 +551,7 @@ static struct ehca_qp *internal_create_qp(
533 "send_sge=%x recv_sge=%x max_sge=%x", 551 "send_sge=%x recv_sge=%x max_sge=%x",
534 init_attr->cap.max_send_sge, 552 init_attr->cap.max_send_sge,
535 init_attr->cap.max_recv_sge, max_sge); 553 init_attr->cap.max_recv_sge, max_sge);
554 atomic_dec(&shca->num_qps);
536 return ERR_PTR(-EINVAL); 555 return ERR_PTR(-EINVAL);
537 } 556 }
538 } 557 }
@@ -543,6 +562,7 @@ static struct ehca_qp *internal_create_qp(
543 my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); 562 my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL);
544 if (!my_qp) { 563 if (!my_qp) {
545 ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); 564 ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd);
565 atomic_dec(&shca->num_qps);
546 return ERR_PTR(-ENOMEM); 566 return ERR_PTR(-ENOMEM);
547 } 567 }
548 568
@@ -823,6 +843,7 @@ create_qp_exit1:
823 843
824create_qp_exit0: 844create_qp_exit0:
825 kmem_cache_free(qp_cache, my_qp); 845 kmem_cache_free(qp_cache, my_qp);
846 atomic_dec(&shca->num_qps);
826 return ERR_PTR(ret); 847 return ERR_PTR(ret);
827} 848}
828 849
@@ -1948,6 +1969,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
1948 if (HAS_SQ(my_qp)) 1969 if (HAS_SQ(my_qp))
1949 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); 1970 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
1950 kmem_cache_free(qp_cache, my_qp); 1971 kmem_cache_free(qp_cache, my_qp);
1972 atomic_dec(&shca->num_qps);
1951 return 0; 1973 return 0;
1952} 1974}
1953 1975
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index e3dddfc687f9..2f199c5c4a72 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -221,7 +221,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector
221 } 221 }
222 222
223 err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, 223 err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar,
224 cq->db.dma, &cq->mcq); 224 cq->db.dma, &cq->mcq, 0);
225 if (err) 225 if (err)
226 goto err_dbmap; 226 goto err_dbmap;
227 227
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 3538da16e3fe..820205dec560 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -818,15 +818,9 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
818 818
819void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) 819void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
820{ 820{
821 u32 key;
822
823 if (!fmr->maps) 821 if (!fmr->maps)
824 return; 822 return;
825 823
826 key = tavor_key_to_hw_index(fmr->ibmr.lkey);
827 key &= dev->limits.num_mpts - 1;
828 fmr->ibmr.lkey = fmr->ibmr.rkey = tavor_hw_index_to_key(key);
829
830 fmr->maps = 0; 824 fmr->maps = 0;
831 825
832 writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt); 826 writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt);
@@ -834,16 +828,9 @@ void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
834 828
835void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) 829void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
836{ 830{
837 u32 key;
838
839 if (!fmr->maps) 831 if (!fmr->maps)
840 return; 832 return;
841 833
842 key = arbel_key_to_hw_index(fmr->ibmr.lkey);
843 key &= dev->limits.num_mpts - 1;
844 key = adjust_key(dev, key);
845 fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key);
846
847 fmr->maps = 0; 834 fmr->maps = 0;
848 835
849 *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; 836 *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW;
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 2a9f460cf061..be34f99ca625 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -39,6 +39,8 @@
39#include <rdma/ib_smi.h> 39#include <rdma/ib_smi.h>
40#include <rdma/ib_umem.h> 40#include <rdma/ib_umem.h>
41#include <rdma/ib_user_verbs.h> 41#include <rdma/ib_user_verbs.h>
42
43#include <linux/sched.h>
42#include <linux/mm.h> 44#include <linux/mm.h>
43 45
44#include "mthca_dev.h" 46#include "mthca_dev.h"
@@ -367,6 +369,8 @@ static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
367 return ERR_PTR(-EFAULT); 369 return ERR_PTR(-EFAULT);
368 } 370 }
369 371
372 context->reg_mr_warned = 0;
373
370 return &context->ibucontext; 374 return &context->ibucontext;
371} 375}
372 376
@@ -1013,7 +1017,15 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
1013 int err = 0; 1017 int err = 0;
1014 int write_mtt_size; 1018 int write_mtt_size;
1015 1019
1016 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) 1020 if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) {
1021 if (!to_mucontext(pd->uobject->context)->reg_mr_warned) {
1022 mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n",
1023 current->comm);
1024 mthca_warn(dev, " Update libmthca to fix this.\n");
1025 }
1026 ++to_mucontext(pd->uobject->context)->reg_mr_warned;
1027 ucmd.mr_attrs = 0;
1028 } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
1017 return ERR_PTR(-EFAULT); 1029 return ERR_PTR(-EFAULT);
1018 1030
1019 mr = kmalloc(sizeof *mr, GFP_KERNEL); 1031 mr = kmalloc(sizeof *mr, GFP_KERNEL);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index 262616c8ebb6..934bf9544037 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -67,6 +67,7 @@ struct mthca_ucontext {
67 struct ib_ucontext ibucontext; 67 struct ib_ucontext ibucontext;
68 struct mthca_uar uar; 68 struct mthca_uar uar;
69 struct mthca_user_db_table *db_tab; 69 struct mthca_user_db_table *db_tab;
70 int reg_mr_warned;
70}; 71};
71 72
72struct mthca_mtt; 73struct mthca_mtt;
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
index f8cb3b664d37..e1262c942db8 100644
--- a/drivers/infiniband/hw/mthca/mthca_user.h
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -41,7 +41,7 @@
41 * Increment this value if any changes that break userspace ABI 41 * Increment this value if any changes that break userspace ABI
42 * compatibility are made. 42 * compatibility are made.
43 */ 43 */
44#define MTHCA_UVERBS_ABI_VERSION 2 44#define MTHCA_UVERBS_ABI_VERSION 1
45 45
46/* 46/*
47 * Make sure that all structs defined in this file remain laid out so 47 * Make sure that all structs defined in this file remain laid out so
@@ -62,10 +62,12 @@ struct mthca_alloc_pd_resp {
62}; 62};
63 63
64struct mthca_reg_mr { 64struct mthca_reg_mr {
65/*
66 * Mark the memory region with a DMA attribute that causes
67 * in-flight DMA to be flushed when the region is written to:
68 */
69#define MTHCA_MR_DMASYNC 0x1
65 __u32 mr_attrs; 70 __u32 mr_attrs;
66#define MTHCA_MR_DMASYNC 0x1
67/* mark the memory region with a DMA attribute that causes
68 * in-flight DMA to be flushed when the region is written to */
69 __u32 reserved; 71 __u32 reserved;
70}; 72};
71 73
diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig
index 2aeb7ac972a9..d449eb6ec78e 100644
--- a/drivers/infiniband/hw/nes/Kconfig
+++ b/drivers/infiniband/hw/nes/Kconfig
@@ -2,6 +2,7 @@ config INFINIBAND_NES
2 tristate "NetEffect RNIC Driver" 2 tristate "NetEffect RNIC Driver"
3 depends on PCI && INET && INFINIBAND 3 depends on PCI && INET && INFINIBAND
4 select LIBCRC32C 4 select LIBCRC32C
5 select INET_LRO
5 ---help--- 6 ---help---
6 This is a low-level driver for NetEffect RDMA enabled 7 This is a low-level driver for NetEffect RDMA enabled
7 Network Interface Cards (RNIC). 8 Network Interface Cards (RNIC).
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index a4e9269a29bd..9f7364a9096d 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -91,6 +91,10 @@ unsigned int nes_debug_level = 0;
91module_param_named(debug_level, nes_debug_level, uint, 0644); 91module_param_named(debug_level, nes_debug_level, uint, 0644);
92MODULE_PARM_DESC(debug_level, "Enable debug output level"); 92MODULE_PARM_DESC(debug_level, "Enable debug output level");
93 93
94unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
95module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR);
96MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation");
97
94LIST_HEAD(nes_adapter_list); 98LIST_HEAD(nes_adapter_list);
95static LIST_HEAD(nes_dev_list); 99static LIST_HEAD(nes_dev_list);
96 100
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index cdf2e9ad62f7..1f9f7bf73862 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -173,6 +173,7 @@ extern int disable_mpa_crc;
173extern unsigned int send_first; 173extern unsigned int send_first;
174extern unsigned int nes_drv_opt; 174extern unsigned int nes_drv_opt;
175extern unsigned int nes_debug_level; 175extern unsigned int nes_debug_level;
176extern unsigned int nes_lro_max_aggr;
176 177
177extern struct list_head nes_adapter_list; 178extern struct list_head nes_adapter_list;
178 179
@@ -535,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *);
535int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); 536int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *);
536void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); 537void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16);
537void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); 538void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *);
538void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); 539void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16);
539void nes_read_10G_phy_reg(struct nes_device *, u16, u8); 540void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16);
540struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); 541struct nes_cqp_request *nes_get_cqp_request(struct nes_device *);
541void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); 542void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int);
542int nes_arp_table(struct nes_device *, u32, u8 *, u32); 543int nes_arp_table(struct nes_device *, u32, u8 *, u32);
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index d940fc27129a..9a4b40fae40d 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -594,7 +594,7 @@ static void nes_cm_timer_tick(unsigned long pass)
594 continue; 594 continue;
595 } 595 }
596 /* this seems like the correct place, but leave send entry unprotected */ 596 /* this seems like the correct place, but leave send entry unprotected */
597 // spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 597 /* spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); */
598 atomic_inc(&send_entry->skb->users); 598 atomic_inc(&send_entry->skb->users);
599 cm_packets_retrans++; 599 cm_packets_retrans++;
600 nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," 600 nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p,"
@@ -1335,7 +1335,7 @@ static int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1335 cm_node->loc_addr, cm_node->loc_port, 1335 cm_node->loc_addr, cm_node->loc_port,
1336 cm_node->rem_addr, cm_node->rem_port, 1336 cm_node->rem_addr, cm_node->rem_port,
1337 cm_node->state, atomic_read(&cm_node->ref_count)); 1337 cm_node->state, atomic_read(&cm_node->ref_count));
1338 // create event 1338 /* create event */
1339 cm_node->state = NES_CM_STATE_CLOSED; 1339 cm_node->state = NES_CM_STATE_CLOSED;
1340 1340
1341 create_event(cm_node, NES_CM_EVENT_ABORTED); 1341 create_event(cm_node, NES_CM_EVENT_ABORTED);
@@ -1669,7 +1669,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1669 if (!cm_node) 1669 if (!cm_node)
1670 return NULL; 1670 return NULL;
1671 1671
1672 // set our node side to client (active) side 1672 /* set our node side to client (active) side */
1673 cm_node->tcp_cntxt.client = 1; 1673 cm_node->tcp_cntxt.client = 1;
1674 cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1674 cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
1675 1675
@@ -1694,7 +1694,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1694 loopbackremotenode->mpa_frame_size = mpa_frame_size - 1694 loopbackremotenode->mpa_frame_size = mpa_frame_size -
1695 sizeof(struct ietf_mpa_frame); 1695 sizeof(struct ietf_mpa_frame);
1696 1696
1697 // we are done handling this state, set node to a TSA state 1697 /* we are done handling this state, set node to a TSA state */
1698 cm_node->state = NES_CM_STATE_TSA; 1698 cm_node->state = NES_CM_STATE_TSA;
1699 cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; 1699 cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num;
1700 loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; 1700 loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num;
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 08964cc7e98a..8dc70f9bad2f 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -38,6 +38,7 @@
38#include <linux/ip.h> 38#include <linux/ip.h>
39#include <linux/tcp.h> 39#include <linux/tcp.h>
40#include <linux/if_vlan.h> 40#include <linux/if_vlan.h>
41#include <linux/inet_lro.h>
41 42
42#include "nes.h" 43#include "nes.h"
43 44
@@ -832,7 +833,7 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou
832 nes_write_indexed(nesdev, 0x00000900, 0x20000001); 833 nes_write_indexed(nesdev, 0x00000900, 0x20000001);
833 nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); 834 nes_write_indexed(nesdev, 0x000060C0, 0x0000028e);
834 nes_write_indexed(nesdev, 0x000060C8, 0x00000020); 835 nes_write_indexed(nesdev, 0x000060C8, 0x00000020);
835 // 836
836 nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); 837 nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0);
837 /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ 838 /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */
838 839
@@ -1207,11 +1208,16 @@ int nes_init_phy(struct nes_device *nesdev)
1207{ 1208{
1208 struct nes_adapter *nesadapter = nesdev->nesadapter; 1209 struct nes_adapter *nesadapter = nesdev->nesadapter;
1209 u32 counter = 0; 1210 u32 counter = 0;
1211 u32 sds_common_control0;
1210 u32 mac_index = nesdev->mac_index; 1212 u32 mac_index = nesdev->mac_index;
1211 u32 tx_config; 1213 u32 tx_config = 0;
1212 u16 phy_data; 1214 u16 phy_data;
1215 u32 temp_phy_data = 0;
1216 u32 temp_phy_data2 = 0;
1217 u32 i = 0;
1213 1218
1214 if (nesadapter->OneG_Mode) { 1219 if ((nesadapter->OneG_Mode) &&
1220 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
1215 nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); 1221 nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
1216 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { 1222 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
1217 printk(PFX "%s: Programming mdc config for 1G\n", __func__); 1223 printk(PFX "%s: Programming mdc config for 1G\n", __func__);
@@ -1223,7 +1229,7 @@ int nes_init_phy(struct nes_device *nesdev)
1223 nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); 1229 nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
1224 nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", 1230 nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
1225 nesadapter->phy_index[mac_index], phy_data); 1231 nesadapter->phy_index[mac_index], phy_data);
1226 nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); 1232 nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
1227 1233
1228 /* Reset the PHY */ 1234 /* Reset the PHY */
1229 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); 1235 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
@@ -1277,12 +1283,126 @@ int nes_init_phy(struct nes_device *nesdev)
1277 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); 1283 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
1278 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); 1284 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
1279 } else { 1285 } else {
1280 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { 1286 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
1287 (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
1281 /* setup 10G MDIO operation */ 1288 /* setup 10G MDIO operation */
1282 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); 1289 tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
1283 tx_config |= 0x14; 1290 tx_config |= 0x14;
1284 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); 1291 nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
1285 } 1292 }
1293 if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
1294 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1295
1296 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1297 mdelay(10);
1298 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1299 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1300
1301 /*
1302 * if firmware is already running (like from a
1303 * driver un-load/load, don't do anything.
1304 */
1305 if (temp_phy_data == temp_phy_data2) {
1306 /* configure QT2505 AMCC PHY */
1307 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
1308 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
1309 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
1310 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
1311 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
1312 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
1313 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
1314 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000);
1315 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
1316
1317 /*
1318 * remove micro from reset; chip boots from ROM,
1319 * uploads EEPROM f/w image, uC executes f/w
1320 */
1321 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
1322
1323 /*
1324 * wait for heart beat to start to
1325 * know loading is done
1326 */
1327 counter = 0;
1328 do {
1329 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1330 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1331 if (counter++ > 1000) {
1332 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
1333 break;
1334 }
1335 mdelay(100);
1336 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
1337 temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1338 } while ((temp_phy_data2 == temp_phy_data));
1339
1340 /*
1341 * wait for tracking to start to know
1342 * f/w is good to go
1343 */
1344 counter = 0;
1345 do {
1346 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
1347 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
1348 if (counter++ > 1000) {
1349 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
1350 break;
1351 }
1352 mdelay(1000);
1353 /*
1354 * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
1355 * temp_phy_data);
1356 */
1357 } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
1358
1359 /* set LOS Control invert RXLOSB_I_PADINV */
1360 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
1361 /* set LOS Control to mask of RXLOSB_I */
1362 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
1363 /* set LED1 to input mode (LED1 and LED2 share same LED) */
1364 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
1365 /* set LED2 to RX link_status and activity */
1366 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
1367 /* set LED3 to RX link_status */
1368 nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
1369
1370 /*
1371 * reset the res-calibration on t2
1372 * serdes; ensures it is stable after
1373 * the amcc phy is stable
1374 */
1375
1376 sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
1377 sds_common_control0 |= 0x1;
1378 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1379
1380 /* release the res-calibration reset */
1381 sds_common_control0 &= 0xfffffffe;
1382 nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
1383
1384 i = 0;
1385 while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
1386 && (i++ < 5000)) {
1387 /* mdelay(1); */
1388 }
1389
1390 /*
1391 * wait for link train done before moving on,
1392 * or will get an interupt storm
1393 */
1394 counter = 0;
1395 do {
1396 temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1397 (0x200 * (nesdev->mac_index & 1)));
1398 if (counter++ > 1000) {
1399 nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
1400 break;
1401 }
1402 mdelay(1);
1403 } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
1404 }
1405 }
1286 } 1406 }
1287 return 0; 1407 return 0;
1288} 1408}
@@ -1375,6 +1495,25 @@ static void nes_rq_wqes_timeout(unsigned long parm)
1375} 1495}
1376 1496
1377 1497
1498static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr,
1499 void **tcph, u64 *hdr_flags, void *priv)
1500{
1501 unsigned int ip_len;
1502 struct iphdr *iph;
1503 skb_reset_network_header(skb);
1504 iph = ip_hdr(skb);
1505 if (iph->protocol != IPPROTO_TCP)
1506 return -1;
1507 ip_len = ip_hdrlen(skb);
1508 skb_set_transport_header(skb, ip_len);
1509 *tcph = tcp_hdr(skb);
1510
1511 *hdr_flags = LRO_IPV4 | LRO_TCP;
1512 *iphdr = iph;
1513 return 0;
1514}
1515
1516
1378/** 1517/**
1379 * nes_init_nic_qp 1518 * nes_init_nic_qp
1380 */ 1519 */
@@ -1520,10 +1659,10 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
1520 } 1659 }
1521 1660
1522 u64temp = (u64)nesvnic->nic.sq_pbase; 1661 u64temp = (u64)nesvnic->nic.sq_pbase;
1523 nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); 1662 nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
1524 nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); 1663 nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1525 u64temp = (u64)nesvnic->nic.rq_pbase; 1664 u64temp = (u64)nesvnic->nic.rq_pbase;
1526 nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); 1665 nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp);
1527 nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); 1666 nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32));
1528 1667
1529 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | 1668 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP |
@@ -1575,7 +1714,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
1575 nic_rqe = &nesvnic->nic.rq_vbase[counter]; 1714 nic_rqe = &nesvnic->nic.rq_vbase[counter];
1576 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); 1715 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size);
1577 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; 1716 nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0;
1578 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); 1717 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem);
1579 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); 1718 nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32));
1580 nesvnic->nic.rx_skb[counter] = skb; 1719 nesvnic->nic.rx_skb[counter] = skb;
1581 } 1720 }
@@ -1592,15 +1731,21 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
1592 nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; 1731 nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout;
1593 nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; 1732 nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic;
1594 nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); 1733 nes_debug(NES_DBG_INIT, "NAPI support Enabled\n");
1595
1596 if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) 1734 if (nesdev->nesadapter->et_use_adaptive_rx_coalesce)
1597 { 1735 {
1598 nes_nic_init_timer(nesdev); 1736 nes_nic_init_timer(nesdev);
1599 if (netdev->mtu > 1500) 1737 if (netdev->mtu > 1500)
1600 jumbomode = 1; 1738 jumbomode = 1;
1601 nes_nic_init_timer_defaults(nesdev, jumbomode); 1739 nes_nic_init_timer_defaults(nesdev, jumbomode);
1602 } 1740 }
1603 1741 nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR;
1742 nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS;
1743 nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc;
1744 nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
1745 nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
1746 nesvnic->lro_mgr.dev = netdev;
1747 nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
1748 nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
1604 return 0; 1749 return 0;
1605} 1750}
1606 1751
@@ -1620,8 +1765,8 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
1620 1765
1621 /* Free remaining NIC receive buffers */ 1766 /* Free remaining NIC receive buffers */
1622 while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { 1767 while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
1623 nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; 1768 nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
1624 wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); 1769 wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
1625 wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; 1770 wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
1626 pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, 1771 pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag,
1627 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); 1772 nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
@@ -1704,17 +1849,17 @@ int nes_napi_isr(struct nes_device *nesdev)
1704 /* iff NIC, process here, else wait for DPC */ 1849 /* iff NIC, process here, else wait for DPC */
1705 if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { 1850 if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) {
1706 nesdev->napi_isr_ran = 0; 1851 nesdev->napi_isr_ran = 0;
1707 nes_write32(nesdev->regs+NES_INT_STAT, 1852 nes_write32(nesdev->regs + NES_INT_STAT,
1708 (int_stat & 1853 (int_stat &
1709 ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0|NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); 1854 ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3)));
1710 1855
1711 /* Process the CEQs */ 1856 /* Process the CEQs */
1712 nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); 1857 nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]);
1713 1858
1714 if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && 1859 if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) &&
1715 (!nesadapter->et_use_adaptive_rx_coalesce)) || 1860 (!nesadapter->et_use_adaptive_rx_coalesce)) ||
1716 ((nesadapter->et_use_adaptive_rx_coalesce) && 1861 ((nesadapter->et_use_adaptive_rx_coalesce) &&
1717 (nesdev->deepcq_count > nesadapter->et_pkt_rate_low)))) ) { 1862 (nesdev->deepcq_count > nesadapter->et_pkt_rate_low))))) {
1718 if ((nesdev->int_req & NES_INT_TIMER) == 0) { 1863 if ((nesdev->int_req & NES_INT_TIMER) == 0) {
1719 /* Enable Periodic timer interrupts */ 1864 /* Enable Periodic timer interrupts */
1720 nesdev->int_req |= NES_INT_TIMER; 1865 nesdev->int_req |= NES_INT_TIMER;
@@ -1792,12 +1937,12 @@ void nes_dpc(unsigned long param)
1792 } 1937 }
1793 1938
1794 if (int_stat) { 1939 if (int_stat) {
1795 if (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 1940 if (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
1796 NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3)) { 1941 NES_INT_MAC1|NES_INT_MAC2 | NES_INT_MAC3)) {
1797 /* Ack the interrupts */ 1942 /* Ack the interrupts */
1798 nes_write32(nesdev->regs+NES_INT_STAT, 1943 nes_write32(nesdev->regs+NES_INT_STAT,
1799 (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 1944 (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0|
1800 NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); 1945 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3)));
1801 } 1946 }
1802 1947
1803 temp_int_stat = int_stat; 1948 temp_int_stat = int_stat;
@@ -1862,8 +2007,8 @@ void nes_dpc(unsigned long param)
1862 } 2007 }
1863 } 2008 }
1864 /* Don't use the interface interrupt bit stay in loop */ 2009 /* Don't use the interface interrupt bit stay in loop */
1865 int_stat &= ~NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 2010 int_stat &= ~NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 |
1866 NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3; 2011 NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3;
1867 } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); 2012 } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS));
1868 2013
1869 if (timer_ints == 1) { 2014 if (timer_ints == 1) {
@@ -1874,9 +2019,9 @@ void nes_dpc(unsigned long param)
1874 nesdev->timer_only_int_count = 0; 2019 nesdev->timer_only_int_count = 0;
1875 nesdev->int_req &= ~NES_INT_TIMER; 2020 nesdev->int_req &= ~NES_INT_TIMER;
1876 nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); 2021 nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
1877 nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 2022 nes_write32(nesdev->regs + NES_INT_MASK, ~nesdev->int_req);
1878 } else { 2023 } else {
1879 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); 2024 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
1880 } 2025 }
1881 } else { 2026 } else {
1882 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) 2027 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
@@ -1884,7 +2029,7 @@ void nes_dpc(unsigned long param)
1884 nes_nic_init_timer(nesdev); 2029 nes_nic_init_timer(nesdev);
1885 } 2030 }
1886 nesdev->timer_only_int_count = 0; 2031 nesdev->timer_only_int_count = 0;
1887 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); 2032 nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req));
1888 } 2033 }
1889 } else { 2034 } else {
1890 nesdev->timer_only_int_count = 0; 2035 nesdev->timer_only_int_count = 0;
@@ -1933,7 +2078,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq)
1933 do { 2078 do {
1934 if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & 2079 if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) &
1935 NES_CEQE_VALID) { 2080 NES_CEQE_VALID) {
1936 u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX])))<<32) | 2081 u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]))) << 32) |
1937 ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); 2082 ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX])));
1938 u64temp <<= 1; 2083 u64temp <<= 1;
1939 cq = *((struct nes_hw_cq **)&u64temp); 2084 cq = *((struct nes_hw_cq **)&u64temp);
@@ -1961,7 +2106,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq)
1961 */ 2106 */
1962static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) 2107static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
1963{ 2108{
1964// u64 u64temp; 2109 /* u64 u64temp; */
1965 u32 head; 2110 u32 head;
1966 u32 aeq_size; 2111 u32 aeq_size;
1967 u32 aeqe_misc; 2112 u32 aeqe_misc;
@@ -1980,8 +2125,10 @@ static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
1980 if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { 2125 if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) {
1981 if (aeqe_cq_id >= NES_FIRST_QPN) { 2126 if (aeqe_cq_id >= NES_FIRST_QPN) {
1982 /* dealing with an accelerated QP related AE */ 2127 /* dealing with an accelerated QP related AE */
1983// u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])))<<32) | 2128 /*
1984// ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); 2129 * u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX]))) << 32) |
2130 * ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX])));
2131 */
1985 nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); 2132 nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe);
1986 } else { 2133 } else {
1987 /* TODO: dealing with a CQP related AE */ 2134 /* TODO: dealing with a CQP related AE */
@@ -2081,6 +2228,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2081 u32 u32temp; 2228 u32 u32temp;
2082 u16 phy_data; 2229 u16 phy_data;
2083 u16 temp_phy_data; 2230 u16 temp_phy_data;
2231 u32 pcs_val = 0x0f0f0000;
2232 u32 pcs_mask = 0x0f1f0000;
2084 2233
2085 spin_lock_irqsave(&nesadapter->phy_lock, flags); 2234 spin_lock_irqsave(&nesadapter->phy_lock, flags);
2086 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { 2235 if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2144,13 +2293,30 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2144 nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", 2293 nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n",
2145 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), 2294 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0),
2146 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); 2295 nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200));
2147 pcs_control_status = nes_read_indexed(nesdev, 2296
2148 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); 2297 if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) {
2149 pcs_control_status = nes_read_indexed(nesdev, 2298 switch (mac_index) {
2150 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); 2299 case 1:
2300 case 3:
2301 pcs_control_status = nes_read_indexed(nesdev,
2302 NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200);
2303 break;
2304 default:
2305 pcs_control_status = nes_read_indexed(nesdev,
2306 NES_IDX_PHY_PCS_CONTROL_STATUS0);
2307 break;
2308 }
2309 } else {
2310 pcs_control_status = nes_read_indexed(nesdev,
2311 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2312 pcs_control_status = nes_read_indexed(nesdev,
2313 NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200));
2314 }
2315
2151 nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", 2316 nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n",
2152 mac_index, pcs_control_status); 2317 mac_index, pcs_control_status);
2153 if (nesadapter->OneG_Mode) { 2318 if ((nesadapter->OneG_Mode) &&
2319 (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
2154 u32temp = 0x01010000; 2320 u32temp = 0x01010000;
2155 if (nesadapter->port_count > 2) { 2321 if (nesadapter->port_count > 2) {
2156 u32temp |= 0x02020000; 2322 u32temp |= 0x02020000;
@@ -2159,24 +2325,59 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2159 phy_data = 0; 2325 phy_data = 0;
2160 nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); 2326 nes_debug(NES_DBG_PHY, "PCS says the link is down\n");
2161 } 2327 }
2162 } else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) {
2163 nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]);
2164 temp_phy_data = (u16)nes_read_indexed(nesdev,
2165 NES_IDX_MAC_MDIO_CONTROL);
2166 u32temp = 20;
2167 do {
2168 nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]);
2169 phy_data = (u16)nes_read_indexed(nesdev,
2170 NES_IDX_MAC_MDIO_CONTROL);
2171 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2172 break;
2173 temp_phy_data = phy_data;
2174 } while (1);
2175 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2176 __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
2177
2178 } else { 2328 } else {
2179 phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0; 2329 switch (nesadapter->phy_type[mac_index]) {
2330 case NES_PHY_TYPE_IRIS:
2331 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2332 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2333 u32temp = 20;
2334 do {
2335 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2336 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2337 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2338 break;
2339 temp_phy_data = phy_data;
2340 } while (1);
2341 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2342 __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
2343 break;
2344
2345 case NES_PHY_TYPE_ARGUS:
2346 /* clear the alarms */
2347 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
2348 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
2349 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002);
2350 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005);
2351 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006);
2352 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
2353 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
2354 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
2355 /* check link status */
2356 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2357 temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2358 u32temp = 100;
2359 do {
2360 nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
2361
2362 phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
2363 if ((phy_data == temp_phy_data) || (!(--u32temp)))
2364 break;
2365 temp_phy_data = phy_data;
2366 } while (1);
2367 nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
2368 __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
2369 break;
2370
2371 case NES_PHY_TYPE_PUMA_1G:
2372 if (mac_index < 2)
2373 pcs_val = pcs_mask = 0x01010000;
2374 else
2375 pcs_val = pcs_mask = 0x02020000;
2376 /* fall through */
2377 default:
2378 phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0;
2379 break;
2380 }
2180 } 2381 }
2181 2382
2182 if (phy_data & 0x0004) { 2383 if (phy_data & 0x0004) {
@@ -2185,8 +2386,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2185 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", 2386 nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n",
2186 nesvnic->linkup); 2387 nesvnic->linkup);
2187 if (nesvnic->linkup == 0) { 2388 if (nesvnic->linkup == 0) {
2188 printk(PFX "The Link is now up for port %u, netdev %p.\n", 2389 printk(PFX "The Link is now up for port %s, netdev %p.\n",
2189 mac_index, nesvnic->netdev); 2390 nesvnic->netdev->name, nesvnic->netdev);
2190 if (netif_queue_stopped(nesvnic->netdev)) 2391 if (netif_queue_stopped(nesvnic->netdev))
2191 netif_start_queue(nesvnic->netdev); 2392 netif_start_queue(nesvnic->netdev);
2192 nesvnic->linkup = 1; 2393 nesvnic->linkup = 1;
@@ -2199,8 +2400,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
2199 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", 2400 nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
2200 nesvnic->linkup); 2401 nesvnic->linkup);
2201 if (nesvnic->linkup == 1) { 2402 if (nesvnic->linkup == 1) {
2202 printk(PFX "The Link is now down for port %u, netdev %p.\n", 2403 printk(PFX "The Link is now down for port %s, netdev %p.\n",
2203 mac_index, nesvnic->netdev); 2404 nesvnic->netdev->name, nesvnic->netdev);
2204 if (!(netif_queue_stopped(nesvnic->netdev))) 2405 if (!(netif_queue_stopped(nesvnic->netdev)))
2205 netif_stop_queue(nesvnic->netdev); 2406 netif_stop_queue(nesvnic->netdev);
2206 nesvnic->linkup = 0; 2407 nesvnic->linkup = 0;
@@ -2254,10 +2455,13 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2254 u16 pkt_type; 2455 u16 pkt_type;
2255 u16 rqes_processed = 0; 2456 u16 rqes_processed = 0;
2256 u8 sq_cqes = 0; 2457 u8 sq_cqes = 0;
2458 u8 nes_use_lro = 0;
2257 2459
2258 head = cq->cq_head; 2460 head = cq->cq_head;
2259 cq_size = cq->cq_size; 2461 cq_size = cq->cq_size;
2260 cq->cqes_pending = 1; 2462 cq->cqes_pending = 1;
2463 if (nesvnic->netdev->features & NETIF_F_LRO)
2464 nes_use_lro = 1;
2261 do { 2465 do {
2262 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & 2466 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
2263 NES_NIC_CQE_VALID) { 2467 NES_NIC_CQE_VALID) {
@@ -2272,8 +2476,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2272 /* bump past the vlan tag */ 2476 /* bump past the vlan tag */
2273 wqe_fragment_length++; 2477 wqe_fragment_length++;
2274 if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { 2478 if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
2275 u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); 2479 u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2276 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; 2480 wqe_fragment_index * 2]);
2481 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX +
2482 wqe_fragment_index * 2])) << 32;
2277 bus_address = (dma_addr_t)u64temp; 2483 bus_address = (dma_addr_t)u64temp;
2278 if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { 2484 if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) {
2279 pci_unmap_single(nesdev->pcidev, 2485 pci_unmap_single(nesdev->pcidev,
@@ -2283,8 +2489,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2283 } 2489 }
2284 for (; wqe_fragment_index < 5; wqe_fragment_index++) { 2490 for (; wqe_fragment_index < 5; wqe_fragment_index++) {
2285 if (wqe_fragment_length[wqe_fragment_index]) { 2491 if (wqe_fragment_length[wqe_fragment_index]) {
2286 u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); 2492 u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX +
2287 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; 2493 wqe_fragment_index * 2]);
2494 u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
2495 + wqe_fragment_index * 2])) <<32;
2288 bus_address = (dma_addr_t)u64temp; 2496 bus_address = (dma_addr_t)u64temp;
2289 pci_unmap_page(nesdev->pcidev, 2497 pci_unmap_page(nesdev->pcidev,
2290 bus_address, 2498 bus_address,
@@ -2331,7 +2539,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2331 if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { 2539 if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) {
2332 nes_write32(nesdev->regs+NES_CQE_ALLOC, 2540 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2333 cq->cq_number | (cqe_count << 16)); 2541 cq->cq_number | (cqe_count << 16));
2334// nesadapter->tune_timer.cq_count += cqe_count; 2542 /* nesadapter->tune_timer.cq_count += cqe_count; */
2335 nesdev->currcq_count += cqe_count; 2543 nesdev->currcq_count += cqe_count;
2336 cqe_count = 0; 2544 cqe_count = 0;
2337 nes_replenish_nic_rq(nesvnic); 2545 nes_replenish_nic_rq(nesvnic);
@@ -2379,9 +2587,16 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2379 >> 16); 2587 >> 16);
2380 nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", 2588 nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
2381 nesvnic->netdev->name, vlan_tag); 2589 nesvnic->netdev->name, vlan_tag);
2382 nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); 2590 if (nes_use_lro)
2591 lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
2592 nesvnic->vlan_grp, vlan_tag, NULL);
2593 else
2594 nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
2383 } else { 2595 } else {
2384 nes_netif_rx(rx_skb); 2596 if (nes_use_lro)
2597 lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
2598 else
2599 nes_netif_rx(rx_skb);
2385 } 2600 }
2386 } 2601 }
2387 2602
@@ -2399,7 +2614,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2399 /* Replenish Nic CQ */ 2614 /* Replenish Nic CQ */
2400 nes_write32(nesdev->regs+NES_CQE_ALLOC, 2615 nes_write32(nesdev->regs+NES_CQE_ALLOC,
2401 cq->cq_number | (cqe_count << 16)); 2616 cq->cq_number | (cqe_count << 16));
2402// nesdev->nesadapter->tune_timer.cq_count += cqe_count; 2617 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
2403 nesdev->currcq_count += cqe_count; 2618 nesdev->currcq_count += cqe_count;
2404 cqe_count = 0; 2619 cqe_count = 0;
2405 } 2620 }
@@ -2413,26 +2628,27 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
2413 2628
2414 } while (1); 2629 } while (1);
2415 2630
2631 if (nes_use_lro)
2632 lro_flush_all(&nesvnic->lro_mgr);
2416 if (sq_cqes) { 2633 if (sq_cqes) {
2417 barrier(); 2634 barrier();
2418 /* restart the queue if it had been stopped */ 2635 /* restart the queue if it had been stopped */
2419 if (netif_queue_stopped(nesvnic->netdev)) 2636 if (netif_queue_stopped(nesvnic->netdev))
2420 netif_wake_queue(nesvnic->netdev); 2637 netif_wake_queue(nesvnic->netdev);
2421 } 2638 }
2422
2423 cq->cq_head = head; 2639 cq->cq_head = head;
2424 /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", 2640 /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
2425 cq->cq_number, cqe_count, cq->cq_head); */ 2641 cq->cq_number, cqe_count, cq->cq_head); */
2426 cq->cqe_allocs_pending = cqe_count; 2642 cq->cqe_allocs_pending = cqe_count;
2427 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) 2643 if (unlikely(nesadapter->et_use_adaptive_rx_coalesce))
2428 { 2644 {
2429// nesdev->nesadapter->tune_timer.cq_count += cqe_count; 2645 /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */
2430 nesdev->currcq_count += cqe_count; 2646 nesdev->currcq_count += cqe_count;
2431 nes_nic_tune_timer(nesdev); 2647 nes_nic_tune_timer(nesdev);
2432 } 2648 }
2433 if (atomic_read(&nesvnic->rx_skbs_needed)) 2649 if (atomic_read(&nesvnic->rx_skbs_needed))
2434 nes_replenish_nic_rq(nesvnic); 2650 nes_replenish_nic_rq(nesvnic);
2435 } 2651}
2436 2652
2437 2653
2438/** 2654/**
@@ -2461,7 +2677,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
2461 2677
2462 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { 2678 if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) {
2463 u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. 2679 u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head].
2464 cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | 2680 cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]))) << 32) |
2465 ((u64)(le32_to_cpu(cq->cq_vbase[head]. 2681 ((u64)(le32_to_cpu(cq->cq_vbase[head].
2466 cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); 2682 cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX])));
2467 cqp = *((struct nes_hw_cqp **)&u64temp); 2683 cqp = *((struct nes_hw_cqp **)&u64temp);
@@ -2478,7 +2694,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
2478 } 2694 }
2479 2695
2480 u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. 2696 u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
2481 wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX])))<<32) | 2697 wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) |
2482 ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. 2698 ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail].
2483 wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); 2699 wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX])));
2484 cqp_request = *((struct nes_cqp_request **)&u64temp); 2700 cqp_request = *((struct nes_cqp_request **)&u64temp);
@@ -2515,7 +2731,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
2515 } else { 2731 } else {
2516 nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", 2732 nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n",
2517 cqp_request, 2733 cqp_request,
2518 le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); 2734 le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]) & 0x3f);
2519 if (cqp_request->dynamic) { 2735 if (cqp_request->dynamic) {
2520 kfree(cqp_request); 2736 kfree(cqp_request);
2521 } else { 2737 } else {
@@ -2529,7 +2745,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq)
2529 } 2745 }
2530 2746
2531 cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; 2747 cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
2532 nes_write32(nesdev->regs+NES_CQE_ALLOC, cq->cq_number | (1 << 16)); 2748 nes_write32(nesdev->regs + NES_CQE_ALLOC, cq->cq_number | (1 << 16));
2533 if (++cqp->sq_tail >= cqp->sq_size) 2749 if (++cqp->sq_tail >= cqp->sq_size)
2534 cqp->sq_tail = 0; 2750 cqp->sq_tail = 0;
2535 2751
@@ -2598,13 +2814,13 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2598 nes_debug(NES_DBG_AEQ, "\n"); 2814 nes_debug(NES_DBG_AEQ, "\n");
2599 aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); 2815 aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
2600 if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { 2816 if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) {
2601 context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); 2817 context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
2602 context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; 2818 context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2603 } else { 2819 } else {
2604 aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); 2820 aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
2605 aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; 2821 aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
2606 context = (unsigned long)nesadapter->qp_table[le32_to_cpu( 2822 context = (unsigned long)nesadapter->qp_table[le32_to_cpu(
2607 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; 2823 aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN];
2608 BUG_ON(!context); 2824 BUG_ON(!context);
2609 } 2825 }
2610 2826
@@ -2617,7 +2833,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2617 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, 2833 le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe,
2618 nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); 2834 nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]);
2619 2835
2620
2621 switch (async_event_id) { 2836 switch (async_event_id) {
2622 case NES_AEQE_AEID_LLP_FIN_RECEIVED: 2837 case NES_AEQE_AEID_LLP_FIN_RECEIVED:
2623 nesqp = *((struct nes_qp **)&context); 2838 nesqp = *((struct nes_qp **)&context);
@@ -3021,7 +3236,7 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr,
3021 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); 3236 cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID);
3022 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( 3237 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32(
3023 (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | 3238 (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) |
3024 (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); 3239 (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]);
3025 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( 3240 cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32(
3026 (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); 3241 (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]);
3027 } else { 3242 } else {
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 8f36e231bdf5..745bf94f3f07 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -33,8 +33,12 @@
33#ifndef __NES_HW_H 33#ifndef __NES_HW_H
34#define __NES_HW_H 34#define __NES_HW_H
35 35
36#define NES_PHY_TYPE_1G 2 36#include <linux/inet_lro.h>
37#define NES_PHY_TYPE_IRIS 3 37
38#define NES_PHY_TYPE_1G 2
39#define NES_PHY_TYPE_IRIS 3
40#define NES_PHY_TYPE_ARGUS 4
41#define NES_PHY_TYPE_PUMA_1G 5
38#define NES_PHY_TYPE_PUMA_10G 6 42#define NES_PHY_TYPE_PUMA_10G 6
39 43
40#define NES_MULTICAST_PF_MAX 8 44#define NES_MULTICAST_PF_MAX 8
@@ -965,7 +969,7 @@ struct nes_arp_entry {
965#define NES_NIC_CQ_DOWNWARD_TREND 16 969#define NES_NIC_CQ_DOWNWARD_TREND 16
966 970
967struct nes_hw_tune_timer { 971struct nes_hw_tune_timer {
968 //u16 cq_count; 972 /* u16 cq_count; */
969 u16 threshold_low; 973 u16 threshold_low;
970 u16 threshold_target; 974 u16 threshold_target;
971 u16 threshold_high; 975 u16 threshold_high;
@@ -982,8 +986,10 @@ struct nes_hw_tune_timer {
982#define NES_TIMER_INT_LIMIT 2 986#define NES_TIMER_INT_LIMIT 2
983#define NES_TIMER_INT_LIMIT_DYNAMIC 10 987#define NES_TIMER_INT_LIMIT_DYNAMIC 10
984#define NES_TIMER_ENABLE_LIMIT 4 988#define NES_TIMER_ENABLE_LIMIT 4
985#define NES_MAX_LINK_INTERRUPTS 128 989#define NES_MAX_LINK_INTERRUPTS 128
986#define NES_MAX_LINK_CHECK 200 990#define NES_MAX_LINK_CHECK 200
991#define NES_MAX_LRO_DESCRIPTORS 32
992#define NES_LRO_MAX_AGGR 64
987 993
988struct nes_adapter { 994struct nes_adapter {
989 u64 fw_ver; 995 u64 fw_ver;
@@ -1183,6 +1189,9 @@ struct nes_vnic {
1183 u8 of_device_registered; 1189 u8 of_device_registered;
1184 u8 rdma_enabled; 1190 u8 rdma_enabled;
1185 u8 rx_checksum_disabled; 1191 u8 rx_checksum_disabled;
1192 u32 lro_max_aggr;
1193 struct net_lro_mgr lro_mgr;
1194 struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
1186}; 1195};
1187 1196
1188struct nes_ib_device { 1197struct nes_ib_device {
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index e5366b013c1a..1b0938c87774 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -185,12 +185,13 @@ static int nes_netdev_open(struct net_device *netdev)
185 nic_active |= nic_active_bit; 185 nic_active |= nic_active_bit;
186 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); 186 nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
187 187
188 macaddr_high = ((u16)netdev->dev_addr[0]) << 8; 188 macaddr_high = ((u16)netdev->dev_addr[0]) << 8;
189 macaddr_high += (u16)netdev->dev_addr[1]; 189 macaddr_high += (u16)netdev->dev_addr[1];
190 macaddr_low = ((u32)netdev->dev_addr[2]) << 24; 190
191 macaddr_low += ((u32)netdev->dev_addr[3]) << 16; 191 macaddr_low = ((u32)netdev->dev_addr[2]) << 24;
192 macaddr_low += ((u32)netdev->dev_addr[4]) << 8; 192 macaddr_low += ((u32)netdev->dev_addr[3]) << 16;
193 macaddr_low += (u32)netdev->dev_addr[5]; 193 macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
194 macaddr_low += (u32)netdev->dev_addr[5];
194 195
195 /* Program the various MAC regs */ 196 /* Program the various MAC regs */
196 for (i = 0; i < NES_MAX_PORT_COUNT; i++) { 197 for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
@@ -451,7 +452,7 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
451 __le16 *wqe_fragment_length; 452 __le16 *wqe_fragment_length;
452 u32 nr_frags; 453 u32 nr_frags;
453 u32 original_first_length; 454 u32 original_first_length;
454// u64 *wqe_fragment_address; 455 /* u64 *wqe_fragment_address; */
455 /* first fragment (0) is used by copy buffer */ 456 /* first fragment (0) is used by copy buffer */
456 u16 wqe_fragment_index=1; 457 u16 wqe_fragment_index=1;
457 u16 hoffset; 458 u16 hoffset;
@@ -461,11 +462,12 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
461 u32 old_head; 462 u32 old_head;
462 u32 wqe_misc; 463 u32 wqe_misc;
463 464
464 /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," 465 /*
465 " (%u frags), tso_size=%u\n", 466 * nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u,"
466 netdev->name, skb->len, skb_headlen(skb), 467 * " (%u frags), tso_size=%u\n",
467 skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); 468 * netdev->name, skb->len, skb_headlen(skb),
468 */ 469 * skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
470 */
469 471
470 if (!netif_carrier_ok(netdev)) 472 if (!netif_carrier_ok(netdev))
471 return NETDEV_TX_OK; 473 return NETDEV_TX_OK;
@@ -795,12 +797,12 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
795 memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); 797 memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
796 printk(PFX "%s: Address length = %d, Address = %s\n", 798 printk(PFX "%s: Address length = %d, Address = %s\n",
797 __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data)); 799 __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data));
798 macaddr_high = ((u16)netdev->dev_addr[0]) << 8; 800 macaddr_high = ((u16)netdev->dev_addr[0]) << 8;
799 macaddr_high += (u16)netdev->dev_addr[1]; 801 macaddr_high += (u16)netdev->dev_addr[1];
800 macaddr_low = ((u32)netdev->dev_addr[2]) << 24; 802 macaddr_low = ((u32)netdev->dev_addr[2]) << 24;
801 macaddr_low += ((u32)netdev->dev_addr[3]) << 16; 803 macaddr_low += ((u32)netdev->dev_addr[3]) << 16;
802 macaddr_low += ((u32)netdev->dev_addr[4]) << 8; 804 macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
803 macaddr_low += (u32)netdev->dev_addr[5]; 805 macaddr_low += (u32)netdev->dev_addr[5];
804 806
805 for (i = 0; i < NES_MAX_PORT_COUNT; i++) { 807 for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
806 if (nesvnic->qp_nic_index[i] == 0xf) { 808 if (nesvnic->qp_nic_index[i] == 0xf) {
@@ -881,12 +883,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
881 print_mac(mac, multicast_addr->dmi_addr), 883 print_mac(mac, multicast_addr->dmi_addr),
882 perfect_filter_register_address+(mc_index * 8), 884 perfect_filter_register_address+(mc_index * 8),
883 mc_nic_index); 885 mc_nic_index);
884 macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; 886 macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8;
885 macaddr_high += (u16)multicast_addr->dmi_addr[1]; 887 macaddr_high += (u16)multicast_addr->dmi_addr[1];
886 macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; 888 macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24;
887 macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; 889 macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16;
888 macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; 890 macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8;
889 macaddr_low += (u32)multicast_addr->dmi_addr[5]; 891 macaddr_low += (u32)multicast_addr->dmi_addr[5];
890 nes_write_indexed(nesdev, 892 nes_write_indexed(nesdev,
891 perfect_filter_register_address+(mc_index * 8), 893 perfect_filter_register_address+(mc_index * 8),
892 macaddr_low); 894 macaddr_low);
@@ -910,23 +912,23 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
910/** 912/**
911 * nes_netdev_change_mtu 913 * nes_netdev_change_mtu
912 */ 914 */
913static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) 915static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
914{ 916{
915 struct nes_vnic *nesvnic = netdev_priv(netdev); 917 struct nes_vnic *nesvnic = netdev_priv(netdev);
916 struct nes_device *nesdev = nesvnic->nesdev; 918 struct nes_device *nesdev = nesvnic->nesdev;
917 int ret = 0; 919 int ret = 0;
918 u8 jumbomode=0; 920 u8 jumbomode = 0;
919 921
920 if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) 922 if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
921 return -EINVAL; 923 return -EINVAL;
922 924
923 netdev->mtu = new_mtu; 925 netdev->mtu = new_mtu;
924 nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; 926 nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN;
925 927
926 if (netdev->mtu > 1500) { 928 if (netdev->mtu > 1500) {
927 jumbomode=1; 929 jumbomode=1;
928 } 930 }
929 nes_nic_init_timer_defaults(nesdev, jumbomode); 931 nes_nic_init_timer_defaults(nesdev, jumbomode);
930 932
931 if (netif_running(netdev)) { 933 if (netif_running(netdev)) {
932 nes_netdev_stop(netdev); 934 nes_netdev_stop(netdev);
@@ -936,8 +938,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
936 return ret; 938 return ret;
937} 939}
938 940
939#define NES_ETHTOOL_STAT_COUNT 55 941static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
940static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = {
941 "Link Change Interrupts", 942 "Link Change Interrupts",
942 "Linearized SKBs", 943 "Linearized SKBs",
943 "T/GSO Requests", 944 "T/GSO Requests",
@@ -993,8 +994,12 @@ static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN]
993 "CQ Depth 32", 994 "CQ Depth 32",
994 "CQ Depth 128", 995 "CQ Depth 128",
995 "CQ Depth 256", 996 "CQ Depth 256",
997 "LRO aggregated",
998 "LRO flushed",
999 "LRO no_desc",
996}; 1000};
997 1001
1002#define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset)
998 1003
999/** 1004/**
1000 * nes_netdev_get_rx_csum 1005 * nes_netdev_get_rx_csum
@@ -1189,6 +1194,9 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
1189 target_stat_values[52] = int_mod_cq_depth_32; 1194 target_stat_values[52] = int_mod_cq_depth_32;
1190 target_stat_values[53] = int_mod_cq_depth_128; 1195 target_stat_values[53] = int_mod_cq_depth_128;
1191 target_stat_values[54] = int_mod_cq_depth_256; 1196 target_stat_values[54] = int_mod_cq_depth_256;
1197 target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated;
1198 target_stat_values[56] = nesvnic->lro_mgr.stats.flushed;
1199 target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc;
1192 1200
1193} 1201}
1194 1202
@@ -1219,14 +1227,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev,
1219 struct ethtool_coalesce *et_coalesce) 1227 struct ethtool_coalesce *et_coalesce)
1220{ 1228{
1221 struct nes_vnic *nesvnic = netdev_priv(netdev); 1229 struct nes_vnic *nesvnic = netdev_priv(netdev);
1222 struct nes_device *nesdev = nesvnic->nesdev; 1230 struct nes_device *nesdev = nesvnic->nesdev;
1223 struct nes_adapter *nesadapter = nesdev->nesadapter; 1231 struct nes_adapter *nesadapter = nesdev->nesadapter;
1224 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 1232 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
1225 unsigned long flags; 1233 unsigned long flags;
1226 1234
1227 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 1235 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
1228 if (et_coalesce->rx_max_coalesced_frames_low) { 1236 if (et_coalesce->rx_max_coalesced_frames_low) {
1229 shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; 1237 shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low;
1230 } 1238 }
1231 if (et_coalesce->rx_max_coalesced_frames_irq) { 1239 if (et_coalesce->rx_max_coalesced_frames_irq) {
1232 shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; 1240 shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq;
@@ -1246,14 +1254,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev,
1246 nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; 1254 nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq;
1247 if (et_coalesce->use_adaptive_rx_coalesce) { 1255 if (et_coalesce->use_adaptive_rx_coalesce) {
1248 nesadapter->et_use_adaptive_rx_coalesce = 1; 1256 nesadapter->et_use_adaptive_rx_coalesce = 1;
1249 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; 1257 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC;
1250 nesadapter->et_rx_coalesce_usecs_irq = 0; 1258 nesadapter->et_rx_coalesce_usecs_irq = 0;
1251 if (et_coalesce->pkt_rate_low) { 1259 if (et_coalesce->pkt_rate_low) {
1252 nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; 1260 nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low;
1253 } 1261 }
1254 } else { 1262 } else {
1255 nesadapter->et_use_adaptive_rx_coalesce = 0; 1263 nesadapter->et_use_adaptive_rx_coalesce = 0;
1256 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; 1264 nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT;
1257 if (nesadapter->et_rx_coalesce_usecs_irq) { 1265 if (nesadapter->et_rx_coalesce_usecs_irq) {
1258 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 1266 nes_write32(nesdev->regs+NES_PERIODIC_CONTROL,
1259 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); 1267 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8)));
@@ -1270,28 +1278,28 @@ static int nes_netdev_get_coalesce(struct net_device *netdev,
1270 struct ethtool_coalesce *et_coalesce) 1278 struct ethtool_coalesce *et_coalesce)
1271{ 1279{
1272 struct nes_vnic *nesvnic = netdev_priv(netdev); 1280 struct nes_vnic *nesvnic = netdev_priv(netdev);
1273 struct nes_device *nesdev = nesvnic->nesdev; 1281 struct nes_device *nesdev = nesvnic->nesdev;
1274 struct nes_adapter *nesadapter = nesdev->nesadapter; 1282 struct nes_adapter *nesadapter = nesdev->nesadapter;
1275 struct ethtool_coalesce temp_et_coalesce; 1283 struct ethtool_coalesce temp_et_coalesce;
1276 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 1284 struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
1277 unsigned long flags; 1285 unsigned long flags;
1278 1286
1279 memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); 1287 memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce));
1280 temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; 1288 temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq;
1281 temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; 1289 temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce;
1282 temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; 1290 temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval;
1283 temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; 1291 temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low;
1284 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 1292 spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
1285 temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; 1293 temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low;
1286 temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; 1294 temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target;
1287 temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; 1295 temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high;
1288 temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; 1296 temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min;
1289 temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; 1297 temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max;
1290 if (nesadapter->et_use_adaptive_rx_coalesce) { 1298 if (nesadapter->et_use_adaptive_rx_coalesce) {
1291 temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; 1299 temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use;
1292 } 1300 }
1293 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 1301 spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
1294 memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); 1302 memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce));
1295 return 0; 1303 return 0;
1296} 1304}
1297 1305
@@ -1370,30 +1378,38 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
1370 u16 phy_data; 1378 u16 phy_data;
1371 1379
1372 et_cmd->duplex = DUPLEX_FULL; 1380 et_cmd->duplex = DUPLEX_FULL;
1373 et_cmd->port = PORT_MII; 1381 et_cmd->port = PORT_MII;
1382
1374 if (nesadapter->OneG_Mode) { 1383 if (nesadapter->OneG_Mode) {
1375 et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg;
1376 et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg;
1377 et_cmd->speed = SPEED_1000; 1384 et_cmd->speed = SPEED_1000;
1378 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1385 if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
1379 &phy_data); 1386 et_cmd->supported = SUPPORTED_1000baseT_Full;
1380 if (phy_data&0x1000) { 1387 et_cmd->advertising = ADVERTISED_1000baseT_Full;
1381 et_cmd->autoneg = AUTONEG_ENABLE; 1388 et_cmd->autoneg = AUTONEG_DISABLE;
1389 et_cmd->transceiver = XCVR_INTERNAL;
1390 et_cmd->phy_address = nesdev->mac_index;
1382 } else { 1391 } else {
1383 et_cmd->autoneg = AUTONEG_DISABLE; 1392 et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
1393 et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
1394 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
1395 if (phy_data & 0x1000)
1396 et_cmd->autoneg = AUTONEG_ENABLE;
1397 else
1398 et_cmd->autoneg = AUTONEG_DISABLE;
1399 et_cmd->transceiver = XCVR_EXTERNAL;
1400 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
1384 } 1401 }
1385 et_cmd->transceiver = XCVR_EXTERNAL;
1386 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
1387 } else { 1402 } else {
1388 if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { 1403 if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
1404 (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
1389 et_cmd->transceiver = XCVR_EXTERNAL; 1405 et_cmd->transceiver = XCVR_EXTERNAL;
1390 et_cmd->port = PORT_FIBRE; 1406 et_cmd->port = PORT_FIBRE;
1391 et_cmd->supported = SUPPORTED_FIBRE; 1407 et_cmd->supported = SUPPORTED_FIBRE;
1392 et_cmd->advertising = ADVERTISED_FIBRE; 1408 et_cmd->advertising = ADVERTISED_FIBRE;
1393 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; 1409 et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
1394 } else { 1410 } else {
1395 et_cmd->transceiver = XCVR_INTERNAL; 1411 et_cmd->transceiver = XCVR_INTERNAL;
1396 et_cmd->supported = SUPPORTED_10000baseT_Full; 1412 et_cmd->supported = SUPPORTED_10000baseT_Full;
1397 et_cmd->advertising = ADVERTISED_10000baseT_Full; 1413 et_cmd->advertising = ADVERTISED_10000baseT_Full;
1398 et_cmd->phy_address = nesdev->mac_index; 1414 et_cmd->phy_address = nesdev->mac_index;
1399 } 1415 }
@@ -1416,14 +1432,15 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
1416 struct nes_adapter *nesadapter = nesdev->nesadapter; 1432 struct nes_adapter *nesadapter = nesdev->nesadapter;
1417 u16 phy_data; 1433 u16 phy_data;
1418 1434
1419 if (nesadapter->OneG_Mode) { 1435 if ((nesadapter->OneG_Mode) &&
1436 (nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) {
1420 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1437 nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
1421 &phy_data); 1438 &phy_data);
1422 if (et_cmd->autoneg) { 1439 if (et_cmd->autoneg) {
1423 /* Turn on Full duplex, Autoneg, and restart autonegotiation */ 1440 /* Turn on Full duplex, Autoneg, and restart autonegotiation */
1424 phy_data |= 0x1300; 1441 phy_data |= 0x1300;
1425 } else { 1442 } else {
1426 // Turn off autoneg 1443 /* Turn off autoneg */
1427 phy_data &= ~0x1000; 1444 phy_data &= ~0x1000;
1428 } 1445 }
1429 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1446 nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index],
@@ -1454,6 +1471,8 @@ static struct ethtool_ops nes_ethtool_ops = {
1454 .set_sg = ethtool_op_set_sg, 1471 .set_sg = ethtool_op_set_sg,
1455 .get_tso = ethtool_op_get_tso, 1472 .get_tso = ethtool_op_get_tso,
1456 .set_tso = ethtool_op_set_tso, 1473 .set_tso = ethtool_op_set_tso,
1474 .get_flags = ethtool_op_get_flags,
1475 .set_flags = ethtool_op_set_flags,
1457}; 1476};
1458 1477
1459 1478
@@ -1607,27 +1626,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1607 list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); 1626 list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
1608 1627
1609 if ((nesdev->netdev_count == 0) && 1628 if ((nesdev->netdev_count == 0) &&
1610 (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { 1629 ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) ||
1611 nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", 1630 ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) &&
1612 NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); 1631 (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
1632 ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
1633 /*
1634 * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n",
1635 * NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1)));
1636 */
1613 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1637 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1614 (0x200*(nesvnic->logical_port&1))); 1638 (0x200 * (nesdev->mac_index & 1)));
1615 u32temp |= 0x00200000; 1639 if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) {
1616 nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1640 u32temp |= 0x00200000;
1617 (0x200*(nesvnic->logical_port&1)), u32temp); 1641 nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1642 (0x200 * (nesdev->mac_index & 1)), u32temp);
1643 }
1644
1618 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1645 u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
1619 (0x200*(nesvnic->logical_port&1)) ); 1646 (0x200 * (nesdev->mac_index & 1)));
1647
1620 if ((u32temp&0x0f1f0000) == 0x0f0f0000) { 1648 if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
1621 if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { 1649 if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) {
1622 nes_init_phy(nesdev); 1650 nes_init_phy(nesdev);
1623 nes_read_10G_phy_reg(nesdev, 1, 1651 nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
1624 nesdev->nesadapter->phy_index[nesvnic->logical_port]);
1625 temp_phy_data = (u16)nes_read_indexed(nesdev, 1652 temp_phy_data = (u16)nes_read_indexed(nesdev,
1626 NES_IDX_MAC_MDIO_CONTROL); 1653 NES_IDX_MAC_MDIO_CONTROL);
1627 u32temp = 20; 1654 u32temp = 20;
1628 do { 1655 do {
1629 nes_read_10G_phy_reg(nesdev, 1, 1656 nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1);
1630 nesdev->nesadapter->phy_index[nesvnic->logical_port]);
1631 phy_data = (u16)nes_read_indexed(nesdev, 1657 phy_data = (u16)nes_read_indexed(nesdev,
1632 NES_IDX_MAC_MDIO_CONTROL); 1658 NES_IDX_MAC_MDIO_CONTROL);
1633 if ((phy_data == temp_phy_data) || (!(--u32temp))) 1659 if ((phy_data == temp_phy_data) || (!(--u32temp)))
@@ -1644,6 +1670,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
1644 nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); 1670 nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
1645 nesvnic->linkup = 1; 1671 nesvnic->linkup = 1;
1646 } 1672 }
1673 } else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
1674 nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n",
1675 nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn));
1676 if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) ||
1677 ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) {
1678 nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
1679 nesvnic->linkup = 1;
1680 }
1647 } 1681 }
1648 /* clear the MAC interrupt status, assumes direct logical to physical mapping */ 1682 /* clear the MAC interrupt status, assumes direct logical to physical mapping */
1649 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); 1683 u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index c6d5631a6995..fe83d1b2b177 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16
444/** 444/**
445 * nes_write_10G_phy_reg 445 * nes_write_10G_phy_reg
446 */ 446 */
447void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, 447void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg,
448 u8 phy_addr, u16 data) 448 u16 data)
449{ 449{
450 u32 dev_addr;
451 u32 port_addr; 450 u32 port_addr;
452 u32 u32temp; 451 u32 u32temp;
453 u32 counter; 452 u32 counter;
454 453
455 dev_addr = 1;
456 port_addr = phy_addr; 454 port_addr = phy_addr;
457 455
458 /* set address */ 456 /* set address */
@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
492 * This routine only issues the read, the data must be read 490 * This routine only issues the read, the data must be read
493 * separately. 491 * separately.
494 */ 492 */
495void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) 493void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg)
496{ 494{
497 u32 dev_addr;
498 u32 port_addr; 495 u32 port_addr;
499 u32 u32temp; 496 u32 u32temp;
500 u32 counter; 497 u32 counter;
501 498
502 dev_addr = 1;
503 port_addr = phy_addr; 499 port_addr = phy_addr;
504 500
505 /* set address */ 501 /* set address */
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 9ae397a0ff7e..99b3c4ae86eb 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1266,7 +1266,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
1266 sq_size = init_attr->cap.max_send_wr; 1266 sq_size = init_attr->cap.max_send_wr;
1267 rq_size = init_attr->cap.max_recv_wr; 1267 rq_size = init_attr->cap.max_recv_wr;
1268 1268
1269 // check if the encoded sizes are OK or not... 1269 /* check if the encoded sizes are OK or not... */
1270 sq_encoded_size = nes_get_encoded_size(&sq_size); 1270 sq_encoded_size = nes_get_encoded_size(&sq_size);
1271 rq_encoded_size = nes_get_encoded_size(&rq_size); 1271 rq_encoded_size = nes_get_encoded_size(&rq_size);
1272 1272
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index f1f142dc64b1..9044f8803532 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -95,6 +95,8 @@ enum {
95 IPOIB_MCAST_FLAG_SENDONLY = 1, 95 IPOIB_MCAST_FLAG_SENDONLY = 1,
96 IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ 96 IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */
97 IPOIB_MCAST_FLAG_ATTACHED = 3, 97 IPOIB_MCAST_FLAG_ATTACHED = 3,
98
99 MAX_SEND_CQE = 16,
98}; 100};
99 101
100#define IPOIB_OP_RECV (1ul << 31) 102#define IPOIB_OP_RECV (1ul << 31)
@@ -285,7 +287,8 @@ struct ipoib_dev_priv {
285 u16 pkey_index; 287 u16 pkey_index;
286 struct ib_pd *pd; 288 struct ib_pd *pd;
287 struct ib_mr *mr; 289 struct ib_mr *mr;
288 struct ib_cq *cq; 290 struct ib_cq *recv_cq;
291 struct ib_cq *send_cq;
289 struct ib_qp *qp; 292 struct ib_qp *qp;
290 u32 qkey; 293 u32 qkey;
291 294
@@ -305,6 +308,7 @@ struct ipoib_dev_priv {
305 struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; 308 struct ib_sge tx_sge[MAX_SKB_FRAGS + 1];
306 struct ib_send_wr tx_wr; 309 struct ib_send_wr tx_wr;
307 unsigned tx_outstanding; 310 unsigned tx_outstanding;
311 struct ib_wc send_wc[MAX_SEND_CQE];
308 312
309 struct ib_recv_wr rx_wr; 313 struct ib_recv_wr rx_wr;
310 struct ib_sge rx_sge[IPOIB_UD_RX_SG]; 314 struct ib_sge rx_sge[IPOIB_UD_RX_SG];
@@ -662,7 +666,6 @@ static inline int ipoib_register_debugfs(void) { return 0; }
662static inline void ipoib_unregister_debugfs(void) { } 666static inline void ipoib_unregister_debugfs(void) { }
663#endif 667#endif
664 668
665
666#define ipoib_printk(level, priv, format, arg...) \ 669#define ipoib_printk(level, priv, format, arg...) \
667 printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg) 670 printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg)
668#define ipoib_warn(priv, format, arg...) \ 671#define ipoib_warn(priv, format, arg...) \
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 9db7b0bd9134..97e67d36378f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -249,8 +249,8 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev,
249 struct ipoib_dev_priv *priv = netdev_priv(dev); 249 struct ipoib_dev_priv *priv = netdev_priv(dev);
250 struct ib_qp_init_attr attr = { 250 struct ib_qp_init_attr attr = {
251 .event_handler = ipoib_cm_rx_event_handler, 251 .event_handler = ipoib_cm_rx_event_handler,
252 .send_cq = priv->cq, /* For drain WR */ 252 .send_cq = priv->recv_cq, /* For drain WR */
253 .recv_cq = priv->cq, 253 .recv_cq = priv->recv_cq,
254 .srq = priv->cm.srq, 254 .srq = priv->cm.srq,
255 .cap.max_send_wr = 1, /* For drain WR */ 255 .cap.max_send_wr = 1, /* For drain WR */
256 .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */ 256 .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
@@ -951,8 +951,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
951{ 951{
952 struct ipoib_dev_priv *priv = netdev_priv(dev); 952 struct ipoib_dev_priv *priv = netdev_priv(dev);
953 struct ib_qp_init_attr attr = { 953 struct ib_qp_init_attr attr = {
954 .send_cq = priv->cq, 954 .send_cq = priv->recv_cq,
955 .recv_cq = priv->cq, 955 .recv_cq = priv->recv_cq,
956 .srq = priv->cm.srq, 956 .srq = priv->cm.srq,
957 .cap.max_send_wr = ipoib_sendq_size, 957 .cap.max_send_wr = ipoib_sendq_size,
958 .cap.max_send_sge = 1, 958 .cap.max_send_sge = 1,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index 9a47428366c9..10279b79c44d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -71,7 +71,7 @@ static int ipoib_set_coalesce(struct net_device *dev,
71 coal->rx_max_coalesced_frames > 0xffff) 71 coal->rx_max_coalesced_frames > 0xffff)
72 return -EINVAL; 72 return -EINVAL;
73 73
74 ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames, 74 ret = ib_modify_cq(priv->recv_cq, coal->rx_max_coalesced_frames,
75 coal->rx_coalesce_usecs); 75 coal->rx_coalesce_usecs);
76 if (ret && ret != -ENOSYS) { 76 if (ret && ret != -ENOSYS) {
77 ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); 77 ipoib_warn(priv, "failed modifying CQ (%d)\n", ret);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 7cf1fa7074ab..97b815c1a3fc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -364,7 +364,6 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
364 struct ipoib_dev_priv *priv = netdev_priv(dev); 364 struct ipoib_dev_priv *priv = netdev_priv(dev);
365 unsigned int wr_id = wc->wr_id; 365 unsigned int wr_id = wc->wr_id;
366 struct ipoib_tx_buf *tx_req; 366 struct ipoib_tx_buf *tx_req;
367 unsigned long flags;
368 367
369 ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", 368 ipoib_dbg_data(priv, "send completion: id %d, status: %d\n",
370 wr_id, wc->status); 369 wr_id, wc->status);
@@ -384,13 +383,11 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
384 383
385 dev_kfree_skb_any(tx_req->skb); 384 dev_kfree_skb_any(tx_req->skb);
386 385
387 spin_lock_irqsave(&priv->tx_lock, flags);
388 ++priv->tx_tail; 386 ++priv->tx_tail;
389 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && 387 if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
390 netif_queue_stopped(dev) && 388 netif_queue_stopped(dev) &&
391 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) 389 test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
392 netif_wake_queue(dev); 390 netif_wake_queue(dev);
393 spin_unlock_irqrestore(&priv->tx_lock, flags);
394 391
395 if (wc->status != IB_WC_SUCCESS && 392 if (wc->status != IB_WC_SUCCESS &&
396 wc->status != IB_WC_WR_FLUSH_ERR) 393 wc->status != IB_WC_WR_FLUSH_ERR)
@@ -399,6 +396,17 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
399 wc->status, wr_id, wc->vendor_err); 396 wc->status, wr_id, wc->vendor_err);
400} 397}
401 398
399static int poll_tx(struct ipoib_dev_priv *priv)
400{
401 int n, i;
402
403 n = ib_poll_cq(priv->send_cq, MAX_SEND_CQE, priv->send_wc);
404 for (i = 0; i < n; ++i)
405 ipoib_ib_handle_tx_wc(priv->dev, priv->send_wc + i);
406
407 return n == MAX_SEND_CQE;
408}
409
402int ipoib_poll(struct napi_struct *napi, int budget) 410int ipoib_poll(struct napi_struct *napi, int budget)
403{ 411{
404 struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); 412 struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi);
@@ -414,7 +422,7 @@ poll_more:
414 int max = (budget - done); 422 int max = (budget - done);
415 423
416 t = min(IPOIB_NUM_WC, max); 424 t = min(IPOIB_NUM_WC, max);
417 n = ib_poll_cq(priv->cq, t, priv->ibwc); 425 n = ib_poll_cq(priv->recv_cq, t, priv->ibwc);
418 426
419 for (i = 0; i < n; i++) { 427 for (i = 0; i < n; i++) {
420 struct ib_wc *wc = priv->ibwc + i; 428 struct ib_wc *wc = priv->ibwc + i;
@@ -425,12 +433,8 @@ poll_more:
425 ipoib_cm_handle_rx_wc(dev, wc); 433 ipoib_cm_handle_rx_wc(dev, wc);
426 else 434 else
427 ipoib_ib_handle_rx_wc(dev, wc); 435 ipoib_ib_handle_rx_wc(dev, wc);
428 } else { 436 } else
429 if (wc->wr_id & IPOIB_OP_CM) 437 ipoib_cm_handle_tx_wc(priv->dev, wc);
430 ipoib_cm_handle_tx_wc(dev, wc);
431 else
432 ipoib_ib_handle_tx_wc(dev, wc);
433 }
434 } 438 }
435 439
436 if (n != t) 440 if (n != t)
@@ -439,7 +443,7 @@ poll_more:
439 443
440 if (done < budget) { 444 if (done < budget) {
441 netif_rx_complete(dev, napi); 445 netif_rx_complete(dev, napi);
442 if (unlikely(ib_req_notify_cq(priv->cq, 446 if (unlikely(ib_req_notify_cq(priv->recv_cq,
443 IB_CQ_NEXT_COMP | 447 IB_CQ_NEXT_COMP |
444 IB_CQ_REPORT_MISSED_EVENTS)) && 448 IB_CQ_REPORT_MISSED_EVENTS)) &&
445 netif_rx_reschedule(dev, napi)) 449 netif_rx_reschedule(dev, napi))
@@ -562,12 +566,16 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
562 566
563 address->last_send = priv->tx_head; 567 address->last_send = priv->tx_head;
564 ++priv->tx_head; 568 ++priv->tx_head;
569 skb_orphan(skb);
565 570
566 if (++priv->tx_outstanding == ipoib_sendq_size) { 571 if (++priv->tx_outstanding == ipoib_sendq_size) {
567 ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); 572 ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
568 netif_stop_queue(dev); 573 netif_stop_queue(dev);
569 } 574 }
570 } 575 }
576
577 if (unlikely(priv->tx_outstanding > MAX_SEND_CQE))
578 poll_tx(priv);
571} 579}
572 580
573static void __ipoib_reap_ah(struct net_device *dev) 581static void __ipoib_reap_ah(struct net_device *dev)
@@ -714,7 +722,7 @@ void ipoib_drain_cq(struct net_device *dev)
714 struct ipoib_dev_priv *priv = netdev_priv(dev); 722 struct ipoib_dev_priv *priv = netdev_priv(dev);
715 int i, n; 723 int i, n;
716 do { 724 do {
717 n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); 725 n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc);
718 for (i = 0; i < n; ++i) { 726 for (i = 0; i < n; ++i) {
719 /* 727 /*
720 * Convert any successful completions to flush 728 * Convert any successful completions to flush
@@ -729,14 +737,13 @@ void ipoib_drain_cq(struct net_device *dev)
729 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); 737 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
730 else 738 else
731 ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); 739 ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
732 } else { 740 } else
733 if (priv->ibwc[i].wr_id & IPOIB_OP_CM) 741 ipoib_cm_handle_tx_wc(dev, priv->ibwc + i);
734 ipoib_cm_handle_tx_wc(dev, priv->ibwc + i);
735 else
736 ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
737 }
738 } 742 }
739 } while (n == IPOIB_NUM_WC); 743 } while (n == IPOIB_NUM_WC);
744
745 while (poll_tx(priv))
746 ; /* nothing */
740} 747}
741 748
742int ipoib_ib_dev_stop(struct net_device *dev, int flush) 749int ipoib_ib_dev_stop(struct net_device *dev, int flush)
@@ -826,7 +833,7 @@ timeout:
826 msleep(1); 833 msleep(1);
827 } 834 }
828 835
829 ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); 836 ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP);
830 837
831 return 0; 838 return 0;
832} 839}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 7a4ed9d3d844..2442090ac8d1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1298,7 +1298,8 @@ static int __init ipoib_init_module(void)
1298 1298
1299 ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); 1299 ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size);
1300 ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); 1300 ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE);
1301 ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); 1301 ipoib_sendq_size = max(ipoib_sendq_size, max(2 * MAX_SEND_CQE,
1302 IPOIB_MIN_QUEUE_SIZE));
1302#ifdef CONFIG_INFINIBAND_IPOIB_CM 1303#ifdef CONFIG_INFINIBAND_IPOIB_CM
1303 ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); 1304 ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
1304#endif 1305#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 07c03f178a49..c1e7ece1fd44 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -171,26 +171,33 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
171 goto out_free_pd; 171 goto out_free_pd;
172 } 172 }
173 173
174 size = ipoib_sendq_size + ipoib_recvq_size + 1; 174 size = ipoib_recvq_size + 1;
175 ret = ipoib_cm_dev_init(dev); 175 ret = ipoib_cm_dev_init(dev);
176 if (!ret) { 176 if (!ret) {
177 size += ipoib_sendq_size;
177 if (ipoib_cm_has_srq(dev)) 178 if (ipoib_cm_has_srq(dev))
178 size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ 179 size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */
179 else 180 else
180 size += ipoib_recvq_size * ipoib_max_conn_qp; 181 size += ipoib_recvq_size * ipoib_max_conn_qp;
181 } 182 }
182 183
183 priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); 184 priv->recv_cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0);
184 if (IS_ERR(priv->cq)) { 185 if (IS_ERR(priv->recv_cq)) {
185 printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); 186 printk(KERN_WARNING "%s: failed to create receive CQ\n", ca->name);
186 goto out_free_mr; 187 goto out_free_mr;
187 } 188 }
188 189
189 if (ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP)) 190 priv->send_cq = ib_create_cq(priv->ca, NULL, NULL, dev, ipoib_sendq_size, 0);
190 goto out_free_cq; 191 if (IS_ERR(priv->send_cq)) {
192 printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name);
193 goto out_free_recv_cq;
194 }
195
196 if (ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP))
197 goto out_free_send_cq;
191 198
192 init_attr.send_cq = priv->cq; 199 init_attr.send_cq = priv->send_cq;
193 init_attr.recv_cq = priv->cq; 200 init_attr.recv_cq = priv->recv_cq;
194 201
195 if (priv->hca_caps & IB_DEVICE_UD_TSO) 202 if (priv->hca_caps & IB_DEVICE_UD_TSO)
196 init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; 203 init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO;
@@ -201,7 +208,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
201 priv->qp = ib_create_qp(priv->pd, &init_attr); 208 priv->qp = ib_create_qp(priv->pd, &init_attr);
202 if (IS_ERR(priv->qp)) { 209 if (IS_ERR(priv->qp)) {
203 printk(KERN_WARNING "%s: failed to create QP\n", ca->name); 210 printk(KERN_WARNING "%s: failed to create QP\n", ca->name);
204 goto out_free_cq; 211 goto out_free_send_cq;
205 } 212 }
206 213
207 priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; 214 priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff;
@@ -230,8 +237,11 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
230 237
231 return 0; 238 return 0;
232 239
233out_free_cq: 240out_free_send_cq:
234 ib_destroy_cq(priv->cq); 241 ib_destroy_cq(priv->send_cq);
242
243out_free_recv_cq:
244 ib_destroy_cq(priv->recv_cq);
235 245
236out_free_mr: 246out_free_mr:
237 ib_dereg_mr(priv->mr); 247 ib_dereg_mr(priv->mr);
@@ -254,8 +264,11 @@ void ipoib_transport_dev_cleanup(struct net_device *dev)
254 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 264 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
255 } 265 }
256 266
257 if (ib_destroy_cq(priv->cq)) 267 if (ib_destroy_cq(priv->send_cq))
258 ipoib_warn(priv, "ib_cq_destroy failed\n"); 268 ipoib_warn(priv, "ib_cq_destroy (send) failed\n");
269
270 if (ib_destroy_cq(priv->recv_cq))
271 ipoib_warn(priv, "ib_cq_destroy (recv) failed\n");
259 272
260 ipoib_cm_dev_cleanup(dev); 273 ipoib_cm_dev_cleanup(dev);
261 274
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 431fdeaa2dc4..1cdb5cfb0ff1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -90,6 +90,9 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
90 } 90 }
91 91
92 priv->max_ib_mtu = ppriv->max_ib_mtu; 92 priv->max_ib_mtu = ppriv->max_ib_mtu;
93 /* MTU will be reset when mcast join happens */
94 priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);
95 priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;
93 set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); 96 set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
94 97
95 priv->pkey = pkey; 98 priv->pkey = pkey;
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index be1b9fbd416d..aeb58cae9a3f 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -473,13 +473,15 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s
473 stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ 473 stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */
474 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 474 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
475 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 475 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
476 stats->custom_length = 3; 476 stats->custom_length = 4;
477 strcpy(stats->custom[0].desc, "qp_tx_queue_full"); 477 strcpy(stats->custom[0].desc, "qp_tx_queue_full");
478 stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ 478 stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */
479 strcpy(stats->custom[1].desc, "fmr_map_not_avail"); 479 strcpy(stats->custom[1].desc, "fmr_map_not_avail");
480 stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; 480 stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */;
481 strcpy(stats->custom[2].desc, "eh_abort_cnt"); 481 strcpy(stats->custom[2].desc, "eh_abort_cnt");
482 stats->custom[2].value = conn->eh_abort_cnt; 482 stats->custom[2].value = conn->eh_abort_cnt;
483 strcpy(stats->custom[3].desc, "fmr_unalign_cnt");
484 stats->custom[3].value = conn->fmr_unalign_cnt;
483} 485}
484 486
485static int 487static int
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 1ee867b1b341..a8c1b300e34d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -71,6 +71,13 @@
71 71
72#define iser_dbg(fmt, arg...) \ 72#define iser_dbg(fmt, arg...) \
73 do { \ 73 do { \
74 if (iser_debug_level > 1) \
75 printk(KERN_DEBUG PFX "%s:" fmt,\
76 __func__ , ## arg); \
77 } while (0)
78
79#define iser_warn(fmt, arg...) \
80 do { \
74 if (iser_debug_level > 0) \ 81 if (iser_debug_level > 0) \
75 printk(KERN_DEBUG PFX "%s:" fmt,\ 82 printk(KERN_DEBUG PFX "%s:" fmt,\
76 __func__ , ## arg); \ 83 __func__ , ## arg); \
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 4a17743a639f..cac50c4dc159 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -334,8 +334,11 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
334 struct scatterlist *sg; 334 struct scatterlist *sg;
335 int i; 335 int i;
336 336
337 if (iser_debug_level == 0)
338 return;
339
337 for_each_sg(sgl, sg, data->dma_nents, i) 340 for_each_sg(sgl, sg, data->dma_nents, i)
338 iser_err("sg[%d] dma_addr:0x%lX page:0x%p " 341 iser_warn("sg[%d] dma_addr:0x%lX page:0x%p "
339 "off:0x%x sz:0x%x dma_len:0x%x\n", 342 "off:0x%x sz:0x%x dma_len:0x%x\n",
340 i, (unsigned long)ib_sg_dma_address(ibdev, sg), 343 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
341 sg_page(sg), sg->offset, 344 sg_page(sg), sg->offset,
@@ -420,6 +423,7 @@ void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
420int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, 423int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
421 enum iser_data_dir cmd_dir) 424 enum iser_data_dir cmd_dir)
422{ 425{
426 struct iscsi_conn *iscsi_conn = iser_ctask->iser_conn->iscsi_conn;
423 struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; 427 struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn;
424 struct iser_device *device = ib_conn->device; 428 struct iser_device *device = ib_conn->device;
425 struct ib_device *ibdev = device->ib_device; 429 struct ib_device *ibdev = device->ib_device;
@@ -434,7 +438,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
434 438
435 aligned_len = iser_data_buf_aligned_len(mem, ibdev); 439 aligned_len = iser_data_buf_aligned_len(mem, ibdev);
436 if (aligned_len != mem->dma_nents) { 440 if (aligned_len != mem->dma_nents) {
437 iser_err("rdma alignment violation %d/%d aligned\n", 441 iscsi_conn->fmr_unalign_cnt++;
442 iser_warn("rdma alignment violation %d/%d aligned\n",
438 aligned_len, mem->size); 443 aligned_len, mem->size);
439 iser_data_buf_dump(mem, ibdev); 444 iser_data_buf_dump(mem, ibdev);
440 445
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 128bb9cd5755..ddf57e135c6c 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -5,16 +5,20 @@
5menu "Multimedia devices" 5menu "Multimedia devices"
6 depends on HAS_IOMEM 6 depends on HAS_IOMEM
7 7
8comment "Multimedia core support"
9
10#
11# V4L core and enabled API's
12#
13
8config VIDEO_DEV 14config VIDEO_DEV
9 tristate "Video For Linux" 15 tristate "Video For Linux"
10 ---help--- 16 ---help---
11 Support for audio/video capture and overlay devices and FM radio 17 V4L core support for video capture and overlay devices, webcams and
12 cards. The exact capabilities of each device vary. 18 AM/FM radio cards.
13 19
14 This kernel includes support for the new Video for Linux Two API, 20 This kernel includes support for the new Video for Linux Two API,
15 (V4L2) as well as the original system. Drivers and applications 21 (V4L2).
16 need to be rewritten to use V4L2, but drivers for popular cards
17 and applications for most video capture functions already exist.
18 22
19 Additional info and docs are available on the web at 23 Additional info and docs are available on the web at
20 <http://linuxtv.org> 24 <http://linuxtv.org>
@@ -36,8 +40,11 @@ config VIDEO_ALLOW_V4L1
36 default VIDEO_DEV && VIDEO_V4L2_COMMON 40 default VIDEO_DEV && VIDEO_V4L2_COMMON
37 select VIDEO_V4L1_COMPAT 41 select VIDEO_V4L1_COMPAT
38 ---help--- 42 ---help---
39 Enables a compatibility API used by most V4L2 devices to allow 43 Enables drivers based on the legacy V4L1 API.
40 its usage with legacy applications that supports only V4L1 api. 44
45 This api were developed to be used at Kernel 2.2 and 2.4, but
46 lacks support for several video standards. There are several
47 drivers at kernel that still depends on it.
41 48
42 If you are unsure as to whether this is required, answer Y. 49 If you are unsure as to whether this is required, answer Y.
43 50
@@ -46,9 +53,8 @@ config VIDEO_V4L1_COMPAT
46 depends on VIDEO_DEV 53 depends on VIDEO_DEV
47 default VIDEO_DEV 54 default VIDEO_DEV
48 ---help--- 55 ---help---
49 This api were developed to be used at Kernel 2.2 and 2.4, but 56 Enables a compatibility API used by most V4L2 devices to allow
50 lacks support for several video standards. There are several 57 its usage with legacy applications that supports only V4L1 api.
51 drivers at kernel that still depends on it.
52 58
53 Documentation for the original API is included in the file 59 Documentation for the original API is included in the file
54 <Documentation/video4linux/API.html>. 60 <Documentation/video4linux/API.html>.
@@ -58,135 +64,57 @@ config VIDEO_V4L1_COMPAT
58 64
59 If you are unsure as to whether this is required, answer Y. 65 If you are unsure as to whether this is required, answer Y.
60 66
61config VIDEO_V4L2 67#
62 tristate 68# DVB Core
63 depends on VIDEO_DEV && VIDEO_V4L2_COMMON 69#
64 default VIDEO_DEV && VIDEO_V4L2_COMMON
65
66config VIDEO_V4L1
67 tristate
68 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
69 default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
70
71source "drivers/media/video/Kconfig"
72
73source "drivers/media/radio/Kconfig"
74
75source "drivers/media/dvb/Kconfig"
76
77source "drivers/media/common/Kconfig"
78 70
79config VIDEO_TUNER 71config DVB_CORE
80 tristate 72 tristate "DVB for Linux"
81 depends on I2C 73 depends on NET && INET
82 select TUNER_XC2028 if !VIDEO_TUNER_CUSTOMIZE 74 select CRC32
83 select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE
84 select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE
85 select TUNER_TEA5761 if !VIDEO_TUNER_CUSTOMIZE
86 select TUNER_TEA5767 if !VIDEO_TUNER_CUSTOMIZE
87 select TUNER_SIMPLE if !VIDEO_TUNER_CUSTOMIZE
88 select TUNER_TDA9887 if !VIDEO_TUNER_CUSTOMIZE
89
90menuconfig VIDEO_TUNER_CUSTOMIZE
91 bool "Customize analog tuner modules to build"
92 depends on VIDEO_TUNER
93 help 75 help
94 This allows the user to deselect tuner drivers unnecessary 76 DVB core utility functions for device handling, software fallbacks etc.
95 for their hardware from the build. Use this option with care
96 as deselecting tuner drivers which are in fact necessary will
97 result in V4L devices which cannot be tuned due to lack of
98 driver support
99 77
100 If unsure say N. 78 Enable this if you own a DVB/ATSC adapter and want to use it or if
101 79 you compile Linux for a digital SetTopBox.
102if VIDEO_TUNER_CUSTOMIZE
103
104config TUNER_XC2028
105 tristate "XCeive xc2028/xc3028 tuners"
106 depends on I2C && FW_LOADER
107 default m if VIDEO_TUNER_CUSTOMIZE
108 help
109 Say Y here to include support for the xc2028/xc3028 tuners.
110 80
111config TUNER_MT20XX 81 Say Y when you have a DVB or an ATSC card and want to use it.
112 tristate "Microtune 2032 / 2050 tuners"
113 depends on I2C
114 default m if VIDEO_TUNER_CUSTOMIZE
115 help
116 Say Y here to include support for the MT2032 / MT2050 tuner.
117
118config TUNER_TDA8290
119 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
120 depends on I2C
121 select DVB_TDA827X
122 select DVB_TDA18271
123 default m if VIDEO_TUNER_CUSTOMIZE
124 help
125 Say Y here to include support for Philips TDA8290+8275(a) tuner.
126 82
127config TUNER_TEA5761 83 API specs and user tools are available from <http://www.linuxtv.org/>.
128 tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
129 depends on I2C && EXPERIMENTAL
130 default m if VIDEO_TUNER_CUSTOMIZE
131 help
132 Say Y here to include support for the Philips TEA5761 radio tuner.
133 84
134config TUNER_TEA5767 85 Please report problems regarding this support to the LinuxDVB
135 tristate "TEA 5767 radio tuner" 86 mailing list.
136 depends on I2C
137 default m if VIDEO_TUNER_CUSTOMIZE
138 help
139 Say Y here to include support for the Philips TEA5767 radio tuner.
140 87
141config TUNER_SIMPLE 88 If unsure say N.
142 tristate "Simple tuner support"
143 depends on I2C
144 select TUNER_TDA9887
145 default m if VIDEO_TUNER_CUSTOMIZE
146 help
147 Say Y here to include support for various simple tuners.
148 89
149config TUNER_TDA9887 90config VIDEO_MEDIA
150 tristate "TDA 9885/6/7 analog IF demodulator" 91 tristate
151 depends on I2C 92 default DVB_CORE || VIDEO_DEV
152 default m if VIDEO_TUNER_CUSTOMIZE 93 depends on DVB_CORE || VIDEO_DEV
153 help
154 Say Y here to include support for Philips TDA9885/6/7
155 analog IF demodulator.
156 94
157endif # VIDEO_TUNER_CUSTOMIZE 95comment "Multimedia drivers"
158 96
159config VIDEOBUF_GEN 97source "drivers/media/common/Kconfig"
160 tristate
161 98
162config VIDEOBUF_DMA_SG 99#
163 depends on HAS_DMA 100# Tuner drivers for DVB and V4L
164 select VIDEOBUF_GEN 101#
165 tristate
166 102
167config VIDEOBUF_VMALLOC 103source "drivers/media/common/tuners/Kconfig"
168 select VIDEOBUF_GEN
169 tristate
170 104
171config VIDEOBUF_DVB 105#
172 tristate 106# Video/Radio/Hybrid adapters
173 select VIDEOBUF_GEN 107#
174 select VIDEOBUF_DMA_SG
175 108
176config VIDEO_BTCX 109source "drivers/media/video/Kconfig"
177 tristate
178 110
179config VIDEO_IR_I2C 111source "drivers/media/radio/Kconfig"
180 tristate
181 112
182config VIDEO_IR 113#
183 tristate 114# DVB adapters
184 depends on INPUT 115#
185 select VIDEO_IR_I2C if I2C
186 116
187config VIDEO_TVEEPROM 117source "drivers/media/dvb/Kconfig"
188 tristate
189 depends on I2C
190 118
191config DAB 119config DAB
192 boolean "DAB adapters" 120 boolean "DAB adapters"
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 7b8bb6949f5e..73f742c7e818 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,10 +2,10 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := common/ 5obj-$(CONFIG_VIDEO_MEDIA) += common/
6obj-y += video/ 6
7# Since hybrid devices are here, should be compiled if DVB and/or V4L
8obj-$(CONFIG_VIDEO_MEDIA) += video/
9
7obj-$(CONFIG_VIDEO_DEV) += radio/ 10obj-$(CONFIG_VIDEO_DEV) += radio/
8obj-$(CONFIG_DVB_CORE) += dvb/ 11obj-$(CONFIG_DVB_CORE) += dvb/
9ifeq ($(CONFIG_DVB_CORE),)
10 obj-$(CONFIG_VIDEO_TUNER) += dvb/frontends/
11endif
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
new file mode 100644
index 000000000000..7b379e1ce01b
--- /dev/null
+++ b/drivers/media/common/tuners/Kconfig
@@ -0,0 +1,146 @@
1config MEDIA_ATTACH
2 bool "Load and attach frontend driver modules as needed"
3 depends on DVB_CORE
4 depends on MODULES
5 help
6 Remove the static dependency of DVB card drivers on all
7 frontend modules for all possible card variants. Instead,
8 allow the card drivers to only load the frontend modules
9 they require. This saves several KBytes of memory.
10
11 Note: You will need module-init-tools v3.2 or later for this feature.
12
13 If unsure say Y.
14
15config MEDIA_TUNER
16 tristate
17 default DVB_CORE || VIDEO_DEV
18 depends on DVB_CORE || VIDEO_DEV
19 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
20 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
21 select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
22 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
23 select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
24 select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
25 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
26 select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
27
28menuconfig MEDIA_TUNER_CUSTOMIZE
29 bool "Customize analog and hybrid tuner modules to build"
30 depends on MEDIA_TUNER
31 help
32 This allows the user to deselect tuner drivers unnecessary
33 for their hardware from the build. Use this option with care
34 as deselecting tuner drivers which are in fact necessary will
35 result in V4L/DVB devices which cannot be tuned due to lack of
36 driver support
37
38 If unsure say N.
39
40if MEDIA_TUNER_CUSTOMIZE
41
42config MEDIA_TUNER_SIMPLE
43 tristate "Simple tuner support"
44 depends on I2C
45 select MEDIA_TUNER_TDA9887
46 default m if MEDIA_TUNER_CUSTOMIZE
47 help
48 Say Y here to include support for various simple tuners.
49
50config MEDIA_TUNER_TDA8290
51 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
52 depends on I2C
53 select MEDIA_TUNER_TDA827X
54 select MEDIA_TUNER_TDA18271
55 default m if MEDIA_TUNER_CUSTOMIZE
56 help
57 Say Y here to include support for Philips TDA8290+8275(a) tuner.
58
59config MEDIA_TUNER_TDA827X
60 tristate "Philips TDA827X silicon tuner"
61 depends on DVB_CORE && I2C
62 default m if DVB_FE_CUSTOMISE
63 help
64 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
65
66config MEDIA_TUNER_TDA18271
67 tristate "NXP TDA18271 silicon tuner"
68 depends on I2C
69 default m if DVB_FE_CUSTOMISE
70 help
71 A silicon tuner module. Say Y when you want to support this tuner.
72
73config MEDIA_TUNER_TDA9887
74 tristate "TDA 9885/6/7 analog IF demodulator"
75 depends on I2C
76 default m if MEDIA_TUNER_CUSTOMIZE
77 help
78 Say Y here to include support for Philips TDA9885/6/7
79 analog IF demodulator.
80
81config MEDIA_TUNER_TEA5761
82 tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
83 depends on I2C && EXPERIMENTAL
84 default m if MEDIA_TUNER_CUSTOMIZE
85 help
86 Say Y here to include support for the Philips TEA5761 radio tuner.
87
88config MEDIA_TUNER_TEA5767
89 tristate "TEA 5767 radio tuner"
90 depends on I2C
91 default m if MEDIA_TUNER_CUSTOMIZE
92 help
93 Say Y here to include support for the Philips TEA5767 radio tuner.
94
95config MEDIA_TUNER_MT20XX
96 tristate "Microtune 2032 / 2050 tuners"
97 depends on I2C
98 default m if MEDIA_TUNER_CUSTOMIZE
99 help
100 Say Y here to include support for the MT2032 / MT2050 tuner.
101
102config MEDIA_TUNER_MT2060
103 tristate "Microtune MT2060 silicon IF tuner"
104 depends on I2C
105 default m if DVB_FE_CUSTOMISE
106 help
107 A driver for the silicon IF tuner MT2060 from Microtune.
108
109config MEDIA_TUNER_MT2266
110 tristate "Microtune MT2266 silicon tuner"
111 depends on I2C
112 default m if DVB_FE_CUSTOMISE
113 help
114 A driver for the silicon baseband tuner MT2266 from Microtune.
115
116config MEDIA_TUNER_MT2131
117 tristate "Microtune MT2131 silicon tuner"
118 depends on I2C
119 default m if DVB_FE_CUSTOMISE
120 help
121 A driver for the silicon baseband tuner MT2131 from Microtune.
122
123config MEDIA_TUNER_QT1010
124 tristate "Quantek QT1010 silicon tuner"
125 depends on DVB_CORE && I2C
126 default m if DVB_FE_CUSTOMISE
127 help
128 A driver for the silicon tuner QT1010 from Quantek.
129
130config MEDIA_TUNER_XC2028
131 tristate "XCeive xc2028/xc3028 tuners"
132 depends on I2C && FW_LOADER
133 default m if MEDIA_TUNER_CUSTOMIZE
134 help
135 Say Y here to include support for the xc2028/xc3028 tuners.
136
137config MEDIA_TUNER_XC5000
138 tristate "Xceive XC5000 silicon tuner"
139 depends on I2C
140 default m if DVB_FE_CUSTOMISE
141 help
142 A driver for the silicon tuner XC5000 from Xceive.
143 This device is only used inside a SiP called togther with a
144 demodulator for now.
145
146endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
new file mode 100644
index 000000000000..236d9932fd92
--- /dev/null
+++ b/drivers/media/common/tuners/Makefile
@@ -0,0 +1,25 @@
1#
2# Makefile for common V4L/DVB tuners
3#
4
5tda18271-objs := tda18271-maps.o tda18271-common.o tda18271-fe.o
6
7obj-$(CONFIG_MEDIA_TUNER_XC2028) += tuner-xc2028.o
8obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-simple.o
9# tuner-types will be merged into tuner-simple, in the future
10obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-types.o
11obj-$(CONFIG_MEDIA_TUNER_MT20XX) += mt20xx.o
12obj-$(CONFIG_MEDIA_TUNER_TDA8290) += tda8290.o
13obj-$(CONFIG_MEDIA_TUNER_TEA5767) += tea5767.o
14obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o
15obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
16obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
17obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
18obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
19obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
20obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
21obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
22obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
23
24EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
25EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 1305b0e63ce5..1305b0e63ce5 100644
--- a/drivers/media/dvb/frontends/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/common/tuners/mt2060.h
index acba0058f519..cb60caffb6b6 100644
--- a/drivers/media/dvb/frontends/mt2060.h
+++ b/drivers/media/common/tuners/mt2060.h
@@ -30,7 +30,7 @@ struct mt2060_config {
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ 30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31}; 31};
32 32
33#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE)) 33#if defined(CONFIG_MEDIA_TUNER_MT2060) || (defined(CONFIG_MEDIA_TUNER_MT2060_MODULE) && defined(MODULE))
34extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); 34extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
35#else 35#else
36static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) 36static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
@@ -38,6 +38,6 @@ static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struc
38 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 38 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
39 return NULL; 39 return NULL;
40} 40}
41#endif // CONFIG_DVB_TUNER_MT2060 41#endif // CONFIG_MEDIA_TUNER_MT2060
42 42
43#endif 43#endif
diff --git a/drivers/media/dvb/frontends/mt2060_priv.h b/drivers/media/common/tuners/mt2060_priv.h
index 5eaccdefd0b0..5eaccdefd0b0 100644
--- a/drivers/media/dvb/frontends/mt2060_priv.h
+++ b/drivers/media/common/tuners/mt2060_priv.h
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index fbcb28233737..fbcb28233737 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/common/tuners/mt20xx.h
index aa848e14ce5e..259553a24903 100644
--- a/drivers/media/video/mt20xx.h
+++ b/drivers/media/common/tuners/mt20xx.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_MT20XX) || (defined(CONFIG_TUNER_MT20XX_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_MT20XX) || (defined(CONFIG_MEDIA_TUNER_MT20XX_MODULE) && defined(MODULE))
24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, 24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
25 struct i2c_adapter* i2c_adap, 25 struct i2c_adapter* i2c_adap,
26 u8 i2c_addr); 26 u8 i2c_addr);
diff --git a/drivers/media/dvb/frontends/mt2131.c b/drivers/media/common/tuners/mt2131.c
index e254bcfc2efb..e254bcfc2efb 100644
--- a/drivers/media/dvb/frontends/mt2131.c
+++ b/drivers/media/common/tuners/mt2131.c
diff --git a/drivers/media/dvb/frontends/mt2131.h b/drivers/media/common/tuners/mt2131.h
index 606d8576bc98..cd8376f6f7b4 100644
--- a/drivers/media/dvb/frontends/mt2131.h
+++ b/drivers/media/common/tuners/mt2131.h
@@ -30,7 +30,7 @@ struct mt2131_config {
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ 30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31}; 31};
32 32
33#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE)) 33#if defined(CONFIG_MEDIA_TUNER_MT2131) || (defined(CONFIG_MEDIA_TUNER_MT2131_MODULE) && defined(MODULE))
34extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe, 34extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c, 35 struct i2c_adapter *i2c,
36 struct mt2131_config *cfg, 36 struct mt2131_config *cfg,
@@ -44,7 +44,7 @@ static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL; 45 return NULL;
46} 46}
47#endif /* CONFIG_DVB_TUNER_MT2131 */ 47#endif /* CONFIG_MEDIA_TUNER_MT2131 */
48 48
49#endif /* __MT2131_H__ */ 49#endif /* __MT2131_H__ */
50 50
diff --git a/drivers/media/dvb/frontends/mt2131_priv.h b/drivers/media/common/tuners/mt2131_priv.h
index e930759c2c00..e930759c2c00 100644
--- a/drivers/media/dvb/frontends/mt2131_priv.h
+++ b/drivers/media/common/tuners/mt2131_priv.h
diff --git a/drivers/media/dvb/frontends/mt2266.c b/drivers/media/common/tuners/mt2266.c
index 54b18f94b14b..54b18f94b14b 100644
--- a/drivers/media/dvb/frontends/mt2266.c
+++ b/drivers/media/common/tuners/mt2266.c
diff --git a/drivers/media/dvb/frontends/mt2266.h b/drivers/media/common/tuners/mt2266.h
index c5113efe333c..4d083882d044 100644
--- a/drivers/media/dvb/frontends/mt2266.h
+++ b/drivers/media/common/tuners/mt2266.h
@@ -24,7 +24,7 @@ struct mt2266_config {
24 u8 i2c_address; 24 u8 i2c_address;
25}; 25};
26 26
27#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE)) 27#if defined(CONFIG_MEDIA_TUNER_MT2266) || (defined(CONFIG_MEDIA_TUNER_MT2266_MODULE) && defined(MODULE))
28extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg); 28extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
29#else 29#else
30static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg) 30static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
@@ -32,6 +32,6 @@ static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struc
32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
33 return NULL; 33 return NULL;
34} 34}
35#endif // CONFIG_DVB_TUNER_MT2266 35#endif // CONFIG_MEDIA_TUNER_MT2266
36 36
37#endif 37#endif
diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/common/tuners/qt1010.c
index 825aa1412e6f..825aa1412e6f 100644
--- a/drivers/media/dvb/frontends/qt1010.c
+++ b/drivers/media/common/tuners/qt1010.c
diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/common/tuners/qt1010.h
index cff6a7ca5380..807fb7b6146b 100644
--- a/drivers/media/dvb/frontends/qt1010.h
+++ b/drivers/media/common/tuners/qt1010.h
@@ -36,7 +36,7 @@ struct qt1010_config {
36 * @param cfg tuner hw based configuration 36 * @param cfg tuner hw based configuration
37 * @return fe pointer on success, NULL on failure 37 * @return fe pointer on success, NULL on failure
38 */ 38 */
39#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE)) 39#if defined(CONFIG_MEDIA_TUNER_QT1010) || (defined(CONFIG_MEDIA_TUNER_QT1010_MODULE) && defined(MODULE))
40extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, 40extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
41 struct i2c_adapter *i2c, 41 struct i2c_adapter *i2c,
42 struct qt1010_config *cfg); 42 struct qt1010_config *cfg);
@@ -48,6 +48,6 @@ static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL; 49 return NULL;
50} 50}
51#endif // CONFIG_DVB_TUNER_QT1010 51#endif // CONFIG_MEDIA_TUNER_QT1010
52 52
53#endif 53#endif
diff --git a/drivers/media/dvb/frontends/qt1010_priv.h b/drivers/media/common/tuners/qt1010_priv.h
index 090cf475f099..090cf475f099 100644
--- a/drivers/media/dvb/frontends/qt1010_priv.h
+++ b/drivers/media/common/tuners/qt1010_priv.h
diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index e27a7620a32f..e27a7620a32f 100644
--- a/drivers/media/dvb/frontends/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b262100ae897..b262100ae897 100644
--- a/drivers/media/dvb/frontends/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
diff --git a/drivers/media/dvb/frontends/tda18271-tables.c b/drivers/media/common/tuners/tda18271-maps.c
index 83e7561960c1..83e7561960c1 100644
--- a/drivers/media/dvb/frontends/tda18271-tables.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bc5eb368ea2..2bc5eb368ea2 100644
--- a/drivers/media/dvb/frontends/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 0e7af8d05a38..7db9831c0cb0 100644
--- a/drivers/media/dvb/frontends/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -81,7 +81,7 @@ struct tda18271_config {
81 unsigned int small_i2c:1; 81 unsigned int small_i2c:1;
82}; 82};
83 83
84#if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE)) 84#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
85extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, 85extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
86 struct i2c_adapter *i2c, 86 struct i2c_adapter *i2c,
87 struct tda18271_config *cfg); 87 struct tda18271_config *cfg);
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/common/tuners/tda827x.c
index d30d2c9094d9..d30d2c9094d9 100644
--- a/drivers/media/dvb/frontends/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/common/tuners/tda827x.h
index b73c23570dab..7850a9a1dc8f 100644
--- a/drivers/media/dvb/frontends/tda827x.h
+++ b/drivers/media/common/tuners/tda827x.h
@@ -51,7 +51,7 @@ struct tda827x_config
51 * @param cfg optional callback function pointers. 51 * @param cfg optional callback function pointers.
52 * @return FE pointer on success, NULL on failure. 52 * @return FE pointer on success, NULL on failure.
53 */ 53 */
54#if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE)) 54#if defined(CONFIG_MEDIA_TUNER_TDA827X) || (defined(CONFIG_MEDIA_TUNER_TDA827X_MODULE) && defined(MODULE))
55extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, 55extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
56 struct i2c_adapter *i2c, 56 struct i2c_adapter *i2c,
57 struct tda827x_config *cfg); 57 struct tda827x_config *cfg);
@@ -64,6 +64,6 @@ static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
64 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 64 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
65 return NULL; 65 return NULL;
66} 66}
67#endif // CONFIG_DVB_TDA827X 67#endif // CONFIG_MEDIA_TUNER_TDA827X
68 68
69#endif // __DVB_TDA827X_H__ 69#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/video/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 0ebb5b525e57..91204d3f282d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -578,16 +578,16 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
578 578
579 if ((data == 0x83) || (data == 0x84)) { 579 if ((data == 0x83) || (data == 0x84)) {
580 priv->ver |= TDA18271; 580 priv->ver |= TDA18271;
581 tda18271_attach(fe, priv->tda827x_addr, 581 dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
582 priv->i2c_props.adap, 582 priv->i2c_props.adap, &tda829x_tda18271_config);
583 &tda829x_tda18271_config);
584 } else { 583 } else {
585 if ((data & 0x3c) == 0) 584 if ((data & 0x3c) == 0)
586 priv->ver |= TDA8275; 585 priv->ver |= TDA8275;
587 else 586 else
588 priv->ver |= TDA8275A; 587 priv->ver |= TDA8275A;
589 588
590 tda827x_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg); 589 dvb_attach(tda827x_attach, fe, priv->tda827x_addr,
590 priv->i2c_props.adap, &priv->cfg);
591 priv->cfg.switch_addr = priv->i2c_props.addr; 591 priv->cfg.switch_addr = priv->i2c_props.addr;
592 } 592 }
593 if (fe->ops.tuner_ops.init) 593 if (fe->ops.tuner_ops.init)
diff --git a/drivers/media/video/tda8290.h b/drivers/media/common/tuners/tda8290.h
index d3bbf276a469..aa074f3f0c07 100644
--- a/drivers/media/video/tda8290.h
+++ b/drivers/media/common/tuners/tda8290.h
@@ -29,7 +29,7 @@ struct tda829x_config {
29#define TDA829X_DONT_PROBE 1 29#define TDA829X_DONT_PROBE 1
30}; 30};
31 31
32#if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE)) 32#if defined(CONFIG_MEDIA_TUNER_TDA8290) || (defined(CONFIG_MEDIA_TUNER_TDA8290_MODULE) && defined(MODULE))
33extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); 33extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
34 34
35extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, 35extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tda9887.c b/drivers/media/common/tuners/tda9887.c
index a0545ba957b0..a0545ba957b0 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
diff --git a/drivers/media/video/tda9887.h b/drivers/media/common/tuners/tda9887.h
index be49dcbfc70e..acc419e8c4fc 100644
--- a/drivers/media/video/tda9887.h
+++ b/drivers/media/common/tuners/tda9887.h
@@ -21,7 +21,7 @@
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23/* ------------------------------------------------------------------------ */ 23/* ------------------------------------------------------------------------ */
24#if defined(CONFIG_TUNER_TDA9887) || (defined(CONFIG_TUNER_TDA9887_MODULE) && defined(MODULE)) 24#if defined(CONFIG_MEDIA_TUNER_TDA9887) || (defined(CONFIG_MEDIA_TUNER_TDA9887_MODULE) && defined(MODULE))
25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, 25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
26 struct i2c_adapter *i2c_adap, 26 struct i2c_adapter *i2c_adap,
27 u8 i2c_addr); 27 u8 i2c_addr);
diff --git a/drivers/media/video/tea5761.c b/drivers/media/common/tuners/tea5761.c
index b93cdef9ac73..b93cdef9ac73 100644
--- a/drivers/media/video/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
diff --git a/drivers/media/video/tea5761.h b/drivers/media/common/tuners/tea5761.h
index 8eb62722b988..2e2ff82c95a4 100644
--- a/drivers/media/video/tea5761.h
+++ b/drivers/media/common/tuners/tea5761.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); 24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
25 25
26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, 26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tea5767.c b/drivers/media/common/tuners/tea5767.c
index f6e7d7ad8424..f6e7d7ad8424 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
diff --git a/drivers/media/video/tea5767.h b/drivers/media/common/tuners/tea5767.h
index 7b547c092e25..d30ab1b483de 100644
--- a/drivers/media/video/tea5767.h
+++ b/drivers/media/common/tuners/tea5767.h
@@ -39,7 +39,7 @@ struct tea5767_ctrl {
39 enum tea5767_xtal xtal_freq; 39 enum tea5767_xtal xtal_freq;
40}; 40};
41 41
42#if defined(CONFIG_TUNER_TEA5767) || (defined(CONFIG_TUNER_TEA5767_MODULE) && defined(MODULE)) 42#if defined(CONFIG_MEDIA_TUNER_TEA5767) || (defined(CONFIG_MEDIA_TUNER_TEA5767_MODULE) && defined(MODULE))
43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); 43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
44 44
45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, 45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h
index 3ad6c8e0b04c..3ad6c8e0b04c 100644
--- a/drivers/media/video/tuner-i2c.h
+++ b/drivers/media/common/tuners/tuner-i2c.h
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index be8d903171b7..be8d903171b7 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/common/tuners/tuner-simple.h
index e46cf0121e03..381fa5d35a9b 100644
--- a/drivers/media/video/tuner-simple.h
+++ b/drivers/media/common/tuners/tuner-simple.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_SIMPLE) || (defined(CONFIG_MEDIA_TUNER_SIMPLE_MODULE) && defined(MODULE))
24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, 24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
25 struct i2c_adapter *i2c_adap, 25 struct i2c_adapter *i2c_adap,
26 u8 i2c_addr, 26 u8 i2c_addr,
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 10dddca8b5d1..10dddca8b5d1 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
diff --git a/drivers/media/video/tuner-xc2028-types.h b/drivers/media/common/tuners/tuner-xc2028-types.h
index 74dc46a71f64..74dc46a71f64 100644
--- a/drivers/media/video/tuner-xc2028-types.h
+++ b/drivers/media/common/tuners/tuner-xc2028-types.h
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 9e9003cffc7f..9e9003cffc7f 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
diff --git a/drivers/media/video/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
index fc2f132a5541..216025cf5d4b 100644
--- a/drivers/media/video/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -47,7 +47,7 @@ struct xc2028_config {
47#define XC2028_TUNER_RESET 0 47#define XC2028_TUNER_RESET 0
48#define XC2028_RESET_CLK 1 48#define XC2028_RESET_CLK 1
49 49
50#if defined(CONFIG_TUNER_XC2028) || (defined(CONFIG_TUNER_XC2028_MODULE) && defined(MODULE)) 50#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
51extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, 51extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
52 struct xc2028_config *cfg); 52 struct xc2028_config *cfg);
53#else 53#else
diff --git a/drivers/media/dvb/frontends/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 43d35bdb221f..43d35bdb221f 100644
--- a/drivers/media/dvb/frontends/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/common/tuners/xc5000.h
index b890883a0cdc..0ee80f9d19b8 100644
--- a/drivers/media/dvb/frontends/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -45,8 +45,8 @@ struct xc5000_config {
45/* xc5000 callback command */ 45/* xc5000 callback command */
46#define XC5000_TUNER_RESET 0 46#define XC5000_TUNER_RESET 0
47 47
48#if defined(CONFIG_DVB_TUNER_XC5000) || \ 48#if defined(CONFIG_MEDIA_TUNER_XC5000) || \
49 (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE)) 49 (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
50extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, 50extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
51 struct i2c_adapter *i2c, 51 struct i2c_adapter *i2c,
52 struct xc5000_config *cfg); 52 struct xc5000_config *cfg);
@@ -58,6 +58,6 @@ static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
59 return NULL; 59 return NULL;
60} 60}
61#endif // CONFIG_DVB_TUNER_XC5000 61#endif // CONFIG_MEDIA_TUNER_XC5000
62 62
63#endif // __XC5000_H__ 63#endif // __XC5000_H__
diff --git a/drivers/media/dvb/frontends/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index 13b2d19341da..13b2d19341da 100644
--- a/drivers/media/dvb/frontends/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 03ef88acd9b8..7b21b49f1945 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -1,9 +1,7 @@
1# 1#
2# Multimedia device configuration 2# DVB device configuration
3# 3#
4 4
5source "drivers/media/dvb/dvb-core/Kconfig"
6
7menuconfig DVB_CAPTURE_DRIVERS 5menuconfig DVB_CAPTURE_DRIVERS
8 bool "DVB/ATSC adapters" 6 bool "DVB/ATSC adapters"
9 depends on DVB_CORE 7 depends on DVB_CORE
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 6ec5afba1ca7..73dc2ee9b014 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -9,7 +9,7 @@ config DVB_B2C2_FLEXCOP
9 select DVB_STV0297 if !DVB_FE_CUSTOMISE 9 select DVB_STV0297 if !DVB_FE_CUSTOMISE
10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE 10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE
11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
12 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 12 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
13 select DVB_S5H1420 if !DVB_FE_CUSTOMISE 13 select DVB_S5H1420 if !DVB_FE_CUSTOMISE
14 select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE 14 select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
15 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 15 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 870e2848c296..d9db066f9854 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -14,4 +14,4 @@ b2c2-flexcop-usb-objs = flexcop-usb.o
14obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o 14obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
15 15
16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
17EXTRA_CFLAGS += -Idrivers/media/video/ 17EXTRA_CFLAGS += -Idrivers/media/common/tuners/
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 902c762e0b7f..d1239b8342f8 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -8,7 +8,7 @@ config DVB_BT8XX
8 select DVB_OR51211 if !DVB_FE_CUSTOMISE 8 select DVB_OR51211 if !DVB_FE_CUSTOMISE
9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
10 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 10 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
11 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 11 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
12 select FW_LOADER 12 select FW_LOADER
13 help 13 help
14 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 14 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
index 9d3e68b5d6eb..d98f1d49ffa8 100644
--- a/drivers/media/dvb/bt8xx/Makefile
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -3,4 +3,4 @@ obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
5EXTRA_CFLAGS += -Idrivers/media/video/bt8xx 5EXTRA_CFLAGS += -Idrivers/media/video/bt8xx
6EXTRA_CFLAGS += -Idrivers/media/video 6EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 75711bde23ad..a7637562e742 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1714,7 +1714,7 @@ static void dst_release(struct dvb_frontend *fe)
1714 struct dst_state *state = fe->demodulator_priv; 1714 struct dst_state *state = fe->demodulator_priv;
1715 if (state->dst_ca) { 1715 if (state->dst_ca) {
1716 dvb_unregister_device(state->dst_ca); 1716 dvb_unregister_device(state->dst_ca);
1717#ifdef CONFIG_DVB_CORE_ATTACH 1717#ifdef CONFIG_MEDIA_ATTACH
1718 symbol_put(dst_ca_attach); 1718 symbol_put(dst_ca_attach);
1719#endif 1719#endif
1720 } 1720 }
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
deleted file mode 100644
index e3e6839f8073..000000000000
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
1config DVB_CORE
2 tristate "DVB for Linux"
3 depends on NET && INET
4 select CRC32
5 help
6 Support Digital Video Broadcasting hardware. Enable this if you
7 own a DVB adapter and want to use it or if you compile Linux for
8 a digital SetTopBox.
9
10 DVB core utility functions for device handling, software fallbacks etc.
11 Say Y when you have a DVB card and want to use it. Say Y if your want
12 to build your drivers outside the kernel, but need the DVB core. All
13 in-kernel drivers will select this automatically if needed.
14
15 API specs and user tools are available from <http://www.linuxtv.org/>.
16
17 Please report problems regarding this driver to the LinuxDVB
18 mailing list.
19
20 If unsure say N.
21
22config DVB_CORE_ATTACH
23 bool "Load and attach frontend modules as needed"
24 depends on DVB_CORE
25 depends on MODULES
26 help
27 Remove the static dependency of DVB card drivers on all
28 frontend modules for all possible card variants. Instead,
29 allow the card drivers to only load the frontend modules
30 they require. This saves several KBytes of memory.
31
32 Note: You will need module-init-tools v3.2 or later for this feature.
33
34 If unsure say Y.
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 2dddd08c5445..8cbdb218952f 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1189,7 +1189,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
1189} 1189}
1190EXPORT_SYMBOL(dvb_unregister_frontend); 1190EXPORT_SYMBOL(dvb_unregister_frontend);
1191 1191
1192#ifdef CONFIG_DVB_CORE_ATTACH 1192#ifdef CONFIG_MEDIA_ATTACH
1193void dvb_frontend_detach(struct dvb_frontend* fe) 1193void dvb_frontend_detach(struct dvb_frontend* fe)
1194{ 1194{
1195 void *ptr; 1195 void *ptr;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 5f9a737c6de1..89d12dc477a7 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -115,7 +115,7 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
115 unsigned int cmd, void *arg)); 115 unsigned int cmd, void *arg));
116 116
117/** generic DVB attach function. */ 117/** generic DVB attach function. */
118#ifdef CONFIG_DVB_CORE_ATTACH 118#ifdef CONFIG_MEDIA_ATTACH
119#define dvb_attach(FUNCTION, ARGS...) ({ \ 119#define dvb_attach(FUNCTION, ARGS...) ({ \
120 void *__r = NULL; \ 120 void *__r = NULL; \
121 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ 121 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 3c8493d2026d..4c1cff9feb2e 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -25,7 +25,7 @@ config DVB_USB_A800
25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" 25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
26 depends on DVB_USB 26 depends on DVB_USB
27 select DVB_DIB3000MC 27 select DVB_DIB3000MC
28 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 28 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
29 select DVB_PLL if !DVB_FE_CUSTOMISE 29 select DVB_PLL if !DVB_FE_CUSTOMISE
30 help 30 help
31 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. 31 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -35,7 +35,7 @@ config DVB_USB_DIBUSB_MB
35 depends on DVB_USB 35 depends on DVB_USB
36 select DVB_PLL if !DVB_FE_CUSTOMISE 36 select DVB_PLL if !DVB_FE_CUSTOMISE
37 select DVB_DIB3000MB 37 select DVB_DIB3000MB
38 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 38 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
39 help 39 help
40 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by 40 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
41 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. 41 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -56,7 +56,7 @@ config DVB_USB_DIBUSB_MC
56 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" 56 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
57 depends on DVB_USB 57 depends on DVB_USB
58 select DVB_DIB3000MC 58 select DVB_DIB3000MC
59 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 59 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
60 help 60 help
61 Support for USB2.0 DVB-T receivers based on reference designs made by 61 Support for USB2.0 DVB-T receivers based on reference designs made by
62 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. 62 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -73,8 +73,8 @@ config DVB_USB_DIB0700
73 select DVB_DIB7000P 73 select DVB_DIB7000P
74 select DVB_DIB7000M 74 select DVB_DIB7000M
75 select DVB_DIB3000MC 75 select DVB_DIB3000MC
76 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 76 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
77 select DVB_TUNER_MT2266 if !DVB_FE_CUSTOMISE 77 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
78 select DVB_TUNER_DIB0070 78 select DVB_TUNER_DIB0070
79 help 79 help
80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The 80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -93,7 +93,7 @@ config DVB_USB_UMT_010
93 depends on DVB_USB 93 depends on DVB_USB
94 select DVB_PLL if !DVB_FE_CUSTOMISE 94 select DVB_PLL if !DVB_FE_CUSTOMISE
95 select DVB_DIB3000MC 95 select DVB_DIB3000MC
96 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 96 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
97 help 97 help
98 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. 98 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
99 99
@@ -105,7 +105,7 @@ config DVB_USB_CXUSB
105 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 105 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
106 select DVB_MT352 if !DVB_FE_CUSTOMISE 106 select DVB_MT352 if !DVB_FE_CUSTOMISE
107 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 107 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
108 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 108 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
109 help 109 help
110 Say Y here to support the Conexant USB2.0 hybrid reference design. 110 Say Y here to support the Conexant USB2.0 hybrid reference design.
111 Currently, only DVB and ATSC modes are supported, analog mode 111 Currently, only DVB and ATSC modes are supported, analog mode
@@ -118,7 +118,7 @@ config DVB_USB_M920X
118 tristate "Uli m920x DVB-T USB2.0 support" 118 tristate "Uli m920x DVB-T USB2.0 support"
119 depends on DVB_USB 119 depends on DVB_USB
120 select DVB_MT352 if !DVB_FE_CUSTOMISE 120 select DVB_MT352 if !DVB_FE_CUSTOMISE
121 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 121 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
122 help 122 help
123 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. 123 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
124 Currently, only devices with a product id of 124 Currently, only devices with a product id of
@@ -129,7 +129,7 @@ config DVB_USB_GL861
129 tristate "Genesys Logic GL861 USB2.0 support" 129 tristate "Genesys Logic GL861 USB2.0 support"
130 depends on DVB_USB 130 depends on DVB_USB
131 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 131 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
132 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 132 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
133 help 133 help
134 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 134 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
135 receiver with USB ID 0db0:5581. 135 receiver with USB ID 0db0:5581.
@@ -138,7 +138,7 @@ config DVB_USB_AU6610
138 tristate "Alcor Micro AU6610 USB2.0 support" 138 tristate "Alcor Micro AU6610 USB2.0 support"
139 depends on DVB_USB 139 depends on DVB_USB
140 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 140 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
141 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 141 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
142 help 142 help
143 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. 143 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
144 144
@@ -190,7 +190,7 @@ config DVB_USB_NOVA_T_USB2
190 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" 190 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
191 depends on DVB_USB 191 depends on DVB_USB
192 select DVB_DIB3000MC 192 select DVB_DIB3000MC
193 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 193 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
194 select DVB_PLL if !DVB_FE_CUSTOMISE 194 select DVB_PLL if !DVB_FE_CUSTOMISE
195 help 195 help
196 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. 196 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
@@ -227,8 +227,8 @@ config DVB_USB_OPERA1
227config DVB_USB_AF9005 227config DVB_USB_AF9005
228 tristate "Afatech AF9005 DVB-T USB1.1 support" 228 tristate "Afatech AF9005 DVB-T USB1.1 support"
229 depends on DVB_USB && EXPERIMENTAL 229 depends on DVB_USB && EXPERIMENTAL
230 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 230 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
231 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 231 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
232 help 232 help
233 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver 233 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
234 and the TerraTec Cinergy T USB XE (Rev.1) 234 and the TerraTec Cinergy T USB XE (Rev.1)
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 60a910052c16..c6511a6c0ab8 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -63,5 +63,5 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
63 63
64EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 64EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
65# due to tuner-xc3028 65# due to tuner-xc3028
66EXTRA_CFLAGS += -Idrivers/media/video 66EXTRA_CFLAGS += -Idrivers/media/common/tuners
67 67
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index f5fceb3cdb3c..6d2384605927 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -15,22 +15,36 @@ config DVB_FE_CUSTOMISE
15comment "DVB-S (satellite) frontends" 15comment "DVB-S (satellite) frontends"
16 depends on DVB_CORE 16 depends on DVB_CORE
17 17
18config DVB_STV0299 18config DVB_CX24110
19 tristate "ST STV0299 based" 19 tristate "Conexant CX24110 based"
20 depends on DVB_CORE && I2C 20 depends on DVB_CORE && I2C
21 default m if DVB_FE_CUSTOMISE 21 default m if DVB_FE_CUSTOMISE
22 help 22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend. 23 A DVB-S tuner module. Say Y when you want to support this frontend.
24 24
25config DVB_CX24110 25config DVB_CX24123
26 tristate "Conexant CX24110 based" 26 tristate "Conexant CX24123 based"
27 depends on DVB_CORE && I2C 27 depends on DVB_CORE && I2C
28 default m if DVB_FE_CUSTOMISE 28 default m if DVB_FE_CUSTOMISE
29 help 29 help
30 A DVB-S tuner module. Say Y when you want to support this frontend. 30 A DVB-S tuner module. Say Y when you want to support this frontend.
31 31
32config DVB_CX24123 32config DVB_MT312
33 tristate "Conexant CX24123 based" 33 tristate "Zarlink VP310/MT312 based"
34 depends on DVB_CORE && I2C
35 default m if DVB_FE_CUSTOMISE
36 help
37 A DVB-S tuner module. Say Y when you want to support this frontend.
38
39config DVB_S5H1420
40 tristate "Samsung S5H1420 based"
41 depends on DVB_CORE && I2C
42 default m if DVB_FE_CUSTOMISE
43 help
44 A DVB-S tuner module. Say Y when you want to support this frontend.
45
46config DVB_STV0299
47 tristate "ST STV0299 based"
34 depends on DVB_CORE && I2C 48 depends on DVB_CORE && I2C
35 default m if DVB_FE_CUSTOMISE 49 default m if DVB_FE_CUSTOMISE
36 help 50 help
@@ -43,8 +57,8 @@ config DVB_TDA8083
43 help 57 help
44 A DVB-S tuner module. Say Y when you want to support this frontend. 58 A DVB-S tuner module. Say Y when you want to support this frontend.
45 59
46config DVB_MT312 60config DVB_TDA10086
47 tristate "Zarlink VP310/MT312 based" 61 tristate "Philips TDA10086 based"
48 depends on DVB_CORE && I2C 62 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE 63 default m if DVB_FE_CUSTOMISE
50 help 64 help
@@ -57,19 +71,26 @@ config DVB_VES1X93
57 help 71 help
58 A DVB-S tuner module. Say Y when you want to support this frontend. 72 A DVB-S tuner module. Say Y when you want to support this frontend.
59 73
60config DVB_S5H1420 74config DVB_TUNER_ITD1000
61 tristate "Samsung S5H1420 based" 75 tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
62 depends on DVB_CORE && I2C 76 depends on DVB_CORE && I2C
63 default m if DVB_FE_CUSTOMISE 77 default m if DVB_FE_CUSTOMISE
64 help 78 help
65 A DVB-S tuner module. Say Y when you want to support this frontend. 79 A DVB-S tuner module. Say Y when you want to support this frontend.
66 80
67config DVB_TDA10086 81config DVB_TDA826X
68 tristate "Philips TDA10086 based" 82 tristate "Philips TDA826X silicon tuner"
69 depends on DVB_CORE && I2C 83 depends on DVB_CORE && I2C
70 default m if DVB_FE_CUSTOMISE 84 default m if DVB_FE_CUSTOMISE
71 help 85 help
72 A DVB-S tuner module. Say Y when you want to support this frontend. 86 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
87
88config DVB_TUA6100
89 tristate "Infineon TUA6100 PLL"
90 depends on DVB_CORE && I2C
91 default m if DVB_FE_CUSTOMISE
92 help
93 A DVB-S PLL chip.
73 94
74comment "DVB-T (terrestrial) frontends" 95comment "DVB-T (terrestrial) frontends"
75 depends on DVB_CORE 96 depends on DVB_CORE
@@ -315,7 +336,7 @@ config DVB_S5H1411
315 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 336 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
316 to support this frontend. 337 to support this frontend.
317 338
318comment "Tuners/PLL support" 339comment "Digital terrestrial only tuners/PLL"
319 depends on DVB_CORE 340 depends on DVB_CORE
320 341
321config DVB_PLL 342config DVB_PLL
@@ -326,55 +347,6 @@ config DVB_PLL
326 This module drives a number of tuners based on PLL chips with a 347 This module drives a number of tuners based on PLL chips with a
327 common I2C interface. Say Y when you want to support these tuners. 348 common I2C interface. Say Y when you want to support these tuners.
328 349
329config DVB_TDA826X
330 tristate "Philips TDA826X silicon tuner"
331 depends on DVB_CORE && I2C
332 default m if DVB_FE_CUSTOMISE
333 help
334 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
335
336config DVB_TDA827X
337 tristate "Philips TDA827X silicon tuner"
338 depends on DVB_CORE && I2C
339 default m if DVB_FE_CUSTOMISE
340 help
341 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
342
343config DVB_TDA18271
344 tristate "NXP TDA18271 silicon tuner"
345 depends on I2C
346 default m if DVB_FE_CUSTOMISE
347 help
348 A silicon tuner module. Say Y when you want to support this tuner.
349
350config DVB_TUNER_QT1010
351 tristate "Quantek QT1010 silicon tuner"
352 depends on DVB_CORE && I2C
353 default m if DVB_FE_CUSTOMISE
354 help
355 A driver for the silicon tuner QT1010 from Quantek.
356
357config DVB_TUNER_MT2060
358 tristate "Microtune MT2060 silicon IF tuner"
359 depends on I2C
360 default m if DVB_FE_CUSTOMISE
361 help
362 A driver for the silicon IF tuner MT2060 from Microtune.
363
364config DVB_TUNER_MT2266
365 tristate "Microtune MT2266 silicon tuner"
366 depends on I2C
367 default m if DVB_FE_CUSTOMISE
368 help
369 A driver for the silicon baseband tuner MT2266 from Microtune.
370
371config DVB_TUNER_MT2131
372 tristate "Microtune MT2131 silicon tuner"
373 depends on I2C
374 default m if DVB_FE_CUSTOMISE
375 help
376 A driver for the silicon baseband tuner MT2131 from Microtune.
377
378config DVB_TUNER_DIB0070 350config DVB_TUNER_DIB0070
379 tristate "DiBcom DiB0070 silicon base-band tuner" 351 tristate "DiBcom DiB0070 silicon base-band tuner"
380 depends on I2C 352 depends on I2C
@@ -384,21 +356,7 @@ config DVB_TUNER_DIB0070
384 This device is only used inside a SiP called togther with a 356 This device is only used inside a SiP called togther with a
385 demodulator for now. 357 demodulator for now.
386 358
387config DVB_TUNER_XC5000 359comment "SEC control devices for DVB-S"
388 tristate "Xceive XC5000 silicon tuner"
389 depends on I2C
390 default m if DVB_FE_CUSTOMISE
391 help
392 A driver for the silicon tuner XC5000 from Xceive.
393 This device is only used inside a SiP called togther with a
394 demodulator for now.
395
396config DVB_TUNER_ITD1000
397 tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
398 depends on DVB_CORE && I2C
399 default m if DVB_FE_CUSTOMISE
400
401comment "Miscellaneous devices"
402 depends on DVB_CORE 360 depends on DVB_CORE
403 361
404config DVB_LNBP21 362config DVB_LNBP21
@@ -422,11 +380,4 @@ config DVB_ISL6421
422 help 380 help
423 An SEC control chip. 381 An SEC control chip.
424 382
425config DVB_TUA6100
426 tristate "TUA6100 PLL"
427 depends on DVB_CORE && I2C
428 default m if DVB_FE_CUSTOMISE
429 help
430 A DVBS PLL chip.
431
432endmenu 383endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 9747c73dc826..a89dc0fc4c6f 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -3,9 +3,7 @@
3# 3#
4 4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
6EXTRA_CFLAGS += -Idrivers/media/video/ 6EXTRA_CFLAGS += -Idrivers/media/common/tuners/
7
8tda18271-objs := tda18271-tables.o tda18271-common.o tda18271-fe.o
9 7
10obj-$(CONFIG_DVB_PLL) += dvb-pll.o 8obj-$(CONFIG_DVB_PLL) += dvb-pll.o
11obj-$(CONFIG_DVB_STV0299) += stv0299.o 9obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -42,16 +40,9 @@ obj-$(CONFIG_DVB_ISL6405) += isl6405.o
42obj-$(CONFIG_DVB_ISL6421) += isl6421.o 40obj-$(CONFIG_DVB_ISL6421) += isl6421.o
43obj-$(CONFIG_DVB_TDA10086) += tda10086.o 41obj-$(CONFIG_DVB_TDA10086) += tda10086.o
44obj-$(CONFIG_DVB_TDA826X) += tda826x.o 42obj-$(CONFIG_DVB_TDA826X) += tda826x.o
45obj-$(CONFIG_DVB_TDA827X) += tda827x.o
46obj-$(CONFIG_DVB_TDA18271) += tda18271.o
47obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
48obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
49obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o 43obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
50obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
51obj-$(CONFIG_DVB_TUA6100) += tua6100.o 44obj-$(CONFIG_DVB_TUA6100) += tua6100.o
52obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
53obj-$(CONFIG_DVB_S5H1409) += s5h1409.o 45obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
54obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
55obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o 46obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
56obj-$(CONFIG_DVB_AU8522) += au8522.o 47obj-$(CONFIG_DVB_AU8522) += au8522.o
57obj-$(CONFIG_DVB_TDA10048) += tda10048.o 48obj-$(CONFIG_DVB_TDA10048) += tda10048.o
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 281e1cb2edc6..720ed9ff7c5f 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -481,7 +481,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state,
481 val *= 2; 481 val *= 2;
482 do_div(val, (state->fclk / 1000)); 482 do_div(val, (state->fclk / 1000));
483 483
484 dprintk("symbol rate register: %06llx\n", val); 484 dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
485 485
486 v = s5h1420_readreg(state, Loop01); 486 v = s5h1420_readreg(state, Loop01);
487 s5h1420_writereg(state, Loop01, v & 0x7f); 487 s5h1420_writereg(state, Loop01, v & 0x7f);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fe9a4cc14141..fe743aa7f645 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1,4 +1,50 @@
1# 1#
2# Generic video config states
3#
4
5config VIDEO_V4L2
6 tristate
7 depends on VIDEO_DEV && VIDEO_V4L2_COMMON
8 default VIDEO_DEV && VIDEO_V4L2_COMMON
9
10config VIDEO_V4L1
11 tristate
12 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
13 default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
14
15config VIDEOBUF_GEN
16 tristate
17
18config VIDEOBUF_DMA_SG
19 depends on HAS_DMA
20 select VIDEOBUF_GEN
21 tristate
22
23config VIDEOBUF_VMALLOC
24 select VIDEOBUF_GEN
25 tristate
26
27config VIDEOBUF_DVB
28 tristate
29 select VIDEOBUF_GEN
30 select VIDEOBUF_DMA_SG
31
32config VIDEO_BTCX
33 tristate
34
35config VIDEO_IR_I2C
36 tristate
37
38config VIDEO_IR
39 tristate
40 depends on INPUT
41 select VIDEO_IR_I2C if I2C
42
43config VIDEO_TVEEPROM
44 tristate
45 depends on I2C
46
47#
2# Multimedia Video device configuration 48# Multimedia Video device configuration
3# 49#
4 50
@@ -644,7 +690,7 @@ config VIDEO_MXB
644 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 690 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
645 depends on PCI && VIDEO_V4L1 && I2C 691 depends on PCI && VIDEO_V4L1 && I2C
646 select VIDEO_SAA7146_VV 692 select VIDEO_SAA7146_VV
647 select VIDEO_TUNER 693 select MEDIA_TUNER
648 select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO 694 select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
649 select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO 695 select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
650 select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO 696 select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
@@ -702,6 +748,8 @@ source "drivers/media/video/au0828/Kconfig"
702 748
703source "drivers/media/video/ivtv/Kconfig" 749source "drivers/media/video/ivtv/Kconfig"
704 750
751source "drivers/media/video/cx18/Kconfig"
752
705config VIDEO_M32R_AR 753config VIDEO_M32R_AR
706 tristate "AR devices" 754 tristate "AR devices"
707 depends on M32R && VIDEO_V4L1 755 depends on M32R && VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index be14227f3726..a352c6e31f0c 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -84,17 +84,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
84obj-$(CONFIG_VIDEO_DPC) += dpc7146.o 84obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
85obj-$(CONFIG_TUNER_3036) += tuner-3036.o 85obj-$(CONFIG_TUNER_3036) += tuner-3036.o
86 86
87obj-$(CONFIG_VIDEO_TUNER) += tuner.o 87obj-$(CONFIG_MEDIA_TUNER) += tuner.o
88
89obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o
90obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o
91# tuner-types will be merged into tuner-simple, in the future
92obj-$(CONFIG_TUNER_SIMPLE) += tuner-types.o
93obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o
94obj-$(CONFIG_TUNER_TDA8290) += tda8290.o
95obj-$(CONFIG_TUNER_TEA5767) += tea5767.o
96obj-$(CONFIG_TUNER_TEA5761) += tea5761.o
97obj-$(CONFIG_TUNER_TDA9887) += tda9887.o
98 88
99obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o 89obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
100obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o 90obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
@@ -134,6 +124,7 @@ obj-$(CONFIG_USB_VICAM) += usbvideo/
134obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ 124obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
135 125
136obj-$(CONFIG_VIDEO_IVTV) += ivtv/ 126obj-$(CONFIG_VIDEO_IVTV) += ivtv/
127obj-$(CONFIG_VIDEO_CX18) += cx18/
137 128
138obj-$(CONFIG_VIDEO_VIVI) += vivi.o 129obj-$(CONFIG_VIDEO_VIVI) += vivi.o
139obj-$(CONFIG_VIDEO_CX23885) += cx23885/ 130obj-$(CONFIG_VIDEO_CX23885) += cx23885/
@@ -147,3 +138,4 @@ obj-$(CONFIG_VIDEO_AU0828) += au0828/
147 138
148EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 139EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
149EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 140EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
141EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 41708267e7a4..cab277fafa63 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -4,7 +4,7 @@ config VIDEO_AU0828
4 depends on VIDEO_DEV && I2C && INPUT && DVB_CORE 4 depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
5 select I2C_ALGOBIT 5 select I2C_ALGOBIT
6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE 6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE
7 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 7 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
8 ---help--- 8 ---help---
9 This is a video4linux driver for Auvitek's USB device. 9 This is a video4linux driver for Auvitek's USB device.
10 10
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index 9f4f572c89c5..cd2c58281b4e 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -2,7 +2,7 @@ au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
2 2
3obj-$(CONFIG_VIDEO_AU0828) += au0828.o 3obj-$(CONFIG_VIDEO_AU0828) += au0828.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/common/tuners
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
8 8
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index cfc822bb502a..7431ef6de9f1 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -6,7 +6,7 @@ config VIDEO_BT848
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEOBUF_DMA_SG 7 select VIDEOBUF_DMA_SG
8 select VIDEO_IR 8 select VIDEO_IR
9 select VIDEO_TUNER 9 select MEDIA_TUNER
10 select VIDEO_TVEEPROM 10 select VIDEO_TVEEPROM
11 select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO 11 select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
12 select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO 12 select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile
index 924d216d9570..e415f6fc447c 100644
--- a/drivers/media/video/bt8xx/Makefile
+++ b/drivers/media/video/bt8xx/Makefile
@@ -9,4 +9,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
9obj-$(CONFIG_VIDEO_BT848) += bttv.o 9obj-$(CONFIG_VIDEO_BT848) += bttv.o
10 10
11EXTRA_CFLAGS += -Idrivers/media/video 11EXTRA_CFLAGS += -Idrivers/media/video
12EXTRA_CFLAGS += -Idrivers/media/common/tuners
12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index fae469ce16f5..2a429f9e32cd 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -142,7 +142,8 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
142 142
143/* ----------------------------------------------------------------------- */ 143/* ----------------------------------------------------------------------- */
144 144
145static int cs5345_probe(struct i2c_client *client) 145static int cs5345_probe(struct i2c_client *client,
146 const struct i2c_device_id *id)
146{ 147{
147 /* Check if the adapter supports the needed features */ 148 /* Check if the adapter supports the needed features */
148 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 149 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index f41bfde045fe..2dfd0afc62db 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -135,7 +135,8 @@ static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
136 */ 136 */
137 137
138static int cs53l32a_probe(struct i2c_client *client) 138static int cs53l32a_probe(struct i2c_client *client,
139 const struct i2c_device_id *id)
139{ 140{
140 int i; 141 int i;
141 142
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
new file mode 100644
index 000000000000..be654a27bd3c
--- /dev/null
+++ b/drivers/media/video/cx18/Kconfig
@@ -0,0 +1,20 @@
1config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_IR
7 select VIDEO_TUNER
8 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X
10 select VIDEO_CS5345
11 select DVB_S5H1409
12 ---help---
13 This is a video4linux driver for Conexant cx23418 based
14 PCI combo video recorder devices.
15
16 This is used in devices such as the Hauppauge HVR-1600
17 cards.
18
19 To compile this driver as a module, choose M here: the
20 module will be called cx18.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
new file mode 100644
index 000000000000..b23d2e26120f
--- /dev/null
+++ b/drivers/media/video/cx18/Makefile
@@ -0,0 +1,11 @@
1cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o
6
7obj-$(CONFIG_VIDEO_CX18) += cx18.o
8
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
new file mode 100644
index 000000000000..1adc404d955e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -0,0 +1,73 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-i2c.h"
26#include "cx18-cards.h"
27#include "cx18-audio.h"
28
29/* Selects the audio input and output according to the current
30 settings. */
31int cx18_audio_set_io(struct cx18 *cx)
32{
33 struct v4l2_routing route;
34 u32 audio_input;
35 int mux_input;
36
37 /* Determine which input to use */
38 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
39 audio_input = cx->card->radio_input.audio_input;
40 mux_input = cx->card->radio_input.muxer_input;
41 } else {
42 audio_input =
43 cx->card->audio_inputs[cx->audio_input].audio_input;
44 mux_input =
45 cx->card->audio_inputs[cx->audio_input].muxer_input;
46 }
47
48 /* handle muxer chips */
49 route.input = mux_input;
50 route.output = 0;
51 cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
52
53 route.input = audio_input;
54 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
55 VIDIOC_INT_S_AUDIO_ROUTING, &route);
56}
57
58void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
59{
60 cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
61 VIDIOC_INT_S_AUDIO_ROUTING, route);
62}
63
64void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
65{
66 static u32 freqs[3] = { 44100, 48000, 32000 };
67
68 /* The audio clock of the digitizer must match the codec sample
69 rate otherwise you get some very strange effects. */
70 if (freq > 2)
71 return;
72 cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
73}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
new file mode 100644
index 000000000000..cb569a69379c
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.h
@@ -0,0 +1,26 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_audio_set_io(struct cx18 *cx);
25void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route);
26void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
new file mode 100644
index 000000000000..2dc3a5dd170e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -0,0 +1,361 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include "cx18-driver.h"
25
26static int set_audclk_freq(struct cx18 *cx, u32 freq)
27{
28 struct cx18_av_state *state = &cx->av_state;
29
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
33 /* common for all inputs and rates */
34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35 cx18_av_write(cx, 0x127, 0x50);
36
37 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
38 switch (freq) {
39 case 32000:
40 /* VID_PLL and AUX_PLL */
41 cx18_av_write4(cx, 0x108, 0x1006040f);
42
43 /* AUX_PLL_FRAC */
44 cx18_av_write4(cx, 0x110, 0x01bb39ee);
45
46 /* src3/4/6_ctl = 0x0801f77f */
47 cx18_av_write4(cx, 0x900, 0x0801f77f);
48 cx18_av_write4(cx, 0x904, 0x0801f77f);
49 cx18_av_write4(cx, 0x90c, 0x0801f77f);
50 break;
51
52 case 44100:
53 /* VID_PLL and AUX_PLL */
54 cx18_av_write4(cx, 0x108, 0x1009040f);
55
56 /* AUX_PLL_FRAC */
57 cx18_av_write4(cx, 0x110, 0x00ec6bd6);
58
59 /* src3/4/6_ctl = 0x08016d59 */
60 cx18_av_write4(cx, 0x900, 0x08016d59);
61 cx18_av_write4(cx, 0x904, 0x08016d59);
62 cx18_av_write4(cx, 0x90c, 0x08016d59);
63 break;
64
65 case 48000:
66 /* VID_PLL and AUX_PLL */
67 cx18_av_write4(cx, 0x108, 0x100a040f);
68
69 /* AUX_PLL_FRAC */
70 cx18_av_write4(cx, 0x110, 0x0098d6e5);
71
72 /* src3/4/6_ctl = 0x08014faa */
73 cx18_av_write4(cx, 0x900, 0x08014faa);
74 cx18_av_write4(cx, 0x904, 0x08014faa);
75 cx18_av_write4(cx, 0x90c, 0x08014faa);
76 break;
77 }
78 } else {
79 switch (freq) {
80 case 32000:
81 /* VID_PLL and AUX_PLL */
82 cx18_av_write4(cx, 0x108, 0x1e08040f);
83
84 /* AUX_PLL_FRAC */
85 cx18_av_write4(cx, 0x110, 0x012a0869);
86
87 /* src1_ctl = 0x08010000 */
88 cx18_av_write4(cx, 0x8f8, 0x08010000);
89
90 /* src3/4/6_ctl = 0x08020000 */
91 cx18_av_write4(cx, 0x900, 0x08020000);
92 cx18_av_write4(cx, 0x904, 0x08020000);
93 cx18_av_write4(cx, 0x90c, 0x08020000);
94
95 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
96 cx18_av_write(cx, 0x127, 0x54);
97 break;
98
99 case 44100:
100 /* VID_PLL and AUX_PLL */
101 cx18_av_write4(cx, 0x108, 0x1809040f);
102
103 /* AUX_PLL_FRAC */
104 cx18_av_write4(cx, 0x110, 0x00ec6bd6);
105
106 /* src1_ctl = 0x08010000 */
107 cx18_av_write4(cx, 0x8f8, 0x080160cd);
108
109 /* src3/4/6_ctl = 0x08020000 */
110 cx18_av_write4(cx, 0x900, 0x08017385);
111 cx18_av_write4(cx, 0x904, 0x08017385);
112 cx18_av_write4(cx, 0x90c, 0x08017385);
113 break;
114
115 case 48000:
116 /* VID_PLL and AUX_PLL */
117 cx18_av_write4(cx, 0x108, 0x180a040f);
118
119 /* AUX_PLL_FRAC */
120 cx18_av_write4(cx, 0x110, 0x0098d6e5);
121
122 /* src1_ctl = 0x08010000 */
123 cx18_av_write4(cx, 0x8f8, 0x08018000);
124
125 /* src3/4/6_ctl = 0x08020000 */
126 cx18_av_write4(cx, 0x900, 0x08015555);
127 cx18_av_write4(cx, 0x904, 0x08015555);
128 cx18_av_write4(cx, 0x90c, 0x08015555);
129 break;
130 }
131 }
132
133 state->audclk_freq = freq;
134
135 return 0;
136}
137
138void cx18_av_audio_set_path(struct cx18 *cx)
139{
140 struct cx18_av_state *state = &cx->av_state;
141
142 /* stop microcontroller */
143 cx18_av_and_or(cx, 0x803, ~0x10, 0);
144
145 /* assert soft reset */
146 cx18_av_and_or(cx, 0x810, ~0x1, 0x01);
147
148 /* Mute everything to prevent the PFFT! */
149 cx18_av_write(cx, 0x8d3, 0x1f);
150
151 if (state->aud_input == CX18_AV_AUDIO_SERIAL) {
152 /* Set Path1 to Serial Audio Input */
153 cx18_av_write4(cx, 0x8d0, 0x01011012);
154
155 /* The microcontroller should not be started for the
156 * non-tuner inputs: autodetection is specific for
157 * TV audio. */
158 } else {
159 /* Set Path1 to Analog Demod Main Channel */
160 cx18_av_write4(cx, 0x8d0, 0x1f063870);
161 }
162
163 set_audclk_freq(cx, state->audclk_freq);
164
165 /* deassert soft reset */
166 cx18_av_and_or(cx, 0x810, ~0x1, 0x00);
167
168 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
169 /* When the microcontroller detects the
170 * audio format, it will unmute the lines */
171 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
172 }
173}
174
175static int get_volume(struct cx18 *cx)
176{
177 /* Volume runs +18dB to -96dB in 1/2dB steps
178 * change to fit the msp3400 -114dB to +12dB range */
179
180 /* check PATH1_VOLUME */
181 int vol = 228 - cx18_av_read(cx, 0x8d4);
182 vol = (vol / 2) + 23;
183 return vol << 9;
184}
185
186static void set_volume(struct cx18 *cx, int volume)
187{
188 /* First convert the volume to msp3400 values (0-127) */
189 int vol = volume >> 9;
190 /* now scale it up to cx18_av values
191 * -114dB to -96dB maps to 0
192 * this should be 19, but in my testing that was 4dB too loud */
193 if (vol <= 23)
194 vol = 0;
195 else
196 vol -= 23;
197
198 /* PATH1_VOLUME */
199 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
200}
201
202static int get_bass(struct cx18 *cx)
203{
204 /* bass is 49 steps +12dB to -12dB */
205
206 /* check PATH1_EQ_BASS_VOL */
207 int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
208 bass = (((48 - bass) * 0xffff) + 47) / 48;
209 return bass;
210}
211
212static void set_bass(struct cx18 *cx, int bass)
213{
214 /* PATH1_EQ_BASS_VOL */
215 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
216}
217
218static int get_treble(struct cx18 *cx)
219{
220 /* treble is 49 steps +12dB to -12dB */
221
222 /* check PATH1_EQ_TREBLE_VOL */
223 int treble = cx18_av_read(cx, 0x8db) & 0x3f;
224 treble = (((48 - treble) * 0xffff) + 47) / 48;
225 return treble;
226}
227
228static void set_treble(struct cx18 *cx, int treble)
229{
230 /* PATH1_EQ_TREBLE_VOL */
231 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
232}
233
234static int get_balance(struct cx18 *cx)
235{
236 /* balance is 7 bit, 0 to -96dB */
237
238 /* check PATH1_BAL_LEVEL */
239 int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
240 /* check PATH1_BAL_LEFT */
241 if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
242 balance = 0x80 - balance;
243 else
244 balance = 0x80 + balance;
245 return balance << 8;
246}
247
248static void set_balance(struct cx18 *cx, int balance)
249{
250 int bal = balance >> 8;
251 if (bal > 0x80) {
252 /* PATH1_BAL_LEFT */
253 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
254 /* PATH1_BAL_LEVEL */
255 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
256 } else {
257 /* PATH1_BAL_LEFT */
258 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
259 /* PATH1_BAL_LEVEL */
260 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
261 }
262}
263
264static int get_mute(struct cx18 *cx)
265{
266 /* check SRC1_MUTE_EN */
267 return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
268}
269
270static void set_mute(struct cx18 *cx, int mute)
271{
272 struct cx18_av_state *state = &cx->av_state;
273
274 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
275 /* Must turn off microcontroller in order to mute sound.
276 * Not sure if this is the best method, but it does work.
277 * If the microcontroller is running, then it will undo any
278 * changes to the mute register. */
279 if (mute) {
280 /* disable microcontroller */
281 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
282 cx18_av_write(cx, 0x8d3, 0x1f);
283 } else {
284 /* enable microcontroller */
285 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
286 }
287 } else {
288 /* SRC1_MUTE_EN */
289 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
290 }
291}
292
293int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
294{
295 struct cx18_av_state *state = &cx->av_state;
296 struct v4l2_control *ctrl = arg;
297 int retval;
298
299 switch (cmd) {
300 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
301 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
302 cx18_av_and_or(cx, 0x803, ~0x10, 0);
303 cx18_av_write(cx, 0x8d3, 0x1f);
304 }
305 cx18_av_and_or(cx, 0x810, ~0x1, 1);
306 retval = set_audclk_freq(cx, *(u32 *)arg);
307 cx18_av_and_or(cx, 0x810, ~0x1, 0);
308 if (state->aud_input != CX18_AV_AUDIO_SERIAL)
309 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
310 return retval;
311
312 case VIDIOC_G_CTRL:
313 switch (ctrl->id) {
314 case V4L2_CID_AUDIO_VOLUME:
315 ctrl->value = get_volume(cx);
316 break;
317 case V4L2_CID_AUDIO_BASS:
318 ctrl->value = get_bass(cx);
319 break;
320 case V4L2_CID_AUDIO_TREBLE:
321 ctrl->value = get_treble(cx);
322 break;
323 case V4L2_CID_AUDIO_BALANCE:
324 ctrl->value = get_balance(cx);
325 break;
326 case V4L2_CID_AUDIO_MUTE:
327 ctrl->value = get_mute(cx);
328 break;
329 default:
330 return -EINVAL;
331 }
332 break;
333
334 case VIDIOC_S_CTRL:
335 switch (ctrl->id) {
336 case V4L2_CID_AUDIO_VOLUME:
337 set_volume(cx, ctrl->value);
338 break;
339 case V4L2_CID_AUDIO_BASS:
340 set_bass(cx, ctrl->value);
341 break;
342 case V4L2_CID_AUDIO_TREBLE:
343 set_treble(cx, ctrl->value);
344 break;
345 case V4L2_CID_AUDIO_BALANCE:
346 set_balance(cx, ctrl->value);
347 break;
348 case V4L2_CID_AUDIO_MUTE:
349 set_mute(cx, ctrl->value);
350 break;
351 default:
352 return -EINVAL;
353 }
354 break;
355
356 default:
357 return -EINVAL;
358 }
359
360 return 0;
361}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
new file mode 100644
index 000000000000..66864904c99b
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -0,0 +1,879 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-core.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include "cx18-driver.h"
25
26int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
27{
28 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
29 u32 mask = 0xff;
30 int shift = (addr & 3) * 8;
31
32 x = (x & ~(mask << shift)) | ((u32)value << shift);
33 writel(x, cx->reg_mem + 0xc40000 + (addr & ~3));
34 return 0;
35}
36
37int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
38{
39 writel(value, cx->reg_mem + 0xc40000 + addr);
40 return 0;
41}
42
43u8 cx18_av_read(struct cx18 *cx, u16 addr)
44{
45 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
46 int shift = (addr & 3) * 8;
47
48 return (x >> shift) & 0xff;
49}
50
51u32 cx18_av_read4(struct cx18 *cx, u16 addr)
52{
53 return readl(cx->reg_mem + 0xc40000 + addr);
54}
55
56int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
57 u8 or_value)
58{
59 return cx18_av_write(cx, addr,
60 (cx18_av_read(cx, addr) & and_mask) |
61 or_value);
62}
63
64int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
65 u32 or_value)
66{
67 return cx18_av_write4(cx, addr,
68 (cx18_av_read4(cx, addr) & and_mask) |
69 or_value);
70}
71
72/* ----------------------------------------------------------------------- */
73
74static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
75 enum cx18_av_audio_input aud_input);
76static void log_audio_status(struct cx18 *cx);
77static void log_video_status(struct cx18 *cx);
78
79/* ----------------------------------------------------------------------- */
80
81static void cx18_av_initialize(struct cx18 *cx)
82{
83 u32 v;
84
85 cx18_av_loadfw(cx);
86 /* Stop 8051 code execution */
87 cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000);
88
89 /* initallize the PLL by toggling sleep bit */
90 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
91 /* enable sleep mode */
92 cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1);
93 /* disable sleep mode */
94 cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe);
95
96 /* initialize DLLs */
97 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
98 /* disable FLD */
99 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
100 /* enable FLD */
101 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
102
103 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
104 /* disable FLD */
105 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
106 /* enable FLD */
107 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
108
109 /* set analog bias currents. Set Vreg to 1.20V. */
110 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
111
112 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
113 /* enable TUNE_FIL_RST */
114 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v);
115 /* disable TUNE_FIL_RST */
116 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE);
117
118 /* enable 656 output */
119 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
120
121 /* video output drive strength */
122 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
123
124 /* reset video */
125 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
126 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
127
128 /* set video to auto-detect */
129 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
130 /* set the comb notch = 1 */
131 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
132
133 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
134 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
135 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
136
137 /* Set VGA_TRACK_RANGE to 0x20 */
138 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
139
140 /* Enable VBI capture */
141 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
142 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
143
144 /* Set the video input.
145 The setting in MODE_CTRL gets lost when we do the above setup */
146 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
147 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
148
149 v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
150 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
151 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
152 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
153 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
154 cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
155
156/* if(dwEnable && dw3DCombAvailable) { */
157/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
158/* } else { */
159/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
160/* } */
161 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
162}
163
164/* ----------------------------------------------------------------------- */
165
166static void input_change(struct cx18 *cx)
167{
168 struct cx18_av_state *state = &cx->av_state;
169 v4l2_std_id std = state->std;
170
171 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
172 if (std & V4L2_STD_SECAM)
173 cx18_av_write(cx, 0x402, 0);
174 else {
175 cx18_av_write(cx, 0x402, 0x04);
176 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
177 }
178 cx18_av_and_or(cx, 0x401, ~0x60, 0);
179 cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
180
181 if (std & V4L2_STD_525_60) {
182 if (std == V4L2_STD_NTSC_M_JP) {
183 /* Japan uses EIAJ audio standard */
184 cx18_av_write(cx, 0x808, 0xf7);
185 } else if (std == V4L2_STD_NTSC_M_KR) {
186 /* South Korea uses A2 audio standard */
187 cx18_av_write(cx, 0x808, 0xf8);
188 } else {
189 /* Others use the BTSC audio standard */
190 cx18_av_write(cx, 0x808, 0xf6);
191 }
192 cx18_av_write(cx, 0x80b, 0x00);
193 } else if (std & V4L2_STD_PAL) {
194 /* Follow tuner change procedure for PAL */
195 cx18_av_write(cx, 0x808, 0xff);
196 cx18_av_write(cx, 0x80b, 0x03);
197 } else if (std & V4L2_STD_SECAM) {
198 /* Select autodetect for SECAM */
199 cx18_av_write(cx, 0x808, 0xff);
200 cx18_av_write(cx, 0x80b, 0x03);
201 }
202
203 if (cx18_av_read(cx, 0x803) & 0x10) {
204 /* restart audio decoder microcontroller */
205 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
206 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
207 }
208}
209
210static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
211 enum cx18_av_audio_input aud_input)
212{
213 struct cx18_av_state *state = &cx->av_state;
214 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
215 vid_input <= CX18_AV_COMPOSITE8);
216 u8 reg;
217
218 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
219 vid_input, aud_input);
220
221 if (is_composite) {
222 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
223 } else {
224 int luma = vid_input & 0xf0;
225 int chroma = vid_input & 0xf00;
226
227 if ((vid_input & ~0xff0) ||
228 luma < CX18_AV_SVIDEO_LUMA1 ||
229 luma > CX18_AV_SVIDEO_LUMA4 ||
230 chroma < CX18_AV_SVIDEO_CHROMA4 ||
231 chroma > CX18_AV_SVIDEO_CHROMA8) {
232 CX18_ERR("0x%04x is not a valid video input!\n",
233 vid_input);
234 return -EINVAL;
235 }
236 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
237 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
238 reg &= 0x3f;
239 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
240 } else {
241 reg &= 0xcf;
242 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
243 }
244 }
245
246 switch (aud_input) {
247 case CX18_AV_AUDIO_SERIAL:
248 /* do nothing, use serial audio input */
249 break;
250 case CX18_AV_AUDIO4: reg &= ~0x30; break;
251 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
252 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
253 case CX18_AV_AUDIO7: reg &= ~0xc0; break;
254 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
255
256 default:
257 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
258 return -EINVAL;
259 }
260
261 cx18_av_write(cx, 0x103, reg);
262 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
263 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
264 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
265 cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
266 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
267 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
268 cx18_av_and_or(cx, 0x102, ~0x4, 4);
269 else
270 cx18_av_and_or(cx, 0x102, ~0x4, 0);
271 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
272
273 state->vid_input = vid_input;
274 state->aud_input = aud_input;
275 cx18_av_audio_set_path(cx);
276 input_change(cx);
277 return 0;
278}
279
280/* ----------------------------------------------------------------------- */
281
282static int set_v4lstd(struct cx18 *cx)
283{
284 struct cx18_av_state *state = &cx->av_state;
285 u8 fmt = 0; /* zero is autodetect */
286 u8 pal_m = 0;
287
288 /* First tests should be against specific std */
289 if (state->std == V4L2_STD_NTSC_M_JP) {
290 fmt = 0x2;
291 } else if (state->std == V4L2_STD_NTSC_443) {
292 fmt = 0x3;
293 } else if (state->std == V4L2_STD_PAL_M) {
294 pal_m = 1;
295 fmt = 0x5;
296 } else if (state->std == V4L2_STD_PAL_N) {
297 fmt = 0x6;
298 } else if (state->std == V4L2_STD_PAL_Nc) {
299 fmt = 0x7;
300 } else if (state->std == V4L2_STD_PAL_60) {
301 fmt = 0x8;
302 } else {
303 /* Then, test against generic ones */
304 if (state->std & V4L2_STD_NTSC)
305 fmt = 0x1;
306 else if (state->std & V4L2_STD_PAL)
307 fmt = 0x4;
308 else if (state->std & V4L2_STD_SECAM)
309 fmt = 0xc;
310 }
311
312 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
313
314 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
315 Without this PAL may display a vertical ghosting effect.
316 This happens for example with the Yuan MPC622. */
317 if (fmt >= 4 && fmt < 8) {
318 /* Set format to NTSC-M */
319 cx18_av_and_or(cx, 0x400, ~0xf, 1);
320 /* Turn off LCOMB */
321 cx18_av_and_or(cx, 0x47b, ~6, 0);
322 }
323 cx18_av_and_or(cx, 0x400, ~0xf, fmt);
324 cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
325 cx18_av_vbi_setup(cx);
326 input_change(cx);
327 return 0;
328}
329
330/* ----------------------------------------------------------------------- */
331
332static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
333{
334 switch (ctrl->id) {
335 case V4L2_CID_BRIGHTNESS:
336 if (ctrl->value < 0 || ctrl->value > 255) {
337 CX18_ERR("invalid brightness setting %d\n",
338 ctrl->value);
339 return -ERANGE;
340 }
341
342 cx18_av_write(cx, 0x414, ctrl->value - 128);
343 break;
344
345 case V4L2_CID_CONTRAST:
346 if (ctrl->value < 0 || ctrl->value > 127) {
347 CX18_ERR("invalid contrast setting %d\n",
348 ctrl->value);
349 return -ERANGE;
350 }
351
352 cx18_av_write(cx, 0x415, ctrl->value << 1);
353 break;
354
355 case V4L2_CID_SATURATION:
356 if (ctrl->value < 0 || ctrl->value > 127) {
357 CX18_ERR("invalid saturation setting %d\n",
358 ctrl->value);
359 return -ERANGE;
360 }
361
362 cx18_av_write(cx, 0x420, ctrl->value << 1);
363 cx18_av_write(cx, 0x421, ctrl->value << 1);
364 break;
365
366 case V4L2_CID_HUE:
367 if (ctrl->value < -127 || ctrl->value > 127) {
368 CX18_ERR("invalid hue setting %d\n", ctrl->value);
369 return -ERANGE;
370 }
371
372 cx18_av_write(cx, 0x422, ctrl->value);
373 break;
374
375 case V4L2_CID_AUDIO_VOLUME:
376 case V4L2_CID_AUDIO_BASS:
377 case V4L2_CID_AUDIO_TREBLE:
378 case V4L2_CID_AUDIO_BALANCE:
379 case V4L2_CID_AUDIO_MUTE:
380 return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
381
382 default:
383 return -EINVAL;
384 }
385
386 return 0;
387}
388
389static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
390{
391 switch (ctrl->id) {
392 case V4L2_CID_BRIGHTNESS:
393 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
394 break;
395 case V4L2_CID_CONTRAST:
396 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
397 break;
398 case V4L2_CID_SATURATION:
399 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
400 break;
401 case V4L2_CID_HUE:
402 ctrl->value = (s8)cx18_av_read(cx, 0x422);
403 break;
404 case V4L2_CID_AUDIO_VOLUME:
405 case V4L2_CID_AUDIO_BASS:
406 case V4L2_CID_AUDIO_TREBLE:
407 case V4L2_CID_AUDIO_BALANCE:
408 case V4L2_CID_AUDIO_MUTE:
409 return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
410 default:
411 return -EINVAL;
412 }
413
414 return 0;
415}
416
417/* ----------------------------------------------------------------------- */
418
419static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
420{
421 switch (fmt->type) {
422 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
423 return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
424 default:
425 return -EINVAL;
426 }
427
428 return 0;
429}
430
431static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
432{
433 struct cx18_av_state *state = &cx->av_state;
434 struct v4l2_pix_format *pix;
435 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
436 int is_50Hz = !(state->std & V4L2_STD_525_60);
437
438 switch (fmt->type) {
439 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
440 pix = &(fmt->fmt.pix);
441
442 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
443 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
444
445 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
446 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
447
448 Vlines = pix->height + (is_50Hz ? 4 : 7);
449
450 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
451 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
452 CX18_ERR("%dx%d is not a valid size!\n",
453 pix->width, pix->height);
454 return -ERANGE;
455 }
456
457 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
458 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
459 VSC &= 0x1fff;
460
461 if (pix->width >= 385)
462 filter = 0;
463 else if (pix->width > 192)
464 filter = 1;
465 else if (pix->width > 96)
466 filter = 2;
467 else
468 filter = 3;
469
470 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
471 pix->width, pix->height, HSC, VSC);
472
473 /* HSCALE=HSC */
474 cx18_av_write(cx, 0x418, HSC & 0xff);
475 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
476 cx18_av_write(cx, 0x41a, HSC >> 16);
477 /* VSCALE=VSC */
478 cx18_av_write(cx, 0x41c, VSC & 0xff);
479 cx18_av_write(cx, 0x41d, VSC >> 8);
480 /* VS_INTRLACE=1 VFILT=filter */
481 cx18_av_write(cx, 0x41e, 0x8 | filter);
482 break;
483
484 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
485 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
486
487 case V4L2_BUF_TYPE_VBI_CAPTURE:
488 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
489
490 default:
491 return -EINVAL;
492 }
493
494 return 0;
495}
496
497/* ----------------------------------------------------------------------- */
498
499int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
500{
501 struct cx18_av_state *state = &cx->av_state;
502 struct v4l2_tuner *vt = arg;
503 struct v4l2_routing *route = arg;
504
505 /* ignore these commands */
506 switch (cmd) {
507 case TUNER_SET_TYPE_ADDR:
508 return 0;
509 }
510
511 if (!state->is_initialized) {
512 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
513 /* initialize on first use */
514 state->is_initialized = 1;
515 cx18_av_initialize(cx);
516 }
517
518 switch (cmd) {
519 case VIDIOC_INT_DECODE_VBI_LINE:
520 return cx18_av_vbi(cx, cmd, arg);
521
522 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
523 return cx18_av_audio(cx, cmd, arg);
524
525 case VIDIOC_STREAMON:
526 CX18_DEBUG_INFO("enable output\n");
527 cx18_av_write(cx, 0x115, 0x8c);
528 cx18_av_write(cx, 0x116, 0x07);
529 break;
530
531 case VIDIOC_STREAMOFF:
532 CX18_DEBUG_INFO("disable output\n");
533 cx18_av_write(cx, 0x115, 0x00);
534 cx18_av_write(cx, 0x116, 0x00);
535 break;
536
537 case VIDIOC_LOG_STATUS:
538 log_video_status(cx);
539 log_audio_status(cx);
540 break;
541
542 case VIDIOC_G_CTRL:
543 return get_v4lctrl(cx, (struct v4l2_control *)arg);
544
545 case VIDIOC_S_CTRL:
546 return set_v4lctrl(cx, (struct v4l2_control *)arg);
547
548 case VIDIOC_QUERYCTRL:
549 {
550 struct v4l2_queryctrl *qc = arg;
551
552 switch (qc->id) {
553 case V4L2_CID_BRIGHTNESS:
554 case V4L2_CID_CONTRAST:
555 case V4L2_CID_SATURATION:
556 case V4L2_CID_HUE:
557 return v4l2_ctrl_query_fill_std(qc);
558 default:
559 break;
560 }
561
562 switch (qc->id) {
563 case V4L2_CID_AUDIO_VOLUME:
564 case V4L2_CID_AUDIO_MUTE:
565 case V4L2_CID_AUDIO_BALANCE:
566 case V4L2_CID_AUDIO_BASS:
567 case V4L2_CID_AUDIO_TREBLE:
568 return v4l2_ctrl_query_fill_std(qc);
569 default:
570 return -EINVAL;
571 }
572 return -EINVAL;
573 }
574
575 case VIDIOC_G_STD:
576 *(v4l2_std_id *)arg = state->std;
577 break;
578
579 case VIDIOC_S_STD:
580 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
581 return 0;
582 state->radio = 0;
583 state->std = *(v4l2_std_id *)arg;
584 return set_v4lstd(cx);
585
586 case AUDC_SET_RADIO:
587 state->radio = 1;
588 break;
589
590 case VIDIOC_INT_G_VIDEO_ROUTING:
591 route->input = state->vid_input;
592 route->output = 0;
593 break;
594
595 case VIDIOC_INT_S_VIDEO_ROUTING:
596 return set_input(cx, route->input, state->aud_input);
597
598 case VIDIOC_INT_G_AUDIO_ROUTING:
599 route->input = state->aud_input;
600 route->output = 0;
601 break;
602
603 case VIDIOC_INT_S_AUDIO_ROUTING:
604 return set_input(cx, state->vid_input, route->input);
605
606 case VIDIOC_S_FREQUENCY:
607 input_change(cx);
608 break;
609
610 case VIDIOC_G_TUNER:
611 {
612 u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
613 u8 mode;
614 int val = 0;
615
616 if (state->radio)
617 break;
618
619 vt->signal = vpres ? 0xffff : 0x0;
620
621 vt->capability |=
622 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
623 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
624
625 mode = cx18_av_read(cx, 0x804);
626
627 /* get rxsubchans and audmode */
628 if ((mode & 0xf) == 1)
629 val |= V4L2_TUNER_SUB_STEREO;
630 else
631 val |= V4L2_TUNER_SUB_MONO;
632
633 if (mode == 2 || mode == 4)
634 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
635
636 if (mode & 0x10)
637 val |= V4L2_TUNER_SUB_SAP;
638
639 vt->rxsubchans = val;
640 vt->audmode = state->audmode;
641 break;
642 }
643
644 case VIDIOC_S_TUNER:
645 if (state->radio)
646 break;
647
648 switch (vt->audmode) {
649 case V4L2_TUNER_MODE_MONO:
650 /* mono -> mono
651 stereo -> mono
652 bilingual -> lang1 */
653 cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
654 break;
655 case V4L2_TUNER_MODE_STEREO:
656 case V4L2_TUNER_MODE_LANG1:
657 /* mono -> mono
658 stereo -> stereo
659 bilingual -> lang1 */
660 cx18_av_and_or(cx, 0x809, ~0xf, 0x04);
661 break;
662 case V4L2_TUNER_MODE_LANG1_LANG2:
663 /* mono -> mono
664 stereo -> stereo
665 bilingual -> lang1/lang2 */
666 cx18_av_and_or(cx, 0x809, ~0xf, 0x07);
667 break;
668 case V4L2_TUNER_MODE_LANG2:
669 /* mono -> mono
670 stereo -> stereo
671 bilingual -> lang2 */
672 cx18_av_and_or(cx, 0x809, ~0xf, 0x01);
673 break;
674 default:
675 return -EINVAL;
676 }
677 state->audmode = vt->audmode;
678 break;
679
680 case VIDIOC_G_FMT:
681 return get_v4lfmt(cx, (struct v4l2_format *)arg);
682
683 case VIDIOC_S_FMT:
684 return set_v4lfmt(cx, (struct v4l2_format *)arg);
685
686 case VIDIOC_INT_RESET:
687 cx18_av_initialize(cx);
688 break;
689
690 default:
691 return -EINVAL;
692 }
693
694 return 0;
695}
696
697/* ----------------------------------------------------------------------- */
698
699/* ----------------------------------------------------------------------- */
700
701static void log_video_status(struct cx18 *cx)
702{
703 static const char *const fmt_strs[] = {
704 "0x0",
705 "NTSC-M", "NTSC-J", "NTSC-4.43",
706 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
707 "0x9", "0xA", "0xB",
708 "SECAM",
709 "0xD", "0xE", "0xF"
710 };
711
712 struct cx18_av_state *state = &cx->av_state;
713 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
714 u8 gen_stat1 = cx18_av_read(cx, 0x40d);
715 u8 gen_stat2 = cx18_av_read(cx, 0x40e);
716 int vid_input = state->vid_input;
717
718 CX18_INFO("Video signal: %spresent\n",
719 (gen_stat2 & 0x20) ? "" : "not ");
720 CX18_INFO("Detected format: %s\n",
721 fmt_strs[gen_stat1 & 0xf]);
722
723 CX18_INFO("Specified standard: %s\n",
724 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
725
726 if (vid_input >= CX18_AV_COMPOSITE1 &&
727 vid_input <= CX18_AV_COMPOSITE8) {
728 CX18_INFO("Specified video input: Composite %d\n",
729 vid_input - CX18_AV_COMPOSITE1 + 1);
730 } else {
731 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
732 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
733 }
734
735 CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
736}
737
738/* ----------------------------------------------------------------------- */
739
740static void log_audio_status(struct cx18 *cx)
741{
742 struct cx18_av_state *state = &cx->av_state;
743 u8 download_ctl = cx18_av_read(cx, 0x803);
744 u8 mod_det_stat0 = cx18_av_read(cx, 0x805);
745 u8 mod_det_stat1 = cx18_av_read(cx, 0x804);
746 u8 audio_config = cx18_av_read(cx, 0x808);
747 u8 pref_mode = cx18_av_read(cx, 0x809);
748 u8 afc0 = cx18_av_read(cx, 0x80b);
749 u8 mute_ctl = cx18_av_read(cx, 0x8d3);
750 int aud_input = state->aud_input;
751 char *p;
752
753 switch (mod_det_stat0) {
754 case 0x00: p = "mono"; break;
755 case 0x01: p = "stereo"; break;
756 case 0x02: p = "dual"; break;
757 case 0x04: p = "tri"; break;
758 case 0x10: p = "mono with SAP"; break;
759 case 0x11: p = "stereo with SAP"; break;
760 case 0x12: p = "dual with SAP"; break;
761 case 0x14: p = "tri with SAP"; break;
762 case 0xfe: p = "forced mode"; break;
763 default: p = "not defined";
764 }
765 CX18_INFO("Detected audio mode: %s\n", p);
766
767 switch (mod_det_stat1) {
768 case 0x00: p = "BTSC"; break;
769 case 0x01: p = "EIAJ"; break;
770 case 0x02: p = "A2-M"; break;
771 case 0x03: p = "A2-BG"; break;
772 case 0x04: p = "A2-DK1"; break;
773 case 0x05: p = "A2-DK2"; break;
774 case 0x06: p = "A2-DK3"; break;
775 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
776 case 0x08: p = "AM-L"; break;
777 case 0x09: p = "NICAM-BG"; break;
778 case 0x0a: p = "NICAM-DK"; break;
779 case 0x0b: p = "NICAM-I"; break;
780 case 0x0c: p = "NICAM-L"; break;
781 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
782 case 0xff: p = "no detected audio standard"; break;
783 default: p = "not defined";
784 }
785 CX18_INFO("Detected audio standard: %s\n", p);
786 CX18_INFO("Audio muted: %s\n",
787 (mute_ctl & 0x2) ? "yes" : "no");
788 CX18_INFO("Audio microcontroller: %s\n",
789 (download_ctl & 0x10) ? "running" : "stopped");
790
791 switch (audio_config >> 4) {
792 case 0x00: p = "BTSC"; break;
793 case 0x01: p = "EIAJ"; break;
794 case 0x02: p = "A2-M"; break;
795 case 0x03: p = "A2-BG"; break;
796 case 0x04: p = "A2-DK1"; break;
797 case 0x05: p = "A2-DK2"; break;
798 case 0x06: p = "A2-DK3"; break;
799 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
800 case 0x08: p = "AM-L"; break;
801 case 0x09: p = "NICAM-BG"; break;
802 case 0x0a: p = "NICAM-DK"; break;
803 case 0x0b: p = "NICAM-I"; break;
804 case 0x0c: p = "NICAM-L"; break;
805 case 0x0d: p = "FM radio"; break;
806 case 0x0f: p = "automatic detection"; break;
807 default: p = "undefined";
808 }
809 CX18_INFO("Configured audio standard: %s\n", p);
810
811 if ((audio_config >> 4) < 0xF) {
812 switch (audio_config & 0xF) {
813 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
814 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
815 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
816 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
817 case 0x04: p = "STEREO"; break;
818 case 0x05: p = "DUAL1 (AB)"; break;
819 case 0x06: p = "DUAL2 (AC) (FM)"; break;
820 case 0x07: p = "DUAL3 (BC) (FM)"; break;
821 case 0x08: p = "DUAL4 (AC) (AM)"; break;
822 case 0x09: p = "DUAL5 (BC) (AM)"; break;
823 case 0x0a: p = "SAP"; break;
824 default: p = "undefined";
825 }
826 CX18_INFO("Configured audio mode: %s\n", p);
827 } else {
828 switch (audio_config & 0xF) {
829 case 0x00: p = "BG"; break;
830 case 0x01: p = "DK1"; break;
831 case 0x02: p = "DK2"; break;
832 case 0x03: p = "DK3"; break;
833 case 0x04: p = "I"; break;
834 case 0x05: p = "L"; break;
835 case 0x06: p = "BTSC"; break;
836 case 0x07: p = "EIAJ"; break;
837 case 0x08: p = "A2-M"; break;
838 case 0x09: p = "FM Radio"; break;
839 case 0x0f: p = "automatic standard and mode detection"; break;
840 default: p = "undefined";
841 }
842 CX18_INFO("Configured audio system: %s\n", p);
843 }
844
845 if (aud_input)
846 CX18_INFO("Specified audio input: Tuner (In%d)\n",
847 aud_input);
848 else
849 CX18_INFO("Specified audio input: External\n");
850
851 switch (pref_mode & 0xf) {
852 case 0: p = "mono/language A"; break;
853 case 1: p = "language B"; break;
854 case 2: p = "language C"; break;
855 case 3: p = "analog fallback"; break;
856 case 4: p = "stereo"; break;
857 case 5: p = "language AC"; break;
858 case 6: p = "language BC"; break;
859 case 7: p = "language AB"; break;
860 default: p = "undefined";
861 }
862 CX18_INFO("Preferred audio mode: %s\n", p);
863
864 if ((audio_config & 0xf) == 0xf) {
865 switch ((afc0 >> 2) & 0x1) {
866 case 0: p = "system DK"; break;
867 case 1: p = "system L"; break;
868 }
869 CX18_INFO("Selected 65 MHz format: %s\n", p);
870
871 switch (afc0 & 0x3) {
872 case 0: p = "BTSC"; break;
873 case 1: p = "EIAJ"; break;
874 case 2: p = "A2-M"; break;
875 default: p = "undefined";
876 }
877 CX18_INFO("Selected 45 MHz format: %s\n", p);
878 }
879}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
new file mode 100644
index 000000000000..786901d72e9a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -0,0 +1,318 @@
1/*
2 * cx18 ADEC header
3 *
4 * Derived from cx25840-core.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX18_AV_CORE_H_
25#define _CX18_AV_CORE_H_
26
27struct cx18;
28
29enum cx18_av_video_input {
30 /* Composite video inputs In1-In8 */
31 CX18_AV_COMPOSITE1 = 1,
32 CX18_AV_COMPOSITE2,
33 CX18_AV_COMPOSITE3,
34 CX18_AV_COMPOSITE4,
35 CX18_AV_COMPOSITE5,
36 CX18_AV_COMPOSITE6,
37 CX18_AV_COMPOSITE7,
38 CX18_AV_COMPOSITE8,
39
40 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
41 chroma input (In5-In8) */
42 CX18_AV_SVIDEO_LUMA1 = 0x10,
43 CX18_AV_SVIDEO_LUMA2 = 0x20,
44 CX18_AV_SVIDEO_LUMA3 = 0x30,
45 CX18_AV_SVIDEO_LUMA4 = 0x40,
46 CX18_AV_SVIDEO_CHROMA4 = 0x400,
47 CX18_AV_SVIDEO_CHROMA5 = 0x500,
48 CX18_AV_SVIDEO_CHROMA6 = 0x600,
49 CX18_AV_SVIDEO_CHROMA7 = 0x700,
50 CX18_AV_SVIDEO_CHROMA8 = 0x800,
51
52 /* S-Video aliases for common luma/chroma combinations */
53 CX18_AV_SVIDEO1 = 0x510,
54 CX18_AV_SVIDEO2 = 0x620,
55 CX18_AV_SVIDEO3 = 0x730,
56 CX18_AV_SVIDEO4 = 0x840,
57};
58
59enum cx18_av_audio_input {
60 /* Audio inputs: serial or In4-In8 */
61 CX18_AV_AUDIO_SERIAL,
62 CX18_AV_AUDIO4 = 4,
63 CX18_AV_AUDIO5,
64 CX18_AV_AUDIO6,
65 CX18_AV_AUDIO7,
66 CX18_AV_AUDIO8,
67};
68
69struct cx18_av_state {
70 int radio;
71 v4l2_std_id std;
72 enum cx18_av_video_input vid_input;
73 enum cx18_av_audio_input aud_input;
74 u32 audclk_freq;
75 int audmode;
76 int vbi_line_offset;
77 u32 id;
78 u32 rev;
79 int is_initialized;
80};
81
82
83/* Registers */
84#define CXADEC_CHIP_TYPE_TIGER 0x837
85#define CXADEC_CHIP_TYPE_MAKO 0x843
86
87#define CXADEC_HOST_REG1 0x000
88#define CXADEC_HOST_REG2 0x001
89
90#define CXADEC_CHIP_CTRL 0x100
91#define CXADEC_AFE_CTRL 0x104
92#define CXADEC_PLL_CTRL1 0x108
93#define CXADEC_VID_PLL_FRAC 0x10C
94#define CXADEC_AUX_PLL_FRAC 0x110
95#define CXADEC_PIN_CTRL1 0x114
96#define CXADEC_PIN_CTRL2 0x118
97#define CXADEC_PIN_CFG1 0x11C
98#define CXADEC_PIN_CFG2 0x120
99
100#define CXADEC_PIN_CFG3 0x124
101#define CXADEC_I2S_MCLK 0x127
102
103#define CXADEC_AUD_LOCK1 0x128
104#define CXADEC_AUD_LOCK2 0x12C
105#define CXADEC_POWER_CTRL 0x130
106#define CXADEC_AFE_DIAG_CTRL1 0x134
107#define CXADEC_AFE_DIAG_CTRL2 0x138
108#define CXADEC_AFE_DIAG_CTRL3 0x13C
109#define CXADEC_PLL_DIAG_CTRL 0x140
110#define CXADEC_TEST_CTRL1 0x144
111#define CXADEC_TEST_CTRL2 0x148
112#define CXADEC_BIST_STAT 0x14C
113#define CXADEC_DLL1_DIAG_CTRL 0x158
114#define CXADEC_DLL2_DIAG_CTRL 0x15C
115
116/* IR registers */
117#define CXADEC_IR_CTRL_REG 0x200
118#define CXADEC_IR_TXCLK_REG 0x204
119#define CXADEC_IR_RXCLK_REG 0x208
120#define CXADEC_IR_CDUTY_REG 0x20C
121#define CXADEC_IR_STAT_REG 0x210
122#define CXADEC_IR_IRQEN_REG 0x214
123#define CXADEC_IR_FILTER_REG 0x218
124#define CXADEC_IR_FIFO_REG 0x21C
125
126/* Video Registers */
127#define CXADEC_MODE_CTRL 0x400
128#define CXADEC_OUT_CTRL1 0x404
129#define CXADEC_OUT_CTRL2 0x408
130#define CXADEC_GEN_STAT 0x40C
131#define CXADEC_INT_STAT_MASK 0x410
132#define CXADEC_LUMA_CTRL 0x414
133
134#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414
135#define CXADEC_CONTRAST_CTRL_BYTE 0x415
136#define CXADEC_LUMA_CTRL_BYTE_3 0x416
137
138#define CXADEC_HSCALE_CTRL 0x418
139#define CXADEC_VSCALE_CTRL 0x41C
140
141#define CXADEC_CHROMA_CTRL 0x420
142
143#define CXADEC_USAT_CTRL_BYTE 0x420
144#define CXADEC_VSAT_CTRL_BYTE 0x421
145#define CXADEC_HUE_CTRL_BYTE 0x422
146
147#define CXADEC_VBI_LINE_CTRL1 0x424
148#define CXADEC_VBI_LINE_CTRL2 0x428
149#define CXADEC_VBI_LINE_CTRL3 0x42C
150#define CXADEC_VBI_LINE_CTRL4 0x430
151#define CXADEC_VBI_LINE_CTRL5 0x434
152#define CXADEC_VBI_FC_CFG 0x438
153#define CXADEC_VBI_MISC_CFG1 0x43C
154#define CXADEC_VBI_MISC_CFG2 0x440
155#define CXADEC_VBI_PAY1 0x444
156#define CXADEC_VBI_PAY2 0x448
157#define CXADEC_VBI_CUST1_CFG1 0x44C
158#define CXADEC_VBI_CUST1_CFG2 0x450
159#define CXADEC_VBI_CUST1_CFG3 0x454
160#define CXADEC_VBI_CUST2_CFG1 0x458
161#define CXADEC_VBI_CUST2_CFG2 0x45C
162#define CXADEC_VBI_CUST2_CFG3 0x460
163#define CXADEC_VBI_CUST3_CFG1 0x464
164#define CXADEC_VBI_CUST3_CFG2 0x468
165#define CXADEC_VBI_CUST3_CFG3 0x46C
166#define CXADEC_HORIZ_TIM_CTRL 0x470
167#define CXADEC_VERT_TIM_CTRL 0x474
168#define CXADEC_SRC_COMB_CFG 0x478
169#define CXADEC_CHROMA_VBIOFF_CFG 0x47C
170#define CXADEC_FIELD_COUNT 0x480
171#define CXADEC_MISC_TIM_CTRL 0x484
172#define CXADEC_DFE_CTRL1 0x488
173#define CXADEC_DFE_CTRL2 0x48C
174#define CXADEC_DFE_CTRL3 0x490
175#define CXADEC_PLL_CTRL2 0x494
176#define CXADEC_HTL_CTRL 0x498
177#define CXADEC_COMB_CTRL 0x49C
178#define CXADEC_CRUSH_CTRL 0x4A0
179#define CXADEC_SOFT_RST_CTRL 0x4A4
180#define CXADEC_MV_DT_CTRL2 0x4A8
181#define CXADEC_MV_DT_CTRL3 0x4AC
182#define CXADEC_MISC_DIAG_CTRL 0x4B8
183
184#define CXADEC_DL_CTL 0x800
185#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
186#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
187#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
188#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
189
190#define CXADEC_STD_DET_STATUS 0x804
191
192#define CXADEC_STD_DET_CTL 0x808
193#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
194#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
195
196#define CXADEC_DW8051_INT 0x80C
197#define CXADEC_GENERAL_CTL 0x810
198#define CXADEC_AAGC_CTL 0x814
199#define CXADEC_IF_SRC_CTL 0x818
200#define CXADEC_ANLOG_DEMOD_CTL 0x81C
201#define CXADEC_ROT_FREQ_CTL 0x820
202#define CXADEC_FM1_CTL 0x824
203#define CXADEC_PDF_CTL 0x828
204#define CXADEC_DFT1_CTL1 0x82C
205#define CXADEC_DFT1_CTL2 0x830
206#define CXADEC_DFT_STATUS 0x834
207#define CXADEC_DFT2_CTL1 0x838
208#define CXADEC_DFT2_CTL2 0x83C
209#define CXADEC_DFT2_STATUS 0x840
210#define CXADEC_DFT3_CTL1 0x844
211#define CXADEC_DFT3_CTL2 0x848
212#define CXADEC_DFT3_STATUS 0x84C
213#define CXADEC_DFT4_CTL1 0x850
214#define CXADEC_DFT4_CTL2 0x854
215#define CXADEC_DFT4_STATUS 0x858
216#define CXADEC_AM_MTS_DET 0x85C
217#define CXADEC_ANALOG_MUX_CTL 0x860
218#define CXADEC_DIG_PLL_CTL1 0x864
219#define CXADEC_DIG_PLL_CTL2 0x868
220#define CXADEC_DIG_PLL_CTL3 0x86C
221#define CXADEC_DIG_PLL_CTL4 0x870
222#define CXADEC_DIG_PLL_CTL5 0x874
223#define CXADEC_DEEMPH_GAIN_CTL 0x878
224#define CXADEC_DEEMPH_COEF1 0x87C
225#define CXADEC_DEEMPH_COEF2 0x880
226#define CXADEC_DBX1_CTL1 0x884
227#define CXADEC_DBX1_CTL2 0x888
228#define CXADEC_DBX1_STATUS 0x88C
229#define CXADEC_DBX2_CTL1 0x890
230#define CXADEC_DBX2_CTL2 0x894
231#define CXADEC_DBX2_STATUS 0x898
232#define CXADEC_AM_FM_DIFF 0x89C
233
234/* NICAM registers go here */
235#define CXADEC_NICAM_STATUS 0x8C8
236#define CXADEC_DEMATRIX_CTL 0x8CC
237
238#define CXADEC_PATH1_CTL1 0x8D0
239#define CXADEC_PATH1_VOL_CTL 0x8D4
240#define CXADEC_PATH1_EQ_CTL 0x8D8
241#define CXADEC_PATH1_SC_CTL 0x8DC
242
243#define CXADEC_PATH2_CTL1 0x8E0
244#define CXADEC_PATH2_VOL_CTL 0x8E4
245#define CXADEC_PATH2_EQ_CTL 0x8E8
246#define CXADEC_PATH2_SC_CTL 0x8EC
247
248#define CXADEC_SRC_CTL 0x8F0
249#define CXADEC_SRC_LF_COEF 0x8F4
250#define CXADEC_SRC1_CTL 0x8F8
251#define CXADEC_SRC2_CTL 0x8FC
252#define CXADEC_SRC3_CTL 0x900
253#define CXADEC_SRC4_CTL 0x904
254#define CXADEC_SRC5_CTL 0x908
255#define CXADEC_SRC6_CTL 0x90C
256
257#define CXADEC_BASEBAND_OUT_SEL 0x910
258#define CXADEC_I2S_IN_CTL 0x914
259#define CXADEC_I2S_OUT_CTL 0x918
260#define CXADEC_AC97_CTL 0x91C
261#define CXADEC_QAM_PDF 0x920
262#define CXADEC_QAM_CONST_DEC 0x924
263#define CXADEC_QAM_ROTATOR_FREQ 0x948
264
265/* Bit defintions / settings used in Mako Audio */
266#define CXADEC_PREF_MODE_MONO_LANGA 0
267#define CXADEC_PREF_MODE_MONO_LANGB 1
268#define CXADEC_PREF_MODE_MONO_LANGC 2
269#define CXADEC_PREF_MODE_FALLBACK 3
270#define CXADEC_PREF_MODE_STEREO 4
271#define CXADEC_PREF_MODE_DUAL_LANG_AC 5
272#define CXADEC_PREF_MODE_DUAL_LANG_BC 6
273#define CXADEC_PREF_MODE_DUAL_LANG_AB 7
274
275
276#define CXADEC_DETECT_STEREO 1
277#define CXADEC_DETECT_DUAL 2
278#define CXADEC_DETECT_TRI 4
279#define CXADEC_DETECT_SAP 0x10
280#define CXADEC_DETECT_NO_SIGNAL 0xFF
281
282#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */
283#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */
284#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2
285#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3
286#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */
287#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */
288#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6
289#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7
290#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */
291#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
292#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
293
294/* ----------------------------------------------------------------------- */
295/* cx18_av-core.c */
296int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
297int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
298u8 cx18_av_read(struct cx18 *cx, u16 addr);
299u32 cx18_av_read4(struct cx18 *cx, u16 addr);
300int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
301int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
302int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
303
304/* ----------------------------------------------------------------------- */
305/* cx18_av-firmware.c */
306int cx18_av_loadfw(struct cx18 *cx);
307
308/* ----------------------------------------------------------------------- */
309/* cx18_av-audio.c */
310int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
311void cx18_av_audio_set_path(struct cx18 *cx);
312
313/* ----------------------------------------------------------------------- */
314/* cx18_av-vbi.c */
315void cx18_av_vbi_setup(struct cx18 *cx);
316int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
317
318#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
new file mode 100644
index 000000000000..526e142156cd
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -0,0 +1,120 @@
1/*
2 * cx18 ADEC firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA.
20 */
21
22#include "cx18-driver.h"
23#include <linux/firmware.h>
24
25#define FWFILE "v4l-cx23418-dig.fw"
26
27int cx18_av_loadfw(struct cx18 *cx)
28{
29 const struct firmware *fw = NULL;
30 u32 size;
31 u32 v;
32 u8 *ptr;
33 int i;
34
35 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
36 CX18_ERR("unable to open firmware %s\n", FWFILE);
37 return -EINVAL;
38 }
39
40 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
41 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */
42
43 /* Reset the Mako core (Register is undocumented.) */
44 cx18_av_write4(cx, 0x8100, 0x00010000);
45
46 /* Put the 8051 in reset and enable firmware upload */
47 cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
48
49 ptr = fw->data;
50 size = fw->size;
51
52 for (i = 0; i < size; i++) {
53 u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16);
54 u32 value = 0;
55 int retries;
56
57 for (retries = 0; retries < 5; retries++) {
58 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
59 value = cx18_av_read4(cx, CXADEC_DL_CTL);
60 if ((value & 0x3F00) == (dl_control & 0x3F00))
61 break;
62 }
63 if (retries >= 5) {
64 CX18_ERR("unable to load firmware %s\n", FWFILE);
65 release_firmware(fw);
66 return -EIO;
67 }
68 }
69
70 cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
71
72 /* Output to the 416 */
73 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
74
75 /* Audio input control 1 set to Sony mode */
76 /* Audio output input 2 is 0 for slave operation input */
77 /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
78 /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
79 after WS transition for first bit of audio word. */
80 cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
81
82 /* Audio output control 1 is set to Sony mode */
83 /* Audio output control 2 is set to 1 for master mode */
84 /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
85 /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
86 after WS transition for first bit of audio word. */
87 /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
88 are generated) */
89 cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
90
91 /* set alt I2s master clock to /16 and enable alt divider i2s
92 passthrough */
93 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
94
95 cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6);
96 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
97
98 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
99 /* Register 0x09CC is defined by the Merlin firmware, and doesn't
100 have a name in the spec. */
101 cx18_av_write4(cx, 0x09CC, 1);
102
103#define CX18_AUDIO_ENABLE 0xc72014
104 v = read_reg(CX18_AUDIO_ENABLE);
105 /* If bit 11 is 1 */
106 if (v & 0x800)
107 write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */
108
109 /* Enable WW auto audio standard detection */
110 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
111 v |= 0xFF; /* Auto by default */
112 v |= 0x400; /* Stereo by default */
113 v |= 0x14000000;
114 cx18_av_write4(cx, CXADEC_STD_DET_CTL, v);
115
116 release_firmware(fw);
117
118 CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
119 return 0;
120}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
new file mode 100644
index 000000000000..d09f1daf4ebf
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -0,0 +1,413 @@
1/*
2 * cx18 ADEC VBI functions
3 *
4 * Derived from cx25840-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24
25#include "cx18-driver.h"
26
27static int odd_parity(u8 c)
28{
29 c ^= (c >> 4);
30 c ^= (c >> 2);
31 c ^= (c >> 1);
32
33 return c & 1;
34}
35
36static int decode_vps(u8 *dst, u8 *p)
37{
38 static const u8 biphase_tbl[] = {
39 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
40 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
41 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
42 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
43 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
44 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
45 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
46 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
47 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
48 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
49 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
50 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
51 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
52 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
53 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
54 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
55 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
56 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
57 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
58 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
59 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
60 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
61 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
62 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
63 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
64 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
65 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
66 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
67 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
68 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
69 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
70 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
71 };
72
73 u8 c, err = 0;
74 int i;
75
76 for (i = 0; i < 2 * 13; i += 2) {
77 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
78 c = (biphase_tbl[p[i + 1]] & 0xf) |
79 ((biphase_tbl[p[i]] & 0xf) << 4);
80 dst[i / 2] = c;
81 }
82
83 return err & 0xf0;
84}
85
86void cx18_av_vbi_setup(struct cx18 *cx)
87{
88 struct cx18_av_state *state = &cx->av_state;
89 v4l2_std_id std = state->std;
90 int hblank, hactive, burst, vblank, vactive, sc;
91 int vblank656, src_decimation;
92 int luma_lpf, uv_lpf, comb;
93 u32 pll_int, pll_frac, pll_post;
94
95 /* datasheet startup, step 8d */
96 if (std & ~V4L2_STD_NTSC)
97 cx18_av_write(cx, 0x49f, 0x11);
98 else
99 cx18_av_write(cx, 0x49f, 0x14);
100
101 if (std & V4L2_STD_625_50) {
102 hblank = 0x084;
103 hactive = 0x2d0;
104 burst = 0x5d;
105 vblank = 0x024;
106 vactive = 0x244;
107 vblank656 = 0x28;
108 src_decimation = 0x21f;
109
110 luma_lpf = 2;
111 if (std & V4L2_STD_SECAM) {
112 uv_lpf = 0;
113 comb = 0;
114 sc = 0x0a425f;
115 } else if (std == V4L2_STD_PAL_Nc) {
116 uv_lpf = 1;
117 comb = 0x20;
118 sc = 556453;
119 } else {
120 uv_lpf = 1;
121 comb = 0x20;
122 sc = 0x0a8263;
123 }
124 } else {
125 hactive = 720;
126 hblank = 122;
127 vactive = 487;
128 luma_lpf = 1;
129 uv_lpf = 1;
130
131 src_decimation = 0x21f;
132 if (std == V4L2_STD_PAL_60) {
133 vblank = 26;
134 vblank656 = 26;
135 burst = 0x5b;
136 luma_lpf = 2;
137 comb = 0x20;
138 sc = 0x0a8263;
139 } else if (std == V4L2_STD_PAL_M) {
140 vblank = 20;
141 vblank656 = 24;
142 burst = 0x61;
143 comb = 0x20;
144
145 sc = 555452;
146 } else {
147 vblank = 26;
148 vblank656 = 26;
149 burst = 0x5b;
150 comb = 0x66;
151 sc = 556063;
152 }
153 }
154
155 /* DEBUG: Displays configured PLL frequency */
156 pll_int = cx18_av_read(cx, 0x108);
157 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
158 pll_post = cx18_av_read(cx, 0x109);
159 CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
160 pll_int, pll_frac, pll_post);
161
162 if (pll_post) {
163 int fin, fsc;
164 int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
165
166 pll >>= 25;
167 pll /= pll_post;
168 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
169 pll / 1000000, pll % 1000000);
170 CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
171 pll / 8000000, (pll / 8) % 1000000);
172
173 fin = ((u64)src_decimation * pll) >> 12;
174 CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
175 fin / 1000000, fin % 1000000);
176
177 fsc = (((u64)sc) * pll) >> 24L;
178 CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
179 fsc / 1000000, fsc % 1000000);
180
181 CX18_DEBUG_INFO("hblank %i, hactive %i, "
182 "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
183 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
184 " sc 0x%06x\n",
185 hblank, hactive, vblank, vactive, vblank656,
186 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
187 }
188
189 /* Sets horizontal blanking delay and active lines */
190 cx18_av_write(cx, 0x470, hblank);
191 cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
192 (hactive << 4)));
193 cx18_av_write(cx, 0x472, hactive >> 4);
194
195 /* Sets burst gate delay */
196 cx18_av_write(cx, 0x473, burst);
197
198 /* Sets vertical blanking delay and active duration */
199 cx18_av_write(cx, 0x474, vblank);
200 cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
201 (vactive << 4)));
202 cx18_av_write(cx, 0x476, vactive >> 4);
203 cx18_av_write(cx, 0x477, vblank656);
204
205 /* Sets src decimation rate */
206 cx18_av_write(cx, 0x478, 0xff & src_decimation);
207 cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
208
209 /* Sets Luma and UV Low pass filters */
210 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
211
212 /* Enables comb filters */
213 cx18_av_write(cx, 0x47b, comb);
214
215 /* Sets SC Step*/
216 cx18_av_write(cx, 0x47c, sc);
217 cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
218 cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
219
220 /* Sets VBI parameters */
221 if (std & V4L2_STD_625_50) {
222 cx18_av_write(cx, 0x47f, 0x01);
223 state->vbi_line_offset = 5;
224 } else {
225 cx18_av_write(cx, 0x47f, 0x00);
226 state->vbi_line_offset = 8;
227 }
228}
229
230int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
231{
232 struct cx18_av_state *state = &cx->av_state;
233 struct v4l2_format *fmt;
234 struct v4l2_sliced_vbi_format *svbi;
235
236 switch (cmd) {
237 case VIDIOC_G_FMT:
238 {
239 static u16 lcr2vbi[] = {
240 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
241 0, V4L2_SLICED_WSS_625, 0, /* 4 */
242 V4L2_SLICED_CAPTION_525, /* 6 */
243 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
244 0, 0, 0, 0
245 };
246 int is_pal = !(state->std & V4L2_STD_525_60);
247 int i;
248
249 fmt = arg;
250 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
251 return -EINVAL;
252 svbi = &fmt->fmt.sliced;
253 memset(svbi, 0, sizeof(*svbi));
254 /* we're done if raw VBI is active */
255 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
256 break;
257
258 if (is_pal) {
259 for (i = 7; i <= 23; i++) {
260 u8 v = cx18_av_read(cx, 0x424 + i - 7);
261
262 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
263 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
264 svbi->service_set |= svbi->service_lines[0][i] |
265 svbi->service_lines[1][i];
266 }
267 } else {
268 for (i = 10; i <= 21; i++) {
269 u8 v = cx18_av_read(cx, 0x424 + i - 10);
270
271 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
272 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
273 svbi->service_set |= svbi->service_lines[0][i] |
274 svbi->service_lines[1][i];
275 }
276 }
277 break;
278 }
279
280 case VIDIOC_S_FMT:
281 {
282 int is_pal = !(state->std & V4L2_STD_525_60);
283 int vbi_offset = is_pal ? 1 : 0;
284 int i, x;
285 u8 lcr[24];
286
287 fmt = arg;
288 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
289 return -EINVAL;
290 svbi = &fmt->fmt.sliced;
291 if (svbi->service_set == 0) {
292 /* raw VBI */
293 memset(svbi, 0, sizeof(*svbi));
294
295 /* Setup VBI */
296 cx18_av_vbi_setup(cx);
297
298 /* VBI Offset */
299 cx18_av_write(cx, 0x47f, vbi_offset);
300 cx18_av_write(cx, 0x404, 0x2e);
301 break;
302 }
303
304 for (x = 0; x <= 23; x++)
305 lcr[x] = 0x00;
306
307 /* Setup VBI */
308 cx18_av_vbi_setup(cx);
309
310 /* Sliced VBI */
311 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
312 cx18_av_write(cx, 0x406, 0x13);
313 cx18_av_write(cx, 0x47f, vbi_offset);
314
315 if (is_pal) {
316 for (i = 0; i <= 6; i++)
317 svbi->service_lines[0][i] =
318 svbi->service_lines[1][i] = 0;
319 } else {
320 for (i = 0; i <= 9; i++)
321 svbi->service_lines[0][i] =
322 svbi->service_lines[1][i] = 0;
323
324 for (i = 22; i <= 23; i++)
325 svbi->service_lines[0][i] =
326 svbi->service_lines[1][i] = 0;
327 }
328
329 for (i = 7; i <= 23; i++) {
330 for (x = 0; x <= 1; x++) {
331 switch (svbi->service_lines[1-x][i]) {
332 case V4L2_SLICED_TELETEXT_B:
333 lcr[i] |= 1 << (4 * x);
334 break;
335 case V4L2_SLICED_WSS_625:
336 lcr[i] |= 4 << (4 * x);
337 break;
338 case V4L2_SLICED_CAPTION_525:
339 lcr[i] |= 6 << (4 * x);
340 break;
341 case V4L2_SLICED_VPS:
342 lcr[i] |= 9 << (4 * x);
343 break;
344 }
345 }
346 }
347
348 if (is_pal) {
349 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
350 cx18_av_write(cx, i, lcr[6 + x]);
351 } else {
352 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
353 cx18_av_write(cx, i, lcr[9 + x]);
354 for (i = 0x431; i <= 0x434; i++)
355 cx18_av_write(cx, i, 0);
356 }
357
358 cx18_av_write(cx, 0x43c, 0x16);
359 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
360 break;
361 }
362
363 case VIDIOC_INT_DECODE_VBI_LINE:
364 {
365 struct v4l2_decode_vbi_line *vbi = arg;
366 u8 *p = vbi->p;
367 int id1, id2, l, err = 0;
368
369 if (p[0] || p[1] != 0xff || p[2] != 0xff ||
370 (p[3] != 0x55 && p[3] != 0x91)) {
371 vbi->line = vbi->type = 0;
372 break;
373 }
374
375 p += 4;
376 id1 = p[-1];
377 id2 = p[0] & 0xf;
378 l = p[2] & 0x3f;
379 l += state->vbi_line_offset;
380 p += 4;
381
382 switch (id2) {
383 case 1:
384 id2 = V4L2_SLICED_TELETEXT_B;
385 break;
386 case 4:
387 id2 = V4L2_SLICED_WSS_625;
388 break;
389 case 6:
390 id2 = V4L2_SLICED_CAPTION_525;
391 err = !odd_parity(p[0]) || !odd_parity(p[1]);
392 break;
393 case 9:
394 id2 = V4L2_SLICED_VPS;
395 if (decode_vps(p, p) != 0)
396 err = 1;
397 break;
398 default:
399 id2 = 0;
400 err = 1;
401 break;
402 }
403
404 vbi->type = err ? 0 : id2;
405 vbi->line = err ? 0 : l;
406 vbi->is_second_field = err ? 0 : (id1 == 0x55);
407 vbi->p = p;
408 break;
409 }
410 }
411
412 return 0;
413}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
new file mode 100644
index 000000000000..f5e3ba1f5354
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -0,0 +1,277 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-i2c.h"
27#include <media/cs5345.h>
28
29/********************** card configuration *******************************/
30
31/* usual i2c tuner addresses to probe */
32static struct cx18_card_tuner_i2c cx18_i2c_std = {
33 .radio = { I2C_CLIENT_END },
34 .demod = { 0x43, I2C_CLIENT_END },
35 .tv = { 0x61, 0x60, I2C_CLIENT_END },
36};
37
38/* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii
39 This keeps the PCI ID database up to date. Note that the entries
40 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
41 New vendor IDs should still be added to the vendor ID list. */
42
43/* Hauppauge HVR-1600 cards */
44
45/* Note: for Hauppauge cards the tveeprom information is used instead
46 of PCI IDs */
47static const struct cx18_card cx18_card_hvr1600_esmt = {
48 .type = CX18_CARD_HVR_1600_ESMT,
49 .name = "Hauppauge HVR-1600",
50 .comment = "DVB & VBI are not yet supported\n",
51 .v4l2_capabilities = CX18_CAP_ENCODER,
52 .hw_audio_ctrl = CX18_HW_CX23418,
53 .hw_muxer = CX18_HW_CS5345,
54 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
55 .video_inputs = {
56 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
57 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
58 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
59 { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
60 { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
61 },
62 .audio_inputs = {
63 { CX18_CARD_INPUT_AUD_TUNER,
64 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
65 { CX18_CARD_INPUT_LINE_IN1,
66 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
67 { CX18_CARD_INPUT_LINE_IN2,
68 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
69 },
70 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
71 CX23418_AUDIO_SERIAL, 0 },
72 .ddr = {
73 /* ESMT M13S128324A-5B memory */
74 .chip_config = 0x003,
75 .refresh = 0x30c,
76 .timing1 = 0x44220e82,
77 .timing2 = 0x08,
78 .tune_lane = 0,
79 .initial_emrs = 0,
80 },
81 .gpio_init.initial_value = 0x3001,
82 .gpio_init.direction = 0x3001,
83 .i2c = &cx18_i2c_std,
84};
85
86static const struct cx18_card cx18_card_hvr1600_samsung = {
87 .type = CX18_CARD_HVR_1600_SAMSUNG,
88 .name = "Hauppauge HVR-1600 (Preproduction)",
89 .comment = "DVB & VBI are not yet supported\n",
90 .v4l2_capabilities = CX18_CAP_ENCODER,
91 .hw_audio_ctrl = CX18_HW_CX23418,
92 .hw_muxer = CX18_HW_CS5345,
93 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
94 .video_inputs = {
95 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
96 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
97 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
98 { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
99 { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
100 },
101 .audio_inputs = {
102 { CX18_CARD_INPUT_AUD_TUNER,
103 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
104 { CX18_CARD_INPUT_LINE_IN1,
105 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
106 { CX18_CARD_INPUT_LINE_IN2,
107 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
108 },
109 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
110 CX23418_AUDIO_SERIAL, 0 },
111 .ddr = {
112 /* Samsung K4D263238G-VC33 memory */
113 .chip_config = 0x003,
114 .refresh = 0x30c,
115 .timing1 = 0x23230b73,
116 .timing2 = 0x08,
117 .tune_lane = 0,
118 .initial_emrs = 2,
119 },
120 .gpio_init.initial_value = 0x3001,
121 .gpio_init.direction = 0x3001,
122 .i2c = &cx18_i2c_std,
123};
124
125/* ------------------------------------------------------------------------- */
126
127/* Compro VideoMate H900: not working at the moment! */
128
129static const struct cx18_card_pci_info cx18_pci_h900[] = {
130 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
131 { 0, 0, 0 }
132};
133
134static const struct cx18_card cx18_card_h900 = {
135 .type = CX18_CARD_COMPRO_H900,
136 .name = "Compro VideoMate H900",
137 .comment = "Not yet supported!\n",
138 .v4l2_capabilities = 0,
139 .hw_audio_ctrl = CX18_HW_CX23418,
140 .hw_all = CX18_HW_TUNER,
141 .video_inputs = {
142 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
143 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
144 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
145 },
146 .audio_inputs = {
147 { CX18_CARD_INPUT_AUD_TUNER,
148 CX23418_AUDIO8, 0 },
149 { CX18_CARD_INPUT_LINE_IN1,
150 CX23418_AUDIO_SERIAL, 0 },
151 },
152 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
153 CX23418_AUDIO_SERIAL, 0 },
154 .tuners = {
155 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
156 },
157 .ddr = {
158 /* EtronTech EM6A9160TS-5G memory */
159 .chip_config = 0x50003,
160 .refresh = 0x753,
161 .timing1 = 0x24330e84,
162 .timing2 = 0x1f,
163 .tune_lane = 0,
164 .initial_emrs = 0,
165 },
166 .pci_list = cx18_pci_h900,
167 .i2c = &cx18_i2c_std,
168};
169
170/* ------------------------------------------------------------------------- */
171
172/* Yuan MPC718: not working at the moment! */
173
174static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
175 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
176 { 0, 0, 0 }
177};
178
179static const struct cx18_card cx18_card_mpc718 = {
180 .type = CX18_CARD_YUAN_MPC718,
181 .name = "Yuan MPC718",
182 .comment = "Not yet supported!\n",
183 .v4l2_capabilities = 0,
184 .hw_audio_ctrl = CX18_HW_CX23418,
185 .hw_all = CX18_HW_TUNER,
186 .video_inputs = {
187 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
188 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
189 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
190 },
191 .audio_inputs = {
192 { CX18_CARD_INPUT_AUD_TUNER,
193 CX23418_AUDIO8, 0 },
194 { CX18_CARD_INPUT_LINE_IN1,
195 CX23418_AUDIO_SERIAL, 0 },
196 },
197 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
198 CX23418_AUDIO_SERIAL, 0 },
199 .tuners = {
200 /* XC3028 tuner */
201 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
202 },
203 /* tuner reset */
204 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
205 .ddr = {
206 /* Probably Samsung K4D263238G-VC33 memory */
207 .chip_config = 0x003,
208 .refresh = 0x30c,
209 .timing1 = 0x23230b73,
210 .timing2 = 0x08,
211 .tune_lane = 0,
212 .initial_emrs = 2,
213 },
214 .pci_list = cx18_pci_mpc718,
215 .i2c = &cx18_i2c_std,
216};
217
218static const struct cx18_card *cx18_card_list[] = {
219 &cx18_card_hvr1600_esmt,
220 &cx18_card_hvr1600_samsung,
221 &cx18_card_h900,
222 &cx18_card_mpc718,
223};
224
225const struct cx18_card *cx18_get_card(u16 index)
226{
227 if (index >= ARRAY_SIZE(cx18_card_list))
228 return NULL;
229 return cx18_card_list[index];
230}
231
232int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
233{
234 const struct cx18_card_video_input *card_input =
235 cx->card->video_inputs + index;
236 static const char * const input_strs[] = {
237 "Tuner 1",
238 "S-Video 1",
239 "S-Video 2",
240 "Composite 1",
241 "Composite 2",
242 "Composite 3"
243 };
244
245 memset(input, 0, sizeof(*input));
246 if (index >= cx->nof_inputs)
247 return -EINVAL;
248 input->index = index;
249 strlcpy(input->name, input_strs[card_input->video_type - 1],
250 sizeof(input->name));
251 input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
252 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
253 input->audioset = (1 << cx->nof_audio_inputs) - 1;
254 input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
255 cx->tuner_std : V4L2_STD_ALL;
256 return 0;
257}
258
259int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
260{
261 const struct cx18_card_audio_input *aud_input =
262 cx->card->audio_inputs + index;
263 static const char * const input_strs[] = {
264 "Tuner 1",
265 "Line In 1",
266 "Line In 2"
267 };
268
269 memset(audio, 0, sizeof(*audio));
270 if (index >= cx->nof_audio_inputs)
271 return -EINVAL;
272 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
273 sizeof(audio->name));
274 audio->index = index;
275 audio->capability = V4L2_AUDCAP_STEREO;
276 return 0;
277}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
new file mode 100644
index 000000000000..bca249bdd337
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -0,0 +1,170 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23/* hardware flags */
24#define CX18_HW_TUNER (1 << 0)
25#define CX18_HW_TVEEPROM (1 << 1)
26#define CX18_HW_CS5345 (1 << 2)
27#define CX18_HW_GPIO (1 << 3)
28#define CX18_HW_CX23418 (1 << 4)
29#define CX18_HW_DVB (1 << 5)
30
31/* video inputs */
32#define CX18_CARD_INPUT_VID_TUNER 1
33#define CX18_CARD_INPUT_SVIDEO1 2
34#define CX18_CARD_INPUT_SVIDEO2 3
35#define CX18_CARD_INPUT_COMPOSITE1 4
36#define CX18_CARD_INPUT_COMPOSITE2 5
37#define CX18_CARD_INPUT_COMPOSITE3 6
38
39enum cx34180_video_input {
40 /* Composite video inputs In1-In8 */
41 CX23418_COMPOSITE1 = 1,
42 CX23418_COMPOSITE2,
43 CX23418_COMPOSITE3,
44 CX23418_COMPOSITE4,
45 CX23418_COMPOSITE5,
46 CX23418_COMPOSITE6,
47 CX23418_COMPOSITE7,
48 CX23418_COMPOSITE8,
49
50 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
51 chroma input (In5-In8) */
52 CX23418_SVIDEO_LUMA1 = 0x10,
53 CX23418_SVIDEO_LUMA2 = 0x20,
54 CX23418_SVIDEO_LUMA3 = 0x30,
55 CX23418_SVIDEO_LUMA4 = 0x40,
56 CX23418_SVIDEO_CHROMA4 = 0x400,
57 CX23418_SVIDEO_CHROMA5 = 0x500,
58 CX23418_SVIDEO_CHROMA6 = 0x600,
59 CX23418_SVIDEO_CHROMA7 = 0x700,
60 CX23418_SVIDEO_CHROMA8 = 0x800,
61
62 /* S-Video aliases for common luma/chroma combinations */
63 CX23418_SVIDEO1 = 0x510,
64 CX23418_SVIDEO2 = 0x620,
65 CX23418_SVIDEO3 = 0x730,
66 CX23418_SVIDEO4 = 0x840,
67};
68
69/* audio inputs */
70#define CX18_CARD_INPUT_AUD_TUNER 1
71#define CX18_CARD_INPUT_LINE_IN1 2
72#define CX18_CARD_INPUT_LINE_IN2 3
73
74#define CX18_CARD_MAX_VIDEO_INPUTS 6
75#define CX18_CARD_MAX_AUDIO_INPUTS 3
76#define CX18_CARD_MAX_TUNERS 2
77
78enum cx23418_audio_input {
79 /* Audio inputs: serial or In4-In8 */
80 CX23418_AUDIO_SERIAL,
81 CX23418_AUDIO4 = 4,
82 CX23418_AUDIO5,
83 CX23418_AUDIO6,
84 CX23418_AUDIO7,
85 CX23418_AUDIO8,
86};
87
88/* V4L2 capability aliases */
89#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
90 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE)
91/* | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
92
93struct cx18_card_video_input {
94 u8 video_type; /* video input type */
95 u8 audio_index; /* index in cx18_card_audio_input array */
96 u16 video_input; /* hardware video input */
97};
98
99struct cx18_card_audio_input {
100 u8 audio_type; /* audio input type */
101 u32 audio_input; /* hardware audio input */
102 u16 muxer_input; /* hardware muxer input for boards with a
103 multiplexer chip */
104};
105
106struct cx18_card_pci_info {
107 u16 device;
108 u16 subsystem_vendor;
109 u16 subsystem_device;
110};
111
112/* GPIO definitions */
113
114/* The mask is the set of bits used by the operation */
115
116struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
117 u16 direction; /* DIR setting. Leave to 0 if no init is needed */
118 u16 initial_value;
119};
120
121struct cx18_card_tuner {
122 v4l2_std_id std; /* standard for which the tuner is suitable */
123 int tuner; /* tuner ID (from tuner.h) */
124};
125
126struct cx18_card_tuner_i2c {
127 unsigned short radio[2];/* radio tuner i2c address to probe */
128 unsigned short demod[2];/* demodulator i2c address to probe */
129 unsigned short tv[4]; /* tv tuner i2c addresses to probe */
130};
131
132struct cx18_ddr { /* DDR config data */
133 u32 chip_config;
134 u32 refresh;
135 u32 timing1;
136 u32 timing2;
137 u32 tune_lane;
138 u32 initial_emrs;
139};
140
141/* for card information/parameters */
142struct cx18_card {
143 int type;
144 char *name;
145 char *comment;
146 u32 v4l2_capabilities;
147 u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
148 1 dev allowed) */
149 u32 hw_muxer; /* hardware used to multiplex audio input */
150 u32 hw_all; /* all hardware used by the board */
151 struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
152 struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS];
153 struct cx18_card_audio_input radio_input;
154
155 /* GPIO card-specific settings */
156 struct cx18_gpio_init gpio_init;
157
158 struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
159 struct cx18_card_tuner_i2c *i2c;
160
161 struct cx18_ddr ddr;
162
163 /* list of device and subsystem vendor/devices that
164 correspond to this card type. */
165 const struct cx18_card_pci_info *pci_list;
166};
167
168int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input);
169int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input);
170const struct cx18_card *cx18_get_card(u16 index);
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
new file mode 100644
index 000000000000..2bdac5ebbb0d
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -0,0 +1,306 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-av-core.h"
26#include "cx18-cards.h"
27#include "cx18-ioctl.h"
28#include "cx18-audio.h"
29#include "cx18-i2c.h"
30#include "cx18-mailbox.h"
31#include "cx18-controls.h"
32
33static const u32 user_ctrls[] = {
34 V4L2_CID_USER_CLASS,
35 V4L2_CID_BRIGHTNESS,
36 V4L2_CID_CONTRAST,
37 V4L2_CID_SATURATION,
38 V4L2_CID_HUE,
39 V4L2_CID_AUDIO_VOLUME,
40 V4L2_CID_AUDIO_BALANCE,
41 V4L2_CID_AUDIO_BASS,
42 V4L2_CID_AUDIO_TREBLE,
43 V4L2_CID_AUDIO_MUTE,
44 V4L2_CID_AUDIO_LOUDNESS,
45 0
46};
47
48static const u32 *ctrl_classes[] = {
49 user_ctrls,
50 cx2341x_mpeg_ctrls,
51 NULL
52};
53
54static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
55{
56 const char *name;
57
58 CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
59
60 qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
61 if (qctrl->id == 0)
62 return -EINVAL;
63
64 switch (qctrl->id) {
65 /* Standard V4L2 controls */
66 case V4L2_CID_BRIGHTNESS:
67 case V4L2_CID_HUE:
68 case V4L2_CID_SATURATION:
69 case V4L2_CID_CONTRAST:
70 if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
71 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
72 return 0;
73
74 case V4L2_CID_AUDIO_VOLUME:
75 case V4L2_CID_AUDIO_MUTE:
76 case V4L2_CID_AUDIO_BALANCE:
77 case V4L2_CID_AUDIO_BASS:
78 case V4L2_CID_AUDIO_TREBLE:
79 case V4L2_CID_AUDIO_LOUDNESS:
80 if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
81 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
82 return 0;
83
84 default:
85 if (cx2341x_ctrl_query(&cx->params, qctrl))
86 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
87 return 0;
88 }
89 strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
90 qctrl->name[sizeof(qctrl->name) - 1] = 0;
91 return 0;
92}
93
94static int cx18_querymenu(struct cx18 *cx, struct v4l2_querymenu *qmenu)
95{
96 struct v4l2_queryctrl qctrl;
97
98 qctrl.id = qmenu->id;
99 cx18_queryctrl(cx, &qctrl);
100 return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
101}
102
103static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
104{
105 s32 v = vctrl->value;
106
107 CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
108
109 switch (vctrl->id) {
110 /* Standard V4L2 controls */
111 case V4L2_CID_BRIGHTNESS:
112 case V4L2_CID_HUE:
113 case V4L2_CID_SATURATION:
114 case V4L2_CID_CONTRAST:
115 return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
116
117 case V4L2_CID_AUDIO_VOLUME:
118 case V4L2_CID_AUDIO_MUTE:
119 case V4L2_CID_AUDIO_BALANCE:
120 case V4L2_CID_AUDIO_BASS:
121 case V4L2_CID_AUDIO_TREBLE:
122 case V4L2_CID_AUDIO_LOUDNESS:
123 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
124
125 default:
126 CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
127 return -EINVAL;
128 }
129 return 0;
130}
131
132static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
133{
134 CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
135
136 switch (vctrl->id) {
137 /* Standard V4L2 controls */
138 case V4L2_CID_BRIGHTNESS:
139 case V4L2_CID_HUE:
140 case V4L2_CID_SATURATION:
141 case V4L2_CID_CONTRAST:
142 return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
143
144 case V4L2_CID_AUDIO_VOLUME:
145 case V4L2_CID_AUDIO_MUTE:
146 case V4L2_CID_AUDIO_BALANCE:
147 case V4L2_CID_AUDIO_BASS:
148 case V4L2_CID_AUDIO_TREBLE:
149 case V4L2_CID_AUDIO_LOUDNESS:
150 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
151 default:
152 CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
153 return -EINVAL;
154 }
155 return 0;
156}
157
158static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt)
159{
160 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
161 return -EINVAL;
162 if (atomic_read(&cx->capturing) > 0)
163 return -EBUSY;
164
165 /* First try to allocate sliced VBI buffers if needed. */
166 if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) {
167 int i;
168
169 for (i = 0; i < CX18_VBI_FRAMES; i++) {
170 /* Yuck, hardcoded. Needs to be a define */
171 cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
172 if (cx->vbi.sliced_mpeg_data[i] == NULL) {
173 while (--i >= 0) {
174 kfree(cx->vbi.sliced_mpeg_data[i]);
175 cx->vbi.sliced_mpeg_data[i] = NULL;
176 }
177 return -ENOMEM;
178 }
179 }
180 }
181
182 cx->vbi.insert_mpeg = fmt;
183
184 if (cx->vbi.insert_mpeg == 0)
185 return 0;
186 /* Need sliced data for mpeg insertion */
187 if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
188 if (cx->is_60hz)
189 cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
190 else
191 cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
192 cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
193 }
194 return 0;
195}
196
197int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
198{
199 struct v4l2_control ctrl;
200
201 switch (cmd) {
202 case VIDIOC_QUERYMENU:
203 CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
204 return cx18_querymenu(cx, arg);
205
206 case VIDIOC_QUERYCTRL:
207 return cx18_queryctrl(cx, arg);
208
209 case VIDIOC_S_CTRL:
210 return cx18_s_ctrl(cx, arg);
211
212 case VIDIOC_G_CTRL:
213 return cx18_g_ctrl(cx, arg);
214
215 case VIDIOC_S_EXT_CTRLS:
216 {
217 struct v4l2_ext_controls *c = arg;
218
219 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
220 int i;
221 int err = 0;
222
223 for (i = 0; i < c->count; i++) {
224 ctrl.id = c->controls[i].id;
225 ctrl.value = c->controls[i].value;
226 err = cx18_s_ctrl(cx, &ctrl);
227 c->controls[i].value = ctrl.value;
228 if (err) {
229 c->error_idx = i;
230 break;
231 }
232 }
233 return err;
234 }
235 CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
236 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
237 struct cx2341x_mpeg_params p = cx->params;
238 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd);
239
240 if (err)
241 return err;
242
243 if (p.video_encoding != cx->params.video_encoding) {
244 int is_mpeg1 = p.video_encoding ==
245 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
246 struct v4l2_format fmt;
247
248 /* fix videodecoder resolution */
249 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
250 fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1);
251 fmt.fmt.pix.height = cx->params.height;
252 cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
253 }
254 err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
255 if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
256 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
257 cx->params = p;
258 cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
259 cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
260 return err;
261 }
262 return -EINVAL;
263 }
264
265 case VIDIOC_G_EXT_CTRLS:
266 {
267 struct v4l2_ext_controls *c = arg;
268
269 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
270 int i;
271 int err = 0;
272
273 for (i = 0; i < c->count; i++) {
274 ctrl.id = c->controls[i].id;
275 ctrl.value = c->controls[i].value;
276 err = cx18_g_ctrl(cx, &ctrl);
277 c->controls[i].value = ctrl.value;
278 if (err) {
279 c->error_idx = i;
280 break;
281 }
282 }
283 return err;
284 }
285 CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
286 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
287 return cx2341x_ext_ctrls(&cx->params, 0, arg, cmd);
288 return -EINVAL;
289 }
290
291 case VIDIOC_TRY_EXT_CTRLS:
292 {
293 struct v4l2_ext_controls *c = arg;
294
295 CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
296 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
297 return cx2341x_ext_ctrls(&cx->params,
298 atomic_read(&cx->capturing), arg, cmd);
299 return -EINVAL;
300 }
301
302 default:
303 return -EINVAL;
304 }
305 return 0;
306}
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
new file mode 100644
index 000000000000..6e985cf422a0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
new file mode 100644
index 000000000000..9f31befc3139
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -0,0 +1,971 @@
1/*
2 * cx18 driver initialization and card probing
3 *
4 * Derived from ivtv-driver.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-version.h"
26#include "cx18-cards.h"
27#include "cx18-i2c.h"
28#include "cx18-irq.h"
29#include "cx18-gpio.h"
30#include "cx18-firmware.h"
31#include "cx18-streams.h"
32#include "cx18-av-core.h"
33#include "cx18-scb.h"
34#include "cx18-mailbox.h"
35#include "cx18-ioctl.h"
36#include "tuner-xc2028.h"
37
38#include <media/tveeprom.h>
39
40
41/* var to keep track of the number of array elements in use */
42int cx18_cards_active;
43
44/* If you have already X v4l cards, then set this to X. This way
45 the device numbers stay matched. Example: you have a WinTV card
46 without radio and a Compro H900 with. Normally this would give a
47 video1 device together with a radio0 device for the Compro. By
48 setting this to 1 you ensure that radio0 is now also radio1. */
49int cx18_first_minor;
50
51/* Master variable for all cx18 info */
52struct cx18 *cx18_cards[CX18_MAX_CARDS];
53
54/* Protects cx18_cards_active */
55DEFINE_SPINLOCK(cx18_cards_lock);
56
57/* add your revision and whatnot here */
58static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
59 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
60 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
61 {0,}
62};
63
64MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
65
66/* Parameter declarations */
67static int cardtype[CX18_MAX_CARDS];
68static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1,
71 -1, -1, -1, -1, -1, -1, -1, -1 };
72static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 };
76
77static int cardtype_c = 1;
78static int tuner_c = 1;
79static int radio_c = 1;
80static char pal[] = "--";
81static char secam[] = "--";
82static char ntsc[] = "-";
83
84/* Buffers */
85static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
86static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
87static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
88static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
89static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
90
91static int cx18_pci_latency = 1;
92
93int cx18_debug;
94
95module_param_array(tuner, int, &tuner_c, 0644);
96module_param_array(radio, bool, &radio_c, 0644);
97module_param_array(cardtype, int, &cardtype_c, 0644);
98module_param_string(pal, pal, sizeof(pal), 0644);
99module_param_string(secam, secam, sizeof(secam), 0644);
100module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
101module_param_named(debug, cx18_debug, int, 0644);
102module_param(cx18_pci_latency, int, 0644);
103module_param(cx18_first_minor, int, 0644);
104
105module_param(enc_mpg_buffers, int, 0644);
106module_param(enc_ts_buffers, int, 0644);
107module_param(enc_yuv_buffers, int, 0644);
108module_param(enc_vbi_buffers, int, 0644);
109module_param(enc_pcm_buffers, int, 0644);
110
111MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
112 "\t\t\tsee tuner.h for values");
113MODULE_PARM_DESC(radio,
114 "Enable or disable the radio. Use only if autodetection\n"
115 "\t\t\tfails. 0 = disable, 1 = enable");
116MODULE_PARM_DESC(cardtype,
117 "Only use this option if your card is not detected properly.\n"
118 "\t\tSpecify card type:\n"
119 "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
120 "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
121 "\t\t\t 3 = Compro VideoMate H900\n"
122 "\t\t\t 4 = Yuan MPC718\n"
123 "\t\t\t 0 = Autodetect (default)\n"
124 "\t\t\t-1 = Ignore this card\n\t\t");
125MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
126MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
127MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
128MODULE_PARM_DESC(debug,
129 "Debug level (bitmask). Default: 0\n"
130 "\t\t\t 1/0x0001: warning\n"
131 "\t\t\t 2/0x0002: info\n"
132 "\t\t\t 4/0x0004: mailbox\n"
133 "\t\t\t 8/0x0008: dma\n"
134 "\t\t\t 16/0x0010: ioctl\n"
135 "\t\t\t 32/0x0020: file\n"
136 "\t\t\t 64/0x0040: i2c\n"
137 "\t\t\t128/0x0080: irq\n"
138 "\t\t\t256/0x0100: high volume\n");
139MODULE_PARM_DESC(cx18_pci_latency,
140 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
141 "\t\t\tDefault: Yes");
142MODULE_PARM_DESC(enc_mpg_buffers,
143 "Encoder MPG Buffers (in MB)\n"
144 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
145MODULE_PARM_DESC(enc_ts_buffers,
146 "Encoder TS Buffers (in MB)\n"
147 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
148MODULE_PARM_DESC(enc_yuv_buffers,
149 "Encoder YUV Buffers (in MB)\n"
150 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
151MODULE_PARM_DESC(enc_vbi_buffers,
152 "Encoder VBI Buffers (in MB)\n"
153 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
154MODULE_PARM_DESC(enc_pcm_buffers,
155 "Encoder PCM buffers (in MB)\n"
156 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
157
158MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card");
159
160MODULE_AUTHOR("Hans Verkuil");
161MODULE_DESCRIPTION("CX23418 driver");
162MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
163MODULE_LICENSE("GPL");
164
165MODULE_VERSION(CX18_VERSION);
166
167int cx18_waitq(wait_queue_head_t *waitq)
168{
169 DEFINE_WAIT(wait);
170
171 prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
172 schedule();
173 finish_wait(waitq, &wait);
174 return signal_pending(current) ? -EINTR : 0;
175}
176
177/* Generic utility functions */
178int cx18_msleep_timeout(unsigned int msecs, int intr)
179{
180 int timeout = msecs_to_jiffies(msecs);
181 int sig;
182
183 do {
184 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
185 timeout = schedule_timeout(timeout);
186 sig = intr ? signal_pending(current) : 0;
187 } while (!sig && timeout);
188 return sig;
189}
190
191/* Release ioremapped memory */
192static void cx18_iounmap(struct cx18 *cx)
193{
194 if (cx == NULL)
195 return;
196
197 /* Release io memory */
198 if (cx->enc_mem != NULL) {
199 CX18_DEBUG_INFO("releasing enc_mem\n");
200 iounmap(cx->enc_mem);
201 cx->enc_mem = NULL;
202 }
203}
204
205/* Hauppauge card? get values from tveeprom */
206void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
207{
208 u8 eedata[256];
209
210 cx->i2c_client[0].addr = 0xA0 >> 1;
211 tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
212 tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
213}
214
215static void cx18_process_eeprom(struct cx18 *cx)
216{
217 struct tveeprom tv;
218
219 cx18_read_eeprom(cx, &tv);
220
221 /* Many thanks to Steven Toth from Hauppauge for providing the
222 model numbers */
223 switch (tv.model) {
224 case 74000 ... 74099:
225 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
226 break;
227 case 74700 ... 74799:
228 cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
229 break;
230 case 0:
231 CX18_ERR("Invalid EEPROM\n");
232 return;
233 default:
234 CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model);
235 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
236 break;
237 }
238
239 cx->v4l2_cap = cx->card->v4l2_capabilities;
240 cx->card_name = cx->card->name;
241 cx->card_i2c = cx->card->i2c;
242
243 CX18_INFO("Autodetected %s\n", cx->card_name);
244
245 if (tv.tuner_type == TUNER_ABSENT)
246 CX18_ERR("tveeprom cannot autodetect tuner!");
247
248 if (cx->options.tuner == -1)
249 cx->options.tuner = tv.tuner_type;
250 if (cx->options.radio == -1)
251 cx->options.radio = (tv.has_radio != 0);
252
253 if (cx->std != 0)
254 /* user specified tuner standard */
255 return;
256
257 /* autodetect tuner standard */
258 if (tv.tuner_formats & V4L2_STD_PAL) {
259 CX18_DEBUG_INFO("PAL tuner detected\n");
260 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
261 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
262 CX18_DEBUG_INFO("NTSC tuner detected\n");
263 cx->std |= V4L2_STD_NTSC_M;
264 } else if (tv.tuner_formats & V4L2_STD_SECAM) {
265 CX18_DEBUG_INFO("SECAM tuner detected\n");
266 cx->std |= V4L2_STD_SECAM_L;
267 } else {
268 CX18_INFO("No tuner detected, default to NTSC-M\n");
269 cx->std |= V4L2_STD_NTSC_M;
270 }
271}
272
273static v4l2_std_id cx18_parse_std(struct cx18 *cx)
274{
275 switch (pal[0]) {
276 case '6':
277 return V4L2_STD_PAL_60;
278 case 'b':
279 case 'B':
280 case 'g':
281 case 'G':
282 return V4L2_STD_PAL_BG;
283 case 'h':
284 case 'H':
285 return V4L2_STD_PAL_H;
286 case 'n':
287 case 'N':
288 if (pal[1] == 'c' || pal[1] == 'C')
289 return V4L2_STD_PAL_Nc;
290 return V4L2_STD_PAL_N;
291 case 'i':
292 case 'I':
293 return V4L2_STD_PAL_I;
294 case 'd':
295 case 'D':
296 case 'k':
297 case 'K':
298 return V4L2_STD_PAL_DK;
299 case 'M':
300 case 'm':
301 return V4L2_STD_PAL_M;
302 case '-':
303 break;
304 default:
305 CX18_WARN("pal= argument not recognised\n");
306 return 0;
307 }
308
309 switch (secam[0]) {
310 case 'b':
311 case 'B':
312 case 'g':
313 case 'G':
314 case 'h':
315 case 'H':
316 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
317 case 'd':
318 case 'D':
319 case 'k':
320 case 'K':
321 return V4L2_STD_SECAM_DK;
322 case 'l':
323 case 'L':
324 if (secam[1] == 'C' || secam[1] == 'c')
325 return V4L2_STD_SECAM_LC;
326 return V4L2_STD_SECAM_L;
327 case '-':
328 break;
329 default:
330 CX18_WARN("secam= argument not recognised\n");
331 return 0;
332 }
333
334 switch (ntsc[0]) {
335 case 'm':
336 case 'M':
337 return V4L2_STD_NTSC_M;
338 case 'j':
339 case 'J':
340 return V4L2_STD_NTSC_M_JP;
341 case 'k':
342 case 'K':
343 return V4L2_STD_NTSC_M_KR;
344 case '-':
345 break;
346 default:
347 CX18_WARN("ntsc= argument not recognised\n");
348 return 0;
349 }
350
351 /* no match found */
352 return 0;
353}
354
355static void cx18_process_options(struct cx18 *cx)
356{
357 int i, j;
358
359 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
360 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
361 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
362 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
363 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
364 cx->options.cardtype = cardtype[cx->num];
365 cx->options.tuner = tuner[cx->num];
366 cx->options.radio = radio[cx->num];
367
368 cx->std = cx18_parse_std(cx);
369 if (cx->options.cardtype == -1) {
370 CX18_INFO("Ignore card\n");
371 return;
372 }
373 cx->card = cx18_get_card(cx->options.cardtype - 1);
374 if (cx->card)
375 CX18_INFO("User specified %s card\n", cx->card->name);
376 else if (cx->options.cardtype != 0)
377 CX18_ERR("Unknown user specified type, trying to autodetect card\n");
378 if (cx->card == NULL) {
379 if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
380 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
381 CX18_INFO("Autodetected Hauppauge card\n");
382 }
383 }
384 if (cx->card == NULL) {
385 for (i = 0; (cx->card = cx18_get_card(i)); i++) {
386 if (cx->card->pci_list == NULL)
387 continue;
388 for (j = 0; cx->card->pci_list[j].device; j++) {
389 if (cx->dev->device !=
390 cx->card->pci_list[j].device)
391 continue;
392 if (cx->dev->subsystem_vendor !=
393 cx->card->pci_list[j].subsystem_vendor)
394 continue;
395 if (cx->dev->subsystem_device !=
396 cx->card->pci_list[j].subsystem_device)
397 continue;
398 CX18_INFO("Autodetected %s card\n", cx->card->name);
399 goto done;
400 }
401 }
402 }
403done:
404
405 if (cx->card == NULL) {
406 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
407 CX18_ERR("Unknown card: vendor/device: %04x/%04x\n",
408 cx->dev->vendor, cx->dev->device);
409 CX18_ERR(" subsystem vendor/device: %04x/%04x\n",
410 cx->dev->subsystem_vendor, cx->dev->subsystem_device);
411 CX18_ERR("Defaulting to %s card\n", cx->card->name);
412 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
413 CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
414 CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
415 }
416 cx->v4l2_cap = cx->card->v4l2_capabilities;
417 cx->card_name = cx->card->name;
418 cx->card_i2c = cx->card->i2c;
419}
420
421/* Precondition: the cx18 structure has been memset to 0. Only
422 the dev and num fields have been filled in.
423 No assumptions on the card type may be made here (see cx18_init_struct2
424 for that).
425 */
426static int __devinit cx18_init_struct1(struct cx18 *cx)
427{
428 cx->base_addr = pci_resource_start(cx->dev, 0);
429
430 mutex_init(&cx->serialize_lock);
431 mutex_init(&cx->i2c_bus_lock[0]);
432 mutex_init(&cx->i2c_bus_lock[1]);
433
434 spin_lock_init(&cx->lock);
435 spin_lock_init(&cx->dma_reg_lock);
436
437 /* start counting open_id at 1 */
438 cx->open_id = 1;
439
440 /* Initial settings */
441 cx2341x_fill_defaults(&cx->params);
442 cx->temporal_strength = cx->params.video_temporal_filter;
443 cx->spatial_strength = cx->params.video_spatial_filter;
444 cx->filter_mode = cx->params.video_spatial_filter_mode |
445 (cx->params.video_temporal_filter_mode << 1) |
446 (cx->params.video_median_filter_type << 2);
447 cx->params.port = CX2341X_PORT_MEMORY;
448 cx->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
449 init_waitqueue_head(&cx->cap_w);
450 init_waitqueue_head(&cx->mb_apu_waitq);
451 init_waitqueue_head(&cx->mb_cpu_waitq);
452 init_waitqueue_head(&cx->mb_epu_waitq);
453 init_waitqueue_head(&cx->mb_hpu_waitq);
454 init_waitqueue_head(&cx->dma_waitq);
455
456 /* VBI */
457 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
458 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
459 cx->vbi.raw_size = 1456;
460 cx->vbi.raw_decoder_line_size = 1456;
461 cx->vbi.raw_decoder_sav_odd_field = 0x20;
462 cx->vbi.raw_decoder_sav_even_field = 0x60;
463 cx->vbi.sliced_decoder_line_size = 272;
464 cx->vbi.sliced_decoder_sav_odd_field = 0xB0;
465 cx->vbi.sliced_decoder_sav_even_field = 0xF0;
466 return 0;
467}
468
469/* Second initialization part. Here the card type has been
470 autodetected. */
471static void __devinit cx18_init_struct2(struct cx18 *cx)
472{
473 int i;
474
475 for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
476 if (cx->card->video_inputs[i].video_type == 0)
477 break;
478 cx->nof_inputs = i;
479 for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
480 if (cx->card->audio_inputs[i].audio_type == 0)
481 break;
482 cx->nof_audio_inputs = i;
483
484 /* Find tuner input */
485 for (i = 0; i < cx->nof_inputs; i++) {
486 if (cx->card->video_inputs[i].video_type ==
487 CX18_CARD_INPUT_VID_TUNER)
488 break;
489 }
490 if (i == cx->nof_inputs)
491 i = 0;
492 cx->active_input = i;
493 cx->audio_input = cx->card->video_inputs[i].audio_index;
494 cx->av_state.vid_input = CX18_AV_COMPOSITE7;
495 cx->av_state.aud_input = CX18_AV_AUDIO8;
496 cx->av_state.audclk_freq = 48000;
497 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
498 cx->av_state.vbi_line_offset = 8;
499}
500
501static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
502 const struct pci_device_id *pci_id)
503{
504 u16 cmd;
505 unsigned char pci_latency;
506
507 CX18_DEBUG_INFO("Enabling pci device\n");
508
509 if (pci_enable_device(dev)) {
510 CX18_ERR("Can't enable device %d!\n", cx->num);
511 return -EIO;
512 }
513 if (pci_set_dma_mask(dev, 0xffffffff)) {
514 CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
515 return -EIO;
516 }
517 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
518 CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
519 return -EIO;
520 }
521
522 /* Check for bus mastering */
523 pci_read_config_word(dev, PCI_COMMAND, &cmd);
524 cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
525 pci_write_config_word(dev, PCI_COMMAND, cmd);
526
527 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
528 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
529
530 if (pci_latency < 64 && cx18_pci_latency) {
531 CX18_INFO("Unreasonably low latency timer, "
532 "setting to 64 (was %d)\n", pci_latency);
533 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
534 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
535 }
536 /* This config space value relates to DMA latencies. The
537 default value 0x8080 is too low however and will lead
538 to DMA errors. 0xffff is the max value which solves
539 these problems. */
540 pci_write_config_dword(dev, 0x40, 0xffff);
541
542 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
543 "irq: %d, latency: %d, memory: 0x%lx\n",
544 cx->dev->device, cx->card_rev, dev->bus->number,
545 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
546 cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
547
548 return 0;
549}
550
551static u32 cx18_request_module(struct cx18 *cx, u32 hw,
552 const char *name, u32 id)
553{
554 if ((hw & id) == 0)
555 return hw;
556 if (request_module(name) != 0) {
557 CX18_ERR("Failed to load module %s\n", name);
558 return hw & ~id;
559 }
560 CX18_DEBUG_INFO("Loaded module %s\n", name);
561 return hw;
562}
563
564static void cx18_load_and_init_modules(struct cx18 *cx)
565{
566 u32 hw = cx->card->hw_all;
567 int i;
568
569 /* load modules */
570#ifndef CONFIG_VIDEO_TUNER
571 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
572#endif
573#ifndef CONFIG_VIDEO_CS5345
574 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
575#endif
576
577 /* check which i2c devices are actually found */
578 for (i = 0; i < 32; i++) {
579 u32 device = 1 << i;
580
581 if (!(device & hw))
582 continue;
583 if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
584 device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
585 /* These 'devices' do not use i2c probing */
586 cx->hw_flags |= device;
587 continue;
588 }
589 cx18_i2c_register(cx, i);
590 if (cx18_i2c_hw_addr(cx, device) > 0)
591 cx->hw_flags |= device;
592 }
593
594 hw = cx->hw_flags;
595}
596
597static int __devinit cx18_probe(struct pci_dev *dev,
598 const struct pci_device_id *pci_id)
599{
600 int retval = 0;
601 int vbi_buf_size;
602 u32 devtype;
603 struct cx18 *cx;
604
605 spin_lock(&cx18_cards_lock);
606
607 /* Make sure we've got a place for this card */
608 if (cx18_cards_active == CX18_MAX_CARDS) {
609 printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
610 cx18_cards_active);
611 spin_unlock(&cx18_cards_lock);
612 return -ENOMEM;
613 }
614
615 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
616 if (cx == 0) {
617 spin_unlock(&cx18_cards_lock);
618 return -ENOMEM;
619 }
620 cx18_cards[cx18_cards_active] = cx;
621 cx->dev = dev;
622 cx->num = cx18_cards_active++;
623 snprintf(cx->name, sizeof(cx->name) - 1, "cx18-%d", cx->num);
624 CX18_INFO("Initializing card #%d\n", cx->num);
625
626 spin_unlock(&cx18_cards_lock);
627
628 cx18_process_options(cx);
629 if (cx->options.cardtype == -1) {
630 retval = -ENODEV;
631 goto err;
632 }
633 if (cx18_init_struct1(cx)) {
634 retval = -ENOMEM;
635 goto err;
636 }
637
638 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
639
640 /* PCI Device Setup */
641 retval = cx18_setup_pci(cx, dev, pci_id);
642 if (retval != 0) {
643 if (retval == -EIO)
644 goto free_workqueue;
645 else if (retval == -ENXIO)
646 goto free_mem;
647 }
648 /* save cx in the pci struct for later use */
649 pci_set_drvdata(dev, cx);
650
651 /* map io memory */
652 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
653 cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
654 cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
655 CX18_MEM_SIZE);
656 if (!cx->enc_mem) {
657 CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
658 CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
659 retval = -ENOMEM;
660 goto free_mem;
661 }
662 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
663 devtype = read_reg(0xC72028);
664 switch (devtype & 0xff000000) {
665 case 0xff000000:
666 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
667 break;
668 case 0x01000000:
669 CX18_INFO("cx23418 revision %08x (B)\n", devtype);
670 break;
671 default:
672 CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
673 break;
674 }
675
676 cx18_init_power(cx, 1);
677 cx18_init_memory(cx);
678
679 cx->scb = (struct cx18_scb *)(cx->enc_mem + SCB_OFFSET);
680 cx18_init_scb(cx);
681
682 cx18_gpio_init(cx);
683
684 /* active i2c */
685 CX18_DEBUG_INFO("activating i2c...\n");
686 if (init_cx18_i2c(cx)) {
687 CX18_ERR("Could not initialize i2c\n");
688 goto free_map;
689 }
690
691 CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
692
693 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
694 /* Based on the model number the cardtype may be changed.
695 The PCI IDs are not always reliable. */
696 cx18_process_eeprom(cx);
697 }
698 if (cx->card->comment)
699 CX18_INFO("%s", cx->card->comment);
700 if (cx->card->v4l2_capabilities == 0) {
701 retval = -ENODEV;
702 goto free_i2c;
703 }
704 cx18_init_memory(cx);
705
706 /* Register IRQ */
707 retval = request_irq(cx->dev->irq, cx18_irq_handler,
708 IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
709 if (retval) {
710 CX18_ERR("Failed to register irq %d\n", retval);
711 goto free_i2c;
712 }
713
714 if (cx->std == 0)
715 cx->std = V4L2_STD_NTSC_M;
716
717 if (cx->options.tuner == -1) {
718 int i;
719
720 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
721 if ((cx->std & cx->card->tuners[i].std) == 0)
722 continue;
723 cx->options.tuner = cx->card->tuners[i].tuner;
724 break;
725 }
726 }
727 /* if no tuner was found, then pick the first tuner in the card list */
728 if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
729 cx->std = cx->card->tuners[0].std;
730 cx->options.tuner = cx->card->tuners[0].tuner;
731 }
732 if (cx->options.radio == -1)
733 cx->options.radio = (cx->card->radio_input.audio_type != 0);
734
735 /* The card is now fully identified, continue with card-specific
736 initialization. */
737 cx18_init_struct2(cx);
738
739 cx18_load_and_init_modules(cx);
740
741 if (cx->std & V4L2_STD_525_60) {
742 cx->is_60hz = 1;
743 cx->is_out_60hz = 1;
744 } else {
745 cx->is_50hz = 1;
746 cx->is_out_50hz = 1;
747 }
748 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
749
750 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000;
751 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000;
752 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200;
753 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000;
754 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
755 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
756
757 if (cx->options.radio > 0)
758 cx->v4l2_cap |= V4L2_CAP_RADIO;
759
760 retval = cx18_streams_setup(cx);
761 if (retval) {
762 CX18_ERR("Error %d setting up streams\n", retval);
763 goto free_irq;
764 }
765 retval = cx18_streams_register(cx);
766 if (retval) {
767 CX18_ERR("Error %d registering devices\n", retval);
768 goto free_streams;
769 }
770
771 if (cx->options.tuner > -1) {
772 struct tuner_setup setup;
773
774 setup.addr = ADDR_UNSET;
775 setup.type = cx->options.tuner;
776 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
777 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
778 cx18_reset_tuner_gpio : NULL;
779 cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
780 if (setup.type == TUNER_XC2028) {
781 static struct xc2028_ctrl ctrl = {
782 .fname = XC2028_DEFAULT_FIRMWARE,
783 .max_len = 64,
784 };
785 struct v4l2_priv_tun_config cfg = {
786 .tuner = cx->options.tuner,
787 .priv = &ctrl,
788 };
789 cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
790 }
791 }
792
793 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
794 are not. */
795 cx->tuner_std = cx->std;
796
797 cx18_init_on_first_open(cx);
798
799 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
800
801 return 0;
802
803free_streams:
804 cx18_streams_cleanup(cx);
805free_irq:
806 free_irq(cx->dev->irq, (void *)cx);
807free_i2c:
808 exit_cx18_i2c(cx);
809free_map:
810 cx18_iounmap(cx);
811free_mem:
812 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
813free_workqueue:
814err:
815 if (retval == 0)
816 retval = -ENODEV;
817 CX18_ERR("Error %d on initialization\n", retval);
818
819 kfree(cx18_cards[cx18_cards_active]);
820 cx18_cards[cx18_cards_active] = NULL;
821 return retval;
822}
823
824int cx18_init_on_first_open(struct cx18 *cx)
825{
826 int video_input;
827 int fw_retry_count = 3;
828 struct v4l2_frequency vf;
829
830 if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
831 return -ENXIO;
832
833 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
834 return 0;
835
836 while (--fw_retry_count > 0) {
837 /* load firmware */
838 if (cx18_firmware_init(cx) == 0)
839 break;
840 if (fw_retry_count > 1)
841 CX18_WARN("Retry loading firmware\n");
842 }
843
844 if (fw_retry_count == 0) {
845 set_bit(CX18_F_I_FAILED, &cx->i_flags);
846 return -ENXIO;
847 }
848 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
849
850 /* Init the firmware twice to work around a silicon bug
851 * transport related. */
852
853 fw_retry_count = 3;
854 while (--fw_retry_count > 0) {
855 /* load firmware */
856 if (cx18_firmware_init(cx) == 0)
857 break;
858 if (fw_retry_count > 1)
859 CX18_WARN("Retry loading firmware\n");
860 }
861
862 if (fw_retry_count == 0) {
863 set_bit(CX18_F_I_FAILED, &cx->i_flags);
864 return -ENXIO;
865 }
866
867 vf.tuner = 0;
868 vf.type = V4L2_TUNER_ANALOG_TV;
869 vf.frequency = 6400; /* the tuner 'baseline' frequency */
870
871 /* Set initial frequency. For PAL/SECAM broadcasts no
872 'default' channel exists AFAIK. */
873 if (cx->std == V4L2_STD_NTSC_M_JP)
874 vf.frequency = 1460; /* ch. 1 91250*16/1000 */
875 else if (cx->std & V4L2_STD_NTSC_M)
876 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
877
878 video_input = cx->active_input;
879 cx->active_input++; /* Force update of input */
880 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_INPUT, &video_input);
881
882 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
883 in one place. */
884 cx->std++; /* Force full standard initialization */
885 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_STD, &cx->tuner_std);
886 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_FREQUENCY, &vf);
887 return 0;
888}
889
890static void cx18_remove(struct pci_dev *pci_dev)
891{
892 struct cx18 *cx = pci_get_drvdata(pci_dev);
893
894 CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
895
896 /* Stop all captures */
897 CX18_DEBUG_INFO("Stopping all streams\n");
898 if (atomic_read(&cx->capturing) > 0)
899 cx18_stop_all_captures(cx);
900
901 /* Interrupts */
902 sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
903 sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
904
905 cx18_halt_firmware(cx);
906
907 cx18_streams_cleanup(cx);
908
909 exit_cx18_i2c(cx);
910
911 free_irq(cx->dev->irq, (void *)cx);
912
913 if (cx->dev)
914 cx18_iounmap(cx);
915
916 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
917
918 pci_disable_device(cx->dev);
919
920 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
921}
922
923/* define a pci_driver for card detection */
924static struct pci_driver cx18_pci_driver = {
925 .name = "cx18",
926 .id_table = cx18_pci_tbl,
927 .probe = cx18_probe,
928 .remove = cx18_remove,
929};
930
931static int module_start(void)
932{
933 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
934
935 memset(cx18_cards, 0, sizeof(cx18_cards));
936
937 /* Validate parameters */
938 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
939 printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n",
940 CX18_MAX_CARDS - 1);
941 return -1;
942 }
943
944 if (cx18_debug < 0 || cx18_debug > 511) {
945 cx18_debug = 0;
946 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
947 }
948
949 if (pci_register_driver(&cx18_pci_driver)) {
950 printk(KERN_ERR "cx18: Error detecting PCI card\n");
951 return -ENODEV;
952 }
953 printk(KERN_INFO "cx18: End initialization\n");
954 return 0;
955}
956
957static void module_cleanup(void)
958{
959 int i;
960
961 pci_unregister_driver(&cx18_pci_driver);
962
963 for (i = 0; i < cx18_cards_active; i++) {
964 if (cx18_cards[i] == NULL)
965 continue;
966 kfree(cx18_cards[i]);
967 }
968}
969
970module_init(module_start);
971module_exit(module_cleanup);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
new file mode 100644
index 000000000000..2ee939193bb7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -0,0 +1,500 @@
1/*
2 * cx18 driver internal defines and structures
3 *
4 * Derived from ivtv-driver.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#ifndef CX18_DRIVER_H
25#define CX18_DRIVER_H
26
27#include <linux/version.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/fs.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/spinlock.h>
37#include <linux/i2c.h>
38#include <linux/i2c-algo-bit.h>
39#include <linux/list.h>
40#include <linux/unistd.h>
41#include <linux/byteorder/swab.h>
42#include <linux/pagemap.h>
43#include <linux/workqueue.h>
44#include <linux/mutex.h>
45
46#include <linux/dvb/video.h>
47#include <linux/dvb/audio.h>
48#include <media/v4l2-common.h>
49#include <media/tuner.h>
50#include "cx18-mailbox.h"
51#include "cx18-av-core.h"
52#include "cx23418.h"
53
54/* DVB */
55#include "demux.h"
56#include "dmxdev.h"
57#include "dvb_demux.h"
58#include "dvb_frontend.h"
59#include "dvb_net.h"
60#include "dvbdev.h"
61
62#ifndef CONFIG_PCI
63# error "This driver requires kernel PCI support."
64#endif
65
66#define CX18_MEM_OFFSET 0x00000000
67#define CX18_MEM_SIZE 0x04000000
68#define CX18_REG_OFFSET 0x02000000
69
70/* Maximum cx18 driver instances. */
71#define CX18_MAX_CARDS 32
72
73/* Supported cards */
74#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
75#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
76#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
77#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
78#define CX18_CARD_LAST 3
79
80#define CX18_ENC_STREAM_TYPE_MPG 0
81#define CX18_ENC_STREAM_TYPE_TS 1
82#define CX18_ENC_STREAM_TYPE_YUV 2
83#define CX18_ENC_STREAM_TYPE_VBI 3
84#define CX18_ENC_STREAM_TYPE_PCM 4
85#define CX18_ENC_STREAM_TYPE_IDX 5
86#define CX18_ENC_STREAM_TYPE_RAD 6
87#define CX18_MAX_STREAMS 7
88
89/* system vendor and device IDs */
90#define PCI_VENDOR_ID_CX 0x14f1
91#define PCI_DEVICE_ID_CX23418 0x5b7a
92
93/* subsystem vendor ID */
94#define CX18_PCI_ID_HAUPPAUGE 0x0070
95#define CX18_PCI_ID_COMPRO 0x185b
96#define CX18_PCI_ID_YUAN 0x12ab
97
98/* ======================================================================== */
99/* ========================== START USER SETTABLE DMA VARIABLES =========== */
100/* ======================================================================== */
101
102/* DMA Buffers, Default size in MB allocated */
103#define CX18_DEFAULT_ENC_TS_BUFFERS 1
104#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
105#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
106#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
107#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
108#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
109
110/* i2c stuff */
111#define I2C_CLIENTS_MAX 16
112
113/* debugging */
114
115/* Flag to turn on high volume debugging */
116#define CX18_DBGFLG_WARN (1 << 0)
117#define CX18_DBGFLG_INFO (1 << 1)
118#define CX18_DBGFLG_API (1 << 2)
119#define CX18_DBGFLG_DMA (1 << 3)
120#define CX18_DBGFLG_IOCTL (1 << 4)
121#define CX18_DBGFLG_FILE (1 << 5)
122#define CX18_DBGFLG_I2C (1 << 6)
123#define CX18_DBGFLG_IRQ (1 << 7)
124/* Flag to turn on high volume debugging */
125#define CX18_DBGFLG_HIGHVOL (1 << 8)
126
127/* NOTE: extra space before comma in 'cx->num , ## args' is required for
128 gcc-2.95, otherwise it won't compile. */
129#define CX18_DEBUG(x, type, fmt, args...) \
130 do { \
131 if ((x) & cx18_debug) \
132 printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
133 } while (0)
134#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
135#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
136#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
137#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
138#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
139#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
140#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
141#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
142
143#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
144 do { \
145 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
146 printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
147 } while (0)
148#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
149#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
150#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
151#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
152#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
153#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
154#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
155#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
156
157/* Standard kernel messages */
158#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
159#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
160#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
161
162/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
163#define MPEG_FRAME_TYPE_IFRAME 1
164#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
165#define MPEG_FRAME_TYPE_ALL 7
166
167#define CX18_MAX_PGM_INDEX (400)
168
169extern int cx18_debug;
170
171
172struct cx18_options {
173 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
174 int cardtype; /* force card type on load */
175 int tuner; /* set tuner on load */
176 int radio; /* enable/disable radio */
177};
178
179/* per-buffer bit flags */
180#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */
181
182/* per-stream, s_flags */
183#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
184#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
185#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
186#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
187#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
188
189/* per-cx18, i_flags */
190#define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */
191#define CX18_F_I_EOS 4 /* End of encoder stream reached */
192#define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */
193#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
194#define CX18_F_I_INITED 21 /* set after first open */
195#define CX18_F_I_FAILED 22 /* set if first open failed */
196
197/* These are the VBI types as they appear in the embedded VBI private packets. */
198#define CX18_SLICED_TYPE_TELETEXT_B (1)
199#define CX18_SLICED_TYPE_CAPTION_525 (4)
200#define CX18_SLICED_TYPE_WSS_625 (5)
201#define CX18_SLICED_TYPE_VPS (7)
202
203struct cx18_buffer {
204 struct list_head list;
205 dma_addr_t dma_handle;
206 u32 id;
207 unsigned long b_flags;
208 char *buf;
209
210 u32 bytesused;
211 u32 readpos;
212};
213
214struct cx18_queue {
215 struct list_head list;
216 u32 buffers;
217 u32 length;
218 u32 bytesused;
219};
220
221struct cx18_dvb {
222 struct dmx_frontend hw_frontend;
223 struct dmx_frontend mem_frontend;
224 struct dmxdev dmxdev;
225 struct dvb_adapter dvb_adapter;
226 struct dvb_demux demux;
227 struct dvb_frontend *fe;
228 struct dvb_net dvbnet;
229 int enabled;
230 int feeding;
231
232 struct mutex feedlock;
233
234};
235
236struct cx18; /* forward reference */
237struct cx18_scb; /* forward reference */
238
239struct cx18_stream {
240 /* These first four fields are always set, even if the stream
241 is not actually created. */
242 struct video_device *v4l2dev; /* NULL when stream not created */
243 struct cx18 *cx; /* for ease of use */
244 const char *name; /* name of the stream */
245 int type; /* stream type */
246 u32 handle; /* task handle */
247 unsigned mdl_offset;
248
249 u32 id;
250 spinlock_t qlock; /* locks access to the queues */
251 unsigned long s_flags; /* status flags, see above */
252 int dma; /* can be PCI_DMA_TODEVICE,
253 PCI_DMA_FROMDEVICE or
254 PCI_DMA_NONE */
255 u64 dma_pts;
256 wait_queue_head_t waitq;
257
258 /* Buffer Stats */
259 u32 buffers;
260 u32 buf_size;
261 u32 buffers_stolen;
262
263 /* Buffer Queues */
264 struct cx18_queue q_free; /* free buffers */
265 struct cx18_queue q_full; /* full buffers */
266 struct cx18_queue q_io; /* waiting for I/O */
267
268 /* DVB / Digital Transport */
269 struct cx18_dvb dvb;
270};
271
272struct cx18_open_id {
273 u32 open_id;
274 int type;
275 enum v4l2_priority prio;
276 struct cx18 *cx;
277};
278
279/* forward declaration of struct defined in cx18-cards.h */
280struct cx18_card;
281
282
283#define CX18_VBI_FRAMES 32
284
285/* VBI data */
286struct vbi_info {
287 u32 enc_size;
288 u32 frame;
289 u8 cc_data_odd[256];
290 u8 cc_data_even[256];
291 int cc_pos;
292 u8 cc_no_update;
293 u8 vps[5];
294 u8 vps_found;
295 int wss;
296 u8 wss_found;
297 u8 wss_no_update;
298 u32 raw_decoder_line_size;
299 u8 raw_decoder_sav_odd_field;
300 u8 raw_decoder_sav_even_field;
301 u32 sliced_decoder_line_size;
302 u8 sliced_decoder_sav_odd_field;
303 u8 sliced_decoder_sav_even_field;
304 struct v4l2_format in;
305 /* convenience pointer to sliced struct in vbi_in union */
306 struct v4l2_sliced_vbi_format *sliced_in;
307 u32 service_set_in;
308 int insert_mpeg;
309
310 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
311 One for /dev/vbi0 and one for /dev/vbi8 */
312 struct v4l2_sliced_vbi_data sliced_data[36];
313
314 /* Buffer for VBI data inserted into MPEG stream.
315 The first byte is a dummy byte that's never used.
316 The next 16 bytes contain the MPEG header for the VBI data,
317 the remainder is the actual VBI data.
318 The max size accepted by the MPEG VBI reinsertion turns out
319 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
320 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
321 a single line header byte and 2 * 18 is the number of VBI lines per frame.
322
323 However, it seems that the data must be 1K aligned, so we have to
324 pad the data until the 1 or 2 K boundary.
325
326 This pointer array will allocate 2049 bytes to store each VBI frame. */
327 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
328 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
329 struct cx18_buffer sliced_mpeg_buf;
330 u32 inserted_frame;
331
332 u32 start[2], count;
333 u32 raw_size;
334 u32 sliced_size;
335};
336
337/* Per cx23418, per I2C bus private algo callback data */
338struct cx18_i2c_algo_callback_data {
339 struct cx18 *cx;
340 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
341};
342
343/* Struct to hold info about cx18 cards */
344struct cx18 {
345 int num; /* board number, -1 during init! */
346 char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
347 struct pci_dev *dev; /* PCI device */
348 const struct cx18_card *card; /* card information */
349 const char *card_name; /* full name of the card */
350 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
351 u8 is_50hz;
352 u8 is_60hz;
353 u8 is_out_50hz;
354 u8 is_out_60hz;
355 u8 nof_inputs; /* number of video inputs */
356 u8 nof_audio_inputs; /* number of audio inputs */
357 u16 buffer_id; /* buffer ID counter */
358 u32 v4l2_cap; /* V4L2 capabilities of card */
359 u32 hw_flags; /* Hardware description of the board */
360 unsigned mdl_offset;
361 struct cx18_scb *scb; /* pointer to SCB */
362
363 struct cx18_av_state av_state;
364
365 /* codec settings */
366 struct cx2341x_mpeg_params params;
367 u32 filter_mode;
368 u32 temporal_strength;
369 u32 spatial_strength;
370
371 /* dualwatch */
372 unsigned long dualwatch_jiffies;
373 u16 dualwatch_stereo_mode;
374
375 /* Digitizer type */
376 int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
377
378 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
379 struct cx18_options options; /* User options */
380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
382 unsigned long i_flags; /* global cx18 flags */
383 atomic_t capturing; /* count number of active capture streams */
384 spinlock_t lock; /* lock access to this struct */
385 int search_pack_header;
386
387 spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
388
389 int open_id; /* incremented each time an open occurs, used as
390 unique ID. Starts at 1, so 0 can be used as
391 uninitialized value in the stream->id. */
392
393 u32 base_addr;
394 struct v4l2_prio_state prio;
395
396 u8 card_rev;
397 void __iomem *enc_mem, *reg_mem;
398
399 struct vbi_info vbi;
400
401 u32 pgm_info_offset;
402 u32 pgm_info_num;
403 u32 pgm_info_write_idx;
404 u32 pgm_info_read_idx;
405 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
406
407 u64 mpg_data_received;
408 u64 vbi_data_inserted;
409
410 wait_queue_head_t mb_apu_waitq;
411 wait_queue_head_t mb_cpu_waitq;
412 wait_queue_head_t mb_epu_waitq;
413 wait_queue_head_t mb_hpu_waitq;
414 wait_queue_head_t cap_w;
415 /* when the current DMA is finished this queue is woken up */
416 wait_queue_head_t dma_waitq;
417
418 /* i2c */
419 struct i2c_adapter i2c_adap[2];
420 struct i2c_algo_bit_data i2c_algo[2];
421 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
422 struct i2c_client i2c_client[2];
423 struct mutex i2c_bus_lock[2];
424 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
425
426 /* v4l2 and User settings */
427
428 /* codec settings */
429 u32 audio_input;
430 u32 active_input;
431 u32 active_output;
432 v4l2_std_id std;
433 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
434};
435
436/* Globals */
437extern struct cx18 *cx18_cards[];
438extern int cx18_cards_active;
439extern int cx18_first_minor;
440extern spinlock_t cx18_cards_lock;
441
442/*==============Prototypes==================*/
443
444/* Return non-zero if a signal is pending */
445int cx18_msleep_timeout(unsigned int msecs, int intr);
446
447/* Wait on queue, returns -EINTR if interrupted */
448int cx18_waitq(wait_queue_head_t *waitq);
449
450/* Read Hauppauge eeprom */
451struct tveeprom; /* forward reference */
452void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
453
454/* First-open initialization: load firmware, etc. */
455int cx18_init_on_first_open(struct cx18 *cx);
456
457/* This is a PCI post thing, where if the pci register is not read, then
458 the write doesn't always take effect right away. By reading back the
459 register any pending PCI writes will be performed (in order), and so
460 you can be sure that the writes are guaranteed to be done.
461
462 Rarely needed, only in some timing sensitive cases.
463 Apparently if this is not done some motherboards seem
464 to kill the firmware and get into the broken state until computer is
465 rebooted. */
466#define write_sync(val, reg) \
467 do { writel(val, reg); readl(reg); } while (0)
468
469#define read_reg(reg) readl(cx->reg_mem + (reg))
470#define write_reg(val, reg) writel(val, cx->reg_mem + (reg))
471#define write_reg_sync(val, reg) \
472 do { write_reg(val, reg); read_reg(reg); } while (0)
473
474#define read_enc(addr) readl(cx->enc_mem + (u32)(addr))
475#define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr))
476#define write_enc_sync(val, addr) \
477 do { write_enc(val, addr); read_enc(addr); } while (0)
478
479#define sw1_irq_enable(val) do { \
480 write_reg(val, SW1_INT_STATUS); \
481 write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \
482} while (0)
483
484#define sw1_irq_disable(val) \
485 write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI);
486
487#define sw2_irq_enable(val) do { \
488 write_reg(val, SW2_INT_STATUS); \
489 write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \
490} while (0)
491
492#define sw2_irq_disable(val) \
493 write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI);
494
495#define setup_page(addr) do { \
496 u32 val = read_reg(0xD000F8) & ~0x1f00; \
497 write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \
498} while (0)
499
500#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
new file mode 100644
index 000000000000..65efe69d939a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -0,0 +1,288 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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#include "cx18-version.h"
23#include "cx18-dvb.h"
24#include "cx18-streams.h"
25#include "cx18-cards.h"
26#include "s5h1409.h"
27
28/* Wait until the MXL500X driver is merged */
29#ifdef HAVE_MXL500X
30#include "mxl500x.h"
31#endif
32
33DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
34
35#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
36
37#ifdef HAVE_MXL500X
38static struct mxl500x_config hauppauge_hvr1600_tuner = {
39 .delsys = MXL500x_MODE_ATSC,
40 .octf = MXL500x_OCTF_CH,
41 .xtal_freq = 16000000,
42 .iflo_freq = 5380000,
43 .ref_freq = 322800000,
44 .rssi_ena = MXL_RSSI_ENABLE,
45 .addr = 0xC6 >> 1,
46};
47
48static struct s5h1409_config hauppauge_hvr1600_config = {
49 .demod_address = 0x32 >> 1,
50 .output_mode = S5H1409_SERIAL_OUTPUT,
51 .gpio = S5H1409_GPIO_ON,
52 .qam_if = 44000,
53 .inversion = S5H1409_INVERSION_OFF,
54 .status_mode = S5H1409_DEMODLOCKING,
55 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
56
57};
58#endif
59
60static int dvb_register(struct cx18_stream *stream);
61
62/* Kernel DVB framework calls this when the feed needs to start.
63 * The CX18 framework should enable the transport DMA handling
64 * and queue processing.
65 */
66static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
67{
68 struct dvb_demux *demux = feed->demux;
69 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
70 struct cx18 *cx = stream->cx;
71 int ret = -EINVAL;
72 u32 v;
73
74 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
75 feed->pid, feed->index);
76 switch (cx->card->type) {
77 case CX18_CARD_HVR_1600_ESMT:
78 case CX18_CARD_HVR_1600_SAMSUNG:
79 v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL);
80 v |= 0x00400000; /* Serial Mode */
81 v |= 0x00002000; /* Data Length - Byte */
82 v |= 0x00010000; /* Error - Polarity */
83 v |= 0x00020000; /* Error - Passthru */
84 v |= 0x000c0000; /* Error - Ignore */
85 write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
86 break;
87
88 default:
89 /* Assumption - Parallel transport - Signalling
90 * undefined or default.
91 */
92 break;
93 }
94
95 if (!demux->dmx.frontend)
96 return -EINVAL;
97
98 if (stream) {
99 mutex_lock(&stream->dvb.feedlock);
100 if (stream->dvb.feeding++ == 0) {
101 CX18_DEBUG_INFO("Starting Transport DMA\n");
102 ret = cx18_start_v4l2_encode_stream(stream);
103 } else
104 ret = 0;
105 mutex_unlock(&stream->dvb.feedlock);
106 }
107
108 return ret;
109}
110
111/* Kernel DVB framework calls this when the feed needs to stop. */
112static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
113{
114 struct dvb_demux *demux = feed->demux;
115 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
116 struct cx18 *cx = stream->cx;
117 int ret = -EINVAL;
118
119 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
120 feed->pid, feed->index);
121
122 if (stream) {
123 mutex_lock(&stream->dvb.feedlock);
124 if (--stream->dvb.feeding == 0) {
125 CX18_DEBUG_INFO("Stopping Transport DMA\n");
126 ret = cx18_stop_v4l2_encode_stream(stream, 0);
127 } else
128 ret = 0;
129 mutex_unlock(&stream->dvb.feedlock);
130 }
131
132 return ret;
133}
134
135int cx18_dvb_register(struct cx18_stream *stream)
136{
137 struct cx18 *cx = stream->cx;
138 struct cx18_dvb *dvb = &stream->dvb;
139 struct dvb_adapter *dvb_adapter;
140 struct dvb_demux *dvbdemux;
141 struct dmx_demux *dmx;
142 int ret;
143
144 if (!dvb)
145 return -EINVAL;
146
147 ret = dvb_register_adapter(&dvb->dvb_adapter,
148 CX18_DRIVER_NAME,
149 THIS_MODULE, &cx->dev->dev, adapter_nr);
150 if (ret < 0)
151 goto err_out;
152
153 dvb_adapter = &dvb->dvb_adapter;
154
155 dvbdemux = &dvb->demux;
156
157 dvbdemux->priv = (void *)stream;
158
159 dvbdemux->filternum = 256;
160 dvbdemux->feednum = 256;
161 dvbdemux->start_feed = cx18_dvb_start_feed;
162 dvbdemux->stop_feed = cx18_dvb_stop_feed;
163 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
164 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
165 ret = dvb_dmx_init(dvbdemux);
166 if (ret < 0)
167 goto err_dvb_unregister_adapter;
168
169 dmx = &dvbdemux->dmx;
170
171 dvb->hw_frontend.source = DMX_FRONTEND_0;
172 dvb->mem_frontend.source = DMX_MEMORY_FE;
173 dvb->dmxdev.filternum = 256;
174 dvb->dmxdev.demux = dmx;
175
176 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
177 if (ret < 0)
178 goto err_dvb_dmx_release;
179
180 ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
181 if (ret < 0)
182 goto err_dvb_dmxdev_release;
183
184 ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
185 if (ret < 0)
186 goto err_remove_hw_frontend;
187
188 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
189 if (ret < 0)
190 goto err_remove_mem_frontend;
191
192 ret = dvb_register(stream);
193 if (ret < 0)
194 goto err_disconnect_frontend;
195
196 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
197
198 CX18_INFO("DVB Frontend registered\n");
199 mutex_init(&dvb->feedlock);
200 dvb->enabled = 1;
201 return ret;
202
203err_disconnect_frontend:
204 dmx->disconnect_frontend(dmx);
205err_remove_mem_frontend:
206 dmx->remove_frontend(dmx, &dvb->mem_frontend);
207err_remove_hw_frontend:
208 dmx->remove_frontend(dmx, &dvb->hw_frontend);
209err_dvb_dmxdev_release:
210 dvb_dmxdev_release(&dvb->dmxdev);
211err_dvb_dmx_release:
212 dvb_dmx_release(dvbdemux);
213err_dvb_unregister_adapter:
214 dvb_unregister_adapter(dvb_adapter);
215err_out:
216 return ret;
217}
218
219void cx18_dvb_unregister(struct cx18_stream *stream)
220{
221 struct cx18 *cx = stream->cx;
222 struct cx18_dvb *dvb = &stream->dvb;
223 struct dvb_adapter *dvb_adapter;
224 struct dvb_demux *dvbdemux;
225 struct dmx_demux *dmx;
226
227 CX18_INFO("unregister DVB\n");
228
229 dvb_adapter = &dvb->dvb_adapter;
230 dvbdemux = &dvb->demux;
231 dmx = &dvbdemux->dmx;
232
233 dmx->close(dmx);
234 dvb_net_release(&dvb->dvbnet);
235 dmx->remove_frontend(dmx, &dvb->mem_frontend);
236 dmx->remove_frontend(dmx, &dvb->hw_frontend);
237 dvb_dmxdev_release(&dvb->dmxdev);
238 dvb_dmx_release(dvbdemux);
239 dvb_unregister_frontend(dvb->fe);
240 dvb_frontend_detach(dvb->fe);
241 dvb_unregister_adapter(dvb_adapter);
242}
243
244/* All the DVB attach calls go here, this function get's modified
245 * for each new card. No other function in this file needs
246 * to change.
247 */
248static int dvb_register(struct cx18_stream *stream)
249{
250 struct cx18_dvb *dvb = &stream->dvb;
251 struct cx18 *cx = stream->cx;
252 int ret = 0;
253
254 switch (cx->card->type) {
255/* Wait until the MXL500X driver is merged */
256#ifdef HAVE_MXL500X
257 case CX18_CARD_HVR_1600_ESMT:
258 case CX18_CARD_HVR_1600_SAMSUNG:
259 dvb->fe = dvb_attach(s5h1409_attach,
260 &hauppauge_hvr1600_config,
261 &cx->i2c_adap[0]);
262 if (dvb->fe != NULL) {
263 dvb_attach(mxl500x_attach, dvb->fe,
264 &hauppauge_hvr1600_tuner,
265 &cx->i2c_adap[0]);
266 ret = 0;
267 }
268 break;
269#endif
270 default:
271 /* No Digital Tv Support */
272 break;
273 }
274
275 if (dvb->fe == NULL) {
276 CX18_ERR("frontend initialization failed\n");
277 return -1;
278 }
279
280 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
281 if (ret < 0) {
282 if (dvb->fe->ops.release)
283 dvb->fe->ops.release(dvb->fe);
284 return ret;
285 }
286
287 return ret;
288}
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
new file mode 100644
index 000000000000..d6a6ccda79a9
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
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#include "cx18-driver.h"
23
24int cx18_dvb_register(struct cx18_stream *stream);
25void cx18_dvb_unregister(struct cx18_stream *stream);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
new file mode 100644
index 000000000000..69303065a294
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -0,0 +1,711 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-fileops.h"
26#include "cx18-i2c.h"
27#include "cx18-queue.h"
28#include "cx18-vbi.h"
29#include "cx18-audio.h"
30#include "cx18-mailbox.h"
31#include "cx18-scb.h"
32#include "cx18-streams.h"
33#include "cx18-controls.h"
34#include "cx18-ioctl.h"
35#include "cx18-cards.h"
36
37/* This function tries to claim the stream for a specific file descriptor.
38 If no one else is using this stream then the stream is claimed and
39 associated VBI streams are also automatically claimed.
40 Possible error returns: -EBUSY if someone else has claimed
41 the stream or 0 on success. */
42int cx18_claim_stream(struct cx18_open_id *id, int type)
43{
44 struct cx18 *cx = id->cx;
45 struct cx18_stream *s = &cx->streams[type];
46 struct cx18_stream *s_vbi;
47 int vbi_type;
48
49 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
50 /* someone already claimed this stream */
51 if (s->id == id->open_id) {
52 /* yes, this file descriptor did. So that's OK. */
53 return 0;
54 }
55 if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
56 /* VBI is handled already internally, now also assign
57 the file descriptor to this stream for external
58 reading of the stream. */
59 s->id = id->open_id;
60 CX18_DEBUG_INFO("Start Read VBI\n");
61 return 0;
62 }
63 /* someone else is using this stream already */
64 CX18_DEBUG_INFO("Stream %d is busy\n", type);
65 return -EBUSY;
66 }
67 s->id = id->open_id;
68
69 /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI,
70 CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
71 (provided VBI insertion is on and sliced VBI is selected), for all
72 other streams we're done */
73 if (type == CX18_ENC_STREAM_TYPE_MPG &&
74 cx->vbi.insert_mpeg && cx->vbi.sliced_in->service_set) {
75 vbi_type = CX18_ENC_STREAM_TYPE_VBI;
76 } else {
77 return 0;
78 }
79 s_vbi = &cx->streams[vbi_type];
80
81 set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
82
83 /* mark that it is used internally */
84 set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags);
85 return 0;
86}
87
88/* This function releases a previously claimed stream. It will take into
89 account associated VBI streams. */
90void cx18_release_stream(struct cx18_stream *s)
91{
92 struct cx18 *cx = s->cx;
93 struct cx18_stream *s_vbi;
94
95 s->id = -1;
96 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
97 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
98 /* this stream is still in use internally */
99 return;
100 }
101 if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
102 CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
103 return;
104 }
105
106 cx18_flush_queues(s);
107
108 /* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI,
109 for all other streams we're done */
110 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
111 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
112 else
113 return;
114
115 /* clear internal use flag */
116 if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
117 /* was already cleared */
118 return;
119 }
120 if (s_vbi->id != -1) {
121 /* VBI stream still claimed by a file descriptor */
122 return;
123 }
124 clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
125 cx18_flush_queues(s_vbi);
126}
127
128static void cx18_dualwatch(struct cx18 *cx)
129{
130 struct v4l2_tuner vt;
131 u16 new_bitmap;
132 u16 new_stereo_mode;
133 const u16 stereo_mask = 0x0300;
134 const u16 dual = 0x0200;
135
136 new_stereo_mode = cx->params.audio_properties & stereo_mask;
137 memset(&vt, 0, sizeof(vt));
138 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt);
139 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
140 (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
141 new_stereo_mode = dual;
142
143 if (new_stereo_mode == cx->dualwatch_stereo_mode)
144 return;
145
146 new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask);
147
148 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n",
149 cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
150
151 if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
152 cx18_find_handle(cx), new_bitmap) == 0) {
153 cx->dualwatch_stereo_mode = new_stereo_mode;
154 return;
155 }
156 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
157}
158
159
160static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err)
161{
162 struct cx18 *cx = s->cx;
163 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
164 struct cx18_buffer *buf;
165 DEFINE_WAIT(wait);
166
167 *err = 0;
168 while (1) {
169 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
170
171 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
172 cx->dualwatch_jiffies = jiffies;
173 cx18_dualwatch(cx);
174 }
175 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
176 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
177 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
178 /* byteswap and process VBI data */
179/* cx18_process_vbi_data(cx, buf, s_vbi->dma_pts, s_vbi->type); */
180 cx18_enqueue(s_vbi, buf, &s_vbi->q_free);
181 }
182 }
183 buf = &cx->vbi.sliced_mpeg_buf;
184 if (buf->readpos != buf->bytesused)
185 return buf;
186 }
187
188 /* do we have leftover data? */
189 buf = cx18_dequeue(s, &s->q_io);
190 if (buf)
191 return buf;
192
193 /* do we have new data? */
194 buf = cx18_dequeue(s, &s->q_full);
195 if (buf) {
196 if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP,
197 &buf->b_flags))
198 return buf;
199 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
200 /* byteswap MPG data */
201 cx18_buf_swap(buf);
202 else {
203 /* byteswap and process VBI data */
204 cx18_process_vbi_data(cx, buf,
205 s->dma_pts, s->type);
206 }
207 return buf;
208 }
209
210 /* return if end of stream */
211 if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
212 CX18_DEBUG_INFO("EOS %s\n", s->name);
213 return NULL;
214 }
215
216 /* return if file was opened with O_NONBLOCK */
217 if (non_block) {
218 *err = -EAGAIN;
219 return NULL;
220 }
221
222 /* wait for more data to arrive */
223 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
224 /* New buffers might have become available before we were added
225 to the waitqueue */
226 if (!s->q_full.buffers)
227 schedule();
228 finish_wait(&s->waitq, &wait);
229 if (signal_pending(current)) {
230 /* return if a signal was received */
231 CX18_DEBUG_INFO("User stopped %s\n", s->name);
232 *err = -EINTR;
233 return NULL;
234 }
235 }
236}
237
238static void cx18_setup_sliced_vbi_buf(struct cx18 *cx)
239{
240 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
241
242 cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx];
243 cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx];
244 cx->vbi.sliced_mpeg_buf.readpos = 0;
245}
246
247static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
248 struct cx18_buffer *buf, char __user *ubuf, size_t ucount)
249{
250 struct cx18 *cx = s->cx;
251 size_t len = buf->bytesused - buf->readpos;
252
253 if (len > ucount)
254 len = ucount;
255 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
256 cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) {
257 const char *start = buf->buf + buf->readpos;
258 const char *p = start + 1;
259 const u8 *q;
260 u8 ch = cx->search_pack_header ? 0xba : 0xe0;
261 int stuffing, i;
262
263 while (start + len > p) {
264 q = memchr(p, 0, start + len - p);
265 if (q == NULL)
266 break;
267 p = q + 1;
268 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
269 q[1] != 0 || q[2] != 1 || q[3] != ch)
270 continue;
271 if (!cx->search_pack_header) {
272 if ((q[6] & 0xc0) != 0x80)
273 continue;
274 if (((q[7] & 0xc0) == 0x80 &&
275 (q[9] & 0xf0) == 0x20) ||
276 ((q[7] & 0xc0) == 0xc0 &&
277 (q[9] & 0xf0) == 0x30)) {
278 ch = 0xba;
279 cx->search_pack_header = 1;
280 p = q + 9;
281 }
282 continue;
283 }
284 stuffing = q[13] & 7;
285 /* all stuffing bytes must be 0xff */
286 for (i = 0; i < stuffing; i++)
287 if (q[14 + i] != 0xff)
288 break;
289 if (i == stuffing &&
290 (q[4] & 0xc4) == 0x44 &&
291 (q[12] & 3) == 3 &&
292 q[14 + stuffing] == 0 &&
293 q[15 + stuffing] == 0 &&
294 q[16 + stuffing] == 1) {
295 cx->search_pack_header = 0;
296 len = (char *)q - start;
297 cx18_setup_sliced_vbi_buf(cx);
298 break;
299 }
300 }
301 }
302 if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
303 CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
304 len, s->name);
305 return -EFAULT;
306 }
307 buf->readpos += len;
308 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
309 buf != &cx->vbi.sliced_mpeg_buf)
310 cx->mpg_data_received += len;
311 return len;
312}
313
314static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
315 size_t tot_count, int non_block)
316{
317 struct cx18 *cx = s->cx;
318 size_t tot_written = 0;
319 int single_frame = 0;
320
321 if (atomic_read(&cx->capturing) == 0 && s->id == -1) {
322 /* shouldn't happen */
323 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
324 s->name);
325 return -EIO;
326 }
327
328 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
329 frames should arrive one-by-one, so make sure we never output more
330 than one VBI frame at a time */
331 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
332 cx->vbi.sliced_in->service_set)
333 single_frame = 1;
334
335 for (;;) {
336 struct cx18_buffer *buf;
337 int rc;
338
339 buf = cx18_get_buffer(s, non_block, &rc);
340 /* if there is no data available... */
341 if (buf == NULL) {
342 /* if we got data, then return that regardless */
343 if (tot_written)
344 break;
345 /* EOS condition */
346 if (rc == 0) {
347 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
348 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
349 cx18_release_stream(s);
350 }
351 /* set errno */
352 return rc;
353 }
354
355 rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written,
356 tot_count - tot_written);
357
358 if (buf != &cx->vbi.sliced_mpeg_buf) {
359 if (buf->readpos == buf->bytesused) {
360 cx18_buf_sync_for_device(s, buf);
361 cx18_enqueue(s, buf, &s->q_free);
362 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5,
363 s->handle,
364 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
365 1, buf->id, s->buf_size);
366 } else
367 cx18_enqueue(s, buf, &s->q_io);
368 } else if (buf->readpos == buf->bytesused) {
369 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
370
371 cx->vbi.sliced_mpeg_size[idx] = 0;
372 cx->vbi.inserted_frame++;
373 cx->vbi_data_inserted += buf->bytesused;
374 }
375 if (rc < 0)
376 return rc;
377 tot_written += rc;
378
379 if (tot_written == tot_count || single_frame)
380 break;
381 }
382 return tot_written;
383}
384
385static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
386 size_t count, loff_t *pos, int non_block)
387{
388 ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
389 struct cx18 *cx = s->cx;
390
391 CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
392 if (rc > 0)
393 pos += rc;
394 return rc;
395}
396
397int cx18_start_capture(struct cx18_open_id *id)
398{
399 struct cx18 *cx = id->cx;
400 struct cx18_stream *s = &cx->streams[id->type];
401 struct cx18_stream *s_vbi;
402
403 if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
404 /* you cannot read from these stream types. */
405 return -EPERM;
406 }
407
408 /* Try to claim this stream. */
409 if (cx18_claim_stream(id, s->type))
410 return -EBUSY;
411
412 /* If capture is already in progress, then we also have to
413 do nothing extra. */
414 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
415 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
416 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
417 return 0;
418 }
419
420 /* Start VBI capture if required */
421 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
422 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
423 test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
424 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
425 /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed
426 automatically when the MPG stream is claimed.
427 We only need to start the VBI capturing. */
428 if (cx18_start_v4l2_encode_stream(s_vbi)) {
429 CX18_DEBUG_WARN("VBI capture start failed\n");
430
431 /* Failure, clean up and return an error */
432 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
433 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
434 /* also releases the associated VBI stream */
435 cx18_release_stream(s);
436 return -EIO;
437 }
438 CX18_DEBUG_INFO("VBI insertion started\n");
439 }
440
441 /* Tell the card to start capturing */
442 if (!cx18_start_v4l2_encode_stream(s)) {
443 /* We're done */
444 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
445 /* Resume a possibly paused encoder */
446 if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
447 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
448 return 0;
449 }
450
451 /* failure, clean up */
452 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
453
454 /* Note: the CX18_ENC_STREAM_TYPE_VBI is released
455 automatically when the MPG stream is released.
456 We only need to stop the VBI capturing. */
457 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
458 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
459 cx18_stop_v4l2_encode_stream(s_vbi, 0);
460 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
461 }
462 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
463 cx18_release_stream(s);
464 return -EIO;
465}
466
467ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
468 loff_t *pos)
469{
470 struct cx18_open_id *id = filp->private_data;
471 struct cx18 *cx = id->cx;
472 struct cx18_stream *s = &cx->streams[id->type];
473 int rc;
474
475 CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
476
477 mutex_lock(&cx->serialize_lock);
478 rc = cx18_start_capture(id);
479 mutex_unlock(&cx->serialize_lock);
480 if (rc)
481 return rc;
482 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
483}
484
485unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
486{
487 struct cx18_open_id *id = filp->private_data;
488 struct cx18 *cx = id->cx;
489 struct cx18_stream *s = &cx->streams[id->type];
490 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
491
492 /* Start a capture if there is none */
493 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
494 int rc;
495
496 mutex_lock(&cx->serialize_lock);
497 rc = cx18_start_capture(id);
498 mutex_unlock(&cx->serialize_lock);
499 if (rc) {
500 CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
501 s->name, rc);
502 return POLLERR;
503 }
504 CX18_DEBUG_FILE("Encoder poll started capture\n");
505 }
506
507 /* add stream's waitq to the poll list */
508 CX18_DEBUG_HI_FILE("Encoder poll\n");
509 poll_wait(filp, &s->waitq, wait);
510
511 if (s->q_full.length || s->q_io.length)
512 return POLLIN | POLLRDNORM;
513 if (eof)
514 return POLLHUP;
515 return 0;
516}
517
518void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
519{
520 struct cx18 *cx = id->cx;
521 struct cx18_stream *s = &cx->streams[id->type];
522
523 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
524
525 /* 'Unclaim' this stream */
526
527 /* Stop capturing */
528 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
529 struct cx18_stream *s_vbi =
530 &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
531
532 CX18_DEBUG_INFO("close stopping capture\n");
533 /* Special case: a running VBI capture for VBI insertion
534 in the mpeg stream. Need to stop that too. */
535 if (id->type == CX18_ENC_STREAM_TYPE_MPG &&
536 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
537 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
538 CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
539 cx18_stop_v4l2_encode_stream(s_vbi, 0);
540 }
541 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
542 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
543 /* Also used internally, don't stop capturing */
544 s->id = -1;
545 else
546 cx18_stop_v4l2_encode_stream(s, gop_end);
547 }
548 if (!gop_end) {
549 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
550 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
551 cx18_release_stream(s);
552 }
553}
554
555int cx18_v4l2_close(struct inode *inode, struct file *filp)
556{
557 struct cx18_open_id *id = filp->private_data;
558 struct cx18 *cx = id->cx;
559 struct cx18_stream *s = &cx->streams[id->type];
560
561 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
562
563 v4l2_prio_close(&cx->prio, &id->prio);
564
565 /* Easy case first: this stream was never claimed by us */
566 if (s->id != id->open_id) {
567 kfree(id);
568 return 0;
569 }
570
571 /* 'Unclaim' this stream */
572
573 /* Stop radio */
574 mutex_lock(&cx->serialize_lock);
575 if (id->type == CX18_ENC_STREAM_TYPE_RAD) {
576 /* Closing radio device, return to TV mode */
577 cx18_mute(cx);
578 /* Mark that the radio is no longer in use */
579 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
580 /* Switch tuner to TV */
581 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
582 /* Select correct audio input (i.e. TV tuner or Line in) */
583 cx18_audio_set_io(cx);
584 if (atomic_read(&cx->capturing) > 0) {
585 /* Undo video mute */
586 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
587 cx->params.video_mute |
588 (cx->params.video_mute_yuv << 8));
589 }
590 /* Done! Unmute and continue. */
591 cx18_unmute(cx);
592 cx18_release_stream(s);
593 } else {
594 cx18_stop_capture(id, 0);
595 }
596 kfree(id);
597 mutex_unlock(&cx->serialize_lock);
598 return 0;
599}
600
601static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
602{
603 struct cx18 *cx = s->cx;
604 struct cx18_open_id *item;
605
606 CX18_DEBUG_FILE("open %s\n", s->name);
607
608 /* Allocate memory */
609 item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
610 if (NULL == item) {
611 CX18_DEBUG_WARN("nomem on v4l2 open\n");
612 return -ENOMEM;
613 }
614 item->cx = cx;
615 item->type = s->type;
616 v4l2_prio_open(&cx->prio, &item->prio);
617
618 item->open_id = cx->open_id++;
619 filp->private_data = item;
620
621 if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
622 /* Try to claim this stream */
623 if (cx18_claim_stream(item, item->type)) {
624 /* No, it's already in use */
625 kfree(item);
626 return -EBUSY;
627 }
628
629 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
630 if (atomic_read(&cx->capturing) > 0) {
631 /* switching to radio while capture is
632 in progress is not polite */
633 cx18_release_stream(s);
634 kfree(item);
635 return -EBUSY;
636 }
637 }
638
639 /* Mark that the radio is being used. */
640 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
641 /* We have the radio */
642 cx18_mute(cx);
643 /* Switch tuner to radio */
644 cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
645 /* Select the correct audio input (i.e. radio tuner) */
646 cx18_audio_set_io(cx);
647 /* Done! Unmute and continue. */
648 cx18_unmute(cx);
649 }
650 return 0;
651}
652
653int cx18_v4l2_open(struct inode *inode, struct file *filp)
654{
655 int res, x, y = 0;
656 struct cx18 *cx = NULL;
657 struct cx18_stream *s = NULL;
658 int minor = iminor(inode);
659
660 /* Find which card this open was on */
661 spin_lock(&cx18_cards_lock);
662 for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
663 /* find out which stream this open was on */
664 for (y = 0; y < CX18_MAX_STREAMS; y++) {
665 s = &cx18_cards[x]->streams[y];
666 if (s->v4l2dev && s->v4l2dev->minor == minor) {
667 cx = cx18_cards[x];
668 break;
669 }
670 }
671 }
672 spin_unlock(&cx18_cards_lock);
673
674 if (cx == NULL) {
675 /* Couldn't find a device registered
676 on that minor, shouldn't happen! */
677 printk(KERN_WARNING "No cx18 device found on minor %d\n",
678 minor);
679 return -ENXIO;
680 }
681
682 mutex_lock(&cx->serialize_lock);
683 if (cx18_init_on_first_open(cx)) {
684 CX18_ERR("Failed to initialize on minor %d\n", minor);
685 mutex_unlock(&cx->serialize_lock);
686 return -ENXIO;
687 }
688 res = cx18_serialized_open(s, filp);
689 mutex_unlock(&cx->serialize_lock);
690 return res;
691}
692
693void cx18_mute(struct cx18 *cx)
694{
695 if (atomic_read(&cx->capturing))
696 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
697 cx18_find_handle(cx), 1);
698 CX18_DEBUG_INFO("Mute\n");
699}
700
701void cx18_unmute(struct cx18 *cx)
702{
703 if (atomic_read(&cx->capturing)) {
704 cx18_msleep_timeout(100, 0);
705 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
706 cx18_find_handle(cx), 12);
707 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
708 cx18_find_handle(cx), 0);
709 }
710 CX18_DEBUG_INFO("Unmute\n");
711}
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
new file mode 100644
index 000000000000..16cdafbd24c5
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -0,0 +1,45 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24/* Testing/Debugging */
25int cx18_v4l2_open(struct inode *inode, struct file *filp);
26ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
27 loff_t *pos);
28ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
29 loff_t *pos);
30int cx18_v4l2_close(struct inode *inode, struct file *filp);
31unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
32int cx18_start_capture(struct cx18_open_id *id);
33void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx);
36
37/* Utilities */
38
39/* Try to claim a stream for the filehandle. Return 0 on success,
40 -EBUSY if stream already claimed. Once a stream is claimed, it
41 remains claimed until the associated filehandle is closed. */
42int cx18_claim_stream(struct cx18_open_id *id, int type);
43
44/* Release a previously claimed stream. */
45void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
new file mode 100644
index 000000000000..2694ce350631
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -0,0 +1,373 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-scb.h"
24#include "cx18-irq.h"
25#include "cx18-firmware.h"
26#include "cx18-cards.h"
27#include <linux/firmware.h>
28
29#define CX18_PROC_SOFT_RESET 0xc70010
30#define CX18_DDR_SOFT_RESET 0xc70014
31#define CX18_CLOCK_SELECT1 0xc71000
32#define CX18_CLOCK_SELECT2 0xc71004
33#define CX18_HALF_CLOCK_SELECT1 0xc71008
34#define CX18_HALF_CLOCK_SELECT2 0xc7100C
35#define CX18_CLOCK_POLARITY1 0xc71010
36#define CX18_CLOCK_POLARITY2 0xc71014
37#define CX18_ADD_DELAY_ENABLE1 0xc71018
38#define CX18_ADD_DELAY_ENABLE2 0xc7101C
39#define CX18_CLOCK_ENABLE1 0xc71020
40#define CX18_CLOCK_ENABLE2 0xc71024
41
42#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
43
44#define CX18_AUDIO_ENABLE 0xc72014
45#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
46
47#define CX18_FAST_CLOCK_PLL_INT 0xc78000
48#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
49#define CX18_FAST_CLOCK_PLL_POST 0xc78008
50#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
51#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
52
53#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
54#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
55#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
56#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
57#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
58#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
59#define CX18_PLL_POWER_DOWN 0xc78088
60#define CX18_SW1_INT_STATUS 0xc73104
61#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
62#define CX18_SW2_INT_SET 0xc73140
63#define CX18_SW2_INT_STATUS 0xc73144
64#define CX18_ADEC_CONTROL 0xc78120
65
66#define CX18_DDR_REQUEST_ENABLE 0xc80000
67#define CX18_DDR_CHIP_CONFIG 0xc80004
68#define CX18_DDR_REFRESH 0xc80008
69#define CX18_DDR_TIMING1 0xc8000C
70#define CX18_DDR_TIMING2 0xc80010
71#define CX18_DDR_POWER_REG 0xc8001C
72
73#define CX18_DDR_TUNE_LANE 0xc80048
74#define CX18_DDR_INITIAL_EMRS 0xc80054
75#define CX18_DDR_MB_PER_ROW_7 0xc8009C
76#define CX18_DDR_BASE_63_ADDR 0xc804FC
77
78#define CX18_WMB_CLIENT02 0xc90108
79#define CX18_WMB_CLIENT05 0xc90114
80#define CX18_WMB_CLIENT06 0xc90118
81#define CX18_WMB_CLIENT07 0xc9011C
82#define CX18_WMB_CLIENT08 0xc90120
83#define CX18_WMB_CLIENT09 0xc90124
84#define CX18_WMB_CLIENT10 0xc90128
85#define CX18_WMB_CLIENT11 0xc9012C
86#define CX18_WMB_CLIENT12 0xc90130
87#define CX18_WMB_CLIENT13 0xc90134
88#define CX18_WMB_CLIENT14 0xc90138
89
90#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
91
92/* Encoder/decoder firmware sizes */
93#define CX18_FW_CPU_SIZE (174716)
94#define CX18_FW_APU_SIZE (141200)
95
96#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
97#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
98
99struct cx18_apu_rom_seghdr {
100 u32 sync1;
101 u32 sync2;
102 u32 addr;
103 u32 size;
104};
105
106static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size)
107{
108 const struct firmware *fw = NULL;
109 int retries = 3;
110 int i, j;
111 u32 __iomem *dst = (u32 __iomem *)mem;
112 const u32 *src;
113
114retry:
115 if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
116 CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n",
117 fn, size);
118 CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
119 return -ENOMEM;
120 }
121
122 src = (const u32 *)fw->data;
123
124 if (fw->size != size) {
125 /* Due to race conditions in firmware loading (esp. with
126 udev <0.95) the wrong file was sometimes loaded. So we check
127 filesizes to see if at least the right-sized file was
128 loaded. If not, then we retry. */
129 CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
130 fn, size, fw->size);
131 release_firmware(fw);
132 retries--;
133 goto retry;
134 }
135 for (i = 0; i < fw->size; i += 4096) {
136 setup_page(i);
137 for (j = i; j < fw->size && j < i + 4096; j += 4) {
138 /* no need for endianness conversion on the ppc */
139 __raw_writel(*src, dst);
140 if (__raw_readl(dst) != *src) {
141 CX18_ERR("Mismatch at offset %x\n", i);
142 release_firmware(fw);
143 return -EIO;
144 }
145 dst++;
146 src++;
147 }
148 }
149 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
150 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
151 release_firmware(fw);
152 return size;
153}
154
155static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size)
156{
157 const struct firmware *fw = NULL;
158 int retries = 3;
159 int i, j;
160 const u32 *src;
161 struct cx18_apu_rom_seghdr seghdr;
162 const u8 *vers;
163 u32 offset = 0;
164 u32 apu_version = 0;
165 int sz;
166
167retry:
168 if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
169 CX18_ERR("unable to open firmware %s (must be %ld bytes)\n",
170 fn, size);
171 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
172 return -ENOMEM;
173 }
174
175 src = (const u32 *)fw->data;
176 vers = fw->data + sizeof(seghdr);
177 sz = fw->size;
178
179 if (fw->size != size) {
180 /* Due to race conditions in firmware loading (esp. with
181 udev <0.95) the wrong file was sometimes loaded. So we check
182 filesizes to see if at least the right-sized file was
183 loaded. If not, then we retry. */
184 CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
185 fn, size, fw->size);
186 release_firmware(fw);
187 retries--;
188 goto retry;
189 }
190 apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
191 while (offset + sizeof(seghdr) < size) {
192 /* TODO: byteswapping */
193 memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
194 offset += sizeof(seghdr);
195 if (seghdr.sync1 != APU_ROM_SYNC1 ||
196 seghdr.sync2 != APU_ROM_SYNC2) {
197 offset += seghdr.size;
198 continue;
199 }
200 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
201 seghdr.addr + seghdr.size - 1);
202 if (offset + seghdr.size > sz)
203 break;
204 for (i = 0; i < seghdr.size; i += 4096) {
205 setup_page(offset + i);
206 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
207 /* no need for endianness conversion on the ppc */
208 __raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j);
209 if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) {
210 CX18_ERR("Mismatch at offset %x\n", offset + j);
211 release_firmware(fw);
212 return -EIO;
213 }
214 }
215 }
216 offset += seghdr.size;
217 }
218 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
219 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
220 fn, apu_version, fw->size);
221 release_firmware(fw);
222 /* Clear bit0 for APU to start from 0 */
223 write_reg(read_reg(0xc72030) & ~1, 0xc72030);
224 return size;
225}
226
227void cx18_halt_firmware(struct cx18 *cx)
228{
229 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
230 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
231 write_reg(0x00020002, CX18_ADEC_CONTROL);
232}
233
234void cx18_init_power(struct cx18 *cx, int lowpwr)
235{
236 /* power-down Spare and AOM PLLs */
237 /* power-up fast, slow and mpeg PLLs */
238 write_reg(0x00000008, CX18_PLL_POWER_DOWN);
239
240 /* ADEC out of sleep */
241 write_reg(0x00020000, CX18_ADEC_CONTROL);
242
243 /* The fast clock is at 200/245 MHz */
244 write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
245 write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC);
246
247 write_reg(2, CX18_FAST_CLOCK_PLL_POST);
248 write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE);
249 write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
250
251 /* set slow clock to 125/120 MHz */
252 write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
253 write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC);
254 write_reg(4, CX18_SLOW_CLOCK_PLL_POST);
255
256 /* mpeg clock pll 54MHz */
257 write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT);
258 write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
259 write_reg(8, CX18_MPEG_CLOCK_PLL_POST);
260
261 /* Defaults */
262 /* APU = SC or SC/2 = 125/62.5 */
263 /* EPU = SC = 125 */
264 /* DDR = FC = 180 */
265 /* ENC = SC = 125 */
266 /* AI1 = SC = 125 */
267 /* VIM2 = disabled */
268 /* PCI = FC/2 = 90 */
269 /* AI2 = disabled */
270 /* DEMUX = disabled */
271 /* AO = SC/2 = 62.5 */
272 /* SER = 54MHz */
273 /* VFC = disabled */
274 /* USB = disabled */
275
276 write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1);
277 write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2);
278
279 write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
280 write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
281
282 write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1);
283 write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2);
284}
285
286void cx18_init_memory(struct cx18 *cx)
287{
288 cx18_msleep_timeout(10, 0);
289 write_reg(0x10000, CX18_DDR_SOFT_RESET);
290 cx18_msleep_timeout(10, 0);
291
292 write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
293
294 cx18_msleep_timeout(10, 0);
295
296 write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH);
297 write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1);
298 write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2);
299
300 cx18_msleep_timeout(10, 0);
301
302 /* Initialize DQS pad time */
303 write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
304 write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
305
306 cx18_msleep_timeout(10, 0);
307
308 write_reg(0x20000, CX18_DDR_SOFT_RESET);
309 cx18_msleep_timeout(10, 0);
310
311 /* use power-down mode when idle */
312 write_reg(0x00000010, CX18_DDR_POWER_REG);
313
314 write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN);
315
316 write_reg(0x48, CX18_DDR_MB_PER_ROW_7);
317 write_reg(0xE0000, CX18_DDR_BASE_63_ADDR);
318
319 write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */
320 write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */
321 write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
322 write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */
323 write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
324 write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */
325 write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */
326 write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */
327 write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */
328 write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */
329}
330
331int cx18_firmware_init(struct cx18 *cx)
332{
333 /* Allow chip to control CLKRUN */
334 write_reg(0x5, CX18_DSP0_INTERRUPT_MASK);
335
336 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
337
338 cx18_msleep_timeout(1, 0);
339
340 sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
341 sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
342
343 /* Only if the processor is not running */
344 if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
345 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
346 cx->enc_mem, cx, CX18_FW_APU_SIZE);
347
348 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
349 cx->enc_mem, cx, CX18_FW_CPU_SIZE);
350
351 if (sz > 0) {
352 int retries = 0;
353
354 /* start the CPU */
355 write_reg(0x00080000, CX18_PROC_SOFT_RESET);
356 while (retries++ < 50) { /* Loop for max 500mS */
357 if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0)
358 break;
359 cx18_msleep_timeout(10, 0);
360 }
361 cx18_msleep_timeout(200, 0);
362 if (retries == 51) {
363 CX18_ERR("Could not start the CPU\n");
364 return -EIO;
365 }
366 }
367 if (sz <= 0)
368 return -EIO;
369 }
370 /* initialize GPIO */
371 write_reg(0x14001400, 0xC78110);
372 return 0;
373}
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h
new file mode 100644
index 000000000000..38d4c05e8499
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22int cx18_firmware_init(struct cx18 *cx);
23void cx18_halt_firmware(struct cx18 *cx);
24void cx18_init_memory(struct cx18 *cx);
25void cx18_init_power(struct cx18 *cx, int lowpwr);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
new file mode 100644
index 000000000000..19253e6b8673
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -0,0 +1,74 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-gpio.h"
27#include "tuner-xc2028.h"
28
29/********************* GPIO stuffs *********************/
30
31/* GPIO registers */
32#define CX18_REG_GPIO_IN 0xc72010
33#define CX18_REG_GPIO_OUT1 0xc78100
34#define CX18_REG_GPIO_DIR1 0xc78108
35#define CX18_REG_GPIO_OUT2 0xc78104
36#define CX18_REG_GPIO_DIR2 0xc7810c
37
38/*
39 * HVR-1600 GPIO pins, courtesy of Hauppauge:
40 *
41 * gpio0: zilog ir process reset pin
42 * gpio1: zilog programming pin (you should never use this)
43 * gpio12: cx24227 reset pin
44 * gpio13: cs5345 reset pin
45*/
46
47void cx18_gpio_init(struct cx18 *cx)
48{
49 if (cx->card->gpio_init.direction == 0)
50 return;
51
52 CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
53 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
54
55 /* init output data then direction */
56 write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
57 write_reg(0, CX18_REG_GPIO_DIR2);
58 write_reg((cx->card->gpio_init.direction << 16) |
59 cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
60 write_reg(0, CX18_REG_GPIO_OUT2);
61}
62
63/* Xceive tuner reset function */
64int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
65{
66 struct i2c_algo_bit_data *algo = dev;
67 struct cx18 *cx = algo->data;
68/* int curdir, curout;*/
69
70 if (cmd != XC2028_TUNER_RESET)
71 return 0;
72 CX18_DEBUG_INFO("Resetting tuner\n");
73 return 0;
74}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
new file mode 100644
index 000000000000..41bac8856b50
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23void cx18_gpio_init(struct cx18 *cx);
24int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
new file mode 100644
index 000000000000..18c88d1e4833
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -0,0 +1,431 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-gpio.h"
27#include "cx18-av-core.h"
28
29#include <media/ir-kbd-i2c.h>
30
31#define CX18_REG_I2C_1_WR 0xf15000
32#define CX18_REG_I2C_1_RD 0xf15008
33#define CX18_REG_I2C_2_WR 0xf25100
34#define CX18_REG_I2C_2_RD 0xf25108
35
36#define SETSCL_BIT 0x0001
37#define SETSDL_BIT 0x0002
38#define GETSCL_BIT 0x0004
39#define GETSDL_BIT 0x0008
40
41#ifndef I2C_ADAP_CLASS_TV_ANALOG
42#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
43#endif
44
45#define CX18_CS5345_I2C_ADDR 0x4c
46
47/* This array should match the CX18_HW_ defines */
48static const u8 hw_driverids[] = {
49 I2C_DRIVERID_TUNER,
50 I2C_DRIVERID_TVEEPROM,
51 I2C_DRIVERID_CS5345,
52 0, /* CX18_HW_GPIO dummy driver ID */
53 0 /* CX18_HW_CX23418 dummy driver ID */
54};
55
56/* This array should match the CX18_HW_ defines */
57static const u8 hw_addrs[] = {
58 0,
59 0,
60 CX18_CS5345_I2C_ADDR,
61 0, /* CX18_HW_GPIO dummy driver ID */
62 0, /* CX18_HW_CX23418 dummy driver ID */
63};
64
65/* This array should match the CX18_HW_ defines */
66/* This might well become a card-specific array */
67static const u8 hw_bus[] = {
68 0,
69 0,
70 0,
71 0, /* CX18_HW_GPIO dummy driver ID */
72 0, /* CX18_HW_CX23418 dummy driver ID */
73};
74
75/* This array should match the CX18_HW_ defines */
76static const char * const hw_drivernames[] = {
77 "tuner",
78 "tveeprom",
79 "cs5345",
80 "gpio",
81 "cx23418",
82};
83
84int cx18_i2c_register(struct cx18 *cx, unsigned idx)
85{
86 struct i2c_board_info info;
87 struct i2c_client *c;
88 u8 id, bus;
89 int i;
90
91 CX18_DEBUG_I2C("i2c client register\n");
92 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
93 return -1;
94 id = hw_driverids[idx];
95 bus = hw_bus[idx];
96 memset(&info, 0, sizeof(info));
97 strlcpy(info.driver_name, hw_drivernames[idx],
98 sizeof(info.driver_name));
99 info.addr = hw_addrs[idx];
100 for (i = 0; i < I2C_CLIENTS_MAX; i++)
101 if (cx->i2c_clients[i] == NULL)
102 break;
103
104 if (i == I2C_CLIENTS_MAX) {
105 CX18_ERR("insufficient room for new I2C client!\n");
106 return -ENOMEM;
107 }
108
109 if (id != I2C_DRIVERID_TUNER) {
110 c = i2c_new_device(&cx->i2c_adap[bus], &info);
111 if (c->driver == NULL)
112 i2c_unregister_device(c);
113 else
114 cx->i2c_clients[i] = c;
115 return cx->i2c_clients[i] ? 0 : -ENODEV;
116 }
117
118 /* special tuner handling */
119 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
120 if (c && c->driver == NULL)
121 i2c_unregister_device(c);
122 else if (c)
123 cx->i2c_clients[i++] = c;
124 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
125 if (c && c->driver == NULL)
126 i2c_unregister_device(c);
127 else if (c)
128 cx->i2c_clients[i++] = c;
129 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
130 if (c && c->driver == NULL)
131 i2c_unregister_device(c);
132 else if (c)
133 cx->i2c_clients[i++] = c;
134 return 0;
135}
136
137static int attach_inform(struct i2c_client *client)
138{
139 return 0;
140}
141
142static int detach_inform(struct i2c_client *client)
143{
144 int i;
145 struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
146
147 CX18_DEBUG_I2C("i2c client detach\n");
148 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
149 if (cx->i2c_clients[i] == client) {
150 cx->i2c_clients[i] = NULL;
151 break;
152 }
153 }
154 CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
155 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
156
157 return 0;
158}
159
160static void cx18_setscl(void *data, int state)
161{
162 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
163 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
164 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
165 u32 r = read_reg(addr);
166
167 if (state)
168 write_reg_sync(r | SETSCL_BIT, addr);
169 else
170 write_reg_sync(r & ~SETSCL_BIT, addr);
171}
172
173static void cx18_setsda(void *data, int state)
174{
175 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
176 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
177 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
178 u32 r = read_reg(addr);
179
180 if (state)
181 write_reg_sync(r | SETSDL_BIT, addr);
182 else
183 write_reg_sync(r & ~SETSDL_BIT, addr);
184}
185
186static int cx18_getscl(void *data)
187{
188 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
189 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
190 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
191
192 return read_reg(addr) & GETSCL_BIT;
193}
194
195static int cx18_getsda(void *data)
196{
197 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
198 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
199 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
200
201 return read_reg(addr) & GETSDL_BIT;
202}
203
204/* template for i2c-bit-algo */
205static struct i2c_adapter cx18_i2c_adap_template = {
206 .name = "cx18 i2c driver",
207 .id = I2C_HW_B_CX2341X,
208 .algo = NULL, /* set by i2c-algo-bit */
209 .algo_data = NULL, /* filled from template */
210 .client_register = attach_inform,
211 .client_unregister = detach_inform,
212 .owner = THIS_MODULE,
213};
214
215#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
216#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
217
218static struct i2c_algo_bit_data cx18_i2c_algo_template = {
219 .setsda = cx18_setsda,
220 .setscl = cx18_setscl,
221 .getsda = cx18_getsda,
222 .getscl = cx18_getscl,
223 .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
224 .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
225};
226
227static struct i2c_client cx18_i2c_client_template = {
228 .name = "cx18 internal",
229};
230
231int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
232{
233 struct i2c_client *client;
234 int retval;
235 int i;
236
237 CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
238 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
239 client = cx->i2c_clients[i];
240 if (client == NULL || client->driver == NULL ||
241 client->driver->command == NULL)
242 continue;
243 if (addr == client->addr) {
244 retval = client->driver->command(client, cmd, arg);
245 return retval;
246 }
247 }
248 if (cmd != VIDIOC_G_CHIP_IDENT)
249 CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
250 addr, cmd);
251 return -ENODEV;
252}
253
254/* Find the i2c device based on the driver ID and return
255 its i2c address or -ENODEV if no matching device was found. */
256static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
257{
258 struct i2c_client *client;
259 int retval = -ENODEV;
260 int i;
261
262 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
263 client = cx->i2c_clients[i];
264 if (client == NULL || client->driver == NULL)
265 continue;
266 if (id == client->driver->id) {
267 retval = client->addr;
268 break;
269 }
270 }
271 return retval;
272}
273
274/* Find the i2c device name matching the DRIVERID */
275static const char *cx18_i2c_id_name(u32 id)
276{
277 int i;
278
279 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
280 if (hw_driverids[i] == id)
281 return hw_drivernames[i];
282 return "unknown device";
283}
284
285/* Find the i2c device name matching the CX18_HW_ flag */
286static const char *cx18_i2c_hw_name(u32 hw)
287{
288 int i;
289
290 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
291 if (1 << i == hw)
292 return hw_drivernames[i];
293 return "unknown device";
294}
295
296/* Find the i2c device matching the CX18_HW_ flag and return
297 its i2c address or -ENODEV if no matching device was found. */
298int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
299{
300 int i;
301
302 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
303 if (1 << i == hw)
304 return cx18_i2c_id_addr(cx, hw_driverids[i]);
305 return -ENODEV;
306}
307
308/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
309 If hw == CX18_HW_GPIO then call the gpio handler. */
310int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
311{
312 int addr;
313
314 if (hw == CX18_HW_GPIO || hw == 0)
315 return 0;
316 if (hw == CX18_HW_CX23418)
317 return cx18_av_cmd(cx, cmd, arg);
318
319 addr = cx18_i2c_hw_addr(cx, hw);
320 if (addr < 0) {
321 CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
322 hw, cx18_i2c_hw_name(hw), cmd);
323 return addr;
324 }
325 return cx18_call_i2c_client(cx, addr, cmd, arg);
326}
327
328/* Calls i2c device based on I2C driver ID. */
329int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg)
330{
331 int addr;
332
333 addr = cx18_i2c_id_addr(cx, id);
334 if (addr < 0) {
335 if (cmd != VIDIOC_G_CHIP_IDENT)
336 CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n",
337 id, cx18_i2c_id_name(id), cmd);
338 return addr;
339 }
340 return cx18_call_i2c_client(cx, addr, cmd, arg);
341}
342
343/* broadcast cmd for all I2C clients and for the gpio subsystem */
344void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
345{
346 if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
347 CX18_ERR("adapter is not set\n");
348 return;
349 }
350 cx18_av_cmd(cx, cmd, arg);
351 i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
352 i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
353}
354
355/* init + register i2c algo-bit adapter */
356int init_cx18_i2c(struct cx18 *cx)
357{
358 int i;
359 CX18_DEBUG_I2C("i2c init\n");
360
361 for (i = 0; i < 2; i++) {
362 memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
363 sizeof(struct i2c_adapter));
364 memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
365 sizeof(struct i2c_algo_bit_data));
366 cx->i2c_algo_cb_data[i].cx = cx;
367 cx->i2c_algo_cb_data[i].bus_index = i;
368 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
369 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
370
371 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
372 " #%d-%d", cx->num, i);
373 i2c_set_adapdata(&cx->i2c_adap[i], cx);
374
375 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
376 sizeof(struct i2c_client));
377 sprintf(cx->i2c_client[i].name +
378 strlen(cx->i2c_client[i].name), "%d", i);
379 cx->i2c_client[i].adapter = &cx->i2c_adap[i];
380 cx->i2c_adap[i].dev.parent = &cx->dev->dev;
381 }
382
383 if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) {
384 /* Reset/Unreset I2C hardware block */
385 write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */
386 write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */
387 }
388 /* courtesy of Steven Toth <stoth@hauppauge.com> */
389 write_reg_sync(0x00c00000, 0xc7001c);
390 mdelay(10);
391 write_reg_sync(0x00c000c0, 0xc7001c);
392 mdelay(10);
393 write_reg_sync(0x00c00000, 0xc7001c);
394
395 write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
396 write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */
397
398 /* Hw I2C1 Clock Freq ~100kHz */
399 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR);
400 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
401 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
402
403 /* Hw I2C2 Clock Freq ~100kHz */
404 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR);
405 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
406 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
407
408 return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
409 i2c_bit_add_bus(&cx->i2c_adap[1]);
410}
411
412void exit_cx18_i2c(struct cx18 *cx)
413{
414 int i;
415 CX18_DEBUG_I2C("i2c exit\n");
416 write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR);
417 write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR);
418
419 for (i = 0; i < 2; i++) {
420 i2c_del_adapter(&cx->i2c_adap[i]);
421 }
422}
423
424/*
425 Hauppauge HVR1600 should have:
426 32 cx24227
427 98 unknown
428 a0 eeprom
429 c2 tuner
430 e? zilog ir
431 */
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
new file mode 100644
index 000000000000..113c3f9a2cc0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -0,0 +1,33 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw);
25int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg);
26int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg);
27int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg);
28void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg);
29int cx18_i2c_register(struct cx18 *cx, unsigned idx);
30
31/* init + register i2c algo-bit adapter */
32int init_cx18_i2c(struct cx18 *cx);
33void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
new file mode 100644
index 000000000000..dbdcb86ec5aa
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -0,0 +1,851 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-version.h"
26#include "cx18-mailbox.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-fileops.h"
30#include "cx18-vbi.h"
31#include "cx18-audio.h"
32#include "cx18-video.h"
33#include "cx18-streams.h"
34#include "cx18-ioctl.h"
35#include "cx18-gpio.h"
36#include "cx18-controls.h"
37#include "cx18-cards.h"
38#include "cx18-av-core.h"
39#include <media/tveeprom.h>
40#include <media/v4l2-chip-ident.h>
41#include <linux/i2c-id.h>
42
43u16 cx18_service2vbi(int type)
44{
45 switch (type) {
46 case V4L2_SLICED_TELETEXT_B:
47 return CX18_SLICED_TYPE_TELETEXT_B;
48 case V4L2_SLICED_CAPTION_525:
49 return CX18_SLICED_TYPE_CAPTION_525;
50 case V4L2_SLICED_WSS_625:
51 return CX18_SLICED_TYPE_WSS_625;
52 case V4L2_SLICED_VPS:
53 return CX18_SLICED_TYPE_VPS;
54 default:
55 return 0;
56 }
57}
58
59static int valid_service_line(int field, int line, int is_pal)
60{
61 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
62 (!is_pal && line >= 10 && line < 22);
63}
64
65static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
66{
67 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
68 int i;
69
70 set = set & valid_set;
71 if (set == 0 || !valid_service_line(field, line, is_pal))
72 return 0;
73 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525;
76 } else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625;
81 if (line == 23)
82 return 0;
83 }
84 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set)
86 return 1 << i;
87 }
88 return 0;
89}
90
91void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
92{
93 u16 set = fmt->service_set;
94 int f, l;
95
96 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++)
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 }
101}
102
103static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
104{
105 int f, l;
106 u16 set = 0;
107
108 for (f = 0; f < 2; f++) {
109 for (l = 0; l < 24; l++) {
110 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
111 set |= fmt->service_lines[f][l];
112 }
113 }
114 return set != 0;
115}
116
117u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
118{
119 int f, l;
120 u16 set = 0;
121
122 for (f = 0; f < 2; f++) {
123 for (l = 0; l < 24; l++)
124 set |= fmt->service_lines[f][l];
125 }
126 return set;
127}
128
129static const struct {
130 v4l2_std_id std;
131 char *name;
132} enum_stds[] = {
133 { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
134 { V4L2_STD_PAL_DK, "PAL-DK" },
135 { V4L2_STD_PAL_I, "PAL-I" },
136 { V4L2_STD_PAL_M, "PAL-M" },
137 { V4L2_STD_PAL_N, "PAL-N" },
138 { V4L2_STD_PAL_Nc, "PAL-Nc" },
139 { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
140 { V4L2_STD_SECAM_DK, "SECAM-DK" },
141 { V4L2_STD_SECAM_L, "SECAM-L" },
142 { V4L2_STD_SECAM_LC, "SECAM-L'" },
143 { V4L2_STD_NTSC_M, "NTSC-M" },
144 { V4L2_STD_NTSC_M_JP, "NTSC-J" },
145 { V4L2_STD_NTSC_M_KR, "NTSC-K" },
146};
147
148static const struct v4l2_standard cx18_std_60hz = {
149 .frameperiod = {.numerator = 1001, .denominator = 30000},
150 .framelines = 525,
151};
152
153static const struct v4l2_standard cx18_std_50hz = {
154 .frameperiod = { .numerator = 1, .denominator = 25 },
155 .framelines = 625,
156};
157
158static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
159{
160 struct v4l2_register *regs = arg;
161 unsigned long flags;
162
163 if (!capable(CAP_SYS_ADMIN))
164 return -EPERM;
165 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
166 return -EINVAL;
167
168 spin_lock_irqsave(&cx18_cards_lock, flags);
169 if (cmd == VIDIOC_DBG_G_REGISTER)
170 regs->val = read_enc(regs->reg);
171 else
172 write_enc(regs->val, regs->reg);
173 spin_unlock_irqrestore(&cx18_cards_lock, flags);
174 return 0;
175}
176
177static int cx18_get_fmt(struct cx18 *cx, int streamtype, struct v4l2_format *fmt)
178{
179 switch (fmt->type) {
180 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
181 fmt->fmt.pix.width = cx->params.width;
182 fmt->fmt.pix.height = cx->params.height;
183 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
184 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
185 if (streamtype == CX18_ENC_STREAM_TYPE_YUV) {
186 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
187 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
188 fmt->fmt.pix.sizeimage =
189 fmt->fmt.pix.height * fmt->fmt.pix.width +
190 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
191 } else {
192 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
193 fmt->fmt.pix.sizeimage = 128 * 1024;
194 }
195 break;
196
197 case V4L2_BUF_TYPE_VBI_CAPTURE:
198 fmt->fmt.vbi.sampling_rate = 27000000;
199 fmt->fmt.vbi.offset = 248;
200 fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4;
201 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
202 fmt->fmt.vbi.start[0] = cx->vbi.start[0];
203 fmt->fmt.vbi.start[1] = cx->vbi.start[1];
204 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count;
205 break;
206
207 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
208 {
209 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
210
211 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
212 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
213 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
214
215 cx18_av_cmd(cx, VIDIOC_G_FMT, fmt);
216 vbifmt->service_set = cx18_get_service_set(vbifmt);
217 break;
218 }
219 default:
220 return -EINVAL;
221 }
222 return 0;
223}
224
225static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
226 struct v4l2_format *fmt, int set_fmt)
227{
228 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
229 u16 set;
230
231 /* set window size */
232 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
233 int w = fmt->fmt.pix.width;
234 int h = fmt->fmt.pix.height;
235
236 if (w > 720)
237 w = 720;
238 else if (w < 1)
239 w = 1;
240 if (h > (cx->is_50hz ? 576 : 480))
241 h = (cx->is_50hz ? 576 : 480);
242 else if (h < 2)
243 h = 2;
244 cx18_get_fmt(cx, streamtype, fmt);
245 fmt->fmt.pix.width = w;
246 fmt->fmt.pix.height = h;
247
248 if (!set_fmt || (cx->params.width == w && cx->params.height == h))
249 return 0;
250 if (atomic_read(&cx->capturing) > 0)
251 return -EBUSY;
252
253 cx->params.width = w;
254 cx->params.height = h;
255 if (w != 720 || h != (cx->is_50hz ? 576 : 480))
256 cx->params.video_temporal_filter = 0;
257 else
258 cx->params.video_temporal_filter = 8;
259 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
260 return cx18_get_fmt(cx, streamtype, fmt);
261 }
262
263 /* set raw VBI format */
264 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
265 if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI &&
266 cx->vbi.sliced_in->service_set &&
267 atomic_read(&cx->capturing) > 0)
268 return -EBUSY;
269 if (set_fmt) {
270 cx->vbi.sliced_in->service_set = 0;
271 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
272 }
273 return cx18_get_fmt(cx, streamtype, fmt);
274 }
275
276 /* any else but sliced VBI capture is an error */
277 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
278 return -EINVAL;
279
280 /* TODO: implement sliced VBI, for now silently return 0 */
281 return 0;
282
283 /* set sliced VBI capture format */
284 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
285 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
286
287 if (vbifmt->service_set)
288 cx18_expand_service_set(vbifmt, cx->is_50hz);
289 set = check_service_set(vbifmt, cx->is_50hz);
290 vbifmt->service_set = cx18_get_service_set(vbifmt);
291
292 if (!set_fmt)
293 return 0;
294 if (set == 0)
295 return -EINVAL;
296 if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
297 return -EBUSY;
298 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
299 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
300 return 0;
301}
302
303static int cx18_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
304{
305 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
306 struct cx18 *cx = id->cx;
307 struct v4l2_register *reg = arg;
308
309 switch (cmd) {
310 /* ioctls to allow direct access to the encoder registers for testing */
311 case VIDIOC_DBG_G_REGISTER:
312 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
313 return cx18_cxc(cx, cmd, arg);
314 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
315 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
316 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
317
318 case VIDIOC_DBG_S_REGISTER:
319 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
320 return cx18_cxc(cx, cmd, arg);
321 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
322 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
323 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
324
325 case VIDIOC_G_CHIP_IDENT: {
326 struct v4l2_chip_ident *chip = arg;
327
328 chip->ident = V4L2_IDENT_NONE;
329 chip->revision = 0;
330 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
331 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
332 struct v4l2_chip_ident *chip = arg;
333
334 chip->ident = V4L2_IDENT_CX23418;
335 }
336 return 0;
337 }
338 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
339 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
340 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
341 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
342 return -EINVAL;
343 }
344
345 case VIDIOC_INT_S_AUDIO_ROUTING: {
346 struct v4l2_routing *route = arg;
347
348 cx18_audio_set_route(cx, route);
349 break;
350 }
351
352 default:
353 return -EINVAL;
354 }
355 return 0;
356}
357
358int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg)
359{
360 struct cx18_open_id *id = NULL;
361
362 if (filp)
363 id = (struct cx18_open_id *)filp->private_data;
364
365 switch (cmd) {
366 case VIDIOC_G_PRIORITY:
367 {
368 enum v4l2_priority *p = arg;
369
370 *p = v4l2_prio_max(&cx->prio);
371 break;
372 }
373
374 case VIDIOC_S_PRIORITY:
375 {
376 enum v4l2_priority *prio = arg;
377
378 return v4l2_prio_change(&cx->prio, &id->prio, *prio);
379 }
380
381 case VIDIOC_QUERYCAP:{
382 struct v4l2_capability *vcap = arg;
383
384 memset(vcap, 0, sizeof(*vcap));
385 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
386 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
387 strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info));
388 vcap->version = CX18_DRIVER_VERSION; /* version */
389 vcap->capabilities = cx->v4l2_cap; /* capabilities */
390
391 /* reserved.. must set to 0! */
392 vcap->reserved[0] = vcap->reserved[1] =
393 vcap->reserved[2] = vcap->reserved[3] = 0;
394 break;
395 }
396
397 case VIDIOC_ENUMAUDIO:{
398 struct v4l2_audio *vin = arg;
399
400 return cx18_get_audio_input(cx, vin->index, vin);
401 }
402
403 case VIDIOC_G_AUDIO:{
404 struct v4l2_audio *vin = arg;
405
406 vin->index = cx->audio_input;
407 return cx18_get_audio_input(cx, vin->index, vin);
408 }
409
410 case VIDIOC_S_AUDIO:{
411 struct v4l2_audio *vout = arg;
412
413 if (vout->index >= cx->nof_audio_inputs)
414 return -EINVAL;
415 cx->audio_input = vout->index;
416 cx18_audio_set_io(cx);
417 break;
418 }
419
420 case VIDIOC_ENUMINPUT:{
421 struct v4l2_input *vin = arg;
422
423 /* set it to defaults from our table */
424 return cx18_get_input(cx, vin->index, vin);
425 }
426
427 case VIDIOC_TRY_FMT:
428 case VIDIOC_S_FMT: {
429 struct v4l2_format *fmt = arg;
430
431 return cx18_try_or_set_fmt(cx, id->type, fmt, cmd == VIDIOC_S_FMT);
432 }
433
434 case VIDIOC_G_FMT: {
435 struct v4l2_format *fmt = arg;
436 int type = fmt->type;
437
438 memset(fmt, 0, sizeof(*fmt));
439 fmt->type = type;
440 return cx18_get_fmt(cx, id->type, fmt);
441 }
442
443 case VIDIOC_CROPCAP: {
444 struct v4l2_cropcap *cropcap = arg;
445
446 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
447 return -EINVAL;
448 cropcap->bounds.top = cropcap->bounds.left = 0;
449 cropcap->bounds.width = 720;
450 cropcap->bounds.height = cx->is_50hz ? 576 : 480;
451 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
452 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
453 cropcap->defrect = cropcap->bounds;
454 return 0;
455 }
456
457 case VIDIOC_S_CROP: {
458 struct v4l2_crop *crop = arg;
459
460 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
461 return -EINVAL;
462 return cx18_av_cmd(cx, VIDIOC_S_CROP, arg);
463 }
464
465 case VIDIOC_G_CROP: {
466 struct v4l2_crop *crop = arg;
467
468 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
469 return -EINVAL;
470 return cx18_av_cmd(cx, VIDIOC_G_CROP, arg);
471 }
472
473 case VIDIOC_ENUM_FMT: {
474 static struct v4l2_fmtdesc formats[] = {
475 { 0, 0, 0,
476 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
477 { 0, 0, 0, 0 }
478 },
479 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
480 "MPEG", V4L2_PIX_FMT_MPEG,
481 { 0, 0, 0, 0 }
482 }
483 };
484 struct v4l2_fmtdesc *fmt = arg;
485 enum v4l2_buf_type type = fmt->type;
486
487 switch (type) {
488 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
489 break;
490 default:
491 return -EINVAL;
492 }
493 if (fmt->index > 1)
494 return -EINVAL;
495 *fmt = formats[fmt->index];
496 fmt->type = type;
497 return 0;
498 }
499
500 case VIDIOC_G_INPUT:{
501 *(int *)arg = cx->active_input;
502 break;
503 }
504
505 case VIDIOC_S_INPUT:{
506 int inp = *(int *)arg;
507
508 if (inp < 0 || inp >= cx->nof_inputs)
509 return -EINVAL;
510
511 if (inp == cx->active_input) {
512 CX18_DEBUG_INFO("Input unchanged\n");
513 break;
514 }
515 CX18_DEBUG_INFO("Changing input from %d to %d\n",
516 cx->active_input, inp);
517
518 cx->active_input = inp;
519 /* Set the audio input to whatever is appropriate for the
520 input type. */
521 cx->audio_input = cx->card->video_inputs[inp].audio_index;
522
523 /* prevent others from messing with the streams until
524 we're finished changing inputs. */
525 cx18_mute(cx);
526 cx18_video_set_io(cx);
527 cx18_audio_set_io(cx);
528 cx18_unmute(cx);
529 break;
530 }
531
532 case VIDIOC_G_FREQUENCY:{
533 struct v4l2_frequency *vf = arg;
534
535 if (vf->tuner != 0)
536 return -EINVAL;
537 cx18_call_i2c_clients(cx, cmd, arg);
538 break;
539 }
540
541 case VIDIOC_S_FREQUENCY:{
542 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
543
544 if (vf.tuner != 0)
545 return -EINVAL;
546
547 cx18_mute(cx);
548 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
549 cx18_call_i2c_clients(cx, cmd, &vf);
550 cx18_unmute(cx);
551 break;
552 }
553
554 case VIDIOC_ENUMSTD:{
555 struct v4l2_standard *vs = arg;
556 int idx = vs->index;
557
558 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
559 return -EINVAL;
560
561 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
562 cx18_std_60hz : cx18_std_50hz;
563 vs->index = idx;
564 vs->id = enum_stds[idx].std;
565 strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
566 break;
567 }
568
569 case VIDIOC_G_STD:{
570 *(v4l2_std_id *) arg = cx->std;
571 break;
572 }
573
574 case VIDIOC_S_STD: {
575 v4l2_std_id std = *(v4l2_std_id *) arg;
576
577 if ((std & V4L2_STD_ALL) == 0)
578 return -EINVAL;
579
580 if (std == cx->std)
581 break;
582
583 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
584 atomic_read(&cx->capturing) > 0) {
585 /* Switching standard would turn off the radio or mess
586 with already running streams, prevent that by
587 returning EBUSY. */
588 return -EBUSY;
589 }
590
591 cx->std = std;
592 cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
593 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz;
594 cx->params.width = 720;
595 cx->params.height = cx->is_50hz ? 576 : 480;
596 cx->vbi.count = cx->is_50hz ? 18 : 12;
597 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
598 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
599 cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
600 CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)cx->std);
601
602 /* Tuner */
603 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
604 break;
605 }
606
607 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
608 struct v4l2_tuner *vt = arg;
609
610 if (vt->index != 0)
611 return -EINVAL;
612
613 cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
614 break;
615 }
616
617 case VIDIOC_G_TUNER: {
618 struct v4l2_tuner *vt = arg;
619
620 if (vt->index != 0)
621 return -EINVAL;
622
623 memset(vt, 0, sizeof(*vt));
624 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
625
626 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
627 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
628 vt->type = V4L2_TUNER_RADIO;
629 } else {
630 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
631 vt->type = V4L2_TUNER_ANALOG_TV;
632 }
633 break;
634 }
635
636 case VIDIOC_G_SLICED_VBI_CAP: {
637 struct v4l2_sliced_vbi_cap *cap = arg;
638 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
639 int f, l;
640 enum v4l2_buf_type type = cap->type;
641
642 memset(cap, 0, sizeof(*cap));
643 cap->type = type;
644 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
645 for (f = 0; f < 2; f++) {
646 for (l = 0; l < 24; l++) {
647 if (valid_service_line(f, l, cx->is_50hz))
648 cap->service_lines[f][l] = set;
649 }
650 }
651 return 0;
652 }
653 return -EINVAL;
654 }
655
656 case VIDIOC_ENCODER_CMD:
657 case VIDIOC_TRY_ENCODER_CMD: {
658 struct v4l2_encoder_cmd *enc = arg;
659 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
660
661 memset(&enc->raw, 0, sizeof(enc->raw));
662 switch (enc->cmd) {
663 case V4L2_ENC_CMD_START:
664 enc->flags = 0;
665 if (try)
666 return 0;
667 return cx18_start_capture(id);
668
669 case V4L2_ENC_CMD_STOP:
670 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
671 if (try)
672 return 0;
673 cx18_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
674 return 0;
675
676 case V4L2_ENC_CMD_PAUSE:
677 enc->flags = 0;
678 if (try)
679 return 0;
680 if (!atomic_read(&cx->capturing))
681 return -EPERM;
682 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
683 return 0;
684 cx18_mute(cx);
685 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx));
686 break;
687
688 case V4L2_ENC_CMD_RESUME:
689 enc->flags = 0;
690 if (try)
691 return 0;
692 if (!atomic_read(&cx->capturing))
693 return -EPERM;
694 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
695 return 0;
696 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx));
697 cx18_unmute(cx);
698 break;
699 default:
700 return -EINVAL;
701 }
702 break;
703 }
704
705 case VIDIOC_LOG_STATUS:
706 {
707 struct v4l2_input vidin;
708 struct v4l2_audio audin;
709 int i;
710
711 CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
712 if (cx->hw_flags & CX18_HW_TVEEPROM) {
713 struct tveeprom tv;
714
715 cx18_read_eeprom(cx, &tv);
716 }
717 cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
718 cx18_get_input(cx, cx->active_input, &vidin);
719 cx18_get_audio_input(cx, cx->audio_input, &audin);
720 CX18_INFO("Video Input: %s\n", vidin.name);
721 CX18_INFO("Audio Input: %s\n", audin.name);
722 CX18_INFO("Tuner: %s\n",
723 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?
724 "Radio" : "TV");
725 cx2341x_log_status(&cx->params, cx->name);
726 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
727 for (i = 0; i < CX18_MAX_STREAMS; i++) {
728 struct cx18_stream *s = &cx->streams[i];
729
730 if (s->v4l2dev == NULL || s->buffers == 0)
731 continue;
732 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
733 s->name, s->s_flags,
734 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
735 (s->buffers * s->buf_size) / 1024, s->buffers);
736 }
737 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
738 (long long)cx->mpg_data_received,
739 (long long)cx->vbi_data_inserted);
740 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
741 break;
742 }
743
744 default:
745 return -EINVAL;
746 }
747 return 0;
748}
749
750static int cx18_v4l2_do_ioctl(struct inode *inode, struct file *filp,
751 unsigned int cmd, void *arg)
752{
753 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
754 struct cx18 *cx = id->cx;
755 int ret;
756
757 /* check priority */
758 switch (cmd) {
759 case VIDIOC_S_CTRL:
760 case VIDIOC_S_STD:
761 case VIDIOC_S_INPUT:
762 case VIDIOC_S_TUNER:
763 case VIDIOC_S_FREQUENCY:
764 case VIDIOC_S_FMT:
765 case VIDIOC_S_CROP:
766 case VIDIOC_S_EXT_CTRLS:
767 ret = v4l2_prio_check(&cx->prio, &id->prio);
768 if (ret)
769 return ret;
770 }
771
772 switch (cmd) {
773 case VIDIOC_DBG_G_REGISTER:
774 case VIDIOC_DBG_S_REGISTER:
775 case VIDIOC_G_CHIP_IDENT:
776 case VIDIOC_INT_S_AUDIO_ROUTING:
777 case VIDIOC_INT_RESET:
778 if (cx18_debug & CX18_DBGFLG_IOCTL) {
779 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
780 v4l_printk_ioctl(cmd);
781 }
782 return cx18_debug_ioctls(filp, cmd, arg);
783
784 case VIDIOC_G_PRIORITY:
785 case VIDIOC_S_PRIORITY:
786 case VIDIOC_QUERYCAP:
787 case VIDIOC_ENUMINPUT:
788 case VIDIOC_G_INPUT:
789 case VIDIOC_S_INPUT:
790 case VIDIOC_G_FMT:
791 case VIDIOC_S_FMT:
792 case VIDIOC_TRY_FMT:
793 case VIDIOC_ENUM_FMT:
794 case VIDIOC_CROPCAP:
795 case VIDIOC_G_CROP:
796 case VIDIOC_S_CROP:
797 case VIDIOC_G_FREQUENCY:
798 case VIDIOC_S_FREQUENCY:
799 case VIDIOC_ENUMSTD:
800 case VIDIOC_G_STD:
801 case VIDIOC_S_STD:
802 case VIDIOC_S_TUNER:
803 case VIDIOC_G_TUNER:
804 case VIDIOC_ENUMAUDIO:
805 case VIDIOC_S_AUDIO:
806 case VIDIOC_G_AUDIO:
807 case VIDIOC_G_SLICED_VBI_CAP:
808 case VIDIOC_LOG_STATUS:
809 case VIDIOC_G_ENC_INDEX:
810 case VIDIOC_ENCODER_CMD:
811 case VIDIOC_TRY_ENCODER_CMD:
812 if (cx18_debug & CX18_DBGFLG_IOCTL) {
813 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
814 v4l_printk_ioctl(cmd);
815 }
816 return cx18_v4l2_ioctls(cx, filp, cmd, arg);
817
818 case VIDIOC_QUERYMENU:
819 case VIDIOC_QUERYCTRL:
820 case VIDIOC_S_CTRL:
821 case VIDIOC_G_CTRL:
822 case VIDIOC_S_EXT_CTRLS:
823 case VIDIOC_G_EXT_CTRLS:
824 case VIDIOC_TRY_EXT_CTRLS:
825 if (cx18_debug & CX18_DBGFLG_IOCTL) {
826 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
827 v4l_printk_ioctl(cmd);
828 }
829 return cx18_control_ioctls(cx, cmd, arg);
830
831 case 0x00005401: /* Handle isatty() calls */
832 return -EINVAL;
833 default:
834 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
835 cx18_v4l2_do_ioctl);
836 }
837 return 0;
838}
839
840int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
841 unsigned long arg)
842{
843 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
844 struct cx18 *cx = id->cx;
845 int res;
846
847 mutex_lock(&cx->serialize_lock);
848 res = video_usercopy(inode, filp, cmd, arg, cx18_v4l2_do_ioctl);
849 mutex_unlock(&cx->serialize_lock);
850 return res;
851}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
new file mode 100644
index 000000000000..9f4c7eb2897f
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -0,0 +1,30 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24u16 cx18_service2vbi(int type);
25void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
26u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
27int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
28 unsigned long arg);
29int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd,
30 void *arg);
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
new file mode 100644
index 000000000000..6e14f8bda559
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -0,0 +1,179 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-firmware.h"
24#include "cx18-fileops.h"
25#include "cx18-queue.h"
26#include "cx18-irq.h"
27#include "cx18-ioctl.h"
28#include "cx18-mailbox.h"
29#include "cx18-vbi.h"
30#include "cx18-scb.h"
31
32#define DMA_MAGIC_COOKIE 0x000001fe
33
34static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
35{
36 u32 handle = mb->args[0];
37 struct cx18_stream *s = NULL;
38 struct cx18_buffer *buf;
39 u32 off;
40 int i;
41 int id;
42
43 for (i = 0; i < CX18_MAX_STREAMS; i++) {
44 s = &cx->streams[i];
45 if ((handle == s->handle) && (s->dvb.enabled))
46 break;
47 if (s->v4l2dev && handle == s->handle)
48 break;
49 }
50 if (i == CX18_MAX_STREAMS) {
51 CX18_WARN("DMA done for unknown handle %d for stream %s\n",
52 handle, s->name);
53 mb->error = CXERR_NOT_OPEN;
54 mb->cmd = 0;
55 cx18_mb_ack(cx, mb);
56 return;
57 }
58
59 off = mb->args[1];
60 if (mb->args[2] != 1)
61 CX18_WARN("Ack struct = %d for %s\n",
62 mb->args[2], s->name);
63 id = read_enc(off);
64 buf = cx18_queue_find_buf(s, id, read_enc(off + 4));
65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
66 if (buf) {
67 cx18_buf_sync_for_cpu(s, buf);
68 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
69 /* process the buffer here */
70 CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n",
71 buf->bytesused);
72
73 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
74 buf->bytesused);
75
76 cx18_buf_sync_for_device(s, buf);
77 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
78 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
79 1, buf->id, s->buf_size);
80 } else
81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
82 } else {
83 CX18_WARN("Could not find buf %d for stream %s\n",
84 read_enc(off), s->name);
85 }
86 mb->error = 0;
87 mb->cmd = 0;
88 cx18_mb_ack(cx, mb);
89 wake_up(&cx->dma_waitq);
90 if (s->id != -1)
91 wake_up(&s->waitq);
92}
93
94static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
95{
96 char str[256] = { 0 };
97 char *p;
98
99 if (mb->args[1]) {
100 setup_page(mb->args[1]);
101 memcpy_fromio(str, cx->enc_mem + mb->args[1], 252);
102 str[252] = 0;
103 }
104 cx18_mb_ack(cx, mb);
105 CX18_DEBUG_INFO("%x %s\n", mb->args[0], str);
106 p = strchr(str, '.');
107 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
108 CX18_INFO("FW version: %s\n", p - 1);
109}
110
111static void hpu_cmd(struct cx18 *cx, u32 sw1)
112{
113 struct cx18_mailbox mb;
114
115 if (sw1 & IRQ_CPU_TO_EPU) {
116 memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb));
117 mb.error = 0;
118
119 switch (mb.cmd) {
120 case CX18_EPU_DMA_DONE:
121 epu_dma_done(cx, &mb);
122 break;
123 case CX18_EPU_DEBUG:
124 epu_debug(cx, &mb);
125 break;
126 default:
127 CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd);
128 break;
129 }
130 }
131 if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU))
132 CX18_WARN("Unexpected interrupt %08x\n", sw1);
133}
134
135irqreturn_t cx18_irq_handler(int irq, void *dev_id)
136{
137 struct cx18 *cx = (struct cx18 *)dev_id;
138 u32 sw1, sw1_mask;
139 u32 sw2, sw2_mask;
140 u32 hw2, hw2_mask;
141
142 spin_lock(&cx->dma_reg_lock);
143
144 hw2_mask = read_reg(HW2_INT_MASK5_PCI);
145 hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask;
146 sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
147 sw2 = read_reg(SW2_INT_STATUS) & sw2_mask;
148 sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
149 sw1 = read_reg(SW1_INT_STATUS) & sw1_mask;
150
151 write_reg(sw2&sw2_mask, SW2_INT_STATUS);
152 write_reg(sw1&sw1_mask, SW1_INT_STATUS);
153 write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS);
154
155 if (sw1 || sw2 || hw2)
156 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
157
158 /* To do: interrupt-based I2C handling
159 if (hw2 & 0x00c00000) {
160 }
161 */
162
163 if (sw2) {
164 if (sw2 & (cx->scb->cpu2hpu_irq_ack | cx->scb->cpu2epu_irq_ack))
165 wake_up(&cx->mb_cpu_waitq);
166 if (sw2 & (cx->scb->apu2hpu_irq_ack | cx->scb->apu2epu_irq_ack))
167 wake_up(&cx->mb_apu_waitq);
168 if (sw2 & cx->scb->epu2hpu_irq_ack)
169 wake_up(&cx->mb_epu_waitq);
170 if (sw2 & cx->scb->hpu2epu_irq_ack)
171 wake_up(&cx->mb_hpu_waitq);
172 }
173
174 if (sw1)
175 hpu_cmd(cx, sw1);
176 spin_unlock(&cx->dma_reg_lock);
177
178 return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE;
179}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
new file mode 100644
index 000000000000..379f704f5cba
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.h
@@ -0,0 +1,37 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#define HW2_I2C1_INT (1 << 22)
23#define HW2_I2C2_INT (1 << 23)
24#define HW2_INT_CLR_STATUS 0xc730c4
25#define HW2_INT_MASK5_PCI 0xc730e4
26#define SW1_INT_SET 0xc73100
27#define SW1_INT_STATUS 0xc73104
28#define SW1_INT_ENABLE_PCI 0xc7311c
29#define SW2_INT_SET 0xc73140
30#define SW2_INT_STATUS 0xc73144
31#define SW2_INT_ENABLE_PCI 0xc7315c
32
33irqreturn_t cx18_irq_handler(int irq, void *dev_id);
34
35void cx18_irq_work_handler(struct work_struct *work);
36void cx18_dma_stream_dec_prepare(struct cx18_stream *s, u32 offset, int lock);
37void cx18_unfinished_dma(unsigned long arg);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
new file mode 100644
index 000000000000..0c5f328bca54
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -0,0 +1,372 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include <stdarg.h>
23
24#include "cx18-driver.h"
25#include "cx18-scb.h"
26#include "cx18-irq.h"
27#include "cx18-mailbox.h"
28
29#define API_FAST (1 << 2) /* Short timeout */
30#define API_SLOW (1 << 3) /* Additional 300ms timeout */
31
32#define APU 0
33#define CPU 1
34#define EPU 2
35#define HPU 3
36
37struct cx18_api_info {
38 u32 cmd;
39 u8 flags; /* Flags, see above */
40 u8 rpu; /* Processing unit */
41 const char *name; /* The name of the command */
42};
43
44#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
45
46static const struct cx18_api_info api_info[] = {
47 /* MPEG encoder API */
48 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
49 API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
50 API_ENTRY(CPU, CX18_CREATE_TASK, 0),
51 API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
52 API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
53 API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
54 API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
55 API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
56 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
57 API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
58 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
59 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
60 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
61 API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
62 API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
63 API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
64 API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
65 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
66 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
67 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
68 API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
69 API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
70 API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
71 API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
72 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
73 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
74 API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
75 API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
76 API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
77 API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
78 API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
79 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
80 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
81 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
82 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
84 API_ENTRY(0, 0, 0),
85};
86
87static const struct cx18_api_info *find_api_info(u32 cmd)
88{
89 int i;
90
91 for (i = 0; api_info[i].cmd; i++)
92 if (api_info[i].cmd == cmd)
93 return &api_info[i];
94 return NULL;
95}
96
97static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu,
98 u32 *state, u32 *irq, u32 *req)
99{
100 struct cx18_mailbox *mb = NULL;
101 int wait_count = 0;
102 u32 ack;
103
104 switch (rpu) {
105 case APU:
106 mb = &cx->scb->epu2apu_mb;
107 *state = readl(&cx->scb->apu_state);
108 *irq = readl(&cx->scb->epu2apu_irq);
109 break;
110
111 case CPU:
112 mb = &cx->scb->epu2cpu_mb;
113 *state = readl(&cx->scb->cpu_state);
114 *irq = readl(&cx->scb->epu2cpu_irq);
115 break;
116
117 case HPU:
118 mb = &cx->scb->epu2hpu_mb;
119 *state = readl(&cx->scb->hpu_state);
120 *irq = readl(&cx->scb->epu2hpu_irq);
121 break;
122 }
123
124 if (mb == NULL)
125 return mb;
126
127 do {
128 *req = readl(&mb->request);
129 ack = readl(&mb->ack);
130 wait_count++;
131 } while (*req != ack && wait_count < 600);
132
133 if (*req == ack) {
134 (*req)++;
135 if (*req == 0 || *req == 0xffffffff)
136 *req = 1;
137 return mb;
138 }
139 return NULL;
140}
141
142long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
143{
144 const struct cx18_api_info *info = find_api_info(mb->cmd);
145 struct cx18_mailbox *ack_mb;
146 u32 ack_irq;
147 u8 rpu = CPU;
148
149 if (info == NULL && mb->cmd) {
150 CX18_WARN("Cannot ack unknown command %x\n", mb->cmd);
151 return -EINVAL;
152 }
153 if (info)
154 rpu = info->rpu;
155
156 switch (rpu) {
157 case HPU:
158 ack_irq = IRQ_EPU_TO_HPU_ACK;
159 ack_mb = &cx->scb->hpu2epu_mb;
160 break;
161 case APU:
162 ack_irq = IRQ_EPU_TO_APU_ACK;
163 ack_mb = &cx->scb->apu2epu_mb;
164 break;
165 case CPU:
166 ack_irq = IRQ_EPU_TO_CPU_ACK;
167 ack_mb = &cx->scb->cpu2epu_mb;
168 break;
169 default:
170 CX18_WARN("Unknown RPU for command %x\n", mb->cmd);
171 return -EINVAL;
172 }
173
174 setup_page(SCB_OFFSET);
175 write_sync(mb->request, &ack_mb->ack);
176 write_reg(ack_irq, SW2_INT_SET);
177 return 0;
178}
179
180
181static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
182{
183 const struct cx18_api_info *info = find_api_info(cmd);
184 u32 state = 0, irq = 0, req, oldreq, err;
185 struct cx18_mailbox *mb;
186 wait_queue_head_t *waitq;
187 int timeout = 100;
188 int cnt = 0;
189 int sig = 0;
190 int i;
191
192 if (info == NULL) {
193 CX18_WARN("unknown cmd %x\n", cmd);
194 return -EINVAL;
195 }
196
197 if (cmd == CX18_CPU_DE_SET_MDL)
198 CX18_DEBUG_HI_API("%s\n", info->name);
199 else
200 CX18_DEBUG_API("%s\n", info->name);
201 setup_page(SCB_OFFSET);
202 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
203
204 if (mb == NULL) {
205 CX18_ERR("mb %s busy\n", info->name);
206 return -EBUSY;
207 }
208
209 oldreq = req - 1;
210 writel(cmd, &mb->cmd);
211 for (i = 0; i < args; i++)
212 writel(data[i], &mb->args[i]);
213 writel(0, &mb->error);
214 writel(req, &mb->request);
215
216 switch (info->rpu) {
217 case APU: waitq = &cx->mb_apu_waitq; break;
218 case CPU: waitq = &cx->mb_cpu_waitq; break;
219 case EPU: waitq = &cx->mb_epu_waitq; break;
220 case HPU: waitq = &cx->mb_hpu_waitq; break;
221 default: return -EINVAL;
222 }
223 if (info->flags & API_FAST)
224 timeout /= 2;
225 write_reg(irq, SW1_INT_SET);
226
227 while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) {
228 if (cnt > 200 && !in_atomic())
229 sig = cx18_msleep_timeout(10, 1);
230 cnt++;
231 }
232 if (sig)
233 return -EINTR;
234 if (cnt == 660) {
235 writel(oldreq, &mb->request);
236 CX18_ERR("mb %s failed\n", info->name);
237 return -EINVAL;
238 }
239 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
240 data[i] = readl(&mb->args[i]);
241 err = readl(&mb->error);
242 if (!in_atomic() && (info->flags & API_SLOW))
243 cx18_msleep_timeout(300, 0);
244 if (err)
245 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
246 info->name);
247 return err ? -EIO : 0;
248}
249
250int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
251{
252 int res = cx18_api_call(cx, cmd, args, data);
253
254 /* Allow a single retry, probably already too late though.
255 If there is no free mailbox then that is usually an indication
256 of a more serious problem. */
257 return (res == -EBUSY) ? cx18_api_call(cx, cmd, args, data) : res;
258}
259
260static int cx18_set_filter_param(struct cx18_stream *s)
261{
262 struct cx18 *cx = s->cx;
263 u32 mode;
264 int ret;
265
266 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
267 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
268 s->handle, 1, mode, cx->spatial_strength);
269 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
270 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
271 s->handle, 0, mode, cx->temporal_strength);
272 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
273 s->handle, 2, cx->filter_mode >> 2, 0);
274 return ret;
275}
276
277int cx18_api_func(void *priv, u32 cmd, int in, int out,
278 u32 data[CX2341X_MBOX_MAX_DATA])
279{
280 struct cx18 *cx = priv;
281 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
282
283 switch (cmd) {
284 case CX2341X_ENC_SET_OUTPUT_PORT:
285 return 0;
286 case CX2341X_ENC_SET_FRAME_RATE:
287 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
288 s->handle, 0, 0, 0, 0, data[0]);
289 case CX2341X_ENC_SET_FRAME_SIZE:
290 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
291 s->handle, data[1], data[0]);
292 case CX2341X_ENC_SET_STREAM_TYPE:
293 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
294 s->handle, data[0]);
295 case CX2341X_ENC_SET_ASPECT_RATIO:
296 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
297 s->handle, data[0]);
298
299 case CX2341X_ENC_SET_GOP_PROPERTIES:
300 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
301 s->handle, data[0], data[1]);
302 case CX2341X_ENC_SET_GOP_CLOSURE:
303 return 0;
304 case CX2341X_ENC_SET_AUDIO_PROPERTIES:
305 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
306 s->handle, data[0]);
307 case CX2341X_ENC_MUTE_AUDIO:
308 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
309 s->handle, data[0]);
310 case CX2341X_ENC_SET_BIT_RATE:
311 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
312 s->handle, data[0], data[1], data[2], data[3]);
313 case CX2341X_ENC_MUTE_VIDEO:
314 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
315 s->handle, data[0]);
316 case CX2341X_ENC_SET_FRAME_DROP_RATE:
317 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
318 s->handle, data[0]);
319 case CX2341X_ENC_MISC:
320 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
321 s->handle, data[0], data[1], data[2]);
322 case CX2341X_ENC_SET_DNR_FILTER_MODE:
323 cx->filter_mode = (data[0] & 3) | (data[1] << 2);
324 return cx18_set_filter_param(s);
325 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
326 cx->spatial_strength = data[0];
327 cx->temporal_strength = data[1];
328 return cx18_set_filter_param(s);
329 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
330 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
331 s->handle, data[0], data[1]);
332 case CX2341X_ENC_SET_CORING_LEVELS:
333 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
334 s->handle, data[0], data[1], data[2], data[3]);
335 }
336 CX18_WARN("Unknown cmd %x\n", cmd);
337 return 0;
338}
339
340int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
341 u32 cmd, int args, ...)
342{
343 va_list ap;
344 int i;
345
346 va_start(ap, args);
347 for (i = 0; i < args; i++)
348 data[i] = va_arg(ap, u32);
349 va_end(ap);
350 return cx18_api(cx, cmd, args, data);
351}
352
353int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
354{
355 u32 data[MAX_MB_ARGUMENTS];
356 va_list ap;
357 int i;
358
359 if (cx == NULL) {
360 CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
361 return 0;
362 }
363 if (args > MAX_MB_ARGUMENTS) {
364 CX18_ERR("args too big (cmd=%x)\n", cmd);
365 args = MAX_MB_ARGUMENTS;
366 }
367 va_start(ap, args);
368 for (i = 0; i < args; i++)
369 data[i] = va_arg(ap, u32);
370 va_end(ap);
371 return cx18_api(cx, cmd, args, data);
372}
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
new file mode 100644
index 000000000000..d995641536b3
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -0,0 +1,73 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef _CX18_MAILBOX_H_
23#define _CX18_MAILBOX_H_
24
25/* mailbox max args */
26#define MAX_MB_ARGUMENTS 6
27/* compatibility, should be same as the define in cx2341x.h */
28#define CX2341X_MBOX_MAX_DATA 16
29
30#define MB_RESERVED_HANDLE_0 0
31#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
32
33struct cx18;
34
35/* The cx18_mailbox struct is the mailbox structure which is used for passing
36 messages between processors */
37struct cx18_mailbox {
38 /* The sender sets a handle in 'request' after he fills the command. The
39 'request' should be different than 'ack'. The sender, also, generates
40 an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the
41 receiver. */
42 u32 request;
43 /* The receiver detects a new command when 'req' is different than 'ack'.
44 He sets 'ack' to the same value as 'req' to clear the command. He, also,
45 generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU
46 is the receiver. */
47 u32 ack;
48 u32 reserved[6];
49 /* 'cmd' identifies the command. The list of these commands are in
50 cx23418.h */
51 u32 cmd;
52 /* Each command can have up to 6 arguments */
53 u32 args[MAX_MB_ARGUMENTS];
54 /* The return code can be one of the codes in the file cx23418.h. If the
55 command is completed successfuly, the error will be ERR_SYS_SUCCESS.
56 If it is pending, the code is ERR_SYS_PENDING. If it failed, the error
57 code would indicate the task from which the error originated and will
58 be one of the errors in cx23418.h. In that case, the following
59 applies ((error & 0xff) != 0).
60 If the command is pending, the return will be passed in a MB from the
61 receiver to the sender. 'req' will be returned in args[0] */
62 u32 error;
63};
64
65int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
66int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
67 int args, ...);
68int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
69int cx18_api_func(void *priv, u32 cmd, int in, int out,
70 u32 data[CX2341X_MBOX_MAX_DATA]);
71long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb);
72
73#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
new file mode 100644
index 000000000000..65af1bb507ca
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -0,0 +1,282 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-streams.h"
26#include "cx18-queue.h"
27#include "cx18-scb.h"
28
29int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
30 const char __user *src, int copybytes)
31{
32 if (s->buf_size - buf->bytesused < copybytes)
33 copybytes = s->buf_size - buf->bytesused;
34 if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
35 return -EFAULT;
36 buf->bytesused += copybytes;
37 return copybytes;
38}
39
40void cx18_buf_swap(struct cx18_buffer *buf)
41{
42 int i;
43
44 for (i = 0; i < buf->bytesused; i += 4)
45 swab32s((u32 *)(buf->buf + i));
46}
47
48void cx18_queue_init(struct cx18_queue *q)
49{
50 INIT_LIST_HEAD(&q->list);
51 q->buffers = 0;
52 q->length = 0;
53 q->bytesused = 0;
54}
55
56void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
57 struct cx18_queue *q)
58{
59 unsigned long flags = 0;
60
61 /* clear the buffer if it is going to be enqueued to the free queue */
62 if (q == &s->q_free) {
63 buf->bytesused = 0;
64 buf->readpos = 0;
65 buf->b_flags = 0;
66 }
67 spin_lock_irqsave(&s->qlock, flags);
68 list_add_tail(&buf->list, &q->list);
69 q->buffers++;
70 q->length += s->buf_size;
71 q->bytesused += buf->bytesused - buf->readpos;
72 spin_unlock_irqrestore(&s->qlock, flags);
73}
74
75struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
76{
77 struct cx18_buffer *buf = NULL;
78 unsigned long flags = 0;
79
80 spin_lock_irqsave(&s->qlock, flags);
81 if (!list_empty(&q->list)) {
82 buf = list_entry(q->list.next, struct cx18_buffer, list);
83 list_del_init(q->list.next);
84 q->buffers--;
85 q->length -= s->buf_size;
86 q->bytesused -= buf->bytesused - buf->readpos;
87 }
88 spin_unlock_irqrestore(&s->qlock, flags);
89 return buf;
90}
91
92struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
93 u32 bytesused)
94{
95 struct cx18 *cx = s->cx;
96 struct list_head *p;
97
98 list_for_each(p, &s->q_free.list) {
99 struct cx18_buffer *buf =
100 list_entry(p, struct cx18_buffer, list);
101
102 if (buf->id != id)
103 continue;
104 buf->bytesused = bytesused;
105 /* the transport buffers are handled differently,
106 so there is no need to move them to the full queue */
107 if (s->type == CX18_ENC_STREAM_TYPE_TS)
108 return buf;
109 s->q_free.buffers--;
110 s->q_free.length -= s->buf_size;
111 s->q_full.buffers++;
112 s->q_full.length += s->buf_size;
113 s->q_full.bytesused += buf->bytesused;
114 list_move_tail(&buf->list, &s->q_full.list);
115 return buf;
116 }
117 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
118 return NULL;
119}
120
121static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
122 struct cx18_queue *to, int clear, int full)
123{
124 struct cx18_buffer *buf =
125 list_entry(from->list.next, struct cx18_buffer, list);
126
127 list_move_tail(from->list.next, &to->list);
128 from->buffers--;
129 from->length -= s->buf_size;
130 from->bytesused -= buf->bytesused - buf->readpos;
131 /* special handling for q_free */
132 if (clear)
133 buf->bytesused = buf->readpos = buf->b_flags = 0;
134 else if (full) {
135 /* special handling for stolen buffers, assume
136 all bytes are used. */
137 buf->bytesused = s->buf_size;
138 buf->readpos = buf->b_flags = 0;
139 }
140 to->buffers++;
141 to->length += s->buf_size;
142 to->bytesused += buf->bytesused - buf->readpos;
143}
144
145/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
146 If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
147 If 'steal' != NULL, then buffers may also taken from that queue if
148 needed.
149
150 The buffer is automatically cleared if it goes to the free queue. It is
151 also cleared if buffers need to be taken from the 'steal' queue and
152 the 'from' queue is the free queue.
153
154 When 'from' is q_free, then needed_bytes is compared to the total
155 available buffer length, otherwise needed_bytes is compared to the
156 bytesused value. For the 'steal' queue the total available buffer
157 length is always used.
158
159 -ENOMEM is returned if the buffers could not be obtained, 0 if all
160 buffers where obtained from the 'from' list and if non-zero then
161 the number of stolen buffers is returned. */
162int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
163 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
164{
165 unsigned long flags;
166 int rc = 0;
167 int from_free = from == &s->q_free;
168 int to_free = to == &s->q_free;
169 int bytes_available;
170
171 spin_lock_irqsave(&s->qlock, flags);
172 if (needed_bytes == 0) {
173 from_free = 1;
174 needed_bytes = from->length;
175 }
176
177 bytes_available = from_free ? from->length : from->bytesused;
178 bytes_available += steal ? steal->length : 0;
179
180 if (bytes_available < needed_bytes) {
181 spin_unlock_irqrestore(&s->qlock, flags);
182 return -ENOMEM;
183 }
184 if (from_free) {
185 u32 old_length = to->length;
186
187 while (to->length - old_length < needed_bytes) {
188 if (list_empty(&from->list))
189 from = steal;
190 if (from == steal)
191 rc++; /* keep track of 'stolen' buffers */
192 cx18_queue_move_buf(s, from, to, 1, 0);
193 }
194 } else {
195 u32 old_bytesused = to->bytesused;
196
197 while (to->bytesused - old_bytesused < needed_bytes) {
198 if (list_empty(&from->list))
199 from = steal;
200 if (from == steal)
201 rc++; /* keep track of 'stolen' buffers */
202 cx18_queue_move_buf(s, from, to, to_free, rc);
203 }
204 }
205 spin_unlock_irqrestore(&s->qlock, flags);
206 return rc;
207}
208
209void cx18_flush_queues(struct cx18_stream *s)
210{
211 cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
212 cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
213}
214
215int cx18_stream_alloc(struct cx18_stream *s)
216{
217 struct cx18 *cx = s->cx;
218 int i;
219
220 if (s->buffers == 0)
221 return 0;
222
223 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
224 s->name, s->buffers, s->buf_size,
225 s->buffers * s->buf_size / 1024);
226
227 if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
228 (char *)cx->scb) > SCB_RESERVED_SIZE) {
229 unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE -
230 ((char *)cx->scb->cpu_mdl));
231
232 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
233 CX18_ERR("Max buffers = %zd\n",
234 bufsz / sizeof(struct cx18_mdl));
235 return -ENOMEM;
236 }
237
238 s->mdl_offset = cx->mdl_offset;
239
240 /* allocate stream buffers. Initially all buffers are in q_free. */
241 for (i = 0; i < s->buffers; i++) {
242 struct cx18_buffer *buf =
243 kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
244
245 if (buf == NULL)
246 break;
247 buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
248 if (buf->buf == NULL) {
249 kfree(buf);
250 break;
251 }
252 buf->id = cx->buffer_id++;
253 INIT_LIST_HEAD(&buf->list);
254 buf->dma_handle = pci_map_single(s->cx->dev,
255 buf->buf, s->buf_size, s->dma);
256 cx18_buf_sync_for_cpu(s, buf);
257 cx18_enqueue(s, buf, &s->q_free);
258 }
259 if (i == s->buffers) {
260 cx->mdl_offset += s->buffers;
261 return 0;
262 }
263 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
264 cx18_stream_free(s);
265 return -ENOMEM;
266}
267
268void cx18_stream_free(struct cx18_stream *s)
269{
270 struct cx18_buffer *buf;
271
272 /* move all buffers to q_free */
273 cx18_flush_queues(s);
274
275 /* empty q_free */
276 while ((buf = cx18_dequeue(s, &s->q_free))) {
277 pci_unmap_single(s->cx->dev, buf->dma_handle,
278 s->buf_size, s->dma);
279 kfree(buf->buf);
280 kfree(buf);
281 }
282}
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
new file mode 100644
index 000000000000..f86c8a6fa6e7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -0,0 +1,59 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#define CX18_DMA_UNMAPPED ((u32) -1)
25
26/* cx18_buffer utility functions */
27
28static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
29 struct cx18_buffer *buf)
30{
31 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
32 s->buf_size, s->dma);
33}
34
35static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
36 struct cx18_buffer *buf)
37{
38 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
39 s->buf_size, s->dma);
40}
41
42int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
43 const char __user *src, int copybytes);
44void cx18_buf_swap(struct cx18_buffer *buf);
45
46/* cx18_queue utility functions */
47void cx18_queue_init(struct cx18_queue *q);
48void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
49 struct cx18_queue *q);
50struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
51int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
52 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
53struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
54 u32 bytesused);
55void cx18_flush_queues(struct cx18_stream *s);
56
57/* cx18_stream utility functions */
58int cx18_stream_alloc(struct cx18_stream *s);
59void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
new file mode 100644
index 000000000000..30bc803e30da
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -0,0 +1,121 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-scb.h"
24
25void cx18_init_scb(struct cx18 *cx)
26{
27 setup_page(SCB_OFFSET);
28 memset_io(cx->scb, 0, 0x10000);
29
30 writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
31 writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
32 writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
33 writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
34 writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
35 writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
36 writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
37 writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
38
39 writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
40 writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
41 writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
42 writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
43 writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
44 writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
45 writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
46 writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
47
48 writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
49 writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
50 writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
51 writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
52 writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
53 writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
54 writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
55 writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
56
57 writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
58 writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
59 writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
60 writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
61 writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
62 writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
63 writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
64 writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
65
66 writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
67 writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
68 writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
69 writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
70 writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
71 writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
72 writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
73 writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
74
75 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
76 &cx->scb->apu2cpu_mb_offset);
77 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
78 &cx->scb->hpu2cpu_mb_offset);
79 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
80 &cx->scb->ppu2cpu_mb_offset);
81 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
82 &cx->scb->epu2cpu_mb_offset);
83 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
84 &cx->scb->cpu2apu_mb_offset);
85 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
86 &cx->scb->hpu2apu_mb_offset);
87 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
88 &cx->scb->ppu2apu_mb_offset);
89 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
90 &cx->scb->epu2apu_mb_offset);
91 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
92 &cx->scb->cpu2hpu_mb_offset);
93 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
94 &cx->scb->apu2hpu_mb_offset);
95 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
96 &cx->scb->ppu2hpu_mb_offset);
97 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
98 &cx->scb->epu2hpu_mb_offset);
99 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
100 &cx->scb->cpu2ppu_mb_offset);
101 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
102 &cx->scb->apu2ppu_mb_offset);
103 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
104 &cx->scb->hpu2ppu_mb_offset);
105 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
106 &cx->scb->epu2ppu_mb_offset);
107 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
108 &cx->scb->cpu2epu_mb_offset);
109 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
110 &cx->scb->apu2epu_mb_offset);
111 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
112 &cx->scb->hpu2epu_mb_offset);
113 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
114 &cx->scb->ppu2epu_mb_offset);
115
116 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
117 &cx->scb->ipc_offset);
118
119 writel(1, &cx->scb->hpu_state);
120 writel(1, &cx->scb->epu_state);
121}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
new file mode 100644
index 000000000000..86b4cb15d163
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -0,0 +1,285 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX18_SCB_H
23#define CX18_SCB_H
24
25#include "cx18-mailbox.h"
26
27/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts
28 are in the SW1 register. */
29
30#define IRQ_APU_TO_CPU 0x00000001
31#define IRQ_CPU_TO_APU_ACK 0x00000001
32#define IRQ_HPU_TO_CPU 0x00000002
33#define IRQ_CPU_TO_HPU_ACK 0x00000002
34#define IRQ_PPU_TO_CPU 0x00000004
35#define IRQ_CPU_TO_PPU_ACK 0x00000004
36#define IRQ_EPU_TO_CPU 0x00000008
37#define IRQ_CPU_TO_EPU_ACK 0x00000008
38
39#define IRQ_CPU_TO_APU 0x00000010
40#define IRQ_APU_TO_CPU_ACK 0x00000010
41#define IRQ_HPU_TO_APU 0x00000020
42#define IRQ_APU_TO_HPU_ACK 0x00000020
43#define IRQ_PPU_TO_APU 0x00000040
44#define IRQ_APU_TO_PPU_ACK 0x00000040
45#define IRQ_EPU_TO_APU 0x00000080
46#define IRQ_APU_TO_EPU_ACK 0x00000080
47
48#define IRQ_CPU_TO_HPU 0x00000100
49#define IRQ_HPU_TO_CPU_ACK 0x00000100
50#define IRQ_APU_TO_HPU 0x00000200
51#define IRQ_HPU_TO_APU_ACK 0x00000200
52#define IRQ_PPU_TO_HPU 0x00000400
53#define IRQ_HPU_TO_PPU_ACK 0x00000400
54#define IRQ_EPU_TO_HPU 0x00000800
55#define IRQ_HPU_TO_EPU_ACK 0x00000800
56
57#define IRQ_CPU_TO_PPU 0x00001000
58#define IRQ_PPU_TO_CPU_ACK 0x00001000
59#define IRQ_APU_TO_PPU 0x00002000
60#define IRQ_PPU_TO_APU_ACK 0x00002000
61#define IRQ_HPU_TO_PPU 0x00004000
62#define IRQ_PPU_TO_HPU_ACK 0x00004000
63#define IRQ_EPU_TO_PPU 0x00008000
64#define IRQ_PPU_TO_EPU_ACK 0x00008000
65
66#define IRQ_CPU_TO_EPU 0x00010000
67#define IRQ_EPU_TO_CPU_ACK 0x00010000
68#define IRQ_APU_TO_EPU 0x00020000
69#define IRQ_EPU_TO_APU_ACK 0x00020000
70#define IRQ_HPU_TO_EPU 0x00040000
71#define IRQ_EPU_TO_HPU_ACK 0x00040000
72#define IRQ_PPU_TO_EPU 0x00080000
73#define IRQ_EPU_TO_PPU_ACK 0x00080000
74
75#define SCB_OFFSET 0xDC0000
76
77/* If Firmware uses fixed memory map, it shall not allocate the area
78 between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */
79#define SCB_RESERVED_SIZE 0x10000
80
81
82/* This structure is used by EPU to provide memory descriptors in its memory */
83struct cx18_mdl {
84 u32 paddr; /* Physical address of a buffer segment */
85 u32 length; /* Length of the buffer segment */
86};
87
88/* This structure is used by CPU to provide completed buffers information */
89struct cx18_mdl_ack {
90 u32 id; /* ID of a completed MDL */
91 u32 data_used; /* Total data filled in the MDL for buffer 'id' */
92};
93
94struct cx18_scb {
95 /* These fields form the System Control Block which is used at boot time
96 for localizing the IPC data as well as the code positions for all
97 processors. The offsets are from the start of this struct. */
98
99 /* Offset where to find the Inter-Processor Communication data */
100 u32 ipc_offset;
101 u32 reserved01[7];
102 /* Offset where to find the start of the CPU code */
103 u32 cpu_code_offset;
104 u32 reserved02[3];
105 /* Offset where to find the start of the APU code */
106 u32 apu_code_offset;
107 u32 reserved03[3];
108 /* Offset where to find the start of the HPU code */
109 u32 hpu_code_offset;
110 u32 reserved04[3];
111 /* Offset where to find the start of the PPU code */
112 u32 ppu_code_offset;
113 u32 reserved05[3];
114
115 /* These fields form Inter-Processor Communication data which is used
116 by all processors to locate the information needed for communicating
117 with other processors */
118
119 /* Fields for CPU: */
120
121 /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */
122 u32 cpu_state;
123 u32 reserved1[7];
124 /* Offset to the mailbox used for sending commands from APU to CPU */
125 u32 apu2cpu_mb_offset;
126 /* Value to write to register SW1 register set (0xC7003100) after the
127 command is ready */
128 u32 apu2cpu_irq;
129 /* Value to write to register SW2 register set (0xC7003140) after the
130 command is cleared */
131 u32 apu2cpu_irq_ack;
132 u32 reserved2[13];
133
134 u32 hpu2cpu_mb_offset;
135 u32 hpu2cpu_irq;
136 u32 hpu2cpu_irq_ack;
137 u32 reserved3[13];
138
139 u32 ppu2cpu_mb_offset;
140 u32 ppu2cpu_irq;
141 u32 ppu2cpu_irq_ack;
142 u32 reserved4[13];
143
144 u32 epu2cpu_mb_offset;
145 u32 epu2cpu_irq;
146 u32 epu2cpu_irq_ack;
147 u32 reserved5[13];
148 u32 reserved6[8];
149
150 /* Fields for APU: */
151
152 u32 apu_state;
153 u32 reserved11[7];
154 u32 cpu2apu_mb_offset;
155 u32 cpu2apu_irq;
156 u32 cpu2apu_irq_ack;
157 u32 reserved12[13];
158
159 u32 hpu2apu_mb_offset;
160 u32 hpu2apu_irq;
161 u32 hpu2apu_irq_ack;
162 u32 reserved13[13];
163
164 u32 ppu2apu_mb_offset;
165 u32 ppu2apu_irq;
166 u32 ppu2apu_irq_ack;
167 u32 reserved14[13];
168
169 u32 epu2apu_mb_offset;
170 u32 epu2apu_irq;
171 u32 epu2apu_irq_ack;
172 u32 reserved15[13];
173 u32 reserved16[8];
174
175 /* Fields for HPU: */
176
177 u32 hpu_state;
178 u32 reserved21[7];
179 u32 cpu2hpu_mb_offset;
180 u32 cpu2hpu_irq;
181 u32 cpu2hpu_irq_ack;
182 u32 reserved22[13];
183
184 u32 apu2hpu_mb_offset;
185 u32 apu2hpu_irq;
186 u32 apu2hpu_irq_ack;
187 u32 reserved23[13];
188
189 u32 ppu2hpu_mb_offset;
190 u32 ppu2hpu_irq;
191 u32 ppu2hpu_irq_ack;
192 u32 reserved24[13];
193
194 u32 epu2hpu_mb_offset;
195 u32 epu2hpu_irq;
196 u32 epu2hpu_irq_ack;
197 u32 reserved25[13];
198 u32 reserved26[8];
199
200 /* Fields for PPU: */
201
202 u32 ppu_state;
203 u32 reserved31[7];
204 u32 cpu2ppu_mb_offset;
205 u32 cpu2ppu_irq;
206 u32 cpu2ppu_irq_ack;
207 u32 reserved32[13];
208
209 u32 apu2ppu_mb_offset;
210 u32 apu2ppu_irq;
211 u32 apu2ppu_irq_ack;
212 u32 reserved33[13];
213
214 u32 hpu2ppu_mb_offset;
215 u32 hpu2ppu_irq;
216 u32 hpu2ppu_irq_ack;
217 u32 reserved34[13];
218
219 u32 epu2ppu_mb_offset;
220 u32 epu2ppu_irq;
221 u32 epu2ppu_irq_ack;
222 u32 reserved35[13];
223 u32 reserved36[8];
224
225 /* Fields for EPU: */
226
227 u32 epu_state;
228 u32 reserved41[7];
229 u32 cpu2epu_mb_offset;
230 u32 cpu2epu_irq;
231 u32 cpu2epu_irq_ack;
232 u32 reserved42[13];
233
234 u32 apu2epu_mb_offset;
235 u32 apu2epu_irq;
236 u32 apu2epu_irq_ack;
237 u32 reserved43[13];
238
239 u32 hpu2epu_mb_offset;
240 u32 hpu2epu_irq;
241 u32 hpu2epu_irq_ack;
242 u32 reserved44[13];
243
244 u32 ppu2epu_mb_offset;
245 u32 ppu2epu_irq;
246 u32 ppu2epu_irq_ack;
247 u32 reserved45[13];
248 u32 reserved46[8];
249
250 u32 semaphores[8]; /* Semaphores */
251
252 u32 reserved50[32]; /* Reserved for future use */
253
254 struct cx18_mailbox apu2cpu_mb;
255 struct cx18_mailbox hpu2cpu_mb;
256 struct cx18_mailbox ppu2cpu_mb;
257 struct cx18_mailbox epu2cpu_mb;
258
259 struct cx18_mailbox cpu2apu_mb;
260 struct cx18_mailbox hpu2apu_mb;
261 struct cx18_mailbox ppu2apu_mb;
262 struct cx18_mailbox epu2apu_mb;
263
264 struct cx18_mailbox cpu2hpu_mb;
265 struct cx18_mailbox apu2hpu_mb;
266 struct cx18_mailbox ppu2hpu_mb;
267 struct cx18_mailbox epu2hpu_mb;
268
269 struct cx18_mailbox cpu2ppu_mb;
270 struct cx18_mailbox apu2ppu_mb;
271 struct cx18_mailbox hpu2ppu_mb;
272 struct cx18_mailbox epu2ppu_mb;
273
274 struct cx18_mailbox cpu2epu_mb;
275 struct cx18_mailbox apu2epu_mb;
276 struct cx18_mailbox hpu2epu_mb;
277 struct cx18_mailbox ppu2epu_mb;
278
279 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][2];
280 struct cx18_mdl cpu_mdl[1];
281};
282
283void cx18_init_scb(struct cx18 *cx);
284
285#endif
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
new file mode 100644
index 000000000000..afb141b2027a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -0,0 +1,566 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-fileops.h"
26#include "cx18-mailbox.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-ioctl.h"
30#include "cx18-streams.h"
31#include "cx18-cards.h"
32#include "cx18-scb.h"
33#include "cx18-av-core.h"
34#include "cx18-dvb.h"
35
36#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
37
38static struct file_operations cx18_v4l2_enc_fops = {
39 .owner = THIS_MODULE,
40 .read = cx18_v4l2_read,
41 .open = cx18_v4l2_open,
42 .ioctl = cx18_v4l2_ioctl,
43 .release = cx18_v4l2_close,
44 .poll = cx18_v4l2_enc_poll,
45};
46
47/* offset from 0 to register ts v4l2 minors on */
48#define CX18_V4L2_ENC_TS_OFFSET 16
49/* offset from 0 to register pcm v4l2 minors on */
50#define CX18_V4L2_ENC_PCM_OFFSET 24
51/* offset from 0 to register yuv v4l2 minors on */
52#define CX18_V4L2_ENC_YUV_OFFSET 32
53
54static struct {
55 const char *name;
56 int vfl_type;
57 int minor_offset;
58 int dma;
59 enum v4l2_buf_type buf_type;
60 struct file_operations *fops;
61} cx18_stream_info[] = {
62 { /* CX18_ENC_STREAM_TYPE_MPG */
63 "encoder MPEG",
64 VFL_TYPE_GRABBER, 0,
65 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
66 &cx18_v4l2_enc_fops
67 },
68 { /* CX18_ENC_STREAM_TYPE_TS */
69 "TS",
70 VFL_TYPE_GRABBER, -1,
71 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
72 &cx18_v4l2_enc_fops
73 },
74 { /* CX18_ENC_STREAM_TYPE_YUV */
75 "encoder YUV",
76 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
77 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
78 &cx18_v4l2_enc_fops
79 },
80 { /* CX18_ENC_STREAM_TYPE_VBI */
81 "encoder VBI",
82 VFL_TYPE_VBI, 0,
83 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
84 &cx18_v4l2_enc_fops
85 },
86 { /* CX18_ENC_STREAM_TYPE_PCM */
87 "encoder PCM audio",
88 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
89 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
90 &cx18_v4l2_enc_fops
91 },
92 { /* CX18_ENC_STREAM_TYPE_IDX */
93 "encoder IDX",
94 VFL_TYPE_GRABBER, -1,
95 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
96 &cx18_v4l2_enc_fops
97 },
98 { /* CX18_ENC_STREAM_TYPE_RAD */
99 "encoder radio",
100 VFL_TYPE_RADIO, 0,
101 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
102 &cx18_v4l2_enc_fops
103 },
104};
105
106static void cx18_stream_init(struct cx18 *cx, int type)
107{
108 struct cx18_stream *s = &cx->streams[type];
109 struct video_device *dev = s->v4l2dev;
110 u32 max_size = cx->options.megabytes[type] * 1024 * 1024;
111
112 /* we need to keep v4l2dev, so restore it afterwards */
113 memset(s, 0, sizeof(*s));
114 s->v4l2dev = dev;
115
116 /* initialize cx18_stream fields */
117 s->cx = cx;
118 s->type = type;
119 s->name = cx18_stream_info[type].name;
120 s->handle = 0xffffffff;
121
122 s->dma = cx18_stream_info[type].dma;
123 s->buf_size = cx->stream_buf_size[type];
124 if (s->buf_size)
125 s->buffers = max_size / s->buf_size;
126 if (s->buffers > 63) {
127 /* Each stream has a maximum of 63 buffers,
128 ensure we do not exceed that. */
129 s->buffers = 63;
130 s->buf_size = (max_size / s->buffers) & ~0xfff;
131 }
132 spin_lock_init(&s->qlock);
133 init_waitqueue_head(&s->waitq);
134 s->id = -1;
135 cx18_queue_init(&s->q_free);
136 cx18_queue_init(&s->q_full);
137 cx18_queue_init(&s->q_io);
138}
139
140static int cx18_prep_dev(struct cx18 *cx, int type)
141{
142 struct cx18_stream *s = &cx->streams[type];
143 u32 cap = cx->v4l2_cap;
144 int minor_offset = cx18_stream_info[type].minor_offset;
145 int minor;
146
147 /* These four fields are always initialized. If v4l2dev == NULL, then
148 this stream is not in use. In that case no other fields but these
149 four can be used. */
150 s->v4l2dev = NULL;
151 s->cx = cx;
152 s->type = type;
153 s->name = cx18_stream_info[type].name;
154
155 /* Check whether the radio is supported */
156 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
157 return 0;
158
159 /* Check whether VBI is supported */
160 if (type == CX18_ENC_STREAM_TYPE_VBI &&
161 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
162 return 0;
163
164 /* card number + user defined offset + device offset */
165 minor = cx->num + cx18_first_minor + minor_offset;
166
167 /* User explicitly selected 0 buffers for these streams, so don't
168 create them. */
169 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
170 cx->options.megabytes[type] == 0) {
171 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
172 return 0;
173 }
174
175 cx18_stream_init(cx, type);
176
177 if (minor_offset == -1)
178 return 0;
179
180 /* allocate and initialize the v4l2 video device structure */
181 s->v4l2dev = video_device_alloc();
182 if (s->v4l2dev == NULL) {
183 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
184 s->name);
185 return -ENOMEM;
186 }
187
188 s->v4l2dev->type =
189 VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
190 VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
191 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18%d %s",
192 cx->num, s->name);
193
194 s->v4l2dev->minor = minor;
195 s->v4l2dev->dev = &cx->dev->dev;
196 s->v4l2dev->fops = cx18_stream_info[type].fops;
197 s->v4l2dev->release = video_device_release;
198
199 return 0;
200}
201
202/* Initialize v4l2 variables and register v4l2 devices */
203int cx18_streams_setup(struct cx18 *cx)
204{
205 int type;
206
207 /* Setup V4L2 Devices */
208 for (type = 0; type < CX18_MAX_STREAMS; type++) {
209 /* Prepare device */
210 if (cx18_prep_dev(cx, type))
211 break;
212
213 /* Allocate Stream */
214 if (cx18_stream_alloc(&cx->streams[type]))
215 break;
216 }
217 if (type == CX18_MAX_STREAMS)
218 return 0;
219
220 /* One or more streams could not be initialized. Clean 'em all up. */
221 cx18_streams_cleanup(cx);
222 return -ENOMEM;
223}
224
225static int cx18_reg_dev(struct cx18 *cx, int type)
226{
227 struct cx18_stream *s = &cx->streams[type];
228 int vfl_type = cx18_stream_info[type].vfl_type;
229 int minor;
230
231 /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
232 * We need a VFL_TYPE_TS defined.
233 */
234 if (strcmp("TS", s->name) == 0) {
235 /* just return if no DVB is supported */
236 if ((cx->card->hw_all & CX18_HW_DVB) == 0)
237 return 0;
238 if (cx18_dvb_register(s) < 0) {
239 CX18_ERR("DVB failed to register\n");
240 return -EINVAL;
241 }
242 }
243
244 if (s->v4l2dev == NULL)
245 return 0;
246
247 minor = s->v4l2dev->minor;
248
249 /* Register device. First try the desired minor, then any free one. */
250 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
251 video_register_device(s->v4l2dev, vfl_type, -1)) {
252 CX18_ERR("Couldn't register v4l2 device for %s minor %d\n",
253 s->name, minor);
254 video_device_release(s->v4l2dev);
255 s->v4l2dev = NULL;
256 return -ENOMEM;
257 }
258 minor = s->v4l2dev->minor;
259
260 switch (vfl_type) {
261 case VFL_TYPE_GRABBER:
262 CX18_INFO("Registered device video%d for %s (%d MB)\n",
263 minor, s->name, cx->options.megabytes[type]);
264 break;
265
266 case VFL_TYPE_RADIO:
267 CX18_INFO("Registered device radio%d for %s\n",
268 minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
269 break;
270
271 case VFL_TYPE_VBI:
272 if (cx->options.megabytes[type])
273 CX18_INFO("Registered device vbi%d for %s (%d MB)\n",
274 minor - MINOR_VFL_TYPE_VBI_MIN,
275 s->name, cx->options.megabytes[type]);
276 else
277 CX18_INFO("Registered device vbi%d for %s\n",
278 minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
279 break;
280 }
281
282 return 0;
283}
284
285/* Register v4l2 devices */
286int cx18_streams_register(struct cx18 *cx)
287{
288 int type;
289 int err = 0;
290
291 /* Register V4L2 devices */
292 for (type = 0; type < CX18_MAX_STREAMS; type++)
293 err |= cx18_reg_dev(cx, type);
294
295 if (err == 0)
296 return 0;
297
298 /* One or more streams could not be initialized. Clean 'em all up. */
299 cx18_streams_cleanup(cx);
300 return -ENOMEM;
301}
302
303/* Unregister v4l2 devices */
304void cx18_streams_cleanup(struct cx18 *cx)
305{
306 struct video_device *vdev;
307 int type;
308
309 /* Teardown all streams */
310 for (type = 0; type < CX18_MAX_STREAMS; type++) {
311 if (cx->streams[type].dvb.enabled)
312 cx18_dvb_unregister(&cx->streams[type]);
313
314 vdev = cx->streams[type].v4l2dev;
315
316 cx->streams[type].v4l2dev = NULL;
317 if (vdev == NULL)
318 continue;
319
320 cx18_stream_free(&cx->streams[type]);
321
322 /* Unregister device */
323 video_unregister_device(vdev);
324 }
325}
326
327static void cx18_vbi_setup(struct cx18_stream *s)
328{
329 struct cx18 *cx = s->cx;
330 int raw = cx->vbi.sliced_in->service_set == 0;
331 u32 data[CX2341X_MBOX_MAX_DATA];
332 int lines;
333
334 if (cx->is_60hz) {
335 cx->vbi.count = 12;
336 cx->vbi.start[0] = 10;
337 cx->vbi.start[1] = 273;
338 } else { /* PAL/SECAM */
339 cx->vbi.count = 18;
340 cx->vbi.start[0] = 6;
341 cx->vbi.start[1] = 318;
342 }
343
344 /* setup VBI registers */
345 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
346
347 /* determine number of lines and total number of VBI bytes.
348 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
349 The '- 1' byte is probably an unused U or V byte. Or something...
350 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
351 header, 42 data bytes + checksum (to be confirmed) */
352 if (raw) {
353 lines = cx->vbi.count * 2;
354 } else {
355 lines = cx->is_60hz ? 24 : 38;
356 if (cx->is_60hz)
357 lines += 2;
358 }
359
360 cx->vbi.enc_size = lines *
361 (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
362
363 data[0] = s->handle;
364 /* Lines per field */
365 data[1] = (lines / 2) | ((lines / 2) << 16);
366 /* bytes per line */
367 data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
368 /* Every X number of frames a VBI interrupt arrives
369 (frames as in 25 or 30 fps) */
370 data[3] = 1;
371 /* Setup VBI for the cx25840 digitizer */
372 if (raw) {
373 data[4] = 0x20602060;
374 data[5] = 0x30703070;
375 } else {
376 data[4] = 0xB0F0B0F0;
377 data[5] = 0xA0E0A0E0;
378 }
379
380 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
381 data[0], data[1], data[2], data[3], data[4], data[5]);
382
383 if (s->type == CX18_ENC_STREAM_TYPE_VBI)
384 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
385}
386
387int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
388{
389 u32 data[MAX_MB_ARGUMENTS];
390 struct cx18 *cx = s->cx;
391 struct list_head *p;
392 int ts = 0;
393 int captype = 0;
394
395 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
396 return -EINVAL;
397
398 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
399
400 switch (s->type) {
401 case CX18_ENC_STREAM_TYPE_MPG:
402 captype = CAPTURE_CHANNEL_TYPE_MPEG;
403 cx->mpg_data_received = cx->vbi_data_inserted = 0;
404 cx->dualwatch_jiffies = jiffies;
405 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300;
406 cx->search_pack_header = 0;
407 break;
408
409 case CX18_ENC_STREAM_TYPE_TS:
410 captype = CAPTURE_CHANNEL_TYPE_TS;
411 ts = 1;
412 break;
413 case CX18_ENC_STREAM_TYPE_YUV:
414 captype = CAPTURE_CHANNEL_TYPE_YUV;
415 break;
416 case CX18_ENC_STREAM_TYPE_PCM:
417 captype = CAPTURE_CHANNEL_TYPE_PCM;
418 break;
419 case CX18_ENC_STREAM_TYPE_VBI:
420 captype = cx->vbi.sliced_in->service_set ?
421 CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI;
422 cx->vbi.frame = 0;
423 cx->vbi.inserted_frame = 0;
424 memset(cx->vbi.sliced_mpeg_size,
425 0, sizeof(cx->vbi.sliced_mpeg_size));
426 break;
427 default:
428 return -EINVAL;
429 }
430 s->buffers_stolen = 0;
431
432 /* mute/unmute video */
433 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
434 s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
435
436 /* Clear Streamoff flags in case left from last capture */
437 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
438
439 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
440 s->handle = data[0];
441 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
442
443 if (atomic_read(&cx->capturing) == 0 && !ts) {
444 /* Stuff from Windows, we don't know what it is */
445 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
446 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
447 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
448 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
449 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
450
451 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
452 s->handle, cx->digitizer, cx->digitizer);
453
454 /* Setup VBI */
455 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
456 cx18_vbi_setup(s);
457
458 /* assign program index info.
459 Mask 7: select I/P/B, Num_req: 400 max */
460 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
461
462 /* Setup API for Stream */
463 cx2341x_update(cx, cx18_api_func, NULL, &cx->params);
464 }
465
466 if (atomic_read(&cx->capturing) == 0) {
467 clear_bit(CX18_F_I_EOS, &cx->i_flags);
468 write_reg(7, CX18_DSP0_INTERRUPT_MASK);
469 }
470
471 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
472 (void *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
473 (void *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
474
475 list_for_each(p, &s->q_free.list) {
476 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
477
478 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr);
479 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
480 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
481 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1,
482 buf->id, s->buf_size);
483 }
484 /* begin_capture */
485 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
486 CX18_DEBUG_WARN("Error starting capture!\n");
487 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
488 return -EINVAL;
489 }
490
491 /* you're live! sit back and await interrupts :) */
492 atomic_inc(&cx->capturing);
493 return 0;
494}
495
496void cx18_stop_all_captures(struct cx18 *cx)
497{
498 int i;
499
500 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
501 struct cx18_stream *s = &cx->streams[i];
502
503 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
504 continue;
505 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
506 cx18_stop_v4l2_encode_stream(s, 0);
507 }
508}
509
510int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
511{
512 struct cx18 *cx = s->cx;
513 unsigned long then;
514
515 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
516 return -EINVAL;
517
518 /* This function assumes that you are allowed to stop the capture
519 and that we are actually capturing */
520
521 CX18_DEBUG_INFO("Stop Capture\n");
522
523 if (atomic_read(&cx->capturing) == 0)
524 return 0;
525
526 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
527 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
528 else
529 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
530
531 then = jiffies;
532
533 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
534 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
535 }
536
537 atomic_dec(&cx->capturing);
538
539 /* Clear capture and no-read bits */
540 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
541
542 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
543 s->handle = 0xffffffff;
544
545 if (atomic_read(&cx->capturing) > 0)
546 return 0;
547
548 write_reg(5, CX18_DSP0_INTERRUPT_MASK);
549 wake_up(&s->waitq);
550
551 return 0;
552}
553
554u32 cx18_find_handle(struct cx18 *cx)
555{
556 int i;
557
558 /* find first available handle to be used for global settings */
559 for (i = 0; i < CX18_MAX_STREAMS; i++) {
560 struct cx18_stream *s = &cx->streams[i];
561
562 if (s->v4l2dev && s->handle)
563 return s->handle;
564 }
565 return 0;
566}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
new file mode 100644
index 000000000000..8c7ba7d2fa79
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -0,0 +1,33 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24u32 cx18_find_handle(struct cx18 *cx);
25int cx18_streams_setup(struct cx18 *cx);
26int cx18_streams_register(struct cx18 *cx);
27void cx18_streams_cleanup(struct cx18 *cx);
28
29/* Capture related */
30int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
31int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
32
33void cx18_stop_all_captures(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
new file mode 100644
index 000000000000..22e76ee3f447
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -0,0 +1,208 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-vbi.h"
26#include "cx18-ioctl.h"
27#include "cx18-queue.h"
28#include "cx18-av-core.h"
29
30static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
31{
32 int line = 0;
33 int i;
34 u32 linemask[2] = { 0, 0 };
35 unsigned short size;
36 static const u8 mpeg_hdr_data[] = {
37 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
38 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
39 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
40 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
41 };
42 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
43 int idx = cx->vbi.frame % CX18_VBI_FRAMES;
44 u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0];
45
46 for (i = 0; i < lines; i++) {
47 struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i;
48 int f, l;
49
50 if (sdata->id == 0)
51 continue;
52
53 l = sdata->line - 6;
54 f = sdata->field;
55 if (f)
56 l += 18;
57 if (l < 32)
58 linemask[0] |= (1 << l);
59 else
60 linemask[1] |= (1 << (l - 32));
61 dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id);
62 memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42);
63 line++;
64 }
65 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
66 if (line == 36) {
67 /* All lines are used, so there is no space for the linemask
68 (the max size of the VBI data is 36 * 43 + 4 bytes).
69 So in this case we use the magic number 'ITV0'. */
70 memcpy(dst + sd, "ITV0", 4);
71 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
72 size = 4 + ((43 * line + 3) & ~3);
73 } else {
74 memcpy(dst + sd, "cx0", 4);
75 memcpy(dst + sd + 4, &linemask[0], 8);
76 size = 12 + ((43 * line + 3) & ~3);
77 }
78 dst[4+16] = (size + 10) >> 8;
79 dst[5+16] = (size + 10) & 0xff;
80 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
81 dst[10+16] = (pts_stamp >> 22) & 0xff;
82 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
83 dst[12+16] = (pts_stamp >> 7) & 0xff;
84 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
85 cx->vbi.sliced_mpeg_size[idx] = sd + size;
86}
87
88/* Compress raw VBI format, removes leading SAV codes and surplus space
89 after the field.
90 Returns new compressed size. */
91static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
92{
93 u32 line_size = cx->vbi.raw_decoder_line_size;
94 u32 lines = cx->vbi.count;
95 u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
96 u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
97 u8 *q = buf;
98 u8 *p;
99 int i;
100
101 for (i = 0; i < lines; i++) {
102 p = buf + i * line_size;
103
104 /* Look for SAV code */
105 if (p[0] != 0xff || p[1] || p[2] ||
106 (p[3] != sav1 && p[3] != sav2))
107 break;
108 memcpy(q, p + 4, line_size - 4);
109 q += line_size - 4;
110 }
111 return lines * (line_size - 4);
112}
113
114
115/* Compressed VBI format, all found sliced blocks put next to one another
116 Returns new compressed size */
117static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
118 u32 size, u8 sav)
119{
120 u32 line_size = cx->vbi.sliced_decoder_line_size;
121 struct v4l2_decode_vbi_line vbi;
122 int i;
123
124 /* find the first valid line */
125 for (i = 0; i < size; i++, buf++) {
126 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
127 break;
128 }
129
130 size -= i;
131 if (size < line_size)
132 return line;
133 for (i = 0; i < size / line_size; i++) {
134 u8 *p = buf + i * line_size;
135
136 /* Look for SAV code */
137 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
138 continue;
139 vbi.p = p + 4;
140 cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
141 if (vbi.type) {
142 cx->vbi.sliced_data[line].id = vbi.type;
143 cx->vbi.sliced_data[line].field = vbi.is_second_field;
144 cx->vbi.sliced_data[line].line = vbi.line;
145 memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42);
146 line++;
147 }
148 }
149 return line;
150}
151
152void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
153 u64 pts_stamp, int streamtype)
154{
155 u8 *p = (u8 *) buf->buf;
156 u32 size = buf->bytesused;
157 int lines;
158
159 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
160 return;
161
162 /* Raw VBI data */
163 if (cx->vbi.sliced_in->service_set == 0) {
164 u8 type;
165
166 cx18_buf_swap(buf);
167
168 type = p[3];
169
170 size = buf->bytesused = compress_raw_buf(cx, p, size);
171
172 /* second field of the frame? */
173 if (type == cx->vbi.raw_decoder_sav_even_field) {
174 /* Dirty hack needed for backwards
175 compatibility of old VBI software. */
176 p += size - 4;
177 memcpy(p, &cx->vbi.frame, 4);
178 cx->vbi.frame++;
179 }
180 return;
181 }
182
183 /* Sliced VBI data with data insertion */
184 cx18_buf_swap(buf);
185
186 /* first field */
187 lines = compress_sliced_buf(cx, 0, p, size / 2,
188 cx->vbi.sliced_decoder_sav_odd_field);
189 /* second field */
190 /* experimentation shows that the second half does not always
191 begin at the exact address. So start a bit earlier
192 (hence 32). */
193 lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
194 size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
195 /* always return at least one empty line */
196 if (lines == 0) {
197 cx->vbi.sliced_data[0].id = 0;
198 cx->vbi.sliced_data[0].line = 0;
199 cx->vbi.sliced_data[0].field = 0;
200 lines = 1;
201 }
202 buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]);
203 memcpy(p, &cx->vbi.sliced_data[0], size);
204
205 if (cx->vbi.insert_mpeg)
206 copy_vbi_data(cx, lines, pts_stamp);
207 cx->vbi.frame++;
208}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
new file mode 100644
index 000000000000..c56ff7d28f20
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -0,0 +1,26 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
25 u64 pts_stamp, int streamtype);
26int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
new file mode 100644
index 000000000000..d5c7a6f968dd
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -0,0 +1,34 @@
1/*
2 * cx18 driver version information
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX18_VERSION_H
23#define CX18_VERSION_H
24
25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 0
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
31#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
32 CX18_DRIVER_VERSION_MINOR, CX18_DRIVER_VERSION_PATCHLEVEL)
33
34#endif
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
new file mode 100644
index 000000000000..2e5c41939330
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -0,0 +1,45 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-video.h"
24#include "cx18-av-core.h"
25#include "cx18-cards.h"
26
27void cx18_video_set_io(struct cx18 *cx)
28{
29 struct v4l2_routing route;
30 int inp = cx->active_input;
31 u32 type;
32
33 route.input = cx->card->video_inputs[inp].video_input;
34 route.output = 0;
35 cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
36
37 type = cx->card->video_inputs[inp].video_type;
38
39 if (type == CX18_CARD_INPUT_VID_TUNER)
40 route.input = 0; /* Tuner */
41 else if (type < CX18_CARD_INPUT_COMPOSITE1)
42 route.input = 2; /* S-Video */
43 else
44 route.input = 1; /* Composite */
45}
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h
new file mode 100644
index 000000000000..529006a06e5c
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.h
@@ -0,0 +1,22 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
new file mode 100644
index 000000000000..33f78da9dba8
--- /dev/null
+++ b/drivers/media/video/cx18/cx23418.h
@@ -0,0 +1,458 @@
1/*
2 * cx18 header containing common defines.
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX23418_H
23#define CX23418_H
24
25#include <media/cx2341x.h>
26
27#define MGR_CMD_MASK 0x40000000
28/* The MSB of the command code indicates that this is the completion of a
29 command */
30#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
31
32/* Description: This command creates a new instance of a certain task
33 IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
34 the processor on which the task YYY will be created
35 OUT[0] - Task handle. This handle is passed along with commands to
36 dispatch to the right instance of the task
37 ReturnCode - One of the ERR_SYS_... */
38#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
39
40/* Description: This command destroys an instance of a task
41 IN[0] - Task handle. Hanlde of the task to destroy
42 ReturnCode - One of the ERR_SYS_... */
43#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
44
45/* All commands for CPU have the following mask set */
46#define CPU_CMD_MASK 0x20000000
47#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
48#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
49#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
50
51#define EPU_CMD_MASK 0x02000000
52#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
53#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
54
55/* Description: This command indicates that a Memory Descriptor List has been
56 filled with the requested channel type
57 IN[0] - Task handle. Handle of the task
58 IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
59 IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
60 ReturnCode - One of the ERR_DE_... */
61#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
62
63/* Something interesting happened
64 IN[0] - A value to log
65 IN[1] - An offset of a string in the MiniMe memory;
66 0/zero/NULL means "I have nothing to say" */
67#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
68
69/* Description: This command starts streaming with the set channel type
70 IN[0] - Task handle. Handle of the task to start
71 ReturnCode - One of the ERR_CAPTURE_... */
72#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
73
74/* Description: This command stops streaming with the set channel type
75 IN[0] - Task handle. Handle of the task to stop
76 IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
77 ReturnCode - One of the ERR_CAPTURE_... */
78#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
79
80/* Description: This command pauses streaming with the set channel type
81 IN[0] - Task handle. Handle of the task to pause
82 ReturnCode - One of the ERR_CAPTURE_... */
83#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
84
85/* Description: This command resumes streaming with the set channel type
86 IN[0] - Task handle. Handle of the task to resume
87 ReturnCode - One of the ERR_CAPTURE_... */
88#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
89
90#define CAPTURE_CHANNEL_TYPE_NONE 0
91#define CAPTURE_CHANNEL_TYPE_MPEG 1
92#define CAPTURE_CHANNEL_TYPE_INDEX 2
93#define CAPTURE_CHANNEL_TYPE_YUV 3
94#define CAPTURE_CHANNEL_TYPE_PCM 4
95#define CAPTURE_CHANNEL_TYPE_VBI 5
96#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
97#define CAPTURE_CHANNEL_TYPE_TS 7
98#define CAPTURE_CHANNEL_TYPE_MAX 15
99
100/* Description: This command sets the channel type. This can only be done
101 when stopped.
102 IN[0] - Task handle. Handle of the task to start
103 IN[1] - Channel Type. See Below.
104 ReturnCode - One of the ERR_CAPTURE_... */
105#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
106
107/* Description: Set stream output type
108 IN[0] - task handle. Handle of the task to start
109 IN[1] - type
110 ReturnCode - One of the ERR_CAPTURE_... */
111#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012)
112
113/* Description: Set video input resolution and frame rate
114 IN[0] - task handle
115 IN[1] - reserved
116 IN[2] - reserved
117 IN[3] - reserved
118 IN[4] - reserved
119 IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
120 ReturnCode - One of the ERR_CAPTURE_... */
121#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
122
123/* Description: Set video frame rate
124 IN[0] - task handle. Handle of the task to start
125 IN[1] - video bit rate mode
126 IN[2] - video average rate
127 IN[3] - video peak rate
128 IN[4] - system mux rate
129 ReturnCode - One of the ERR_CAPTURE_... */
130#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
131
132/* Description: Set video output resolution
133 IN[0] - task handle
134 IN[1] - horizontal size
135 IN[2] - vertical size
136 ReturnCode - One of the ERR_CAPTURE_... */
137#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006)
138
139/* Description: This command set filter parameters
140 IN[0] - Task handle. Handle of the task
141 IN[1] - type, 0 - temporal, 1 - spatial, 2 - median
142 IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic
143 median: 0 = disable, 1 = horizontal, 2 = vertical,
144 3 = horizontal/vertical, 4 = diagonal
145 IN[3] - strength, temporal 0 - 31, spatial 0 - 15
146 ReturnCode - One of the ERR_CAPTURE_... */
147#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
148
149/* Description: This command set spatial filter type
150 IN[0] - Task handle.
151 IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only,
152 3 = 2D H/V separable, 4 = 2D symmetric non-separable
153 IN[2] - chroma type: 0 - diable, 1 = 1D horizontal
154 ReturnCode - One of the ERR_CAPTURE_... */
155#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
156
157/* Description: This command set coring levels for median filter
158 IN[0] - Task handle.
159 IN[1] - luma_high
160 IN[2] - luma_low
161 IN[3] - chroma_high
162 IN[4] - chroma_low
163 ReturnCode - One of the ERR_CAPTURE_... */
164#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
165
166/* Description: This command set the picture type mask for index file
167 IN[0] - 0 = disable index file output
168 1 = output I picture
169 2 = P picture
170 4 = B picture
171 other = illegal */
172#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
173
174/* Description: Set audio parameters
175 IN[0] - task handle. Handle of the task to start
176 IN[1] - audio parameter
177 ReturnCode - One of the ERR_CAPTURE_... */
178#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011)
179
180/* Description: Set video mute
181 IN[0] - task handle. Handle of the task to start
182 IN[1] - bit31-24: muteYvalue
183 bit23-16: muteUvalue
184 bit15-8: muteVvalue
185 bit0: 1:mute, 0: unmute
186 ReturnCode - One of the ERR_CAPTURE_... */
187#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013)
188
189/* Description: Set audio mute
190 IN[0] - task handle. Handle of the task to start
191 IN[1] - mute/unmute
192 ReturnCode - One of the ERR_CAPTURE_... */
193#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014)
194
195/* Description: Set stream output type
196 IN[0] - task handle. Handle of the task to start
197 IN[1] - subType
198 SET_INITIAL_SCR 1
199 SET_QUALITY_MODE 2
200 SET_VIM_PROTECT_MODE 3
201 SET_PTS_CORRECTION 4
202 SET_USB_FLUSH_MODE 5
203 SET_MERAQPAR_ENABLE 6
204 SET_NAV_PACK_INSERTION 7
205 SET_SCENE_CHANGE_ENABLE 8
206 IN[2] - parameter 1
207 IN[3] - parameter 2
208 ReturnCode - One of the ERR_CAPTURE_... */
209#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015)
210
211/* Description: Set raw VBI parameters
212 IN[0] - Task handle
213 IN[1] - No. of input lines per field:
214 bit[15:0]: field 1,
215 bit[31:16]: field 2
216 IN[2] - No. of input bytes per line
217 IN[3] - No. of output frames per transfer
218 IN[4] - start code
219 IN[5] - stop code
220 ReturnCode */
221#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016)
222
223/* Description: Set capture line No.
224 IN[0] - task handle. Handle of the task to start
225 IN[1] - height1
226 IN[2] - height2
227 ReturnCode - One of the ERR_CAPTURE_... */
228#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017)
229
230/* Description: Set copyright
231 IN[0] - task handle. Handle of the task to start
232 IN[1] - copyright
233 ReturnCode - One of the ERR_CAPTURE_... */
234#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018)
235
236/* Description: Set audio PID
237 IN[0] - task handle. Handle of the task to start
238 IN[1] - PID
239 ReturnCode - One of the ERR_CAPTURE_... */
240#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019)
241
242/* Description: Set video PID
243 IN[0] - task handle. Handle of the task to start
244 IN[1] - PID
245 ReturnCode - One of the ERR_CAPTURE_... */
246#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A)
247
248/* Description: Set Vertical Crop Line
249 IN[0] - task handle. Handle of the task to start
250 IN[1] - Line
251 ReturnCode - One of the ERR_CAPTURE_... */
252#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B)
253
254/* Description: Set COP structure
255 IN[0] - task handle. Handle of the task to start
256 IN[1] - M
257 IN[2] - N
258 ReturnCode - One of the ERR_CAPTURE_... */
259#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C)
260
261/* Description: Set Scene Change Detection
262 IN[0] - task handle. Handle of the task to start
263 IN[1] - scene change
264 ReturnCode - One of the ERR_CAPTURE_... */
265#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D)
266
267/* Description: Set Aspect Ratio
268 IN[0] - task handle. Handle of the task to start
269 IN[1] - AspectRatio
270 ReturnCode - One of the ERR_CAPTURE_... */
271#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E)
272
273/* Description: Set Skip Input Frame
274 IN[0] - task handle. Handle of the task to start
275 IN[1] - skip input frames
276 ReturnCode - One of the ERR_CAPTURE_... */
277#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F)
278
279/* Description: Set sliced VBI parameters -
280 Note This API will only apply to MPEG and Sliced VBI Channels
281 IN[0] - Task handle
282 IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext
283 IN[2] - start / stop line
284 bit[15:0] start line number
285 bit[31:16] stop line number
286 IN[3] - number of output frames per interrupt
287 IN[4] - VBI insertion mode
288 bit 0: output user data, 1 - enable
289 bit 1: output private stream, 1 - enable
290 bit 2: mux option, 0 - in GOP, 1 - in picture
291 bit[7:0] private stream ID
292 IN[5] - insertion period while mux option is in picture
293 ReturnCode - VBI data offset */
294#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
295
296/* Description: Set the user data place holder
297 IN[0] - type of data (0 for user)
298 IN[1] - Stuffing period
299 IN[2] - ID data size in word (less than 10)
300 IN[3] - Pointer to ID buffer */
301#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021)
302
303
304/* Description:
305 In[0] Task Handle
306 return parameter:
307 Out[0] Reserved
308 Out[1] Video PTS bit[32:2] of last output video frame.
309 Out[2] Video PTS bit[ 1:0] of last output video frame.
310 Out[3] Hardware Video PTS counter bit[31:0],
311 these bits get incremented on every 90kHz clock tick.
312 Out[4] Hardware Video PTS counter bit32,
313 these bits get incremented on every 90kHz clock tick.
314 ReturnCode */
315#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
316
317/* Below is the list of commands related to the data exchange */
318#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
319
320/* Description: This command provides the physical base address of the local
321 DDR as viewed by EPU
322 IN[0] - Physical offset where EPU has the local DDR mapped
323 ReturnCode - One of the ERR_DE_... */
324#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
325
326/* Description: This command provides the offsets in the device memory where
327 the 2 cx18_mdl_ack blocks reside
328 IN[0] - Task handle. Handle of the task to start
329 IN[1] - Offset of the first cx18_mdl_ack from the beginning of the
330 local DDR.
331 IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
332 local DDR.
333 ReturnCode - One of the ERR_DE_... */
334#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
335
336/* Description: This command provides the offset to a Memory Descriptor List
337 IN[0] - Task handle. Handle of the task to start
338 IN[1] - Offset of the MDL from the beginning of the local DDR.
339 IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1]
340 IN[3] - Buffer ID
341 IN[4] - Total buffer length
342 ReturnCode - One of the ERR_DE_... */
343#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
344
345/* Description: This command requests return of all current Memory
346 Descriptor Lists to the driver
347 IN[0] - Task handle. Handle of the task to start
348 ReturnCode - One of the ERR_DE_... */
349/* #define CX18_CPU_DE_ReleaseMDL (CPU_CMD_MASK_DE | 0x0006) */
350
351/* Description: This command signals the cpu that the dat buffer has been
352 consumed and ready for re-use.
353 IN[0] - Task handle. Handle of the task
354 IN[1] - Offset of the data block from the beginning of the local DDR.
355 IN[2] - Number of bytes in the data block
356 ReturnCode - One of the ERR_DE_... */
357/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */
358
359/* No Error / Success */
360#define CNXT_OK 0x000000
361
362/* Received unknown command */
363#define CXERR_UNK_CMD 0x000001
364
365/* First parameter in the command is invalid */
366#define CXERR_INVALID_PARAM1 0x000002
367
368/* Second parameter in the command is invalid */
369#define CXERR_INVALID_PARAM2 0x000003
370
371/* Device interface is not open/found */
372#define CXERR_DEV_NOT_FOUND 0x000004
373
374/* Requested function is not implemented/available */
375#define CXERR_NOTSUPPORTED 0x000005
376
377/* Invalid pointer is provided */
378#define CXERR_BADPTR 0x000006
379
380/* Unable to allocate memory */
381#define CXERR_NOMEM 0x000007
382
383/* Object/Link not found */
384#define CXERR_LINK 0x000008
385
386/* Device busy, command cannot be executed */
387#define CXERR_BUSY 0x000009
388
389/* File/device/handle is not open. */
390#define CXERR_NOT_OPEN 0x00000A
391
392/* Value is out of range */
393#define CXERR_OUTOFRANGE 0x00000B
394
395/* Buffer overflow */
396#define CXERR_OVERFLOW 0x00000C
397
398/* Version mismatch */
399#define CXERR_BADVER 0x00000D
400
401/* Operation timed out */
402#define CXERR_TIMEOUT 0x00000E
403
404/* Operation aborted */
405#define CXERR_ABORT 0x00000F
406
407/* Specified I2C device not found for read/write */
408#define CXERR_I2CDEV_NOTFOUND 0x000010
409
410/* Error in I2C data xfer (but I2C device is present) */
411#define CXERR_I2CDEV_XFERERR 0x000011
412
413/* Chanel changing component not ready */
414#define CXERR_CHANNELNOTREADY 0x000012
415
416/* PPU (Presensation/Decoder) mail box is corrupted */
417#define CXERR_PPU_MB_CORRUPT 0x000013
418
419/* CPU (Capture/Encoder) mail box is corrupted */
420#define CXERR_CPU_MB_CORRUPT 0x000014
421
422/* APU (Audio) mail box is corrupted */
423#define CXERR_APU_MB_CORRUPT 0x000015
424
425/* Unable to open file for reading */
426#define CXERR_FILE_OPEN_READ 0x000016
427
428/* Unable to open file for writing */
429#define CXERR_FILE_OPEN_WRITE 0x000017
430
431/* Unable to find the I2C section specified */
432#define CXERR_I2C_BADSECTION 0x000018
433
434/* Error in I2C data xfer (but I2C device is present) */
435#define CXERR_I2CDEV_DATALOW 0x000019
436
437/* Error in I2C data xfer (but I2C device is present) */
438#define CXERR_I2CDEV_CLOCKLOW 0x00001A
439
440/* No Interrupt received from HW (for I2C access) */
441#define CXERR_NO_HW_I2C_INTR 0x00001B
442
443/* RPU is not ready to accept commands! */
444#define CXERR_RPU_NOT_READY 0x00001C
445
446/* RPU is not ready to accept commands! */
447#define CXERR_RPU_NO_ACK 0x00001D
448
449/* The are no buffers ready. Try again soon! */
450#define CXERR_NODATA_AGAIN 0x00001E
451
452/* The stream is stopping. Function not alllowed now! */
453#define CXERR_STOPPING_STATUS 0x00001F
454
455/* Trying to access hardware when the power is turned OFF */
456#define CXERR_DEVPOWER_OFF 0x000020
457
458#endif /* CX23418_H */
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index ca5fbce3a909..cadf936c3673 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -4,19 +4,19 @@ config VIDEO_CX23885
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEO_TUNER 7 select MEDIA_TUNER
8 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
9 select VIDEO_IR 9 select VIDEO_IR
10 select VIDEOBUF_DVB 10 select VIDEOBUF_DVB
11 select VIDEO_CX25840 11 select VIDEO_CX25840
12 select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE 12 select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
13 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 13 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
14 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 14 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
15 select DVB_PLL if !DVB_FE_CUSTOMISE 15 select DVB_PLL if !DVB_FE_CUSTOMISE
16 select TUNER_XC2028 if !DVB_FE_CUSTOMIZE 16 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
17 select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE 17 select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
18 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE 18 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
19 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 19 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
20 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 20 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
21 ---help--- 21 ---help---
22 This is a video4linux driver for Conexant 23885 based 22 This is a video4linux driver for Conexant 23885 based
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index d7b0721af062..29c23b44c13c 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -3,6 +3,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx2
3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 7EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 8EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
8 9
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 7fde678b2c4a..88823810497c 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1209,7 +1209,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
1209 1209
1210/* ----------------------------------------------------------------------- */ 1210/* ----------------------------------------------------------------------- */
1211 1211
1212static int cx25840_probe(struct i2c_client *client) 1212static int cx25840_probe(struct i2c_client *client,
1213 const struct i2c_device_id *did)
1213{ 1214{
1214 struct cx25840_state *state; 1215 struct cx25840_state *state;
1215 u32 id; 1216 u32 id;
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 27635cdcbaf2..b0d7d6a7a4cc 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_CX88
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEOBUF_DMA_SG 7 select VIDEOBUF_DMA_SG
8 select VIDEO_TUNER 8 select MEDIA_TUNER
9 select VIDEO_TVEEPROM 9 select VIDEO_TVEEPROM
10 select VIDEO_IR 10 select VIDEO_IR
11 select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO 11 select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
@@ -57,7 +57,7 @@ config VIDEO_CX88_DVB
57 select DVB_NXT200X if !DVB_FE_CUSTOMISE 57 select DVB_NXT200X if !DVB_FE_CUSTOMISE
58 select DVB_CX24123 if !DVB_FE_CUSTOMISE 58 select DVB_CX24123 if !DVB_FE_CUSTOMISE
59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
60 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 60 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
61 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 61 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
62 ---help--- 62 ---help---
63 This adds support for DVB/ATSC cards based on the 63 This adds support for DVB/ATSC cards based on the
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 532cee35eb3c..6ec30f242578 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
10obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o 10obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
11 11
12EXTRA_CFLAGS += -Idrivers/media/video 12EXTRA_CFLAGS += -Idrivers/media/video
13EXTRA_CFLAGS += -Idrivers/media/common/tuners
13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 14EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
14EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 15EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 2b6b283cda15..aeba26dc0a37 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -57,6 +57,9 @@ MODULE_PARM_DESC(latency,"pci latency timer");
57/* ------------------------------------------------------------------ */ 57/* ------------------------------------------------------------------ */
58/* board config info */ 58/* board config info */
59 59
60/* If radio_type !=UNSET, radio_addr should be specified
61 */
62
60static const struct cx88_board cx88_boards[] = { 63static const struct cx88_board cx88_boards[] = {
61 [CX88_BOARD_UNKNOWN] = { 64 [CX88_BOARD_UNKNOWN] = {
62 .name = "UNKNOWN/GENERIC", 65 .name = "UNKNOWN/GENERIC",
@@ -2446,25 +2449,31 @@ EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
2446static void cx88_card_setup(struct cx88_core *core) 2449static void cx88_card_setup(struct cx88_core *core)
2447{ 2450{
2448 static u8 eeprom[256]; 2451 static u8 eeprom[256];
2452 struct tuner_setup tun_setup;
2453 unsigned int mode_mask = T_RADIO |
2454 T_ANALOG_TV |
2455 T_DIGITAL_TV;
2456
2457 memset(&tun_setup, 0, sizeof(tun_setup));
2449 2458
2450 if (0 == core->i2c_rc) { 2459 if (0 == core->i2c_rc) {
2451 core->i2c_client.addr = 0xa0 >> 1; 2460 core->i2c_client.addr = 0xa0 >> 1;
2452 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom)); 2461 tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
2453 } 2462 }
2454 2463
2455 switch (core->boardnr) { 2464 switch (core->boardnr) {
2456 case CX88_BOARD_HAUPPAUGE: 2465 case CX88_BOARD_HAUPPAUGE:
2457 case CX88_BOARD_HAUPPAUGE_ROSLYN: 2466 case CX88_BOARD_HAUPPAUGE_ROSLYN:
2458 if (0 == core->i2c_rc) 2467 if (0 == core->i2c_rc)
2459 hauppauge_eeprom(core,eeprom+8); 2468 hauppauge_eeprom(core, eeprom+8);
2460 break; 2469 break;
2461 case CX88_BOARD_GDI: 2470 case CX88_BOARD_GDI:
2462 if (0 == core->i2c_rc) 2471 if (0 == core->i2c_rc)
2463 gdi_eeprom(core,eeprom); 2472 gdi_eeprom(core, eeprom);
2464 break; 2473 break;
2465 case CX88_BOARD_WINFAST2000XP_EXPERT: 2474 case CX88_BOARD_WINFAST2000XP_EXPERT:
2466 if (0 == core->i2c_rc) 2475 if (0 == core->i2c_rc)
2467 leadtek_eeprom(core,eeprom); 2476 leadtek_eeprom(core, eeprom);
2468 break; 2477 break;
2469 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 2478 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
2470 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 2479 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
@@ -2474,7 +2483,7 @@ static void cx88_card_setup(struct cx88_core *core)
2474 case CX88_BOARD_HAUPPAUGE_HVR3000: 2483 case CX88_BOARD_HAUPPAUGE_HVR3000:
2475 case CX88_BOARD_HAUPPAUGE_HVR1300: 2484 case CX88_BOARD_HAUPPAUGE_HVR1300:
2476 if (0 == core->i2c_rc) 2485 if (0 == core->i2c_rc)
2477 hauppauge_eeprom(core,eeprom); 2486 hauppauge_eeprom(core, eeprom);
2478 break; 2487 break;
2479 case CX88_BOARD_KWORLD_DVBS_100: 2488 case CX88_BOARD_KWORLD_DVBS_100:
2480 cx_write(MO_GP0_IO, 0x000007f8); 2489 cx_write(MO_GP0_IO, 0x000007f8);
@@ -2555,6 +2564,35 @@ static void cx88_card_setup(struct cx88_core *core)
2555 2564
2556 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); 2565 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
2557 } 2566 }
2567 } /*end switch() */
2568
2569
2570 /* Setup tuners */
2571 if ((core->board.radio_type != UNSET)) {
2572 tun_setup.mode_mask = T_RADIO;
2573 tun_setup.type = core->board.radio_type;
2574 tun_setup.addr = core->board.radio_addr;
2575 tun_setup.tuner_callback = cx88_tuner_callback;
2576 cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2577 mode_mask &= ~T_RADIO;
2578 }
2579
2580 if (core->board.tuner_type != TUNER_ABSENT) {
2581 tun_setup.mode_mask = mode_mask;
2582 tun_setup.type = core->board.tuner_type;
2583 tun_setup.addr = core->board.tuner_addr;
2584 tun_setup.tuner_callback = cx88_tuner_callback;
2585
2586 cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2587 }
2588
2589 if (core->board.tda9887_conf) {
2590 struct v4l2_priv_tun_config tda9887_cfg;
2591
2592 tda9887_cfg.tuner = TUNER_TDA9887;
2593 tda9887_cfg.priv = &core->board.tda9887_conf;
2594
2595 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
2558 } 2596 }
2559 2597
2560 if (core->board.tuner_type == TUNER_XC2028) { 2598 if (core->board.tuner_type == TUNER_XC2028) {
@@ -2572,6 +2610,7 @@ static void cx88_card_setup(struct cx88_core *core)
2572 ctl.fname); 2610 ctl.fname);
2573 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); 2611 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
2574 } 2612 }
2613 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
2575} 2614}
2576 2615
2577/* ------------------------------------------------------------------ */ 2616/* ------------------------------------------------------------------ */
@@ -2710,7 +2749,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2710 if (TUNER_ABSENT != core->board.tuner_type) 2749 if (TUNER_ABSENT != core->board.tuner_type)
2711 request_module("tuner"); 2750 request_module("tuner");
2712 2751
2713 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
2714 cx88_card_setup(core); 2752 cx88_card_setup(core);
2715 cx88_ir_init(core, pci); 2753 cx88_ir_init(core, pci);
2716 2754
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index c6b44732a082..00aa7a3f1105 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -104,37 +104,7 @@ static int attach_inform(struct i2c_client *client)
104 104
105 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 105 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
106 client->driver->driver.name, client->addr, client->name); 106 client->driver->driver.name, client->addr, client->name);
107 if (!client->driver->command)
108 return 0;
109
110 if (core->board.radio_type != UNSET) {
111 if ((core->board.radio_addr==ADDR_UNSET)||(core->board.radio_addr==client->addr)) {
112 tun_setup.mode_mask = T_RADIO;
113 tun_setup.type = core->board.radio_type;
114 tun_setup.addr = core->board.radio_addr;
115 tun_setup.tuner_callback = cx88_tuner_callback;
116 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
117 }
118 }
119 if (core->board.tuner_type != UNSET) {
120 if ((core->board.tuner_addr==ADDR_UNSET)||(core->board.tuner_addr==client->addr)) {
121
122 tun_setup.mode_mask = T_ANALOG_TV;
123 tun_setup.type = core->board.tuner_type;
124 tun_setup.addr = core->board.tuner_addr;
125 tun_setup.tuner_callback = cx88_tuner_callback;
126 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
127 }
128 }
129
130 if (core->board.tda9887_conf) {
131 struct v4l2_priv_tun_config tda9887_cfg;
132 107
133 tda9887_cfg.tuner = TUNER_TDA9887;
134 tda9887_cfg.priv = &core->board.tda9887_conf;
135
136 client->driver->command(client, TUNER_SET_CONFIG, &tda9887_cfg);
137 }
138 return 0; 108 return 0;
139} 109}
140 110
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 9caffed2b6b8..c7c2896bbd8b 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,7 @@
1config VIDEO_EM28XX 1config VIDEO_EM28XX
2 tristate "Empia EM28xx USB video capture support" 2 tristate "Empia EM28xx USB video capture support"
3 depends on VIDEO_DEV && I2C && INPUT 3 depends on VIDEO_DEV && I2C && INPUT
4 select VIDEO_TUNER 4 select MEDIA_TUNER
5 select VIDEO_TVEEPROM 5 select VIDEO_TVEEPROM
6 select VIDEO_IR 6 select VIDEO_IR
7 select VIDEOBUF_VMALLOC 7 select VIDEOBUF_VMALLOC
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 3d1c3cc337fe..8137a8c94bfc 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
8obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o 8obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
9 9
10EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 13EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
13 14
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index b6171702c4d0..eec115bf9517 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -4,7 +4,7 @@ config VIDEO_IVTV
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_IR 6 select VIDEO_IR
7 select VIDEO_TUNER 7 select MEDIA_TUNER
8 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X 9 select VIDEO_CX2341X
10 select VIDEO_CX25840 10 select VIDEO_CX25840
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
index a0389014fa88..26ce0d6eaee1 100644
--- a/drivers/media/video/ivtv/Makefile
+++ b/drivers/media/video/ivtv/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o 8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
9 9
10EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 13EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
13 14
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index e908649ea37c..4fb8faefe2ce 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -40,6 +40,8 @@
40#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \ 40#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
41 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) 41 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
42 42
43#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM)
44
43/* usual i2c tuner addresses to probe */ 45/* usual i2c tuner addresses to probe */
44static struct ivtv_card_tuner_i2c ivtv_i2c_std = { 46static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
45 .radio = { I2C_CLIENT_END }, 47 .radio = { I2C_CLIENT_END },
@@ -298,7 +300,7 @@ static const struct ivtv_card ivtv_card_mpg600 = {
298 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, 300 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
299 .tuners = { 301 .tuners = {
300 /* The PAL tuner is confirmed */ 302 /* The PAL tuner is confirmed */
301 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 303 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
302 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 304 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
303 }, 305 },
304 .pci_list = ivtv_pci_mpg600, 306 .pci_list = ivtv_pci_mpg600,
@@ -339,7 +341,7 @@ static const struct ivtv_card ivtv_card_mpg160 = {
339 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 }, 341 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
340 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, 342 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
341 .tuners = { 343 .tuners = {
342 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 344 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
343 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 345 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
344 }, 346 },
345 .pci_list = ivtv_pci_mpg160, 347 .pci_list = ivtv_pci_mpg160,
@@ -375,7 +377,7 @@ static const struct ivtv_card ivtv_card_pg600 = {
375 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, 377 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
376 }, 378 },
377 .tuners = { 379 .tuners = {
378 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 380 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
379 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 381 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
380 }, 382 },
381 .pci_list = ivtv_pci_pg600, 383 .pci_list = ivtv_pci_pg600,
@@ -416,7 +418,7 @@ static const struct ivtv_card ivtv_card_avc2410 = {
416 on the country/region setting of the user to decide which tuner 418 on the country/region setting of the user to decide which tuner
417 is available. */ 419 is available. */
418 .tuners = { 420 .tuners = {
419 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 421 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
420 { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP, 422 { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP,
421 .tuner = TUNER_PHILIPS_FM1236_MK3 }, 423 .tuner = TUNER_PHILIPS_FM1236_MK3 },
422 { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 }, 424 { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 },
@@ -490,7 +492,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = {
490 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, 492 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
491 .composite = 0x0010, .svideo = 0x0020 }, 493 .composite = 0x0010, .svideo = 0x0020 },
492 .tuners = { 494 .tuners = {
493 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 495 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
494 }, 496 },
495 .pci_list = ivtv_pci_tg5000tv, 497 .pci_list = ivtv_pci_tg5000tv,
496 .i2c = &ivtv_i2c_std, 498 .i2c = &ivtv_i2c_std,
@@ -521,7 +523,7 @@ static const struct ivtv_card ivtv_card_va2000 = {
521 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, 523 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
522 }, 524 },
523 .tuners = { 525 .tuners = {
524 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 526 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
525 }, 527 },
526 .pci_list = ivtv_pci_va2000, 528 .pci_list = ivtv_pci_va2000,
527 .i2c = &ivtv_i2c_std, 529 .i2c = &ivtv_i2c_std,
@@ -565,7 +567,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = {
565 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 567 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
566 .f44100 = 0x4000, .f48000 = 0x8000 }, 568 .f44100 = 0x4000, .f48000 = 0x8000 },
567 .tuners = { 569 .tuners = {
568 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 570 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
569 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 571 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
570 }, 572 },
571 .pci_list = ivtv_pci_cx23416gyc, 573 .pci_list = ivtv_pci_cx23416gyc,
@@ -597,7 +599,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
597 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 599 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
598 .f44100 = 0x4000, .f48000 = 0x8000 }, 600 .f44100 = 0x4000, .f48000 = 0x8000 },
599 .tuners = { 601 .tuners = {
600 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 602 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
601 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 603 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
602 }, 604 },
603 .i2c = &ivtv_i2c_std, 605 .i2c = &ivtv_i2c_std,
@@ -627,7 +629,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
627 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 629 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
628 .f44100 = 0x4000, .f48000 = 0x8000 }, 630 .f44100 = 0x4000, .f48000 = 0x8000 },
629 .tuners = { 631 .tuners = {
630 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 632 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
631 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 633 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
632 }, 634 },
633 .i2c = &ivtv_i2c_std, 635 .i2c = &ivtv_i2c_std,
@@ -667,7 +669,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = {
667 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, 669 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
668 .tuners = { 670 .tuners = {
669 /* This card has the Panasonic VP27 tuner */ 671 /* This card has the Panasonic VP27 tuner */
670 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, 672 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
671 }, 673 },
672 .pci_list = ivtv_pci_gv_mvprx, 674 .pci_list = ivtv_pci_gv_mvprx,
673 .i2c = &ivtv_i2c_std, 675 .i2c = &ivtv_i2c_std,
@@ -704,7 +706,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = {
704 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, 706 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
705 .tuners = { 707 .tuners = {
706 /* This card has the Panasonic VP27 tuner */ 708 /* This card has the Panasonic VP27 tuner */
707 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, 709 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
708 }, 710 },
709 .pci_list = ivtv_pci_gv_mvprx2e, 711 .pci_list = ivtv_pci_gv_mvprx2e,
710 .i2c = &ivtv_i2c_std, 712 .i2c = &ivtv_i2c_std,
@@ -739,7 +741,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
739 .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 }, 741 .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
740 .tuners = { 742 .tuners = {
741 /* This card has a Philips FQ1216ME MK3 tuner */ 743 /* This card has a Philips FQ1216ME MK3 tuner */
742 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 744 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
743 }, 745 },
744 .pci_list = ivtv_pci_gotview_pci_dvd, 746 .pci_list = ivtv_pci_gotview_pci_dvd,
745 .i2c = &ivtv_i2c_std, 747 .i2c = &ivtv_i2c_std,
@@ -778,7 +780,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
778 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, 780 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
779 .tuners = { 781 .tuners = {
780 /* This card has a Philips FQ1216ME MK5 tuner */ 782 /* This card has a Philips FQ1216ME MK5 tuner */
781 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 783 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
782 }, 784 },
783 .pci_list = ivtv_pci_gotview_pci_dvd2, 785 .pci_list = ivtv_pci_gotview_pci_dvd2,
784 .i2c = &ivtv_i2c_std, 786 .i2c = &ivtv_i2c_std,
@@ -856,7 +858,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = {
856 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, 858 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
857 .composite = 0x0010, .svideo = 0x0020}, 859 .composite = 0x0010, .svideo = 0x0020},
858 .tuners = { 860 .tuners = {
859 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 861 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
860 }, 862 },
861 .pci_list = ivtv_pci_dctmvtvp1, 863 .pci_list = ivtv_pci_dctmvtvp1,
862 .i2c = &ivtv_i2c_std, 864 .i2c = &ivtv_i2c_std,
@@ -875,6 +877,7 @@ static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
875static const struct ivtv_card ivtv_card_pg600v2 = { 877static const struct ivtv_card ivtv_card_pg600v2 = {
876 .type = IVTV_CARD_PG600V2, 878 .type = IVTV_CARD_PG600V2,
877 .name = "Yuan PG600-2, GotView PCI DVD Lite", 879 .name = "Yuan PG600-2, GotView PCI DVD Lite",
880 .comment = "only Composite and S-Video inputs are supported, not the tuner\n",
878 .v4l2_capabilities = IVTV_CAP_ENCODER, 881 .v4l2_capabilities = IVTV_CAP_ENCODER,
879 .hw_video = IVTV_HW_CX25840, 882 .hw_video = IVTV_HW_CX25840,
880 .hw_audio = IVTV_HW_CX25840, 883 .hw_audio = IVTV_HW_CX25840,
@@ -921,6 +924,7 @@ static const struct ivtv_card ivtv_card_club3d = {
921 }, 924 },
922 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, 925 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
923 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */ 926 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
927 .xceive_pin = 12,
924 .tuners = { 928 .tuners = {
925 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, 929 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
926 }, 930 },
@@ -944,15 +948,22 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
944 .hw_video = IVTV_HW_CX25840, 948 .hw_video = IVTV_HW_CX25840,
945 .hw_audio = IVTV_HW_CX25840, 949 .hw_audio = IVTV_HW_CX25840,
946 .hw_audio_ctrl = IVTV_HW_CX25840, 950 .hw_audio_ctrl = IVTV_HW_CX25840,
947 .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739, 951 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
948 .video_inputs = { 952 .video_inputs = {
949 { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 }, 953 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
950 { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 }, 954 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
955 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
951 }, 956 },
952 .audio_inputs = { 957 .audio_inputs = {
958 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
953 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, 959 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
954 }, 960 },
955 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, /* enable line-in */ 961 /* enable line-in */
962 .gpio_init = { .direction = 0xe400, .initial_value = 0x4400 },
963 .xceive_pin = 10,
964 .tuners = {
965 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
966 },
956 .pci_list = ivtv_pci_avertv_mce116, 967 .pci_list = ivtv_pci_avertv_mce116,
957 .i2c = &ivtv_i2c_std, 968 .i2c = &ivtv_i2c_std,
958}; 969};
@@ -990,7 +1001,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
990 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, 1001 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
991 .tuners = { 1002 .tuners = {
992 /* This card has a Partsnic PTI-5NF05 tuner */ 1003 /* This card has a Partsnic PTI-5NF05 tuner */
993 { .std = V4L2_STD_525_60, .tuner = TUNER_TCL_2002N }, 1004 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_TCL_2002N },
994 }, 1005 },
995 .pci_list = ivtv_pci_aver_pvr150, 1006 .pci_list = ivtv_pci_aver_pvr150,
996 .i2c = &ivtv_i2c_radio, 1007 .i2c = &ivtv_i2c_radio,
@@ -1058,12 +1069,48 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = {
1058 }, 1069 },
1059 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER }, 1070 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
1060 .tuners = { 1071 .tuners = {
1061 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 1072 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
1062 }, 1073 },
1063 .pci_list = ivtv_pci_asus_falcon2, 1074 .pci_list = ivtv_pci_asus_falcon2,
1064 .i2c = &ivtv_i2c_std, 1075 .i2c = &ivtv_i2c_std,
1065}; 1076};
1066 1077
1078/* ------------------------------------------------------------------------- */
1079
1080/* AVerMedia M104 miniPCI card */
1081
1082static const struct ivtv_card_pci_info ivtv_pci_aver_m104[] = {
1083 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc136 },
1084 { 0, 0, 0 }
1085};
1086
1087static const struct ivtv_card ivtv_card_aver_m104 = {
1088 .type = IVTV_CARD_AVER_M104,
1089 .name = "AVerMedia M104",
1090 .comment = "Not yet supported!\n",
1091 .v4l2_capabilities = 0, /*IVTV_CAP_ENCODER,*/
1092 .hw_video = IVTV_HW_CX25840,
1093 .hw_audio = IVTV_HW_CX25840,
1094 .hw_audio_ctrl = IVTV_HW_CX25840,
1095 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
1096 .video_inputs = {
1097 { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
1098 { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
1099 },
1100 .audio_inputs = {
1101 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
1102 },
1103 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
1104 /* enable line-in + reset tuner */
1105 .gpio_init = { .direction = 0xe400, .initial_value = 0x4000 },
1106 .xceive_pin = 10,
1107 .tuners = {
1108 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
1109 },
1110 .pci_list = ivtv_pci_aver_m104,
1111 .i2c = &ivtv_i2c_std,
1112};
1113
1067static const struct ivtv_card *ivtv_card_list[] = { 1114static const struct ivtv_card *ivtv_card_list[] = {
1068 &ivtv_card_pvr250, 1115 &ivtv_card_pvr250,
1069 &ivtv_card_pvr350, 1116 &ivtv_card_pvr350,
@@ -1089,6 +1136,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
1089 &ivtv_card_asus_falcon2, 1136 &ivtv_card_asus_falcon2,
1090 &ivtv_card_aver_pvr150, 1137 &ivtv_card_aver_pvr150,
1091 &ivtv_card_aver_ezmaker, 1138 &ivtv_card_aver_ezmaker,
1139 &ivtv_card_aver_m104,
1092 1140
1093 /* Variations of standard cards but with the same PCI IDs. 1141 /* Variations of standard cards but with the same PCI IDs.
1094 These cards must come last in this list. */ 1142 These cards must come last in this list. */
@@ -1120,7 +1168,8 @@ int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
1120 if (index >= itv->nof_inputs) 1168 if (index >= itv->nof_inputs)
1121 return -EINVAL; 1169 return -EINVAL;
1122 input->index = index; 1170 input->index = index;
1123 strcpy(input->name, input_strs[card_input->video_type - 1]); 1171 strlcpy(input->name, input_strs[card_input->video_type - 1],
1172 sizeof(input->name));
1124 input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ? 1173 input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
1125 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); 1174 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
1126 input->audioset = (1 << itv->nof_audio_inputs) - 1; 1175 input->audioset = (1 << itv->nof_audio_inputs) - 1;
@@ -1137,7 +1186,7 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
1137 if (index >= itv->card->nof_outputs) 1186 if (index >= itv->card->nof_outputs)
1138 return -EINVAL; 1187 return -EINVAL;
1139 output->index = index; 1188 output->index = index;
1140 strcpy(output->name, card_output->name); 1189 strlcpy(output->name, card_output->name, sizeof(output->name));
1141 output->type = V4L2_OUTPUT_TYPE_ANALOG; 1190 output->type = V4L2_OUTPUT_TYPE_ANALOG;
1142 output->audioset = 1; 1191 output->audioset = 1;
1143 output->std = V4L2_STD_ALL; 1192 output->std = V4L2_STD_ALL;
@@ -1156,7 +1205,8 @@ int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
1156 memset(audio, 0, sizeof(*audio)); 1205 memset(audio, 0, sizeof(*audio));
1157 if (index >= itv->nof_audio_inputs) 1206 if (index >= itv->nof_audio_inputs)
1158 return -EINVAL; 1207 return -EINVAL;
1159 strcpy(audio->name, input_strs[aud_input->audio_type - 1]); 1208 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
1209 sizeof(audio->name));
1160 audio->index = index; 1210 audio->index = index;
1161 audio->capability = V4L2_AUDCAP_STEREO; 1211 audio->capability = V4L2_AUDCAP_STEREO;
1162 return 0; 1212 return 0;
@@ -1167,6 +1217,6 @@ int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud
1167 memset(aud_output, 0, sizeof(*aud_output)); 1217 memset(aud_output, 0, sizeof(*aud_output));
1168 if (itv->card->video_outputs == NULL || index != 0) 1218 if (itv->card->video_outputs == NULL || index != 0)
1169 return -EINVAL; 1219 return -EINVAL;
1170 strcpy(aud_output->name, "A/V Audio Out"); 1220 strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
1171 return 0; 1221 return 0;
1172} 1222}
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 9186fa2ee5fc..748485dcebbd 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -48,7 +48,8 @@
48#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */ 48#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */
49#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */ 49#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */ 50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
51#define IVTV_CARD_LAST 23 51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
52#define IVTV_CARD_LAST 24
52 53
53/* Variants of existing cards but with the same PCI IDs. The driver 54/* Variants of existing cards but with the same PCI IDs. The driver
54 detects these based on other device information. 55 detects these based on other device information.
@@ -244,6 +245,7 @@ struct ivtv_card_tuner_i2c {
244struct ivtv_card { 245struct ivtv_card {
245 int type; 246 int type;
246 char *name; 247 char *name;
248 char *comment;
247 u32 v4l2_capabilities; 249 u32 v4l2_capabilities;
248 u32 hw_video; /* hardware used to process video */ 250 u32 hw_video; /* hardware used to process video */
249 u32 hw_audio; /* hardware used to process audio */ 251 u32 hw_audio; /* hardware used to process audio */
@@ -256,6 +258,7 @@ struct ivtv_card {
256 int nof_outputs; 258 int nof_outputs;
257 const struct ivtv_card_output *video_outputs; 259 const struct ivtv_card_output *video_outputs;
258 u8 gr_config; /* config byte for the ghost reduction device */ 260 u8 gr_config; /* config byte for the ghost reduction device */
261 u8 xceive_pin; /* XCeive tuner GPIO reset pin */
259 262
260 /* GPIO card-specific settings */ 263 /* GPIO card-specific settings */
261 struct ivtv_gpio_init gpio_init; 264 struct ivtv_gpio_init gpio_init;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 065df53f80fd..47b5649729df 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -190,6 +190,7 @@ MODULE_PARM_DESC(cardtype,
190 "\t\t\t22 = ASUS Falcon2\n" 190 "\t\t\t22 = ASUS Falcon2\n"
191 "\t\t\t23 = AverMedia PVR-150 Plus\n" 191 "\t\t\t23 = AverMedia PVR-150 Plus\n"
192 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" 192 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
193 "\t\t\t25 = AverMedia M104 (not yet working)\n"
193 "\t\t\t 0 = Autodetect (default)\n" 194 "\t\t\t 0 = Autodetect (default)\n"
194 "\t\t\t-1 = Ignore this card\n\t\t"); 195 "\t\t\t-1 = Ignore this card\n\t\t");
195MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); 196MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
@@ -871,7 +872,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
871 unsigned i; 872 unsigned i;
872 873
873 /* load modules */ 874 /* load modules */
874#ifndef CONFIG_VIDEO_TUNER 875#ifndef CONFIG_MEDIA_TUNER
875 hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); 876 hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
876#endif 877#endif
877#ifndef CONFIG_VIDEO_CX25840 878#ifndef CONFIG_VIDEO_CX25840
@@ -1097,6 +1098,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1097 The PCI IDs are not always reliable. */ 1098 The PCI IDs are not always reliable. */
1098 ivtv_process_eeprom(itv); 1099 ivtv_process_eeprom(itv);
1099 } 1100 }
1101 if (itv->card->comment)
1102 IVTV_INFO("%s", itv->card->comment);
1103 if (itv->card->v4l2_capabilities == 0) {
1104 /* card was detected but is not supported */
1105 retval = -ENODEV;
1106 goto free_i2c;
1107 }
1100 1108
1101 if (itv->std == 0) { 1109 if (itv->std == 0) {
1102 itv->std = V4L2_STD_NTSC_M; 1110 itv->std = V4L2_STD_NTSC_M;
@@ -1195,13 +1203,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1195 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std); 1203 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
1196 } 1204 }
1197 1205
1198 retval = ivtv_streams_setup(itv);
1199 if (retval) {
1200 IVTV_ERR("Error %d setting up streams\n", retval);
1201 goto free_i2c;
1202 }
1203
1204 IVTV_DEBUG_IRQ("Masking interrupts\n");
1205 /* clear interrupt mask, effectively disabling interrupts */ 1206 /* clear interrupt mask, effectively disabling interrupts */
1206 ivtv_set_irq_mask(itv, 0xffffffff); 1207 ivtv_set_irq_mask(itv, 0xffffffff);
1207 1208
@@ -1210,32 +1211,38 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1210 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv); 1211 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv);
1211 if (retval) { 1212 if (retval) {
1212 IVTV_ERR("Failed to register irq %d\n", retval); 1213 IVTV_ERR("Failed to register irq %d\n", retval);
1213 goto free_streams; 1214 goto free_i2c;
1215 }
1216
1217 retval = ivtv_streams_setup(itv);
1218 if (retval) {
1219 IVTV_ERR("Error %d setting up streams\n", retval);
1220 goto free_irq;
1214 } 1221 }
1215 retval = ivtv_streams_register(itv); 1222 retval = ivtv_streams_register(itv);
1216 if (retval) { 1223 if (retval) {
1217 IVTV_ERR("Error %d registering devices\n", retval); 1224 IVTV_ERR("Error %d registering devices\n", retval);
1218 goto free_irq; 1225 goto free_streams;
1219 } 1226 }
1220 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); 1227 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
1221 return 0; 1228 return 0;
1222 1229
1223 free_irq: 1230free_streams:
1224 free_irq(itv->dev->irq, (void *)itv);
1225 free_streams:
1226 ivtv_streams_cleanup(itv); 1231 ivtv_streams_cleanup(itv);
1227 free_i2c: 1232free_irq:
1233 free_irq(itv->dev->irq, (void *)itv);
1234free_i2c:
1228 exit_ivtv_i2c(itv); 1235 exit_ivtv_i2c(itv);
1229 free_io: 1236free_io:
1230 ivtv_iounmap(itv); 1237 ivtv_iounmap(itv);
1231 free_mem: 1238free_mem:
1232 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); 1239 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
1233 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); 1240 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1234 if (itv->has_cx23415) 1241 if (itv->has_cx23415)
1235 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1242 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1236 free_workqueue: 1243free_workqueue:
1237 destroy_workqueue(itv->irq_work_queues); 1244 destroy_workqueue(itv->irq_work_queues);
1238 err: 1245err:
1239 if (retval == 0) 1246 if (retval == 0)
1240 retval = -ENODEV; 1247 retval = -ENODEV;
1241 IVTV_ERR("Error %d on initialization\n", retval); 1248 IVTV_ERR("Error %d on initialization\n", retval);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 688cd3856685..d8ac09f3cce6 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -128,20 +128,17 @@ int ivtv_reset_tuner_gpio(void *dev, int cmd, int value)
128{ 128{
129 struct i2c_algo_bit_data *algo = dev; 129 struct i2c_algo_bit_data *algo = dev;
130 struct ivtv *itv = algo->data; 130 struct ivtv *itv = algo->data;
131 int curdir, curout; 131 u32 curout;
132 132
133 if (cmd != XC2028_TUNER_RESET) 133 if (cmd != XC2028_TUNER_RESET)
134 return 0; 134 return 0;
135 IVTV_DEBUG_INFO("Resetting tuner\n"); 135 IVTV_DEBUG_INFO("Resetting tuner\n");
136 curout = read_reg(IVTV_REG_GPIO_OUT); 136 curout = read_reg(IVTV_REG_GPIO_OUT);
137 curdir = read_reg(IVTV_REG_GPIO_DIR); 137 curout &= ~(1 << itv->card->xceive_pin);
138 curdir |= (1 << 12); /* GPIO bit 12 */
139
140 curout &= ~(1 << 12);
141 write_reg(curout, IVTV_REG_GPIO_OUT); 138 write_reg(curout, IVTV_REG_GPIO_OUT);
142 schedule_timeout_interruptible(msecs_to_jiffies(1)); 139 schedule_timeout_interruptible(msecs_to_jiffies(1));
143 140
144 curout |= (1 << 12); 141 curout |= 1 << itv->card->xceive_pin;
145 write_reg(curout, IVTV_REG_GPIO_OUT); 142 write_reg(curout, IVTV_REG_GPIO_OUT);
146 schedule_timeout_interruptible(msecs_to_jiffies(1)); 143 schedule_timeout_interruptible(msecs_to_jiffies(1));
147 return 0; 144 return 0;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9824eafee021..771adf47e944 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -167,7 +167,8 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
167 return -1; 167 return -1;
168 id = hw_driverids[idx]; 168 id = hw_driverids[idx];
169 memset(&info, 0, sizeof(info)); 169 memset(&info, 0, sizeof(info));
170 strcpy(info.driver_name, hw_drivernames[idx]); 170 strlcpy(info.driver_name, hw_drivernames[idx],
171 sizeof(info.driver_name));
171 info.addr = hw_addrs[idx]; 172 info.addr = hw_addrs[idx];
172 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {} 173 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {}
173 174
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 15cac1812122..d508b5d0538c 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -243,20 +243,31 @@ static int ivtv_validate_speed(int cur_speed, int new_speed)
243 int fact = new_speed < 0 ? -1 : 1; 243 int fact = new_speed < 0 ? -1 : 1;
244 int s; 244 int s;
245 245
246 if (new_speed < 0) new_speed = -new_speed; 246 if (cur_speed == 0)
247 if (cur_speed < 0) cur_speed = -cur_speed; 247 cur_speed = 1000;
248 if (new_speed < 0)
249 new_speed = -new_speed;
250 if (cur_speed < 0)
251 cur_speed = -cur_speed;
248 252
249 if (cur_speed <= new_speed) { 253 if (cur_speed <= new_speed) {
250 if (new_speed > 1500) return fact * 2000; 254 if (new_speed > 1500)
251 if (new_speed > 1000) return fact * 1500; 255 return fact * 2000;
256 if (new_speed > 1000)
257 return fact * 1500;
252 } 258 }
253 else { 259 else {
254 if (new_speed >= 2000) return fact * 2000; 260 if (new_speed >= 2000)
255 if (new_speed >= 1500) return fact * 1500; 261 return fact * 2000;
256 if (new_speed >= 1000) return fact * 1000; 262 if (new_speed >= 1500)
257 } 263 return fact * 1500;
258 if (new_speed == 0) return 1000; 264 if (new_speed >= 1000)
259 if (new_speed == 1 || new_speed == 1000) return fact * new_speed; 265 return fact * 1000;
266 }
267 if (new_speed == 0)
268 return 1000;
269 if (new_speed == 1 || new_speed == 1000)
270 return fact * new_speed;
260 271
261 s = new_speed; 272 s = new_speed;
262 new_speed = 1000 / new_speed; 273 new_speed = 1000 / new_speed;
@@ -741,10 +752,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
741 struct v4l2_capability *vcap = arg; 752 struct v4l2_capability *vcap = arg;
742 753
743 memset(vcap, 0, sizeof(*vcap)); 754 memset(vcap, 0, sizeof(*vcap));
744 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ 755 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
745 strncpy(vcap->card, itv->card_name, 756 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
746 sizeof(vcap->card)-1); /* card type */ 757 strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
747 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
748 vcap->version = IVTV_DRIVER_VERSION; /* version */ 758 vcap->version = IVTV_DRIVER_VERSION; /* version */
749 vcap->capabilities = itv->v4l2_cap; /* capabilities */ 759 vcap->capabilities = itv->v4l2_cap; /* capabilities */
750 760
@@ -1018,7 +1028,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1018 ivtv_std_60hz : ivtv_std_50hz; 1028 ivtv_std_60hz : ivtv_std_50hz;
1019 vs->index = idx; 1029 vs->index = idx;
1020 vs->id = enum_stds[idx].std; 1030 vs->id = enum_stds[idx].std;
1021 strcpy(vs->name, enum_stds[idx].name); 1031 strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
1022 break; 1032 break;
1023 } 1033 }
1024 1034
@@ -1102,10 +1112,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1102 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); 1112 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1103 1113
1104 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 1114 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1105 strcpy(vt->name, "ivtv Radio Tuner"); 1115 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1106 vt->type = V4L2_TUNER_RADIO; 1116 vt->type = V4L2_TUNER_RADIO;
1107 } else { 1117 } else {
1108 strcpy(vt->name, "ivtv TV Tuner"); 1118 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1109 vt->type = V4L2_TUNER_ANALOG_TV; 1119 vt->type = V4L2_TUNER_ANALOG_TV;
1110 } 1120 }
1111 break; 1121 break;
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index a329c4689dbf..d8ba3a4a8761 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -384,7 +384,7 @@ static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
384 ivtv_stream_sync_for_device(s); 384 ivtv_stream_sync_for_device(s);
385 write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); 385 write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
386 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); 386 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
387 itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); 387 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
388 add_timer(&itv->dma_timer); 388 add_timer(&itv->dma_timer);
389} 389}
390 390
@@ -400,7 +400,7 @@ static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
400 ivtv_stream_sync_for_device(s); 400 ivtv_stream_sync_for_device(s);
401 write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); 401 write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
402 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); 402 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
403 itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); 403 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
404 add_timer(&itv->dma_timer); 404 add_timer(&itv->dma_timer);
405} 405}
406 406
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 0f1d4cc4b4d9..02c5ab071d1b 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -23,7 +23,7 @@
23#define IVTV_DRIVER_NAME "ivtv" 23#define IVTV_DRIVER_NAME "ivtv"
24#define IVTV_DRIVER_VERSION_MAJOR 1 24#define IVTV_DRIVER_VERSION_MAJOR 1
25#define IVTV_DRIVER_VERSION_MINOR 2 25#define IVTV_DRIVER_VERSION_MINOR 2
26#define IVTV_DRIVER_VERSION_PATCHLEVEL 0 26#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
27 27
28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) 28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
29#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) 29#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 3b23fc05f7c4..df789f683e63 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -532,7 +532,7 @@ static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
532 532
533 IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n"); 533 IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
534 memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 534 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
535 strcpy(fix->id, "cx23415 TV out"); 535 strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
536 fix->smem_start = oi->video_pbase; 536 fix->smem_start = oi->video_pbase;
537 fix->smem_len = oi->video_buffer_size; 537 fix->smem_len = oi->video_buffer_size;
538 fix->type = FB_TYPE_PACKED_PIXELS; 538 fix->type = FB_TYPE_PACKED_PIXELS;
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index d4bf14c284ef..5b9dfa2c51b4 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -126,7 +126,8 @@ static int m52790_command(struct i2c_client *client, unsigned int cmd,
126 126
127/* i2c implementation */ 127/* i2c implementation */
128 128
129static int m52790_probe(struct i2c_client *client) 129static int m52790_probe(struct i2c_client *client,
130 const struct i2c_device_id *id)
130{ 131{
131 struct m52790_state *state; 132 struct m52790_state *state;
132 133
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index b73c740f7fb2..e6273162e123 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -805,7 +805,7 @@ static int msp_resume(struct i2c_client *client)
805 805
806/* ----------------------------------------------------------------------- */ 806/* ----------------------------------------------------------------------- */
807 807
808static int msp_probe(struct i2c_client *client) 808static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
809{ 809{
810 struct msp_state *state; 810 struct msp_state *state;
811 int (*thread_func)(void *data) = NULL; 811 int (*thread_func)(void *data) = NULL;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 3fb5f63df1e6..179e47049a45 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -372,7 +372,7 @@ static int mt9m001_set_register(struct soc_camera_device *icd,
372} 372}
373#endif 373#endif
374 374
375const struct v4l2_queryctrl mt9m001_controls[] = { 375static const struct v4l2_queryctrl mt9m001_controls[] = {
376 { 376 {
377 .id = V4L2_CID_VFLIP, 377 .id = V4L2_CID_VFLIP,
378 .type = V4L2_CTRL_TYPE_BOOLEAN, 378 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -620,7 +620,8 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
620 soc_camera_video_stop(&mt9m001->icd); 620 soc_camera_video_stop(&mt9m001->icd);
621} 621}
622 622
623static int mt9m001_probe(struct i2c_client *client) 623static int mt9m001_probe(struct i2c_client *client,
624 const struct i2c_device_id *did)
624{ 625{
625 struct mt9m001 *mt9m001; 626 struct mt9m001 *mt9m001;
626 struct soc_camera_device *icd; 627 struct soc_camera_device *icd;
@@ -696,12 +697,19 @@ static int mt9m001_remove(struct i2c_client *client)
696 return 0; 697 return 0;
697} 698}
698 699
700static const struct i2c_device_id mt9m001_id[] = {
701 { "mt9m001", 0 },
702 { }
703};
704MODULE_DEVICE_TABLE(i2c, mt9m001_id);
705
699static struct i2c_driver mt9m001_i2c_driver = { 706static struct i2c_driver mt9m001_i2c_driver = {
700 .driver = { 707 .driver = {
701 .name = "mt9m001", 708 .name = "mt9m001",
702 }, 709 },
703 .probe = mt9m001_probe, 710 .probe = mt9m001_probe,
704 .remove = mt9m001_remove, 711 .remove = mt9m001_remove,
712 .id_table = mt9m001_id,
705}; 713};
706 714
707static int __init mt9m001_mod_init(void) 715static int __init mt9m001_mod_init(void)
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index d4b9e2744343..d1391ac55096 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -452,7 +452,7 @@ static int mt9v022_set_register(struct soc_camera_device *icd,
452} 452}
453#endif 453#endif
454 454
455const struct v4l2_queryctrl mt9v022_controls[] = { 455static const struct v4l2_queryctrl mt9v022_controls[] = {
456 { 456 {
457 .id = V4L2_CID_VFLIP, 457 .id = V4L2_CID_VFLIP,
458 .type = V4L2_CTRL_TYPE_BOOLEAN, 458 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -745,7 +745,8 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
745 soc_camera_video_stop(&mt9v022->icd); 745 soc_camera_video_stop(&mt9v022->icd);
746} 746}
747 747
748static int mt9v022_probe(struct i2c_client *client) 748static int mt9v022_probe(struct i2c_client *client,
749 const struct i2c_device_id *did)
749{ 750{
750 struct mt9v022 *mt9v022; 751 struct mt9v022 *mt9v022;
751 struct soc_camera_device *icd; 752 struct soc_camera_device *icd;
@@ -818,12 +819,19 @@ static int mt9v022_remove(struct i2c_client *client)
818 return 0; 819 return 0;
819} 820}
820 821
822static const struct i2c_device_id mt9v022_id[] = {
823 { "mt9v022", 0 },
824 { }
825};
826MODULE_DEVICE_TABLE(i2c, mt9v022_id);
827
821static struct i2c_driver mt9v022_i2c_driver = { 828static struct i2c_driver mt9v022_i2c_driver = {
822 .driver = { 829 .driver = {
823 .name = "mt9v022", 830 .name = "mt9v022",
824 }, 831 },
825 .probe = mt9v022_probe, 832 .probe = mt9v022_probe,
826 .remove = mt9v022_remove, 833 .remove = mt9v022_remove,
834 .id_table = mt9v022_id,
827}; 835};
828 836
829static int __init mt9v022_mod_init(void) 837static int __init mt9v022_mod_init(void)
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 158b3d0c6532..9620c67fae77 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -1,14 +1,15 @@
1config VIDEO_PVRUSB2 1config VIDEO_PVRUSB2
2 tristate "Hauppauge WinTV-PVR USB2 support" 2 tristate "Hauppauge WinTV-PVR USB2 support"
3 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && I2C
4 select FW_LOADER 4 select FW_LOADER
5 select VIDEO_TUNER 5 select MEDIA_TUNER
6 select VIDEO_TVEEPROM 6 select VIDEO_TVEEPROM
7 select VIDEO_CX2341X 7 select VIDEO_CX2341X
8 select VIDEO_SAA711X 8 select VIDEO_SAA711X
9 select VIDEO_CX25840 9 select VIDEO_CX25840
10 select VIDEO_MSP3400 10 select VIDEO_MSP3400
11 select VIDEO_WM8775 11 select VIDEO_WM8775
12 select VIDEO_CS53L32A
12 ---help--- 13 ---help---
13 This is a video4linux driver for Conexant 23416 based 14 This is a video4linux driver for Conexant 23416 based
14 usb2 personal video recorder devices. 15 usb2 personal video recorder devices.
@@ -16,32 +17,6 @@ config VIDEO_PVRUSB2
16 To compile this driver as a module, choose M here: the 17 To compile this driver as a module, choose M here: the
17 module will be called pvrusb2 18 module will be called pvrusb2
18 19
19config VIDEO_PVRUSB2_ONAIR_CREATOR
20 bool "pvrusb2 driver support for OnAir Creator model"
21 depends on VIDEO_PVRUSB2 && EXPERIMENTAL
22 select VIDEO_SAA711X
23 select VIDEO_CS53L32A
24 ---help---
25
26 This option enables support for the OnAir Creator USB tuner
27 device. This is a hybrid device, however currently only
28 analog mode is supported.
29
30 If you are in doubt, say Y.
31
32config VIDEO_PVRUSB2_ONAIR_USB2
33 bool "pvrusb2 driver support for OnAir USB2 model"
34 depends on VIDEO_PVRUSB2 && EXPERIMENTAL
35 select VIDEO_SAA711X
36 select VIDEO_CS53L32A
37 ---help---
38
39 This option enables support for the OnAir USB2 tuner device
40 (also known as the Sasem tuner). This is a hybrid device,
41 however currently only analog mode is supported.
42
43 If you are in doubt, say Y.
44
45config VIDEO_PVRUSB2_SYSFS 20config VIDEO_PVRUSB2_SYSFS
46 bool "pvrusb2 sysfs support (EXPERIMENTAL)" 21 bool "pvrusb2 sysfs support (EXPERIMENTAL)"
47 default y 22 default y
@@ -59,29 +34,23 @@ config VIDEO_PVRUSB2_SYSFS
59 Note: This feature is experimental and subject to change. 34 Note: This feature is experimental and subject to change.
60 35
61config VIDEO_PVRUSB2_DVB 36config VIDEO_PVRUSB2_DVB
62 bool "pvrusb2 DVB support (EXPERIMENTAL)" 37 bool "pvrusb2 ATSC/DVB support (EXPERIMENTAL)"
63 default n 38 default y
64 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL 39 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL
65 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 40 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
66 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 41 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
67 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 42 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
68 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 43 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
69 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE 44 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
70 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 45 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
71 select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE 46 select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
72 ---help--- 47 ---help---
73 48
74 This option enables compilation of a DVB interface for the 49 This option enables a DVB interface for the pvrusb2 driver.
75 pvrusb2 driver. Currently this is very very experimental. 50 If your device does not support digital television, this
76 It is also limiting - the DVB interface can only access the 51 feature will have no affect on the driver's operation.
77 digital side of hybrid devices, and there are going to be
78 issues if you attempt to mess with the V4L side at the same
79 time. Don't turn this on unless you know what you are
80 doing.
81
82 If you are in doubt, say N.
83 52
84 Note: This feature is very experimental and might break 53 If you are in doubt, say Y.
85 54
86config VIDEO_PVRUSB2_DEBUGIFC 55config VIDEO_PVRUSB2_DEBUGIFC
87 bool "pvrusb2 debug interface" 56 bool "pvrusb2 debug interface"
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 5b3083c89aa9..4fda2de69ab7 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -16,5 +16,6 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o 16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
17 17
18EXTRA_CFLAGS += -Idrivers/media/video 18EXTRA_CFLAGS += -Idrivers/media/video
19EXTRA_CFLAGS += -Idrivers/media/common/tuners
19EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 20EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
20EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 21EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
index 11537ddf8aa3..707d2d9635d7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debug.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h
@@ -54,6 +54,7 @@ extern int pvrusb2_debug;
54#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */ 54#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */
55#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */ 55#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */
56#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */ 56#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */
57#define PVR2_TRACE_DVB_FEED (1 << 28) /* DVB transport feed debug */
57 58
58 59
59#endif /* __PVRUSB2_HDW_INTERNAL_H */ 60#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 3a141d93e1a9..5bf6d8fda1f9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -153,7 +153,6 @@ static const struct pvr2_device_desc pvr2_device_gotview_2d = {
153 153
154 154
155 155
156#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR
157/*------------------------------------------------------------------------*/ 156/*------------------------------------------------------------------------*/
158/* OnAir Creator */ 157/* OnAir Creator */
159 158
@@ -212,11 +211,9 @@ static const struct pvr2_device_desc pvr2_device_onair_creator = {
212 .dvb_props = &pvr2_onair_creator_fe_props, 211 .dvb_props = &pvr2_onair_creator_fe_props,
213#endif 212#endif
214}; 213};
215#endif
216 214
217 215
218 216
219#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_USB2
220/*------------------------------------------------------------------------*/ 217/*------------------------------------------------------------------------*/
221/* OnAir USB 2.0 */ 218/* OnAir USB 2.0 */
222 219
@@ -274,7 +271,6 @@ static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
274 .dvb_props = &pvr2_onair_usb2_fe_props, 271 .dvb_props = &pvr2_onair_usb2_fe_props,
275#endif 272#endif
276}; 273};
277#endif
278 274
279 275
280 276
@@ -497,14 +493,10 @@ struct usb_device_id pvr2_device_table[] = {
497 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2}, 493 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2},
498 { USB_DEVICE(0x1164, 0x0602), 494 { USB_DEVICE(0x1164, 0x0602),
499 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d}, 495 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d},
500#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR
501 { USB_DEVICE(0x11ba, 0x1003), 496 { USB_DEVICE(0x11ba, 0x1003),
502 .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator}, 497 .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator},
503#endif
504#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_USB2
505 { USB_DEVICE(0x11ba, 0x1001), 498 { USB_DEVICE(0x11ba, 0x1001),
506 .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2}, 499 .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2},
507#endif
508 { USB_DEVICE(0x2040, 0x7300), 500 { USB_DEVICE(0x2040, 0x7300),
509 .driver_info = (kernel_ulong_t)&pvr2_device_73xxx}, 501 .driver_info = (kernel_ulong_t)&pvr2_device_73xxx},
510 { USB_DEVICE(0x2040, 0x7500), 502 { USB_DEVICE(0x2040, 0x7500),
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 6504c97e0bbc..6ec4bf81fc7f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -21,6 +21,7 @@
21#include <linux/kthread.h> 21#include <linux/kthread.h>
22#include <linux/freezer.h> 22#include <linux/freezer.h>
23#include "dvbdev.h" 23#include "dvbdev.h"
24#include "pvrusb2-debug.h"
24#include "pvrusb2-hdw-internal.h" 25#include "pvrusb2-hdw-internal.h"
25#include "pvrusb2-hdw.h" 26#include "pvrusb2-hdw.h"
26#include "pvrusb2-io.h" 27#include "pvrusb2-io.h"
@@ -35,7 +36,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
35 struct pvr2_buffer *bp; 36 struct pvr2_buffer *bp;
36 struct pvr2_stream *stream; 37 struct pvr2_stream *stream;
37 38
38 printk(KERN_DEBUG "dvb thread started\n"); 39 pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started");
39 set_freezable(); 40 set_freezable();
40 41
41 stream = adap->channel.stream->stream; 42 stream = adap->channel.stream->stream;
@@ -82,7 +83,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
82 /* If we get here and ret is < 0, then an error has occurred. 83 /* If we get here and ret is < 0, then an error has occurred.
83 Probably would be a good idea to communicate that to DVB core... */ 84 Probably would be a good idea to communicate that to DVB core... */
84 85
85 printk(KERN_DEBUG "dvb thread stopped\n"); 86 pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped");
86 87
87 return 0; 88 return 0;
88} 89}
@@ -210,7 +211,8 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
210 do { 211 do {
211 if (onoff) { 212 if (onoff) {
212 if (!adap->feedcount) { 213 if (!adap->feedcount) {
213 printk(KERN_DEBUG "start feeding\n"); 214 pvr2_trace(PVR2_TRACE_DVB_FEED,
215 "start feeding demux");
214 ret = pvr2_dvb_stream_start(adap); 216 ret = pvr2_dvb_stream_start(adap);
215 if (ret < 0) break; 217 if (ret < 0) break;
216 } 218 }
@@ -218,7 +220,8 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
218 } else if (adap->feedcount > 0) { 220 } else if (adap->feedcount > 0) {
219 (adap->feedcount)--; 221 (adap->feedcount)--;
220 if (!adap->feedcount) { 222 if (!adap->feedcount) {
221 printk(KERN_DEBUG "stop feeding\n"); 223 pvr2_trace(PVR2_TRACE_DVB_FEED,
224 "stop feeding demux");
222 pvr2_dvb_stream_end(adap); 225 pvr2_dvb_stream_end(adap);
223 } 226 }
224 } 227 }
@@ -230,15 +233,13 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
230 233
231static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) 234static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
232{ 235{
233 printk(KERN_DEBUG "start pid: 0x%04x, feedtype: %d\n", 236 pvr2_trace(PVR2_TRACE_DVB_FEED, "start pid: 0x%04x", dvbdmxfeed->pid);
234 dvbdmxfeed->pid, dvbdmxfeed->type);
235 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1); 237 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1);
236} 238}
237 239
238static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 240static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
239{ 241{
240 printk(KERN_DEBUG "stop pid: 0x%04x, feedtype: %d\n", 242 pvr2_trace(PVR2_TRACE_DVB_FEED, "stop pid: 0x%04x", dvbdmxfeed->pid);
241 dvbdmxfeed->pid, dvbdmxfeed->type);
242 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0); 243 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0);
243} 244}
244 245
@@ -259,7 +260,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
259 &adap->channel.hdw->usb_dev->dev, 260 &adap->channel.hdw->usb_dev->dev,
260 adapter_nr); 261 adapter_nr);
261 if (ret < 0) { 262 if (ret < 0) {
262 err("dvb_register_adapter failed: error %d", ret); 263 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
264 "dvb_register_adapter failed: error %d", ret);
263 goto err; 265 goto err;
264 } 266 }
265 adap->dvb_adap.priv = adap; 267 adap->dvb_adap.priv = adap;
@@ -276,7 +278,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
276 278
277 ret = dvb_dmx_init(&adap->demux); 279 ret = dvb_dmx_init(&adap->demux);
278 if (ret < 0) { 280 if (ret < 0) {
279 err("dvb_dmx_init failed: error %d", ret); 281 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
282 "dvb_dmx_init failed: error %d", ret);
280 goto err_dmx; 283 goto err_dmx;
281 } 284 }
282 285
@@ -286,7 +289,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
286 289
287 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); 290 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
288 if (ret < 0) { 291 if (ret < 0) {
289 err("dvb_dmxdev_init failed: error %d", ret); 292 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
293 "dvb_dmxdev_init failed: error %d", ret);
290 goto err_dmx_dev; 294 goto err_dmx_dev;
291 } 295 }
292 296
@@ -304,7 +308,7 @@ err:
304 308
305static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap) 309static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
306{ 310{
307 printk(KERN_DEBUG "unregistering DVB devices\n"); 311 pvr2_trace(PVR2_TRACE_INFO, "unregistering DVB devices");
308 dvb_net_release(&adap->dvb_net); 312 dvb_net_release(&adap->dvb_net);
309 adap->demux.dmx.close(&adap->demux.dmx); 313 adap->demux.dmx.close(&adap->demux.dmx);
310 dvb_dmxdev_release(&adap->dmxdev); 314 dvb_dmxdev_release(&adap->dmxdev);
@@ -320,7 +324,7 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
320 int ret = 0; 324 int ret = 0;
321 325
322 if (dvb_props == NULL) { 326 if (dvb_props == NULL) {
323 err("fe_props not defined!"); 327 pvr2_trace(PVR2_TRACE_ERROR_LEGS, "fe_props not defined!");
324 return -EINVAL; 328 return -EINVAL;
325 } 329 }
326 330
@@ -328,13 +332,15 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
328 &adap->channel, 332 &adap->channel,
329 (1 << PVR2_CVAL_INPUT_DTV)); 333 (1 << PVR2_CVAL_INPUT_DTV));
330 if (ret) { 334 if (ret) {
331 err("failed to grab control of dtv input (code=%d)", 335 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
336 "failed to grab control of dtv input (code=%d)",
332 ret); 337 ret);
333 return ret; 338 return ret;
334 } 339 }
335 340
336 if (dvb_props->frontend_attach == NULL) { 341 if (dvb_props->frontend_attach == NULL) {
337 err("frontend_attach not defined!"); 342 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
343 "frontend_attach not defined!");
338 ret = -EINVAL; 344 ret = -EINVAL;
339 goto done; 345 goto done;
340 } 346 }
@@ -342,7 +348,8 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
342 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) { 348 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
343 349
344 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { 350 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
345 err("frontend registration failed!"); 351 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
352 "frontend registration failed!");
346 dvb_frontend_detach(adap->fe); 353 dvb_frontend_detach(adap->fe);
347 adap->fe = NULL; 354 adap->fe = NULL;
348 ret = -ENODEV; 355 ret = -ENODEV;
@@ -359,7 +366,8 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
359 adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl; 366 adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
360 367
361 } else { 368 } else {
362 err("no frontend was attached!"); 369 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
370 "no frontend was attached!");
363 ret = -ENODEV; 371 ret = -ENODEV;
364 return ret; 372 return ret;
365 } 373 }
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 416d05d4a969..e684108637ad 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1450,7 +1450,8 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1450 1450
1451/* ----------------------------------------------------------------------- */ 1451/* ----------------------------------------------------------------------- */
1452 1452
1453static int saa7115_probe(struct i2c_client *client) 1453static int saa7115_probe(struct i2c_client *client,
1454 const struct i2c_device_id *id)
1454{ 1455{
1455 struct saa711x_state *state; 1456 struct saa711x_state *state;
1456 int i; 1457 int i;
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 06c88db656b4..e750cd65c1c3 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -661,7 +661,8 @@ static int saa7127_command(struct i2c_client *client,
661 661
662/* ----------------------------------------------------------------------- */ 662/* ----------------------------------------------------------------------- */
663 663
664static int saa7127_probe(struct i2c_client *client) 664static int saa7127_probe(struct i2c_client *client,
665 const struct i2c_device_id *id)
665{ 666{
666 struct saa7127_state *state; 667 struct saa7127_state *state;
667 struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */ 668 struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index e086f14d5663..40e4c3bd2cb9 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_SAA7134
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 select VIDEOBUF_DMA_SG 4 select VIDEOBUF_DMA_SG
5 select VIDEO_IR 5 select VIDEO_IR
6 select VIDEO_TUNER 6 select MEDIA_TUNER
7 select VIDEO_TVEEPROM 7 select VIDEO_TVEEPROM
8 select CRC32 8 select CRC32
9 ---help--- 9 ---help---
@@ -35,9 +35,9 @@ config VIDEO_SAA7134_DVB
35 select DVB_NXT200X if !DVB_FE_CUSTOMISE 35 select DVB_NXT200X if !DVB_FE_CUSTOMISE
36 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 36 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
37 select DVB_TDA826X if !DVB_FE_CUSTOMISE 37 select DVB_TDA826X if !DVB_FE_CUSTOMISE
38 select DVB_TDA827X if !DVB_FE_CUSTOMISE 38 select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
39 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 39 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
40 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 40 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
41 ---help--- 41 ---help---
42 This adds support for DVB cards based on the 42 This adds support for DVB cards based on the
43 Philips saa7134 chip. 43 Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index 9aff937ba7a5..3dbaa19a6d00 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -11,5 +11,6 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
12 12
13EXTRA_CFLAGS += -Idrivers/media/video 13EXTRA_CFLAGS += -Idrivers/media/video
14EXTRA_CFLAGS += -Idrivers/media/common/tuners
14EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 15EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
15EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 16EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 98375955a84b..b111903aa322 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -47,6 +47,9 @@ static char name_svideo[] = "S-Video";
47/* ------------------------------------------------------------------ */ 47/* ------------------------------------------------------------------ */
48/* board config info */ 48/* board config info */
49 49
50/* If radio_type !=UNSET, radio_addr should be specified
51 */
52
50struct saa7134_board saa7134_boards[] = { 53struct saa7134_board saa7134_boards[] = {
51 [SAA7134_BOARD_UNKNOWN] = { 54 [SAA7134_BOARD_UNKNOWN] = {
52 .name = "UNKNOWN/GENERIC", 55 .name = "UNKNOWN/GENERIC",
@@ -3087,7 +3090,7 @@ struct saa7134_board saa7134_boards[] = {
3087 .tuner_type = TUNER_PHILIPS_TD1316, /* untested */ 3090 .tuner_type = TUNER_PHILIPS_TD1316, /* untested */
3088 .radio_type = TUNER_TEA5767, /* untested */ 3091 .radio_type = TUNER_TEA5767, /* untested */
3089 .tuner_addr = ADDR_UNSET, 3092 .tuner_addr = ADDR_UNSET,
3090 .radio_addr = ADDR_UNSET, 3093 .radio_addr = 0x60,
3091 .tda9887_conf = TDA9887_PRESENT, 3094 .tda9887_conf = TDA9887_PRESENT,
3092 .mpeg = SAA7134_MPEG_DVB, 3095 .mpeg = SAA7134_MPEG_DVB,
3093 .inputs = {{ 3096 .inputs = {{
@@ -4247,6 +4250,36 @@ struct saa7134_board saa7134_boards[] = {
4247 .amux = LINE1, 4250 .amux = LINE1,
4248 } }, 4251 } },
4249 }, 4252 },
4253 [SAA7134_BOARD_BEHOLD_H6] = {
4254 /* Igor Kuznetsov <igk@igk.ru> */
4255 .name = "Beholder BeholdTV H6",
4256 .audio_clock = 0x00187de7,
4257 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
4258 .radio_type = UNSET,
4259 .tuner_addr = ADDR_UNSET,
4260 .radio_addr = ADDR_UNSET,
4261 .tda9887_conf = TDA9887_PRESENT,
4262 .inputs = {{
4263 .name = name_tv,
4264 .vmux = 3,
4265 .amux = TV,
4266 .tv = 1,
4267 }, {
4268 .name = name_comp1,
4269 .vmux = 1,
4270 .amux = LINE1,
4271 }, {
4272 .name = name_svideo,
4273 .vmux = 8,
4274 .amux = LINE1,
4275 } },
4276 .radio = {
4277 .name = name_radio,
4278 .amux = LINE2,
4279 },
4280 /* no DVB support for now */
4281 /* .mpeg = SAA7134_MPEG_DVB, */
4282 },
4250}; 4283};
4251 4284
4252const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 4285const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5197,6 +5230,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5197 .subvendor = 0x5ace, 5230 .subvendor = 0x5ace,
5198 .subdevice = 0x6193, 5231 .subdevice = 0x6193,
5199 .driver_data = SAA7134_BOARD_BEHOLD_M6, 5232 .driver_data = SAA7134_BOARD_BEHOLD_M6,
5233 }, {
5234 .vendor = PCI_VENDOR_ID_PHILIPS,
5235 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5236 .subvendor = 0x5ace,
5237 .subdevice = 0x6191,
5238 .driver_data = SAA7134_BOARD_BEHOLD_M6,
5200 },{ 5239 },{
5201 .vendor = PCI_VENDOR_ID_PHILIPS, 5240 .vendor = PCI_VENDOR_ID_PHILIPS,
5202 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 5241 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -5246,6 +5285,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5246 .subdevice = 0xc900, 5285 .subdevice = 0xc900,
5247 .driver_data = SAA7134_BOARD_VIDEOMATE_T750, 5286 .driver_data = SAA7134_BOARD_VIDEOMATE_T750,
5248 }, { 5287 }, {
5288 .vendor = PCI_VENDOR_ID_PHILIPS,
5289 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5290 .subvendor = 0x5ace,
5291 .subdevice = 0x6290,
5292 .driver_data = SAA7134_BOARD_BEHOLD_H6,
5293 }, {
5249 /* --- boards without eeprom + subsystem ID --- */ 5294 /* --- boards without eeprom + subsystem ID --- */
5250 .vendor = PCI_VENDOR_ID_PHILIPS, 5295 .vendor = PCI_VENDOR_ID_PHILIPS,
5251 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 5296 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5577,20 +5622,87 @@ int saa7134_board_init1(struct saa7134_dev *dev)
5577 return 0; 5622 return 0;
5578} 5623}
5579 5624
5625static void saa7134_tuner_setup(struct saa7134_dev *dev)
5626{
5627 struct tuner_setup tun_setup;
5628 unsigned int mode_mask = T_RADIO |
5629 T_ANALOG_TV |
5630 T_DIGITAL_TV;
5631
5632 memset(&tun_setup, 0, sizeof(tun_setup));
5633 tun_setup.tuner_callback = saa7134_tuner_callback;
5634
5635 if (saa7134_boards[dev->board].radio_type != UNSET) {
5636 tun_setup.type = saa7134_boards[dev->board].radio_type;
5637 tun_setup.addr = saa7134_boards[dev->board].radio_addr;
5638
5639 tun_setup.mode_mask = T_RADIO;
5640
5641 saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
5642 mode_mask &= ~T_RADIO;
5643 }
5644
5645 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type != UNSET)) {
5646 tun_setup.type = dev->tuner_type;
5647 tun_setup.addr = dev->tuner_addr;
5648 tun_setup.config = saa7134_boards[dev->board].tuner_config;
5649 tun_setup.tuner_callback = saa7134_tuner_callback;
5650
5651 tun_setup.mode_mask = mode_mask;
5652
5653 saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
5654 }
5655
5656 if (dev->tda9887_conf) {
5657 struct v4l2_priv_tun_config tda9887_cfg;
5658
5659 tda9887_cfg.tuner = TUNER_TDA9887;
5660 tda9887_cfg.priv = &dev->tda9887_conf;
5661
5662 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
5663 &tda9887_cfg);
5664 }
5665
5666 if (dev->tuner_type == TUNER_XC2028) {
5667 struct v4l2_priv_tun_config xc2028_cfg;
5668 struct xc2028_ctrl ctl;
5669
5670 memset(&xc2028_cfg, 0, sizeof(ctl));
5671 memset(&ctl, 0, sizeof(ctl));
5672
5673 ctl.fname = XC2028_DEFAULT_FIRMWARE;
5674 ctl.max_len = 64;
5675
5676 switch (dev->board) {
5677 case SAA7134_BOARD_AVERMEDIA_A16D:
5678 ctl.demod = XC3028_FE_ZARLINK456;
5679 break;
5680 default:
5681 ctl.demod = XC3028_FE_OREN538;
5682 ctl.mts = 1;
5683 }
5684
5685 xc2028_cfg.tuner = TUNER_XC2028;
5686 xc2028_cfg.priv = &ctl;
5687
5688 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
5689 }
5690}
5691
5580/* stuff which needs working i2c */ 5692/* stuff which needs working i2c */
5581int saa7134_board_init2(struct saa7134_dev *dev) 5693int saa7134_board_init2(struct saa7134_dev *dev)
5582{ 5694{
5583 unsigned char buf; 5695 unsigned char buf;
5584 int board; 5696 int board;
5585 struct tuner_setup tun_setup; 5697
5586 tun_setup.config = 0; 5698 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
5587 tun_setup.tuner_callback = saa7134_tuner_callback; 5699 dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
5588 5700
5589 switch (dev->board) { 5701 switch (dev->board) {
5590 case SAA7134_BOARD_BMK_MPEX_NOTUNER: 5702 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
5591 case SAA7134_BOARD_BMK_MPEX_TUNER: 5703 case SAA7134_BOARD_BMK_MPEX_TUNER:
5592 dev->i2c_client.addr = 0x60; 5704 dev->i2c_client.addr = 0x60;
5593 board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0) 5705 board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
5594 ? SAA7134_BOARD_BMK_MPEX_NOTUNER 5706 ? SAA7134_BOARD_BMK_MPEX_NOTUNER
5595 : SAA7134_BOARD_BMK_MPEX_TUNER; 5707 : SAA7134_BOARD_BMK_MPEX_TUNER;
5596 if (board == dev->board) 5708 if (board == dev->board)
@@ -5600,21 +5712,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5600 saa7134_boards[dev->board].name); 5712 saa7134_boards[dev->board].name);
5601 dev->tuner_type = saa7134_boards[dev->board].tuner_type; 5713 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
5602 5714
5603 if (TUNER_ABSENT != dev->tuner_type) {
5604 tun_setup.mode_mask = T_RADIO |
5605 T_ANALOG_TV |
5606 T_DIGITAL_TV;
5607 tun_setup.type = dev->tuner_type;
5608 tun_setup.addr = ADDR_UNSET;
5609 tun_setup.tuner_callback = saa7134_tuner_callback;
5610
5611 saa7134_i2c_call_clients(dev,
5612 TUNER_SET_TYPE_ADDR,
5613 &tun_setup);
5614 }
5615 break; 5715 break;
5616 case SAA7134_BOARD_MD7134: 5716 case SAA7134_BOARD_MD7134:
5617 { 5717 {
5618 u8 subaddr; 5718 u8 subaddr;
5619 u8 data[3]; 5719 u8 data[3];
5620 int ret, tuner_t; 5720 int ret, tuner_t;
@@ -5667,30 +5767,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5667 } 5767 }
5668 5768
5669 printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type); 5769 printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
5670 if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
5671 struct v4l2_priv_tun_config tda9887_cfg;
5672
5673 tda9887_cfg.tuner = TUNER_TDA9887;
5674 tda9887_cfg.priv = &dev->tda9887_conf;
5675
5676 dev->tda9887_conf = TDA9887_PRESENT |
5677 TDA9887_PORT1_ACTIVE |
5678 TDA9887_PORT2_ACTIVE;
5679
5680 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
5681 &tda9887_cfg);
5682 }
5683
5684 tun_setup.mode_mask = T_RADIO |
5685 T_ANALOG_TV |
5686 T_DIGITAL_TV;
5687 tun_setup.type = dev->tuner_type;
5688 tun_setup.addr = ADDR_UNSET;
5689
5690 saa7134_i2c_call_clients(dev,
5691 TUNER_SET_TYPE_ADDR, &tun_setup);
5692 }
5693 break; 5770 break;
5771 }
5694 case SAA7134_BOARD_PHILIPS_EUROPA: 5772 case SAA7134_BOARD_PHILIPS_EUROPA:
5695 if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) { 5773 if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) {
5696 /* Reconfigure board as Snake reference design */ 5774 /* Reconfigure board as Snake reference design */
@@ -5702,43 +5780,43 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5702 } 5780 }
5703 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 5781 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
5704 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: 5782 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
5783 {
5784
5705 /* The Philips EUROPA based hybrid boards have the tuner connected through 5785 /* The Philips EUROPA based hybrid boards have the tuner connected through
5706 * the channel decoder. We have to make it transparent to find it 5786 * the channel decoder. We have to make it transparent to find it
5707 */ 5787 */
5708 {
5709 u8 data[] = { 0x07, 0x02}; 5788 u8 data[] = { 0x07, 0x02};
5710 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5789 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5711 i2c_transfer(&dev->i2c_adap, &msg, 1); 5790 i2c_transfer(&dev->i2c_adap, &msg, 1);
5712 5791
5713 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
5714 tun_setup.type = dev->tuner_type;
5715 tun_setup.addr = dev->tuner_addr;
5716
5717 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
5718 }
5719 break; 5792 break;
5793 }
5720 case SAA7134_BOARD_PHILIPS_TIGER: 5794 case SAA7134_BOARD_PHILIPS_TIGER:
5721 case SAA7134_BOARD_PHILIPS_TIGER_S: 5795 case SAA7134_BOARD_PHILIPS_TIGER_S:
5722 { 5796 {
5723 u8 data[] = { 0x3c, 0x33, 0x60}; 5797 u8 data[] = { 0x3c, 0x33, 0x60};
5724 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5798 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5725 if(dev->autodetected && (dev->eedata[0x49] == 0x50)) { 5799 if (dev->autodetected && (dev->eedata[0x49] == 0x50)) {
5726 dev->board = SAA7134_BOARD_PHILIPS_TIGER_S; 5800 dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
5727 printk(KERN_INFO "%s: Reconfigured board as %s\n", 5801 printk(KERN_INFO "%s: Reconfigured board as %s\n",
5728 dev->name, saa7134_boards[dev->board].name); 5802 dev->name, saa7134_boards[dev->board].name);
5729 } 5803 }
5730 if(dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { 5804 if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
5731 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 5805 dev->tuner_type = TUNER_PHILIPS_TDA8290;
5732 tun_setup.type = TUNER_PHILIPS_TDA8290; 5806
5733 tun_setup.addr = 0x4b; 5807 saa7134_tuner_setup(dev);
5734 tun_setup.config = 2;
5735 5808
5736 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
5737 data[2] = 0x68; 5809 data[2] = 0x68;
5810 i2c_transfer(&dev->i2c_adap, &msg, 1);
5811
5812 /* Tuner setup is handled before I2C transfer.
5813 Due to that, there's no need to do it later
5814 */
5815 return 0;
5738 } 5816 }
5739 i2c_transfer(&dev->i2c_adap, &msg, 1); 5817 i2c_transfer(&dev->i2c_adap, &msg, 1);
5740 }
5741 break; 5818 break;
5819 }
5742 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 5820 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
5743 hauppauge_eeprom(dev, dev->eedata+0x80); 5821 hauppauge_eeprom(dev, dev->eedata+0x80);
5744 /* break intentionally omitted */ 5822 /* break intentionally omitted */
@@ -5751,52 +5829,55 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5751 case SAA7134_BOARD_AVERMEDIA_SUPER_007: 5829 case SAA7134_BOARD_AVERMEDIA_SUPER_007:
5752 case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: 5830 case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
5753 case SAA7134_BOARD_CREATIX_CTX953: 5831 case SAA7134_BOARD_CREATIX_CTX953:
5832 {
5754 /* this is a hybrid board, initialize to analog mode 5833 /* this is a hybrid board, initialize to analog mode
5755 * and configure firmware eeprom address 5834 * and configure firmware eeprom address
5756 */ 5835 */
5757 {
5758 u8 data[] = { 0x3c, 0x33, 0x60}; 5836 u8 data[] = { 0x3c, 0x33, 0x60};
5759 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5837 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5760 i2c_transfer(&dev->i2c_adap, &msg, 1); 5838 i2c_transfer(&dev->i2c_adap, &msg, 1);
5761 }
5762 break; 5839 break;
5840 }
5763 case SAA7134_BOARD_FLYDVB_TRIO: 5841 case SAA7134_BOARD_FLYDVB_TRIO:
5764 { 5842 {
5765 u8 data[] = { 0x3c, 0x33, 0x62}; 5843 u8 data[] = { 0x3c, 0x33, 0x62};
5766 struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; 5844 struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
5767 i2c_transfer(&dev->i2c_adap, &msg, 1); 5845 i2c_transfer(&dev->i2c_adap, &msg, 1);
5768 }
5769 break; 5846 break;
5847 }
5770 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 5848 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
5771 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 5849 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
5850 {
5772 /* initialize analog mode */ 5851 /* initialize analog mode */
5773 {
5774 u8 data[] = { 0x3c, 0x33, 0x6a}; 5852 u8 data[] = { 0x3c, 0x33, 0x6a};
5775 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5853 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5776 i2c_transfer(&dev->i2c_adap, &msg, 1); 5854 i2c_transfer(&dev->i2c_adap, &msg, 1);
5777 }
5778 break; 5855 break;
5856 }
5779 case SAA7134_BOARD_CINERGY_HT_PCMCIA: 5857 case SAA7134_BOARD_CINERGY_HT_PCMCIA:
5780 case SAA7134_BOARD_CINERGY_HT_PCI: 5858 case SAA7134_BOARD_CINERGY_HT_PCI:
5859 {
5781 /* initialize analog mode */ 5860 /* initialize analog mode */
5782 {
5783 u8 data[] = { 0x3c, 0x33, 0x68}; 5861 u8 data[] = { 0x3c, 0x33, 0x68};
5784 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5862 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5785 i2c_transfer(&dev->i2c_adap, &msg, 1); 5863 i2c_transfer(&dev->i2c_adap, &msg, 1);
5786 }
5787 break; 5864 break;
5865 }
5788 case SAA7134_BOARD_KWORLD_ATSC110: 5866 case SAA7134_BOARD_KWORLD_ATSC110:
5789 { 5867 {
5790 /* enable tuner */ 5868 /* enable tuner */
5791 int i; 5869 int i;
5792 static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; 5870 static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
5793 dev->i2c_client.addr = 0x0a; 5871 0x00, 0x14, 0x04, 0x17, 0x00 };
5794 for (i = 0; i < 5; i++) 5872 dev->i2c_client.addr = 0x0a;
5795 if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2)) 5873 for (i = 0; i < 5; i++)
5796 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n", 5874 if (2 != i2c_master_send(&dev->i2c_client,
5797 dev->name, i); 5875 &buffer[i*2], 2))
5798 } 5876 printk(KERN_WARNING
5877 "%s: Unable to enable tuner(%i).\n",
5878 dev->name, i);
5799 break; 5879 break;
5880 }
5800 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 5881 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
5801 case SAA7134_BOARD_VIDEOMATE_DVBT_200A: 5882 case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
5802 /* The T200 and the T200A share the same pci id. Consequently, 5883 /* The T200 and the T200A share the same pci id. Consequently,
@@ -5821,7 +5902,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5821 } 5902 }
5822 break; 5903 break;
5823 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: 5904 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
5824 { 5905 {
5825 struct v4l2_priv_tun_config tea5767_cfg; 5906 struct v4l2_priv_tun_config tea5767_cfg;
5826 struct tea5767_ctrl ctl; 5907 struct tea5767_ctrl ctl;
5827 5908
@@ -5832,34 +5913,11 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5832 tea5767_cfg.tuner = TUNER_TEA5767; 5913 tea5767_cfg.tuner = TUNER_TEA5767;
5833 tea5767_cfg.priv = &ctl; 5914 tea5767_cfg.priv = &ctl;
5834 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg); 5915 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
5835 }
5836 break; 5916 break;
5837 } 5917 }
5918 } /* switch() */
5838 5919
5839 if (dev->tuner_type == TUNER_XC2028) { 5920 saa7134_tuner_setup(dev);
5840 struct v4l2_priv_tun_config xc2028_cfg;
5841 struct xc2028_ctrl ctl;
5842
5843 memset(&xc2028_cfg, 0, sizeof(ctl));
5844 memset(&ctl, 0, sizeof(ctl));
5845
5846 ctl.fname = XC2028_DEFAULT_FIRMWARE;
5847 ctl.max_len = 64;
5848
5849 switch (dev->board) {
5850 case SAA7134_BOARD_AVERMEDIA_A16D:
5851 ctl.demod = XC3028_FE_ZARLINK456;
5852 break;
5853 default:
5854 ctl.demod = XC3028_FE_OREN538;
5855 ctl.mts = 1;
5856 }
5857
5858 xc2028_cfg.tuner = TUNER_XC2028;
5859 xc2028_cfg.priv = &ctl;
5860
5861 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
5862 }
5863 5921
5864 return 0; 5922 return 0;
5865} 5923}
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 2ccfaba0c490..d8af3863f2d3 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -324,8 +324,6 @@ static u32 functionality(struct i2c_adapter *adap)
324static int attach_inform(struct i2c_client *client) 324static int attach_inform(struct i2c_client *client)
325{ 325{
326 struct saa7134_dev *dev = client->adapter->algo_data; 326 struct saa7134_dev *dev = client->adapter->algo_data;
327 int tuner = dev->tuner_type;
328 struct tuner_setup tun_setup;
329 327
330 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 328 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
331 client->driver->driver.name, client->addr, client->name); 329 client->driver->driver.name, client->addr, client->name);
@@ -346,46 +344,6 @@ static int attach_inform(struct i2c_client *client)
346 } 344 }
347 } 345 }
348 346
349 if (!client->driver->command)
350 return 0;
351
352 if (saa7134_boards[dev->board].radio_type != UNSET) {
353
354 tun_setup.type = saa7134_boards[dev->board].radio_type;
355 tun_setup.addr = saa7134_boards[dev->board].radio_addr;
356
357 if ((tun_setup.addr == ADDR_UNSET) || (tun_setup.addr == client->addr)) {
358 tun_setup.mode_mask = T_RADIO;
359
360 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
361 }
362 }
363
364 if (tuner != UNSET) {
365 tun_setup.type = tuner;
366 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
367 tun_setup.config = saa7134_boards[dev->board].tuner_config;
368 tun_setup.tuner_callback = saa7134_tuner_callback;
369
370 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
371
372 tun_setup.mode_mask = T_ANALOG_TV;
373
374 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
375 }
376
377 if (tuner == TUNER_TDA9887) {
378 struct v4l2_priv_tun_config tda9887_cfg;
379
380 tda9887_cfg.tuner = TUNER_TDA9887;
381 tda9887_cfg.priv = &dev->tda9887_conf;
382
383 client->driver->command(client, TUNER_SET_CONFIG,
384 &tda9887_cfg);
385 }
386 }
387
388
389 return 0; 347 return 0;
390} 348}
391 349
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 767ff30832f2..919632b10aae 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -531,6 +531,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
531 break; 531 break;
532 case SAA7134_BOARD_BEHOLD_607_9FM: 532 case SAA7134_BOARD_BEHOLD_607_9FM:
533 case SAA7134_BOARD_BEHOLD_M6: 533 case SAA7134_BOARD_BEHOLD_M6:
534 case SAA7134_BOARD_BEHOLD_H6:
534 snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); 535 snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
535 ir->get_key = get_key_beholdm6xx; 536 ir->get_key = get_key_beholdm6xx;
536 ir->ir_codes = ir_codes_behold; 537 ir->ir_codes = ir_codes_behold;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 924ffd13637e..34ff0d4998f3 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -263,6 +263,7 @@ struct saa7134_format {
263#define SAA7134_BOARD_VIDEOMATE_T750 139 263#define SAA7134_BOARD_VIDEOMATE_T750 139
264#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140 264#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140
265#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141 265#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141
266#define SAA7134_BOARD_BEHOLD_H6 142
266 267
267 268
268#define SAA7134_MAXBOARDS 8 269#define SAA7134_MAXBOARDS 8
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 53c5edbcf7ea..72c4081feff5 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1418,7 +1418,8 @@ static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
1418/* i2c implementation */ 1418/* i2c implementation */
1419 1419
1420/* ----------------------------------------------------------------------- */ 1420/* ----------------------------------------------------------------------- */
1421static int saa717x_probe(struct i2c_client *client) 1421static int saa717x_probe(struct i2c_client *client,
1422 const struct i2c_device_id *did)
1422{ 1423{
1423 struct saa717x_state *decoder; 1424 struct saa717x_state *decoder;
1424 u8 id = 0; 1425 u8 id = 0;
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 6943b447a1bd..e57a64605778 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -840,7 +840,8 @@ static struct v4l2_int_device tcm825x_int_device = {
840 }, 840 },
841}; 841};
842 842
843static int tcm825x_probe(struct i2c_client *client) 843static int tcm825x_probe(struct i2c_client *client,
844 const struct i2c_device_id *did)
844{ 845{
845 struct tcm825x_sensor *sensor = &tcm825x; 846 struct tcm825x_sensor *sensor = &tcm825x;
846 int rval; 847 int rval;
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index dc7b9c220b90..f1db54202dea 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -125,7 +125,8 @@ static int tlv320aic23b_command(struct i2c_client *client,
125 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 125 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
126 */ 126 */
127 127
128static int tlv320aic23b_probe(struct i2c_client *client) 128static int tlv320aic23b_probe(struct i2c_client *client,
129 const struct i2c_device_id *id)
129{ 130{
130 struct tlv320aic23b_state *state; 131 struct tlv320aic23b_state *state;
131 132
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2b72e10e6b9f..cc19c4abb467 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -33,6 +33,46 @@
33 33
34#define PREFIX t->i2c->driver->driver.name 34#define PREFIX t->i2c->driver->driver.name
35 35
36/** This macro allows us to probe dynamically, avoiding static links */
37#ifdef CONFIG_DVB_CORE_ATTACH
38#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
39 int __r = -EINVAL; \
40 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
41 if (__a) { \
42 __r = (int) __a(ARGS); \
43 } else { \
44 printk(KERN_ERR "TUNER: Unable to find " \
45 "symbol "#FUNCTION"()\n"); \
46 } \
47 symbol_put(FUNCTION); \
48 __r; \
49})
50
51static void tuner_detach(struct dvb_frontend *fe)
52{
53 if (fe->ops.tuner_ops.release) {
54 fe->ops.tuner_ops.release(fe);
55 symbol_put_addr(fe->ops.tuner_ops.release);
56 }
57 if (fe->ops.analog_ops.release) {
58 fe->ops.analog_ops.release(fe);
59 symbol_put_addr(fe->ops.analog_ops.release);
60 }
61}
62#else
63#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
64 FUNCTION(ARGS); \
65})
66
67static void tuner_detach(struct dvb_frontend *fe)
68{
69 if (fe->ops.tuner_ops.release)
70 fe->ops.tuner_ops.release(fe);
71 if (fe->ops.analog_ops.release)
72 fe->ops.analog_ops.release(fe);
73}
74#endif
75
36struct tuner { 76struct tuner {
37 /* device */ 77 /* device */
38 struct dvb_frontend fe; 78 struct dvb_frontend fe;
@@ -56,7 +96,7 @@ struct tuner {
56 96
57/* standard i2c insmod options */ 97/* standard i2c insmod options */
58static unsigned short normal_i2c[] = { 98static unsigned short normal_i2c[] = {
59#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE)) 99#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
60 0x10, 100 0x10,
61#endif 101#endif
62 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ 102 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
@@ -139,22 +179,6 @@ static void fe_set_params(struct dvb_frontend *fe,
139 fe_tuner_ops->set_analog_params(fe, params); 179 fe_tuner_ops->set_analog_params(fe, params);
140} 180}
141 181
142static void fe_release(struct dvb_frontend *fe)
143{
144 if (fe->ops.tuner_ops.release)
145 fe->ops.tuner_ops.release(fe);
146
147 /* DO NOT kfree(fe->analog_demod_priv)
148 *
149 * If we are in this function, analog_demod_priv contains a pointer
150 * to struct tuner *t. This will be kfree'd in tuner_detach().
151 *
152 * Otherwise, fe->ops.analog_demod_ops->release will
153 * handle the cleanup for analog demodulator modules.
154 */
155 fe->analog_demod_priv = NULL;
156}
157
158static void fe_standby(struct dvb_frontend *fe) 182static void fe_standby(struct dvb_frontend *fe)
159{ 183{
160 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; 184 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
@@ -191,7 +215,6 @@ static void tuner_status(struct dvb_frontend *fe);
191static struct analog_demod_ops tuner_core_ops = { 215static struct analog_demod_ops tuner_core_ops = {
192 .set_params = fe_set_params, 216 .set_params = fe_set_params,
193 .standby = fe_standby, 217 .standby = fe_standby,
194 .release = fe_release,
195 .has_signal = fe_has_signal, 218 .has_signal = fe_has_signal,
196 .set_config = fe_set_config, 219 .set_config = fe_set_config,
197 .tuner_status = tuner_status 220 .tuner_status = tuner_status
@@ -323,7 +346,8 @@ static void attach_tda829x(struct tuner *t)
323 .lna_cfg = t->config, 346 .lna_cfg = t->config,
324 .tuner_callback = t->tuner_callback, 347 .tuner_callback = t->tuner_callback,
325 }; 348 };
326 tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); 349 dvb_attach(tda829x_attach,
350 &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
327} 351}
328 352
329static struct xc5000_config xc5000_cfg; 353static struct xc5000_config xc5000_cfg;
@@ -356,12 +380,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
356 } 380 }
357 381
358 /* discard private data, in case set_type() was previously called */ 382 /* discard private data, in case set_type() was previously called */
359 if (analog_ops->release) 383 tuner_detach(&t->fe);
360 analog_ops->release(&t->fe); 384 t->fe.analog_demod_priv = NULL;
361 385
362 switch (t->type) { 386 switch (t->type) {
363 case TUNER_MT2032: 387 case TUNER_MT2032:
364 microtune_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 388 dvb_attach(microtune_attach,
389 &t->fe, t->i2c->adapter, t->i2c->addr);
365 break; 390 break;
366 case TUNER_PHILIPS_TDA8290: 391 case TUNER_PHILIPS_TDA8290:
367 { 392 {
@@ -369,12 +394,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
369 break; 394 break;
370 } 395 }
371 case TUNER_TEA5767: 396 case TUNER_TEA5767:
372 if (!tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 397 if (!dvb_attach(tea5767_attach, &t->fe,
398 t->i2c->adapter, t->i2c->addr))
373 goto attach_failed; 399 goto attach_failed;
374 t->mode_mask = T_RADIO; 400 t->mode_mask = T_RADIO;
375 break; 401 break;
376 case TUNER_TEA5761: 402 case TUNER_TEA5761:
377 if (!tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 403 if (!dvb_attach(tea5761_attach, &t->fe,
404 t->i2c->adapter, t->i2c->addr))
378 goto attach_failed; 405 goto attach_failed;
379 t->mode_mask = T_RADIO; 406 t->mode_mask = T_RADIO;
380 break; 407 break;
@@ -388,8 +415,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
388 buffer[2] = 0x86; 415 buffer[2] = 0x86;
389 buffer[3] = 0x54; 416 buffer[3] = 0x54;
390 i2c_master_send(c, buffer, 4); 417 i2c_master_send(c, buffer, 4);
391 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, 418 if (!dvb_attach(simple_tuner_attach, &t->fe,
392 t->type)) 419 t->i2c->adapter, t->i2c->addr, t->type))
393 goto attach_failed; 420 goto attach_failed;
394 break; 421 break;
395 case TUNER_PHILIPS_TD1316: 422 case TUNER_PHILIPS_TD1316:
@@ -397,9 +424,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
397 buffer[1] = 0xdc; 424 buffer[1] = 0xdc;
398 buffer[2] = 0x86; 425 buffer[2] = 0x86;
399 buffer[3] = 0xa4; 426 buffer[3] = 0xa4;
400 i2c_master_send(c,buffer,4); 427 i2c_master_send(c, buffer, 4);
401 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 428 if (!dvb_attach(simple_tuner_attach, &t->fe,
402 t->i2c->addr, t->type)) 429 t->i2c->adapter, t->i2c->addr, t->type))
403 goto attach_failed; 430 goto attach_failed;
404 break; 431 break;
405 case TUNER_XC2028: 432 case TUNER_XC2028:
@@ -409,12 +436,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
409 .i2c_addr = t->i2c->addr, 436 .i2c_addr = t->i2c->addr,
410 .callback = t->tuner_callback, 437 .callback = t->tuner_callback,
411 }; 438 };
412 if (!xc2028_attach(&t->fe, &cfg)) 439 if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
413 goto attach_failed; 440 goto attach_failed;
414 break; 441 break;
415 } 442 }
416 case TUNER_TDA9887: 443 case TUNER_TDA9887:
417 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 444 dvb_attach(tda9887_attach,
445 &t->fe, t->i2c->adapter, t->i2c->addr);
418 break; 446 break;
419 case TUNER_XC5000: 447 case TUNER_XC5000:
420 { 448 {
@@ -424,7 +452,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
424 xc5000_cfg.if_khz = 5380; 452 xc5000_cfg.if_khz = 5380;
425 xc5000_cfg.priv = c->adapter->algo_data; 453 xc5000_cfg.priv = c->adapter->algo_data;
426 xc5000_cfg.tuner_callback = t->tuner_callback; 454 xc5000_cfg.tuner_callback = t->tuner_callback;
427 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) 455 if (!dvb_attach(xc5000_attach,
456 &t->fe, t->i2c->adapter, &xc5000_cfg))
428 goto attach_failed; 457 goto attach_failed;
429 458
430 xc_tuner_ops = &t->fe.ops.tuner_ops; 459 xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -433,8 +462,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
433 break; 462 break;
434 } 463 }
435 default: 464 default:
436 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 465 if (!dvb_attach(simple_tuner_attach, &t->fe,
437 t->i2c->addr, t->type)) 466 t->i2c->adapter, t->i2c->addr, t->type))
438 goto attach_failed; 467 goto attach_failed;
439 468
440 break; 469 break;
@@ -442,12 +471,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
442 471
443 if ((NULL == analog_ops->set_params) && 472 if ((NULL == analog_ops->set_params) &&
444 (fe_tuner_ops->set_analog_params)) { 473 (fe_tuner_ops->set_analog_params)) {
474
445 strlcpy(t->i2c->name, fe_tuner_ops->info.name, 475 strlcpy(t->i2c->name, fe_tuner_ops->info.name,
446 sizeof(t->i2c->name)); 476 sizeof(t->i2c->name));
447 477
448 t->fe.analog_demod_priv = t; 478 t->fe.analog_demod_priv = t;
449 memcpy(analog_ops, &tuner_core_ops, 479 memcpy(analog_ops, &tuner_core_ops,
450 sizeof(struct analog_demod_ops)); 480 sizeof(struct analog_demod_ops));
481
451 } else { 482 } else {
452 strlcpy(t->i2c->name, analog_ops->info.name, 483 strlcpy(t->i2c->name, analog_ops->info.name,
453 sizeof(t->i2c->name)); 484 sizeof(t->i2c->name));
@@ -645,8 +676,8 @@ static void tuner_status(struct dvb_frontend *fe)
645{ 676{
646 struct tuner *t = fe->analog_demod_priv; 677 struct tuner *t = fe->analog_demod_priv;
647 unsigned long freq, freq_fraction; 678 unsigned long freq, freq_fraction;
648 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 679 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
649 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 680 struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
650 const char *p; 681 const char *p;
651 682
652 switch (t->mode) { 683 switch (t->mode) {
@@ -730,8 +761,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
730 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 761 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
731 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 762 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
732 763
733 if (tuner_debug>1) 764 if (tuner_debug > 1) {
734 v4l_i2c_print_ioctl(client,cmd); 765 v4l_i2c_print_ioctl(client,cmd);
766 printk("\n");
767 }
735 768
736 switch (cmd) { 769 switch (cmd) {
737 /* --- configuration --- */ 770 /* --- configuration --- */
@@ -1073,7 +1106,8 @@ static void tuner_lookup(struct i2c_adapter *adap,
1073/* During client attach, set_type is called by adapter's attach_inform callback. 1106/* During client attach, set_type is called by adapter's attach_inform callback.
1074 set_type must then be completed by tuner_probe. 1107 set_type must then be completed by tuner_probe.
1075 */ 1108 */
1076static int tuner_probe(struct i2c_client *client) 1109static int tuner_probe(struct i2c_client *client,
1110 const struct i2c_device_id *id)
1077{ 1111{
1078 struct tuner *t; 1112 struct tuner *t;
1079 struct tuner *radio; 1113 struct tuner *radio;
@@ -1111,8 +1145,9 @@ static int tuner_probe(struct i2c_client *client)
1111 if (!no_autodetect) { 1145 if (!no_autodetect) {
1112 switch (client->addr) { 1146 switch (client->addr) {
1113 case 0x10: 1147 case 0x10:
1114 if (tea5761_autodetection(t->i2c->adapter, 1148 if (tuner_symbol_probe(tea5761_autodetection,
1115 t->i2c->addr) >= 0) { 1149 t->i2c->adapter,
1150 t->i2c->addr) >= 0) {
1116 t->type = TUNER_TEA5761; 1151 t->type = TUNER_TEA5761;
1117 t->mode_mask = T_RADIO; 1152 t->mode_mask = T_RADIO;
1118 t->mode = T_STANDBY; 1153 t->mode = T_STANDBY;
@@ -1131,8 +1166,8 @@ static int tuner_probe(struct i2c_client *client)
1131 case 0x4b: 1166 case 0x4b:
1132 /* If chip is not tda8290, don't register. 1167 /* If chip is not tda8290, don't register.
1133 since it can be tda9887*/ 1168 since it can be tda9887*/
1134 if (tda829x_probe(t->i2c->adapter, 1169 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
1135 t->i2c->addr) == 0) { 1170 t->i2c->addr) == 0) {
1136 tuner_dbg("tda829x detected\n"); 1171 tuner_dbg("tda829x detected\n");
1137 } else { 1172 } else {
1138 /* Default is being tda9887 */ 1173 /* Default is being tda9887 */
@@ -1144,7 +1179,8 @@ static int tuner_probe(struct i2c_client *client)
1144 } 1179 }
1145 break; 1180 break;
1146 case 0x60: 1181 case 0x60:
1147 if (tea5767_autodetection(t->i2c->adapter, t->i2c->addr) 1182 if (tuner_symbol_probe(tea5767_autodetection,
1183 t->i2c->adapter, t->i2c->addr)
1148 != EINVAL) { 1184 != EINVAL) {
1149 t->type = TUNER_TEA5767; 1185 t->type = TUNER_TEA5767;
1150 t->mode_mask = T_RADIO; 1186 t->mode_mask = T_RADIO;
@@ -1233,10 +1269,9 @@ static int tuner_legacy_probe(struct i2c_adapter *adap)
1233static int tuner_remove(struct i2c_client *client) 1269static int tuner_remove(struct i2c_client *client)
1234{ 1270{
1235 struct tuner *t = i2c_get_clientdata(client); 1271 struct tuner *t = i2c_get_clientdata(client);
1236 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1237 1272
1238 if (analog_ops->release) 1273 tuner_detach(&t->fe);
1239 analog_ops->release(&t->fe); 1274 t->fe.analog_demod_priv = NULL;
1240 1275
1241 list_del(&t->list); 1276 list_del(&t->list);
1242 kfree(t); 1277 kfree(t);
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index f29a2cd0f2f2..6f9945b04e1f 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1461,7 +1461,7 @@ static struct CHIPDESC chiplist[] = {
1461/* ---------------------------------------------------------------------- */ 1461/* ---------------------------------------------------------------------- */
1462/* i2c registration */ 1462/* i2c registration */
1463 1463
1464static int chip_probe(struct i2c_client *client) 1464static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
1465{ 1465{
1466 struct CHIPSTATE *chip; 1466 struct CHIPSTATE *chip;
1467 struct CHIPDESC *desc; 1467 struct CHIPDESC *desc;
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index bd201397a2ac..93bfd19dec7d 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -195,7 +195,8 @@ static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
195 195
196/* i2c implementation */ 196/* i2c implementation */
197 197
198static int upd64031a_probe(struct i2c_client *client) 198static int upd64031a_probe(struct i2c_client *client,
199 const struct i2c_device_id *id)
199{ 200{
200 struct upd64031a_state *state; 201 struct upd64031a_state *state;
201 int i; 202 int i;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 2d9a88f70c85..9ab712a56ce0 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -172,7 +172,8 @@ static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
172 172
173/* i2c implementation */ 173/* i2c implementation */
174 174
175static int upd64083_probe(struct i2c_client *client) 175static int upd64083_probe(struct i2c_client *client,
176 const struct i2c_device_id *id)
176{ 177{
177 struct upd64083_state *state; 178 struct upd64083_state *state;
178 int i; 179 int i;
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
index fc24ef05b3f3..74e1d3075a20 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/video/usbvision/Kconfig
@@ -1,7 +1,7 @@
1config VIDEO_USBVISION 1config VIDEO_USBVISION
2 tristate "USB video devices based on Nogatech NT1003/1004/1005" 2 tristate "USB video devices based on Nogatech NT1003/1004/1005"
3 depends on I2C && VIDEO_V4L2 3 depends on I2C && VIDEO_V4L2
4 select VIDEO_TUNER 4 select MEDIA_TUNER
5 select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO 5 select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
6 ---help--- 6 ---help---
7 There are more than 50 different USB video devices based on 7 There are more than 50 different USB video devices based on
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/video/usbvision/Makefile
index 9ac92a80c645..338718750945 100644
--- a/drivers/media/video/usbvision/Makefile
+++ b/drivers/media/video/usbvision/Makefile
@@ -3,3 +3,4 @@ usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-
3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o 3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 7cc42c1da457..e9dd996fd5df 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
710/* Helper function for I2C legacy drivers */ 710/* Helper function for I2C legacy drivers */
711 711
712int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver, 712int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
713 const char *name, int (*probe)(struct i2c_client *)) 713 const char *name,
714 int (*probe)(struct i2c_client *, const struct i2c_device_id *))
714{ 715{
715 struct i2c_client *client; 716 struct i2c_client *client;
716 int err; 717 int err;
@@ -724,7 +725,7 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver
724 client->driver = driver; 725 client->driver = driver;
725 strlcpy(client->name, name, sizeof(client->name)); 726 strlcpy(client->name, name, sizeof(client->name));
726 727
727 err = probe(client); 728 err = probe(client, NULL);
728 if (err == 0) { 729 if (err == 0) {
729 i2c_attach_client(client); 730 i2c_attach_client(client);
730 } else { 731 } else {
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 282c81403c97..fac0deba24af 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -121,7 +121,8 @@ static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
121 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 121 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
122 */ 122 */
123 123
124static int vp27smpx_probe(struct i2c_client *client) 124static int vp27smpx_probe(struct i2c_client *client,
125 const struct i2c_device_id *id)
125{ 126{
126 struct vp27smpx_state *state; 127 struct vp27smpx_state *state;
127 128
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 31795b4f8b63..0f8ed8461fba 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -261,7 +261,8 @@ static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
261 261
262/* i2c implementation */ 262/* i2c implementation */
263 263
264static int wm8739_probe(struct i2c_client *client) 264static int wm8739_probe(struct i2c_client *client,
265 const struct i2c_device_id *id)
265{ 266{
266 struct wm8739_state *state; 267 struct wm8739_state *state;
267 268
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 869f9e7946b6..67a409e60c46 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -159,7 +159,8 @@ static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
159 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 159 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
160 */ 160 */
161 161
162static int wm8775_probe(struct i2c_client *client) 162static int wm8775_probe(struct i2c_client *client,
163 const struct i2c_device_id *id)
163{ 164{
164 struct wm8775_state *state; 165 struct wm8775_state *state;
165 166
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 4edc120a6359..633cbba072f0 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -132,8 +132,9 @@ static struct ds1wm_platform_data ds1wm_pdata = {
132 .disable = ds1wm_disable, 132 .disable = ds1wm_disable,
133}; 133};
134 134
135static int ds1wm_device_add(struct device *pasic3_dev, int bus_shift) 135static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
136{ 136{
137 struct device *pasic3_dev = &pasic3_pdev->dev;
137 struct pasic3_data *asic = pasic3_dev->driver_data; 138 struct pasic3_data *asic = pasic3_dev->driver_data;
138 struct platform_device *pdev; 139 struct platform_device *pdev;
139 int ret; 140 int ret;
@@ -144,8 +145,8 @@ static int ds1wm_device_add(struct device *pasic3_dev, int bus_shift)
144 return -ENOMEM; 145 return -ENOMEM;
145 } 146 }
146 147
147 ret = platform_device_add_resources(pdev, pdev->resource, 148 ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
148 pdev->num_resources); 149 pasic3_pdev->num_resources);
149 if (ret < 0) { 150 if (ret < 0) {
150 dev_dbg(pasic3_dev, "failed to add DS1WM resources\n"); 151 dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
151 goto exit_pdev_put; 152 goto exit_pdev_put;
@@ -207,7 +208,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
207 return -ENOMEM; 208 return -ENOMEM;
208 } 209 }
209 210
210 ret = ds1wm_device_add(dev, asic->bus_shift); 211 ret = ds1wm_device_add(pdev, asic->bus_shift);
211 if (ret < 0) 212 if (ret < 0)
212 dev_warn(dev, "failed to register DS1WM\n"); 213 dev_warn(dev, "failed to register DS1WM\n");
213 214
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 95244a7e7353..626ac083f4e0 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -213,9 +213,10 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
213 void __iomem *base = host->base; 213 void __iomem *base = host->base;
214 char *ptr = buffer; 214 char *ptr = buffer;
215 u32 status; 215 u32 status;
216 int host_remain = host->size;
216 217
217 do { 218 do {
218 int count = host->size - (readl(base + MMCIFIFOCNT) << 2); 219 int count = host_remain - (readl(base + MMCIFIFOCNT) << 2);
219 220
220 if (count > remain) 221 if (count > remain)
221 count = remain; 222 count = remain;
@@ -227,6 +228,7 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
227 228
228 ptr += count; 229 ptr += count;
229 remain -= count; 230 remain -= count;
231 host_remain -= count;
230 232
231 if (remain == 0) 233 if (remain == 0)
232 break; 234 break;
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index ba6bd03a015f..a637910b02dd 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -693,11 +693,15 @@ static int __init am79c961_probe(struct platform_device *pdev)
693 * done by the ether bootp loader. 693 * done by the ether bootp loader.
694 */ 694 */
695 dev->base_addr = res->start; 695 dev->base_addr = res->start;
696 dev->irq = platform_get_irq(pdev, 0); 696 ret = platform_get_irq(pdev, 0);
697 697
698 ret = -ENODEV; 698 if (ret < 0) {
699 if (dev->irq < 0) 699 ret = -ENODEV;
700 goto nodev; 700 goto nodev;
701 }
702 dev->irq = ret;
703
704 ret = -ENODEV;
701 if (!request_region(dev->base_addr, 0x18, dev->name)) 705 if (!request_region(dev->base_addr, 0x18, dev->name))
702 goto nodev; 706 goto nodev;
703 707
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 229303ff6a39..a0177fc55e28 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -38,7 +38,7 @@
38#define DRV_VERSION "1.0-ko" 38#define DRV_VERSION "1.0-ko"
39 39
40/* Firmware version */ 40/* Firmware version */
41#define FW_VERSION_MAJOR 5 41#define FW_VERSION_MAJOR 6
42#define FW_VERSION_MINOR 0 42#define FW_VERSION_MINOR 0
43#define FW_VERSION_MICRO 0 43#define FW_VERSION_MICRO 0
44#endif /* __CHELSIO_VERSION_H */ 44#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 6fda0af9d0a6..95e87a2f8896 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -188,7 +188,8 @@ int mlx4_cq_resize(struct mlx4_dev *dev, struct mlx4_cq *cq,
188EXPORT_SYMBOL_GPL(mlx4_cq_resize); 188EXPORT_SYMBOL_GPL(mlx4_cq_resize);
189 189
190int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, 190int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
191 struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq) 191 struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq,
192 int collapsed)
192{ 193{
193 struct mlx4_priv *priv = mlx4_priv(dev); 194 struct mlx4_priv *priv = mlx4_priv(dev);
194 struct mlx4_cq_table *cq_table = &priv->cq_table; 195 struct mlx4_cq_table *cq_table = &priv->cq_table;
@@ -224,6 +225,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
224 cq_context = mailbox->buf; 225 cq_context = mailbox->buf;
225 memset(cq_context, 0, sizeof *cq_context); 226 memset(cq_context, 0, sizeof *cq_context);
226 227
228 cq_context->flags = cpu_to_be32(!!collapsed << 18);
227 cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index); 229 cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
228 cq_context->comp_eqn = priv->eq_table.eq[MLX4_EQ_COMP].eqn; 230 cq_context->comp_eqn = priv->eq_table.eq[MLX4_EQ_COMP].eqn;
229 cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; 231 cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index 79b317b88c86..cb46446b2691 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -607,15 +607,9 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_enable);
607void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr, 607void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr,
608 u32 *lkey, u32 *rkey) 608 u32 *lkey, u32 *rkey)
609{ 609{
610 u32 key;
611
612 if (!fmr->maps) 610 if (!fmr->maps)
613 return; 611 return;
614 612
615 key = key_to_hw_index(fmr->mr.key);
616 key &= dev->caps.num_mpts - 1;
617 *lkey = *rkey = fmr->mr.key = hw_index_to_key(key);
618
619 fmr->maps = 0; 613 fmr->maps = 0;
620 614
621 *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW; 615 *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW;
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index f389a28720d2..bbf97e65202a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -99,45 +99,38 @@ struct ds1307 {
99}; 99};
100 100
101struct chip_desc { 101struct chip_desc {
102 char name[9];
103 unsigned nvram56:1; 102 unsigned nvram56:1;
104 unsigned alarm:1; 103 unsigned alarm:1;
105 enum ds_type type;
106}; 104};
107 105
108static const struct chip_desc chips[] = { { 106static const struct chip_desc chips[] = {
109 .name = "ds1307", 107[ds_1307] = {
110 .type = ds_1307,
111 .nvram56 = 1, 108 .nvram56 = 1,
112}, { 109},
113 .name = "ds1337", 110[ds_1337] = {
114 .type = ds_1337,
115 .alarm = 1, 111 .alarm = 1,
116}, { 112},
117 .name = "ds1338", 113[ds_1338] = {
118 .type = ds_1338,
119 .nvram56 = 1, 114 .nvram56 = 1,
120}, { 115},
121 .name = "ds1339", 116[ds_1339] = {
122 .type = ds_1339,
123 .alarm = 1, 117 .alarm = 1,
124}, { 118},
125 .name = "ds1340", 119[ds_1340] = {
126 .type = ds_1340, 120},
127}, { 121[m41t00] = {
128 .name = "m41t00",
129 .type = m41t00,
130}, }; 122}, };
131 123
132static inline const struct chip_desc *find_chip(const char *s) 124static const struct i2c_device_id ds1307_id[] = {
133{ 125 { "ds1307", ds_1307 },
134 unsigned i; 126 { "ds1337", ds_1337 },
135 127 { "ds1338", ds_1338 },
136 for (i = 0; i < ARRAY_SIZE(chips); i++) 128 { "ds1339", ds_1339 },
137 if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0) 129 { "ds1340", ds_1340 },
138 return &chips[i]; 130 { "m41t00", m41t00 },
139 return NULL; 131 { }
140} 132};
133MODULE_DEVICE_TABLE(i2c, ds1307_id);
141 134
142static int ds1307_get_time(struct device *dev, struct rtc_time *t) 135static int ds1307_get_time(struct device *dev, struct rtc_time *t)
143{ 136{
@@ -326,21 +319,15 @@ static struct bin_attribute nvram = {
326 319
327static struct i2c_driver ds1307_driver; 320static struct i2c_driver ds1307_driver;
328 321
329static int __devinit ds1307_probe(struct i2c_client *client) 322static int __devinit ds1307_probe(struct i2c_client *client,
323 const struct i2c_device_id *id)
330{ 324{
331 struct ds1307 *ds1307; 325 struct ds1307 *ds1307;
332 int err = -ENODEV; 326 int err = -ENODEV;
333 int tmp; 327 int tmp;
334 const struct chip_desc *chip; 328 const struct chip_desc *chip = &chips[id->driver_data];
335 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 329 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
336 330
337 chip = find_chip(client->name);
338 if (!chip) {
339 dev_err(&client->dev, "unknown chip type '%s'\n",
340 client->name);
341 return -ENODEV;
342 }
343
344 if (!i2c_check_functionality(adapter, 331 if (!i2c_check_functionality(adapter,
345 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 332 I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
346 return -EIO; 333 return -EIO;
@@ -361,7 +348,7 @@ static int __devinit ds1307_probe(struct i2c_client *client)
361 ds1307->msg[1].len = sizeof(ds1307->regs); 348 ds1307->msg[1].len = sizeof(ds1307->regs);
362 ds1307->msg[1].buf = ds1307->regs; 349 ds1307->msg[1].buf = ds1307->regs;
363 350
364 ds1307->type = chip->type; 351 ds1307->type = id->driver_data;
365 352
366 switch (ds1307->type) { 353 switch (ds1307->type) {
367 case ds_1337: 354 case ds_1337:
@@ -550,6 +537,7 @@ static struct i2c_driver ds1307_driver = {
550 }, 537 },
551 .probe = ds1307_probe, 538 .probe = ds1307_probe,
552 .remove = __devexit_p(ds1307_remove), 539 .remove = __devexit_p(ds1307_remove),
540 .id_table = ds1307_id,
553}; 541};
554 542
555static int __init ds1307_init(void) 543static int __init ds1307_init(void)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda186befc..fa2d2f8b3f4d 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -41,6 +41,12 @@
41#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */ 41#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
42#define DS1374_REG_TCR 0x09 /* Trickle Charge */ 42#define DS1374_REG_TCR 0x09 /* Trickle Charge */
43 43
44static const struct i2c_device_id ds1374_id[] = {
45 { "rtc-ds1374", 0 },
46 { }
47};
48MODULE_DEVICE_TABLE(i2c, ds1374_id);
49
44struct ds1374 { 50struct ds1374 {
45 struct i2c_client *client; 51 struct i2c_client *client;
46 struct rtc_device *rtc; 52 struct rtc_device *rtc;
@@ -355,7 +361,8 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
355 .ioctl = ds1374_ioctl, 361 .ioctl = ds1374_ioctl,
356}; 362};
357 363
358static int ds1374_probe(struct i2c_client *client) 364static int ds1374_probe(struct i2c_client *client,
365 const struct i2c_device_id *id)
359{ 366{
360 struct ds1374 *ds1374; 367 struct ds1374 *ds1374;
361 int ret; 368 int ret;
@@ -429,6 +436,7 @@ static struct i2c_driver ds1374_driver = {
429 }, 436 },
430 .probe = ds1374_probe, 437 .probe = ds1374_probe,
431 .remove = __devexit_p(ds1374_remove), 438 .remove = __devexit_p(ds1374_remove),
439 .id_table = ds1374_id,
432}; 440};
433 441
434static int __init ds1374_init(void) 442static int __init ds1374_init(void)
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index fb15e3fb4ce2..fbb90b1e4098 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -490,7 +490,7 @@ isl1208_sysfs_unregister(struct device *dev)
490} 490}
491 491
492static int 492static int
493isl1208_probe(struct i2c_client *client) 493isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
494{ 494{
495 int rc = 0; 495 int rc = 0;
496 struct rtc_device *rtc; 496 struct rtc_device *rtc;
@@ -545,12 +545,19 @@ isl1208_remove(struct i2c_client *client)
545 return 0; 545 return 0;
546} 546}
547 547
548static const struct i2c_device_id isl1208_id[] = {
549 { "isl1208", 0 },
550 { }
551};
552MODULE_DEVICE_TABLE(i2c, isl1208_id);
553
548static struct i2c_driver isl1208_driver = { 554static struct i2c_driver isl1208_driver = {
549 .driver = { 555 .driver = {
550 .name = "rtc-isl1208", 556 .name = "rtc-isl1208",
551 }, 557 },
552 .probe = isl1208_probe, 558 .probe = isl1208_probe,
553 .remove = isl1208_remove, 559 .remove = isl1208_remove,
560 .id_table = isl1208_id,
554}; 561};
555 562
556static int __init 563static int __init
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 1cb33cac1237..316bfaa80872 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -60,48 +60,21 @@
60 60
61#define DRV_VERSION "0.05" 61#define DRV_VERSION "0.05"
62 62
63struct m41t80_chip_info { 63static const struct i2c_device_id m41t80_id[] = {
64 const char *name; 64 { "m41t80", 0 },
65 u8 features; 65 { "m41t81", M41T80_FEATURE_HT },
66}; 66 { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
67 67 { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
68static const struct m41t80_chip_info m41t80_chip_info_tbl[] = { 68 { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
69 { 69 { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
70 .name = "m41t80", 70 { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
71 .features = 0, 71 { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
72 }, 72 { }
73 {
74 .name = "m41t81",
75 .features = M41T80_FEATURE_HT,
76 },
77 {
78 .name = "m41t81s",
79 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
80 },
81 {
82 .name = "m41t82",
83 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
84 },
85 {
86 .name = "m41t83",
87 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
88 },
89 {
90 .name = "m41st84",
91 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
92 },
93 {
94 .name = "m41st85",
95 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
96 },
97 {
98 .name = "m41st87",
99 .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
100 },
101}; 73};
74MODULE_DEVICE_TABLE(i2c, m41t80_id);
102 75
103struct m41t80_data { 76struct m41t80_data {
104 const struct m41t80_chip_info *chip; 77 u8 features;
105 struct rtc_device *rtc; 78 struct rtc_device *rtc;
106}; 79};
107 80
@@ -208,7 +181,7 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
208 struct m41t80_data *clientdata = i2c_get_clientdata(client); 181 struct m41t80_data *clientdata = i2c_get_clientdata(client);
209 u8 reg; 182 u8 reg;
210 183
211 if (clientdata->chip->features & M41T80_FEATURE_BL) { 184 if (clientdata->features & M41T80_FEATURE_BL) {
212 reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); 185 reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
213 seq_printf(seq, "battery\t\t: %s\n", 186 seq_printf(seq, "battery\t\t: %s\n",
214 (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok"); 187 (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
@@ -756,12 +729,12 @@ static struct notifier_block wdt_notifier = {
756 * 729 *
757 ***************************************************************************** 730 *****************************************************************************
758 */ 731 */
759static int m41t80_probe(struct i2c_client *client) 732static int m41t80_probe(struct i2c_client *client,
733 const struct i2c_device_id *id)
760{ 734{
761 int i, rc = 0; 735 int rc = 0;
762 struct rtc_device *rtc = NULL; 736 struct rtc_device *rtc = NULL;
763 struct rtc_time tm; 737 struct rtc_time tm;
764 const struct m41t80_chip_info *chip;
765 struct m41t80_data *clientdata = NULL; 738 struct m41t80_data *clientdata = NULL;
766 739
767 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C 740 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
@@ -773,19 +746,6 @@ static int m41t80_probe(struct i2c_client *client)
773 dev_info(&client->dev, 746 dev_info(&client->dev,
774 "chip found, driver version " DRV_VERSION "\n"); 747 "chip found, driver version " DRV_VERSION "\n");
775 748
776 chip = NULL;
777 for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
778 if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
779 chip = &m41t80_chip_info_tbl[i];
780 break;
781 }
782 }
783 if (!chip) {
784 dev_err(&client->dev, "%s is not supported\n", client->name);
785 rc = -ENODEV;
786 goto exit;
787 }
788
789 clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL); 749 clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
790 if (!clientdata) { 750 if (!clientdata) {
791 rc = -ENOMEM; 751 rc = -ENOMEM;
@@ -801,7 +761,7 @@ static int m41t80_probe(struct i2c_client *client)
801 } 761 }
802 762
803 clientdata->rtc = rtc; 763 clientdata->rtc = rtc;
804 clientdata->chip = chip; 764 clientdata->features = id->driver_data;
805 i2c_set_clientdata(client, clientdata); 765 i2c_set_clientdata(client, clientdata);
806 766
807 /* Make sure HT (Halt Update) bit is cleared */ 767 /* Make sure HT (Halt Update) bit is cleared */
@@ -810,7 +770,7 @@ static int m41t80_probe(struct i2c_client *client)
810 goto ht_err; 770 goto ht_err;
811 771
812 if (rc & M41T80_ALHOUR_HT) { 772 if (rc & M41T80_ALHOUR_HT) {
813 if (chip->features & M41T80_FEATURE_HT) { 773 if (clientdata->features & M41T80_FEATURE_HT) {
814 m41t80_get_datetime(client, &tm); 774 m41t80_get_datetime(client, &tm);
815 dev_info(&client->dev, "HT bit was set!\n"); 775 dev_info(&client->dev, "HT bit was set!\n");
816 dev_info(&client->dev, 776 dev_info(&client->dev,
@@ -842,7 +802,7 @@ static int m41t80_probe(struct i2c_client *client)
842 goto exit; 802 goto exit;
843 803
844#ifdef CONFIG_RTC_DRV_M41T80_WDT 804#ifdef CONFIG_RTC_DRV_M41T80_WDT
845 if (chip->features & M41T80_FEATURE_HT) { 805 if (clientdata->features & M41T80_FEATURE_HT) {
846 rc = misc_register(&wdt_dev); 806 rc = misc_register(&wdt_dev);
847 if (rc) 807 if (rc)
848 goto exit; 808 goto exit;
@@ -878,7 +838,7 @@ static int m41t80_remove(struct i2c_client *client)
878 struct rtc_device *rtc = clientdata->rtc; 838 struct rtc_device *rtc = clientdata->rtc;
879 839
880#ifdef CONFIG_RTC_DRV_M41T80_WDT 840#ifdef CONFIG_RTC_DRV_M41T80_WDT
881 if (clientdata->chip->features & M41T80_FEATURE_HT) { 841 if (clientdata->features & M41T80_FEATURE_HT) {
882 misc_deregister(&wdt_dev); 842 misc_deregister(&wdt_dev);
883 unregister_reboot_notifier(&wdt_notifier); 843 unregister_reboot_notifier(&wdt_notifier);
884 } 844 }
@@ -896,6 +856,7 @@ static struct i2c_driver m41t80_driver = {
896 }, 856 },
897 .probe = m41t80_probe, 857 .probe = m41t80_probe,
898 .remove = m41t80_remove, 858 .remove = m41t80_remove,
859 .id_table = m41t80_id,
899}; 860};
900 861
901static int __init m41t80_rtc_init(void) 862static int __init m41t80_rtc_init(void)
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index a41681d26eba..0fc4c3630780 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -246,7 +246,8 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
246 .set_time = pcf8563_rtc_set_time, 246 .set_time = pcf8563_rtc_set_time,
247}; 247};
248 248
249static int pcf8563_probe(struct i2c_client *client) 249static int pcf8563_probe(struct i2c_client *client,
250 const struct i2c_device_id *id)
250{ 251{
251 struct pcf8563 *pcf8563; 252 struct pcf8563 *pcf8563;
252 253
@@ -299,12 +300,19 @@ static int pcf8563_remove(struct i2c_client *client)
299 return 0; 300 return 0;
300} 301}
301 302
303static const struct i2c_device_id pcf8563_id[] = {
304 { "pcf8563", 0 },
305 { }
306};
307MODULE_DEVICE_TABLE(i2c, pcf8563_id);
308
302static struct i2c_driver pcf8563_driver = { 309static struct i2c_driver pcf8563_driver = {
303 .driver = { 310 .driver = {
304 .name = "rtc-pcf8563", 311 .name = "rtc-pcf8563",
305 }, 312 },
306 .probe = pcf8563_probe, 313 .probe = pcf8563_probe,
307 .remove = pcf8563_remove, 314 .remove = pcf8563_remove,
315 .id_table = pcf8563_id,
308}; 316};
309 317
310static int __init pcf8563_init(void) 318static int __init pcf8563_init(void)
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 7e63074708eb..56caf6b2c3e5 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -69,6 +69,15 @@ enum rtc_type {
69 rtc_rv5c387a, 69 rtc_rv5c387a,
70}; 70};
71 71
72static const struct i2c_device_id rs5c372_id[] = {
73 { "rs5c372a", rtc_rs5c372a },
74 { "rs5c372b", rtc_rs5c372b },
75 { "rv5c386", rtc_rv5c386 },
76 { "rv5c387a", rtc_rv5c387a },
77 { }
78};
79MODULE_DEVICE_TABLE(i2c, rs5c372_id);
80
72/* REVISIT: this assumes that: 81/* REVISIT: this assumes that:
73 * - we're in the 21st century, so it's safe to ignore the century 82 * - we're in the 21st century, so it's safe to ignore the century
74 * bit for rv5c38[67] (REG_MONTH bit 7); 83 * bit for rv5c38[67] (REG_MONTH bit 7);
@@ -494,7 +503,8 @@ static void rs5c_sysfs_unregister(struct device *dev)
494 503
495static struct i2c_driver rs5c372_driver; 504static struct i2c_driver rs5c372_driver;
496 505
497static int rs5c372_probe(struct i2c_client *client) 506static int rs5c372_probe(struct i2c_client *client,
507 const struct i2c_device_id *id)
498{ 508{
499 int err = 0; 509 int err = 0;
500 struct rs5c372 *rs5c372; 510 struct rs5c372 *rs5c372;
@@ -514,6 +524,7 @@ static int rs5c372_probe(struct i2c_client *client)
514 524
515 rs5c372->client = client; 525 rs5c372->client = client;
516 i2c_set_clientdata(client, rs5c372); 526 i2c_set_clientdata(client, rs5c372);
527 rs5c372->type = id->driver_data;
517 528
518 /* we read registers 0x0f then 0x00-0x0f; skip the first one */ 529 /* we read registers 0x0f then 0x00-0x0f; skip the first one */
519 rs5c372->regs = &rs5c372->buf[1]; 530 rs5c372->regs = &rs5c372->buf[1];
@@ -522,19 +533,6 @@ static int rs5c372_probe(struct i2c_client *client)
522 if (err < 0) 533 if (err < 0)
523 goto exit_kfree; 534 goto exit_kfree;
524 535
525 if (strcmp(client->name, "rs5c372a") == 0)
526 rs5c372->type = rtc_rs5c372a;
527 else if (strcmp(client->name, "rs5c372b") == 0)
528 rs5c372->type = rtc_rs5c372b;
529 else if (strcmp(client->name, "rv5c386") == 0)
530 rs5c372->type = rtc_rv5c386;
531 else if (strcmp(client->name, "rv5c387a") == 0)
532 rs5c372->type = rtc_rv5c387a;
533 else {
534 rs5c372->type = rtc_rs5c372b;
535 dev_warn(&client->dev, "assuming rs5c372b\n");
536 }
537
538 /* clock may be set for am/pm or 24 hr time */ 536 /* clock may be set for am/pm or 24 hr time */
539 switch (rs5c372->type) { 537 switch (rs5c372->type) {
540 case rtc_rs5c372a: 538 case rtc_rs5c372a:
@@ -651,6 +649,7 @@ static struct i2c_driver rs5c372_driver = {
651 }, 649 },
652 .probe = rs5c372_probe, 650 .probe = rs5c372_probe,
653 .remove = rs5c372_remove, 651 .remove = rs5c372_remove,
652 .id_table = rs5c372_id,
654}; 653};
655 654
656static __init int rs5c372_init(void) 655static __init int rs5c372_init(void)
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index e8abc90c32c5..29f47bacfc77 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -34,6 +34,12 @@
34#define S35390A_FLAG_RESET 0x80 34#define S35390A_FLAG_RESET 0x80
35#define S35390A_FLAG_TEST 0x01 35#define S35390A_FLAG_TEST 0x01
36 36
37static const struct i2c_device_id s35390a_id[] = {
38 { "s35390a", 0 },
39 { }
40};
41MODULE_DEVICE_TABLE(i2c, s35390a_id);
42
37struct s35390a { 43struct s35390a {
38 struct i2c_client *client[8]; 44 struct i2c_client *client[8];
39 struct rtc_device *rtc; 45 struct rtc_device *rtc;
@@ -195,7 +201,8 @@ static const struct rtc_class_ops s35390a_rtc_ops = {
195 201
196static struct i2c_driver s35390a_driver; 202static struct i2c_driver s35390a_driver;
197 203
198static int s35390a_probe(struct i2c_client *client) 204static int s35390a_probe(struct i2c_client *client,
205 const struct i2c_device_id *id)
199{ 206{
200 int err; 207 int err;
201 unsigned int i; 208 unsigned int i;
@@ -296,6 +303,7 @@ static struct i2c_driver s35390a_driver = {
296 }, 303 },
297 .probe = s35390a_probe, 304 .probe = s35390a_probe,
298 .remove = s35390a_remove, 305 .remove = s35390a_remove,
306 .id_table = s35390a_id,
299}; 307};
300 308
301static int __init s35390a_rtc_init(void) 309static int __init s35390a_rtc_init(void)
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 095282f63523..eaf55945f21b 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -494,7 +494,8 @@ static void x1205_sysfs_unregister(struct device *dev)
494} 494}
495 495
496 496
497static int x1205_probe(struct i2c_client *client) 497static int x1205_probe(struct i2c_client *client,
498 const struct i2c_device_id *id)
498{ 499{
499 int err = 0; 500 int err = 0;
500 unsigned char sr; 501 unsigned char sr;
@@ -552,12 +553,19 @@ static int x1205_remove(struct i2c_client *client)
552 return 0; 553 return 0;
553} 554}
554 555
556static const struct i2c_device_id x1205_id[] = {
557 { "x1205", 0 },
558 { }
559};
560MODULE_DEVICE_TABLE(i2c, x1205_id);
561
555static struct i2c_driver x1205_driver = { 562static struct i2c_driver x1205_driver = {
556 .driver = { 563 .driver = {
557 .name = "rtc-x1205", 564 .name = "rtc-x1205",
558 }, 565 },
559 .probe = x1205_probe, 566 .probe = x1205_probe,
560 .remove = x1205_remove, 567 .remove = x1205_remove,
568 .id_table = x1205_id,
561}; 569};
562 570
563static int __init x1205_init(void) 571static int __init x1205_init(void)
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 4ffa2585429a..da5a02cb4f63 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1022,6 +1022,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1022 struct uart_port *port = &ourport->port; 1022 struct uart_port *port = &ourport->port;
1023 struct s3c2410_uartcfg *cfg; 1023 struct s3c2410_uartcfg *cfg;
1024 struct resource *res; 1024 struct resource *res;
1025 int ret;
1025 1026
1026 dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev); 1027 dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);
1027 1028
@@ -1064,9 +1065,11 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1064 1065
1065 port->mapbase = res->start; 1066 port->mapbase = res->start;
1066 port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); 1067 port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
1067 port->irq = platform_get_irq(platdev, 0); 1068 ret = platform_get_irq(platdev, 0);
1068 if (port->irq < 0) 1069 if (ret < 0)
1069 port->irq = 0; 1070 port->irq = 0;
1071 else
1072 port->irq = ret;
1070 1073
1071 ourport->clk = clk_get(&platdev->dev, "uart"); 1074 ourport->clk = clk_get(&platdev->dev, "uart");
1072 1075