aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-11-10 09:29:07 -0500
committerJames Bottomley <jejb@titanic.(none)>2005-11-10 09:29:07 -0500
commit8a87a0b6313109d2fea87b1271d497c954ce2ca8 (patch)
tree1b7ae51ff681e27118590e9cab4bf0ce38f5d80e /drivers
parente6a04466ba965875a6132700fabb2f2c0249c41a (diff)
parent3b44f137b9a846c5452d9e6e1271b79b1dbcc942 (diff)
Merge by hand (whitespace conflicts in libata.h)
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_idle.c37
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/floppy.c9
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/bluetooth/bpa10x.c4
-rw-r--r--drivers/bluetooth/hci_usb.c7
-rw-r--r--drivers/char/agp/backend.c9
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/agp/i460-agp.c17
-rw-r--r--drivers/char/agp/intel-agp.c5
-rw-r--r--drivers/char/drm/ati_pcigart.c4
-rw-r--r--drivers/char/ip2.c1
-rw-r--r--drivers/char/mwave/tp3780i.c1
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/viocons.c1
-rw-r--r--drivers/char/viotape.c1
-rw-r--r--drivers/cpufreq/cpufreq.c24
-rw-r--r--drivers/firmware/dell_rbu.c1
-rw-r--r--drivers/hwmon/w83627hf.c16
-rw-r--r--drivers/i2c/busses/i2c-viapro.c27
-rw-r--r--drivers/i2c/chips/ds1337.c4
-rw-r--r--drivers/ide/Kconfig9
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-taskfile.c2
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/cs5535.c305
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/isdn/divert/divert_init.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c1
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/icn/icn.h1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/md/bitmap.c34
-rw-r--r--drivers/md/md.c636
-rw-r--r--drivers/md/multipath.c31
-rw-r--r--drivers/md/raid1.c216
-rw-r--r--drivers/md/raid10.c63
-rw-r--r--drivers/md/raid5.c261
-rw-r--r--drivers/md/raid6main.c40
-rw-r--r--drivers/media/common/ir-common.c4
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c54
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c136
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h5
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c114
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h1
-rw-r--r--drivers/media/dvb/dvb-core/demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c54
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c26
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h4
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1205
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h61
-rw-r--r--drivers/media/dvb/frontends/or51132.c7
-rw-r--r--drivers/media/dvb/frontends/or51211.c8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c100
-rw-r--r--drivers/media/dvb/frontends/stv0299.h3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c21
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c120
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c5
-rw-r--r--drivers/media/video/Kconfig63
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/bt832.c89
-rw-r--r--drivers/media/video/bt832.h4
-rw-r--r--drivers/media/video/bttv-cards.c5307
-rw-r--r--drivers/media/video/bttv-driver.c379
-rw-r--r--drivers/media/video/bttv-gpio.c2
-rw-r--r--drivers/media/video/bttv-i2c.c61
-rw-r--r--drivers/media/video/bttv-if.c4
-rw-r--r--drivers/media/video/bttv-risc.c110
-rw-r--r--drivers/media/video/bttv.h282
-rw-r--r--drivers/media/video/bttvp.h14
-rw-r--r--drivers/media/video/cs53l32a.c240
-rw-r--r--drivers/media/video/cx88/Kconfig91
-rw-r--r--drivers/media/video/cx88/Makefile6
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c677
-rw-r--r--drivers/media/video/cx88/cx88-cards.c474
-rw-r--r--drivers/media/video/cx88/cx88-core.c55
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c59
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c22
-rw-r--r--drivers/media/video/cx88/cx88-input.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c25
-rw-r--r--drivers/media/video/cx88/cx88-reg.h12
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1184
-rw-r--r--drivers/media/video/cx88/cx88-video.c38
-rw-r--r--drivers/media/video/cx88/cx88.h55
-rw-r--r--drivers/media/video/em28xx/Kconfig12
-rw-r--r--drivers/media/video/em28xx/Makefile6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c292
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c817
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c586
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c184
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1933
-rw-r--r--drivers/media/video/em28xx/em28xx.h513
-rw-r--r--drivers/media/video/ir-kbd-gpio.c99
-rw-r--r--drivers/media/video/ir-kbd-i2c.c166
-rw-r--r--drivers/media/video/msp3400.c962
-rw-r--r--drivers/media/video/mt20xx.c206
-rw-r--r--drivers/media/video/saa6588.c11
-rw-r--r--drivers/media/video/saa711x.c593
-rw-r--r--drivers/media/video/saa7134/Kconfig68
-rw-r--r--drivers/media/video/saa7134/Makefile9
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c187
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1047
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c587
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c370
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c403
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c375
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h27
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c185
-rw-r--r--drivers/media/video/saa7134/saa7134.h62
-rw-r--r--drivers/media/video/tda7432.c17
-rw-r--r--drivers/media/video/tda8290.c681
-rw-r--r--drivers/media/video/tda9875.c57
-rw-r--r--drivers/media/video/tda9887.c163
-rw-r--r--drivers/media/video/tea5767.c8
-rw-r--r--drivers/media/video/tuner-core.c74
-rw-r--r--drivers/media/video/tuner-simple.c143
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c458
-rw-r--r--drivers/media/video/tvmixer.c54
-rw-r--r--drivers/media/video/tvp5150.c829
-rw-r--r--drivers/media/video/tvp5150_reg.h173
-rw-r--r--drivers/media/video/v4l1-compat.c6
-rw-r--r--drivers/media/video/video-buf.c18
-rw-r--r--drivers/media/video/wm8775.c254
-rw-r--r--drivers/media/video/zr36016.c1
-rw-r--r--drivers/media/video/zr36050.c1
-rw-r--r--drivers/media/video/zr36060.c1
-rw-r--r--drivers/message/fusion/mptbase.c7
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptctl.h1
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c1
-rw-r--r--drivers/misc/ibmasm/ibmasm.h1
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c1
-rw-r--r--drivers/mtd/devices/pmc551.c1
-rw-r--r--drivers/mtd/maps/ebony.c1
-rw-r--r--drivers/mtd/maps/ocotea.c1
-rw-r--r--drivers/mtd/maps/walnut.c1
-rw-r--r--drivers/mtd/nand/au1550nd.c1
-rw-r--r--drivers/mtd/nand/autcpu12.c1
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/rfd_ftl.c1
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/b44.c178
-rw-r--r--drivers/net/b44.h75
-rw-r--r--drivers/net/bonding/bond_main.c32
-rw-r--r--drivers/net/bonding/bonding.h7
-rw-r--r--drivers/net/cassini.c1
-rw-r--r--drivers/net/cris/eth_v10.c149
-rw-r--r--drivers/net/dgrs.c16
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/e100.c6
-rw-r--r--drivers/net/fs_enet/fs_enet.h1
-rw-r--r--drivers/net/gianfar.c1
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.c1
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/ibmveth.c1
-rw-r--r--drivers/net/ioc3-eth.c42
-rw-r--r--drivers/net/irda/donauboe.c14
-rw-r--r--drivers/net/iseries_veth.c1
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mv643xx_eth.h1
-rw-r--r--drivers/net/ns83820.c13
-rw-r--r--drivers/net/ppp_async.c17
-rw-r--r--drivers/net/ppp_generic.c88
-rw-r--r--drivers/net/ppp_mppe.c724
-rw-r--r--drivers/net/ppp_mppe.h86
-rw-r--r--drivers/net/s2io.c44
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h3
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/sk_mca.h2
-rw-r--r--drivers/net/skge.c267
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/via-velocity.c1
-rw-r--r--drivers/net/wireless/airo.c36
-rw-r--r--drivers/net/wireless/airo_cs.c6
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c6
-rw-r--r--drivers/net/wireless/hostap/hostap.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2100.c2858
-rw-r--r--drivers/net/wireless/ipw2100.h170
-rw-r--r--drivers/net/wireless/ipw2200.c6610
-rw-r--r--drivers/net/wireless/ipw2200.h575
-rw-r--r--drivers/net/wireless/orinoco.h1
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c13
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h1
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c11
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c1
-rw-r--r--drivers/net/wireless/wavelan_cs.c3
-rw-r--r--drivers/net/wireless/wl3501_cs.c3
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c140
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/crypto/z90main.c1
-rw-r--r--drivers/s390/net/claw.c1
-rw-r--r--drivers/s390/net/fsm.h6
-rw-r--r--drivers/s390/s390mach.h2
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/openprom.c3
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/ahci.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/amiga7xx.c1
-rw-r--r--drivers/scsi/ata_piix.c1
-rw-r--r--drivers/scsi/bvme6000.c1
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/ibmmca.c6
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/libata-core.c11
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/megaraid/mega_common.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/mvme16x.c1
-rw-r--r--drivers/scsi/nsp32.h1
-rw-r--r--drivers/scsi/pci2000.h3
-rw-r--r--drivers/scsi/pdc_adma.c1
-rw-r--r--drivers/scsi/sata_mv.c2
-rw-r--r--drivers/scsi/sata_nv.c1
-rw-r--r--drivers/scsi/sata_promise.c2
-rw-r--r--drivers/scsi/sata_qstor.c1
-rw-r--r--drivers/scsi/sata_sil.c1
-rw-r--r--drivers/scsi/sata_sil24.c2
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c1
-rw-r--r--drivers/scsi/sata_sx4.c2
-rw-r--r--drivers/scsi/sata_uli.c1
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c1
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/sg.c4
-rw-r--r--drivers/scsi/sgiwd93.c1
-rw-r--r--drivers/scsi/wd33c93.c1
-rw-r--r--drivers/telephony/ixj.h1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/host/hc_crisv10.c1
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/pwc/pwc.h2
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/video/Kconfig32
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/cfbimgblt.c4
-rw-r--r--drivers/video/console/Kconfig10
-rw-r--r--drivers/video/console/Makefile4
-rw-r--r--drivers/video/console/bitblit.c46
-rw-r--r--drivers/video/console/fbcon.c375
-rw-r--r--drivers/video/console/fbcon.h62
-rw-r--r--drivers/video/console/fbcon_ccw.c428
-rw-r--r--drivers/video/console/fbcon_cw.c412
-rw-r--r--drivers/video/console/fbcon_rotate.c117
-rw-r--r--drivers/video/console/fbcon_rotate.h105
-rw-r--r--drivers/video/console/fbcon_ud.c454
-rw-r--r--drivers/video/console/tileblit.c13
-rw-r--r--drivers/video/fbmem.c299
-rw-r--r--drivers/video/fbsysfs.c67
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c1
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/savage/savagefb_driver.c10
-rw-r--r--drivers/video/vga16fb.c169
-rw-r--r--drivers/video/vgastate.c5
335 files changed, 31203 insertions, 10090 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 161db4acfb91..573b6a97bb1f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -167,6 +167,19 @@ acpi_processor_power_activate(struct acpi_processor *pr,
167 return; 167 return;
168} 168}
169 169
170static void acpi_safe_halt(void)
171{
172 int polling = test_thread_flag(TIF_POLLING_NRFLAG);
173 if (polling) {
174 clear_thread_flag(TIF_POLLING_NRFLAG);
175 smp_mb__after_clear_bit();
176 }
177 if (!need_resched())
178 safe_halt();
179 if (polling)
180 set_thread_flag(TIF_POLLING_NRFLAG);
181}
182
170static atomic_t c3_cpu_count; 183static atomic_t c3_cpu_count;
171 184
172static void acpi_processor_idle(void) 185static void acpi_processor_idle(void)
@@ -177,7 +190,7 @@ static void acpi_processor_idle(void)
177 int sleep_ticks = 0; 190 int sleep_ticks = 0;
178 u32 t1, t2 = 0; 191 u32 t1, t2 = 0;
179 192
180 pr = processors[raw_smp_processor_id()]; 193 pr = processors[smp_processor_id()];
181 if (!pr) 194 if (!pr)
182 return; 195 return;
183 196
@@ -197,8 +210,13 @@ static void acpi_processor_idle(void)
197 } 210 }
198 211
199 cx = pr->power.state; 212 cx = pr->power.state;
200 if (!cx) 213 if (!cx) {
201 goto easy_out; 214 if (pm_idle_save)
215 pm_idle_save();
216 else
217 acpi_safe_halt();
218 return;
219 }
202 220
203 /* 221 /*
204 * Check BM Activity 222 * Check BM Activity
@@ -278,7 +296,8 @@ static void acpi_processor_idle(void)
278 if (pm_idle_save) 296 if (pm_idle_save)
279 pm_idle_save(); 297 pm_idle_save();
280 else 298 else
281 safe_halt(); 299 acpi_safe_halt();
300
282 /* 301 /*
283 * TBD: Can't get time duration while in C1, as resumes 302 * TBD: Can't get time duration while in C1, as resumes
284 * go to an ISR rather than here. Need to instrument 303 * go to an ISR rather than here. Need to instrument
@@ -414,16 +433,6 @@ static void acpi_processor_idle(void)
414 */ 433 */
415 if (next_state != pr->power.state) 434 if (next_state != pr->power.state)
416 acpi_processor_power_activate(pr, next_state); 435 acpi_processor_power_activate(pr, next_state);
417
418 return;
419
420 easy_out:
421 /* do C1 instead of busy loop */
422 if (pm_idle_save)
423 pm_idle_save();
424 else
425 safe_halt();
426 return;
427} 436}
428 437
429static int acpi_processor_set_power_policy(struct acpi_processor *pr) 438static int acpi_processor_set_power_policy(struct acpi_processor *pr)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 1468e8cf712d..0acbfff8ad28 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1816,7 +1816,6 @@ out_blkdev:
1816} 1816}
1817 1817
1818#ifdef MODULE 1818#ifdef MODULE
1819#include <linux/version.h>
1820 1819
1821int init_module(void) 1820int init_module(void)
1822{ 1821{
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5eadbb9d4d71..28002de783b6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3714,6 +3714,12 @@ static int floppy_open(struct inode *inode, struct file *filp)
3714 USETF(FD_VERIFY); 3714 USETF(FD_VERIFY);
3715 } 3715 }
3716 3716
3717 /* set underlying gendisk policy to reflect real ro/rw status */
3718 if (UTESTF(FD_DISK_WRITABLE))
3719 inode->i_bdev->bd_disk->policy = 0;
3720 else
3721 inode->i_bdev->bd_disk->policy = 1;
3722
3717 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) 3723 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3718 goto out2; 3724 goto out2;
3719 3725
@@ -3770,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
3770 /* Allow ioctls if we have write-permissions even if read-only open. 3776 /* Allow ioctls if we have write-permissions even if read-only open.
3771 * Needed so that programs such as fdrawcmd still can work on write 3777 * Needed so that programs such as fdrawcmd still can work on write
3772 * protected disks */ 3778 * protected disks */
3773 if (filp->f_mode & 2 3779 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
3774 || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
3775 filp->private_data = (void *)8; 3780 filp->private_data = (void *)8;
3776 3781
3777 if (UFDCS->rawcmd == 1) 3782 if (UFDCS->rawcmd == 1)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a280e679b1ca..59e5982a5db3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -511,14 +511,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
511 */ 511 */
512static void pkt_iosched_process_queue(struct pktcdvd_device *pd) 512static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
513{ 513{
514 request_queue_t *q;
515 514
516 if (atomic_read(&pd->iosched.attention) == 0) 515 if (atomic_read(&pd->iosched.attention) == 0)
517 return; 516 return;
518 atomic_set(&pd->iosched.attention, 0); 517 atomic_set(&pd->iosched.attention, 0);
519 518
520 q = bdev_get_queue(pd->bdev);
521
522 for (;;) { 519 for (;;) {
523 struct bio *bio; 520 struct bio *bio;
524 int reads_queued, writes_queued; 521 int reads_queued, writes_queued;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index ecbeb7eaba8e..394796315adc 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -84,8 +84,8 @@ struct bpa10x_data {
84 84
85struct hci_vendor_hdr { 85struct hci_vendor_hdr {
86 __u8 type; 86 __u8 type;
87 __u16 snum; 87 __le16 snum;
88 __u16 dlen; 88 __le16 dlen;
89} __attribute__ ((packed)); 89} __attribute__ ((packed));
90 90
91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count) 91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index f510b25b2c59..057cb2b6e6d1 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,6 +65,7 @@
65#endif 65#endif
66 66
67static int ignore = 0; 67static int ignore = 0;
68static int ignore_dga = 0;
68static int ignore_csr = 0; 69static int ignore_csr = 0;
69static int ignore_sniffer = 0; 70static int ignore_sniffer = 0;
70static int reset = 0; 71static int reset = 0;
@@ -841,6 +842,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
841 if (ignore || id->driver_info & HCI_IGNORE) 842 if (ignore || id->driver_info & HCI_IGNORE)
842 return -ENODEV; 843 return -ENODEV;
843 844
845 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
846 return -ENODEV;
847
844 if (ignore_csr && id->driver_info & HCI_CSR) 848 if (ignore_csr && id->driver_info & HCI_CSR)
845 return -ENODEV; 849 return -ENODEV;
846 850
@@ -1070,6 +1074,9 @@ module_exit(hci_usb_exit);
1070module_param(ignore, bool, 0644); 1074module_param(ignore, bool, 0644);
1071MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); 1075MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1072 1076
1077module_param(ignore_dga, bool, 0644);
1078MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1079
1073module_param(ignore_csr, bool, 0644); 1080module_param(ignore_csr, bool, 0644);
1074MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); 1081MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1075 1082
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 73f333f491bd..27bca34b4a65 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); 147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 flush_agp_mappings();
150 151
151 bridge->scratch_page_real = virt_to_gart(addr); 152 bridge->scratch_page_real = virt_to_gart(addr);
152 bridge->scratch_page = 153 bridge->scratch_page =
@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
187 return 0; 188 return 0;
188 189
189err_out: 190err_out:
190 if (bridge->driver->needs_scratch_page) 191 if (bridge->driver->needs_scratch_page) {
191 bridge->driver->agp_destroy_page( 192 bridge->driver->agp_destroy_page(
192 gart_to_virt(bridge->scratch_page_real)); 193 gart_to_virt(bridge->scratch_page_real));
194 flush_agp_mappings();
195 }
193 if (got_gatt) 196 if (got_gatt)
194 bridge->driver->free_gatt_table(bridge); 197 bridge->driver->free_gatt_table(bridge);
195 if (got_keylist) { 198 if (got_keylist) {
@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
211 bridge->key_list = NULL; 214 bridge->key_list = NULL;
212 215
213 if (bridge->driver->agp_destroy_page && 216 if (bridge->driver->agp_destroy_page &&
214 bridge->driver->needs_scratch_page) 217 bridge->driver->needs_scratch_page) {
215 bridge->driver->agp_destroy_page( 218 bridge->driver->agp_destroy_page(
216 gart_to_virt(bridge->scratch_page_real)); 219 gart_to_virt(bridge->scratch_page_real));
220 flush_agp_mappings();
221 }
217} 222}
218 223
219/* When we remove the global variable agp_bridge from all drivers 224/* When we remove the global variable agp_bridge from all drivers
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c4a38715c6f9..5567ce8d72b0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
57{ 57{
58 int i; 58 int i;
59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); 59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
60 global_flush_tlb(); 60 /* Caller's responsibility to call global_flush_tlb() for
61 * performance reasons */
61 return i; 62 return i;
62} 63}
63EXPORT_SYMBOL_GPL(map_page_into_agp); 64EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
66{ 67{
67 int i; 68 int i;
68 i = change_page_attr(page, 1, PAGE_KERNEL); 69 i = change_page_attr(page, 1, PAGE_KERNEL);
69 global_flush_tlb(); 70 /* Caller's responsibility to call global_flush_tlb() for
71 * performance reasons */
70 return i; 72 return i;
71} 73}
72EXPORT_SYMBOL_GPL(unmap_page_from_agp); 74EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -153,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
153 for (i = 0; i < curr->page_count; i++) { 155 for (i = 0; i < curr->page_count; i++) {
154 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); 156 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
155 } 157 }
158 flush_agp_mappings();
156 } 159 }
157 agp_free_key(curr->key); 160 agp_free_key(curr->key);
158 vfree(curr->memory); 161 vfree(curr->memory);
@@ -210,7 +213,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
210 new->memory[i] = virt_to_gart(addr); 213 new->memory[i] = virt_to_gart(addr);
211 new->page_count++; 214 new->page_count++;
212 } 215 }
213 new->bridge = bridge; 216 new->bridge = bridge;
214 217
215 flush_agp_mappings(); 218 flush_agp_mappings();
216 219
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 58944cd271ea..34a444658ffe 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
111 111
112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { 112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
113 printk(KERN_ERR PFX 113 printk(KERN_ERR PFX
114 "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", 114 "I/O (GART) page-size %luKB doesn't match expected "
115 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); 115 "size %luKB\n",
116 1UL << (i460.io_page_shift - 10),
117 1UL << (I460_IO_PAGE_SHIFT));
116 return 0; 118 return 0;
117 } 119 }
118 120
@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
514{ 516{
515 void *page; 517 void *page;
516 518
517 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 519 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
518 page = agp_generic_alloc_page(agp_bridge); 520 page = agp_generic_alloc_page(agp_bridge);
519 else 521 global_flush_tlb();
522 } else
520 /* Returning NULL would cause problems */ 523 /* Returning NULL would cause problems */
521 /* AK: really dubious code. */ 524 /* AK: really dubious code. */
522 page = (void *)~0UL; 525 page = (void *)~0UL;
@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
525 528
526static void i460_destroy_page (void *page) 529static void i460_destroy_page (void *page)
527{ 530{
528 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 531 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
529 agp_generic_destroy_page(page); 532 agp_generic_destroy_page(page);
533 global_flush_tlb();
534 }
530} 535}
531 536
532#endif /* I460_LARGE_IO_PAGES */ 537#endif /* I460_LARGE_IO_PAGES */
@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
536{ 541{
537 /* Make sure the returned address is a valid GATT entry */ 542 /* Make sure the returned address is a valid GATT entry */
538 return bridge->driver->masks[0].mask 543 return bridge->driver->masks[0].mask
539 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12); 544 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
540} 545}
541 546
542struct agp_bridge_driver intel_i460_driver = { 547struct agp_bridge_driver intel_i460_driver = {
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index bf4cc9ffd5b1..027161ab88e9 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
270 270
271 switch (pg_count) { 271 switch (pg_count) {
272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); 272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
273 global_flush_tlb();
273 break; 274 break;
274 case 4: 275 case 4:
275 /* kludge to get 4 physical pages for ARGB cursor */ 276 /* kludge to get 4 physical pages for ARGB cursor */
@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
330 if(curr->type == AGP_PHYS_MEMORY) { 331 if(curr->type == AGP_PHYS_MEMORY) {
331 if (curr->page_count == 4) 332 if (curr->page_count == 4)
332 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 333 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
333 else 334 else {
334 agp_bridge->driver->agp_destroy_page( 335 agp_bridge->driver->agp_destroy_page(
335 gart_to_virt(curr->memory[0])); 336 gart_to_virt(curr->memory[0]));
337 global_flush_tlb();
338 }
336 vfree(curr->memory); 339 vfree(curr->memory);
337 } 340 }
338 kfree(curr); 341 kfree(curr);
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 6d3fec160bff..efff0eec618c 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -203,10 +203,10 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
203 203
204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
205 if (gart_info->is_pcie) 205 if (gart_info->is_pcie)
206 *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; 206 *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
207 else 207 else
208 *pci_gart = cpu_to_le32(page_base); 208 *pci_gart = cpu_to_le32(page_base);
209 *pci_gart++; 209 pci_gart++;
210 page_base += ATI_PCIGART_PAGE_SIZE; 210 page_base += ATI_PCIGART_PAGE_SIZE;
211 } 211 }
212 } 212 }
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
index 6cd12f23aa58..7cadfc6ef352 100644
--- a/drivers/char/ip2.c
+++ b/drivers/char/ip2.c
@@ -7,7 +7,6 @@
7// 7//
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/wait.h> 11#include <linux/wait.h>
13 12
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index d6c72e0934e2..cc3e54dd7234 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -46,7 +46,6 @@
46* First release to the public 46* First release to the public
47*/ 47*/
48 48
49#include <linux/version.h>
50#include <linux/interrupt.h> 49#include <linux/interrupt.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/ptrace.h> 51#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 3b965a651da4..26448f176803 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -38,7 +38,6 @@
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/version.h>
42#include <linux/autoconf.h> 41#include <linux/autoconf.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
44#include <linux/signal.h> 43#include <linux/signal.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 352547eabf7b..0bbfce43031c 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -90,7 +90,6 @@
90#include <linux/fcntl.h> 90#include <linux/fcntl.h>
91#include <linux/major.h> 91#include <linux/major.h>
92#include <linux/delay.h> 92#include <linux/delay.h>
93#include <linux/version.h>
94#include <linux/pci.h> 93#include <linux/pci.h>
95#include <linux/init.h> 94#include <linux/init.h>
96#include <asm/uaccess.h> 95#include <asm/uaccess.h>
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index feb25158c8ee..145275ebdd7e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -354,7 +354,7 @@ struct sysrq_key_op *__sysrq_get_key_op (int key) {
354 return op_p; 354 return op_p;
355} 355}
356 356
357void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) { 357static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
358 int i; 358 int i;
359 359
360 i = sysrq_key_table_key2index(key); 360 i = sysrq_key_table_key2index(key);
@@ -419,7 +419,7 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
419 __handle_sysrq(key, pt_regs, tty, 1); 419 __handle_sysrq(key, pt_regs, tty, 1);
420} 420}
421 421
422int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, 422static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
423 struct sysrq_key_op *remove_op_p) { 423 struct sysrq_key_op *remove_op_p) {
424 424
425 int retval; 425 int retval;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 99a60496ecc6..9293bcc4dc62 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/version.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/fs.h> 24#include <linux/fs.h>
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 98601c7d04a9..4d75c261f98a 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -26,7 +26,6 @@
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */ 27 */
28#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/version.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 867cc4e418c7..60aabdb4a046 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -32,7 +32,6 @@
32 * iseries/vio.h 32 * iseries/vio.h
33 */ 33 */
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/kernel.h> 36#include <linux/kernel.h>
38#include <linux/errno.h> 37#include <linux/errno.h>
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 25acf478c9e8..23a63207d747 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -38,7 +38,6 @@ static struct cpufreq_driver *cpufreq_driver;
38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
39static DEFINE_SPINLOCK(cpufreq_driver_lock); 39static DEFINE_SPINLOCK(cpufreq_driver_lock);
40 40
41
42/* internal prototypes */ 41/* internal prototypes */
43static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); 42static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
44static void handle_update(void *data); 43static void handle_update(void *data);
@@ -1115,24 +1114,21 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1115 int retval = -EINVAL; 1114 int retval = -EINVAL;
1116 1115
1117 /* 1116 /*
1118 * Converted the lock_cpu_hotplug to preempt_disable() 1117 * If we are already in context of hotplug thread, we dont need to
1119 * and preempt_enable(). This is a bit kludgy and relies on how cpu 1118 * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
1120 * hotplug works. All we need is a guarantee that cpu hotplug won't make 1119 * hotplug from removing this cpu that we are working on.
1121 * progress on any cpu. Once we do preempt_disable(), this would ensure
1122 * that hotplug threads don't get onto this cpu, thereby delaying
1123 * the cpu remove process.
1124 *
1125 * We removed the lock_cpu_hotplug since we need to call this function
1126 * via cpu hotplug callbacks, which result in locking the cpu hotplug
1127 * thread itself. Agree this is not very clean, cpufreq community
1128 * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
1129 */ 1120 */
1130 preempt_disable(); 1121 if (!current_in_cpu_hotplug())
1122 lock_cpu_hotplug();
1123
1131 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, 1124 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1132 target_freq, relation); 1125 target_freq, relation);
1133 if (cpu_online(policy->cpu) && cpufreq_driver->target) 1126 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1134 retval = cpufreq_driver->target(policy, target_freq, relation); 1127 retval = cpufreq_driver->target(policy, target_freq, relation);
1135 preempt_enable(); 1128
1129 if (!current_in_cpu_hotplug())
1130 unlock_cpu_hotplug();
1131
1136 return retval; 1132 return retval;
1137} 1133}
1138EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1134EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index ba17292eb290..6d83299e7c9b 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -34,7 +34,6 @@
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details. 35 * GNU General Public License for more details.
36 */ 36 */
37#include <linux/version.h>
38#include <linux/config.h> 37#include <linux/config.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/module.h> 39#include <linux/module.h>
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 70ef926c3bd8..4e9a04e1f08e 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -180,11 +180,10 @@ superio_exit(void)
180#define W83781D_REG_BANK 0x4E 180#define W83781D_REG_BANK 0x4E
181 181
182#define W83781D_REG_CONFIG 0x40 182#define W83781D_REG_CONFIG 0x40
183#define W83781D_REG_ALARM1 0x41 183#define W83781D_REG_ALARM1 0x459
184#define W83781D_REG_ALARM2 0x42 184#define W83781D_REG_ALARM2 0x45A
185#define W83781D_REG_ALARM3 0x450 185#define W83781D_REG_ALARM3 0x45B
186 186
187#define W83781D_REG_IRQ 0x4C
188#define W83781D_REG_BEEP_CONFIG 0x4D 187#define W83781D_REG_BEEP_CONFIG 0x4D
189#define W83781D_REG_BEEP_INTS1 0x56 188#define W83781D_REG_BEEP_INTS1 0x56
190#define W83781D_REG_BEEP_INTS2 0x57 189#define W83781D_REG_BEEP_INTS2 0x57
@@ -1370,13 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client)
1370 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); 1369 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
1371 } 1370 }
1372 } 1371 }
1373
1374 /* enable comparator mode for temp2 and temp3 so
1375 alarm indication will work correctly */
1376 i = w83627hf_read_value(client, W83781D_REG_IRQ);
1377 if (!(i & 0x40))
1378 w83627hf_write_value(client, W83781D_REG_IRQ,
1379 i | 0x40);
1380 } 1372 }
1381 1373
1382 /* Start monitoring */ 1374 /* Start monitoring */
@@ -1400,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1400 /* skip missing sensors */ 1392 /* skip missing sensors */
1401 if (((data->type == w83697hf) && (i == 1)) || 1393 if (((data->type == w83697hf) && (i == 1)) ||
1402 ((data->type == w83627thf || data->type == w83637hf) 1394 ((data->type == w83627thf || data->type == w83637hf)
1403 && (i == 4 || i == 5))) 1395 && (i == 5 || i == 6)))
1404 continue; 1396 continue;
1405 data->in[i] = 1397 data->in[i] =
1406 w83627hf_read_value(client, W83781D_REG_IN(i)); 1398 w83627hf_read_value(client, W83781D_REG_IN(i));
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c9366b504833..a2237d4b2cf2 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -142,19 +142,18 @@ static int vt596_transaction(u8 size)
142 /* Make sure the SMBus host is ready to start transmitting */ 142 /* Make sure the SMBus host is ready to start transmitting */
143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " 144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
145 "Resetting... ", temp); 145 "Resetting...\n", temp);
146 146
147 outb_p(temp, SMBHSTSTS); 147 outb_p(temp, SMBHSTSTS);
148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
149 printk("Failed! (0x%02x)\n", temp); 149 dev_err(&vt596_adapter.dev, "SMBus reset failed! "
150 "(0x%02x)\n", temp);
150 return -1; 151 return -1;
151 } else {
152 printk("Successful!\n");
153 } 152 }
154 } 153 }
155 154
156 /* Start the transaction by setting bit 6 */ 155 /* Start the transaction by setting bit 6 */
157 outb_p(0x40 | (size & 0x3C), SMBHSTCNT); 156 outb_p(0x40 | size, SMBHSTCNT);
158 157
159 /* We will always wait for a fraction of a second */ 158 /* We will always wait for a fraction of a second */
160 do { 159 do {
@@ -171,7 +170,7 @@ static int vt596_transaction(u8 size)
171 if (temp & 0x10) { 170 if (temp & 0x10) {
172 result = -1; 171 result = -1;
173 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", 172 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
174 inb_p(SMBHSTCNT) & 0x3C); 173 size);
175 } 174 }
176 175
177 if (temp & 0x08) { 176 if (temp & 0x08) {
@@ -180,11 +179,13 @@ static int vt596_transaction(u8 size)
180 } 179 }
181 180
182 if (temp & 0x04) { 181 if (temp & 0x04) {
182 int read = inb_p(SMBHSTADD) & 0x01;
183 result = -1; 183 result = -1;
184 /* Quick commands are used to probe for chips, so 184 /* The quick and receive byte commands are used to probe
185 errors are expected, and we don't want to frighten the 185 for chips, so errors are expected, and we don't want
186 user. */ 186 to frighten the user. */
187 if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) 187 if (!((size == VT596_QUICK && !read) ||
188 (size == VT596_BYTE && read)))
188 dev_err(&vt596_adapter.dev, "Transaction error!\n"); 189 dev_err(&vt596_adapter.dev, "Transaction error!\n");
189 } 190 }
190 191
@@ -462,9 +463,9 @@ static void __exit i2c_vt596_exit(void)
462 } 463 }
463} 464}
464 465
465MODULE_AUTHOR( 466MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
466 "Frodo Looijaard <frodol@dds.nl> and " 467 "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
467 "Philip Edelbrock <phil@netroedge.com>"); 468 "Jean Delvare <khali@linux-fr.org>");
468MODULE_DESCRIPTION("vt82c596 SMBus driver"); 469MODULE_DESCRIPTION("vt82c596 SMBus driver");
469MODULE_LICENSE("GPL"); 470MODULE_LICENSE("GPL");
470 471
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 01b037007410..02682fb794c8 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
164 buf[1] = BIN2BCD(dt->tm_sec); 164 buf[1] = BIN2BCD(dt->tm_sec);
165 buf[2] = BIN2BCD(dt->tm_min); 165 buf[2] = BIN2BCD(dt->tm_min);
166 buf[3] = BIN2BCD(dt->tm_hour); 166 buf[3] = BIN2BCD(dt->tm_hour);
167 buf[4] = BIN2BCD(dt->tm_wday) + 1; 167 buf[4] = BIN2BCD(dt->tm_wday + 1);
168 buf[5] = BIN2BCD(dt->tm_mday); 168 buf[5] = BIN2BCD(dt->tm_mday);
169 buf[6] = BIN2BCD(dt->tm_mon) + 1; 169 buf[6] = BIN2BCD(dt->tm_mon + 1);
170 val = dt->tm_year; 170 val = dt->tm_year;
171 if (val >= 100) { 171 if (val >= 100) {
172 val -= 100; 172 val -= 100;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index a737886e39d1..42e5b8175cbf 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
539 539
540 It is safe to say Y to this question. 540 It is safe to say Y to this question.
541 541
542config BLK_DEV_CS5535
543 tristate "AMD CS5535 chipset support"
544 depends on X86 && !X86_64
545 help
546 Include support for UDMA on the NSC/AMD CS5535 companion chipset.
547 This will automatically be detected and configured if found.
548
549 It is safe to say Y to this question.
550
542config BLK_DEV_HPT34X 551config BLK_DEV_HPT34X
543 tristate "HPT34X chipset support" 552 tristate "HPT34X chipset support"
544 help 553 help
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index e83f54d37f96..f615ab759962 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); 2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2039 ide_drive_t *drive = floppy->drive; 2039 ide_drive_t *drive = floppy->drive;
2040 void __user *argp = (void __user *)arg; 2040 void __user *argp = (void __user *)arg;
2041 int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); 2041 int err;
2042 int prevent = (arg) ? 1 : 0; 2042 int prevent = (arg) ? 1 : 0;
2043 idefloppy_pc_t pc; 2043 idefloppy_pc_t pc;
2044 if (err != -EINVAL)
2045 return err;
2046 2044
2047 switch (cmd) { 2045 switch (cmd) {
2048 case CDROMEJECT: 2046 case CDROMEJECT:
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2094 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: 2092 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
2095 return idefloppy_get_format_progress(drive, argp); 2093 return idefloppy_get_format_progress(drive, argp);
2096 } 2094 }
2097 return -EINVAL; 2095 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
2098} 2096}
2099 2097
2100static int idefloppy_media_changed(struct gendisk *disk) 2098static int idefloppy_media_changed(struct gendisk *disk)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0b0aa4f51628..af7af958ab3e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif)
104 hwif->INSL = ide_insl; 104 hwif->INSL = ide_insl;
105} 105}
106 106
107EXPORT_SYMBOL(default_hwif_iops);
108
109/* 107/*
110 * MMIO operations, typically used for SATA controllers 108 * MMIO operations, typically used for SATA controllers
111 */ 109 */
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif)
329 hwif->atapi_output_bytes = atapi_output_bytes; 327 hwif->atapi_output_bytes = atapi_output_bytes;
330} 328}
331 329
332EXPORT_SYMBOL(default_hwif_transport);
333
334/* 330/*
335 * Beginning of Taskfile OPCODE Library and feature sets. 331 * Beginning of Taskfile OPCODE Library and feature sets.
336 */ 332 */
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
529 return 0; 525 return 0;
530} 526}
531 527
532EXPORT_SYMBOL(wait_for_ready);
533
534/* 528/*
535 * This routine busy-waits for the drive status to be not "busy". 529 * This routine busy-waits for the drive status to be not "busy".
536 * It then checks the status for all of the "good" bits and none 530 * It then checks the status for all of the "good" bits and none
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 7ec18fa3b5ff..54f9639c2a8c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
161 return ide_stopped; 161 return ide_stopped;
162} 162}
163 163
164EXPORT_SYMBOL(do_rw_taskfile);
165
166/* 164/*
167 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. 165 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
168 */ 166 */
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 9fe19808d815..8af179b531c3 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -803,6 +803,7 @@ found:
803 hwif->irq = hw->irq; 803 hwif->irq = hw->irq;
804 hwif->noprobe = 0; 804 hwif->noprobe = 0;
805 hwif->chipset = hw->chipset; 805 hwif->chipset = hw->chipset;
806 hwif->gendev.parent = hw->dev;
806 807
807 if (!initializing) { 808 if (!initializing) {
808 probe_hwif_init_with_fixup(hwif, fixup); 809 probe_hwif_init_with_fixup(hwif, fixup);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 1dafffa7e513..ef79805218e4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -182,13 +182,14 @@ static void ide_detach(dev_link_t *link)
182 182
183} /* ide_detach */ 183} /* ide_detach */
184 184
185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) 185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
186{ 186{
187 hw_regs_t hw; 187 hw_regs_t hw;
188 memset(&hw, 0, sizeof(hw)); 188 memset(&hw, 0, sizeof(hw));
189 ide_init_hwif_ports(&hw, io, ctl, NULL); 189 ide_init_hwif_ports(&hw, io, ctl, NULL);
190 hw.irq = irq; 190 hw.irq = irq;
191 hw.chipset = ide_pci; 191 hw.chipset = ide_pci;
192 hw.dev = &handle->dev;
192 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); 193 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
193} 194}
194 195
@@ -327,12 +328,12 @@ static void ide_config(dev_link_t *link)
327 328
328 /* retry registration in case device is still spinning up */ 329 /* retry registration in case device is still spinning up */
329 for (hd = -1, i = 0; i < 10; i++) { 330 for (hd = -1, i = 0; i < 10; i++) {
330 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); 331 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
331 if (hd >= 0) break; 332 if (hd >= 0) break;
332 if (link->io.NumPorts1 == 0x20) { 333 if (link->io.NumPorts1 == 0x20) {
333 outb(0x02, ctl_base + 0x10); 334 outb(0x02, ctl_base + 0x10);
334 hd = idecs_register(io_base + 0x10, ctl_base + 0x10, 335 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
335 link->irq.AssignedIRQ); 336 link->irq.AssignedIRQ, handle);
336 if (hd >= 0) { 337 if (hd >= 0) {
337 io_base += 0x10; 338 io_base += 0x10;
338 ctl_base += 0x10; 339 ctl_base += 0x10;
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index af46226c1796..f35d684edc25 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o 6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o 7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o 8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
9obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
9obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o 10obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
10obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o 11obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
11obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o 12obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 844a6c9fb949..21965e5ef25e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, 74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, 75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, 76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
77 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
77 { 0 } 78 { 0 }
78}; 79};
79 80
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
491 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), 492 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
492 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), 493 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
493 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), 494 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
495 /* 17 */ DECLARE_AMD_DEV("AMD5536"),
494}; 496};
495 497
496static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) 498static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
527 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, 529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
528 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, 530 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, 531 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
532 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
530 { 0, }, 533 { 0, },
531}; 534};
532MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); 535MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
new file mode 100644
index 000000000000..6eb305197f3c
--- /dev/null
+++ b/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
1/*
2 * linux/drivers/ide/pci/cs5535.c
3 *
4 * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
5 *
6 * History:
7 * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
8 * - Reworked tuneproc, set_drive, misc mods to prep for mainline
9 * - Work was sponsored by CIS (M) Sdn Bhd.
10 * Ported to Kernel 2.6.11 on June 26, 2005 by
11 * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
12 * Alexander Kiausch <alex.kiausch@t-online.de>
13 * Originally developed by AMD for 2.4/2.6
14 *
15 * Development of this chipset driver was funded
16 * by the nice folks at National Semiconductor/AMD.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License version 2 as published by
20 * the Free Software Foundation.
21 *
22 * Documentation:
23 * CS5535 documentation available from AMD
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/ide.h>
30
31#include "ide-timing.h"
32
33#define MSR_ATAC_BASE 0x51300000
34#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
35#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
36#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
37#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
38#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
39#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
40#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
41#define ATAC_RESET (MSR_ATAC_BASE+0x10)
42#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
43#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
44#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
45#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
46#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
47#define ATAC_BM0_CMD_PRIM 0x00
48#define ATAC_BM0_STS_PRIM 0x02
49#define ATAC_BM0_PRD 0x04
50#define CS5535_CABLE_DETECT 0x48
51
52/* Format I PIO settings. We seperate out cmd and data for safer timings */
53
54static unsigned int cs5535_pio_cmd_timings[5] =
55{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
56static unsigned int cs5535_pio_dta_timings[5] =
57{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
58
59static unsigned int cs5535_mwdma_timings[3] =
60{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
61
62static unsigned int cs5535_udma_timings[5] =
63{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
64
65/* Macros to check if the register is the reset value - reset value is an
66 invalid timing and indicates the register has not been set previously */
67
68#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
69#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
70
71/****
72 * cs5535_set_speed - Configure the chipset to the new speed
73 * @drive: Drive to set up
74 * @speed: desired speed
75 *
76 * cs5535_set_speed() configures the chipset to a new speed.
77 */
78static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
79{
80
81 u32 reg = 0, dummy;
82 int unit = drive->select.b.unit;
83
84
85 /* Set the PIO timings */
86 if ((speed & XFER_MODE) == XFER_PIO) {
87 u8 pioa;
88 u8 piob;
89 u8 cmd;
90
91 pioa = speed - XFER_PIO_0;
92 piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
93 255, 4, NULL);
94 cmd = pioa < piob ? pioa : piob;
95
96 /* Write the speed of the current drive */
97 reg = (cs5535_pio_cmd_timings[cmd] << 16) |
98 cs5535_pio_dta_timings[pioa];
99 wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
100
101 /* And if nessesary - change the speed of the other drive */
102 rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
103
104 if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
105 cs5535_pio_cmd_timings[cmd]) {
106 reg &= 0x0000FFFF;
107 reg |= cs5535_pio_cmd_timings[cmd] << 16;
108 wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
109 }
110
111 /* Set bit 31 of the DMA register for PIO format 1 timings */
112 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
113 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
114 reg | 0x80000000UL, 0);
115 } else {
116 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
117
118 reg &= 0x80000000UL; /* Preserve the PIO format bit */
119
120 if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
121 reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
122 else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
123 reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
124 else
125 return;
126
127 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
128 }
129}
130
131static u8 cs5535_ratemask(ide_drive_t *drive)
132{
133 /* eighty93 will return 1 if it's 80core and capable of
134 exceeding udma2, 0 otherwise. we need ratemask to set
135 the max speed and if we can > udma2 then we return 2
136 which selects speed_max as udma4 which is the 5535's max
137 speed, and 1 selects udma2 which is the max for 40c */
138 if (!eighty_ninty_three(drive))
139 return 1;
140
141 return 2;
142}
143
144
145/****
146 * cs5535_set_drive - Configure the drive to the new speed
147 * @drive: Drive to set up
148 * @speed: desired speed
149 *
150 * cs5535_set_drive() configures the drive and the chipset to a
151 * new speed. It also can be called by upper layers.
152 */
153static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
154{
155 speed = ide_rate_filter(cs5535_ratemask(drive), speed);
156 ide_config_drive_speed(drive, speed);
157 cs5535_set_speed(drive, speed);
158
159 return 0;
160}
161
162/****
163 * cs5535_tuneproc - PIO setup
164 * @drive: drive to set up
165 * @pio: mode to use (255 for 'best possible')
166 *
167 * A callback from the upper layers for PIO-only tuning.
168 */
169static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
170{
171 u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
172 XFER_PIO_4 };
173
174 /* cs5535 max pio is pio 4, best_pio will check the blacklist.
175 i think we don't need to rate_filter the incoming xferspeed
176 since we know we're only going to choose pio */
177 xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
178 ide_config_drive_speed(drive, modes[xferspeed]);
179 cs5535_set_speed(drive, xferspeed);
180}
181
182static int cs5535_config_drive_for_dma(ide_drive_t *drive)
183{
184 u8 speed;
185
186 speed = ide_dma_speed(drive, cs5535_ratemask(drive));
187
188 /* If no DMA speed was available then let dma_check hit pio */
189 if (!speed) {
190 return 0;
191 }
192
193 cs5535_set_drive(drive, speed);
194 return ide_dma_enable(drive);
195}
196
197static int cs5535_dma_check(ide_drive_t *drive)
198{
199 ide_hwif_t *hwif = drive->hwif;
200 struct hd_driveid *id = drive->id;
201 u8 speed;
202
203 drive->init_speed = 0;
204
205 if ((id->capability & 1) && drive->autodma) {
206 if (ide_use_dma(drive)) {
207 if (cs5535_config_drive_for_dma(drive))
208 return hwif->ide_dma_on(drive);
209 }
210
211 goto fast_ata_pio;
212
213 } else if ((id->capability & 8) || (id->field_valid & 2)) {
214fast_ata_pio:
215 speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
216 cs5535_set_drive(drive, speed);
217 return hwif->ide_dma_off_quietly(drive);
218 }
219 /* IORDY not supported */
220 return 0;
221}
222
223static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
224{
225 u8 bit;
226
227 /* if a 80 wire cable was detected */
228 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
229 return (bit & 1);
230}
231
232/****
233 * init_hwif_cs5535 - Initialize one ide cannel
234 * @hwif: Channel descriptor
235 *
236 * This gets invoked by the IDE driver once for each channel. It
237 * performs channel-specific pre-initialization before drive probing.
238 *
239 */
240static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
241{
242 int i;
243
244 hwif->autodma = 0;
245
246 hwif->tuneproc = &cs5535_tuneproc;
247 hwif->speedproc = &cs5535_set_drive;
248 hwif->ide_dma_check = &cs5535_dma_check;
249
250 hwif->atapi_dma = 1;
251 hwif->ultra_mask = 0x1F;
252 hwif->mwdma_mask = 0x07;
253
254
255 hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
256
257 if (!noautodma)
258 hwif->autodma = 1;
259
260 /* just setting autotune and not worrying about bios timings */
261 for (i = 0; i < 2; i++) {
262 hwif->drives[i].autotune = 1;
263 hwif->drives[i].autodma = hwif->autodma;
264 }
265}
266
267static ide_pci_device_t cs5535_chipset __devinitdata = {
268 .name = "CS5535",
269 .init_hwif = init_hwif_cs5535,
270 .channels = 1,
271 .autodma = AUTODMA,
272 .bootable = ON_BOARD,
273};
274
275static int __devinit cs5535_init_one(struct pci_dev *dev,
276 const struct pci_device_id *id)
277{
278 return ide_setup_pci_device(dev, &cs5535_chipset);
279}
280
281static struct pci_device_id cs5535_pci_tbl[] =
282{
283 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
284 PCI_ANY_ID, 0, 0, 0},
285 { 0, },
286};
287
288MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
289
290static struct pci_driver driver = {
291 .name = "CS5535_IDE",
292 .id_table = cs5535_pci_tbl,
293 .probe = cs5535_init_one,
294};
295
296static int __init cs5535_ide_init(void)
297{
298 return ide_pci_register_driver(&driver);
299}
300
301module_init(cs5535_ide_init);
302
303MODULE_AUTHOR("AMD");
304MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
305MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 5a33513f3dd1..9f41ecd56338 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
469 469
470static __devinitdata ide_hwif_t *primary; 470static __devinitdata ide_hwif_t *primary;
471 471
472void __devinit init_iops_cy82c693(ide_hwif_t *hwif) 472static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
473{ 473{
474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1) 474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
475 primary = hwif; 475 primary = hwif;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 2b9961b88135..022d244f2eb0 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
701 unsigned long barsize = pci_resource_len(dev, 5); 701 unsigned long barsize = pci_resource_len(dev, 5);
702 u8 tmpbyte = 0; 702 u8 tmpbyte = 0;
703 void __iomem *ioaddr; 703 void __iomem *ioaddr;
704 u32 tmp, irq_mask;
704 705
705 /* 706 /*
706 * Drop back to PIO if we can't map the mmio. Some 707 * Drop back to PIO if we can't map the mmio. Some
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
726 pci_set_drvdata(dev, (void *) ioaddr); 727 pci_set_drvdata(dev, (void *) ioaddr);
727 728
728 if (pdev_is_sata(dev)) { 729 if (pdev_is_sata(dev)) {
730 /* make sure IDE0/1 interrupts are not masked */
731 irq_mask = (1 << 22) | (1 << 23);
732 tmp = readl(ioaddr + 0x48);
733 if (tmp & irq_mask) {
734 tmp &= ~irq_mask;
735 writel(tmp, ioaddr + 0x48);
736 readl(ioaddr + 0x48); /* flush */
737 }
729 writel(0, ioaddr + 0x148); 738 writel(0, ioaddr + 0x148);
730 writel(0, ioaddr + 0x1C8); 739 writel(0, ioaddr + 0x1C8);
731 } 740 }
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2687e34aa5bc..321a3a10e69b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -32,7 +32,6 @@
32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ 32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
33 */ 33 */
34 34
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/init.h> 36#include <linux/init.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 0879915b14d5..c8ae2bb054e0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -669,7 +669,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name); 669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
670 if (dev->phys) 670 if (dev->phys)
671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys); 671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
672 if (dev->phys) 672 if (dev->uniq)
673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); 673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
674 674
675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); 675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 434e684f5dbb..2f7c9fc2e898 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/version.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16 15
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 0b0ea26023e5..1b37d86d5ee1 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
17#ifdef CONFIG_PROC_FS 16#ifdef CONFIG_PROC_FS
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 0bfd698726a6..f1a1f9a9b88e 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/version.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
14 13
15#include "isdn_divert.h" 14#include "isdn_divert.h"
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index b4d795d40154..dc7ef957e897 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -23,7 +23,6 @@
23 * o tx_skb at PH_DEACTIVATE time 23 * o tx_skb at PH_DEACTIVATE time
24 */ 24 */
25 25
26#include <linux/version.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2cf5d1a6df6c..8e192a3a3490 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..acc1d3cceebb 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/signal.h> 14#include <linux/signal.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..cb791f8e793a 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -13,7 +13,6 @@
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/poll.h> 16#include <linux/poll.h>
18#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index babec8157ae6..aa01628d74c6 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/version.h>
18#include <linux/signal.h> 17#include <linux/signal.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/netdevice.h> 19#include <linux/netdevice.h>
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 87f59a0e2a95..40e56143c768 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/version.h>
16#include <linux/poll.h> 15#include <linux/poll.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..6c26f1efabd5 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8a7d54a5c97d..4643df097bfe 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,7 +14,6 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
20#include <linux/isdn.h> 19#include <linux/isdn.h>
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 9028cc3b5071..7d7245fb0b32 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -35,7 +35,6 @@ typedef struct icn_cdef {
35#ifdef __KERNEL__ 35#ifdef __KERNEL__
36/* Kernel includes */ 36/* Kernel includes */
37 37
38#include <linux/version.h>
39#include <linux/errno.h> 38#include <linux/errno.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/major.h> 40#include <linux/major.h>
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 8fb7bc1bfe0f..d699fe53e1c3 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -33,7 +33,6 @@ typedef struct isdnloop_sdef {
33#ifdef __KERNEL__ 33#ifdef __KERNEL__
34/* Kernel includes */ 34/* Kernel includes */
35 35
36#include <linux/version.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/fs.h> 37#include <linux/fs.h>
39#include <linux/major.h> 38#include <linux/major.h>
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 4611da6e9231..5286e0c810a9 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -4,7 +4,6 @@
4 * 4 *
5 */ 5 */
6 6
7#include <linux/version.h>
8#include <linux/errno.h> 7#include <linux/errno.h>
9#include <asm/io.h> 8#include <asm/io.h>
10#include <linux/delay.h> 9#include <linux/delay.h>
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 01654fcabc52..51315302a85e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/version.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/init.h> 26#include <linux/init.h>
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
272 return ERR_PTR(-ENOMEM); 271 return ERR_PTR(-ENOMEM);
273 272
274 ITERATE_RDEV(mddev, rdev, tmp) { 273 ITERATE_RDEV(mddev, rdev, tmp) {
275 if (! rdev->in_sync || rdev->faulty) 274 if (! test_bit(In_sync, &rdev->flags)
275 || test_bit(Faulty, &rdev->flags))
276 continue; 276 continue;
277 277
278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); 278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
292 struct list_head *tmp; 292 struct list_head *tmp;
293 293
294 ITERATE_RDEV(mddev, rdev, tmp) 294 ITERATE_RDEV(mddev, rdev, tmp)
295 if (rdev->in_sync && !rdev->faulty) 295 if (test_bit(In_sync, &rdev->flags)
296 && !test_bit(Faulty, &rdev->flags))
296 md_super_write(mddev, rdev, 297 md_super_write(mddev, rdev,
297 (rdev->sb_offset<<1) + offset 298 (rdev->sb_offset<<1) + offset
298 + page->index * (PAGE_SIZE/512), 299 + page->index * (PAGE_SIZE/512),
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
300 page); 301 page);
301 302
302 if (wait) 303 if (wait)
303 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 304 md_super_wait(mddev);
304 return 0; 305 return 0;
305} 306}
306 307
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap)
481 /* verify that the bitmap-specific fields are valid */ 482 /* verify that the bitmap-specific fields are valid */
482 if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) 483 if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
483 reason = "bad magic"; 484 reason = "bad magic";
484 else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) 485 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
486 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
485 reason = "unrecognized superblock version"; 487 reason = "unrecognized superblock version";
486 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) 488 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
487 reason = "bitmap chunksize out of range (512B - 4MB)"; 489 reason = "bitmap chunksize out of range (512B - 4MB)";
@@ -526,6 +528,8 @@ success:
526 bitmap->daemon_lastrun = jiffies; 528 bitmap->daemon_lastrun = jiffies;
527 bitmap->max_write_behind = write_behind; 529 bitmap->max_write_behind = write_behind;
528 bitmap->flags |= sb->state; 530 bitmap->flags |= sb->state;
531 if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
532 bitmap->flags |= BITMAP_HOSTENDIAN;
529 bitmap->events_cleared = le64_to_cpu(sb->events_cleared); 533 bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
530 if (sb->state & BITMAP_STALE) 534 if (sb->state & BITMAP_STALE)
531 bitmap->events_cleared = bitmap->mddev->events; 535 bitmap->events_cleared = bitmap->mddev->events;
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
763 767
764 /* set the bit */ 768 /* set the bit */
765 kaddr = kmap_atomic(page, KM_USER0); 769 kaddr = kmap_atomic(page, KM_USER0);
766 set_bit(bit, kaddr); 770 if (bitmap->flags & BITMAP_HOSTENDIAN)
771 set_bit(bit, kaddr);
772 else
773 ext2_set_bit(bit, kaddr);
767 kunmap_atomic(kaddr, KM_USER0); 774 kunmap_atomic(kaddr, KM_USER0);
768 PRINTK("set file bit %lu page %lu\n", bit, page->index); 775 PRINTK("set file bit %lu page %lu\n", bit, page->index);
769 776
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap)
821 wake_up_process(bitmap->writeback_daemon->tsk)); 828 wake_up_process(bitmap->writeback_daemon->tsk));
822 spin_unlock_irq(&bitmap->write_lock); 829 spin_unlock_irq(&bitmap->write_lock);
823 } else 830 } else
824 wait_event(bitmap->mddev->sb_wait, 831 md_super_wait(bitmap->mddev);
825 atomic_read(&bitmap->mddev->pending_writes)==0);
826 } 832 }
827 return 0; 833 return 0;
828} 834}
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
890 oldindex = ~0L; 896 oldindex = ~0L;
891 897
892 for (i = 0; i < chunks; i++) { 898 for (i = 0; i < chunks; i++) {
899 int b;
893 index = file_page_index(i); 900 index = file_page_index(i);
894 bit = file_page_offset(i); 901 bit = file_page_offset(i);
895 if (index != oldindex) { /* this is a new page, read it in */ 902 if (index != oldindex) { /* this is a new page, read it in */
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
938 945
939 bitmap->filemap[bitmap->file_pages++] = page; 946 bitmap->filemap[bitmap->file_pages++] = page;
940 } 947 }
941 if (test_bit(bit, page_address(page))) { 948 if (bitmap->flags & BITMAP_HOSTENDIAN)
949 b = test_bit(bit, page_address(page));
950 else
951 b = ext2_test_bit(bit, page_address(page));
952 if (b) {
942 /* if the disk bit is set, set the memory bit */ 953 /* if the disk bit is set, set the memory bit */
943 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), 954 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
944 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) 955 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1096 -1); 1107 -1);
1097 1108
1098 /* clear the bit */ 1109 /* clear the bit */
1099 clear_bit(file_page_offset(j), page_address(page)); 1110 if (bitmap->flags & BITMAP_HOSTENDIAN)
1111 clear_bit(file_page_offset(j), page_address(page));
1112 else
1113 ext2_clear_bit(file_page_offset(j), page_address(page));
1100 } 1114 }
1101 } 1115 }
1102 spin_unlock_irqrestore(&bitmap->lock, flags); 1116 spin_unlock_irqrestore(&bitmap->lock, flags);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ecf51ee596f..adf960d8a7c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
131 131
132static struct block_device_operations md_fops; 132static struct block_device_operations md_fops;
133 133
134static int start_readonly;
135
134/* 136/*
135 * Enables to iterate over all existing md arrays 137 * Enables to iterate over all existing md arrays
136 * all_mddevs_lock protects this list. 138 * all_mddevs_lock protects this list.
@@ -181,7 +183,7 @@ static void mddev_put(mddev_t *mddev)
181 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 183 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
182 list_del(&mddev->all_mddevs); 184 list_del(&mddev->all_mddevs);
183 blk_put_queue(mddev->queue); 185 blk_put_queue(mddev->queue);
184 kfree(mddev); 186 kobject_unregister(&mddev->kobj);
185 } 187 }
186 spin_unlock(&all_mddevs_lock); 188 spin_unlock(&all_mddevs_lock);
187} 189}
@@ -330,18 +332,46 @@ static void free_disk_sb(mdk_rdev_t * rdev)
330static int super_written(struct bio *bio, unsigned int bytes_done, int error) 332static int super_written(struct bio *bio, unsigned int bytes_done, int error)
331{ 333{
332 mdk_rdev_t *rdev = bio->bi_private; 334 mdk_rdev_t *rdev = bio->bi_private;
335 mddev_t *mddev = rdev->mddev;
333 if (bio->bi_size) 336 if (bio->bi_size)
334 return 1; 337 return 1;
335 338
336 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) 339 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
337 md_error(rdev->mddev, rdev); 340 md_error(mddev, rdev);
338 341
339 if (atomic_dec_and_test(&rdev->mddev->pending_writes)) 342 if (atomic_dec_and_test(&mddev->pending_writes))
340 wake_up(&rdev->mddev->sb_wait); 343 wake_up(&mddev->sb_wait);
341 bio_put(bio); 344 bio_put(bio);
342 return 0; 345 return 0;
343} 346}
344 347
348static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
349{
350 struct bio *bio2 = bio->bi_private;
351 mdk_rdev_t *rdev = bio2->bi_private;
352 mddev_t *mddev = rdev->mddev;
353 if (bio->bi_size)
354 return 1;
355
356 if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
357 error == -EOPNOTSUPP) {
358 unsigned long flags;
359 /* barriers don't appear to be supported :-( */
360 set_bit(BarriersNotsupp, &rdev->flags);
361 mddev->barriers_work = 0;
362 spin_lock_irqsave(&mddev->write_lock, flags);
363 bio2->bi_next = mddev->biolist;
364 mddev->biolist = bio2;
365 spin_unlock_irqrestore(&mddev->write_lock, flags);
366 wake_up(&mddev->sb_wait);
367 bio_put(bio);
368 return 0;
369 }
370 bio_put(bio2);
371 bio->bi_private = rdev;
372 return super_written(bio, bytes_done, error);
373}
374
345void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 375void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
346 sector_t sector, int size, struct page *page) 376 sector_t sector, int size, struct page *page)
347{ 377{
@@ -350,16 +380,54 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
350 * and decrement it on completion, waking up sb_wait 380 * and decrement it on completion, waking up sb_wait
351 * if zero is reached. 381 * if zero is reached.
352 * If an error occurred, call md_error 382 * If an error occurred, call md_error
383 *
384 * As we might need to resubmit the request if BIO_RW_BARRIER
385 * causes ENOTSUPP, we allocate a spare bio...
353 */ 386 */
354 struct bio *bio = bio_alloc(GFP_NOIO, 1); 387 struct bio *bio = bio_alloc(GFP_NOIO, 1);
388 int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
355 389
356 bio->bi_bdev = rdev->bdev; 390 bio->bi_bdev = rdev->bdev;
357 bio->bi_sector = sector; 391 bio->bi_sector = sector;
358 bio_add_page(bio, page, size, 0); 392 bio_add_page(bio, page, size, 0);
359 bio->bi_private = rdev; 393 bio->bi_private = rdev;
360 bio->bi_end_io = super_written; 394 bio->bi_end_io = super_written;
395 bio->bi_rw = rw;
396
361 atomic_inc(&mddev->pending_writes); 397 atomic_inc(&mddev->pending_writes);
362 submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio); 398 if (!test_bit(BarriersNotsupp, &rdev->flags)) {
399 struct bio *rbio;
400 rw |= (1<<BIO_RW_BARRIER);
401 rbio = bio_clone(bio, GFP_NOIO);
402 rbio->bi_private = bio;
403 rbio->bi_end_io = super_written_barrier;
404 submit_bio(rw, rbio);
405 } else
406 submit_bio(rw, bio);
407}
408
409void md_super_wait(mddev_t *mddev)
410{
411 /* wait for all superblock writes that were scheduled to complete.
412 * if any had to be retried (due to BARRIER problems), retry them
413 */
414 DEFINE_WAIT(wq);
415 for(;;) {
416 prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
417 if (atomic_read(&mddev->pending_writes)==0)
418 break;
419 while (mddev->biolist) {
420 struct bio *bio;
421 spin_lock_irq(&mddev->write_lock);
422 bio = mddev->biolist;
423 mddev->biolist = bio->bi_next ;
424 bio->bi_next = NULL;
425 spin_unlock_irq(&mddev->write_lock);
426 submit_bio(bio->bi_rw, bio);
427 }
428 schedule();
429 }
430 finish_wait(&mddev->sb_wait, &wq);
363} 431}
364 432
365static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) 433static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
@@ -610,7 +678,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
610 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); 678 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
611 679
612 rdev->raid_disk = -1; 680 rdev->raid_disk = -1;
613 rdev->in_sync = 0; 681 rdev->flags = 0;
614 if (mddev->raid_disks == 0) { 682 if (mddev->raid_disks == 0) {
615 mddev->major_version = 0; 683 mddev->major_version = 0;
616 mddev->minor_version = sb->minor_version; 684 mddev->minor_version = sb->minor_version;
@@ -671,21 +739,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
671 return 0; 739 return 0;
672 740
673 if (mddev->level != LEVEL_MULTIPATH) { 741 if (mddev->level != LEVEL_MULTIPATH) {
674 rdev->faulty = 0;
675 rdev->flags = 0;
676 desc = sb->disks + rdev->desc_nr; 742 desc = sb->disks + rdev->desc_nr;
677 743
678 if (desc->state & (1<<MD_DISK_FAULTY)) 744 if (desc->state & (1<<MD_DISK_FAULTY))
679 rdev->faulty = 1; 745 set_bit(Faulty, &rdev->flags);
680 else if (desc->state & (1<<MD_DISK_SYNC) && 746 else if (desc->state & (1<<MD_DISK_SYNC) &&
681 desc->raid_disk < mddev->raid_disks) { 747 desc->raid_disk < mddev->raid_disks) {
682 rdev->in_sync = 1; 748 set_bit(In_sync, &rdev->flags);
683 rdev->raid_disk = desc->raid_disk; 749 rdev->raid_disk = desc->raid_disk;
684 } 750 }
685 if (desc->state & (1<<MD_DISK_WRITEMOSTLY)) 751 if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
686 set_bit(WriteMostly, &rdev->flags); 752 set_bit(WriteMostly, &rdev->flags);
687 } else /* MULTIPATH are always insync */ 753 } else /* MULTIPATH are always insync */
688 rdev->in_sync = 1; 754 set_bit(In_sync, &rdev->flags);
689 return 0; 755 return 0;
690} 756}
691 757
@@ -699,6 +765,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
699 mdk_rdev_t *rdev2; 765 mdk_rdev_t *rdev2;
700 int next_spare = mddev->raid_disks; 766 int next_spare = mddev->raid_disks;
701 767
768
702 /* make rdev->sb match mddev data.. 769 /* make rdev->sb match mddev data..
703 * 770 *
704 * 1/ zero out disks 771 * 1/ zero out disks
@@ -758,23 +825,27 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
758 sb->disks[0].state = (1<<MD_DISK_REMOVED); 825 sb->disks[0].state = (1<<MD_DISK_REMOVED);
759 ITERATE_RDEV(mddev,rdev2,tmp) { 826 ITERATE_RDEV(mddev,rdev2,tmp) {
760 mdp_disk_t *d; 827 mdp_disk_t *d;
761 if (rdev2->raid_disk >= 0 && rdev2->in_sync && !rdev2->faulty) 828 int desc_nr;
762 rdev2->desc_nr = rdev2->raid_disk; 829 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
830 && !test_bit(Faulty, &rdev2->flags))
831 desc_nr = rdev2->raid_disk;
763 else 832 else
764 rdev2->desc_nr = next_spare++; 833 desc_nr = next_spare++;
834 rdev2->desc_nr = desc_nr;
765 d = &sb->disks[rdev2->desc_nr]; 835 d = &sb->disks[rdev2->desc_nr];
766 nr_disks++; 836 nr_disks++;
767 d->number = rdev2->desc_nr; 837 d->number = rdev2->desc_nr;
768 d->major = MAJOR(rdev2->bdev->bd_dev); 838 d->major = MAJOR(rdev2->bdev->bd_dev);
769 d->minor = MINOR(rdev2->bdev->bd_dev); 839 d->minor = MINOR(rdev2->bdev->bd_dev);
770 if (rdev2->raid_disk >= 0 && rdev->in_sync && !rdev2->faulty) 840 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
841 && !test_bit(Faulty, &rdev2->flags))
771 d->raid_disk = rdev2->raid_disk; 842 d->raid_disk = rdev2->raid_disk;
772 else 843 else
773 d->raid_disk = rdev2->desc_nr; /* compatibility */ 844 d->raid_disk = rdev2->desc_nr; /* compatibility */
774 if (rdev2->faulty) { 845 if (test_bit(Faulty, &rdev2->flags)) {
775 d->state = (1<<MD_DISK_FAULTY); 846 d->state = (1<<MD_DISK_FAULTY);
776 failed++; 847 failed++;
777 } else if (rdev2->in_sync) { 848 } else if (test_bit(In_sync, &rdev2->flags)) {
778 d->state = (1<<MD_DISK_ACTIVE); 849 d->state = (1<<MD_DISK_ACTIVE);
779 d->state |= (1<<MD_DISK_SYNC); 850 d->state |= (1<<MD_DISK_SYNC);
780 active++; 851 active++;
@@ -787,7 +858,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
787 if (test_bit(WriteMostly, &rdev2->flags)) 858 if (test_bit(WriteMostly, &rdev2->flags))
788 d->state |= (1<<MD_DISK_WRITEMOSTLY); 859 d->state |= (1<<MD_DISK_WRITEMOSTLY);
789 } 860 }
790
791 /* now set the "removed" and "faulty" bits on any missing devices */ 861 /* now set the "removed" and "faulty" bits on any missing devices */
792 for (i=0 ; i < mddev->raid_disks ; i++) { 862 for (i=0 ; i < mddev->raid_disks ; i++) {
793 mdp_disk_t *d = &sb->disks[i]; 863 mdp_disk_t *d = &sb->disks[i];
@@ -944,7 +1014,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
944 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); 1014 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
945 1015
946 rdev->raid_disk = -1; 1016 rdev->raid_disk = -1;
947 rdev->in_sync = 0; 1017 rdev->flags = 0;
948 if (mddev->raid_disks == 0) { 1018 if (mddev->raid_disks == 0) {
949 mddev->major_version = 1; 1019 mddev->major_version = 1;
950 mddev->patch_version = 0; 1020 mddev->patch_version = 0;
@@ -996,22 +1066,19 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
996 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1066 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
997 switch(role) { 1067 switch(role) {
998 case 0xffff: /* spare */ 1068 case 0xffff: /* spare */
999 rdev->faulty = 0;
1000 break; 1069 break;
1001 case 0xfffe: /* faulty */ 1070 case 0xfffe: /* faulty */
1002 rdev->faulty = 1; 1071 set_bit(Faulty, &rdev->flags);
1003 break; 1072 break;
1004 default: 1073 default:
1005 rdev->in_sync = 1; 1074 set_bit(In_sync, &rdev->flags);
1006 rdev->faulty = 0;
1007 rdev->raid_disk = role; 1075 rdev->raid_disk = role;
1008 break; 1076 break;
1009 } 1077 }
1010 rdev->flags = 0;
1011 if (sb->devflags & WriteMostly1) 1078 if (sb->devflags & WriteMostly1)
1012 set_bit(WriteMostly, &rdev->flags); 1079 set_bit(WriteMostly, &rdev->flags);
1013 } else /* MULTIPATH are always insync */ 1080 } else /* MULTIPATH are always insync */
1014 rdev->in_sync = 1; 1081 set_bit(In_sync, &rdev->flags);
1015 1082
1016 return 0; 1083 return 0;
1017} 1084}
@@ -1055,9 +1122,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1055 1122
1056 ITERATE_RDEV(mddev,rdev2,tmp) { 1123 ITERATE_RDEV(mddev,rdev2,tmp) {
1057 i = rdev2->desc_nr; 1124 i = rdev2->desc_nr;
1058 if (rdev2->faulty) 1125 if (test_bit(Faulty, &rdev2->flags))
1059 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1126 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1060 else if (rdev2->in_sync) 1127 else if (test_bit(In_sync, &rdev2->flags))
1061 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); 1128 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1062 else 1129 else
1063 sb->dev_roles[i] = cpu_to_le16(0xffff); 1130 sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1115,6 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1115{ 1182{
1116 mdk_rdev_t *same_pdev; 1183 mdk_rdev_t *same_pdev;
1117 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; 1184 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
1185 struct kobject *ko;
1118 1186
1119 if (rdev->mddev) { 1187 if (rdev->mddev) {
1120 MD_BUG(); 1188 MD_BUG();
@@ -1143,10 +1211,22 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1143 if (find_rdev_nr(mddev, rdev->desc_nr)) 1211 if (find_rdev_nr(mddev, rdev->desc_nr))
1144 return -EBUSY; 1212 return -EBUSY;
1145 } 1213 }
1214 bdevname(rdev->bdev,b);
1215 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
1216 return -ENOMEM;
1146 1217
1147 list_add(&rdev->same_set, &mddev->disks); 1218 list_add(&rdev->same_set, &mddev->disks);
1148 rdev->mddev = mddev; 1219 rdev->mddev = mddev;
1149 printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b)); 1220 printk(KERN_INFO "md: bind<%s>\n", b);
1221
1222 rdev->kobj.parent = &mddev->kobj;
1223 kobject_add(&rdev->kobj);
1224
1225 if (rdev->bdev->bd_part)
1226 ko = &rdev->bdev->bd_part->kobj;
1227 else
1228 ko = &rdev->bdev->bd_disk->kobj;
1229 sysfs_create_link(&rdev->kobj, ko, "block");
1150 return 0; 1230 return 0;
1151} 1231}
1152 1232
@@ -1160,6 +1240,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1160 list_del_init(&rdev->same_set); 1240 list_del_init(&rdev->same_set);
1161 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1241 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1162 rdev->mddev = NULL; 1242 rdev->mddev = NULL;
1243 sysfs_remove_link(&rdev->kobj, "block");
1244 kobject_del(&rdev->kobj);
1163} 1245}
1164 1246
1165/* 1247/*
@@ -1215,7 +1297,7 @@ static void export_rdev(mdk_rdev_t * rdev)
1215 md_autodetect_dev(rdev->bdev->bd_dev); 1297 md_autodetect_dev(rdev->bdev->bd_dev);
1216#endif 1298#endif
1217 unlock_rdev(rdev); 1299 unlock_rdev(rdev);
1218 kfree(rdev); 1300 kobject_put(&rdev->kobj);
1219} 1301}
1220 1302
1221static void kick_rdev_from_array(mdk_rdev_t * rdev) 1303static void kick_rdev_from_array(mdk_rdev_t * rdev)
@@ -1287,7 +1369,8 @@ static void print_rdev(mdk_rdev_t *rdev)
1287 char b[BDEVNAME_SIZE]; 1369 char b[BDEVNAME_SIZE];
1288 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", 1370 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
1289 bdevname(rdev->bdev,b), (unsigned long long)rdev->size, 1371 bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
1290 rdev->faulty, rdev->in_sync, rdev->desc_nr); 1372 test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
1373 rdev->desc_nr);
1291 if (rdev->sb_loaded) { 1374 if (rdev->sb_loaded) {
1292 printk(KERN_INFO "md: rdev superblock:\n"); 1375 printk(KERN_INFO "md: rdev superblock:\n");
1293 print_sb((mdp_super_t*)page_address(rdev->sb_page)); 1376 print_sb((mdp_super_t*)page_address(rdev->sb_page));
@@ -1344,7 +1427,7 @@ static void md_update_sb(mddev_t * mddev)
1344 int sync_req; 1427 int sync_req;
1345 1428
1346repeat: 1429repeat:
1347 spin_lock(&mddev->write_lock); 1430 spin_lock_irq(&mddev->write_lock);
1348 sync_req = mddev->in_sync; 1431 sync_req = mddev->in_sync;
1349 mddev->utime = get_seconds(); 1432 mddev->utime = get_seconds();
1350 mddev->events ++; 1433 mddev->events ++;
@@ -1367,11 +1450,11 @@ repeat:
1367 */ 1450 */
1368 if (!mddev->persistent) { 1451 if (!mddev->persistent) {
1369 mddev->sb_dirty = 0; 1452 mddev->sb_dirty = 0;
1370 spin_unlock(&mddev->write_lock); 1453 spin_unlock_irq(&mddev->write_lock);
1371 wake_up(&mddev->sb_wait); 1454 wake_up(&mddev->sb_wait);
1372 return; 1455 return;
1373 } 1456 }
1374 spin_unlock(&mddev->write_lock); 1457 spin_unlock_irq(&mddev->write_lock);
1375 1458
1376 dprintk(KERN_INFO 1459 dprintk(KERN_INFO
1377 "md: updating %s RAID superblock on device (in sync %d)\n", 1460 "md: updating %s RAID superblock on device (in sync %d)\n",
@@ -1381,11 +1464,11 @@ repeat:
1381 ITERATE_RDEV(mddev,rdev,tmp) { 1464 ITERATE_RDEV(mddev,rdev,tmp) {
1382 char b[BDEVNAME_SIZE]; 1465 char b[BDEVNAME_SIZE];
1383 dprintk(KERN_INFO "md: "); 1466 dprintk(KERN_INFO "md: ");
1384 if (rdev->faulty) 1467 if (test_bit(Faulty, &rdev->flags))
1385 dprintk("(skipping faulty "); 1468 dprintk("(skipping faulty ");
1386 1469
1387 dprintk("%s ", bdevname(rdev->bdev,b)); 1470 dprintk("%s ", bdevname(rdev->bdev,b));
1388 if (!rdev->faulty) { 1471 if (!test_bit(Faulty, &rdev->flags)) {
1389 md_super_write(mddev,rdev, 1472 md_super_write(mddev,rdev,
1390 rdev->sb_offset<<1, rdev->sb_size, 1473 rdev->sb_offset<<1, rdev->sb_size,
1391 rdev->sb_page); 1474 rdev->sb_page);
@@ -1399,21 +1482,106 @@ repeat:
1399 /* only need to write one superblock... */ 1482 /* only need to write one superblock... */
1400 break; 1483 break;
1401 } 1484 }
1402 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 1485 md_super_wait(mddev);
1403 /* if there was a failure, sb_dirty was set to 1, and we re-write super */ 1486 /* if there was a failure, sb_dirty was set to 1, and we re-write super */
1404 1487
1405 spin_lock(&mddev->write_lock); 1488 spin_lock_irq(&mddev->write_lock);
1406 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { 1489 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
1407 /* have to write it out again */ 1490 /* have to write it out again */
1408 spin_unlock(&mddev->write_lock); 1491 spin_unlock_irq(&mddev->write_lock);
1409 goto repeat; 1492 goto repeat;
1410 } 1493 }
1411 mddev->sb_dirty = 0; 1494 mddev->sb_dirty = 0;
1412 spin_unlock(&mddev->write_lock); 1495 spin_unlock_irq(&mddev->write_lock);
1413 wake_up(&mddev->sb_wait); 1496 wake_up(&mddev->sb_wait);
1414 1497
1415} 1498}
1416 1499
1500struct rdev_sysfs_entry {
1501 struct attribute attr;
1502 ssize_t (*show)(mdk_rdev_t *, char *);
1503 ssize_t (*store)(mdk_rdev_t *, const char *, size_t);
1504};
1505
1506static ssize_t
1507state_show(mdk_rdev_t *rdev, char *page)
1508{
1509 char *sep = "";
1510 int len=0;
1511
1512 if (test_bit(Faulty, &rdev->flags)) {
1513 len+= sprintf(page+len, "%sfaulty",sep);
1514 sep = ",";
1515 }
1516 if (test_bit(In_sync, &rdev->flags)) {
1517 len += sprintf(page+len, "%sin_sync",sep);
1518 sep = ",";
1519 }
1520 if (!test_bit(Faulty, &rdev->flags) &&
1521 !test_bit(In_sync, &rdev->flags)) {
1522 len += sprintf(page+len, "%sspare", sep);
1523 sep = ",";
1524 }
1525 return len+sprintf(page+len, "\n");
1526}
1527
1528static struct rdev_sysfs_entry
1529rdev_state = __ATTR_RO(state);
1530
1531static ssize_t
1532super_show(mdk_rdev_t *rdev, char *page)
1533{
1534 if (rdev->sb_loaded && rdev->sb_size) {
1535 memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
1536 return rdev->sb_size;
1537 } else
1538 return 0;
1539}
1540static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
1541
1542static struct attribute *rdev_default_attrs[] = {
1543 &rdev_state.attr,
1544 &rdev_super.attr,
1545 NULL,
1546};
1547static ssize_t
1548rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1549{
1550 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1551 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1552
1553 if (!entry->show)
1554 return -EIO;
1555 return entry->show(rdev, page);
1556}
1557
1558static ssize_t
1559rdev_attr_store(struct kobject *kobj, struct attribute *attr,
1560 const char *page, size_t length)
1561{
1562 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1563 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1564
1565 if (!entry->store)
1566 return -EIO;
1567 return entry->store(rdev, page, length);
1568}
1569
1570static void rdev_free(struct kobject *ko)
1571{
1572 mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
1573 kfree(rdev);
1574}
1575static struct sysfs_ops rdev_sysfs_ops = {
1576 .show = rdev_attr_show,
1577 .store = rdev_attr_store,
1578};
1579static struct kobj_type rdev_ktype = {
1580 .release = rdev_free,
1581 .sysfs_ops = &rdev_sysfs_ops,
1582 .default_attrs = rdev_default_attrs,
1583};
1584
1417/* 1585/*
1418 * Import a device. If 'super_format' >= 0, then sanity check the superblock 1586 * Import a device. If 'super_format' >= 0, then sanity check the superblock
1419 * 1587 *
@@ -1445,11 +1613,15 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
1445 if (err) 1613 if (err)
1446 goto abort_free; 1614 goto abort_free;
1447 1615
1616 rdev->kobj.parent = NULL;
1617 rdev->kobj.ktype = &rdev_ktype;
1618 kobject_init(&rdev->kobj);
1619
1448 rdev->desc_nr = -1; 1620 rdev->desc_nr = -1;
1449 rdev->faulty = 0; 1621 rdev->flags = 0;
1450 rdev->in_sync = 0;
1451 rdev->data_offset = 0; 1622 rdev->data_offset = 0;
1452 atomic_set(&rdev->nr_pending, 0); 1623 atomic_set(&rdev->nr_pending, 0);
1624 atomic_set(&rdev->read_errors, 0);
1453 1625
1454 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 1626 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
1455 if (!size) { 1627 if (!size) {
@@ -1537,7 +1709,7 @@ static void analyze_sbs(mddev_t * mddev)
1537 if (mddev->level == LEVEL_MULTIPATH) { 1709 if (mddev->level == LEVEL_MULTIPATH) {
1538 rdev->desc_nr = i++; 1710 rdev->desc_nr = i++;
1539 rdev->raid_disk = rdev->desc_nr; 1711 rdev->raid_disk = rdev->desc_nr;
1540 rdev->in_sync = 1; 1712 set_bit(In_sync, &rdev->flags);
1541 } 1713 }
1542 } 1714 }
1543 1715
@@ -1551,6 +1723,162 @@ static void analyze_sbs(mddev_t * mddev)
1551 1723
1552} 1724}
1553 1725
1726static ssize_t
1727level_show(mddev_t *mddev, char *page)
1728{
1729 mdk_personality_t *p = mddev->pers;
1730 if (p == NULL && mddev->raid_disks == 0)
1731 return 0;
1732 if (mddev->level >= 0)
1733 return sprintf(page, "RAID-%d\n", mddev->level);
1734 else
1735 return sprintf(page, "%s\n", p->name);
1736}
1737
1738static struct md_sysfs_entry md_level = __ATTR_RO(level);
1739
1740static ssize_t
1741raid_disks_show(mddev_t *mddev, char *page)
1742{
1743 if (mddev->raid_disks == 0)
1744 return 0;
1745 return sprintf(page, "%d\n", mddev->raid_disks);
1746}
1747
1748static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
1749
1750static ssize_t
1751action_show(mddev_t *mddev, char *page)
1752{
1753 char *type = "idle";
1754 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1755 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
1756 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1757 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1758 type = "resync";
1759 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
1760 type = "check";
1761 else
1762 type = "repair";
1763 } else
1764 type = "recover";
1765 }
1766 return sprintf(page, "%s\n", type);
1767}
1768
1769static ssize_t
1770action_store(mddev_t *mddev, const char *page, size_t len)
1771{
1772 if (!mddev->pers || !mddev->pers->sync_request)
1773 return -EINVAL;
1774
1775 if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
1776 if (mddev->sync_thread) {
1777 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1778 md_unregister_thread(mddev->sync_thread);
1779 mddev->sync_thread = NULL;
1780 mddev->recovery = 0;
1781 }
1782 return len;
1783 }
1784
1785 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1786 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
1787 return -EBUSY;
1788 if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
1789 strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
1790 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1791 else {
1792 if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
1793 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
1794 else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
1795 return -EINVAL;
1796 set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
1797 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
1798 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1799 }
1800 md_wakeup_thread(mddev->thread);
1801 return len;
1802}
1803
1804static ssize_t
1805mismatch_cnt_show(mddev_t *mddev, char *page)
1806{
1807 return sprintf(page, "%llu\n",
1808 (unsigned long long) mddev->resync_mismatches);
1809}
1810
1811static struct md_sysfs_entry
1812md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
1813
1814
1815static struct md_sysfs_entry
1816md_mismatches = __ATTR_RO(mismatch_cnt);
1817
1818static struct attribute *md_default_attrs[] = {
1819 &md_level.attr,
1820 &md_raid_disks.attr,
1821 NULL,
1822};
1823
1824static struct attribute *md_redundancy_attrs[] = {
1825 &md_scan_mode.attr,
1826 &md_mismatches.attr,
1827 NULL,
1828};
1829static struct attribute_group md_redundancy_group = {
1830 .name = NULL,
1831 .attrs = md_redundancy_attrs,
1832};
1833
1834
1835static ssize_t
1836md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1837{
1838 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1839 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1840 ssize_t rv;
1841
1842 if (!entry->show)
1843 return -EIO;
1844 mddev_lock(mddev);
1845 rv = entry->show(mddev, page);
1846 mddev_unlock(mddev);
1847 return rv;
1848}
1849
1850static ssize_t
1851md_attr_store(struct kobject *kobj, struct attribute *attr,
1852 const char *page, size_t length)
1853{
1854 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1855 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1856 ssize_t rv;
1857
1858 if (!entry->store)
1859 return -EIO;
1860 mddev_lock(mddev);
1861 rv = entry->store(mddev, page, length);
1862 mddev_unlock(mddev);
1863 return rv;
1864}
1865
1866static void md_free(struct kobject *ko)
1867{
1868 mddev_t *mddev = container_of(ko, mddev_t, kobj);
1869 kfree(mddev);
1870}
1871
1872static struct sysfs_ops md_sysfs_ops = {
1873 .show = md_attr_show,
1874 .store = md_attr_store,
1875};
1876static struct kobj_type md_ktype = {
1877 .release = md_free,
1878 .sysfs_ops = &md_sysfs_ops,
1879 .default_attrs = md_default_attrs,
1880};
1881
1554int mdp_major = 0; 1882int mdp_major = 0;
1555 1883
1556static struct kobject *md_probe(dev_t dev, int *part, void *data) 1884static struct kobject *md_probe(dev_t dev, int *part, void *data)
@@ -1592,6 +1920,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
1592 add_disk(disk); 1920 add_disk(disk);
1593 mddev->gendisk = disk; 1921 mddev->gendisk = disk;
1594 up(&disks_sem); 1922 up(&disks_sem);
1923 mddev->kobj.parent = &disk->kobj;
1924 mddev->kobj.k_name = NULL;
1925 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
1926 mddev->kobj.ktype = &md_ktype;
1927 kobject_register(&mddev->kobj);
1595 return NULL; 1928 return NULL;
1596} 1929}
1597 1930
@@ -1663,7 +1996,7 @@ static int do_md_run(mddev_t * mddev)
1663 1996
1664 /* devices must have minimum size of one chunk */ 1997 /* devices must have minimum size of one chunk */
1665 ITERATE_RDEV(mddev,rdev,tmp) { 1998 ITERATE_RDEV(mddev,rdev,tmp) {
1666 if (rdev->faulty) 1999 if (test_bit(Faulty, &rdev->flags))
1667 continue; 2000 continue;
1668 if (rdev->size < chunk_size / 1024) { 2001 if (rdev->size < chunk_size / 1024) {
1669 printk(KERN_WARNING 2002 printk(KERN_WARNING
@@ -1691,7 +2024,7 @@ static int do_md_run(mddev_t * mddev)
1691 * Also find largest hardsector size 2024 * Also find largest hardsector size
1692 */ 2025 */
1693 ITERATE_RDEV(mddev,rdev,tmp) { 2026 ITERATE_RDEV(mddev,rdev,tmp) {
1694 if (rdev->faulty) 2027 if (test_bit(Faulty, &rdev->flags))
1695 continue; 2028 continue;
1696 sync_blockdev(rdev->bdev); 2029 sync_blockdev(rdev->bdev);
1697 invalidate_bdev(rdev->bdev, 0); 2030 invalidate_bdev(rdev->bdev, 0);
@@ -1715,6 +2048,10 @@ static int do_md_run(mddev_t * mddev)
1715 2048
1716 mddev->recovery = 0; 2049 mddev->recovery = 0;
1717 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2050 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2051 mddev->barriers_work = 1;
2052
2053 if (start_readonly)
2054 mddev->ro = 2; /* read-only, but switch on first write */
1718 2055
1719 /* before we start the array running, initialise the bitmap */ 2056 /* before we start the array running, initialise the bitmap */
1720 err = bitmap_create(mddev); 2057 err = bitmap_create(mddev);
@@ -1730,12 +2067,24 @@ static int do_md_run(mddev_t * mddev)
1730 bitmap_destroy(mddev); 2067 bitmap_destroy(mddev);
1731 return err; 2068 return err;
1732 } 2069 }
2070 if (mddev->pers->sync_request)
2071 sysfs_create_group(&mddev->kobj, &md_redundancy_group);
2072 else if (mddev->ro == 2) /* auto-readonly not meaningful */
2073 mddev->ro = 0;
2074
1733 atomic_set(&mddev->writes_pending,0); 2075 atomic_set(&mddev->writes_pending,0);
1734 mddev->safemode = 0; 2076 mddev->safemode = 0;
1735 mddev->safemode_timer.function = md_safemode_timeout; 2077 mddev->safemode_timer.function = md_safemode_timeout;
1736 mddev->safemode_timer.data = (unsigned long) mddev; 2078 mddev->safemode_timer.data = (unsigned long) mddev;
1737 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2079 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
1738 mddev->in_sync = 1; 2080 mddev->in_sync = 1;
2081
2082 ITERATE_RDEV(mddev,rdev,tmp)
2083 if (rdev->raid_disk >= 0) {
2084 char nm[20];
2085 sprintf(nm, "rd%d", rdev->raid_disk);
2086 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
2087 }
1739 2088
1740 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2089 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1741 md_wakeup_thread(mddev->thread); 2090 md_wakeup_thread(mddev->thread);
@@ -1821,16 +2170,19 @@ static int do_md_stop(mddev_t * mddev, int ro)
1821 2170
1822 if (ro) { 2171 if (ro) {
1823 err = -ENXIO; 2172 err = -ENXIO;
1824 if (mddev->ro) 2173 if (mddev->ro==1)
1825 goto out; 2174 goto out;
1826 mddev->ro = 1; 2175 mddev->ro = 1;
1827 } else { 2176 } else {
1828 bitmap_flush(mddev); 2177 bitmap_flush(mddev);
1829 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 2178 md_super_wait(mddev);
1830 if (mddev->ro) 2179 if (mddev->ro)
1831 set_disk_ro(disk, 0); 2180 set_disk_ro(disk, 0);
1832 blk_queue_make_request(mddev->queue, md_fail_request); 2181 blk_queue_make_request(mddev->queue, md_fail_request);
1833 mddev->pers->stop(mddev); 2182 mddev->pers->stop(mddev);
2183 if (mddev->pers->sync_request)
2184 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
2185
1834 module_put(mddev->pers->owner); 2186 module_put(mddev->pers->owner);
1835 mddev->pers = NULL; 2187 mddev->pers = NULL;
1836 if (mddev->ro) 2188 if (mddev->ro)
@@ -1857,9 +2209,18 @@ static int do_md_stop(mddev_t * mddev, int ro)
1857 * Free resources if final stop 2209 * Free resources if final stop
1858 */ 2210 */
1859 if (!ro) { 2211 if (!ro) {
2212 mdk_rdev_t *rdev;
2213 struct list_head *tmp;
1860 struct gendisk *disk; 2214 struct gendisk *disk;
1861 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); 2215 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
1862 2216
2217 ITERATE_RDEV(mddev,rdev,tmp)
2218 if (rdev->raid_disk >= 0) {
2219 char nm[20];
2220 sprintf(nm, "rd%d", rdev->raid_disk);
2221 sysfs_remove_link(&mddev->kobj, nm);
2222 }
2223
1863 export_array(mddev); 2224 export_array(mddev);
1864 2225
1865 mddev->array_size = 0; 2226 mddev->array_size = 0;
@@ -2012,7 +2373,7 @@ static int autostart_array(dev_t startdev)
2012 return err; 2373 return err;
2013 } 2374 }
2014 2375
2015 if (start_rdev->faulty) { 2376 if (test_bit(Faulty, &start_rdev->flags)) {
2016 printk(KERN_WARNING 2377 printk(KERN_WARNING
2017 "md: can not autostart based on faulty %s!\n", 2378 "md: can not autostart based on faulty %s!\n",
2018 bdevname(start_rdev->bdev,b)); 2379 bdevname(start_rdev->bdev,b));
@@ -2071,11 +2432,11 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
2071 nr=working=active=failed=spare=0; 2432 nr=working=active=failed=spare=0;
2072 ITERATE_RDEV(mddev,rdev,tmp) { 2433 ITERATE_RDEV(mddev,rdev,tmp) {
2073 nr++; 2434 nr++;
2074 if (rdev->faulty) 2435 if (test_bit(Faulty, &rdev->flags))
2075 failed++; 2436 failed++;
2076 else { 2437 else {
2077 working++; 2438 working++;
2078 if (rdev->in_sync) 2439 if (test_bit(In_sync, &rdev->flags))
2079 active++; 2440 active++;
2080 else 2441 else
2081 spare++; 2442 spare++;
@@ -2166,9 +2527,9 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
2166 info.minor = MINOR(rdev->bdev->bd_dev); 2527 info.minor = MINOR(rdev->bdev->bd_dev);
2167 info.raid_disk = rdev->raid_disk; 2528 info.raid_disk = rdev->raid_disk;
2168 info.state = 0; 2529 info.state = 0;
2169 if (rdev->faulty) 2530 if (test_bit(Faulty, &rdev->flags))
2170 info.state |= (1<<MD_DISK_FAULTY); 2531 info.state |= (1<<MD_DISK_FAULTY);
2171 else if (rdev->in_sync) { 2532 else if (test_bit(In_sync, &rdev->flags)) {
2172 info.state |= (1<<MD_DISK_ACTIVE); 2533 info.state |= (1<<MD_DISK_ACTIVE);
2173 info.state |= (1<<MD_DISK_SYNC); 2534 info.state |= (1<<MD_DISK_SYNC);
2174 } 2535 }
@@ -2261,7 +2622,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2261 validate_super(mddev, rdev); 2622 validate_super(mddev, rdev);
2262 rdev->saved_raid_disk = rdev->raid_disk; 2623 rdev->saved_raid_disk = rdev->raid_disk;
2263 2624
2264 rdev->in_sync = 0; /* just to be sure */ 2625 clear_bit(In_sync, &rdev->flags); /* just to be sure */
2265 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2626 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2266 set_bit(WriteMostly, &rdev->flags); 2627 set_bit(WriteMostly, &rdev->flags);
2267 2628
@@ -2299,11 +2660,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2299 else 2660 else
2300 rdev->raid_disk = -1; 2661 rdev->raid_disk = -1;
2301 2662
2302 rdev->faulty = 0; 2663 rdev->flags = 0;
2664
2303 if (rdev->raid_disk < mddev->raid_disks) 2665 if (rdev->raid_disk < mddev->raid_disks)
2304 rdev->in_sync = (info->state & (1<<MD_DISK_SYNC)); 2666 if (info->state & (1<<MD_DISK_SYNC))
2305 else 2667 set_bit(In_sync, &rdev->flags);
2306 rdev->in_sync = 0;
2307 2668
2308 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2669 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2309 set_bit(WriteMostly, &rdev->flags); 2670 set_bit(WriteMostly, &rdev->flags);
@@ -2402,14 +2763,14 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
2402 goto abort_export; 2763 goto abort_export;
2403 } 2764 }
2404 2765
2405 if (rdev->faulty) { 2766 if (test_bit(Faulty, &rdev->flags)) {
2406 printk(KERN_WARNING 2767 printk(KERN_WARNING
2407 "md: can not hot-add faulty %s disk to %s!\n", 2768 "md: can not hot-add faulty %s disk to %s!\n",
2408 bdevname(rdev->bdev,b), mdname(mddev)); 2769 bdevname(rdev->bdev,b), mdname(mddev));
2409 err = -EINVAL; 2770 err = -EINVAL;
2410 goto abort_export; 2771 goto abort_export;
2411 } 2772 }
2412 rdev->in_sync = 0; 2773 clear_bit(In_sync, &rdev->flags);
2413 rdev->desc_nr = -1; 2774 rdev->desc_nr = -1;
2414 bind_rdev_to_array(rdev, mddev); 2775 bind_rdev_to_array(rdev, mddev);
2415 2776
@@ -2929,12 +3290,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
2929 3290
2930 /* 3291 /*
2931 * The remaining ioctls are changing the state of the 3292 * The remaining ioctls are changing the state of the
2932 * superblock, so we do not allow read-only arrays 3293 * superblock, so we do not allow them on read-only arrays.
2933 * here: 3294 * However non-MD ioctls (e.g. get-size) will still come through
3295 * here and hit the 'default' below, so only disallow
3296 * 'md' ioctls, and switch to rw mode if started auto-readonly.
2934 */ 3297 */
2935 if (mddev->ro) { 3298 if (_IOC_TYPE(cmd) == MD_MAJOR &&
2936 err = -EROFS; 3299 mddev->ro && mddev->pers) {
2937 goto abort_unlock; 3300 if (mddev->ro == 2) {
3301 mddev->ro = 0;
3302 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3303 md_wakeup_thread(mddev->thread);
3304
3305 } else {
3306 err = -EROFS;
3307 goto abort_unlock;
3308 }
2938 } 3309 }
2939 3310
2940 switch (cmd) 3311 switch (cmd)
@@ -3064,21 +3435,17 @@ static int md_thread(void * arg)
3064 */ 3435 */
3065 3436
3066 allow_signal(SIGKILL); 3437 allow_signal(SIGKILL);
3067 complete(thread->event);
3068 while (!kthread_should_stop()) { 3438 while (!kthread_should_stop()) {
3069 void (*run)(mddev_t *);
3070 3439
3071 wait_event_interruptible_timeout(thread->wqueue, 3440 wait_event_timeout(thread->wqueue,
3072 test_bit(THREAD_WAKEUP, &thread->flags) 3441 test_bit(THREAD_WAKEUP, &thread->flags)
3073 || kthread_should_stop(), 3442 || kthread_should_stop(),
3074 thread->timeout); 3443 thread->timeout);
3075 try_to_freeze(); 3444 try_to_freeze();
3076 3445
3077 clear_bit(THREAD_WAKEUP, &thread->flags); 3446 clear_bit(THREAD_WAKEUP, &thread->flags);
3078 3447
3079 run = thread->run; 3448 thread->run(thread->mddev);
3080 if (run)
3081 run(thread->mddev);
3082 } 3449 }
3083 3450
3084 return 0; 3451 return 0;
@@ -3097,7 +3464,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3097 const char *name) 3464 const char *name)
3098{ 3465{
3099 mdk_thread_t *thread; 3466 mdk_thread_t *thread;
3100 struct completion event;
3101 3467
3102 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL); 3468 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
3103 if (!thread) 3469 if (!thread)
@@ -3106,18 +3472,14 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3106 memset(thread, 0, sizeof(mdk_thread_t)); 3472 memset(thread, 0, sizeof(mdk_thread_t));
3107 init_waitqueue_head(&thread->wqueue); 3473 init_waitqueue_head(&thread->wqueue);
3108 3474
3109 init_completion(&event);
3110 thread->event = &event;
3111 thread->run = run; 3475 thread->run = run;
3112 thread->mddev = mddev; 3476 thread->mddev = mddev;
3113 thread->name = name;
3114 thread->timeout = MAX_SCHEDULE_TIMEOUT; 3477 thread->timeout = MAX_SCHEDULE_TIMEOUT;
3115 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev)); 3478 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
3116 if (IS_ERR(thread->tsk)) { 3479 if (IS_ERR(thread->tsk)) {
3117 kfree(thread); 3480 kfree(thread);
3118 return NULL; 3481 return NULL;
3119 } 3482 }
3120 wait_for_completion(&event);
3121 return thread; 3483 return thread;
3122} 3484}
3123 3485
@@ -3136,7 +3498,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
3136 return; 3498 return;
3137 } 3499 }
3138 3500
3139 if (!rdev || rdev->faulty) 3501 if (!rdev || test_bit(Faulty, &rdev->flags))
3140 return; 3502 return;
3141/* 3503/*
3142 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", 3504 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
@@ -3322,8 +3684,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
3322 seq_printf(seq, "%s : %sactive", mdname(mddev), 3684 seq_printf(seq, "%s : %sactive", mdname(mddev),
3323 mddev->pers ? "" : "in"); 3685 mddev->pers ? "" : "in");
3324 if (mddev->pers) { 3686 if (mddev->pers) {
3325 if (mddev->ro) 3687 if (mddev->ro==1)
3326 seq_printf(seq, " (read-only)"); 3688 seq_printf(seq, " (read-only)");
3689 if (mddev->ro==2)
3690 seq_printf(seq, "(auto-read-only)");
3327 seq_printf(seq, " %s", mddev->pers->name); 3691 seq_printf(seq, " %s", mddev->pers->name);
3328 } 3692 }
3329 3693
@@ -3334,7 +3698,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
3334 bdevname(rdev->bdev,b), rdev->desc_nr); 3698 bdevname(rdev->bdev,b), rdev->desc_nr);
3335 if (test_bit(WriteMostly, &rdev->flags)) 3699 if (test_bit(WriteMostly, &rdev->flags))
3336 seq_printf(seq, "(W)"); 3700 seq_printf(seq, "(W)");
3337 if (rdev->faulty) { 3701 if (test_bit(Faulty, &rdev->flags)) {
3338 seq_printf(seq, "(F)"); 3702 seq_printf(seq, "(F)");
3339 continue; 3703 continue;
3340 } else if (rdev->raid_disk < 0) 3704 } else if (rdev->raid_disk < 0)
@@ -3363,11 +3727,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
3363 if (mddev->pers) { 3727 if (mddev->pers) {
3364 mddev->pers->status (seq, mddev); 3728 mddev->pers->status (seq, mddev);
3365 seq_printf(seq, "\n "); 3729 seq_printf(seq, "\n ");
3366 if (mddev->curr_resync > 2) { 3730 if (mddev->pers->sync_request) {
3367 status_resync (seq, mddev); 3731 if (mddev->curr_resync > 2) {
3368 seq_printf(seq, "\n "); 3732 status_resync (seq, mddev);
3369 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 3733 seq_printf(seq, "\n ");
3370 seq_printf(seq, " resync=DELAYED\n "); 3734 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
3735 seq_printf(seq, "\tresync=DELAYED\n ");
3736 else if (mddev->recovery_cp < MaxSector)
3737 seq_printf(seq, "\tresync=PENDING\n ");
3738 }
3371 } else 3739 } else
3372 seq_printf(seq, "\n "); 3740 seq_printf(seq, "\n ");
3373 3741
@@ -3504,15 +3872,22 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
3504 if (bio_data_dir(bi) != WRITE) 3872 if (bio_data_dir(bi) != WRITE)
3505 return; 3873 return;
3506 3874
3875 BUG_ON(mddev->ro == 1);
3876 if (mddev->ro == 2) {
3877 /* need to switch to read/write */
3878 mddev->ro = 0;
3879 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3880 md_wakeup_thread(mddev->thread);
3881 }
3507 atomic_inc(&mddev->writes_pending); 3882 atomic_inc(&mddev->writes_pending);
3508 if (mddev->in_sync) { 3883 if (mddev->in_sync) {
3509 spin_lock(&mddev->write_lock); 3884 spin_lock_irq(&mddev->write_lock);
3510 if (mddev->in_sync) { 3885 if (mddev->in_sync) {
3511 mddev->in_sync = 0; 3886 mddev->in_sync = 0;
3512 mddev->sb_dirty = 1; 3887 mddev->sb_dirty = 1;
3513 md_wakeup_thread(mddev->thread); 3888 md_wakeup_thread(mddev->thread);
3514 } 3889 }
3515 spin_unlock(&mddev->write_lock); 3890 spin_unlock_irq(&mddev->write_lock);
3516 } 3891 }
3517 wait_event(mddev->sb_wait, mddev->sb_dirty==0); 3892 wait_event(mddev->sb_wait, mddev->sb_dirty==0);
3518} 3893}
@@ -3568,9 +3943,7 @@ static void md_do_sync(mddev_t *mddev)
3568 mddev->curr_resync = 2; 3943 mddev->curr_resync = 2;
3569 3944
3570 try_again: 3945 try_again:
3571 if (signal_pending(current) || 3946 if (kthread_should_stop()) {
3572 kthread_should_stop()) {
3573 flush_signals(current);
3574 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 3947 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3575 goto skip; 3948 goto skip;
3576 } 3949 }
@@ -3590,9 +3963,8 @@ static void md_do_sync(mddev_t *mddev)
3590 * time 'round when curr_resync == 2 3963 * time 'round when curr_resync == 2
3591 */ 3964 */
3592 continue; 3965 continue;
3593 prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); 3966 prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
3594 if (!signal_pending(current) && 3967 if (!kthread_should_stop() &&
3595 !kthread_should_stop() &&
3596 mddev2->curr_resync >= mddev->curr_resync) { 3968 mddev2->curr_resync >= mddev->curr_resync) {
3597 printk(KERN_INFO "md: delaying resync of %s" 3969 printk(KERN_INFO "md: delaying resync of %s"
3598 " until %s has finished resync (they" 3970 " until %s has finished resync (they"
@@ -3608,12 +3980,13 @@ static void md_do_sync(mddev_t *mddev)
3608 } 3980 }
3609 } while (mddev->curr_resync < 2); 3981 } while (mddev->curr_resync < 2);
3610 3982
3611 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 3983 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
3612 /* resync follows the size requested by the personality, 3984 /* resync follows the size requested by the personality,
3613 * which defaults to physical size, but can be virtual size 3985 * which defaults to physical size, but can be virtual size
3614 */ 3986 */
3615 max_sectors = mddev->resync_max_sectors; 3987 max_sectors = mddev->resync_max_sectors;
3616 else 3988 mddev->resync_mismatches = 0;
3989 } else
3617 /* recovery follows the physical size of devices */ 3990 /* recovery follows the physical size of devices */
3618 max_sectors = mddev->size << 1; 3991 max_sectors = mddev->size << 1;
3619 3992
@@ -3626,7 +3999,8 @@ static void md_do_sync(mddev_t *mddev)
3626 3999
3627 is_mddev_idle(mddev); /* this also initializes IO event counters */ 4000 is_mddev_idle(mddev); /* this also initializes IO event counters */
3628 /* we don't use the checkpoint if there's a bitmap */ 4001 /* we don't use the checkpoint if there's a bitmap */
3629 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) 4002 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
4003 && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
3630 j = mddev->recovery_cp; 4004 j = mddev->recovery_cp;
3631 else 4005 else
3632 j = 0; 4006 j = 0;
@@ -3699,13 +4073,12 @@ static void md_do_sync(mddev_t *mddev)
3699 } 4073 }
3700 4074
3701 4075
3702 if (signal_pending(current) || kthread_should_stop()) { 4076 if (kthread_should_stop()) {
3703 /* 4077 /*
3704 * got a signal, exit. 4078 * got a signal, exit.
3705 */ 4079 */
3706 printk(KERN_INFO 4080 printk(KERN_INFO
3707 "md: md_do_sync() got signal ... exiting\n"); 4081 "md: md_do_sync() got signal ... exiting\n");
3708 flush_signals(current);
3709 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 4082 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3710 goto out; 4083 goto out;
3711 } 4084 }
@@ -3727,7 +4100,7 @@ static void md_do_sync(mddev_t *mddev)
3727 if (currspeed > sysctl_speed_limit_min) { 4100 if (currspeed > sysctl_speed_limit_min) {
3728 if ((currspeed > sysctl_speed_limit_max) || 4101 if ((currspeed > sysctl_speed_limit_max) ||
3729 !is_mddev_idle(mddev)) { 4102 !is_mddev_idle(mddev)) {
3730 msleep_interruptible(250); 4103 msleep(250);
3731 goto repeat; 4104 goto repeat;
3732 } 4105 }
3733 } 4106 }
@@ -3820,7 +4193,7 @@ void md_check_recovery(mddev_t *mddev)
3820 if (mddev_trylock(mddev)==0) { 4193 if (mddev_trylock(mddev)==0) {
3821 int spares =0; 4194 int spares =0;
3822 4195
3823 spin_lock(&mddev->write_lock); 4196 spin_lock_irq(&mddev->write_lock);
3824 if (mddev->safemode && !atomic_read(&mddev->writes_pending) && 4197 if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
3825 !mddev->in_sync && mddev->recovery_cp == MaxSector) { 4198 !mddev->in_sync && mddev->recovery_cp == MaxSector) {
3826 mddev->in_sync = 1; 4199 mddev->in_sync = 1;
@@ -3828,7 +4201,7 @@ void md_check_recovery(mddev_t *mddev)
3828 } 4201 }
3829 if (mddev->safemode == 1) 4202 if (mddev->safemode == 1)
3830 mddev->safemode = 0; 4203 mddev->safemode = 0;
3831 spin_unlock(&mddev->write_lock); 4204 spin_unlock_irq(&mddev->write_lock);
3832 4205
3833 if (mddev->sb_dirty) 4206 if (mddev->sb_dirty)
3834 md_update_sb(mddev); 4207 md_update_sb(mddev);
@@ -3864,9 +4237,13 @@ void md_check_recovery(mddev_t *mddev)
3864 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3865 goto unlock; 4238 goto unlock;
3866 } 4239 }
3867 if (mddev->recovery) 4240 /* Clear some bits that don't mean anything, but
3868 /* probably just the RECOVERY_NEEDED flag */ 4241 * might be left set
3869 mddev->recovery = 0; 4242 */
4243 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4244 clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
4245 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
4246 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
3870 4247
3871 /* no recovery is running. 4248 /* no recovery is running.
3872 * remove any failed drives, then 4249 * remove any failed drives, then
@@ -3876,31 +4253,41 @@ void md_check_recovery(mddev_t *mddev)
3876 */ 4253 */
3877 ITERATE_RDEV(mddev,rdev,rtmp) 4254 ITERATE_RDEV(mddev,rdev,rtmp)
3878 if (rdev->raid_disk >= 0 && 4255 if (rdev->raid_disk >= 0 &&
3879 (rdev->faulty || ! rdev->in_sync) && 4256 (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
3880 atomic_read(&rdev->nr_pending)==0) { 4257 atomic_read(&rdev->nr_pending)==0) {
3881 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) 4258 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
4259 char nm[20];
4260 sprintf(nm,"rd%d", rdev->raid_disk);
4261 sysfs_remove_link(&mddev->kobj, nm);
3882 rdev->raid_disk = -1; 4262 rdev->raid_disk = -1;
4263 }
3883 } 4264 }
3884 4265
3885 if (mddev->degraded) { 4266 if (mddev->degraded) {
3886 ITERATE_RDEV(mddev,rdev,rtmp) 4267 ITERATE_RDEV(mddev,rdev,rtmp)
3887 if (rdev->raid_disk < 0 4268 if (rdev->raid_disk < 0
3888 && !rdev->faulty) { 4269 && !test_bit(Faulty, &rdev->flags)) {
3889 if (mddev->pers->hot_add_disk(mddev,rdev)) 4270 if (mddev->pers->hot_add_disk(mddev,rdev)) {
4271 char nm[20];
4272 sprintf(nm, "rd%d", rdev->raid_disk);
4273 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
3890 spares++; 4274 spares++;
3891 else 4275 } else
3892 break; 4276 break;
3893 } 4277 }
3894 } 4278 }
3895 4279
3896 if (!spares && (mddev->recovery_cp == MaxSector )) { 4280 if (spares) {
3897 /* nothing we can do ... */ 4281 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4282 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
4283 } else if (mddev->recovery_cp < MaxSector) {
4284 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4285 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
4286 /* nothing to be done ... */
3898 goto unlock; 4287 goto unlock;
3899 } 4288
3900 if (mddev->pers->sync_request) { 4289 if (mddev->pers->sync_request) {
3901 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 4290 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3902 if (!spares)
3903 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3904 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 4291 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
3905 /* We are adding a device or devices to an array 4292 /* We are adding a device or devices to an array
3906 * which has the bitmap stored on all devices. 4293 * which has the bitmap stored on all devices.
@@ -3975,7 +4362,7 @@ static int __init md_init(void)
3975 " MD_SB_DISKS=%d\n", 4362 " MD_SB_DISKS=%d\n",
3976 MD_MAJOR_VERSION, MD_MINOR_VERSION, 4363 MD_MAJOR_VERSION, MD_MINOR_VERSION,
3977 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); 4364 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
3978 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR, 4365 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
3979 BITMAP_MINOR); 4366 BITMAP_MINOR);
3980 4367
3981 if (register_blkdev(MAJOR_NR, "md")) 4368 if (register_blkdev(MAJOR_NR, "md"))
@@ -4039,7 +4426,7 @@ static void autostart_arrays(int part)
4039 if (IS_ERR(rdev)) 4426 if (IS_ERR(rdev))
4040 continue; 4427 continue;
4041 4428
4042 if (rdev->faulty) { 4429 if (test_bit(Faulty, &rdev->flags)) {
4043 MD_BUG(); 4430 MD_BUG();
4044 continue; 4431 continue;
4045 } 4432 }
@@ -4086,6 +4473,23 @@ static __exit void md_exit(void)
4086module_init(md_init) 4473module_init(md_init)
4087module_exit(md_exit) 4474module_exit(md_exit)
4088 4475
4476static int get_ro(char *buffer, struct kernel_param *kp)
4477{
4478 return sprintf(buffer, "%d", start_readonly);
4479}
4480static int set_ro(const char *val, struct kernel_param *kp)
4481{
4482 char *e;
4483 int num = simple_strtoul(val, &e, 10);
4484 if (*val && (*e == '\0' || *e == '\n')) {
4485 start_readonly = num;
4486 return 0;;
4487 }
4488 return -EINVAL;
4489}
4490
4491module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
4492
4089EXPORT_SYMBOL(register_md_personality); 4493EXPORT_SYMBOL(register_md_personality);
4090EXPORT_SYMBOL(unregister_md_personality); 4494EXPORT_SYMBOL(unregister_md_personality);
4091EXPORT_SYMBOL(md_error); 4495EXPORT_SYMBOL(md_error);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c06f4474192b..145cdc5ad008 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -63,8 +63,8 @@ static int multipath_map (multipath_conf_t *conf)
63 63
64 rcu_read_lock(); 64 rcu_read_lock();
65 for (i = 0; i < disks; i++) { 65 for (i = 0; i < disks; i++) {
66 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 66 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
67 if (rdev && rdev->in_sync) { 67 if (rdev && test_bit(In_sync, &rdev->flags)) {
68 atomic_inc(&rdev->nr_pending); 68 atomic_inc(&rdev->nr_pending);
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 return i; 70 return i;
@@ -139,8 +139,9 @@ static void unplug_slaves(mddev_t *mddev)
139 139
140 rcu_read_lock(); 140 rcu_read_lock();
141 for (i=0; i<mddev->raid_disks; i++) { 141 for (i=0; i<mddev->raid_disks; i++) {
142 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 142 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
143 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 143 if (rdev && !test_bit(Faulty, &rdev->flags)
144 && atomic_read(&rdev->nr_pending)) {
144 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 145 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
145 146
146 atomic_inc(&rdev->nr_pending); 147 atomic_inc(&rdev->nr_pending);
@@ -211,7 +212,7 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
211 for (i = 0; i < conf->raid_disks; i++) 212 for (i = 0; i < conf->raid_disks; i++)
212 seq_printf (seq, "%s", 213 seq_printf (seq, "%s",
213 conf->multipaths[i].rdev && 214 conf->multipaths[i].rdev &&
214 conf->multipaths[i].rdev->in_sync ? "U" : "_"); 215 test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
215 seq_printf (seq, "]"); 216 seq_printf (seq, "]");
216} 217}
217 218
@@ -224,8 +225,8 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
224 225
225 rcu_read_lock(); 226 rcu_read_lock();
226 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 227 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
227 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 228 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
228 if (rdev && !rdev->faulty) { 229 if (rdev && !test_bit(Faulty, &rdev->flags)) {
229 struct block_device *bdev = rdev->bdev; 230 struct block_device *bdev = rdev->bdev;
230 request_queue_t *r_queue = bdev_get_queue(bdev); 231 request_queue_t *r_queue = bdev_get_queue(bdev);
231 232
@@ -265,10 +266,10 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
265 /* 266 /*
266 * Mark disk as unusable 267 * Mark disk as unusable
267 */ 268 */
268 if (!rdev->faulty) { 269 if (!test_bit(Faulty, &rdev->flags)) {
269 char b[BDEVNAME_SIZE]; 270 char b[BDEVNAME_SIZE];
270 rdev->in_sync = 0; 271 clear_bit(In_sync, &rdev->flags);
271 rdev->faulty = 1; 272 set_bit(Faulty, &rdev->flags);
272 mddev->sb_dirty = 1; 273 mddev->sb_dirty = 1;
273 conf->working_disks--; 274 conf->working_disks--;
274 printk(KERN_ALERT "multipath: IO failure on %s," 275 printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -298,7 +299,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
298 tmp = conf->multipaths + i; 299 tmp = conf->multipaths + i;
299 if (tmp->rdev) 300 if (tmp->rdev)
300 printk(" disk%d, o:%d, dev:%s\n", 301 printk(" disk%d, o:%d, dev:%s\n",
301 i,!tmp->rdev->faulty, 302 i,!test_bit(Faulty, &tmp->rdev->flags),
302 bdevname(tmp->rdev->bdev,b)); 303 bdevname(tmp->rdev->bdev,b));
303 } 304 }
304} 305}
@@ -330,8 +331,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
330 331
331 conf->working_disks++; 332 conf->working_disks++;
332 rdev->raid_disk = path; 333 rdev->raid_disk = path;
333 rdev->in_sync = 1; 334 set_bit(In_sync, &rdev->flags);
334 p->rdev = rdev; 335 rcu_assign_pointer(p->rdev, rdev);
335 found = 1; 336 found = 1;
336 } 337 }
337 338
@@ -350,7 +351,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
350 351
351 rdev = p->rdev; 352 rdev = p->rdev;
352 if (rdev) { 353 if (rdev) {
353 if (rdev->in_sync || 354 if (test_bit(In_sync, &rdev->flags) ||
354 atomic_read(&rdev->nr_pending)) { 355 atomic_read(&rdev->nr_pending)) {
355 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); 356 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number);
356 err = -EBUSY; 357 err = -EBUSY;
@@ -482,7 +483,7 @@ static int multipath_run (mddev_t *mddev)
482 mddev->queue->max_sectors > (PAGE_SIZE>>9)) 483 mddev->queue->max_sectors > (PAGE_SIZE>>9))
483 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 484 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
484 485
485 if (!rdev->faulty) 486 if (!test_bit(Faulty, &rdev->flags))
486 conf->working_disks++; 487 conf->working_disks++;
487 } 488 }
488 489
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e16f473bcf46..2da9d3ba902d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -301,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
301{ 301{
302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); 303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
304 int mirror, behind; 304 int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
305 conf_t *conf = mddev_to_conf(r1_bio->mddev); 305 conf_t *conf = mddev_to_conf(r1_bio->mddev);
306 306
307 if (bio->bi_size) 307 if (bio->bi_size)
@@ -311,47 +311,54 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
311 if (r1_bio->bios[mirror] == bio) 311 if (r1_bio->bios[mirror] == bio)
312 break; 312 break;
313 313
314 /* 314 if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
315 * this branch is our 'one mirror IO has finished' event handler: 315 set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
316 */ 316 set_bit(R1BIO_BarrierRetry, &r1_bio->state);
317 if (!uptodate) { 317 r1_bio->mddev->barriers_work = 0;
318 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); 318 } else {
319 /* an I/O failed, we can't clear the bitmap */
320 set_bit(R1BIO_Degraded, &r1_bio->state);
321 } else
322 /* 319 /*
323 * Set R1BIO_Uptodate in our master bio, so that 320 * this branch is our 'one mirror IO has finished' event handler:
324 * we will return a good error code for to the higher
325 * levels even if IO on some other mirrored buffer fails.
326 *
327 * The 'master' represents the composite IO operation to
328 * user-side. So if something waits for IO, then it will
329 * wait for the 'master' bio.
330 */ 321 */
331 set_bit(R1BIO_Uptodate, &r1_bio->state); 322 r1_bio->bios[mirror] = NULL;
332 323 bio_put(bio);
333 update_head_pos(mirror, r1_bio); 324 if (!uptodate) {
334 325 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
335 behind = test_bit(R1BIO_BehindIO, &r1_bio->state); 326 /* an I/O failed, we can't clear the bitmap */
336 if (behind) { 327 set_bit(R1BIO_Degraded, &r1_bio->state);
337 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags)) 328 } else
338 atomic_dec(&r1_bio->behind_remaining); 329 /*
339 330 * Set R1BIO_Uptodate in our master bio, so that
340 /* In behind mode, we ACK the master bio once the I/O has safely 331 * we will return a good error code for to the higher
341 * reached all non-writemostly disks. Setting the Returned bit 332 * levels even if IO on some other mirrored buffer fails.
342 * ensures that this gets done only once -- we don't ever want to 333 *
343 * return -EIO here, instead we'll wait */ 334 * The 'master' represents the composite IO operation to
344 335 * user-side. So if something waits for IO, then it will
345 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) && 336 * wait for the 'master' bio.
346 test_bit(R1BIO_Uptodate, &r1_bio->state)) { 337 */
347 /* Maybe we can return now */ 338 set_bit(R1BIO_Uptodate, &r1_bio->state);
348 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) { 339
349 struct bio *mbio = r1_bio->master_bio; 340 update_head_pos(mirror, r1_bio);
350 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n", 341
351 (unsigned long long) mbio->bi_sector, 342 if (behind) {
352 (unsigned long long) mbio->bi_sector + 343 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
353 (mbio->bi_size >> 9) - 1); 344 atomic_dec(&r1_bio->behind_remaining);
354 bio_endio(mbio, mbio->bi_size, 0); 345
346 /* In behind mode, we ACK the master bio once the I/O has safely
347 * reached all non-writemostly disks. Setting the Returned bit
348 * ensures that this gets done only once -- we don't ever want to
349 * return -EIO here, instead we'll wait */
350
351 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
352 test_bit(R1BIO_Uptodate, &r1_bio->state)) {
353 /* Maybe we can return now */
354 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
355 struct bio *mbio = r1_bio->master_bio;
356 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
357 (unsigned long long) mbio->bi_sector,
358 (unsigned long long) mbio->bi_sector +
359 (mbio->bi_size >> 9) - 1);
360 bio_endio(mbio, mbio->bi_size, 0);
361 }
355 } 362 }
356 } 363 }
357 } 364 }
@@ -361,8 +368,16 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
361 * already. 368 * already.
362 */ 369 */
363 if (atomic_dec_and_test(&r1_bio->remaining)) { 370 if (atomic_dec_and_test(&r1_bio->remaining)) {
371 if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
372 reschedule_retry(r1_bio);
373 /* Don't dec_pending yet, we want to hold
374 * the reference over the retry
375 */
376 return 0;
377 }
364 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { 378 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
365 /* free extra copy of the data pages */ 379 /* free extra copy of the data pages */
380/* FIXME bio has been freed!!! */
366 int i = bio->bi_vcnt; 381 int i = bio->bi_vcnt;
367 while (i--) 382 while (i--)
368 __free_page(bio->bi_io_vec[i].bv_page); 383 __free_page(bio->bi_io_vec[i].bv_page);
@@ -416,12 +431,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
416 /* Choose the first operation device, for consistancy */ 431 /* Choose the first operation device, for consistancy */
417 new_disk = 0; 432 new_disk = 0;
418 433
419 for (rdev = conf->mirrors[new_disk].rdev; 434 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
420 !rdev || !rdev->in_sync 435 !rdev || !test_bit(In_sync, &rdev->flags)
421 || test_bit(WriteMostly, &rdev->flags); 436 || test_bit(WriteMostly, &rdev->flags);
422 rdev = conf->mirrors[++new_disk].rdev) { 437 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
423 438
424 if (rdev && rdev->in_sync) 439 if (rdev && test_bit(In_sync, &rdev->flags))
425 wonly_disk = new_disk; 440 wonly_disk = new_disk;
426 441
427 if (new_disk == conf->raid_disks - 1) { 442 if (new_disk == conf->raid_disks - 1) {
@@ -434,12 +449,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
434 449
435 450
436 /* make sure the disk is operational */ 451 /* make sure the disk is operational */
437 for (rdev = conf->mirrors[new_disk].rdev; 452 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
438 !rdev || !rdev->in_sync || 453 !rdev || !test_bit(In_sync, &rdev->flags) ||
439 test_bit(WriteMostly, &rdev->flags); 454 test_bit(WriteMostly, &rdev->flags);
440 rdev = conf->mirrors[new_disk].rdev) { 455 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
441 456
442 if (rdev && rdev->in_sync) 457 if (rdev && test_bit(In_sync, &rdev->flags))
443 wonly_disk = new_disk; 458 wonly_disk = new_disk;
444 459
445 if (new_disk <= 0) 460 if (new_disk <= 0)
@@ -474,10 +489,10 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
474 disk = conf->raid_disks; 489 disk = conf->raid_disks;
475 disk--; 490 disk--;
476 491
477 rdev = conf->mirrors[disk].rdev; 492 rdev = rcu_dereference(conf->mirrors[disk].rdev);
478 493
479 if (!rdev || 494 if (!rdev ||
480 !rdev->in_sync || 495 !test_bit(In_sync, &rdev->flags) ||
481 test_bit(WriteMostly, &rdev->flags)) 496 test_bit(WriteMostly, &rdev->flags))
482 continue; 497 continue;
483 498
@@ -496,11 +511,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
496 511
497 512
498 if (new_disk >= 0) { 513 if (new_disk >= 0) {
499 rdev = conf->mirrors[new_disk].rdev; 514 rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
500 if (!rdev) 515 if (!rdev)
501 goto retry; 516 goto retry;
502 atomic_inc(&rdev->nr_pending); 517 atomic_inc(&rdev->nr_pending);
503 if (!rdev->in_sync) { 518 if (!test_bit(In_sync, &rdev->flags)) {
504 /* cannot risk returning a device that failed 519 /* cannot risk returning a device that failed
505 * before we inc'ed nr_pending 520 * before we inc'ed nr_pending
506 */ 521 */
@@ -522,8 +537,8 @@ static void unplug_slaves(mddev_t *mddev)
522 537
523 rcu_read_lock(); 538 rcu_read_lock();
524 for (i=0; i<mddev->raid_disks; i++) { 539 for (i=0; i<mddev->raid_disks; i++) {
525 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 540 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
526 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 541 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
527 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 542 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
528 543
529 atomic_inc(&rdev->nr_pending); 544 atomic_inc(&rdev->nr_pending);
@@ -556,8 +571,8 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
556 571
557 rcu_read_lock(); 572 rcu_read_lock();
558 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 573 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
559 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 574 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
560 if (rdev && !rdev->faulty) { 575 if (rdev && !test_bit(Faulty, &rdev->flags)) {
561 struct block_device *bdev = rdev->bdev; 576 struct block_device *bdev = rdev->bdev;
562 request_queue_t *r_queue = bdev_get_queue(bdev); 577 request_queue_t *r_queue = bdev_get_queue(bdev);
563 578
@@ -648,8 +663,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
648 struct bio_list bl; 663 struct bio_list bl;
649 struct page **behind_pages = NULL; 664 struct page **behind_pages = NULL;
650 const int rw = bio_data_dir(bio); 665 const int rw = bio_data_dir(bio);
666 int do_barriers;
651 667
652 if (unlikely(bio_barrier(bio))) { 668 if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
653 bio_endio(bio, bio->bi_size, -EOPNOTSUPP); 669 bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
654 return 0; 670 return 0;
655 } 671 }
@@ -728,10 +744,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
728#endif 744#endif
729 rcu_read_lock(); 745 rcu_read_lock();
730 for (i = 0; i < disks; i++) { 746 for (i = 0; i < disks; i++) {
731 if ((rdev=conf->mirrors[i].rdev) != NULL && 747 if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
732 !rdev->faulty) { 748 !test_bit(Faulty, &rdev->flags)) {
733 atomic_inc(&rdev->nr_pending); 749 atomic_inc(&rdev->nr_pending);
734 if (rdev->faulty) { 750 if (test_bit(Faulty, &rdev->flags)) {
735 atomic_dec(&rdev->nr_pending); 751 atomic_dec(&rdev->nr_pending);
736 r1_bio->bios[i] = NULL; 752 r1_bio->bios[i] = NULL;
737 } else 753 } else
@@ -759,6 +775,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
759 atomic_set(&r1_bio->remaining, 0); 775 atomic_set(&r1_bio->remaining, 0);
760 atomic_set(&r1_bio->behind_remaining, 0); 776 atomic_set(&r1_bio->behind_remaining, 0);
761 777
778 do_barriers = bio->bi_rw & BIO_RW_BARRIER;
779 if (do_barriers)
780 set_bit(R1BIO_Barrier, &r1_bio->state);
781
762 bio_list_init(&bl); 782 bio_list_init(&bl);
763 for (i = 0; i < disks; i++) { 783 for (i = 0; i < disks; i++) {
764 struct bio *mbio; 784 struct bio *mbio;
@@ -771,7 +791,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
771 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; 791 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
772 mbio->bi_bdev = conf->mirrors[i].rdev->bdev; 792 mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
773 mbio->bi_end_io = raid1_end_write_request; 793 mbio->bi_end_io = raid1_end_write_request;
774 mbio->bi_rw = WRITE; 794 mbio->bi_rw = WRITE | do_barriers;
775 mbio->bi_private = r1_bio; 795 mbio->bi_private = r1_bio;
776 796
777 if (behind_pages) { 797 if (behind_pages) {
@@ -824,7 +844,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 844 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 845 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 846 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 847 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 848 seq_printf(seq, "]");
829} 849}
830 850
@@ -840,14 +860,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
840 * next level up know. 860 * next level up know.
841 * else mark the drive as failed 861 * else mark the drive as failed
842 */ 862 */
843 if (rdev->in_sync 863 if (test_bit(In_sync, &rdev->flags)
844 && conf->working_disks == 1) 864 && conf->working_disks == 1)
845 /* 865 /*
846 * Don't fail the drive, act as though we were just a 866 * Don't fail the drive, act as though we were just a
847 * normal single drive 867 * normal single drive
848 */ 868 */
849 return; 869 return;
850 if (rdev->in_sync) { 870 if (test_bit(In_sync, &rdev->flags)) {
851 mddev->degraded++; 871 mddev->degraded++;
852 conf->working_disks--; 872 conf->working_disks--;
853 /* 873 /*
@@ -855,8 +875,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
855 */ 875 */
856 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 876 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
857 } 877 }
858 rdev->in_sync = 0; 878 clear_bit(In_sync, &rdev->flags);
859 rdev->faulty = 1; 879 set_bit(Faulty, &rdev->flags);
860 mddev->sb_dirty = 1; 880 mddev->sb_dirty = 1;
861 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" 881 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
862 " Operation continuing on %d devices\n", 882 " Operation continuing on %d devices\n",
@@ -881,7 +901,7 @@ static void print_conf(conf_t *conf)
881 tmp = conf->mirrors + i; 901 tmp = conf->mirrors + i;
882 if (tmp->rdev) 902 if (tmp->rdev)
883 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 903 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
884 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 904 i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
885 bdevname(tmp->rdev->bdev,b)); 905 bdevname(tmp->rdev->bdev,b));
886 } 906 }
887} 907}
@@ -913,11 +933,11 @@ static int raid1_spare_active(mddev_t *mddev)
913 for (i = 0; i < conf->raid_disks; i++) { 933 for (i = 0; i < conf->raid_disks; i++) {
914 tmp = conf->mirrors + i; 934 tmp = conf->mirrors + i;
915 if (tmp->rdev 935 if (tmp->rdev
916 && !tmp->rdev->faulty 936 && !test_bit(Faulty, &tmp->rdev->flags)
917 && !tmp->rdev->in_sync) { 937 && !test_bit(In_sync, &tmp->rdev->flags)) {
918 conf->working_disks++; 938 conf->working_disks++;
919 mddev->degraded--; 939 mddev->degraded--;
920 tmp->rdev->in_sync = 1; 940 set_bit(In_sync, &tmp->rdev->flags);
921 } 941 }
922 } 942 }
923 943
@@ -954,7 +974,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
954 found = 1; 974 found = 1;
955 if (rdev->saved_raid_disk != mirror) 975 if (rdev->saved_raid_disk != mirror)
956 conf->fullsync = 1; 976 conf->fullsync = 1;
957 p->rdev = rdev; 977 rcu_assign_pointer(p->rdev, rdev);
958 break; 978 break;
959 } 979 }
960 980
@@ -972,7 +992,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
972 print_conf(conf); 992 print_conf(conf);
973 rdev = p->rdev; 993 rdev = p->rdev;
974 if (rdev) { 994 if (rdev) {
975 if (rdev->in_sync || 995 if (test_bit(In_sync, &rdev->flags) ||
976 atomic_read(&rdev->nr_pending)) { 996 atomic_read(&rdev->nr_pending)) {
977 err = -EBUSY; 997 err = -EBUSY;
978 goto abort; 998 goto abort;
@@ -1153,6 +1173,36 @@ static void raid1d(mddev_t *mddev)
1153 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 1173 if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
1154 sync_request_write(mddev, r1_bio); 1174 sync_request_write(mddev, r1_bio);
1155 unplug = 1; 1175 unplug = 1;
1176 } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
1177 /* some requests in the r1bio were BIO_RW_BARRIER
1178 * requests which failed with -ENOTSUPP. Hohumm..
1179 * Better resubmit without the barrier.
1180 * We know which devices to resubmit for, because
1181 * all others have had their bios[] entry cleared.
1182 */
1183 int i;
1184 clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
1185 clear_bit(R1BIO_Barrier, &r1_bio->state);
1186 for (i=0; i < conf->raid_disks; i++)
1187 if (r1_bio->bios[i]) {
1188 struct bio_vec *bvec;
1189 int j;
1190
1191 bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
1192 /* copy pages from the failed bio, as
1193 * this might be a write-behind device */
1194 __bio_for_each_segment(bvec, bio, j, 0)
1195 bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
1196 bio_put(r1_bio->bios[i]);
1197 bio->bi_sector = r1_bio->sector +
1198 conf->mirrors[i].rdev->data_offset;
1199 bio->bi_bdev = conf->mirrors[i].rdev->bdev;
1200 bio->bi_end_io = raid1_end_write_request;
1201 bio->bi_rw = WRITE;
1202 bio->bi_private = r1_bio;
1203 r1_bio->bios[i] = bio;
1204 generic_make_request(bio);
1205 }
1156 } else { 1206 } else {
1157 int disk; 1207 int disk;
1158 bio = r1_bio->bios[r1_bio->read_disk]; 1208 bio = r1_bio->bios[r1_bio->read_disk];
@@ -1260,7 +1310,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1260 * This call the bitmap_start_sync doesn't actually record anything 1310 * This call the bitmap_start_sync doesn't actually record anything
1261 */ 1311 */
1262 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1312 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1263 !conf->fullsync) { 1313 !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1264 /* We can skip this block, and probably several more */ 1314 /* We can skip this block, and probably several more */
1265 *skipped = 1; 1315 *skipped = 1;
1266 return sync_blocks; 1316 return sync_blocks;
@@ -1282,11 +1332,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1282 /* make sure disk is operational */ 1332 /* make sure disk is operational */
1283 wonly = disk; 1333 wonly = disk;
1284 while (conf->mirrors[disk].rdev == NULL || 1334 while (conf->mirrors[disk].rdev == NULL ||
1285 !conf->mirrors[disk].rdev->in_sync || 1335 !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
1286 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags) 1336 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
1287 ) { 1337 ) {
1288 if (conf->mirrors[disk].rdev && 1338 if (conf->mirrors[disk].rdev &&
1289 conf->mirrors[disk].rdev->in_sync) 1339 test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
1290 wonly = disk; 1340 wonly = disk;
1291 if (disk <= 0) 1341 if (disk <= 0)
1292 disk = conf->raid_disks; 1342 disk = conf->raid_disks;
@@ -1333,11 +1383,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1333 bio->bi_rw = READ; 1383 bio->bi_rw = READ;
1334 bio->bi_end_io = end_sync_read; 1384 bio->bi_end_io = end_sync_read;
1335 } else if (conf->mirrors[i].rdev == NULL || 1385 } else if (conf->mirrors[i].rdev == NULL ||
1336 conf->mirrors[i].rdev->faulty) { 1386 test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
1337 still_degraded = 1; 1387 still_degraded = 1;
1338 continue; 1388 continue;
1339 } else if (!conf->mirrors[i].rdev->in_sync || 1389 } else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
1340 sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { 1390 sector_nr + RESYNC_SECTORS > mddev->recovery_cp ||
1391 test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1341 bio->bi_rw = WRITE; 1392 bio->bi_rw = WRITE;
1342 bio->bi_end_io = end_sync_write; 1393 bio->bi_end_io = end_sync_write;
1343 write_targets ++; 1394 write_targets ++;
@@ -1371,8 +1422,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1371 break; 1422 break;
1372 if (sync_blocks == 0) { 1423 if (sync_blocks == 0) {
1373 if (!bitmap_start_sync(mddev->bitmap, sector_nr, 1424 if (!bitmap_start_sync(mddev->bitmap, sector_nr,
1374 &sync_blocks, still_degraded) && 1425 &sync_blocks, still_degraded) &&
1375 !conf->fullsync) 1426 !conf->fullsync &&
1427 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1376 break; 1428 break;
1377 if (sync_blocks < (PAGE_SIZE>>9)) 1429 if (sync_blocks < (PAGE_SIZE>>9))
1378 BUG(); 1430 BUG();
@@ -1478,7 +1530,7 @@ static int run(mddev_t *mddev)
1478 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 1530 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
1479 1531
1480 disk->head_position = 0; 1532 disk->head_position = 0;
1481 if (!rdev->faulty && rdev->in_sync) 1533 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1482 conf->working_disks++; 1534 conf->working_disks++;
1483 } 1535 }
1484 conf->raid_disks = mddev->raid_disks; 1536 conf->raid_disks = mddev->raid_disks;
@@ -1518,7 +1570,7 @@ static int run(mddev_t *mddev)
1518 */ 1570 */
1519 for (j = 0; j < conf->raid_disks && 1571 for (j = 0; j < conf->raid_disks &&
1520 (!conf->mirrors[j].rdev || 1572 (!conf->mirrors[j].rdev ||
1521 !conf->mirrors[j].rdev->in_sync) ; j++) 1573 !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
1522 /* nothing */; 1574 /* nothing */;
1523 conf->last_used = j; 1575 conf->last_used = j;
1524 1576
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index bbe40e9cf923..867f06ae33d9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
496 int disk, slot, nslot; 496 int disk, slot, nslot;
497 const int sectors = r10_bio->sectors; 497 const int sectors = r10_bio->sectors;
498 sector_t new_distance, current_distance; 498 sector_t new_distance, current_distance;
499 mdk_rdev_t *rdev;
499 500
500 raid10_find_phys(conf, r10_bio); 501 raid10_find_phys(conf, r10_bio);
501 rcu_read_lock(); 502 rcu_read_lock();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
510 slot = 0; 511 slot = 0;
511 disk = r10_bio->devs[slot].devnum; 512 disk = r10_bio->devs[slot].devnum;
512 513
513 while (!conf->mirrors[disk].rdev || 514 while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
514 !conf->mirrors[disk].rdev->in_sync) { 515 !test_bit(In_sync, &rdev->flags)) {
515 slot++; 516 slot++;
516 if (slot == conf->copies) { 517 if (slot == conf->copies) {
517 slot = 0; 518 slot = 0;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
527 /* make sure the disk is operational */ 528 /* make sure the disk is operational */
528 slot = 0; 529 slot = 0;
529 disk = r10_bio->devs[slot].devnum; 530 disk = r10_bio->devs[slot].devnum;
530 while (!conf->mirrors[disk].rdev || 531 while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
531 !conf->mirrors[disk].rdev->in_sync) { 532 !test_bit(In_sync, &rdev->flags)) {
532 slot ++; 533 slot ++;
533 if (slot == conf->copies) { 534 if (slot == conf->copies) {
534 disk = -1; 535 disk = -1;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
547 int ndisk = r10_bio->devs[nslot].devnum; 548 int ndisk = r10_bio->devs[nslot].devnum;
548 549
549 550
550 if (!conf->mirrors[ndisk].rdev || 551 if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
551 !conf->mirrors[ndisk].rdev->in_sync) 552 !test_bit(In_sync, &rdev->flags))
552 continue; 553 continue;
553 554
554 if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) { 555 if (!atomic_read(&rdev->nr_pending)) {
555 disk = ndisk; 556 disk = ndisk;
556 slot = nslot; 557 slot = nslot;
557 break; 558 break;
@@ -569,7 +570,7 @@ rb_out:
569 r10_bio->read_slot = slot; 570 r10_bio->read_slot = slot;
570/* conf->next_seq_sect = this_sector + sectors;*/ 571/* conf->next_seq_sect = this_sector + sectors;*/
571 572
572 if (disk >= 0 && conf->mirrors[disk].rdev) 573 if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
573 atomic_inc(&conf->mirrors[disk].rdev->nr_pending); 574 atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
574 rcu_read_unlock(); 575 rcu_read_unlock();
575 576
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev)
583 584
584 rcu_read_lock(); 585 rcu_read_lock();
585 for (i=0; i<mddev->raid_disks; i++) { 586 for (i=0; i<mddev->raid_disks; i++) {
586 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 587 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
587 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 588 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
588 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 589 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
589 590
590 atomic_inc(&rdev->nr_pending); 591 atomic_inc(&rdev->nr_pending);
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
614 615
615 rcu_read_lock(); 616 rcu_read_lock();
616 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 617 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
617 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 618 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
618 if (rdev && !rdev->faulty) { 619 if (rdev && !test_bit(Faulty, &rdev->flags)) {
619 struct block_device *bdev = rdev->bdev; 620 struct block_device *bdev = rdev->bdev;
620 request_queue_t *r_queue = bdev_get_queue(bdev); 621 request_queue_t *r_queue = bdev_get_queue(bdev);
621 622
@@ -768,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
768 rcu_read_lock(); 769 rcu_read_lock();
769 for (i = 0; i < conf->copies; i++) { 770 for (i = 0; i < conf->copies; i++) {
770 int d = r10_bio->devs[i].devnum; 771 int d = r10_bio->devs[i].devnum;
771 if (conf->mirrors[d].rdev && 772 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
772 !conf->mirrors[d].rdev->faulty) { 773 if (rdev &&
773 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 774 !test_bit(Faulty, &rdev->flags)) {
775 atomic_inc(&rdev->nr_pending);
774 r10_bio->devs[i].bio = bio; 776 r10_bio->devs[i].bio = bio;
775 } else 777 } else
776 r10_bio->devs[i].bio = NULL; 778 r10_bio->devs[i].bio = NULL;
@@ -824,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 826 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 827 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 828 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 829 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 830 seq_printf(seq, "]");
829} 831}
830 832
@@ -839,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
839 * next level up know. 841 * next level up know.
840 * else mark the drive as failed 842 * else mark the drive as failed
841 */ 843 */
842 if (rdev->in_sync 844 if (test_bit(In_sync, &rdev->flags)
843 && conf->working_disks == 1) 845 && conf->working_disks == 1)
844 /* 846 /*
845 * Don't fail the drive, just return an IO error. 847 * Don't fail the drive, just return an IO error.
@@ -849,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
849 * really dead" tests... 851 * really dead" tests...
850 */ 852 */
851 return; 853 return;
852 if (rdev->in_sync) { 854 if (test_bit(In_sync, &rdev->flags)) {
853 mddev->degraded++; 855 mddev->degraded++;
854 conf->working_disks--; 856 conf->working_disks--;
855 /* 857 /*
@@ -857,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
857 */ 859 */
858 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 860 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
859 } 861 }
860 rdev->in_sync = 0; 862 clear_bit(In_sync, &rdev->flags);
861 rdev->faulty = 1; 863 set_bit(Faulty, &rdev->flags);
862 mddev->sb_dirty = 1; 864 mddev->sb_dirty = 1;
863 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" 865 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
864 " Operation continuing on %d devices\n", 866 " Operation continuing on %d devices\n",
@@ -883,7 +885,8 @@ static void print_conf(conf_t *conf)
883 tmp = conf->mirrors + i; 885 tmp = conf->mirrors + i;
884 if (tmp->rdev) 886 if (tmp->rdev)
885 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 887 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
886 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 888 i, !test_bit(In_sync, &tmp->rdev->flags),
889 !test_bit(Faulty, &tmp->rdev->flags),
887 bdevname(tmp->rdev->bdev,b)); 890 bdevname(tmp->rdev->bdev,b));
888 } 891 }
889} 892}
@@ -936,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev)
936 for (i = 0; i < conf->raid_disks; i++) { 939 for (i = 0; i < conf->raid_disks; i++) {
937 tmp = conf->mirrors + i; 940 tmp = conf->mirrors + i;
938 if (tmp->rdev 941 if (tmp->rdev
939 && !tmp->rdev->faulty 942 && !test_bit(Faulty, &tmp->rdev->flags)
940 && !tmp->rdev->in_sync) { 943 && !test_bit(In_sync, &tmp->rdev->flags)) {
941 conf->working_disks++; 944 conf->working_disks++;
942 mddev->degraded--; 945 mddev->degraded--;
943 tmp->rdev->in_sync = 1; 946 set_bit(In_sync, &tmp->rdev->flags);
944 } 947 }
945 } 948 }
946 949
@@ -980,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
980 p->head_position = 0; 983 p->head_position = 0;
981 rdev->raid_disk = mirror; 984 rdev->raid_disk = mirror;
982 found = 1; 985 found = 1;
983 p->rdev = rdev; 986 rcu_assign_pointer(p->rdev, rdev);
984 break; 987 break;
985 } 988 }
986 989
@@ -998,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
998 print_conf(conf); 1001 print_conf(conf);
999 rdev = p->rdev; 1002 rdev = p->rdev;
1000 if (rdev) { 1003 if (rdev) {
1001 if (rdev->in_sync || 1004 if (test_bit(In_sync, &rdev->flags) ||
1002 atomic_read(&rdev->nr_pending)) { 1005 atomic_read(&rdev->nr_pending)) {
1003 err = -EBUSY; 1006 err = -EBUSY;
1004 goto abort; 1007 goto abort;
@@ -1414,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1414 1417
1415 for (i=0 ; i<conf->raid_disks; i++) 1418 for (i=0 ; i<conf->raid_disks; i++)
1416 if (conf->mirrors[i].rdev && 1419 if (conf->mirrors[i].rdev &&
1417 !conf->mirrors[i].rdev->in_sync) { 1420 !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
1418 /* want to reconstruct this device */ 1421 /* want to reconstruct this device */
1419 r10bio_t *rb2 = r10_bio; 1422 r10bio_t *rb2 = r10_bio;
1420 1423
@@ -1435,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1435 for (j=0; j<conf->copies;j++) { 1438 for (j=0; j<conf->copies;j++) {
1436 int d = r10_bio->devs[j].devnum; 1439 int d = r10_bio->devs[j].devnum;
1437 if (conf->mirrors[d].rdev && 1440 if (conf->mirrors[d].rdev &&
1438 conf->mirrors[d].rdev->in_sync) { 1441 test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
1439 /* This is where we read from */ 1442 /* This is where we read from */
1440 bio = r10_bio->devs[0].bio; 1443 bio = r10_bio->devs[0].bio;
1441 bio->bi_next = biolist; 1444 bio->bi_next = biolist;
@@ -1511,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1511 bio = r10_bio->devs[i].bio; 1514 bio = r10_bio->devs[i].bio;
1512 bio->bi_end_io = NULL; 1515 bio->bi_end_io = NULL;
1513 if (conf->mirrors[d].rdev == NULL || 1516 if (conf->mirrors[d].rdev == NULL ||
1514 conf->mirrors[d].rdev->faulty) 1517 test_bit(Faulty, &conf->mirrors[d].rdev->flags))
1515 continue; 1518 continue;
1516 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 1519 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
1517 atomic_inc(&r10_bio->remaining); 1520 atomic_inc(&r10_bio->remaining);
@@ -1697,7 +1700,7 @@ static int run(mddev_t *mddev)
1697 mddev->queue->max_sectors = (PAGE_SIZE>>9); 1700 mddev->queue->max_sectors = (PAGE_SIZE>>9);
1698 1701
1699 disk->head_position = 0; 1702 disk->head_position = 0;
1700 if (!rdev->faulty && rdev->in_sync) 1703 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1701 conf->working_disks++; 1704 conf->working_disks++;
1702 } 1705 }
1703 conf->raid_disks = mddev->raid_disks; 1706 conf->raid_disks = mddev->raid_disks;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1223e98ecd70..e2a40283e323 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
293 return sh; 293 return sh;
294} 294}
295 295
296static int grow_stripes(raid5_conf_t *conf, int num) 296static int grow_one_stripe(raid5_conf_t *conf)
297{ 297{
298 struct stripe_head *sh; 298 struct stripe_head *sh;
299 sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
300 if (!sh)
301 return 0;
302 memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
303 sh->raid_conf = conf;
304 spin_lock_init(&sh->lock);
305
306 if (grow_buffers(sh, conf->raid_disks)) {
307 shrink_buffers(sh, conf->raid_disks);
308 kmem_cache_free(conf->slab_cache, sh);
309 return 0;
310 }
311 /* we just created an active stripe so... */
312 atomic_set(&sh->count, 1);
313 atomic_inc(&conf->active_stripes);
314 INIT_LIST_HEAD(&sh->lru);
315 release_stripe(sh);
316 return 1;
317}
318
319static int grow_stripes(raid5_conf_t *conf, int num)
320{
299 kmem_cache_t *sc; 321 kmem_cache_t *sc;
300 int devs = conf->raid_disks; 322 int devs = conf->raid_disks;
301 323
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num)
308 return 1; 330 return 1;
309 conf->slab_cache = sc; 331 conf->slab_cache = sc;
310 while (num--) { 332 while (num--) {
311 sh = kmem_cache_alloc(sc, GFP_KERNEL); 333 if (!grow_one_stripe(conf))
312 if (!sh)
313 return 1;
314 memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
315 sh->raid_conf = conf;
316 spin_lock_init(&sh->lock);
317
318 if (grow_buffers(sh, conf->raid_disks)) {
319 shrink_buffers(sh, conf->raid_disks);
320 kmem_cache_free(sc, sh);
321 return 1; 334 return 1;
322 }
323 /* we just created an active stripe so... */
324 atomic_set(&sh->count, 1);
325 atomic_inc(&conf->active_stripes);
326 INIT_LIST_HEAD(&sh->lru);
327 release_stripe(sh);
328 } 335 }
329 return 0; 336 return 0;
330} 337}
331 338
332static void shrink_stripes(raid5_conf_t *conf) 339static int drop_one_stripe(raid5_conf_t *conf)
333{ 340{
334 struct stripe_head *sh; 341 struct stripe_head *sh;
335 342
336 while (1) { 343 spin_lock_irq(&conf->device_lock);
337 spin_lock_irq(&conf->device_lock); 344 sh = get_free_stripe(conf);
338 sh = get_free_stripe(conf); 345 spin_unlock_irq(&conf->device_lock);
339 spin_unlock_irq(&conf->device_lock); 346 if (!sh)
340 if (!sh) 347 return 0;
341 break; 348 if (atomic_read(&sh->count))
342 if (atomic_read(&sh->count)) 349 BUG();
343 BUG(); 350 shrink_buffers(sh, conf->raid_disks);
344 shrink_buffers(sh, conf->raid_disks); 351 kmem_cache_free(conf->slab_cache, sh);
345 kmem_cache_free(conf->slab_cache, sh); 352 atomic_dec(&conf->active_stripes);
346 atomic_dec(&conf->active_stripes); 353 return 1;
347 } 354}
355
356static void shrink_stripes(raid5_conf_t *conf)
357{
358 while (drop_one_stripe(conf))
359 ;
360
348 kmem_cache_destroy(conf->slab_cache); 361 kmem_cache_destroy(conf->slab_cache);
349 conf->slab_cache = NULL; 362 conf->slab_cache = NULL;
350} 363}
351 364
352static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, 365static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
353 int error) 366 int error)
354{ 367{
355 struct stripe_head *sh = bi->bi_private; 368 struct stripe_head *sh = bi->bi_private;
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
401 } 414 }
402#else 415#else
403 set_bit(R5_UPTODATE, &sh->dev[i].flags); 416 set_bit(R5_UPTODATE, &sh->dev[i].flags);
404#endif 417#endif
418 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
419 printk("R5: read error corrected!!\n");
420 clear_bit(R5_ReadError, &sh->dev[i].flags);
421 clear_bit(R5_ReWrite, &sh->dev[i].flags);
422 }
423 if (atomic_read(&conf->disks[i].rdev->read_errors))
424 atomic_set(&conf->disks[i].rdev->read_errors, 0);
405 } else { 425 } else {
406 md_error(conf->mddev, conf->disks[i].rdev); 426 int retry = 0;
407 clear_bit(R5_UPTODATE, &sh->dev[i].flags); 427 clear_bit(R5_UPTODATE, &sh->dev[i].flags);
428 atomic_inc(&conf->disks[i].rdev->read_errors);
429 if (conf->mddev->degraded)
430 printk("R5: read error not correctable.\n");
431 else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
432 /* Oh, no!!! */
433 printk("R5: read error NOT corrected!!\n");
434 else if (atomic_read(&conf->disks[i].rdev->read_errors)
435 > conf->max_nr_stripes)
436 printk("raid5: Too many read errors, failing device.\n");
437 else
438 retry = 1;
439 if (retry)
440 set_bit(R5_ReadError, &sh->dev[i].flags);
441 else {
442 clear_bit(R5_ReadError, &sh->dev[i].flags);
443 clear_bit(R5_ReWrite, &sh->dev[i].flags);
444 md_error(conf->mddev, conf->disks[i].rdev);
445 }
408 } 446 }
409 rdev_dec_pending(conf->disks[i].rdev, conf->mddev); 447 rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
410#if 0 448#if 0
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
487 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 525 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
488 PRINTK("raid5: error called\n"); 526 PRINTK("raid5: error called\n");
489 527
490 if (!rdev->faulty) { 528 if (!test_bit(Faulty, &rdev->flags)) {
491 mddev->sb_dirty = 1; 529 mddev->sb_dirty = 1;
492 if (rdev->in_sync) { 530 if (test_bit(In_sync, &rdev->flags)) {
493 conf->working_disks--; 531 conf->working_disks--;
494 mddev->degraded++; 532 mddev->degraded++;
495 conf->failed_disks++; 533 conf->failed_disks++;
496 rdev->in_sync = 0; 534 clear_bit(In_sync, &rdev->flags);
497 /* 535 /*
498 * if recovery was running, make sure it aborts. 536 * if recovery was running, make sure it aborts.
499 */ 537 */
500 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 538 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
501 } 539 }
502 rdev->faulty = 1; 540 set_bit(Faulty, &rdev->flags);
503 printk (KERN_ALERT 541 printk (KERN_ALERT
504 "raid5: Disk failure on %s, disabling device." 542 "raid5: Disk failure on %s, disabling device."
505 " Operation continuing on %d devices\n", 543 " Operation continuing on %d devices\n",
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh)
965 } 1003 }
966 if (dev->written) written++; 1004 if (dev->written) written++;
967 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1005 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
968 if (!rdev || !rdev->in_sync) { 1006 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1007 /* The ReadError flag wil just be confusing now */
1008 clear_bit(R5_ReadError, &dev->flags);
1009 clear_bit(R5_ReWrite, &dev->flags);
1010 }
1011 if (!rdev || !test_bit(In_sync, &rdev->flags)
1012 || test_bit(R5_ReadError, &dev->flags)) {
969 failed++; 1013 failed++;
970 failed_num = i; 1014 failed_num = i;
971 } else 1015 } else
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh)
980 if (failed > 1 && to_read+to_write+written) { 1024 if (failed > 1 && to_read+to_write+written) {
981 for (i=disks; i--; ) { 1025 for (i=disks; i--; ) {
982 int bitmap_end = 0; 1026 int bitmap_end = 0;
1027
1028 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
1029 mdk_rdev_t *rdev = conf->disks[i].rdev;
1030 if (rdev && test_bit(In_sync, &rdev->flags))
1031 /* multiple read failures in one stripe */
1032 md_error(conf->mddev, rdev);
1033 }
1034
983 spin_lock_irq(&conf->device_lock); 1035 spin_lock_irq(&conf->device_lock);
984 /* fail all writes first */ 1036 /* fail all writes first */
985 bi = sh->dev[i].towrite; 1037 bi = sh->dev[i].towrite;
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh)
1015 } 1067 }
1016 1068
1017 /* fail any reads if this device is non-operational */ 1069 /* fail any reads if this device is non-operational */
1018 if (!test_bit(R5_Insync, &sh->dev[i].flags)) { 1070 if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
1071 test_bit(R5_ReadError, &sh->dev[i].flags)) {
1019 bi = sh->dev[i].toread; 1072 bi = sh->dev[i].toread;
1020 sh->dev[i].toread = NULL; 1073 sh->dev[i].toread = NULL;
1021 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 1074 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh)
1247 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { 1300 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
1248 /* parity is correct (on disc, not in buffer any more) */ 1301 /* parity is correct (on disc, not in buffer any more) */
1249 set_bit(STRIPE_INSYNC, &sh->state); 1302 set_bit(STRIPE_INSYNC, &sh->state);
1303 } else {
1304 conf->mddev->resync_mismatches += STRIPE_SECTORS;
1305 if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
1306 /* don't try to repair!! */
1307 set_bit(STRIPE_INSYNC, &sh->state);
1250 } 1308 }
1251 } 1309 }
1252 if (!test_bit(STRIPE_INSYNC, &sh->state)) { 1310 if (!test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh)
1274 md_done_sync(conf->mddev, STRIPE_SECTORS,1); 1332 md_done_sync(conf->mddev, STRIPE_SECTORS,1);
1275 clear_bit(STRIPE_SYNCING, &sh->state); 1333 clear_bit(STRIPE_SYNCING, &sh->state);
1276 } 1334 }
1277 1335
1336 /* If the failed drive is just a ReadError, then we might need to progress
1337 * the repair/check process
1338 */
1339 if (failed == 1 && ! conf->mddev->ro &&
1340 test_bit(R5_ReadError, &sh->dev[failed_num].flags)
1341 && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags)
1342 && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)
1343 ) {
1344 dev = &sh->dev[failed_num];
1345 if (!test_bit(R5_ReWrite, &dev->flags)) {
1346 set_bit(R5_Wantwrite, &dev->flags);
1347 set_bit(R5_ReWrite, &dev->flags);
1348 set_bit(R5_LOCKED, &dev->flags);
1349 } else {
1350 /* let's read it back */
1351 set_bit(R5_Wantread, &dev->flags);
1352 set_bit(R5_LOCKED, &dev->flags);
1353 }
1354 }
1355
1278 spin_unlock(&sh->lock); 1356 spin_unlock(&sh->lock);
1279 1357
1280 while ((bi=return_bi)) { 1358 while ((bi=return_bi)) {
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh)
1305 bi->bi_end_io = raid5_end_read_request; 1383 bi->bi_end_io = raid5_end_read_request;
1306 1384
1307 rcu_read_lock(); 1385 rcu_read_lock();
1308 rdev = conf->disks[i].rdev; 1386 rdev = rcu_dereference(conf->disks[i].rdev);
1309 if (rdev && rdev->faulty) 1387 if (rdev && test_bit(Faulty, &rdev->flags))
1310 rdev = NULL; 1388 rdev = NULL;
1311 if (rdev) 1389 if (rdev)
1312 atomic_inc(&rdev->nr_pending); 1390 atomic_inc(&rdev->nr_pending);
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev)
1379 1457
1380 rcu_read_lock(); 1458 rcu_read_lock();
1381 for (i=0; i<mddev->raid_disks; i++) { 1459 for (i=0; i<mddev->raid_disks; i++) {
1382 mdk_rdev_t *rdev = conf->disks[i].rdev; 1460 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1383 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1461 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1384 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1462 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1385 1463
1386 atomic_inc(&rdev->nr_pending); 1464 atomic_inc(&rdev->nr_pending);
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
1424 1502
1425 rcu_read_lock(); 1503 rcu_read_lock();
1426 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1504 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1427 mdk_rdev_t *rdev = conf->disks[i].rdev; 1505 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1428 if (rdev && !rdev->faulty) { 1506 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1429 struct block_device *bdev = rdev->bdev; 1507 struct block_device *bdev = rdev->bdev;
1430 request_queue_t *r_queue = bdev_get_queue(bdev); 1508 request_queue_t *r_queue = bdev_get_queue(bdev);
1431 1509
@@ -1567,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1567 return rv; 1645 return rv;
1568 } 1646 }
1569 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1647 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1648 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
1570 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { 1649 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
1571 /* we can skip this block, and probably more */ 1650 /* we can skip this block, and probably more */
1572 sync_blocks /= STRIPE_SECTORS; 1651 sync_blocks /= STRIPE_SECTORS;
@@ -1663,6 +1742,74 @@ static void raid5d (mddev_t *mddev)
1663 PRINTK("--- raid5d inactive\n"); 1742 PRINTK("--- raid5d inactive\n");
1664} 1743}
1665 1744
1745static ssize_t
1746raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
1747{
1748 raid5_conf_t *conf = mddev_to_conf(mddev);
1749 if (conf)
1750 return sprintf(page, "%d\n", conf->max_nr_stripes);
1751 else
1752 return 0;
1753}
1754
1755static ssize_t
1756raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
1757{
1758 raid5_conf_t *conf = mddev_to_conf(mddev);
1759 char *end;
1760 int new;
1761 if (len >= PAGE_SIZE)
1762 return -EINVAL;
1763 if (!conf)
1764 return -ENODEV;
1765
1766 new = simple_strtoul(page, &end, 10);
1767 if (!*page || (*end && *end != '\n') )
1768 return -EINVAL;
1769 if (new <= 16 || new > 32768)
1770 return -EINVAL;
1771 while (new < conf->max_nr_stripes) {
1772 if (drop_one_stripe(conf))
1773 conf->max_nr_stripes--;
1774 else
1775 break;
1776 }
1777 while (new > conf->max_nr_stripes) {
1778 if (grow_one_stripe(conf))
1779 conf->max_nr_stripes++;
1780 else break;
1781 }
1782 return len;
1783}
1784
1785static struct md_sysfs_entry
1786raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
1787 raid5_show_stripe_cache_size,
1788 raid5_store_stripe_cache_size);
1789
1790static ssize_t
1791stripe_cache_active_show(mddev_t *mddev, char *page)
1792{
1793 raid5_conf_t *conf = mddev_to_conf(mddev);
1794 if (conf)
1795 return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
1796 else
1797 return 0;
1798}
1799
1800static struct md_sysfs_entry
1801raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
1802
1803static struct attribute *raid5_attrs[] = {
1804 &raid5_stripecache_size.attr,
1805 &raid5_stripecache_active.attr,
1806 NULL,
1807};
1808static struct attribute_group raid5_attrs_group = {
1809 .name = NULL,
1810 .attrs = raid5_attrs,
1811};
1812
1666static int run(mddev_t *mddev) 1813static int run(mddev_t *mddev)
1667{ 1814{
1668 raid5_conf_t *conf; 1815 raid5_conf_t *conf;
@@ -1709,7 +1856,7 @@ static int run(mddev_t *mddev)
1709 1856
1710 disk->rdev = rdev; 1857 disk->rdev = rdev;
1711 1858
1712 if (rdev->in_sync) { 1859 if (test_bit(In_sync, &rdev->flags)) {
1713 char b[BDEVNAME_SIZE]; 1860 char b[BDEVNAME_SIZE];
1714 printk(KERN_INFO "raid5: device %s operational as raid" 1861 printk(KERN_INFO "raid5: device %s operational as raid"
1715 " disk %d\n", bdevname(rdev->bdev,b), 1862 " disk %d\n", bdevname(rdev->bdev,b),
@@ -1804,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
1804 } 1951 }
1805 1952
1806 /* Ok, everything is just fine now */ 1953 /* Ok, everything is just fine now */
1954 sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
1807 1955
1808 if (mddev->bitmap) 1956 if (mddev->bitmap)
1809 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; 1957 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
@@ -1828,7 +1976,7 @@ abort:
1828 1976
1829 1977
1830 1978
1831static int stop (mddev_t *mddev) 1979static int stop(mddev_t *mddev)
1832{ 1980{
1833 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1981 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1834 1982
@@ -1837,6 +1985,7 @@ static int stop (mddev_t *mddev)
1837 shrink_stripes(conf); 1985 shrink_stripes(conf);
1838 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); 1986 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
1839 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
1840 kfree(conf); 1989 kfree(conf);
1841 mddev->private = NULL; 1990 mddev->private = NULL;
1842 return 0; 1991 return 0;
@@ -1887,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
1887 for (i = 0; i < conf->raid_disks; i++) 2036 for (i = 0; i < conf->raid_disks; i++)
1888 seq_printf (seq, "%s", 2037 seq_printf (seq, "%s",
1889 conf->disks[i].rdev && 2038 conf->disks[i].rdev &&
1890 conf->disks[i].rdev->in_sync ? "U" : "_"); 2039 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
1891 seq_printf (seq, "]"); 2040 seq_printf (seq, "]");
1892#if RAID5_DEBUG 2041#if RAID5_DEBUG
1893#define D(x) \ 2042#define D(x) \
@@ -1914,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
1914 tmp = conf->disks + i; 2063 tmp = conf->disks + i;
1915 if (tmp->rdev) 2064 if (tmp->rdev)
1916 printk(" disk %d, o:%d, dev:%s\n", 2065 printk(" disk %d, o:%d, dev:%s\n",
1917 i, !tmp->rdev->faulty, 2066 i, !test_bit(Faulty, &tmp->rdev->flags),
1918 bdevname(tmp->rdev->bdev,b)); 2067 bdevname(tmp->rdev->bdev,b));
1919 } 2068 }
1920} 2069}
@@ -1928,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev)
1928 for (i = 0; i < conf->raid_disks; i++) { 2077 for (i = 0; i < conf->raid_disks; i++) {
1929 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
1930 if (tmp->rdev 2079 if (tmp->rdev
1931 && !tmp->rdev->faulty 2080 && !test_bit(Faulty, &tmp->rdev->flags)
1932 && !tmp->rdev->in_sync) { 2081 && !test_bit(In_sync, &tmp->rdev->flags)) {
1933 mddev->degraded--; 2082 mddev->degraded--;
1934 conf->failed_disks--; 2083 conf->failed_disks--;
1935 conf->working_disks++; 2084 conf->working_disks++;
1936 tmp->rdev->in_sync = 1; 2085 set_bit(In_sync, &tmp->rdev->flags);
1937 } 2086 }
1938 } 2087 }
1939 print_raid5_conf(conf); 2088 print_raid5_conf(conf);
@@ -1950,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
1950 print_raid5_conf(conf); 2099 print_raid5_conf(conf);
1951 rdev = p->rdev; 2100 rdev = p->rdev;
1952 if (rdev) { 2101 if (rdev) {
1953 if (rdev->in_sync || 2102 if (test_bit(In_sync, &rdev->flags) ||
1954 atomic_read(&rdev->nr_pending)) { 2103 atomic_read(&rdev->nr_pending)) {
1955 err = -EBUSY; 2104 err = -EBUSY;
1956 goto abort; 2105 goto abort;
@@ -1985,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1985 */ 2134 */
1986 for (disk=0; disk < mddev->raid_disks; disk++) 2135 for (disk=0; disk < mddev->raid_disks; disk++)
1987 if ((p=conf->disks + disk)->rdev == NULL) { 2136 if ((p=conf->disks + disk)->rdev == NULL) {
1988 rdev->in_sync = 0; 2137 clear_bit(In_sync, &rdev->flags);
1989 rdev->raid_disk = disk; 2138 rdev->raid_disk = disk;
1990 found = 1; 2139 found = 1;
1991 if (rdev->saved_raid_disk != disk) 2140 if (rdev->saved_raid_disk != disk)
1992 conf->fullsync = 1; 2141 conf->fullsync = 1;
1993 p->rdev = rdev; 2142 rcu_assign_pointer(p->rdev, rdev);
1994 break; 2143 break;
1995 } 2144 }
1996 print_raid5_conf(conf); 2145 print_raid5_conf(conf);
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 775786947701..eae5a35629c5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private; 507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
508 PRINTK("raid6: error called\n"); 508 PRINTK("raid6: error called\n");
509 509
510 if (!rdev->faulty) { 510 if (!test_bit(Faulty, &rdev->flags)) {
511 mddev->sb_dirty = 1; 511 mddev->sb_dirty = 1;
512 if (rdev->in_sync) { 512 if (test_bit(In_sync, &rdev->flags)) {
513 conf->working_disks--; 513 conf->working_disks--;
514 mddev->degraded++; 514 mddev->degraded++;
515 conf->failed_disks++; 515 conf->failed_disks++;
516 rdev->in_sync = 0; 516 clear_bit(In_sync, &rdev->flags);
517 /* 517 /*
518 * if recovery was running, make sure it aborts. 518 * if recovery was running, make sure it aborts.
519 */ 519 */
520 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 520 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
521 } 521 }
522 rdev->faulty = 1; 522 set_bit(Faulty, &rdev->flags);
523 printk (KERN_ALERT 523 printk (KERN_ALERT
524 "raid6: Disk failure on %s, disabling device." 524 "raid6: Disk failure on %s, disabling device."
525 " Operation continuing on %d devices\n", 525 " Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_head *sh)
1071 } 1071 }
1072 if (dev->written) written++; 1072 if (dev->written) written++;
1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
1074 if (!rdev || !rdev->in_sync) { 1074 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1075 if ( failed < 2 ) 1075 if ( failed < 2 )
1076 failed_num[failed] = i; 1076 failed_num[failed] = i;
1077 failed++; 1077 failed++;
@@ -1464,8 +1464,8 @@ static void handle_stripe(struct stripe_head *sh)
1464 bi->bi_end_io = raid6_end_read_request; 1464 bi->bi_end_io = raid6_end_read_request;
1465 1465
1466 rcu_read_lock(); 1466 rcu_read_lock();
1467 rdev = conf->disks[i].rdev; 1467 rdev = rcu_dereference(conf->disks[i].rdev);
1468 if (rdev && rdev->faulty) 1468 if (rdev && test_bit(Faulty, &rdev->flags))
1469 rdev = NULL; 1469 rdev = NULL;
1470 if (rdev) 1470 if (rdev)
1471 atomic_inc(&rdev->nr_pending); 1471 atomic_inc(&rdev->nr_pending);
@@ -1538,8 +1538,8 @@ static void unplug_slaves(mddev_t *mddev)
1538 1538
1539 rcu_read_lock(); 1539 rcu_read_lock();
1540 for (i=0; i<mddev->raid_disks; i++) { 1540 for (i=0; i<mddev->raid_disks; i++) {
1541 mdk_rdev_t *rdev = conf->disks[i].rdev; 1541 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1542 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1542 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1544 1544
1545 atomic_inc(&rdev->nr_pending); 1545 atomic_inc(&rdev->nr_pending);
@@ -1583,8 +1583,8 @@ static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk,
1583 1583
1584 rcu_read_lock(); 1584 rcu_read_lock();
1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1586 mdk_rdev_t *rdev = conf->disks[i].rdev; 1586 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1587 if (rdev && !rdev->faulty) { 1587 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1588 struct block_device *bdev = rdev->bdev; 1588 struct block_device *bdev = rdev->bdev;
1589 request_queue_t *r_queue = bdev_get_queue(bdev); 1589 request_queue_t *r_queue = bdev_get_queue(bdev);
1590 1590
@@ -1868,7 +1868,7 @@ static int run(mddev_t *mddev)
1868 1868
1869 disk->rdev = rdev; 1869 disk->rdev = rdev;
1870 1870
1871 if (rdev->in_sync) { 1871 if (test_bit(In_sync, &rdev->flags)) {
1872 char b[BDEVNAME_SIZE]; 1872 char b[BDEVNAME_SIZE];
1873 printk(KERN_INFO "raid6: device %s operational as raid" 1873 printk(KERN_INFO "raid6: device %s operational as raid"
1874 " disk %d\n", bdevname(rdev->bdev,b), 1874 " disk %d\n", bdevname(rdev->bdev,b),
@@ -2052,7 +2052,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
2052 for (i = 0; i < conf->raid_disks; i++) 2052 for (i = 0; i < conf->raid_disks; i++)
2053 seq_printf (seq, "%s", 2053 seq_printf (seq, "%s",
2054 conf->disks[i].rdev && 2054 conf->disks[i].rdev &&
2055 conf->disks[i].rdev->in_sync ? "U" : "_"); 2055 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
2056 seq_printf (seq, "]"); 2056 seq_printf (seq, "]");
2057#if RAID6_DUMPSTATE 2057#if RAID6_DUMPSTATE
2058 seq_printf (seq, "\n"); 2058 seq_printf (seq, "\n");
@@ -2078,7 +2078,7 @@ static void print_raid6_conf (raid6_conf_t *conf)
2078 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
2079 if (tmp->rdev) 2079 if (tmp->rdev)
2080 printk(" disk %d, o:%d, dev:%s\n", 2080 printk(" disk %d, o:%d, dev:%s\n",
2081 i, !tmp->rdev->faulty, 2081 i, !test_bit(Faulty, &tmp->rdev->flags),
2082 bdevname(tmp->rdev->bdev,b)); 2082 bdevname(tmp->rdev->bdev,b));
2083 } 2083 }
2084} 2084}
@@ -2092,12 +2092,12 @@ static int raid6_spare_active(mddev_t *mddev)
2092 for (i = 0; i < conf->raid_disks; i++) { 2092 for (i = 0; i < conf->raid_disks; i++) {
2093 tmp = conf->disks + i; 2093 tmp = conf->disks + i;
2094 if (tmp->rdev 2094 if (tmp->rdev
2095 && !tmp->rdev->faulty 2095 && !test_bit(Faulty, &tmp->rdev->flags)
2096 && !tmp->rdev->in_sync) { 2096 && !test_bit(In_sync, &tmp->rdev->flags)) {
2097 mddev->degraded--; 2097 mddev->degraded--;
2098 conf->failed_disks--; 2098 conf->failed_disks--;
2099 conf->working_disks++; 2099 conf->working_disks++;
2100 tmp->rdev->in_sync = 1; 2100 set_bit(In_sync, &tmp->rdev->flags);
2101 } 2101 }
2102 } 2102 }
2103 print_raid6_conf(conf); 2103 print_raid6_conf(conf);
@@ -2114,7 +2114,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
2114 print_raid6_conf(conf); 2114 print_raid6_conf(conf);
2115 rdev = p->rdev; 2115 rdev = p->rdev;
2116 if (rdev) { 2116 if (rdev) {
2117 if (rdev->in_sync || 2117 if (test_bit(In_sync, &rdev->flags) ||
2118 atomic_read(&rdev->nr_pending)) { 2118 atomic_read(&rdev->nr_pending)) {
2119 err = -EBUSY; 2119 err = -EBUSY;
2120 goto abort; 2120 goto abort;
@@ -2149,12 +2149,12 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
2149 */ 2149 */
2150 for (disk=0; disk < mddev->raid_disks; disk++) 2150 for (disk=0; disk < mddev->raid_disks; disk++)
2151 if ((p=conf->disks + disk)->rdev == NULL) { 2151 if ((p=conf->disks + disk)->rdev == NULL) {
2152 rdev->in_sync = 0; 2152 clear_bit(In_sync, &rdev->flags);
2153 rdev->raid_disk = disk; 2153 rdev->raid_disk = disk;
2154 found = 1; 2154 found = 1;
2155 if (rdev->saved_raid_disk != disk) 2155 if (rdev->saved_raid_disk != disk)
2156 conf->fullsync = 1; 2156 conf->fullsync = 1;
2157 p->rdev = rdev; 2157 rcu_assign_pointer(p->rdev, rdev);
2158 break; 2158 break;
2159 } 2159 }
2160 print_raid6_conf(conf); 2160 print_raid6_conf(conf);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 31fccb4f05d6..4b71fd6f7aed 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -116,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
116 [ 46 ] = KEY_BLUE, 116 [ 46 ] = KEY_BLUE,
117 [ 24 ] = KEY_KPPLUS, /* fine tune + */ 117 [ 24 ] = KEY_KPPLUS, /* fine tune + */
118 [ 25 ] = KEY_KPMINUS, /* fine tune - */ 118 [ 25 ] = KEY_KPMINUS, /* fine tune - */
119 [ 33 ] = KEY_KPDOT, 119 [ 33 ] = KEY_KPDOT,
120 [ 19 ] = KEY_KPENTER, 120 [ 19 ] = KEY_KPENTER,
121 [ 34 ] = KEY_BACK, 121 [ 34 ] = KEY_BACK,
122 [ 35 ] = KEY_PLAYPAUSE, 122 [ 35 ] = KEY_PLAYPAUSE,
@@ -239,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
239 dprintk(1,"%s: key event code=%d down=%d\n", 239 dprintk(1,"%s: key event code=%d down=%d\n",
240 dev->name,ir->keycode,ir->keypressed); 240 dev->name,ir->keycode,ir->keypressed);
241 input_report_key(dev,ir->keycode,ir->keypressed); 241 input_report_key(dev,ir->keycode,ir->keypressed);
242 input_sync(dev); 242 input_sync(dev);
243} 243}
244 244
245/* -------------------------------------------------------------------------- */ 245/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 47e28b0ee951..a35330315f65 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -13,6 +13,8 @@
13#include "bcm3510.h" 13#include "bcm3510.h"
14#include "stv0297.h" 14#include "stv0297.h"
15#include "mt312.h" 15#include "mt312.h"
16#include "lgdt330x.h"
17#include "dvb-pll.h"
16 18
17/* lnb control */ 19/* lnb control */
18 20
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
234 .inittab = samsung_tbmu24112_inittab, 236 .inittab = samsung_tbmu24112_inittab,
235 .mclk = 88000000UL, 237 .mclk = 88000000UL,
236 .invert = 0, 238 .invert = 0,
237 .enhanced_tuning = 0,
238 .skip_reinit = 0, 239 .skip_reinit = 0,
239 .lock_output = STV0229_LOCKOUTPUT_LK, 240 .lock_output = STV0229_LOCKOUTPUT_LK,
240 .volt13_op0_op1 = STV0299_VOLT13_OP1, 241 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
296 return request_firmware(fw, name, fc->dev); 297 return request_firmware(fw, name, fc->dev);
297} 298}
298 299
300static int lgdt3303_pll_set(struct dvb_frontend* fe,
301 struct dvb_frontend_parameters* params)
302{
303 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4];
305 struct i2c_msg msg =
306 { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
307 int err;
308
309 dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
310 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
311 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
312 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
313 printk(KERN_WARNING "lgdt3303: %s error "
314 "(addr %02x <- %02x, err = %i)\n",
315 __FUNCTION__, buf[0], buf[1], err);
316 if (err < 0)
317 return err;
318 else
319 return -EREMOTEIO;
320 }
321
322 buf[0] = 0x86 | 0x18;
323 buf[1] = 0x50;
324 msg.len = 2;
325 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
326 printk(KERN_WARNING "lgdt3303: %s error "
327 "(addr %02x <- %02x, err = %i)\n",
328 __FUNCTION__, buf[0], buf[1], err);
329 if (err < 0)
330 return err;
331 else
332 return -EREMOTEIO;
333 }
334
335 return 0;
336}
337
338static struct lgdt330x_config air2pc_atsc_hd5000_config = {
339 .demod_address = 0x59,
340 .demod_chip = LGDT3303,
341 .serial_mpeg = 0x04,
342 .pll_set = lgdt3303_pll_set,
343 .clock_polarity_flip = 1,
344};
345
299static struct nxt2002_config samsung_tbmv_config = { 346static struct nxt2002_config samsung_tbmv_config = {
300 .demod_address = 0x0a, 347 .demod_address = 0x0a,
301 .request_firmware = flexcop_fe_request_firmware, 348 .request_firmware = flexcop_fe_request_firmware,
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc)
458 fc->dev_type = FC_AIR_ATSC2; 505 fc->dev_type = FC_AIR_ATSC2;
459 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 506 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
460 } else 507 } else
508 /* try the air atsc 3nd generation (lgdt3303) */
509 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
510 fc->dev_type = FC_AIR_ATSC3;
511 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
512 } else
461 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 513 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
462 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { 514 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
463 fc->dev_type = FC_AIR_ATSC1; 515 fc->dev_type = FC_AIR_ATSC1;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 3a08d38b318a..62282d8dbfa8 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = {
51 "Sky2PC/SkyStar 2 DVB-S", 51 "Sky2PC/SkyStar 2 DVB-S",
52 "Sky2PC/SkyStar 2 DVB-S (old version)", 52 "Sky2PC/SkyStar 2 DVB-S (old version)",
53 "Cable2PC/CableStar 2 DVB-C", 53 "Cable2PC/CableStar 2 DVB-C",
54 "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
54}; 55};
55 56
56const char *flexcop_bus_names[] = { 57const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 4ae1eb5bfe98..23cc6431e2b8 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -26,6 +26,7 @@ typedef enum {
26 FC_SKY, 26 FC_SKY,
27 FC_SKY_OLD, 27 FC_SKY_OLD,
28 FC_CABLE, 28 FC_CABLE,
29 FC_AIR_ATSC3,
29} flexcop_device_type_t; 30} flexcop_device_type_t;
30 31
31typedef enum { 32typedef enum {
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 12873d435406..123ed96f6faa 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc)
193 v204 = fc->read_ibi_reg(fc,misc_204); 193 v204 = fc->read_ibi_reg(fc,misc_204);
194 v204.misc_204.Per_reset_sig = 0; 194 v204.misc_204.Per_reset_sig = 0;
195 fc->write_ibi_reg(fc,misc_204,v204); 195 fc->write_ibi_reg(fc,misc_204,v204);
196 msleep(1);
196 v204.misc_204.Per_reset_sig = 1; 197 v204.misc_204.Per_reset_sig = 1;
197 fc->write_ibi_reg(fc,misc_204,v204); 198 fc->write_ibi_reg(fc,misc_204,v204);
198} 199}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 1e85d16491b0..2337b41714e0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -6,10 +6,12 @@ config DVB_BT8XX
6 select DVB_NXT6000 6 select DVB_NXT6000
7 select DVB_CX24110 7 select DVB_CX24110
8 select DVB_OR51211 8 select DVB_OR51211
9 select DVB_LGDT330X
9 help 10 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 11 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, 12 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
12 the pcHDTV HD2000 cards, and certain AVerMedia cards. 13 the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
14 some AVerMedia cards.
13 15
14 Since these cards have no MPEG decoder onboard, they transmit 16 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need 17 only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index b3c9d7327ac1..8977c7a313df 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = {
690 .device_id = "DTT-CI", 690 .device_id = "DTT-CI",
691 .offset = 1, 691 .offset = 1,
692 .dst_type = DST_TYPE_IS_TERR, 692 .dst_type = DST_TYPE_IS_TERR,
693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
694 .dst_feature = 0 694 .dst_feature = DST_TYPE_HAS_CA
695 }, 695 },
696 696
697 { 697 {
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state)
796 return 0; 796 return 0;
797} 797}
798 798
799static int dst_get_tuner_info(struct dst_state *state)
800{
801 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
802 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
803
804 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
805 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
806 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
807 if (dst_command(state, get_tuner_2, 8) < 0) {
808 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
809 return -1;
810 }
811 } else {
812 if (dst_command(state, get_tuner_1, 8) < 0) {
813 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
814 return -1;
815 }
816 }
817 memset(&state->board_info, '\0', 8);
818 memcpy(&state->board_info, &state->rxbuffer, 8);
819 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
820 if (state->board_info[1] == 0x0b) {
821 if (state->type_flags & DST_TYPE_HAS_TS204)
822 state->type_flags &= ~DST_TYPE_HAS_TS204;
823 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
824 dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
825 } else {
826 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
827 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
828 state->type_flags |= DST_TYPE_HAS_TS204;
829 dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
830 }
831 } else {
832 if (state->board_info[0] == 0xbc) {
833 if (state->type_flags & DST_TYPE_HAS_TS204)
834 state->type_flags &= ~DST_TYPE_HAS_TS204;
835 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
836 dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
837
838 } else if (state->board_info[0] == 0xcc) {
839 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
840 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
841 state->type_flags |= DST_TYPE_HAS_TS204;
842 dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
843 }
844 }
845
846 return 0;
847}
848
799static int dst_get_device_id(struct dst_state *state) 849static int dst_get_device_id(struct dst_state *state)
800{ 850{
801 u8 reply; 851 u8 reply;
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state)
855 state->dst_type = use_dst_type; 905 state->dst_type = use_dst_type;
856 dst_type_flags_print(state->type_flags); 906 dst_type_flags_print(state->type_flags);
857 907
858 if (state->type_flags & DST_TYPE_HAS_TS204) {
859 dst_packsize(state, 204);
860 }
861
862 return 0; 908 return 0;
863} 909}
864 910
865static int dst_probe(struct dst_state *state) 911static int dst_probe(struct dst_state *state)
866{ 912{
913 sema_init(&state->dst_mutex, 1);
867 if ((rdc_8820_reset(state)) < 0) { 914 if ((rdc_8820_reset(state)) < 0) {
868 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); 915 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
869 return -1; 916 return -1;
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state)
886 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); 933 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
887 return 0; 934 return 0;
888 } 935 }
936 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
937 if (dst_get_tuner_info(state) < 0)
938 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
939 }
940 if (state->type_flags & DST_TYPE_HAS_TS204) {
941 dst_packsize(state, 204);
942 }
889 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { 943 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
890 if (dst_fw_ver(state) < 0) { 944 if (dst_fw_ver(state) < 0) {
891 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); 945 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state)
907int dst_command(struct dst_state *state, u8 *data, u8 len) 961int dst_command(struct dst_state *state, u8 *data, u8 len)
908{ 962{
909 u8 reply; 963 u8 reply;
964
965 down(&state->dst_mutex);
910 if ((dst_comm_init(state)) < 0) { 966 if ((dst_comm_init(state)) < 0) {
911 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); 967 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
912 return -1; 968 goto error;
913 } 969 }
914 if (write_dst(state, data, len)) { 970 if (write_dst(state, data, len)) {
915 dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); 971 dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
916 if ((dst_error_recovery(state)) < 0) { 972 if ((dst_error_recovery(state)) < 0) {
917 dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); 973 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
918 return -1; 974 goto error;
919 } 975 }
920 return -1; 976 goto error;
921 } 977 }
922 if ((dst_pio_disable(state)) < 0) { 978 if ((dst_pio_disable(state)) < 0) {
923 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); 979 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
924 return -1; 980 goto error;
925 } 981 }
926 if (state->type_flags & DST_TYPE_HAS_FW_1) 982 if (state->type_flags & DST_TYPE_HAS_FW_1)
927 udelay(3000); 983 udelay(3000);
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
929 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 985 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
930 if ((dst_error_recovery(state)) < 0) { 986 if ((dst_error_recovery(state)) < 0) {
931 dprintk(verbose, DST_INFO, 1, "Recovery Failed."); 987 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
932 return -1; 988 goto error;
933 } 989 }
934 return -1; 990 goto error;
935 } 991 }
936 if (reply != ACK) { 992 if (reply != ACK) {
937 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); 993 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
938 return -1; 994 goto error;
939 } 995 }
940 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 996 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
941 return 0; 997 goto error;
942 if (state->type_flags & DST_TYPE_HAS_FW_1) 998 if (state->type_flags & DST_TYPE_HAS_FW_1)
943 udelay(3000); 999 udelay(3000);
944 else 1000 else
945 udelay(2000); 1001 udelay(2000);
946 if (!dst_wait_dst_ready(state, NO_DELAY)) 1002 if (!dst_wait_dst_ready(state, NO_DELAY))
947 return -1; 1003 goto error;
948 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 1004 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
949 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 1005 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
950 if ((dst_error_recovery(state)) < 0) { 1006 if ((dst_error_recovery(state)) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Recovery failed."); 1007 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
952 return -1; 1008 goto error;
953 } 1009 }
954 return -1; 1010 goto error;
955 } 1011 }
956 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1012 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
957 dprintk(verbose, DST_INFO, 1, "checksum failure"); 1013 dprintk(verbose, DST_INFO, 1, "checksum failure");
958 return -1; 1014 goto error;
959 } 1015 }
960 1016 up(&state->dst_mutex);
961 return 0; 1017 return 0;
1018
1019error:
1020 up(&state->dst_mutex);
1021 return -EIO;
1022
962} 1023}
963EXPORT_SYMBOL(dst_command); 1024EXPORT_SYMBOL(dst_command);
964 1025
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state)
1016 return 0; 1077 return 0;
1017 state->diseq_flags &= ~(HAS_LOCK); 1078 state->diseq_flags &= ~(HAS_LOCK);
1018 if (!dst_wait_dst_ready(state, NO_DELAY)) 1079 if (!dst_wait_dst_ready(state, NO_DELAY))
1019 return 0; 1080 return -EIO;
1020 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1081 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
1021 /* how to get variable length reply ???? */ 1082 /* how to get variable length reply ???? */
1022 retval = read_dst(state, state->rx_tuna, 10); 1083 retval = read_dst(state, state->rx_tuna, 10);
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state)
1024 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1085 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1025 if (retval < 0) { 1086 if (retval < 0) {
1026 dprintk(verbose, DST_DEBUG, 1, "read not successful"); 1087 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1027 return 0; 1088 return retval;
1028 } 1089 }
1029 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1090 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1030 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1091 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1031 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1092 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1032 return 0; 1093 return -EIO;
1033 } 1094 }
1034 } else { 1095 } else {
1035 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1096 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1036 dprintk(verbose, DST_INFO, 1, "checksum failure? "); 1097 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1037 return 0; 1098 return -EIO;
1038 } 1099 }
1039 } 1100 }
1040 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1101 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1041 return 0; 1102 return 0;
1042 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1103 if (state->dst_type == DST_TYPE_IS_SAT) {
1104 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1105 } else {
1106 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1107 }
1108 state->decode_freq = state->decode_freq * 1000;
1043 state->decode_lock = 1; 1109 state->decode_lock = 1;
1044 state->diseq_flags |= HAS_LOCK; 1110 state->diseq_flags |= HAS_LOCK;
1045 1111
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1062 dst_set_voltage(fe, SEC_VOLTAGE_13); 1128 dst_set_voltage(fe, SEC_VOLTAGE_13);
1063 } 1129 }
1064 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1130 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1065 1131 down(&state->dst_mutex);
1066 if ((dst_comm_init(state)) < 0) { 1132 if ((dst_comm_init(state)) < 0) {
1067 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); 1133 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1068 return -1; 1134 goto error;
1069 } 1135 }
1070 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1136 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1071 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1137 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1077 if (retval < 0) { 1143 if (retval < 0) {
1078 dst_pio_disable(state); 1144 dst_pio_disable(state);
1079 dprintk(verbose, DST_DEBUG, 1, "write not successful"); 1145 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1080 return retval; 1146 goto werr;
1081 } 1147 }
1082 if ((dst_pio_disable(state)) < 0) { 1148 if ((dst_pio_disable(state)) < 0) {
1083 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); 1149 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1084 return -1; 1150 goto error;
1085 } 1151 }
1086 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1152 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1087 dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); 1153 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1088 return -1; 1154 goto error;
1089 } 1155 }
1090 if (reply != ACK) { 1156 if (reply != ACK) {
1091 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); 1157 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1092 return 0; 1158 goto error;
1093 } 1159 }
1094 state->diseq_flags |= ATTEMPT_TUNE; 1160 state->diseq_flags |= ATTEMPT_TUNE;
1095 1161 retval = dst_get_tuna(state);
1096 return dst_get_tuna(state); 1162werr:
1163 up(&state->dst_mutex);
1164 return retval;
1165
1166error:
1167 up(&state->dst_mutex);
1168 return -EIO;
1097} 1169}
1098 1170
1099/* 1171/*
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
69} 69}
70 70
71 71
72static int put_checksum(u8 *check_string, int length) 72static void put_checksum(u8 *check_string, int length)
73{ 73{
74 u8 i = 0, checksum = 0; 74 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
75 75 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); 76 check_string[length] = dst_check_sum (check_string, length);
77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); 77 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
79
80 while (i < length) {
81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
82 checksum += check_string[i];
83 i++;
84 }
85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
87 check_string[length] = ~checksum + 1;
88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
90
91 return 0;
92} 78}
93 79
94static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 80static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
95{ 81{
96 u8 reply; 82 u8 reply;
97 83
84 down(&state->dst_mutex);
98 dst_comm_init(state); 85 dst_comm_init(state);
99 msleep(65); 86 msleep(65);
100 87
101 if (write_dst(state, data, len)) { 88 if (write_dst(state, data, len)) {
102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); 89 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
103 dst_error_recovery(state); 90 dst_error_recovery(state);
104 return -1; 91 goto error;
105 } 92 }
106 if ((dst_pio_disable(state)) < 0) { 93 if ((dst_pio_disable(state)) < 0) {
107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); 94 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
108 return -1; 95 goto error;
109 } 96 }
110 if (read_dst(state, &reply, GET_ACK) < 0) { 97 if (read_dst(state, &reply, GET_ACK) < 0) {
111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 98 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
112 dst_error_recovery(state); 99 dst_error_recovery(state);
113 return -1; 100 goto error;
114 } 101 }
115 if (read) { 102 if (read) {
116 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 103 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 104 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
118 return -1; 105 goto error;
119 } 106 }
120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 107 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
122 dst_error_recovery(state); 109 dst_error_recovery(state);
123 return -1; 110 goto error;
124 } 111 }
125 } 112 }
126 113 up(&state->dst_mutex);
127 return 0; 114 return 0;
115
116error:
117 up(&state->dst_mutex);
118 return -EIO;
128} 119}
129 120
130 121
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
166 return 0; 157 return 0;
167} 158}
168 159
169static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 160static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
170{ 161{
171 int i; 162 int i;
172 u8 slot_cap[256]; 163 u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
192 p_ca_caps->descr_num = slot_cap[7]; 183 p_ca_caps->descr_num = slot_cap[7];
193 p_ca_caps->descr_type = 1; 184 p_ca_caps->descr_type = 1;
194 185
195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) 186 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
196 return -EFAULT; 187 return -EFAULT;
197 188
198 return 0; 189 return 0;
199} 190}
200 191
201/* Need some more work */ 192/* Need some more work */
202static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 193static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
203{ 194{
204 return -EOPNOTSUPP; 195 return -EOPNOTSUPP;
205} 196}
206 197
207 198
208static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 199static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
209{ 200{
210 int i; 201 int i;
211 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 202 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
212 203
213 u8 *slot_info = state->rxbuffer; 204 u8 *slot_info = state->messages;
214 205
215 put_checksum(&slot_command[0], 7); 206 put_checksum(&slot_command[0], 7);
216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 207 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
238 } else 229 } else
239 p_ca_slot_info->flags = 0; 230 p_ca_slot_info->flags = 0;
240 231
241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) 232 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
242 return -EFAULT; 233 return -EFAULT;
243 234
244 return 0; 235 return 0;
245} 236}
246 237
247 238
248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 239static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
249{ 240{
250 u8 i = 0; 241 u8 i = 0;
251 u32 command = 0; 242 u32 command = 0;
252 243
253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 244 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
254 return -EFAULT; 245 return -EFAULT;
255 246
256 if (p_ca_message->msg) { 247 if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
266 switch (command) { 257 switch (command) {
267 case CA_APP_INFO: 258 case CA_APP_INFO:
268 memcpy(p_ca_message->msg, state->messages, 128); 259 memcpy(p_ca_message->msg, state->messages, 128);
269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
270 return -EFAULT; 261 return -EFAULT;
271 break; 262 break;
272 } 263 }
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
315 return 0; 306 return 0;
316} 307}
317 308
318u32 asn_1_decode(u8 *asn_1_array) 309static u32 asn_1_decode(u8 *asn_1_array)
319{ 310{
320 u8 length_field = 0, word_count = 0, count = 0; 311 u8 length_field = 0, word_count = 0, count = 0;
321 u32 length = 0; 312 u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
328 } else { 319 } else {
329 word_count = length_field & 0x7f; 320 word_count = length_field & 0x7f;
330 for (count = 0; count < word_count; count++) { 321 for (count = 0; count < word_count; count++) {
331 length = (length | asn_1_array[count + 1]) << 8; 322 length = length << 8;
323 length += asn_1_array[count + 1];
332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
333 } 325 }
334 } 326 }
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
399 return 0; 391 return 0;
400} 392}
401 393
402static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 394static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
403{ 395{
404 int i = 0; 396 int i = 0;
405 unsigned int ca_message_header_len; 397 unsigned int ca_message_header_len;
406 398
407 u32 command = 0; 399 u32 command = 0;
408 struct ca_msg *hw_buffer; 400 struct ca_msg *hw_buffer;
401 int result = 0;
409 402
410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 403 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 404 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
413 } 406 }
414 dprintk(verbose, DST_CA_DEBUG, 1, " "); 407 dprintk(verbose, DST_CA_DEBUG, 1, " ");
415 408
416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 409 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
417 return -EFAULT; 410 result = -EFAULT;
411 goto free_mem_and_exit;
412 }
413
418 414
419 if (p_ca_message->msg) { 415 if (p_ca_message->msg) {
420 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 416 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); 429 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 430 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); 431 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
436 return -1; 432 result = -1;
433 goto free_mem_and_exit;
437 } 434 }
438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); 435 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
439 break; 436 break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
442 /* Have to handle the 2 basic types of cards here */ 439 /* Have to handle the 2 basic types of cards here */
443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 440 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); 441 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
445 return -1; 442 result = -1;
443 goto free_mem_and_exit;
446 } 444 }
447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); 445 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
448 break; 446 break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
451 449
452 if ((ca_get_app_info(state)) < 0) { 450 if ((ca_get_app_info(state)) < 0) {
453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); 451 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
454 return -1; 452 result = -1;
453 goto free_mem_and_exit;
455 } 454 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 455 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 456 break;
458 } 457 }
459 } 458 }
460 return 0; 459free_mem_and_exit:
460 kfree (hw_buffer);
461
462 return result;
461} 463}
462 464
463static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 465static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
464{ 466{
465 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 467 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
466 struct dst_state* state = (struct dst_state*) dvbdev->priv; 468 struct dst_state* state = (struct dst_state*) dvbdev->priv;
467 struct ca_slot_info *p_ca_slot_info; 469 struct ca_slot_info *p_ca_slot_info;
468 struct ca_caps *p_ca_caps; 470 struct ca_caps *p_ca_caps;
469 struct ca_msg *p_ca_message; 471 struct ca_msg *p_ca_message;
472 void __user *arg = (void __user *)ioctl_arg;
473 int result = 0;
470 474
471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 475 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
486 dprintk(verbose, DST_CA_INFO, 1, " Sending message"); 490 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
487 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 491 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); 492 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
489 return -1; 493 result = -1;
494 goto free_mem_and_exit;
490 } 495 }
491 break; 496 break;
492 case CA_GET_MSG: 497 case CA_GET_MSG:
493 dprintk(verbose, DST_CA_INFO, 1, " Getting message"); 498 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
494 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 499 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); 500 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
496 return -1; 501 result = -1;
502 goto free_mem_and_exit;
497 } 503 }
498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); 504 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
499 break; 505 break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); 512 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 513 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); 514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
509 return -1; 515 result = -1;
516 goto free_mem_and_exit;
510 } 517 }
511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); 518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
512 break; 519 break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); 521 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 522 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); 523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
517 return -1; 524 result = -1;
525 goto free_mem_and_exit;
518 } 526 }
519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
520 break; 528 break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); 530 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 531 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
525 return -1; 533 result = -1;
534 goto free_mem_and_exit;
526 } 535 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); 536 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
528 break; 537 break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); 539 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
531 if ((ca_set_slot_descr()) < 0) { 540 if ((ca_set_slot_descr()) < 0) {
532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); 541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
533 return -1; 542 result = -1;
543 goto free_mem_and_exit;
534 } 544 }
535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); 545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
536 break; 546 break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); 548 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
539 if ((ca_set_pid()) < 0) { 549 if ((ca_set_pid()) < 0) {
540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); 550 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
541 return -1; 551 result = -1;
552 goto free_mem_and_exit;
542 } 553 }
543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); 554 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
544 default: 555 default:
545 return -EOPNOTSUPP; 556 result = -EOPNOTSUPP;
546 }; 557 };
558 free_mem_and_exit:
559 kfree (p_ca_message);
560 kfree (p_ca_slot_info);
561 kfree (p_ca_caps);
547 562
548 return 0; 563 return result;
549} 564}
550 565
551static int dst_ca_open(struct inode *inode, struct file *file) 566static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
582 597
583static struct file_operations dst_ca_fops = { 598static struct file_operations dst_ca_fops = {
584 .owner = THIS_MODULE, 599 .owner = THIS_MODULE,
585 .ioctl = (void *)dst_ca_ioctl, 600 .ioctl = dst_ca_ioctl,
586 .open = dst_ca_open, 601 .open = dst_ca_open,
587 .release = dst_ca_release, 602 .release = dst_ca_release,
588 .read = dst_ca_read, 603 .read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3281a6ca3685..81557f38fe38 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,6 +22,7 @@
22#ifndef DST_COMMON_H 22#ifndef DST_COMMON_H
23#define DST_COMMON_H 23#define DST_COMMON_H
24 24
25#include <linux/smp_lock.h>
25#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include "bt878.h" 28#include "bt878.h"
@@ -49,6 +50,7 @@
49#define DST_TYPE_HAS_FW_BUILD 64 50#define DST_TYPE_HAS_FW_BUILD 64
50#define DST_TYPE_HAS_OBS_REGS 128 51#define DST_TYPE_HAS_OBS_REGS 128
51#define DST_TYPE_HAS_INC_COUNT 256 52#define DST_TYPE_HAS_INC_COUNT 256
53#define DST_TYPE_HAS_MULTI_FE 512
52 54
53/* Card capability list */ 55/* Card capability list */
54 56
@@ -117,6 +119,9 @@ struct dst_state {
117 u8 fw_version[8]; 119 u8 fw_version[8];
118 u8 card_info[8]; 120 u8 card_info[8];
119 u8 vendor[8]; 121 u8 vendor[8];
122 u8 board_info[8];
123
124 struct semaphore dst_mutex;
120}; 125};
121 126
122struct dst_types { 127struct dst_types {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index c5c7672cd538..2e398090cf63 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -34,6 +34,7 @@
34#include "dvb_frontend.h" 34#include "dvb_frontend.h"
35#include "dvb-bt8xx.h" 35#include "dvb-bt8xx.h"
36#include "bt878.h" 36#include "bt878.h"
37#include "dvb-pll.h"
37 38
38static int debug; 39static int debug;
39 40
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
279 data[0] = (div >> 8) & 0x7f; 280 data[0] = (div >> 8) & 0x7f;
280 data[1] = div & 0xff; 281 data[1] = div & 0xff;
281 data[2] = ((div >> 10) & 0x60) | cfg; 282 data[2] = ((div >> 10) & 0x60) | cfg;
282 data[3] = cpump | band_select; 283 data[3] = (cpump << 6) | band_select;
283 284
284 i2c_transfer(card->i2c_adapter, &msg, 1); 285 i2c_transfer(card->i2c_adapter, &msg, 1);
285 return (div * 166666 - 36000000); 286 return (div * 166666 - 36000000);
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
522 /* 523 /*
523 * Reset the frontend, must be called before trying 524 * Reset the frontend, must be called before trying
524 * to initialise the MT352 or mt352_attach 525 * to initialise the MT352 or mt352_attach
525 * will fail. 526 * will fail. Same goes for the nxt6000 frontend.
526 *
527 * Presumably not required for the NXT6000 frontend.
528 * 527 *
529 */ 528 */
530 529
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = {
546 .pll_set = digitv_alps_tded4_pll_set, 545 .pll_set = digitv_alps_tded4_pll_set,
547}; 546};
548 547
548static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
549{
550 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
551 u8 buf[4];
552 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
553 int err;
554
555 dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
556 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
557 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
558 if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
559 printk(KERN_WARNING "dvb-bt8xx: %s error "
560 "(addr %02x <- %02x, err = %i)\n",
561 __FUNCTION__, buf[0], buf[1], err);
562 if (err < 0)
563 return err;
564 else
565 return -EREMOTEIO;
566 }
567
568 /* Set the Auxiliary Byte. */
569 buf[2] &= ~0x20;
570 buf[2] |= 0x18;
571 buf[3] = 0x50;
572 i2c_transfer(card->i2c_adapter, &msg, 1);
573
574 return 0;
575}
576
577static struct lgdt330x_config tdvs_tua6034_config = {
578 .demod_address = 0x0e,
579 .demod_chip = LGDT3303,
580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
581 .pll_set = tdvs_tua6034_pll_set,
582};
583
584static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
585{
586 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
587
588 /* Pulse the reset line */
589 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
590 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
591 msleep(100);
592
593 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
594 msleep(100);
595}
596
549static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 597static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
550{ 598{
551 int ret; 599 int ret;
552 struct dst_state* state = NULL; 600 struct dst_state* state = NULL;
553 601
554 switch(type) { 602 switch(type) {
555#ifdef BTTV_DVICO_DVBT_LITE 603#ifdef BTTV_BOARD_DVICO_DVBT_LITE
556 case BTTV_DVICO_DVBT_LITE: 604 case BTTV_BOARD_DVICO_DVBT_LITE:
557 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 605 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
558 if (card->fe != NULL) { 606 if (card->fe != NULL) {
559 card->fe->ops->info.frequency_min = 174000000; 607 card->fe->ops->info.frequency_min = 174000000;
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
562 break; 610 break;
563#endif 611#endif
564 612
565#ifdef BTTV_TWINHAN_VP3021 613#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
566 case BTTV_TWINHAN_VP3021: 614 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
615 lgdt330x_reset(card);
616 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
617 if (card->fe != NULL)
618 dprintk ("dvb_bt8xx: lgdt330x detected\n");
619 break;
620#endif
621
622#ifdef BTTV_BOARD_TWINHAN_VP3021
623 case BTTV_BOARD_TWINHAN_VP3021:
567#else 624#else
568 case BTTV_NEBULA_DIGITV: 625 case BTTV_BOARD_NEBULA_DIGITV:
569#endif 626#endif
570 /* 627 /*
571 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); 628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
573 */ 630 */
574 631
575 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ 632 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633 digitv_alps_tded4_reset(card);
576 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 634 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
577 if (card->fe != NULL) { 635 if (card->fe != NULL) {
578 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); 636 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
587 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); 645 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
588 break; 646 break;
589 647
590 case BTTV_AVDVBT_761: 648 case BTTV_BOARD_AVDVBT_761:
591 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 649 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
592 break; 650 break;
593 651
594 case BTTV_AVDVBT_771: 652 case BTTV_BOARD_AVDVBT_771:
595 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); 653 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
596 if (card->fe != NULL) { 654 if (card->fe != NULL) {
597 card->fe->ops->info.frequency_min = 174000000; 655 card->fe->ops->info.frequency_min = 174000000;
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
599 } 657 }
600 break; 658 break;
601 659
602 case BTTV_TWINHAN_DST: 660 case BTTV_BOARD_TWINHAN_DST:
603 /* DST is not a frontend driver !!! */ 661 /* DST is not a frontend driver !!! */
604 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); 662 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
605 /* Setup the Card */ 663 /* Setup the Card */
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
620 ret = dst_ca_attach(state, &card->dvb_adapter); 678 ret = dst_ca_attach(state, &card->dvb_adapter);
621 break; 679 break;
622 680
623 case BTTV_PINNACLESAT: 681 case BTTV_BOARD_PINNACLESAT:
624 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 682 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
625 break; 683 break;
626 684
627 case BTTV_PC_HDTV: 685 case BTTV_BOARD_PC_HDTV:
628 card->fe = or51211_attach(&or51211_config, card->i2c_adapter); 686 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
629 break; 687 break;
630 } 688 }
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
746 card->i2c_adapter = &sub->core->i2c_adap; 804 card->i2c_adapter = &sub->core->i2c_adap;
747 805
748 switch(sub->core->type) { 806 switch(sub->core->type) {
749 case BTTV_PINNACLESAT: 807 case BTTV_BOARD_PINNACLESAT:
750 card->gpio_mode = 0x0400c060; 808 card->gpio_mode = 0x0400c060;
751 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 809 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
752 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 810 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev)
754 card->irq_err_ignore = 0; 812 card->irq_err_ignore = 0;
755 break; 813 break;
756 814
757#ifdef BTTV_DVICO_DVBT_LITE 815#ifdef BTTV_BOARD_DVICO_DVBT_LITE
758 case BTTV_DVICO_DVBT_LITE: 816 case BTTV_BOARD_DVICO_DVBT_LITE:
759#endif 817#endif
760 card->gpio_mode = 0x0400C060; 818 card->gpio_mode = 0x0400C060;
761 card->op_sync_orin = 0; 819 card->op_sync_orin = 0;
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev)
765 * DA_APP(parallel) */ 823 * DA_APP(parallel) */
766 break; 824 break;
767 825
768#ifdef BTTV_TWINHAN_VP3021 826#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
769 case BTTV_TWINHAN_VP3021: 827 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
828#endif
829 card->gpio_mode = 0x0400c060;
830 card->op_sync_orin = BT878_RISC_SYNC_MASK;
831 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
832 break;
833
834#ifdef BTTV_BOARD_TWINHAN_VP3021
835 case BTTV_BOARD_TWINHAN_VP3021:
770#else 836#else
771 case BTTV_NEBULA_DIGITV: 837 case BTTV_BOARD_NEBULA_DIGITV:
772#endif 838#endif
773 case BTTV_AVDVBT_761: 839 case BTTV_BOARD_AVDVBT_761:
774 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); 840 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
775 card->op_sync_orin = 0; 841 card->op_sync_orin = 0;
776 card->irq_err_ignore = 0; 842 card->irq_err_ignore = 0;
777 /* A_PWRDN DA_SBR DA_APP (high speed serial) */ 843 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
778 break; 844 break;
779 845
780 case BTTV_AVDVBT_771: //case 0x07711461: 846 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
781 card->gpio_mode = 0x0400402B; 847 card->gpio_mode = 0x0400402B;
782 card->op_sync_orin = BT878_RISC_SYNC_MASK; 848 card->op_sync_orin = BT878_RISC_SYNC_MASK;
783 card->irq_err_ignore = 0; 849 card->irq_err_ignore = 0;
784 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ 850 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
785 break; 851 break;
786 852
787 case BTTV_TWINHAN_DST: 853 case BTTV_BOARD_TWINHAN_DST:
788 card->gpio_mode = 0x2204f2c; 854 card->gpio_mode = 0x2204f2c;
789 card->op_sync_orin = BT878_RISC_SYNC_MASK; 855 card->op_sync_orin = BT878_RISC_SYNC_MASK;
790 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | 856 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev)
802 * RISC+FIFO ENABLE */ 868 * RISC+FIFO ENABLE */
803 break; 869 break;
804 870
805 case BTTV_PC_HDTV: 871 case BTTV_BOARD_PC_HDTV:
806 card->gpio_mode = 0x0100EC7B; 872 card->gpio_mode = 0x0100EC7B;
807 card->op_sync_orin = 0; 873 card->op_sync_orin = 0;
808 card->irq_err_ignore = 0; 874 card->irq_err_ignore = 0;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 9ec8e5bd6c1f..cf035a80361c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -35,6 +35,7 @@
35#include "nxt6000.h" 35#include "nxt6000.h"
36#include "cx24110.h" 36#include "cx24110.h"
37#include "or51211.h" 37#include "or51211.h"
38#include "lgdt330x.h"
38 39
39struct dvb_bt8xx_card { 40struct dvb_bt8xx_card {
40 struct semaphore lock; 41 struct semaphore lock;
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9719a3b30f78..7d7b0067f228 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -48,8 +48,11 @@
48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. 48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
49 */ 49 */
50 50
51#ifndef DMX_MAX_SECTION_SIZE
52#define DMX_MAX_SECTION_SIZE 4096
53#endif
51#ifndef DMX_MAX_SECFEED_SIZE 54#ifndef DMX_MAX_SECFEED_SIZE
52#define DMX_MAX_SECFEED_SIZE 4096 55#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
53#endif 56#endif
54 57
55 58
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dc476dda2b71..b4c899b15959 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
246 246
247 for (n = 0; sec->secbufp + 2 < limit; n++) { 247 for (n = 0; sec->secbufp + 2 < limit; n++) {
248 seclen = section_length(sec->secbuf); 248 seclen = section_length(sec->secbuf);
249 if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 249 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
250 || seclen + sec->secbufp > limit) 250 || seclen + sec->secbufp > limit)
251 return 0; 251 return 0;
252 sec->seclen = seclen; 252 sec->seclen = seclen;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a8bc84240b50..6ffa6b216363 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,8 +42,6 @@
42#include "dvb_frontend.h" 42#include "dvb_frontend.h"
43#include "dvbdev.h" 43#include "dvbdev.h"
44 44
45// #define DEBUG_LOCKLOSS 1
46
47static int dvb_frontend_debug; 45static int dvb_frontend_debug;
48static int dvb_shutdown_timeout = 5; 46static int dvb_shutdown_timeout = 5;
49static int dvb_force_auto_inversion; 47static int dvb_force_auto_inversion;
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data)
438 if (s & FE_HAS_LOCK) 436 if (s & FE_HAS_LOCK)
439 continue; 437 continue;
440 else { /* if we _WERE_ tuned, but now don't have a lock */ 438 else { /* if we _WERE_ tuned, but now don't have a lock */
441#ifdef DEBUG_LOCKLOSS
442 /* first of all try setting the tone again if it was on - this
443 * sometimes works around problems with noisy power supplies */
444 if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
445 fe->ops->set_tone(fe, fepriv->tone);
446 mdelay(100);
447 s = 0;
448 fe->ops->read_status(fe, &s);
449 if (s & FE_HAS_LOCK) {
450 printk("DVB%i: Lock was lost, but regained by setting "
451 "the tone. This may indicate your power supply "
452 "is noisy/slightly incompatable with this DVB-S "
453 "adapter\n", fe->dvb->num);
454 fepriv->state = FESTATE_TUNED;
455 continue;
456 }
457 }
458#endif
459 /* some other reason for losing the lock - start zigzagging */
460 fepriv->state = FESTATE_ZIGZAG_FAST; 439 fepriv->state = FESTATE_ZIGZAG_FAST;
461 fepriv->started_auto_step = fepriv->auto_step; 440 fepriv->started_auto_step = fepriv->auto_step;
462 check_wrapped = 0; 441 check_wrapped = 0;
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
577 fepriv->thread_pid); 556 fepriv->thread_pid);
578} 557}
579 558
559s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
560{
561 return ((curtime.tv_usec < lasttime.tv_usec) ?
562 1000000 - lasttime.tv_usec + curtime.tv_usec :
563 curtime.tv_usec - lasttime.tv_usec);
564}
565EXPORT_SYMBOL(timeval_usec_diff);
566
567static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
568{
569 curtime->tv_usec += add_usec;
570 if (curtime->tv_usec >= 1000000) {
571 curtime->tv_usec -= 1000000;
572 curtime->tv_sec++;
573 }
574}
575
576/*
577 * Sleep until gettimeofday() > waketime + add_usec
578 * This needs to be as precise as possible, but as the delay is
579 * usually between 2ms and 32ms, it is done using a scheduled msleep
580 * followed by usleep (normally a busy-wait loop) for the remainder
581 */
582void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
583{
584 struct timeval lasttime;
585 s32 delta, newdelta;
586
587 timeval_usec_add(waketime, add_usec);
588
589 do_gettimeofday(&lasttime);
590 delta = timeval_usec_diff(lasttime, *waketime);
591 if (delta > 2500) {
592 msleep((delta - 1500) / 1000);
593 do_gettimeofday(&lasttime);
594 newdelta = timeval_usec_diff(lasttime, *waketime);
595 delta = (newdelta > delta) ? 0 : newdelta;
596 }
597 if (delta > 0)
598 udelay(delta);
599}
600EXPORT_SYMBOL(dvb_frontend_sleep_until);
601
580static int dvb_frontend_start(struct dvb_frontend *fe) 602static int dvb_frontend_start(struct dvb_frontend *fe)
581{ 603{
582 int ret; 604 int ret;
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
728 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 750 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
729 fepriv->state = FESTATE_DISEQC; 751 fepriv->state = FESTATE_DISEQC;
730 fepriv->status = 0; 752 fepriv->status = 0;
753 } else if (fe->ops->set_voltage) {
754 /*
755 * NOTE: This is a fallback condition. Some frontends
756 * (stv0299 for instance) take longer than 8msec to
757 * respond to a set_voltage command. Those switches
758 * need custom routines to switch properly. For all
759 * other frontends, the following shoule work ok.
760 * Dish network legacy switches (as used by Dish500)
761 * are controlled by sending 9-bit command words
762 * spaced 8msec apart.
763 * the actual command word is switch/port dependant
764 * so it is up to the userspace application to send
765 * the right command.
766 * The command must always start with a '0' after
767 * initialization, so parg is 8 bits and does not
768 * include the initialization or start bit
769 */
770 unsigned int cmd = ((unsigned int) parg) << 1;
771 struct timeval nexttime;
772 struct timeval tv[10];
773 int i;
774 u8 last = 1;
775 if (dvb_frontend_debug)
776 printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
777 do_gettimeofday(&nexttime);
778 if (dvb_frontend_debug)
779 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
780 /* before sending a command, initialize by sending
781 * a 32ms 18V to the switch
782 */
783 fe->ops->set_voltage(fe, SEC_VOLTAGE_18);
784 dvb_frontend_sleep_until(&nexttime, 32000);
785
786 for (i = 0; i < 9; i++) {
787 if (dvb_frontend_debug)
788 do_gettimeofday(&tv[i + 1]);
789 if ((cmd & 0x01) != last) {
790 /* set voltage to (last ? 13V : 18V) */
791 fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
792 last = (last) ? 0 : 1;
793 }
794 cmd = cmd >> 1;
795 if (i != 8)
796 dvb_frontend_sleep_until(&nexttime, 8000);
797 }
798 if (dvb_frontend_debug) {
799 printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
800 __FUNCTION__, fe->dvb->num);
801 for (i = 1; i < 10; i++)
802 printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
803 }
804 err = 0;
805 fepriv->state = FESTATE_DISEQC;
806 fepriv->status = 0;
731 } 807 }
732 break; 808 break;
733 809
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9c2c1d1136bd..348c9b0b988a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
101 101
102extern int dvb_unregister_frontend(struct dvb_frontend* fe); 102extern int dvb_unregister_frontend(struct dvb_frontend* fe);
103 103
104extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
105extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
106
104#endif 107#endif
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index e55322ef76b3..49f541d9a042 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ 43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ 44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ 45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 46 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ 47 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ 48 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */ 49 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ 50 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */ 51 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */ 55 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ 56 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ 57 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */ 58 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */ 59 { 0x02, 0x15, KEY_MENU }, /* MENU */
64 60
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 0058505634a0..aa271a2496d5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
82static struct dvb_usb_properties dibusb1_1_properties; 82static struct dvb_usb_properties dibusb1_1_properties;
83static struct dvb_usb_properties dibusb1_1_an2235_properties; 83static struct dvb_usb_properties dibusb1_1_an2235_properties;
84static struct dvb_usb_properties dibusb2_0b_properties; 84static struct dvb_usb_properties dibusb2_0b_properties;
85static struct dvb_usb_properties artec_t1_usb2_properties;
85 86
86static int dibusb_probe(struct usb_interface *intf, 87static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id) 88 const struct usb_device_id *id)
88{ 89{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || 90 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || 91 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) 92 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
93 dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
92 return 0; 94 return 0;
93 95
94 return -EINVAL; 96 return -EINVAL;
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
128 130
129/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
130 132
133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
135
131// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 136// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132 137
133#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 138#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
134/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 139/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
135#endif 140#endif
136 { } /* Terminating entry */ 141 { } /* Terminating entry */
137}; 142};
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
264 }, 269 },
265#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 270#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
266 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 271 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
267 { &dibusb_dib3000mb_table[28], NULL }, 272 { &dibusb_dib3000mb_table[30], NULL },
268 { NULL }, 273 { NULL },
269 }, 274 },
270#endif 275#endif
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
273 278
274static struct dvb_usb_properties dibusb2_0b_properties = { 279static struct dvb_usb_properties dibusb2_0b_properties = {
275 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, 280 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
276 .pid_filter_count = 32, 281 .pid_filter_count = 16,
277 282
278 .usb_ctrl = CYPRESS_FX2, 283 .usb_ctrl = CYPRESS_FX2,
279 284
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
321 } 326 }
322}; 327};
323 328
329static struct dvb_usb_properties artec_t1_usb2_properties = {
330 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
331 .pid_filter_count = 16,
332
333 .usb_ctrl = CYPRESS_FX2,
334
335 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
336
337 .size_of_priv = sizeof(struct dibusb_state),
338
339 .streaming_ctrl = dibusb2_0_streaming_ctrl,
340 .pid_filter = dibusb_pid_filter,
341 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
342 .power_ctrl = dibusb2_0_power_ctrl,
343 .frontend_attach = dibusb_dib3000mb_frontend_attach,
344 .tuner_attach = dibusb_tuner_probe_and_attach,
345
346 .rc_interval = DEFAULT_RC_INTERVAL,
347 .rc_key_map = dibusb_rc_keys,
348 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
349 .rc_query = dibusb_rc_query,
350
351 .i2c_algo = &dibusb_i2c_algo,
352
353 .generic_bulk_ctrl_endpoint = 0x01,
354 /* parameter for the MPEG2-data transfer */
355 .urb = {
356 .type = DVB_USB_BULK,
357 .count = 7,
358 .endpoint = 0x06,
359 .u = {
360 .bulk = {
361 .buffersize = 4096,
362 }
363 }
364 },
365
366 .num_device_descs = 1,
367 .devices = {
368 { "Artec T1 USB2.0",
369 { &dibusb_dib3000mb_table[28], NULL },
370 { &dibusb_dib3000mb_table[29], NULL },
371 },
372 }
373};
374
324static struct usb_driver dibusb_driver = { 375static struct usb_driver dibusb_driver = {
325 .owner = THIS_MODULE, 376 .owner = THIS_MODULE,
326 .name = "dvb_usb_dibusb_mb", 377 .name = "dvb_usb_dibusb_mb",
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 6611f62977c0..2d99d05c7eab 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -11,7 +11,9 @@
11#ifndef _DVB_USB_DIBUSB_H_ 11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_ 12#define _DVB_USB_DIBUSB_H_
13 13
14#define DVB_USB_LOG_PREFIX "dibusb" 14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
15#include "dvb-usb.h" 17#include "dvb-usb.h"
16 18
17#include "dib3000.h" 19#include "dib3000.h"
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0818996bf150..6be99e537e12 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -43,10 +43,14 @@
43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c 44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
46#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
47#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
46#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 48#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
47#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 49#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
48#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 50#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
49#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 51#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
52#define USB_PID_DIBCOM_STK7700 0x1e14
53#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
50#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 54#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
51#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 55#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
52#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 56#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -68,6 +72,7 @@
68#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 72#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
69#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 73#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
70#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 74#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
75#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
71#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 76#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
72#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 77#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
73#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e 78#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index f5799a4c228e..36b7048c02d2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un
196 dvb_usb_free_stream_buffers(d); 196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM; 197 return -ENOMEM;
198 } 198 }
199 deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]); 199 deb_mem("buffer %d: %p (dma: %llu)\n",
200 d->buf_num, d->buf_list[d->buf_num],
201 (unsigned long long)d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size); 202 memset(d->buf_list[d->buf_num],0,size);
201 } 203 }
202 deb_mem("allocation successful\n"); 204 deb_mem("allocation successful\n");
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a50a41f6f79d..8e269e1c1f9d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -164,6 +164,14 @@ config DVB_NXT2002
164 help 164 help
165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
166 166
167config DVB_NXT200X
168 tristate "Nextwave NXT2002/NXT2004 based"
169 depends on DVB_CORE
170 select FW_LOADER
171 help
172 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
173 to support this frontend.
174
167config DVB_OR51211 175config DVB_OR51211
168 tristate "or51211 based (pcHDTV HD2000 card)" 176 tristate "or51211 based (pcHDTV HD2000 card)"
169 depends on DVB_CORE 177 depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index ad8658ffd60a..a98760fe08a1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o 26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o 27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o 28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 30obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 31obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 536c35d969b7..f857b869616c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
226EXPORT_SYMBOL(dvb_pll_tua6034); 226EXPORT_SYMBOL(dvb_pll_tua6034);
227 227
228/* Infineon TUA6034 228/* Infineon TUA6034
229 * used in LG Innotek TDVS-H062F 229 * used in LG TDVS H061F and LG TDVS H062F
230 */ 230 */
231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { 231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
232 .name = "LG/Infineon TUA6034", 232 .name = "LG/Infineon TUA6034",
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = {
292}; 292};
293EXPORT_SYMBOL(dvb_pll_tded4); 293EXPORT_SYMBOL(dvb_pll_tded4);
294 294
295/* ALPS TDHU2
296 * used in AverTVHD MCE A180
297 */
298struct dvb_pll_desc dvb_pll_tdhu2 = {
299 .name = "ALPS TDHU2",
300 .min = 54000000,
301 .max = 864000000,
302 .count = 4,
303 .entries = {
304 { 162000000, 44000000, 62500, 0x85, 0x01 },
305 { 426000000, 44000000, 62500, 0x85, 0x02 },
306 { 782000000, 44000000, 62500, 0x85, 0x08 },
307 { 999999999, 44000000, 62500, 0x85, 0x88 },
308 }
309};
310EXPORT_SYMBOL(dvb_pll_tdhu2);
311
312/* Philips TUV1236D
313 * used in ATI HDTV Wonder
314 */
315struct dvb_pll_desc dvb_pll_tuv1236d = {
316 .name = "Philips TUV1236D",
317 .min = 54000000,
318 .max = 864000000,
319 .count = 3,
320 .entries = {
321 { 157250000, 44000000, 62500, 0xc6, 0x41 },
322 { 454000000, 44000000, 62500, 0xc6, 0x42 },
323 { 999999999, 44000000, 62500, 0xc6, 0x44 },
324 },
325};
326EXPORT_SYMBOL(dvb_pll_tuv1236d);
327
328/* Samsung TBMV30111IN
329 * used in Air2PC ATSC - 2nd generation (nxt2002)
330 */
331struct dvb_pll_desc dvb_pll_tbmv30111in = {
332 .name = "Samsung TBMV30111IN",
333 .min = 54000000,
334 .max = 860000000,
335 .count = 4,
336 .entries = {
337 { 172000000, 44000000, 166666, 0xb4, 0x01 },
338 { 214000000, 44000000, 166666, 0xb4, 0x02 },
339 { 467000000, 44000000, 166666, 0xbc, 0x02 },
340 { 721000000, 44000000, 166666, 0xbc, 0x08 },
341 { 841000000, 44000000, 166666, 0xf4, 0x08 },
342 { 999999999, 44000000, 166666, 0xfc, 0x02 },
343 }
344};
345EXPORT_SYMBOL(dvb_pll_tbmv30111in);
346
295/* ----------------------------------------------------------- */ 347/* ----------------------------------------------------------- */
296/* code */ 348/* code */
297 349
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 205b2d1a8852..497d31dcf41e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x;
36extern struct dvb_pll_desc dvb_pll_fmd1216me; 36extern struct dvb_pll_desc dvb_pll_fmd1216me;
37extern struct dvb_pll_desc dvb_pll_tded4; 37extern struct dvb_pll_desc dvb_pll_tded4;
38 38
39extern struct dvb_pll_desc dvb_pll_tuv1236d;
40extern struct dvb_pll_desc dvb_pll_tdhu2;
41extern struct dvb_pll_desc dvb_pll_tbmv30111in;
42
39int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 43int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
40 u32 freq, int bandwidth); 44 u32 freq, int bandwidth);
41 45
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 7852b83b82d4..6a33f5a19a8d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -26,6 +26,8 @@
26 * DViCO FusionHDTV 3 Gold-Q 26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T 27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold 28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite
30 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
29 * 31 *
30 * TODO: 32 * TODO:
31 * signal strength always returns 0. 33 * signal strength always returns 0.
@@ -222,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe)
222 0x4c, 0x14 224 0x4c, 0x14
223 }; 225 };
224 226
227 static u8 flip_lgdt3303_init_data[] = {
228 0x4c, 0x14,
229 0x87, 0xf3
230 };
231
225 struct lgdt330x_state* state = fe->demodulator_priv; 232 struct lgdt330x_state* state = fe->demodulator_priv;
226 char *chip_name; 233 char *chip_name;
227 int err; 234 int err;
@@ -234,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe)
234 break; 241 break;
235 case LGDT3303: 242 case LGDT3303:
236 chip_name = "LGDT3303"; 243 chip_name = "LGDT3303";
237 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 244 if (state->config->clock_polarity_flip) {
238 sizeof(lgdt3303_init_data)); 245 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
246 sizeof(flip_lgdt3303_init_data));
247 } else {
248 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
249 sizeof(lgdt3303_init_data));
250 }
239 break; 251 break;
240 default: 252 default:
241 chip_name = "undefined"; 253 chip_name = "undefined";
@@ -743,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
743 .frequency_min= 54000000, 755 .frequency_min= 54000000,
744 .frequency_max= 858000000, 756 .frequency_max= 858000000,
745 .frequency_stepsize= 62500, 757 .frequency_stepsize= 62500,
746 /* Symbol rate is for all VSB modes need to check QAM */ 758 .symbol_rate_min = 5056941, /* QAM 64 */
747 .symbol_rate_min = 10762000, 759 .symbol_rate_max = 10762000, /* VSB 8 */
748 .symbol_rate_max = 10762000,
749 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 760 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
750 }, 761 },
751 .init = lgdt330x_init, 762 .init = lgdt330x_init,
@@ -767,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
767 .frequency_min= 54000000, 778 .frequency_min= 54000000,
768 .frequency_max= 858000000, 779 .frequency_max= 858000000,
769 .frequency_stepsize= 62500, 780 .frequency_stepsize= 62500,
770 /* Symbol rate is for all VSB modes need to check QAM */ 781 .symbol_rate_min = 5056941, /* QAM 64 */
771 .symbol_rate_min = 10762000, 782 .symbol_rate_max = 10762000, /* VSB 8 */
772 .symbol_rate_max = 10762000,
773 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
774 }, 784 },
775 .init = lgdt330x_init, 785 .init = lgdt330x_init,
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index e209ba1e47c5..2a6529cccf1a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -47,6 +47,10 @@ struct lgdt330x_config
47 47
48 /* Need to set device param for start_dma */ 48 /* Need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50
51 /* Flip the polarity of the mpeg data transfer clock using alternate init data
52 * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
53 int clock_polarity_flip;
50}; 54};
51 55
52extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, 56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 000000000000..bad0933eb714
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1205 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24/*
25 * NOTES ABOUT THIS DRIVER
26 *
27 * This Linux driver supports:
28 * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
29 * AverTVHD MCE A180 (NXT2004)
30 * ATI HDTV Wonder (NXT2004)
31 *
32 * This driver needs external firmware. Please use the command
33 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
35 * download/extract the appropriate firmware, and then copy it to
36 * /usr/lib/hotplug/firmware/ or /lib/firmware/
37 * (depending on configuration of firmware hotplug).
38 */
39#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
40#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
41#define CRC_CCIT_MASK 0x1021
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/module.h>
46#include <linux/moduleparam.h>
47
48#include "dvb_frontend.h"
49#include "dvb-pll.h"
50#include "nxt200x.h"
51
52struct nxt200x_state {
53
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56 const struct nxt200x_config* config;
57 struct dvb_frontend frontend;
58
59 /* demodulator private data */
60 nxt_chip_type demod_chip;
61 u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66 do { \
67 if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68 } while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72 int err;
73 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77 __FUNCTION__, addr, err);
78 return -EREMOTEIO;
79 }
80 return 0;
81}
82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
84{
85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90 __FUNCTION__, addr, err);
91 return -EREMOTEIO;
92 }
93 return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
97{
98 u8 buf2 [len+1];
99 int err;
100 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
101
102 buf2[0] = reg;
103 memcpy(&buf2[1], buf, len);
104
105 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
106 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
107 __FUNCTION__, state->config->demod_address, err);
108 return -EREMOTEIO;
109 }
110 return 0;
111}
112
113static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
114{
115 u8 reg2 [] = { reg };
116
117 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
118 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
119
120 int err;
121
122 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
123 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
124 __FUNCTION__, state->config->demod_address, err);
125 return -EREMOTEIO;
126 }
127 return 0;
128}
129
130static u16 nxt200x_crc(u16 crc, u8 c)
131{
132 u8 i;
133 u16 input = (u16) c & 0xFF;
134
135 input<<=8;
136 for(i=0; i<8; i++) {
137 if((crc^input) & 0x8000)
138 crc=(crc<<1)^CRC_CCIT_MASK;
139 else
140 crc<<=1;
141 input<<=1;
142 }
143 return crc;
144}
145
146static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
147{
148 u8 attr, len2, buf;
149 dprintk("%s\n", __FUNCTION__);
150
151 /* set mutli register register */
152 nxt200x_writebytes(state, 0x35, &reg, 1);
153
154 /* send the actual data */
155 nxt200x_writebytes(state, 0x36, data, len);
156
157 switch (state->demod_chip) {
158 case NXT2002:
159 len2 = len;
160 buf = 0x02;
161 break;
162 case NXT2004:
163 /* probably not right, but gives correct values */
164 attr = 0x02;
165 if (reg & 0x80) {
166 attr = attr << 1;
167 if (reg & 0x04)
168 attr = attr >> 1;
169 }
170 /* set write bit */
171 len2 = ((attr << 4) | 0x10) | len;
172 buf = 0x80;
173 break;
174 default:
175 return -EINVAL;
176 break;
177 }
178
179 /* set multi register length */
180 nxt200x_writebytes(state, 0x34, &len2, 1);
181
182 /* toggle the multireg write bit */
183 nxt200x_writebytes(state, 0x21, &buf, 1);
184
185 nxt200x_readbytes(state, 0x21, &buf, 1);
186
187 switch (state->demod_chip) {
188 case NXT2002:
189 if ((buf & 0x02) == 0)
190 return 0;
191 break;
192 case NXT2004:
193 if (buf == 0)
194 return 0;
195 break;
196 default:
197 return -EINVAL;
198 break;
199 }
200
201 printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
202
203 return 0;
204}
205
206static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
207{
208 int i;
209 u8 buf, len2, attr;
210 dprintk("%s\n", __FUNCTION__);
211
212 /* set mutli register register */
213 nxt200x_writebytes(state, 0x35, &reg, 1);
214
215 switch (state->demod_chip) {
216 case NXT2002:
217 /* set multi register length */
218 len2 = len & 0x80;
219 nxt200x_writebytes(state, 0x34, &len2, 1);
220
221 /* read the actual data */
222 nxt200x_readbytes(state, reg, data, len);
223 return 0;
224 break;
225 case NXT2004:
226 /* probably not right, but gives correct values */
227 attr = 0x02;
228 if (reg & 0x80) {
229 attr = attr << 1;
230 if (reg & 0x04)
231 attr = attr >> 1;
232 }
233
234 /* set multi register length */
235 len2 = (attr << 4) | len;
236 nxt200x_writebytes(state, 0x34, &len2, 1);
237
238 /* toggle the multireg bit*/
239 buf = 0x80;
240 nxt200x_writebytes(state, 0x21, &buf, 1);
241
242 /* read the actual data */
243 for(i = 0; i < len; i++) {
244 nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
245 }
246 return 0;
247 break;
248 default:
249 return -EINVAL;
250 break;
251 }
252}
253
254static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
255{
256 u8 buf, stopval, counter = 0;
257 dprintk("%s\n", __FUNCTION__);
258
259 /* set correct stop value */
260 switch (state->demod_chip) {
261 case NXT2002:
262 stopval = 0x40;
263 break;
264 case NXT2004:
265 stopval = 0x10;
266 break;
267 default:
268 stopval = 0;
269 break;
270 }
271
272 buf = 0x80;
273 nxt200x_writebytes(state, 0x22, &buf, 1);
274
275 while (counter < 20) {
276 nxt200x_readbytes(state, 0x31, &buf, 1);
277 if (buf & stopval)
278 return;
279 msleep(10);
280 counter++;
281 }
282
283 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
284 return;
285}
286
287static void nxt200x_microcontroller_start (struct nxt200x_state* state)
288{
289 u8 buf;
290 dprintk("%s\n", __FUNCTION__);
291
292 buf = 0x00;
293 nxt200x_writebytes(state, 0x22, &buf, 1);
294}
295
296static void nxt2004_microcontroller_init (struct nxt200x_state* state)
297{
298 u8 buf[9];
299 u8 counter = 0;
300 dprintk("%s\n", __FUNCTION__);
301
302 buf[0] = 0x00;
303 nxt200x_writebytes(state, 0x2b, buf, 1);
304 buf[0] = 0x70;
305 nxt200x_writebytes(state, 0x34, buf, 1);
306 buf[0] = 0x04;
307 nxt200x_writebytes(state, 0x35, buf, 1);
308 buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
309 buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
310 nxt200x_writebytes(state, 0x36, buf, 9);
311 buf[0] = 0x80;
312 nxt200x_writebytes(state, 0x21, buf, 1);
313
314 while (counter < 20) {
315 nxt200x_readbytes(state, 0x21, buf, 1);
316 if (buf[0] == 0)
317 return;
318 msleep(10);
319 counter++;
320 }
321
322 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
323
324 return;
325}
326
327static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
328{
329 u8 buf, count = 0;
330
331 dprintk("%s\n", __FUNCTION__);
332
333 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
334
335 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
336 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
337 switch (state->demod_chip) {
338 case NXT2004:
339 if (i2c_writebytes(state, state->config->pll_address, data, 4))
340 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
341 /* wait until we have a lock */
342 while (count < 20) {
343 i2c_readbytes(state, state->config->pll_address, &buf, 1);
344 if (buf & 0x40)
345 return 0;
346 msleep(100);
347 count++;
348 }
349 printk("nxt2004: timeout waiting for tuner lock\n");
350 break;
351 case NXT2002:
352 /* set the i2c transfer speed to the tuner */
353 buf = 0x03;
354 nxt200x_writebytes(state, 0x20, &buf, 1);
355
356 /* setup to transfer 4 bytes via i2c */
357 buf = 0x04;
358 nxt200x_writebytes(state, 0x34, &buf, 1);
359
360 /* write actual tuner bytes */
361 nxt200x_writebytes(state, 0x36, data, 4);
362
363 /* set tuner i2c address */
364 buf = state->config->pll_address;
365 nxt200x_writebytes(state, 0x35, &buf, 1);
366
367 /* write UC Opmode to begin transfer */
368 buf = 0x80;
369 nxt200x_writebytes(state, 0x21, &buf, 1);
370
371 while (count < 20) {
372 nxt200x_readbytes(state, 0x21, &buf, 1);
373 if ((buf & 0x80)== 0x00)
374 return 0;
375 msleep(100);
376 count++;
377 }
378 printk("nxt2002: timeout error writing tuner\n");
379 break;
380 default:
381 return -EINVAL;
382 break;
383 }
384 return 0;
385}
386
387static void nxt200x_agc_reset(struct nxt200x_state* state)
388{
389 u8 buf;
390 dprintk("%s\n", __FUNCTION__);
391
392 switch (state->demod_chip) {
393 case NXT2002:
394 buf = 0x08;
395 nxt200x_writebytes(state, 0x08, &buf, 1);
396 buf = 0x00;
397 nxt200x_writebytes(state, 0x08, &buf, 1);
398 break;
399 case NXT2004:
400 nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
401 buf = 0x08;
402 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
403 buf = 0x00;
404 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
405 break;
406 default:
407 break;
408 }
409 return;
410}
411
412static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
413{
414
415 struct nxt200x_state* state = fe->demodulator_priv;
416 u8 buf[3], written = 0, chunkpos = 0;
417 u16 rambase, position, crc = 0;
418
419 dprintk("%s\n", __FUNCTION__);
420 dprintk("Firmware is %zu bytes\n", fw->size);
421
422 /* Get the RAM base for this nxt2002 */
423 nxt200x_readbytes(state, 0x10, buf, 1);
424
425 if (buf[0] & 0x10)
426 rambase = 0x1000;
427 else
428 rambase = 0x0000;
429
430 dprintk("rambase on this nxt2002 is %04X\n", rambase);
431
432 /* Hold the micro in reset while loading firmware */
433 buf[0] = 0x80;
434 nxt200x_writebytes(state, 0x2B, buf, 1);
435
436 for (position = 0; position < fw->size; position++) {
437 if (written == 0) {
438 crc = 0;
439 chunkpos = 0x28;
440 buf[0] = ((rambase + position) >> 8);
441 buf[1] = (rambase + position) & 0xFF;
442 buf[2] = 0x81;
443 /* write starting address */
444 nxt200x_writebytes(state, 0x29, buf, 3);
445 }
446 written++;
447 chunkpos++;
448
449 if ((written % 4) == 0)
450 nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
451
452 crc = nxt200x_crc(crc, fw->data[position]);
453
454 if ((written == 255) || (position+1 == fw->size)) {
455 /* write remaining bytes of firmware */
456 nxt200x_writebytes(state, chunkpos+4-(written %4),
457 &fw->data[position-(written %4) + 1],
458 written %4);
459 buf[0] = crc << 8;
460 buf[1] = crc & 0xFF;
461
462 /* write crc */
463 nxt200x_writebytes(state, 0x2C, buf, 2);
464
465 /* do a read to stop things */
466 nxt200x_readbytes(state, 0x2A, buf, 1);
467
468 /* set transfer mode to complete */
469 buf[0] = 0x80;
470 nxt200x_writebytes(state, 0x2B, buf, 1);
471
472 written = 0;
473 }
474 }
475
476 return 0;
477};
478
479static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
480{
481
482 struct nxt200x_state* state = fe->demodulator_priv;
483 u8 buf[3];
484 u16 rambase, position, crc=0;
485
486 dprintk("%s\n", __FUNCTION__);
487 dprintk("Firmware is %zu bytes\n", fw->size);
488
489 /* set rambase */
490 rambase = 0x1000;
491
492 /* hold the micro in reset while loading firmware */
493 buf[0] = 0x80;
494 nxt200x_writebytes(state, 0x2B, buf,1);
495
496 /* calculate firmware CRC */
497 for (position = 0; position < fw->size; position++) {
498 crc = nxt200x_crc(crc, fw->data[position]);
499 }
500
501 buf[0] = rambase >> 8;
502 buf[1] = rambase & 0xFF;
503 buf[2] = 0x81;
504 /* write starting address */
505 nxt200x_writebytes(state,0x29,buf,3);
506
507 for (position = 0; position < fw->size;) {
508 nxt200x_writebytes(state, 0x2C, &fw->data[position],
509 fw->size-position > 255 ? 255 : fw->size-position);
510 position += (fw->size-position > 255 ? 255 : fw->size-position);
511 }
512 buf[0] = crc >> 8;
513 buf[1] = crc & 0xFF;
514
515 dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
516
517 /* write crc */
518 nxt200x_writebytes(state, 0x2C, buf,2);
519
520 /* do a read to stop things */
521 nxt200x_readbytes(state, 0x2C, buf, 1);
522
523 /* set transfer mode to complete */
524 buf[0] = 0x80;
525 nxt200x_writebytes(state, 0x2B, buf,1);
526
527 return 0;
528};
529
530static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
531 struct dvb_frontend_parameters *p)
532{
533 struct nxt200x_state* state = fe->demodulator_priv;
534 u8 buf[4];
535
536 /* stop the micro first */
537 nxt200x_microcontroller_stop(state);
538
539 if (state->demod_chip == NXT2004) {
540 /* make sure demod is set to digital */
541 buf[0] = 0x04;
542 nxt200x_writebytes(state, 0x14, buf, 1);
543 buf[0] = 0x00;
544 nxt200x_writebytes(state, 0x17, buf, 1);
545 }
546
547 /* get tuning information */
548 dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0);
549
550 /* set additional params */
551 switch (p->u.vsb.modulation) {
552 case QAM_64:
553 case QAM_256:
554 /* Set punctured clock for QAM */
555 /* This is just a guess since I am unable to test it */
556 if (state->config->set_ts_params)
557 state->config->set_ts_params(fe, 1);
558
559 /* set input */
560 if (state->config->set_pll_input)
561 state->config->set_pll_input(buf, 1);
562 break;
563 case VSB_8:
564 /* Set non-punctured clock for VSB */
565 if (state->config->set_ts_params)
566 state->config->set_ts_params(fe, 0);
567
568 /* set input */
569 if (state->config->set_pll_input)
570 state->config->set_pll_input(buf, 0);
571 break;
572 default:
573 return -EINVAL;
574 break;
575 }
576
577 /* write frequency information */
578 nxt200x_writetuner(state, buf);
579
580 /* reset the agc now that tuning has been completed */
581 nxt200x_agc_reset(state);
582
583 /* set target power level */
584 switch (p->u.vsb.modulation) {
585 case QAM_64:
586 case QAM_256:
587 buf[0] = 0x74;
588 break;
589 case VSB_8:
590 buf[0] = 0x70;
591 break;
592 default:
593 return -EINVAL;
594 break;
595 }
596 nxt200x_writebytes(state, 0x42, buf, 1);
597
598 /* configure sdm */
599 switch (state->demod_chip) {
600 case NXT2002:
601 buf[0] = 0x87;
602 break;
603 case NXT2004:
604 buf[0] = 0x07;
605 break;
606 default:
607 return -EINVAL;
608 break;
609 }
610 nxt200x_writebytes(state, 0x57, buf, 1);
611
612 /* write sdm1 input */
613 buf[0] = 0x10;
614 buf[1] = 0x00;
615 nxt200x_writebytes(state, 0x58, buf, 2);
616
617 /* write sdmx input */
618 switch (p->u.vsb.modulation) {
619 case QAM_64:
620 buf[0] = 0x68;
621 break;
622 case QAM_256:
623 buf[0] = 0x64;
624 break;
625 case VSB_8:
626 buf[0] = 0x60;
627 break;
628 default:
629 return -EINVAL;
630 break;
631 }
632 buf[1] = 0x00;
633 nxt200x_writebytes(state, 0x5C, buf, 2);
634
635 /* write adc power lpf fc */
636 buf[0] = 0x05;
637 nxt200x_writebytes(state, 0x43, buf, 1);
638
639 if (state->demod_chip == NXT2004) {
640 /* write ??? */
641 buf[0] = 0x00;
642 buf[1] = 0x00;
643 nxt200x_writebytes(state, 0x46, buf, 2);
644 }
645
646 /* write accumulator2 input */
647 buf[0] = 0x80;
648 buf[1] = 0x00;
649 nxt200x_writebytes(state, 0x4B, buf, 2);
650
651 /* write kg1 */
652 buf[0] = 0x00;
653 nxt200x_writebytes(state, 0x4D, buf, 1);
654
655 /* write sdm12 lpf fc */
656 buf[0] = 0x44;
657 nxt200x_writebytes(state, 0x55, buf, 1);
658
659 /* write agc control reg */
660 buf[0] = 0x04;
661 nxt200x_writebytes(state, 0x41, buf, 1);
662
663 if (state->demod_chip == NXT2004) {
664 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
665 buf[0] = 0x24;
666 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
667
668 /* soft reset? */
669 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
670 buf[0] = 0x10;
671 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
672 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
673 buf[0] = 0x00;
674 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
675
676 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
677 buf[0] = 0x04;
678 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
679 buf[0] = 0x00;
680 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
681 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
682 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
683 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
684 buf[0] = 0x11;
685 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
686 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
687 buf[0] = 0x44;
688 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
689 }
690
691 /* write agc ucgp0 */
692 switch (p->u.vsb.modulation) {
693 case QAM_64:
694 buf[0] = 0x02;
695 break;
696 case QAM_256:
697 buf[0] = 0x03;
698 break;
699 case VSB_8:
700 buf[0] = 0x00;
701 break;
702 default:
703 return -EINVAL;
704 break;
705 }
706 nxt200x_writebytes(state, 0x30, buf, 1);
707
708 /* write agc control reg */
709 buf[0] = 0x00;
710 nxt200x_writebytes(state, 0x41, buf, 1);
711
712 /* write accumulator2 input */
713 buf[0] = 0x80;
714 buf[1] = 0x00;
715 nxt200x_writebytes(state, 0x49, buf,2);
716 nxt200x_writebytes(state, 0x4B, buf,2);
717
718 /* write agc control reg */
719 buf[0] = 0x04;
720 nxt200x_writebytes(state, 0x41, buf, 1);
721
722 nxt200x_microcontroller_start(state);
723
724 if (state->demod_chip == NXT2004) {
725 nxt2004_microcontroller_init(state);
726
727 /* ???? */
728 buf[0] = 0xF0;
729 buf[1] = 0x00;
730 nxt200x_writebytes(state, 0x5C, buf, 2);
731 }
732
733 /* adjacent channel detection should be done here, but I don't
734 have any stations with this need so I cannot test it */
735
736 return 0;
737}
738
739static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
740{
741 struct nxt200x_state* state = fe->demodulator_priv;
742 u8 lock;
743 nxt200x_readbytes(state, 0x31, &lock, 1);
744
745 *status = 0;
746 if (lock & 0x20) {
747 *status |= FE_HAS_SIGNAL;
748 *status |= FE_HAS_CARRIER;
749 *status |= FE_HAS_VITERBI;
750 *status |= FE_HAS_SYNC;
751 *status |= FE_HAS_LOCK;
752 }
753 return 0;
754}
755
756static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
757{
758 struct nxt200x_state* state = fe->demodulator_priv;
759 u8 b[3];
760
761 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
762
763 *ber = ((b[0] << 8) + b[1]) * 8;
764
765 return 0;
766}
767
768static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
769{
770 struct nxt200x_state* state = fe->demodulator_priv;
771 u8 b[2];
772 u16 temp = 0;
773
774 /* setup to read cluster variance */
775 b[0] = 0x00;
776 nxt200x_writebytes(state, 0xA1, b, 1);
777
778 /* get multreg val */
779 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
780
781 temp = (b[0] << 8) | b[1];
782 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
783
784 return 0;
785}
786
787static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
788{
789
790 struct nxt200x_state* state = fe->demodulator_priv;
791 u8 b[2];
792 u16 temp = 0, temp2;
793 u32 snrdb = 0;
794
795 /* setup to read cluster variance */
796 b[0] = 0x00;
797 nxt200x_writebytes(state, 0xA1, b, 1);
798
799 /* get multreg val from 0xA6 */
800 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
801
802 temp = (b[0] << 8) | b[1];
803 temp2 = 0x7FFF - temp;
804
805 /* snr will be in db */
806 if (temp2 > 0x7F00)
807 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
808 else if (temp2 > 0x7EC0)
809 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
810 else if (temp2 > 0x7C00)
811 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
812 else
813 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
814
815 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
816 *snr = snrdb * (0xFFFF/32000);
817
818 return 0;
819}
820
821static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
822{
823 struct nxt200x_state* state = fe->demodulator_priv;
824 u8 b[3];
825
826 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
827 *ucblocks = b[2];
828
829 return 0;
830}
831
832static int nxt200x_sleep(struct dvb_frontend* fe)
833{
834 return 0;
835}
836
837static int nxt2002_init(struct dvb_frontend* fe)
838{
839 struct nxt200x_state* state = fe->demodulator_priv;
840 const struct firmware *fw;
841 int ret;
842 u8 buf[2];
843
844 /* request the firmware, this will block until someone uploads it */
845 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
846 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
847 printk("nxt2002: Waiting for firmware upload(2)...\n");
848 if (ret) {
849 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
850 return ret;
851 }
852
853 ret = nxt2002_load_firmware(fe, fw);
854 if (ret) {
855 printk("nxt2002: Writing firmware to device failed\n");
856 release_firmware(fw);
857 return ret;
858 }
859 printk("nxt2002: Firmware upload complete\n");
860
861 /* Put the micro into reset */
862 nxt200x_microcontroller_stop(state);
863
864 /* ensure transfer is complete */
865 buf[0]=0x00;
866 nxt200x_writebytes(state, 0x2B, buf, 1);
867
868 /* Put the micro into reset for real this time */
869 nxt200x_microcontroller_stop(state);
870
871 /* soft reset everything (agc,frontend,eq,fec)*/
872 buf[0] = 0x0F;
873 nxt200x_writebytes(state, 0x08, buf, 1);
874 buf[0] = 0x00;
875 nxt200x_writebytes(state, 0x08, buf, 1);
876
877 /* write agc sdm configure */
878 buf[0] = 0xF1;
879 nxt200x_writebytes(state, 0x57, buf, 1);
880
881 /* write mod output format */
882 buf[0] = 0x20;
883 nxt200x_writebytes(state, 0x09, buf, 1);
884
885 /* write fec mpeg mode */
886 buf[0] = 0x7E;
887 buf[1] = 0x00;
888 nxt200x_writebytes(state, 0xE9, buf, 2);
889
890 /* write mux selection */
891 buf[0] = 0x00;
892 nxt200x_writebytes(state, 0xCC, buf, 1);
893
894 return 0;
895}
896
897static int nxt2004_init(struct dvb_frontend* fe)
898{
899 struct nxt200x_state* state = fe->demodulator_priv;
900 const struct firmware *fw;
901 int ret;
902 u8 buf[3];
903
904 /* ??? */
905 buf[0]=0x00;
906 nxt200x_writebytes(state, 0x1E, buf, 1);
907
908 /* request the firmware, this will block until someone uploads it */
909 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
910 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
911 printk("nxt2004: Waiting for firmware upload(2)...\n");
912 if (ret) {
913 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
914 return ret;
915 }
916
917 ret = nxt2004_load_firmware(fe, fw);
918 if (ret) {
919 printk("nxt2004: Writing firmware to device failed\n");
920 release_firmware(fw);
921 return ret;
922 }
923 printk("nxt2004: Firmware upload complete\n");
924
925 /* ensure transfer is complete */
926 buf[0] = 0x01;
927 nxt200x_writebytes(state, 0x19, buf, 1);
928
929 nxt2004_microcontroller_init(state);
930 nxt200x_microcontroller_stop(state);
931 nxt200x_microcontroller_stop(state);
932 nxt2004_microcontroller_init(state);
933 nxt200x_microcontroller_stop(state);
934
935 /* soft reset everything (agc,frontend,eq,fec)*/
936 buf[0] = 0xFF;
937 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
938 buf[0] = 0x00;
939 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
940
941 /* write agc sdm configure */
942 buf[0] = 0xD7;
943 nxt200x_writebytes(state, 0x57, buf, 1);
944
945 /* ???*/
946 buf[0] = 0x07;
947 buf[1] = 0xfe;
948 nxt200x_writebytes(state, 0x35, buf, 2);
949 buf[0] = 0x12;
950 nxt200x_writebytes(state, 0x34, buf, 1);
951 buf[0] = 0x80;
952 nxt200x_writebytes(state, 0x21, buf, 1);
953
954 /* ???*/
955 buf[0] = 0x21;
956 nxt200x_writebytes(state, 0x0A, buf, 1);
957
958 /* ???*/
959 buf[0] = 0x01;
960 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
961
962 /* write fec mpeg mode */
963 buf[0] = 0x7E;
964 buf[1] = 0x00;
965 nxt200x_writebytes(state, 0xE9, buf, 2);
966
967 /* write mux selection */
968 buf[0] = 0x00;
969 nxt200x_writebytes(state, 0xCC, buf, 1);
970
971 /* ???*/
972 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
973 buf[0] = 0x00;
974 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
975
976 /* soft reset? */
977 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
978 buf[0] = 0x10;
979 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
980 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
981 buf[0] = 0x00;
982 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
983
984 /* ???*/
985 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
986 buf[0] = 0x01;
987 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
988 buf[0] = 0x70;
989 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
990 buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
991 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
992
993 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
994 buf[0] = 0x11;
995 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
996 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
997 buf[0] = 0x40;
998 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000 nxt200x_readbytes(state, 0x10, buf, 1);
1001 buf[0] = 0x10;
1002 nxt200x_writebytes(state, 0x10, buf, 1);
1003 nxt200x_readbytes(state, 0x0A, buf, 1);
1004 buf[0] = 0x21;
1005 nxt200x_writebytes(state, 0x0A, buf, 1);
1006
1007 nxt2004_microcontroller_init(state);
1008
1009 buf[0] = 0x21;
1010 nxt200x_writebytes(state, 0x0A, buf, 1);
1011 buf[0] = 0x7E;
1012 nxt200x_writebytes(state, 0xE9, buf, 1);
1013 buf[0] = 0x00;
1014 nxt200x_writebytes(state, 0xEA, buf, 1);
1015
1016 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1017 buf[0] = 0x00;
1018 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1019 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1020 buf[0] = 0x00;
1021 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1022
1023 /* soft reset? */
1024 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1025 buf[0] = 0x10;
1026 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1027 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1028 buf[0] = 0x00;
1029 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1030
1031 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1032 buf[0] = 0x04;
1033 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1034 buf[0] = 0x00;
1035 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1036 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1037 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1038
1039 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1040 buf[0] = 0x11;
1041 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1042
1043 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1044 buf[0] = 0x44;
1045 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1046
1047 /* initialize tuner */
1048 nxt200x_readbytes(state, 0x10, buf, 1);
1049 buf[0] = 0x12;
1050 nxt200x_writebytes(state, 0x10, buf, 1);
1051 buf[0] = 0x04;
1052 nxt200x_writebytes(state, 0x13, buf, 1);
1053 buf[0] = 0x00;
1054 nxt200x_writebytes(state, 0x16, buf, 1);
1055 buf[0] = 0x04;
1056 nxt200x_writebytes(state, 0x14, buf, 1);
1057 buf[0] = 0x00;
1058 nxt200x_writebytes(state, 0x14, buf, 1);
1059 nxt200x_writebytes(state, 0x17, buf, 1);
1060 nxt200x_writebytes(state, 0x14, buf, 1);
1061 nxt200x_writebytes(state, 0x17, buf, 1);
1062
1063 return 0;
1064}
1065
1066static int nxt200x_init(struct dvb_frontend* fe)
1067{
1068 struct nxt200x_state* state = fe->demodulator_priv;
1069 int ret = 0;
1070
1071 if (!state->initialised) {
1072 switch (state->demod_chip) {
1073 case NXT2002:
1074 ret = nxt2002_init(fe);
1075 break;
1076 case NXT2004:
1077 ret = nxt2004_init(fe);
1078 break;
1079 default:
1080 return -EINVAL;
1081 break;
1082 }
1083 state->initialised = 1;
1084 }
1085 return ret;
1086}
1087
1088static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1089{
1090 fesettings->min_delay_ms = 500;
1091 fesettings->step_size = 0;
1092 fesettings->max_drift = 0;
1093 return 0;
1094}
1095
1096static void nxt200x_release(struct dvb_frontend* fe)
1097{
1098 struct nxt200x_state* state = fe->demodulator_priv;
1099 kfree(state);
1100}
1101
1102static struct dvb_frontend_ops nxt200x_ops;
1103
1104struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1105 struct i2c_adapter* i2c)
1106{
1107 struct nxt200x_state* state = NULL;
1108 u8 buf [] = {0,0,0,0,0};
1109
1110 /* allocate memory for the internal state */
1111 state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1112 if (state == NULL)
1113 goto error;
1114 memset(state,0,sizeof(*state));
1115
1116 /* setup the state */
1117 state->config = config;
1118 state->i2c = i2c;
1119 memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1120 state->initialised = 0;
1121
1122 /* read card id */
1123 nxt200x_readbytes(state, 0x00, buf, 5);
1124 dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1125 buf[0], buf[1], buf[2], buf[3], buf[4]);
1126
1127 /* set demod chip */
1128 switch (buf[0]) {
1129 case 0x04:
1130 state->demod_chip = NXT2002;
1131 printk("nxt200x: NXT2002 Detected\n");
1132 break;
1133 case 0x05:
1134 state->demod_chip = NXT2004;
1135 printk("nxt200x: NXT2004 Detected\n");
1136 break;
1137 default:
1138 goto error;
1139 }
1140
1141 /* make sure demod chip is supported */
1142 switch (state->demod_chip) {
1143 case NXT2002:
1144 if (buf[0] != 0x04) goto error; /* device id */
1145 if (buf[1] != 0x02) goto error; /* fab id */
1146 if (buf[2] != 0x11) goto error; /* month */
1147 if (buf[3] != 0x20) goto error; /* year msb */
1148 if (buf[4] != 0x00) goto error; /* year lsb */
1149 break;
1150 case NXT2004:
1151 if (buf[0] != 0x05) goto error; /* device id */
1152 break;
1153 default:
1154 goto error;
1155 }
1156
1157 /* create dvb_frontend */
1158 state->frontend.ops = &state->ops;
1159 state->frontend.demodulator_priv = state;
1160 return &state->frontend;
1161
1162error:
1163 kfree(state);
1164 printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1165 buf[0], buf[1], buf[2], buf[3], buf[4]);
1166 return NULL;
1167}
1168
1169static struct dvb_frontend_ops nxt200x_ops = {
1170
1171 .info = {
1172 .name = "Nextwave NXT200X VSB/QAM frontend",
1173 .type = FE_ATSC,
1174 .frequency_min = 54000000,
1175 .frequency_max = 860000000,
1176 .frequency_stepsize = 166666, /* stepsize is just a guess */
1177 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1178 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1179 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1180 },
1181
1182 .release = nxt200x_release,
1183
1184 .init = nxt200x_init,
1185 .sleep = nxt200x_sleep,
1186
1187 .set_frontend = nxt200x_setup_frontend_parameters,
1188 .get_tune_settings = nxt200x_get_tune_settings,
1189
1190 .read_status = nxt200x_read_status,
1191 .read_ber = nxt200x_read_ber,
1192 .read_signal_strength = nxt200x_read_signal_strength,
1193 .read_snr = nxt200x_read_snr,
1194 .read_ucblocks = nxt200x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1201MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(nxt200x_attach);
1205
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 000000000000..1d9d70bc37ef
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,61 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24#ifndef NXT200X_H
25#define NXT200X_H
26
27#include <linux/dvb/frontend.h>
28#include <linux/firmware.h>
29
30typedef enum nxt_chip_t {
31 NXTUNDEFINED,
32 NXT2002,
33 NXT2004
34}nxt_chip_type;
35
36struct nxt200x_config
37{
38 /* the demodulator's i2c address */
39 u8 demod_address;
40
41 /* tuner information */
42 u8 pll_address;
43 struct dvb_pll_desc *pll_desc;
44
45 /* used to set pll input */
46 int (*set_pll_input)(u8* buf, int input);
47
48 /* need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50};
51
52extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
53 struct i2c_adapter* i2c);
54
55#endif /* NXT200X_H */
56
57/*
58 * Local variables:
59 * c-basic-offset: 8
60 * End:
61 */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index fc74c40d6477..78bded861d02 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -468,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
468 unsigned char snd_buf[2]; 468 unsigned char snd_buf[2];
469 u8 rcvr_stat; 469 u8 rcvr_stat;
470 u16 snr_equ; 470 u16 snr_equ;
471 u32 signal_strength;
471 int usK; 472 int usK;
472 473
473 snd_buf[0]=0x04; 474 snd_buf[0]=0x04;
@@ -503,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
503 usK = (rcvr_stat & 0x10) ? 3 : 0; 504 usK = (rcvr_stat & 0x10) ? 3 : 0;
504 505
505 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
506 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; 507 signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 if (signal_strength > 0xffff)
509 *strength = 0xffff;
510 else
511 *strength = signal_strength;
507 dprintk("read_signal_strength %i\n",*strength); 512 dprintk("read_signal_strength %i\n",*strength);
508 513
509 return 0; 514 return 0;
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 8a9db23dd1b7..531f76246e5f 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -339,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
339 u8 rec_buf[2]; 339 u8 rec_buf[2];
340 u8 snd_buf[4]; 340 u8 snd_buf[4];
341 u8 snr_equ; 341 u8 snr_equ;
342 u32 signal_strength;
342 343
343 /* SNR after Equalizer */ 344 /* SNR after Equalizer */
344 snd_buf[0] = 0x04; 345 snd_buf[0] = 0x04;
@@ -358,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
358 snr_equ = rec_buf[0] & 0xff; 359 snr_equ = rec_buf[0] & 0xff;
359 360
360 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 361 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
361 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; 362 signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
362 363 if (signal_strength > 0xffff)
364 *strength = 0xffff;
365 else
366 *strength = signal_strength;
363 dprintk("read_signal_strength %i\n",*strength); 367 dprintk("read_signal_strength %i\n",*strength);
364 368
365 return 0; 369 return 0;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 889d9257215d..29c48665e130 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -64,8 +64,12 @@ struct stv0299_state {
64 u32 tuner_frequency; 64 u32 tuner_frequency;
65 u32 symbol_rate; 65 u32 symbol_rate;
66 fe_code_rate_t fec_inner; 66 fe_code_rate_t fec_inner;
67 int errmode;
67}; 68};
68 69
70#define STATUS_BER 0
71#define STATUS_UCBLOCKS 1
72
69static int debug; 73static int debug;
70static int debug_legacy_dish_switch; 74static int debug_legacy_dish_switch;
71#define dprintk(args...) \ 75#define dprintk(args...) \
@@ -383,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
383 }; 387 };
384} 388}
385 389
386static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
387{
388 return ((curtime.tv_usec < lasttime.tv_usec) ?
389 1000000 - lasttime.tv_usec + curtime.tv_usec :
390 curtime.tv_usec - lasttime.tv_usec);
391}
392
393static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
394{
395 struct timeval lasttime;
396 s32 delta, newdelta;
397
398 waketime->tv_usec += add_usec;
399 if (waketime->tv_usec >= 1000000) {
400 waketime->tv_usec -= 1000000;
401 waketime->tv_sec++;
402 }
403
404 do_gettimeofday (&lasttime);
405 delta = stv0299_calc_usec_delay (lasttime, *waketime);
406 if (delta > 2500) {
407 msleep ((delta - 1500) / 1000);
408 do_gettimeofday (&lasttime);
409 newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
410 delta = (newdelta > delta) ? 0 : newdelta;
411 }
412 if (delta > 0)
413 udelay (delta);
414}
415
416static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) 390static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
417{ 391{
418 struct stv0299_state* state = fe->demodulator_priv; 392 struct stv0299_state* state = fe->demodulator_priv;
@@ -440,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
440 memcpy (&tv[0], &nexttime, sizeof (struct timeval)); 414 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
441 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ 415 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
442 416
443 stv0299_sleep_until (&nexttime, 32000); 417 dvb_frontend_sleep_until(&nexttime, 32000);
444 418
445 for (i=0; i<9; i++) { 419 for (i=0; i<9; i++) {
446 if (debug_legacy_dish_switch) 420 if (debug_legacy_dish_switch)
@@ -454,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
454 cmd = cmd >> 1; 428 cmd = cmd >> 1;
455 429
456 if (i != 8) 430 if (i != 8)
457 stv0299_sleep_until (&nexttime, 8000); 431 dvb_frontend_sleep_until(&nexttime, 8000);
458 } 432 }
459 if (debug_legacy_dish_switch) { 433 if (debug_legacy_dish_switch) {
460 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", 434 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
461 __FUNCTION__, fe->dvb->num); 435 __FUNCTION__, fe->dvb->num);
462 for (i=1; i < 10; i++) 436 for (i = 1; i < 10; i++)
463 printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); 437 printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
464 } 438 }
465 439
466 return 0; 440 return 0;
@@ -517,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
517{ 491{
518 struct stv0299_state* state = fe->demodulator_priv; 492 struct stv0299_state* state = fe->demodulator_priv;
519 493
520 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10); 494 if (state->errmode != STATUS_BER) return 0;
521 msleep(100);
522 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 495 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
523 496
524 return 0; 497 return 0;
@@ -557,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
557{ 530{
558 struct stv0299_state* state = fe->demodulator_priv; 531 struct stv0299_state* state = fe->demodulator_priv;
559 532
560 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30); 533 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
561 msleep(100); 534 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
562 *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
563 535
564 return 0; 536 return 0;
565} 537}
@@ -581,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
581 if (state->config->invert) invval = (~invval) & 1; 553 if (state->config->invert) invval = (~invval) & 1;
582 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); 554 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
583 555
584 if (state->config->enhanced_tuning) { 556 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
585 /* check if we should do a finetune */ 557 state->config->pll_set(fe, state->i2c, p);
586 int frequency_delta = p->frequency - state->tuner_frequency; 558 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
587 int minmax = p->u.qpsk.symbol_rate / 2000;
588 if (minmax < 5000) minmax = 5000;
589
590 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
591 (state->fec_inner == p->u.qpsk.fec_inner) &&
592 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
593 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
594
595 // zap the derotator registers first
596 stv0299_writeregI(state, 0x22, 0x00);
597 stv0299_writeregI(state, 0x23, 0x00);
598
599 // now set them as we want
600 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
601 stv0299_writeregI(state, 0x23, Drot_freq);
602 } else {
603 /* A "normal" tune is requested */
604 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
605 state->config->pll_set(fe, state->i2c, p);
606 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
607
608 stv0299_writeregI(state, 0x32, 0x80);
609 stv0299_writeregI(state, 0x22, 0x00);
610 stv0299_writeregI(state, 0x23, 0x00);
611 stv0299_writeregI(state, 0x32, 0x19);
612 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
613 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
614 }
615 } else {
616 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
617 state->config->pll_set(fe, state->i2c, p);
618 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
619 559
620 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 560 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
621 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); 561 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
622 stv0299_writeregI(state, 0x22, 0x00); 562 stv0299_writeregI(state, 0x22, 0x00);
623 stv0299_writeregI(state, 0x23, 0x00); 563 stv0299_writeregI(state, 0x23, 0x00);
624 stv0299_readreg (state, 0x23);
625 stv0299_writeregI(state, 0x12, 0xb9);
626 }
627 564
628 state->tuner_frequency = p->frequency; 565 state->tuner_frequency = p->frequency;
629 state->fec_inner = p->u.qpsk.fec_inner; 566 state->fec_inner = p->u.qpsk.fec_inner;
@@ -708,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
708 state->tuner_frequency = 0; 645 state->tuner_frequency = 0;
709 state->symbol_rate = 0; 646 state->symbol_rate = 0;
710 state->fec_inner = 0; 647 state->fec_inner = 0;
648 state->errmode = STATUS_BER;
711 649
712 /* check if the demod is there */ 650 /* check if the demod is there */
713 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 651 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index d0c4484861e1..9af3d71c89db 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -73,9 +73,6 @@ struct stv0299_config
73 /* does the inversion require inversion? */ 73 /* does the inversion require inversion? */
74 u8 invert:1; 74 u8 invert:1;
75 75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */ 76 /* Skip reinitialisation? */
80 u8 skip_reinit:1; 77 u8 skip_reinit:1;
81 78
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 3529c618f828..7968743826fc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -420,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
420 struct tda1004x_state* state = fe->demodulator_priv; 420 struct tda1004x_state* state = fe->demodulator_priv;
421 421
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); 422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { 424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); 425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -597,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe)
597 // Init the tuner PLL 597 // Init the tuner PLL
598 if (state->config->pll_init) { 598 if (state->config->pll_init) {
599 tda1004x_enable_tuner_i2c(state); 599 tda1004x_enable_tuner_i2c(state);
600 state->config->pll_init(fe); 600 if (state->config->pll_init(fe)) {
601 printk(KERN_ERR "tda1004x: pll init failed\n");
602 return -EIO;
603 }
601 tda1004x_disable_tuner_i2c(state); 604 tda1004x_disable_tuner_i2c(state);
602 } 605 }
603 606
@@ -667,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
667 670
668 // set frequency 671 // set frequency
669 tda1004x_enable_tuner_i2c(state); 672 tda1004x_enable_tuner_i2c(state);
670 state->config->pll_set(fe, fe_params); 673 if (state->config->pll_set(fe, fe_params)) {
674 printk(KERN_ERR "tda1004x: pll set failed\n");
675 return -EIO;
676 }
671 tda1004x_disable_tuner_i2c(state); 677 tda1004x_disable_tuner_i2c(state);
672 678
673 // Hardcoded to use auto as much as possible on the TDA10045 as it 679 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -832,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
832 838
833 case TDA1004X_DEMOD_TDA10046: 839 case TDA1004X_DEMOD_TDA10046:
834 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); 840 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
841 msleep(1);
842 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
835 break; 843 break;
836 } 844 }
837 845
@@ -1129,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1129 if (state->config->pll_sleep != NULL) { 1137 if (state->config->pll_sleep != NULL) {
1130 tda1004x_enable_tuner_i2c(state); 1138 tda1004x_enable_tuner_i2c(state);
1131 state->config->pll_sleep(fe); 1139 state->config->pll_sleep(fe);
1132 tda1004x_disable_tuner_i2c(state); 1140 if (state->config->if_freq != TDA10046_FREQ_052) {
1141 /* special hack for Philips EUROPA Based boards:
1142 * keep the I2c bridge open for tuner access in analog mode
1143 */
1144 tda1004x_disable_tuner_i2c(state);
1145 }
1133 } 1146 }
1134 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1147 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1135 break; 1148 break;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 85b437bbddcd..bbebd1c4caca 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
286 * although one packet has been transfered. 286 * although one packet has been transfered.
287 */ 287 */
288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { 288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
289 unsigned int i = 0, valid; 289 unsigned int i = 0;
290 while (pluto->dma_buf[i] == 0x47) 290 while (pluto->dma_buf[i] == 0x47)
291 i += 188; 291 i += 188;
292 valid = i / 188; 292 nbpackets = i / 188;
293 if (nbpackets != valid) {
294 dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
295 nbpackets, valid);
296 nbpackets = valid;
297 }
298 } 293 }
299 294
300 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); 295 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 22b203f8ff27..87ea52757a21 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = {
1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1567 0x10, 0x3f, // AGC2 0x3d 1567 0x10, 0x3f, // AGC2 0x3d
1568 0x11, 0x84, 1568 0x11, 0x84,
1569 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1569 0x12, 0xb9,
1570 0x15, 0xc9, // lock detector threshold 1570 0x15, 0xc9, // lock detector threshold
1571 0x16, 0x00, 1571 0x16, 0x00,
1572 0x17, 0x00, 1572 0x17, 0x00,
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = {
1644 .inittab = alps_bsru6_inittab, 1644 .inittab = alps_bsru6_inittab,
1645 .mclk = 88000000UL, 1645 .mclk = 88000000UL,
1646 .invert = 1, 1646 .invert = 1,
1647 .enhanced_tuning = 0,
1648 .skip_reinit = 0, 1647 .skip_reinit = 0,
1649 .lock_output = STV0229_LOCKOUTPUT_1, 1648 .lock_output = STV0229_LOCKOUTPUT_1,
1650 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1649 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = {
1669 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1668 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1670 0x10, 0x3f, // AGC2 0x3d 1669 0x10, 0x3f, // AGC2 0x3d
1671 0x11, 0x84, 1670 0x11, 0x84,
1672 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1671 0x12, 0xb9,
1673 0x15, 0xc9, // lock detector threshold 1672 0x15, 0xc9, // lock detector threshold
1674 0x16, 0x00, 1673 0x16, 0x00,
1675 0x17, 0x00, 1674 0x17, 0x00,
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = {
1721 .inittab = alps_bsbe1_inittab, 1720 .inittab = alps_bsbe1_inittab,
1722 .mclk = 88000000UL, 1721 .mclk = 88000000UL,
1723 .invert = 1, 1722 .invert = 1,
1724 .enhanced_tuning = 0,
1725 .skip_reinit = 0, 1723 .skip_reinit = 0,
1726 .min_delay_ms = 100, 1724 .min_delay_ms = 100,
1727 .set_symbol_rate = alps_bsru6_set_symbol_rate, 1725 .set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 7692cd23f839..aa75dc03a0b3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
500 0x10, 0x3f, // AGC2 0x3d 500 0x10, 0x3f, // AGC2 0x3d
501 0x11, 0x84, 501 0x11, 0x84,
502 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 502 0x12, 0xb9,
503 0x15, 0xc9, // lock detector threshold 503 0x15, 0xc9, // lock detector threshold
504 0x16, 0x00, 504 0x16, 0x00,
505 0x17, 0x00, 505 0x17, 0x00,
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = {
531 .inittab = typhoon_cinergy1200s_inittab, 531 .inittab = typhoon_cinergy1200s_inittab,
532 .mclk = 88000000UL, 532 .mclk = 88000000UL,
533 .invert = 0, 533 .invert = 0,
534 .enhanced_tuning = 0,
535 .skip_reinit = 0, 534 .skip_reinit = 0,
536 .lock_output = STV0229_LOCKOUTPUT_1, 535 .lock_output = STV0229_LOCKOUTPUT_1,
537 .volt13_op0_op1 = STV0299_VOLT13_OP0, 536 .volt13_op0_op1 = STV0299_VOLT13_OP0,
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = {
546 .inittab = typhoon_cinergy1200s_inittab, 545 .inittab = typhoon_cinergy1200s_inittab,
547 .mclk = 88000000UL, 546 .mclk = 88000000UL,
548 .invert = 0, 547 .invert = 0,
549 .enhanced_tuning = 0,
550 .skip_reinit = 0, 548 .skip_reinit = 0,
551 .lock_output = STV0229_LOCKOUTPUT_0, 549 .lock_output = STV0229_LOCKOUTPUT_0,
552 .volt13_op0_op1 = STV0299_VOLT13_OP0, 550 .volt13_op0_op1 = STV0299_VOLT13_OP0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 51c30ba68140..75fb92d60998 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -490,7 +490,7 @@ static u8 alps_bsru6_inittab[] = {
490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
491 0x10, 0x3f, // AGC2 0x3d 491 0x10, 0x3f, // AGC2 0x3d
492 0x11, 0x84, 492 0x11, 0x84,
493 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 493 0x12, 0xb9,
494 0x15, 0xc9, // lock detector threshold 494 0x15, 0xc9, // lock detector threshold
495 0x16, 0x00, 495 0x16, 0x00,
496 0x17, 0x00, 496 0x17, 0x00,
@@ -580,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = {
580 .inittab = alps_bsru6_inittab, 580 .inittab = alps_bsru6_inittab,
581 .mclk = 88000000UL, 581 .mclk = 88000000UL,
582 .invert = 1, 582 .invert = 1,
583 .enhanced_tuning = 0,
584 .skip_reinit = 0, 583 .skip_reinit = 0,
585 .lock_output = STV0229_LOCKOUTPUT_1, 584 .lock_output = STV0229_LOCKOUTPUT_1,
586 .volt13_op0_op1 = STV0299_VOLT13_OP1, 585 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -710,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = {
710 .inittab = philips_su1278_tt_inittab, 709 .inittab = philips_su1278_tt_inittab,
711 .mclk = 64000000UL, 710 .mclk = 64000000UL,
712 .invert = 0, 711 .invert = 0,
713 .enhanced_tuning = 1,
714 .skip_reinit = 1, 712 .skip_reinit = 1,
715 .lock_output = STV0229_LOCKOUTPUT_1, 713 .lock_output = STV0229_LOCKOUTPUT_1,
716 .volt13_op0_op1 = STV0299_VOLT13_OP1, 714 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index b1f21ef0e3b3..755df81cbc49 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = {
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d 306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84, 307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 308 0x12, 0xb9,
309 0x15, 0xc9, // lock detector threshold 309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00, 310 0x16, 0x00,
311 0x17, 0x00, 311 0x17, 0x00,
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = {
379 .inittab = alps_bsru6_inittab, 379 .inittab = alps_bsru6_inittab,
380 .mclk = 88000000UL, 380 .mclk = 88000000UL,
381 .invert = 1, 381 .invert = 1,
382 .enhanced_tuning = 0,
383 .skip_reinit = 0, 382 .skip_reinit = 0,
384 .lock_output = STV0229_LOCKOUTPUT_1, 383 .lock_output = STV0229_LOCKOUTPUT_1,
385 .volt13_op0_op1 = STV0299_VOLT13_OP1, 384 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 43d6c8268642..4fd8bbc47037 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
226 return 0; 226 return 0;
227} 227}
228 228
229static void lnbp21_init(struct budget* budget) 229static int lnbp21_init(struct budget* budget)
230{ 230{
231 u8 buf = 0x00; 231 u8 buf = 0x00;
232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; 232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233 233
234 i2c_transfer (&budget->i2c_adap, &msg, 1); 234 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
235 return -EIO;
236 return 0;
235} 237}
236 238
237static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 239static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = {
273 0x01, 0x15, 275 0x01, 0x15,
274 0x02, 0x00, 276 0x02, 0x00,
275 0x03, 0x00, 277 0x03, 0x00,
276 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 278 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
277 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 279 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
278 0x06, 0x40, /* DAC not used, set to high impendance mode */ 280 0x06, 0x40, /* DAC not used, set to high impendance mode */
279 0x07, 0x00, /* DAC LSB */ 281 0x07, 0x00, /* DAC LSB */
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = {
284 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 286 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
285 0x10, 0x3f, // AGC2 0x3d 287 0x10, 0x3f, // AGC2 0x3d
286 0x11, 0x84, 288 0x11, 0x84,
287 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 289 0x12, 0xb9,
288 0x15, 0xc9, // lock detector threshold 290 0x15, 0xc9, // lock detector threshold
289 0x16, 0x00, 291 0x16, 0x00,
290 0x17, 0x00, 292 0x17, 0x00,
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = {
358 .inittab = alps_bsru6_inittab, 360 .inittab = alps_bsru6_inittab,
359 .mclk = 88000000UL, 361 .mclk = 88000000UL,
360 .invert = 1, 362 .invert = 1,
361 .enhanced_tuning = 0,
362 .skip_reinit = 0, 363 .skip_reinit = 0,
363 .lock_output = STV0229_LOCKOUTPUT_1, 364 .lock_output = STV0229_LOCKOUTPUT_1,
364 .volt13_op0_op1 = STV0299_VOLT13_OP1, 365 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = {
367 .pll_set = alps_bsru6_pll_set, 368 .pll_set = alps_bsru6_pll_set,
368}; 369};
369 370
371static u8 alps_bsbe1_inittab[] = {
372 0x01, 0x15,
373 0x02, 0x30,
374 0x03, 0x00,
375 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
376 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
377 0x06, 0x40, /* DAC not used, set to high impendance mode */
378 0x07, 0x00, /* DAC LSB */
379 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
380 0x09, 0x00, /* FIFO */
381 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
382 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
383 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
384 0x10, 0x3f, // AGC2 0x3d
385 0x11, 0x84,
386 0x12, 0xb9,
387 0x15, 0xc9, // lock detector threshold
388 0x16, 0x00,
389 0x17, 0x00,
390 0x18, 0x00,
391 0x19, 0x00,
392 0x1a, 0x00,
393 0x1f, 0x50,
394 0x20, 0x00,
395 0x21, 0x00,
396 0x22, 0x00,
397 0x23, 0x00,
398 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
399 0x29, 0x1e, // 1/2 threshold
400 0x2a, 0x14, // 2/3 threshold
401 0x2b, 0x0f, // 3/4 threshold
402 0x2c, 0x09, // 5/6 threshold
403 0x2d, 0x05, // 7/8 threshold
404 0x2e, 0x01,
405 0x31, 0x1f, // test all FECs
406 0x32, 0x19, // viterbi and synchro search
407 0x33, 0xfc, // rs control
408 0x34, 0x93, // error control
409 0x0f, 0x92, // 0x80 = inverse AGC
410 0xff, 0xff
411};
412
413static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
414{
415 int ret;
416 u8 data[4];
417 u32 div;
418 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
419
420 if ((params->frequency < 950000) || (params->frequency > 2150000))
421 return -EINVAL;
422
423 div = (params->frequency + (125 - 1)) / 125; // round correctly
424 data[0] = (div >> 8) & 0x7f;
425 data[1] = div & 0xff;
426 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
427 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
428
429 ret = i2c_transfer(i2c, &msg, 1);
430 return (ret != 1) ? -EIO : 0;
431}
432
433static struct stv0299_config alps_bsbe1_config = {
434 .demod_address = 0x68,
435 .inittab = alps_bsbe1_inittab,
436 .mclk = 88000000UL,
437 .invert = 1,
438 .skip_reinit = 0,
439 .min_delay_ms = 100,
440 .set_symbol_rate = alps_bsru6_set_symbol_rate,
441 .pll_set = alps_bsbe1_pll_set,
442};
443
370static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 444static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
371{ 445{
372 struct budget* budget = (struct budget*) fe->dvb->priv; 446 struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget)
500static void frontend_init(struct budget *budget) 574static void frontend_init(struct budget *budget)
501{ 575{
502 switch(budget->dev->pci->subsystem_device) { 576 switch(budget->dev->pci->subsystem_device) {
577 case 0x1017:
578 // try the ALPS BSBE1 now
579 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
580 if (budget->dvb_frontend) {
581 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
583 if (lnbp21_init(budget)) {
584 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585 goto error_out;
586 }
587 }
588
589 break;
503 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 590 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
504 case 0x1013: 591 case 0x1013:
505 // try the ALPS BSRV2 first of all 592 // try the ALPS BSRV2 first of all
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget)
554 if (budget->dvb_frontend) { 641 if (budget->dvb_frontend) {
555 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; 642 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
556 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 643 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
557 lnbp21_init(budget); 644 if (lnbp21_init(budget)) {
645 printk("%s: No LNBP21 found!\n", __FUNCTION__);
646 goto error_out;
647 }
558 break; 648 break;
559 } 649 }
560 } 650 }
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget)
566 budget->dev->pci->subsystem_vendor, 656 budget->dev->pci->subsystem_vendor,
567 budget->dev->pci->subsystem_device); 657 budget->dev->pci->subsystem_device);
568 } else { 658 } else {
569 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { 659 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
570 printk("budget: Frontend registration failed!\n"); 660 goto error_out;
571 if (budget->dvb_frontend->ops->release)
572 budget->dvb_frontend->ops->release(budget->dvb_frontend);
573 budget->dvb_frontend = NULL;
574 }
575 } 661 }
662 return;
663
664error_out:
665 printk("budget: Frontend registration failed!\n");
666 if (budget->dvb_frontend->ops->release)
667 budget->dvb_frontend->ops->release(budget->dvb_frontend);
668 budget->dvb_frontend = NULL;
669 return;
576} 670}
577 671
578static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 672static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev)
618 712
619static struct saa7146_extension budget_extension; 713static struct saa7146_extension budget_extension;
620 714
715MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
621MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 716MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
622MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 717MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
623MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 718MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = {
630 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 725 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
631 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 726 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
632 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 727 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
728 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
633 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 729 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
634 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 730 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
635 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 731 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index d200ab0ad9e7..fd53d6010502 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = {
1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1199 0x10, 0x3f, // AGC2 0x3d 1199 0x10, 0x3f, // AGC2 0x3d
1200 0x11, 0x84, 1200 0x11, 0x84,
1201 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1201 0x12, 0xb9,
1202 0x15, 0xc9, // lock detector threshold 1202 0x15, 0xc9, // lock detector threshold
1203 0x16, 0x00, 1203 0x16, 0x00,
1204 0x17, 0x00, 1204 0x17, 0x00,
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = {
1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1241 0x10, 0x3f, // AGC2 0x3d 1241 0x10, 0x3f, // AGC2 0x3d
1242 0x11, 0x84, 1242 0x11, 0x84,
1243 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1243 0x12, 0xb9,
1244 0x15, 0xc9, // lock detector threshold 1244 0x15, 0xc9, // lock detector threshold
1245 0x16, 0x00, 1245 0x16, 0x00,
1246 0x17, 0x00, 1246 0x17, 0x00,
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = {
1335 .inittab = alps_bsru6_inittab, 1335 .inittab = alps_bsru6_inittab,
1336 .mclk = 88000000UL, 1336 .mclk = 88000000UL,
1337 .invert = 1, 1337 .invert = 1,
1338 .enhanced_tuning = 0,
1339 .skip_reinit = 0, 1338 .skip_reinit = 0,
1340 .lock_output = STV0229_LOCKOUTPUT_1, 1339 .lock_output = STV0229_LOCKOUTPUT_1,
1341 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1340 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bbb989df4cf0..199b01188858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -25,6 +25,16 @@ config VIDEO_BT848
25 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
26 module will be called bttv. 26 module will be called bttv.
27 27
28config VIDEO_BT848_DVB
29 tristate "DVB/ATSC Support for bt878 based TV cards"
30 depends on VIDEO_BT848 && DVB_CORE
31 select DVB_BT8XX
32 ---help---
33 This adds support for DVB/ATSC cards based on the BT878 chip.
34
35 To compile this driver as a module, choose M here: the
36 module will be called dvb-bt8xx.
37
28config VIDEO_SAA6588 38config VIDEO_SAA6588
29 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" 39 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
30 depends on VIDEO_DEV && I2C && VIDEO_BT848 40 depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -243,29 +253,7 @@ config VIDEO_MEYE
243 To compile this driver as a module, choose M here: the 253 To compile this driver as a module, choose M here: the
244 module will be called meye. 254 module will be called meye.
245 255
246config VIDEO_SAA7134 256source "drivers/media/video/saa7134/Kconfig"
247 tristate "Philips SAA7134 support"
248 depends on VIDEO_DEV && PCI && I2C && SOUND
249 select VIDEO_BUF
250 select VIDEO_IR
251 select VIDEO_TUNER
252 select CRC32
253 ---help---
254 This is a video4linux driver for Philips SAA7130/7134 based
255 TV cards.
256
257 To compile this driver as a module, choose M here: the
258 module will be called saa7134.
259
260config VIDEO_SAA7134_DVB
261 tristate "DVB Support for saa7134 based TV cards"
262 depends on VIDEO_SAA7134 && DVB_CORE
263 select VIDEO_BUF_DVB
264 select DVB_MT352
265 select DVB_TDA1004X
266 ---help---
267 This adds support for DVB cards based on the
268 Philips saa7134 chip.
269 257
270config VIDEO_MXB 258config VIDEO_MXB
271 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 259 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI
316 To compile this driver as a module, choose M here: the 304 To compile this driver as a module, choose M here: the
317 module will be called hexium_gemini. 305 module will be called hexium_gemini.
318 306
319config VIDEO_CX88 307source "drivers/media/video/cx88/Kconfig"
320 tristate "Conexant 2388x (bt878 successor) support"
321 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
322 select I2C_ALGOBIT
323 select FW_LOADER
324 select VIDEO_BTCX
325 select VIDEO_BUF
326 select VIDEO_TUNER
327 select VIDEO_TVEEPROM
328 select VIDEO_IR
329 ---help---
330 This is a video4linux driver for Conexant 2388x based
331 TV cards.
332 308
333 To compile this driver as a module, choose M here: the 309source "drivers/media/video/em28xx/Kconfig"
334 module will be called cx8800
335
336config VIDEO_CX88_DVB
337 tristate "DVB Support for cx2388x based TV cards"
338 depends on VIDEO_CX88 && DVB_CORE
339 select VIDEO_BUF_DVB
340 select DVB_MT352
341 select DVB_OR51132
342 select DVB_CX22702
343 select DVB_LGDT330X
344 ---help---
345 This adds support for DVB/ATSC cards based on the
346 Connexant 2388x chip.
347 310
348config VIDEO_OVCAMCHIP 311config VIDEO_OVCAMCHIP
349 tristate "OmniVision Camera Chip support" 312 tristate "OmniVision Camera Chip support"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 046b82de9285..3ac465992400 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,7 +5,6 @@
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ 5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o 6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o 7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8rds-objs := saa6588.o
9zr36067-objs := zoran_procfs.o zoran_device.o \ 8zr36067-objs := zoran_procfs.o zoran_device.o \
10 zoran_driver.o zoran_card.o 9 zoran_driver.o zoran_card.o
11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17 16
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA6588) += rds.o 18obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
20obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
21obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
22obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o 21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
39obj-$(CONFIG_VIDEO_MEYE) += meye.o 38obj-$(CONFIG_VIDEO_MEYE) += meye.o
40obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
41obj-$(CONFIG_VIDEO_CX88) += cx88/ 40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
42obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
42obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 43obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
43obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o 44obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
44obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 45obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 0823ddaf7004..881cdcb1875d 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/fs.h> 27#include <linux/fs.h>
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 76c1b63ebdf2..e4063950ae57 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -32,7 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36#include "bttv.h" 35#include "bttv.h"
37#include "bt832.h" 36#include "bt832.h"
38 37
@@ -54,36 +53,36 @@ static struct i2c_driver driver;
54static struct i2c_client client_template; 53static struct i2c_client client_template;
55 54
56struct bt832 { 55struct bt832 {
57 struct i2c_client client; 56 struct i2c_client client;
58}; 57};
59 58
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) 59int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{ 60{
62 int i,rc; 61 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment 62 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) 63 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); 64 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
66 65
67 for(i=0;i<65;i++) 66 for(i=0;i<65;i++)
68 buf[i]=0; 67 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) 68 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); 69 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
71 70
72 // Note: On READ the first byte is the current index 71 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote) 72 // (e.g. 0x80, what we just wrote)
74 73
75 if(1) { 74 if(1) {
76 int i; 75 int i;
77 printk("BT832 hexdump:\n"); 76 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) { 77 for(i=1;i<65;i++) {
79 if(i!=1) { 78 if(i!=1) {
80 if(((i-1)%8)==0) printk(" "); 79 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n"); 80 if(((i-1)%16)==0) printk("\n");
82 } 81 }
83 printk(" %02x",buf[i]); 82 printk(" %02x",buf[i]);
84 } 83 }
85 printk("\n"); 84 printk("\n");
86 } 85 }
87 return 0; 86 return 0;
88} 87}
89 88
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
102 return 0; 101 return 0;
103 } 102 }
104 103
105 printk("Write 0 tp VPSTATUS\n"); 104 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52 105 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00; 106 buf[1]= 0x00;
108 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 107 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
109 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 108 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
110 109
111 bt832_hexdump(i2c_client_s,buf); 110 bt832_hexdump(i2c_client_s,buf);
112 111
113 112
114 // Leave low power mode: 113 // Leave low power mode:
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s)
116 buf[0]=BT832_CAM_SETUP0; //0x39 57 115 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08; 116 buf[1]=0x08;
118 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 117 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
119 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); 118 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
120 119
121 bt832_hexdump(i2c_client_s,buf); 120 bt832_hexdump(i2c_client_s,buf);
122 121
123 printk("Write 0 tp VPSTATUS\n"); 122 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52 123 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00; 124 buf[1]= 0x00;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 125 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 126 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
128 127
129 bt832_hexdump(i2c_client_s,buf); 128 bt832_hexdump(i2c_client_s,buf);
130 129
131 130
132 // Enable Output 131 // Enable Output
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s)
134 buf[0]=BT832_VP_CONTROL1; // Reg.40 133 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip 134 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 135 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 136 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138 137
139 bt832_hexdump(i2c_client_s,buf); 138 bt832_hexdump(i2c_client_s,buf);
140 139
141 140
142 // for testing (even works when no camera attached) 141 // for testing (even works when no camera attached)
143 printk("bt832: *** Generate NTSC M Bars *****\n"); 142 printk("bt832: *** Generate NTSC M Bars *****\n");
144 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 143 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
145 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally 144 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 145 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); 146 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
148 147
149 printk("Bt832: Camera Present: %s\n", 148 printk("Bt832: Camera Present: %s\n",
150 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); 149 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
151 150
152 bt832_hexdump(i2c_client_s,buf); 151 bt832_hexdump(i2c_client_s,buf);
153 kfree(buf); 152 kfree(buf);
154 return 1; 153 return 1;
155} 154}
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
162 161
163 printk("bt832_attach\n"); 162 printk("bt832_attach\n");
164 163
165 client_template.adapter = adap; 164 client_template.adapter = adap;
166 client_template.addr = addr; 165 client_template.addr = addr;
167 166
168 printk("bt832: chip found @ 0x%x\n", addr<<1); 167 printk("bt832: chip found @ 0x%x\n", addr<<1);
169 168
170 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 169 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
171 return -ENOMEM; 170 return -ENOMEM;
172 memset(t,0,sizeof(*t)); 171 memset(t,0,sizeof(*t));
173 t->client = client_template; 172 t->client = client_template;
174 i2c_set_clientdata(&t->client, t); 173 i2c_set_clientdata(&t->client, t);
175 i2c_attach_client(&t->client); 174 i2c_attach_client(&t->client);
176 175
177 if(! bt832_init(&t->client)) { 176 if(! bt832_init(&t->client)) {
178 bt832_detach(&t->client); 177 bt832_detach(&t->client);
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
211 210
212 printk("bt832: command %x\n",cmd); 211 printk("bt832: command %x\n",cmd);
213 212
214 switch (cmd) { 213 switch (cmd) {
215 case BT832_HEXDUMP: { 214 case BT832_HEXDUMP: {
216 unsigned char *buf; 215 unsigned char *buf;
217 buf=kmalloc(65,GFP_KERNEL); 216 buf=kmalloc(65,GFP_KERNEL);
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 9b6a8d2c96b5..1ce8fa71f7db 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace );
233/* from web: 233/* from web:
234 Video Sampling 234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are: 235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert 236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active 237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525 238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525 239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525 240NTSC 4FSc 14.32 MHz 910 768 525
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 0881a17d5226..3413bace443a 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -6,7 +6,7 @@
6 like the big tvcards array for the most part 6 like the big tvcards array for the most part
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
@@ -145,162 +145,163 @@ static struct CARD {
145 int cardnr; 145 int cardnr;
146 char *name; 146 char *name;
147} cards[] __devinitdata = { 147} cards[] __devinitdata = {
148 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" }, 148 { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
149 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" }, 149 { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
150 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, 150 { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
151 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" }, 151 { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
152 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" }, 152 { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
153 { 0xff020070, BTTV_OSPREY500, "Osprey-500" }, 153 { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
154 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" }, 154 { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
155 { 0xff040070, BTTV_OSPREY540, "Osprey-540" }, 155 { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
156 156 { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
157 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" }, 157
158 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, 158 { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
159 159 { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
160 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 160
161 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, 161 { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
162 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" }, 162 { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
163 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 163 { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
164 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 164 { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
165 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, 165 { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
166 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, 166 { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
167 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 167 { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
168 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 168 { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
169 169 { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
170 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 170
171 { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
171 /* some cards ship with byteswapped IDs ... */ 172 /* some cards ship with byteswapped IDs ... */
172 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 173 { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
173 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 174 { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
174 /* this seems to happen as well ... */ 175 /* this seems to happen as well ... */
175 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 176 { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
176 177
177 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 178 { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
178 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 179 { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
179 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, 180 { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
180 181
181 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, 182 { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
182 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, 183 { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
183 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, 184 { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
184 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, 185 { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
185 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, 186 { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
186 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, 187 { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
187 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, 188 { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
188 189
189 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 190 { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
190 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, 191 { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
191 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 192 { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
192 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, 193 { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
193 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, 194 { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
194 195
195 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, 196 { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
196 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, 197 { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
197 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, 198 { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
198 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, 199 { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
199 200
200 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, 201 { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
201 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, 202 { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
202 /* clashes with FlyVideo 203 /* clashes with FlyVideo
203 *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */ 204 *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
204 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, 205 { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
205 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ 206 { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
206 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */ 207 { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
207 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ 208 { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
208 209
209 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 210 { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
210 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 211 { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
211 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 212 { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
212 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 213 { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
213 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 214 { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
214 215
215 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, 216 { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
216 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, 217 { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
217 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, 218 { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
218 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, 219 { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
219 { 0x1433aa03, BTTV_PV143, "Security Eyes" }, 220 { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
220 221
221 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, 222 { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
222 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, 223 { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
223 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, 224 { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
224 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, 225 { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
225 226
226 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, 227 { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
227 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, 228 { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
228 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, 229 { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
229 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, 230 { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
230 231
231 { 0xa132ff00, BTTV_IVC100, "IVC-100" }, 232 { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
232 { 0xa1550000, BTTV_IVC200, "IVC-200" }, 233 { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
233 { 0xa1550001, BTTV_IVC200, "IVC-200" }, 234 { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
234 { 0xa1550002, BTTV_IVC200, "IVC-200" }, 235 { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
235 { 0xa1550003, BTTV_IVC200, "IVC-200" }, 236 { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
236 { 0xa1550100, BTTV_IVC200, "IVC-200G" }, 237 { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
237 { 0xa1550101, BTTV_IVC200, "IVC-200G" }, 238 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
238 { 0xa1550102, BTTV_IVC200, "IVC-200G" }, 239 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
239 { 0xa1550103, BTTV_IVC200, "IVC-200G" }, 240 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
240 { 0xa182ff00, BTTV_IVC120, "IVC-120G" }, 241 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
241 { 0xa182ff01, BTTV_IVC120, "IVC-120G" }, 242 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
242 { 0xa182ff02, BTTV_IVC120, "IVC-120G" }, 243 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
243 { 0xa182ff03, BTTV_IVC120, "IVC-120G" }, 244 { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
244 { 0xa182ff04, BTTV_IVC120, "IVC-120G" }, 245 { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
245 { 0xa182ff05, BTTV_IVC120, "IVC-120G" }, 246 { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff06, BTTV_IVC120, "IVC-120G" }, 247 { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
247 { 0xa182ff07, BTTV_IVC120, "IVC-120G" }, 248 { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
248 { 0xa182ff08, BTTV_IVC120, "IVC-120G" }, 249 { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
249 { 0xa182ff09, BTTV_IVC120, "IVC-120G" }, 250 { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
250 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" }, 251 { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
251 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" }, 252 { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
252 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" }, 253 { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
253 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, 254 { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
254 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, 255 { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
255 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, 256 { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
256 257
257 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, 258 { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
258 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, 259 { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
259 260
260 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 261 { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
261 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 262 { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
262 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, 263 { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
263 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, 264 { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
264 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, 265 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
265 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, 266 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
266 267
267 { 0x010115cb, BTTV_GMV1, "AG GMV1" }, 268 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
268 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, 269 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
269 270
270 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, 271 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
271 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 272 { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
272 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 273 { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
273 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, 274 { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
274 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, 275 { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
275 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, 276 { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
276 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, 277 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
277 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, 278 { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
278 { 0x146caa0c, BTTV_PV951, "ituner spectra8" }, 279 { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
279 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" }, 280 { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
280 281
281 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, 282 { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
282 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, 283 { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
283 284
284 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, 285 { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
285 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, 286 { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
286 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, 287 { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
287 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, 288 { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
288 289
289 { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" }, 290 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
290 291
291 /* likely broken, vendor id doesn't match the other magic views ... 292 /* likely broken, vendor id doesn't match the other magic views ...
292 * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 293 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
293 294
294 /* DVB cards (using pci function .1 for mpeg data xfer) */ 295 /* DVB cards (using pci function .1 for mpeg data xfer) */
295 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 296 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
296 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 297 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
297 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, 298 { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
298 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, 299 { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
299 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, 300 { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
300 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, 301 { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
301 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 302 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
302 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 303 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
303 { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 304 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
304 305
305 { 0, -1, NULL } 306 { 0, -1, NULL }
306}; 307};
@@ -309,2116 +310,2494 @@ static struct CARD {
309/* array with description for bt848 / bt878 tv/grabber cards */ 310/* array with description for bt848 / bt878 tv/grabber cards */
310 311
311struct tvcard bttv_tvcards[] = { 312struct tvcard bttv_tvcards[] = {
312{ 313 /* ---- card 0x00 ---------------------------------- */
313/* ---- card 0x00 ---------------------------------- */ 314 [BTTV_BOARD_UNKNOWN] = {
314 .name = " *** UNKNOWN/GENERIC *** ", 315 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4, 316 .video_inputs = 4,
316 .audio_inputs = 1, 317 .audio_inputs = 1,
317 .tuner = 0, 318 .tuner = 0,
318 .svhs = 2, 319 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0}, 320 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1, 321 .tuner_type = -1,
321 .tuner_addr = ADDR_UNSET, 322 .tuner_addr = ADDR_UNSET,
322},{ 323 .radio_addr = ADDR_UNSET,
323 .name = "MIRO PCTV", 324 },
324 .video_inputs = 4, 325 [BTTV_BOARD_MIRO] = {
325 .audio_inputs = 1, 326 .name = "MIRO PCTV",
326 .tuner = 0, 327 .video_inputs = 4,
327 .svhs = 2, 328 .audio_inputs = 1,
328 .gpiomask = 15, 329 .tuner = 0,
329 .muxsel = { 2, 3, 1, 1}, 330 .svhs = 2,
330 .audiomux = { 2, 0, 0, 0, 10}, 331 .gpiomask = 15,
331 .needs_tvaudio = 1, 332 .muxsel = { 2, 3, 1, 1},
332 .tuner_type = -1, 333 .audiomux = { 2, 0, 0, 0, 10},
333 .tuner_addr = ADDR_UNSET, 334 .needs_tvaudio = 1,
334},{ 335 .tuner_type = -1,
335 .name = "Hauppauge (bt848)", 336 .tuner_addr = ADDR_UNSET,
336 .video_inputs = 4, 337 .radio_addr = ADDR_UNSET,
337 .audio_inputs = 1, 338 },
338 .tuner = 0, 339 [BTTV_BOARD_HAUPPAUGE] = {
339 .svhs = 2, 340 .name = "Hauppauge (bt848)",
340 .gpiomask = 7, 341 .video_inputs = 4,
341 .muxsel = { 2, 3, 1, 1}, 342 .audio_inputs = 1,
342 .audiomux = { 0, 1, 2, 3, 4}, 343 .tuner = 0,
343 .needs_tvaudio = 1, 344 .svhs = 2,
344 .tuner_type = -1, 345 .gpiomask = 7,
345 .tuner_addr = ADDR_UNSET, 346 .muxsel = { 2, 3, 1, 1},
346},{ 347 .audiomux = { 0, 1, 2, 3, 4},
347 .name = "STB, Gateway P/N 6000699 (bt848)", 348 .needs_tvaudio = 1,
348 .video_inputs = 3, 349 .tuner_type = -1,
349 .audio_inputs = 1, 350 .tuner_addr = ADDR_UNSET,
350 .tuner = 0, 351 .radio_addr = ADDR_UNSET,
351 .svhs = 2, 352 },
352 .gpiomask = 7, 353 [BTTV_BOARD_STB] = {
353 .muxsel = { 2, 3, 1, 1}, 354 .name = "STB, Gateway P/N 6000699 (bt848)",
354 .audiomux = { 4, 0, 2, 3, 1}, 355 .video_inputs = 3,
355 .no_msp34xx = 1, 356 .audio_inputs = 1,
356 .needs_tvaudio = 1, 357 .tuner = 0,
357 .tuner_type = TUNER_PHILIPS_NTSC, 358 .svhs = 2,
358 .tuner_addr = ADDR_UNSET, 359 .gpiomask = 7,
359 .pll = PLL_28, 360 .muxsel = { 2, 3, 1, 1},
360 .has_radio = 1, 361 .audiomux = { 4, 0, 2, 3, 1},
361},{ 362 .no_msp34xx = 1,
362 363 .needs_tvaudio = 1,
363/* ---- card 0x04 ---------------------------------- */ 364 .tuner_type = TUNER_PHILIPS_NTSC,
364 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 365 .tuner_addr = ADDR_UNSET,
365 .video_inputs = 4, 366 .radio_addr = ADDR_UNSET,
366 .audio_inputs = 0, 367 .pll = PLL_28,
367 .tuner = -1, 368 .has_radio = 1,
368 .svhs = 2, 369 },
369 .gpiomask = 0, 370
370 .muxsel = { 2, 3, 1, 1}, 371 /* ---- card 0x04 ---------------------------------- */
371 .audiomux = { 0 }, 372 [BTTV_BOARD_INTEL] = {
372 .needs_tvaudio = 0, 373 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
373 .tuner_type = 4, 374 .video_inputs = 4,
374 .tuner_addr = ADDR_UNSET, 375 .audio_inputs = 0,
375},{ 376 .tuner = -1,
376 .name = "Diamond DTV2000", 377 .svhs = 2,
377 .video_inputs = 4, 378 .gpiomask = 0,
378 .audio_inputs = 1, 379 .muxsel = { 2, 3, 1, 1},
379 .tuner = 0, 380 .audiomux = { 0 },
380 .svhs = 2, 381 .needs_tvaudio = 0,
381 .gpiomask = 3, 382 .tuner_type = 4,
382 .muxsel = { 2, 3, 1, 0}, 383 .tuner_addr = ADDR_UNSET,
383 .audiomux = { 0, 1, 0, 1, 3}, 384 .radio_addr = ADDR_UNSET,
384 .needs_tvaudio = 1, 385 },
385 .tuner_type = -1, 386 [BTTV_BOARD_DIAMOND] = {
386 .tuner_addr = ADDR_UNSET, 387 .name = "Diamond DTV2000",
387},{ 388 .video_inputs = 4,
388 .name = "AVerMedia TVPhone", 389 .audio_inputs = 1,
389 .video_inputs = 3, 390 .tuner = 0,
390 .audio_inputs = 1, 391 .svhs = 2,
391 .tuner = 0, 392 .gpiomask = 3,
392 .svhs = 3, 393 .muxsel = { 2, 3, 1, 0},
393 .muxsel = { 2, 3, 1, 1}, 394 .audiomux = { 0, 1, 0, 1, 3},
394 .gpiomask = 0x0f, 395 .needs_tvaudio = 1,
395 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, 396 .tuner_type = -1,
396 /* 0x04 for some cards ?? */ 397 .tuner_addr = ADDR_UNSET,
397 .needs_tvaudio = 1, 398 .radio_addr = ADDR_UNSET,
398 .tuner_type = -1, 399 },
399 .tuner_addr = ADDR_UNSET, 400 [BTTV_BOARD_AVERMEDIA] = {
400 .audio_hook = avermedia_tvphone_audio, 401 .name = "AVerMedia TVPhone",
401 .has_remote = 1, 402 .video_inputs = 3,
402},{ 403 .audio_inputs = 1,
403 .name = "MATRIX-Vision MV-Delta", 404 .tuner = 0,
404 .video_inputs = 5, 405 .svhs = 3,
405 .audio_inputs = 1, 406 .muxsel = { 2, 3, 1, 1},
406 .tuner = -1, 407 .gpiomask = 0x0f,
407 .svhs = 3, 408 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
408 .gpiomask = 0, 409 /* 0x04 for some cards ?? */
409 .muxsel = { 2, 3, 1, 0, 0}, 410 .needs_tvaudio = 1,
410 .audiomux = {0 }, 411 .tuner_type = -1,
411 .needs_tvaudio = 1, 412 .tuner_addr = ADDR_UNSET,
412 .tuner_type = -1, 413 .radio_addr = ADDR_UNSET,
413 .tuner_addr = ADDR_UNSET, 414 .audio_hook = avermedia_tvphone_audio,
414},{ 415 .has_remote = 1,
415 416 },
416/* ---- card 0x08 ---------------------------------- */ 417 [BTTV_BOARD_MATRIX_VISION] = {
417 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", 418 .name = "MATRIX-Vision MV-Delta",
418 .video_inputs = 4, 419 .video_inputs = 5,
419 .audio_inputs = 1, 420 .audio_inputs = 1,
420 .tuner = 0, 421 .tuner = -1,
421 .svhs = 2, 422 .svhs = 3,
422 .gpiomask = 0xc00, 423 .gpiomask = 0,
423 .muxsel = { 2, 3, 1, 1}, 424 .muxsel = { 2, 3, 1, 0, 0},
424 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, 425 .audiomux = {0 },
425 .needs_tvaudio = 1, 426 .needs_tvaudio = 1,
426 .pll = PLL_28, 427 .tuner_type = -1,
427 .tuner_type = -1, 428 .tuner_addr = ADDR_UNSET,
428 .tuner_addr = ADDR_UNSET, 429 .radio_addr = ADDR_UNSET,
429},{ 430 },
430 .name = "IMS/IXmicro TurboTV", 431
431 .video_inputs = 3, 432 /* ---- card 0x08 ---------------------------------- */
432 .audio_inputs = 1, 433 [BTTV_BOARD_FLYVIDEO] = {
433 .tuner = 0, 434 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
434 .svhs = 2, 435 .video_inputs = 4,
435 .gpiomask = 3, 436 .audio_inputs = 1,
436 .muxsel = { 2, 3, 1, 1}, 437 .tuner = 0,
437 .audiomux = { 1, 1, 2, 3, 0}, 438 .svhs = 2,
438 .needs_tvaudio = 0, 439 .gpiomask = 0xc00,
439 .pll = PLL_28, 440 .muxsel = { 2, 3, 1, 1},
440 .tuner_type = TUNER_TEMIC_PAL, 441 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
441 .tuner_addr = ADDR_UNSET, 442 .needs_tvaudio = 1,
442},{ 443 .pll = PLL_28,
443 .name = "Hauppauge (bt878)", 444 .tuner_type = -1,
444 .video_inputs = 4, 445 .tuner_addr = ADDR_UNSET,
445 .audio_inputs = 1, 446 .radio_addr = ADDR_UNSET,
446 .tuner = 0, 447 },
447 .svhs = 2, 448 [BTTV_BOARD_TURBOTV] = {
448 .gpiomask = 0x0f, /* old: 7 */ 449 .name = "IMS/IXmicro TurboTV",
449 .muxsel = { 2, 0, 1, 1}, 450 .video_inputs = 3,
450 .audiomux = { 0, 1, 2, 3, 4}, 451 .audio_inputs = 1,
451 .needs_tvaudio = 1, 452 .tuner = 0,
452 .pll = PLL_28, 453 .svhs = 2,
453 .tuner_type = -1, 454 .gpiomask = 3,
454 .tuner_addr = ADDR_UNSET, 455 .muxsel = { 2, 3, 1, 1},
455},{ 456 .audiomux = { 1, 1, 2, 3, 0},
456 .name = "MIRO PCTV pro", 457 .needs_tvaudio = 0,
457 .video_inputs = 3, 458 .pll = PLL_28,
458 .audio_inputs = 1, 459 .tuner_type = TUNER_TEMIC_PAL,
459 .tuner = 0, 460 .tuner_addr = ADDR_UNSET,
460 .svhs = 2, 461 .radio_addr = ADDR_UNSET,
461 .gpiomask = 0x3014f, 462 },
462 .muxsel = { 2, 3, 1, 1}, 463 [BTTV_BOARD_HAUPPAUGE878] = {
463 .audiomux = { 0x20001,0x10001, 0, 0,10}, 464 .name = "Hauppauge (bt878)",
464 .needs_tvaudio = 1, 465 .video_inputs = 4,
465 .tuner_type = -1, 466 .audio_inputs = 1,
466 .tuner_addr = ADDR_UNSET, 467 .tuner = 0,
467},{ 468 .svhs = 2,
468 469 .gpiomask = 0x0f, /* old: 7 */
469/* ---- card 0x0c ---------------------------------- */ 470 .muxsel = { 2, 0, 1, 1},
470 .name = "ADS Technologies Channel Surfer TV (bt848)", 471 .audiomux = { 0, 1, 2, 3, 4},
471 .video_inputs = 3, 472 .needs_tvaudio = 1,
472 .audio_inputs = 1, 473 .pll = PLL_28,
473 .tuner = 0, 474 .tuner_type = -1,
474 .svhs = 2, 475 .tuner_addr = ADDR_UNSET,
475 .gpiomask = 15, 476 .radio_addr = ADDR_UNSET,
476 .muxsel = { 2, 3, 1, 1}, 477 },
477 .audiomux = { 13, 14, 11, 7, 0, 0}, 478 [BTTV_BOARD_MIROPRO] = {
478 .needs_tvaudio = 1, 479 .name = "MIRO PCTV pro",
479 .tuner_type = -1, 480 .video_inputs = 3,
480 .tuner_addr = ADDR_UNSET, 481 .audio_inputs = 1,
481},{ 482 .tuner = 0,
482 .name = "AVerMedia TVCapture 98", 483 .svhs = 2,
483 .video_inputs = 3, 484 .gpiomask = 0x3014f,
484 .audio_inputs = 4, 485 .muxsel = { 2, 3, 1, 1},
485 .tuner = 0, 486 .audiomux = { 0x20001,0x10001, 0, 0,10},
486 .svhs = 2, 487 .needs_tvaudio = 1,
487 .gpiomask = 15, 488 .tuner_type = -1,
488 .muxsel = { 2, 3, 1, 1}, 489 .tuner_addr = ADDR_UNSET,
489 .audiomux = { 13, 14, 11, 7, 0, 0}, 490 .radio_addr = ADDR_UNSET,
490 .needs_tvaudio = 1, 491 },
491 .msp34xx_alt = 1, 492
492 .pll = PLL_28, 493 /* ---- card 0x0c ---------------------------------- */
493 .tuner_type = TUNER_PHILIPS_PAL, 494 [BTTV_BOARD_ADSTECH_TV] = {
494 .tuner_addr = ADDR_UNSET, 495 .name = "ADS Technologies Channel Surfer TV (bt848)",
495 .audio_hook = avermedia_tv_stereo_audio, 496 .video_inputs = 3,
496},{ 497 .audio_inputs = 1,
497 .name = "Aimslab Video Highway Xtreme (VHX)", 498 .tuner = 0,
498 .video_inputs = 3, 499 .svhs = 2,
499 .audio_inputs = 1, 500 .gpiomask = 15,
500 .tuner = 0, 501 .muxsel = { 2, 3, 1, 1},
501 .svhs = 2, 502 .audiomux = { 13, 14, 11, 7, 0, 0},
502 .gpiomask = 7, 503 .needs_tvaudio = 1,
503 .muxsel = { 2, 3, 1, 1}, 504 .tuner_type = -1,
504 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ 505 .tuner_addr = ADDR_UNSET,
505 .needs_tvaudio = 1, 506 .radio_addr = ADDR_UNSET,
506 .pll = PLL_28, 507 },
507 .tuner_type = -1, 508 [BTTV_BOARD_AVERMEDIA98] = {
508 .tuner_addr = ADDR_UNSET, 509 .name = "AVerMedia TVCapture 98",
509},{ 510 .video_inputs = 3,
510 .name = "Zoltrix TV-Max", 511 .audio_inputs = 4,
511 .video_inputs = 3, 512 .tuner = 0,
512 .audio_inputs = 1, 513 .svhs = 2,
513 .tuner = 0, 514 .gpiomask = 15,
514 .svhs = 2, 515 .muxsel = { 2, 3, 1, 1},
515 .gpiomask = 15, 516 .audiomux = { 13, 14, 11, 7, 0, 0},
516 .muxsel = { 2, 3, 1, 1}, 517 .needs_tvaudio = 1,
517 .audiomux = {0 , 0, 1 , 0, 10}, 518 .msp34xx_alt = 1,
518 .needs_tvaudio = 1, 519 .pll = PLL_28,
519 .tuner_type = -1, 520 .tuner_type = TUNER_PHILIPS_PAL,
520 .tuner_addr = ADDR_UNSET, 521 .tuner_addr = ADDR_UNSET,
521},{ 522 .radio_addr = ADDR_UNSET,
522 523 .audio_hook = avermedia_tv_stereo_audio,
523/* ---- card 0x10 ---------------------------------- */ 524 .no_gpioirq = 1,
524 .name = "Prolink Pixelview PlayTV (bt878)", 525 },
525 .video_inputs = 3, 526 [BTTV_BOARD_VHX] = {
526 .audio_inputs = 1, 527 .name = "Aimslab Video Highway Xtreme (VHX)",
527 .tuner = 0, 528 .video_inputs = 3,
528 .svhs = 2, 529 .audio_inputs = 1,
529 .gpiomask = 0x01fe00, 530 .tuner = 0,
530 .muxsel = { 2, 3, 1, 1}, 531 .svhs = 2,
531 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ 532 .gpiomask = 7,
532 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 533 .muxsel = { 2, 3, 1, 1},
533 .needs_tvaudio = 1, 534 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
534 .pll = PLL_28, 535 .needs_tvaudio = 1,
535 .tuner_type = -1, 536 .pll = PLL_28,
536},{ 537 .tuner_type = -1,
537 .name = "Leadtek WinView 601", 538 .tuner_addr = ADDR_UNSET,
538 .video_inputs = 3, 539 .radio_addr = ADDR_UNSET,
539 .audio_inputs = 1, 540 },
540 .tuner = 0, 541 [BTTV_BOARD_ZOLTRIX] = {
541 .svhs = 2, 542 .name = "Zoltrix TV-Max",
542 .gpiomask = 0x8300f8, 543 .video_inputs = 3,
543 .muxsel = { 2, 3, 1, 1,0}, 544 .audio_inputs = 1,
544 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, 545 .tuner = 0,
545 .needs_tvaudio = 1, 546 .svhs = 2,
546 .tuner_type = -1, 547 .gpiomask = 15,
547 .tuner_addr = ADDR_UNSET, 548 .muxsel = { 2, 3, 1, 1},
548 .audio_hook = winview_audio, 549 .audiomux = {0 , 0, 1 , 0, 10},
549 .has_radio = 1, 550 .needs_tvaudio = 1,
550},{ 551 .tuner_type = -1,
551 .name = "AVEC Intercapture", 552 .tuner_addr = ADDR_UNSET,
552 .video_inputs = 3, 553 .radio_addr = ADDR_UNSET,
553 .audio_inputs = 2, 554 },
554 .tuner = 0, 555
555 .svhs = 2, 556 /* ---- card 0x10 ---------------------------------- */
556 .gpiomask = 0, 557 [BTTV_BOARD_PIXVIEWPLAYTV] = {
557 .muxsel = {2, 3, 1, 1}, 558 .name = "Prolink Pixelview PlayTV (bt878)",
558 .audiomux = {1, 0, 0, 0, 0}, 559 .video_inputs = 3,
559 .needs_tvaudio = 1, 560 .audio_inputs = 1,
560 .tuner_type = -1, 561 .tuner = 0,
561 .tuner_addr = ADDR_UNSET, 562 .svhs = 2,
562},{ 563 .gpiomask = 0x01fe00,
563 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", 564 .muxsel = { 2, 3, 1, 1},
564 .video_inputs = 4, 565 #if 0
565 .audio_inputs = 1, 566 /* old */
566 .tuner = -1, 567 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
567 .svhs = -1, 568 #else
568 .gpiomask = 0x8dff00, 569 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
569 .muxsel = { 2, 3, 1, 1}, 570 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
570 .audiomux = { 0 }, 571 #endif
571 .no_msp34xx = 1, 572 .needs_tvaudio = 1,
572 .tuner_type = -1, 573 .pll = PLL_28,
573 .tuner_addr = ADDR_UNSET, 574 .tuner_type = -1,
574},{ 575 },
575 576 [BTTV_BOARD_WINVIEW_601] = {
576/* ---- card 0x14 ---------------------------------- */ 577 .name = "Leadtek WinView 601",
577 .name = "CEI Raffles Card", 578 .video_inputs = 3,
578 .video_inputs = 3, 579 .audio_inputs = 1,
579 .audio_inputs = 3, 580 .tuner = 0,
580 .tuner = 0, 581 .svhs = 2,
581 .svhs = 2, 582 .gpiomask = 0x8300f8,
582 .muxsel = {2, 3, 1, 1}, 583 .muxsel = { 2, 3, 1, 1,0},
583 .tuner_type = -1, 584 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
584 .tuner_addr = ADDR_UNSET, 585 .needs_tvaudio = 1,
585},{ 586 .tuner_type = -1,
586 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", 587 .tuner_addr = ADDR_UNSET,
587 .video_inputs = 4, 588 .radio_addr = ADDR_UNSET,
588 .audio_inputs = 2, /* tuner, line in */ 589 .audio_hook = winview_audio,
589 .tuner = 0, 590 .has_radio = 1,
590 .svhs = 2, 591 },
591 .gpiomask = 0x1800, 592 [BTTV_BOARD_AVEC_INTERCAP] = {
592 .muxsel = { 2, 3, 1, 1}, 593 .name = "AVEC Intercapture",
593 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 594 .video_inputs = 3,
594 .pll = PLL_28, 595 .audio_inputs = 2,
595 .tuner_type = TUNER_PHILIPS_PAL_I, 596 .tuner = 0,
596 .tuner_addr = ADDR_UNSET, 597 .svhs = 2,
597},{ 598 .gpiomask = 0,
598 .name = "Askey CPH050/ Phoebe Tv Master + FM", 599 .muxsel = {2, 3, 1, 1},
599 .video_inputs = 3, 600 .audiomux = {1, 0, 0, 0, 0},
600 .audio_inputs = 1, 601 .needs_tvaudio = 1,
601 .tuner = 0, 602 .tuner_type = -1,
602 .svhs = 2, 603 .tuner_addr = ADDR_UNSET,
603 .gpiomask = 0xc00, 604 .radio_addr = ADDR_UNSET,
604 .muxsel = { 2, 3, 1, 1}, 605 },
605 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, 606 [BTTV_BOARD_LIFE_FLYKIT] = {
606 .needs_tvaudio = 1, 607 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
607 .pll = PLL_28, 608 .video_inputs = 4,
608 .tuner_type = -1, 609 .audio_inputs = 1,
609 .tuner_addr = ADDR_UNSET, 610 .tuner = -1,
610},{ 611 .svhs = -1,
611 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", 612 .gpiomask = 0x8dff00,
612 .video_inputs = 3, 613 .muxsel = { 2, 3, 1, 1},
613 .audio_inputs = 1, 614 .audiomux = { 0 },
614 .tuner = 0, 615 .no_msp34xx = 1,
615 .svhs = -1, 616 .tuner_type = -1,
616 .gpiomask = 7, 617 .tuner_addr = ADDR_UNSET,
617 .muxsel = { 2, 3, -1 }, 618 .radio_addr = ADDR_UNSET,
618 .digital_mode = DIGITAL_MODE_CAMERA, 619 },
619 .audiomux = { 0, 0, 0, 0, 0 }, 620
620 .no_msp34xx = 1, 621 /* ---- card 0x14 ---------------------------------- */
621 .pll = PLL_28, 622 [BTTV_BOARD_CEI_RAFFLES] = {
622 .tuner_type = TUNER_ALPS_TSBB5_PAL_I, 623 .name = "CEI Raffles Card",
623 .tuner_addr = ADDR_UNSET, 624 .video_inputs = 3,
624},{ 625 .audio_inputs = 3,
625 626 .tuner = 0,
626/* ---- card 0x18 ---------------------------------- */ 627 .svhs = 2,
627 .name = "Askey CPH05X/06X (bt878) [many vendors]", 628 .muxsel = {2, 3, 1, 1},
628 .video_inputs = 3, 629 .tuner_type = -1,
629 .audio_inputs = 1, 630 .tuner_addr = ADDR_UNSET,
630 .tuner = 0, 631 .radio_addr = ADDR_UNSET,
631 .svhs = 2, 632 },
632 .gpiomask = 0xe00, 633 [BTTV_BOARD_CONFERENCETV] = {
633 .muxsel = { 2, 3, 1, 1}, 634 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
634 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, 635 .video_inputs = 4,
635 .needs_tvaudio = 1, 636 .audio_inputs = 2, /* tuner, line in */
636 .pll = PLL_28, 637 .tuner = 0,
637 .tuner_type = -1, 638 .svhs = 2,
638 .tuner_addr = ADDR_UNSET, 639 .gpiomask = 0x1800,
639 .has_remote = 1, 640 .muxsel = { 2, 3, 1, 1},
640},{ 641 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
641 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", 642 .pll = PLL_28,
642 .video_inputs = 3, 643 .tuner_type = TUNER_PHILIPS_PAL_I,
643 .audio_inputs = 1, 644 .tuner_addr = ADDR_UNSET,
644 .tuner = 0, 645 .radio_addr = ADDR_UNSET,
645 .svhs = 2, 646 },
646 .gpiomask = 0x1f0fff, 647 [BTTV_BOARD_PHOEBE_TVMAS] = {
647 .muxsel = { 2, 3, 1, 1}, 648 .name = "Askey CPH050/ Phoebe Tv Master + FM",
648 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, 649 .video_inputs = 3,
649 .needs_tvaudio = 0, 650 .audio_inputs = 1,
650 .tuner_type = TUNER_PHILIPS_PAL, 651 .tuner = 0,
651 .tuner_addr = ADDR_UNSET, 652 .svhs = 2,
652 .audio_hook = terratv_audio, 653 .gpiomask = 0xc00,
653},{ 654 .muxsel = { 2, 3, 1, 1},
654 .name = "Hauppauge WinCam newer (bt878)", 655 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
655 .video_inputs = 4, 656 .needs_tvaudio = 1,
656 .audio_inputs = 1, 657 .pll = PLL_28,
657 .tuner = 0, 658 .tuner_type = -1,
658 .svhs = 3, 659 .tuner_addr = ADDR_UNSET,
659 .gpiomask = 7, 660 .radio_addr = ADDR_UNSET,
660 .muxsel = { 2, 0, 1, 1}, 661 },
661 .audiomux = { 0, 1, 2, 3, 4}, 662 [BTTV_BOARD_MODTEC_205] = {
662 .needs_tvaudio = 1, 663 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
663 .tuner_type = -1, 664 .video_inputs = 3,
664 .tuner_addr = ADDR_UNSET, 665 .audio_inputs = 1,
665},{ 666 .tuner = 0,
666 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", 667 .svhs = -1,
667 .video_inputs = 4, 668 .gpiomask = 7,
668 .audio_inputs = 2, 669 .muxsel = { 2, 3, -1 },
669 .tuner = 0, 670 .digital_mode = DIGITAL_MODE_CAMERA,
670 .svhs = 2, 671 .audiomux = { 0, 0, 0, 0, 0 },
671 .gpiomask = 0x1800, 672 .no_msp34xx = 1,
672 .muxsel = { 2, 3, 1, 1}, 673 .pll = PLL_28,
673 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 674 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
674 .pll = PLL_28, 675 .tuner_addr = ADDR_UNSET,
675 .tuner_type = TUNER_PHILIPS_SECAM, 676 .radio_addr = ADDR_UNSET,
676 .tuner_addr = ADDR_UNSET, 677 },
677},{ 678
678 679 /* ---- card 0x18 ---------------------------------- */
679/* ---- card 0x1c ---------------------------------- */ 680 [BTTV_BOARD_MAGICTVIEW061] = {
680 .name = "Terratec TerraTV+ Version 1.1 (bt878)", 681 .name = "Askey CPH05X/06X (bt878) [many vendors]",
681 .video_inputs = 3, 682 .video_inputs = 3,
682 .audio_inputs = 1, 683 .audio_inputs = 1,
683 .tuner = 0, 684 .tuner = 0,
684 .svhs = 2, 685 .svhs = 2,
685 .gpiomask = 0x1f0fff, 686 .gpiomask = 0xe00,
686 .muxsel = { 2, 3, 1, 1}, 687 .muxsel = { 2, 3, 1, 1},
687 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, 688 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
688 .needs_tvaudio = 0, 689 .needs_tvaudio = 1,
689 .tuner_type = TUNER_PHILIPS_PAL, 690 .pll = PLL_28,
690 .tuner_addr = ADDR_UNSET, 691 .tuner_type = -1,
691 .audio_hook = terratv_audio, 692 .tuner_addr = ADDR_UNSET,
692 /* GPIO wiring: 693 .radio_addr = ADDR_UNSET,
693 External 20 pin connector (for Active Radio Upgrade board) 694 .has_remote = 1,
694 gpio00: i2c-sda 695 },
695 gpio01: i2c-scl 696 [BTTV_BOARD_VOBIS_BOOSTAR] = {
696 gpio02: om5610-data 697 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
697 gpio03: om5610-clk 698 .video_inputs = 3,
698 gpio04: om5610-wre 699 .audio_inputs = 1,
699 gpio05: om5610-stereo 700 .tuner = 0,
700 gpio06: rds6588-davn 701 .svhs = 2,
701 gpio07: Pin 7 n.c. 702 .gpiomask = 0x1f0fff,
702 gpio08: nIOW 703 .muxsel = { 2, 3, 1, 1},
703 gpio09+10: nIOR, nSEL ?? (bt878) 704 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
704 gpio09: nIOR (bt848) 705 .needs_tvaudio = 0,
705 gpio10: nSEL (bt848) 706 .tuner_type = TUNER_PHILIPS_PAL,
706 Sound Routing: 707 .tuner_addr = ADDR_UNSET,
707 gpio16: u2-A0 (1st 4052bt) 708 .radio_addr = ADDR_UNSET,
708 gpio17: u2-A1 709 .audio_hook = terratv_audio,
709 gpio18: u2-nEN 710 },
710 gpio19: u4-A0 (2nd 4052) 711 [BTTV_BOARD_HAUPPAUG_WCAM] = {
711 gpio20: u4-A1 712 .name = "Hauppauge WinCam newer (bt878)",
712 u4-nEN - GND 713 .video_inputs = 4,
713 Btspy: 714 .audio_inputs = 1,
714 00000 : Cdrom (internal audio input) 715 .tuner = 0,
715 10000 : ext. Video audio input 716 .svhs = 3,
716 20000 : TV Mono 717 .gpiomask = 7,
717 a0000 : TV Mono/2 718 .muxsel = { 2, 0, 1, 1},
718 1a0000 : TV Stereo 719 .audiomux = { 0, 1, 2, 3, 4},
719 30000 : Radio 720 .needs_tvaudio = 1,
720 40000 : Mute 721 .tuner_type = -1,
721*/ 722 .tuner_addr = ADDR_UNSET,
722 723 .radio_addr = ADDR_UNSET,
723},{ 724 },
724 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ 725 [BTTV_BOARD_MAXI] = {
725 .name = "Imagenation PXC200", 726 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
726 .video_inputs = 5, 727 .video_inputs = 4,
727 .audio_inputs = 1, 728 .audio_inputs = 2,
728 .tuner = -1, 729 .tuner = 0,
729 .svhs = 1, /* was: 4 */ 730 .svhs = 2,
730 .gpiomask = 0, 731 .gpiomask = 0x1800,
731 .muxsel = { 2, 3, 1, 0, 0}, 732 .muxsel = { 2, 3, 1, 1},
732 .audiomux = { 0 }, 733 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
733 .needs_tvaudio = 1, 734 .pll = PLL_28,
734 .tuner_type = -1, 735 .tuner_type = TUNER_PHILIPS_SECAM,
735 .tuner_addr = ADDR_UNSET, 736 .tuner_addr = ADDR_UNSET,
736 .muxsel_hook = PXC200_muxsel, 737 .radio_addr = ADDR_UNSET,
737 738 },
738},{ 739
739 .name = "Lifeview FlyVideo 98 LR50", 740 /* ---- card 0x1c ---------------------------------- */
740 .video_inputs = 4, 741 [BTTV_BOARD_TERRATV] = {
741 .audio_inputs = 1, 742 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
742 .tuner = 0, 743 .video_inputs = 3,
743 .svhs = 2, 744 .audio_inputs = 1,
744 .gpiomask = 0x1800, /* 0x8dfe00 */ 745 .tuner = 0,
745 .muxsel = { 2, 3, 1, 1}, 746 .svhs = 2,
746 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, 747 .gpiomask = 0x1f0fff,
747 .pll = PLL_28, 748 .muxsel = { 2, 3, 1, 1},
748 .tuner_type = -1, 749 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
749 .tuner_addr = ADDR_UNSET, 750 .needs_tvaudio = 0,
750},{ 751 .tuner_type = TUNER_PHILIPS_PAL,
751 .name = "Formac iProTV, Formac ProTV I (bt848)", 752 .tuner_addr = ADDR_UNSET,
752 .video_inputs = 4, 753 .radio_addr = ADDR_UNSET,
753 .audio_inputs = 1, 754 .audio_hook = terratv_audio,
754 .tuner = 0, 755 /* GPIO wiring:
755 .svhs = 3, 756 External 20 pin connector (for Active Radio Upgrade board)
756 .gpiomask = 1, 757 gpio00: i2c-sda
757 .muxsel = { 2, 3, 1, 1}, 758 gpio01: i2c-scl
758 .audiomux = { 1, 0, 0, 0, 0 }, 759 gpio02: om5610-data
759 .pll = PLL_28, 760 gpio03: om5610-clk
760 .tuner_type = TUNER_PHILIPS_PAL, 761 gpio04: om5610-wre
761 .tuner_addr = ADDR_UNSET, 762 gpio05: om5610-stereo
762},{ 763 gpio06: rds6588-davn
763 764 gpio07: Pin 7 n.c.
764/* ---- card 0x20 ---------------------------------- */ 765 gpio08: nIOW
765 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 766 gpio09+10: nIOR, nSEL ?? (bt878)
766 .video_inputs = 4, 767 gpio09: nIOR (bt848)
767 .audio_inputs = 0, 768 gpio10: nSEL (bt848)
768 .tuner = -1, 769 Sound Routing:
769 .svhs = 2, 770 gpio16: u2-A0 (1st 4052bt)
770 .gpiomask = 0, 771 gpio17: u2-A1
771 .muxsel = { 2, 3, 1, 1}, 772 gpio18: u2-nEN
772 .audiomux = { 0 }, 773 gpio19: u4-A0 (2nd 4052)
773 .needs_tvaudio = 0, 774 gpio20: u4-A1
774 .tuner_type = 4, 775 u4-nEN - GND
775 .tuner_addr = ADDR_UNSET, 776 Btspy:
776},{ 777 00000 : Cdrom (internal audio input)
777 .name = "Terratec TerraTValue Version Bt878", 778 10000 : ext. Video audio input
778 .video_inputs = 3, 779 20000 : TV Mono
779 .audio_inputs = 1, 780 a0000 : TV Mono/2
780 .tuner = 0, 781 1a0000 : TV Stereo
781 .svhs = 2, 782 30000 : Radio
782 .gpiomask = 0xffff00, 783 40000 : Mute
783 .muxsel = { 2, 3, 1, 1},
784 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
785 .needs_tvaudio = 1,
786 .pll = PLL_28,
787 .tuner_type = TUNER_PHILIPS_PAL,
788 .tuner_addr = ADDR_UNSET,
789},{
790 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
791 .video_inputs = 4,
792 .audio_inputs = 1,
793 .tuner = 0,
794 .svhs = 2,
795 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
796 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
797 .gpiomask = 0xb33000,
798 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
799 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
800 gpio23 -- hef4052:nEnable (0x800000)
801 gpio12 -- hef4052:A1
802 gpio13 -- hef4052:A0
803 0x0000: external audio
804 0x1000: FM
805 0x2000: TV
806 0x3000: n.c.
807 Note: There exists another variant "Winfast 2000" with tv stereo !?
808 Note: eeprom only contains FF and pci subsystem id 107d:6606
809 */
810 .needs_tvaudio = 0,
811 .pll = PLL_28,
812 .has_radio = 1,
813 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
814 .tuner_addr = ADDR_UNSET,
815 .audio_hook = winfast2000_audio,
816 .has_remote = 1,
817},{
818 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
819 .video_inputs = 4,
820 .audio_inputs = 3,
821 .tuner = 0,
822 .svhs = 2,
823 .gpiomask = 0x1800,
824 .muxsel = { 2, 3, 1, 1},
825 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
826 .pll = PLL_28,
827 .tuner_type = -1,
828 .tuner_addr = ADDR_UNSET,
829},{
830
831/* ---- card 0x24 ---------------------------------- */
832 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
833 .video_inputs = 4,
834 .audio_inputs = 3,
835 .tuner = 0,
836 .svhs = 2,
837 .gpiomask = 0x1800,
838 .muxsel = { 2, 3, 1, 1},
839 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
840 .pll = PLL_28,
841 .tuner_type = -1,
842 .tuner_addr = ADDR_UNSET,
843 .has_radio = 1,
844},{
845 .name = "Prolink PixelView PlayTV pro",
846 .video_inputs = 3,
847 .audio_inputs = 1,
848 .tuner = 0,
849 .svhs = 2,
850 .gpiomask = 0xff,
851 .muxsel = { 2, 3, 1, 1 },
852 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
853 .no_msp34xx = 1,
854 .pll = PLL_28,
855 .tuner_type = -1,
856 .tuner_addr = ADDR_UNSET,
857},{
858 .name = "Askey CPH06X TView99",
859 .video_inputs = 4,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 0x551e00,
864 .muxsel = { 2, 3, 1, 0},
865 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
866 .needs_tvaudio = 1,
867 .pll = PLL_28,
868 .tuner_type = 1,
869 .tuner_addr = ADDR_UNSET,
870 .has_remote = 1,
871},{
872 .name = "Pinnacle PCTV Studio/Rave",
873 .video_inputs = 3,
874 .audio_inputs = 1,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 0x03000F,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 2, 0xd0001, 0, 0, 1},
880 .needs_tvaudio = 0,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .tuner_addr = ADDR_UNSET,
884},{
885
886/* ---- card 0x28 ---------------------------------- */
887 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
888 .video_inputs = 3,
889 .audio_inputs = 1,
890 .tuner = 0,
891 .svhs = 2,
892 .gpiomask = 7,
893 .muxsel = { 2, 3, 1, 1},
894 .audiomux = { 4, 0, 2, 3, 1},
895 .no_msp34xx = 1,
896 .needs_tvaudio = 1,
897 .tuner_type = TUNER_PHILIPS_NTSC,
898 .tuner_addr = ADDR_UNSET,
899 .pll = PLL_28,
900 .has_radio = 1,
901},{
902 .name = "AVerMedia TVPhone 98",
903 .video_inputs = 3,
904 .audio_inputs = 4,
905 .tuner = 0,
906 .svhs = 2,
907 .gpiomask = 15,
908 .muxsel = { 2, 3, 1, 1},
909 .audiomux = { 13, 4, 11, 7, 0, 0},
910 .needs_tvaudio = 1,
911 .pll = PLL_28,
912 .tuner_type = -1,
913 .tuner_addr = ADDR_UNSET,
914 .has_radio = 1,
915 .audio_hook = avermedia_tvphone_audio,
916},{
917 .name = "ProVideo PV951", /* pic16c54 */
918 .video_inputs = 3,
919 .audio_inputs = 1,
920 .tuner = 0,
921 .svhs = 2,
922 .gpiomask = 0,
923 .muxsel = { 2, 3, 1, 1},
924 .audiomux = { 0, 0, 0, 0, 0},
925 .needs_tvaudio = 1,
926 .no_msp34xx = 1,
927 .pll = PLL_28,
928 .tuner_type = 1,
929 .tuner_addr = ADDR_UNSET,
930},{
931 .name = "Little OnAir TV",
932 .video_inputs = 3,
933 .audio_inputs = 1,
934 .tuner = 0,
935 .svhs = 2,
936 .gpiomask = 0xe00b,
937 .muxsel = {2, 3, 1, 1},
938 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
939 .no_msp34xx = 1,
940 .tuner_type = -1,
941 .tuner_addr = ADDR_UNSET,
942},{
943
944/* ---- card 0x2c ---------------------------------- */
945 .name = "Sigma TVII-FM",
946 .video_inputs = 2,
947 .audio_inputs = 1,
948 .tuner = 0,
949 .svhs = -1,
950 .gpiomask = 3,
951 .muxsel = {2, 3, 1, 1},
952 .audiomux = {1, 1, 0, 2, 3},
953 .no_msp34xx = 1,
954 .pll = PLL_NONE,
955 .tuner_type = -1,
956 .tuner_addr = ADDR_UNSET,
957},{
958 .name = "MATRIX-Vision MV-Delta 2",
959 .video_inputs = 5,
960 .audio_inputs = 1,
961 .tuner = -1,
962 .svhs = 3,
963 .gpiomask = 0,
964 .muxsel = { 2, 3, 1, 0, 0},
965 .audiomux = {0 },
966 .no_msp34xx = 1,
967 .pll = PLL_28,
968 .tuner_type = -1,
969 .tuner_addr = ADDR_UNSET,
970},{
971 .name = "Zoltrix Genie TV/FM",
972 .video_inputs = 3,
973 .audio_inputs = 1,
974 .tuner = 0,
975 .svhs = 2,
976 .gpiomask = 0xbcf03f,
977 .muxsel = { 2, 3, 1, 1},
978 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
979 .no_msp34xx = 1,
980 .pll = PLL_28,
981 .tuner_type = 21,
982 .tuner_addr = ADDR_UNSET,
983},{
984 .name = "Terratec TV/Radio+",
985 .video_inputs = 3,
986 .audio_inputs = 1,
987 .tuner = 0,
988 .svhs = 2,
989 .gpiomask = 0x70000,
990 .muxsel = { 2, 3, 1, 1},
991 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
992 .needs_tvaudio = 1,
993 .no_msp34xx = 1,
994 .pll = PLL_35,
995 .tuner_type = 1,
996 .tuner_addr = ADDR_UNSET,
997 .has_radio = 1,
998},{
999
1000/* ---- card 0x30 ---------------------------------- */
1001 .name = "Askey CPH03x/ Dynalink Magic TView",
1002 .video_inputs = 3,
1003 .audio_inputs = 1,
1004 .tuner = 0,
1005 .svhs = 2,
1006 .gpiomask = 15,
1007 .muxsel = { 2, 3, 1, 1},
1008 .audiomux = {2,0,0,0,1},
1009 .needs_tvaudio = 1,
1010 .pll = PLL_28,
1011 .tuner_type = -1,
1012 .tuner_addr = ADDR_UNSET,
1013},{
1014 .name = "IODATA GV-BCTV3/PCI",
1015 .video_inputs = 3,
1016 .audio_inputs = 1,
1017 .tuner = 0,
1018 .svhs = 2,
1019 .gpiomask = 0x010f00,
1020 .muxsel = {2, 3, 0, 0},
1021 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1022 .no_msp34xx = 1,
1023 .pll = PLL_28,
1024 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1025 .tuner_addr = ADDR_UNSET,
1026 .audio_hook = gvbctv3pci_audio,
1027},{
1028 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1029 .video_inputs = 5,
1030 .audio_inputs = 1,
1031 .tuner = 0,
1032 .svhs = 3,
1033 .gpiomask = 0xAA0000,
1034 .muxsel = { 2,3,1,1,-1 },
1035 .digital_mode = DIGITAL_MODE_CAMERA,
1036 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1037 .no_msp34xx = 1,
1038 .pll = PLL_28,
1039 .tuner_type = TUNER_PHILIPS_PAL_I,
1040 .tuner_addr = ADDR_UNSET,
1041 .has_remote = 1,
1042 /* GPIO wiring: (different from Rev.4C !)
1043 GPIO17: U4.A0 (first hef4052bt)
1044 GPIO19: U4.A1
1045 GPIO20: U5.A1 (second hef4052bt)
1046 GPIO21: U4.nEN
1047 GPIO22: BT832 Reset Line
1048 GPIO23: A5,A0, U5,nEN
1049 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1050 */
1051},{
1052 .name = "Eagle Wireless Capricorn2 (bt878A)",
1053 .video_inputs = 4,
1054 .audio_inputs = 1,
1055 .tuner = 0,
1056 .svhs = 2,
1057 .gpiomask = 7,
1058 .muxsel = { 2, 0, 1, 1},
1059 .audiomux = { 0, 1, 2, 3, 4},
1060 .pll = PLL_28,
1061 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1062 .tuner_addr = ADDR_UNSET,
1063},{
1064
1065/* ---- card 0x34 ---------------------------------- */
1066 /* David Härdeman <david@2gen.com> */
1067 .name = "Pinnacle PCTV Studio Pro",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 3,
1072 .gpiomask = 0x03000F,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 1, 0xd0001, 0, 0, 10},
1075 /* sound path (5 sources):
1076 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1077 0= ext. Audio IN
1078 1= from MUX2
1079 2= Mono TV sound from Tuner
1080 3= not connected
1081 MUX2 (mask 0x30000):
1082 0,2,3= from MSP34xx
1083 1= FM stereo Radio from Tuner */
1084 .needs_tvaudio = 0,
1085 .pll = PLL_28,
1086 .tuner_type = -1,
1087 .tuner_addr = ADDR_UNSET,
1088},{
1089 /* Claas Langbehn <claas@bigfoot.com>,
1090 Sven Grothklags <sven@upb.de> */
1091 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1092 .video_inputs = 4,
1093 .audio_inputs = 3,
1094 .tuner = 0,
1095 .svhs = 2,
1096 .gpiomask = 0x1c,
1097 .muxsel = { 2, 3, 1, 1},
1098 .audiomux = { 0, 0, 0x10, 8, 4 },
1099 .needs_tvaudio = 1,
1100 .pll = PLL_28,
1101 .tuner_type = TUNER_PHILIPS_PAL,
1102 .tuner_addr = ADDR_UNSET,
1103 .has_radio = 1,
1104},{
1105 /* Tim Röstermundt <rosterm@uni-muenster.de>
1106 in de.comp.os.unix.linux.hardware:
1107 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1108 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1109 options tuner type=5 */
1110 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1111 .video_inputs = 4,
1112 .audio_inputs = 1,
1113 .tuner = 0,
1114 .svhs = 2,
1115 .gpiomask = 0x18e0,
1116 .muxsel = { 2, 3, 1, 1},
1117 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1118 /* For cards with tda9820/tda9821:
1119 0x0000: Tuner normal stereo
1120 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1121 0x0880: Tuner A2 stereo */
1122 .pll = PLL_28,
1123 .tuner_type = -1,
1124 .tuner_addr = ADDR_UNSET,
1125},{
1126 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1127 old Easy TV BT848 version (model CPH031) */
1128 .name = "Askey CPH031/ BESTBUY Easy TV",
1129 .video_inputs = 4,
1130 .audio_inputs = 1,
1131 .tuner = 0,
1132 .svhs = 2,
1133 .gpiomask = 0xF,
1134 .muxsel = { 2, 3, 1, 0},
1135 .audiomux = { 2, 0, 0, 0, 10},
1136 .needs_tvaudio = 0,
1137 .pll = PLL_28,
1138 .tuner_type = TUNER_TEMIC_PAL,
1139 .tuner_addr = ADDR_UNSET,
1140},{
1141
1142/* ---- card 0x38 ---------------------------------- */
1143 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1144 .name = "Lifeview FlyVideo 98FM LR50",
1145 .video_inputs = 4,
1146 .audio_inputs = 3,
1147 .tuner = 0,
1148 .svhs = 2,
1149 .gpiomask = 0x1800,
1150 .muxsel = { 2, 3, 1, 1},
1151 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1152 .pll = PLL_28,
1153 .tuner_type = 5,
1154 .tuner_addr = ADDR_UNSET,
1155},{
1156 /* This is the ultimate cheapo capture card
1157 * just a BT848A on a small PCB!
1158 * Steve Hosgood <steve@equiinet.com> */
1159 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1160 .video_inputs = 2,
1161 .audio_inputs = 0,
1162 .tuner = -1,
1163 .svhs = 1,
1164 .gpiomask = 0,
1165 .muxsel = { 3, 1 },
1166 .audiomux = { 0 },
1167 .needs_tvaudio = 0,
1168 .no_msp34xx = 1,
1169 .pll = PLL_35,
1170 .tuner_type = -1,
1171 .tuner_addr = ADDR_UNSET,
1172},{
1173 /* Daniel Herrington <daniel.herrington@home.com> */
1174 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1175 .video_inputs = 3,
1176 .audio_inputs = 1,
1177 .tuner = 0,
1178 .svhs = 2,
1179 .gpiomask = 0xe00,
1180 .muxsel = { 2, 3, 1, 1},
1181 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1182 .needs_tvaudio = 1,
1183 .pll = PLL_28,
1184 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1185 .tuner_addr = ADDR_UNSET,
1186},{
1187 /* Matti Mottus <mottus@physic.ut.ee> */
1188 .name = "Askey CPH03x TV Capturer",
1189 .video_inputs = 4,
1190 .audio_inputs = 1,
1191 .tuner = 0,
1192 .svhs = 2,
1193 .gpiomask = 0x03000F,
1194 .muxsel = { 2, 3, 1, 0},
1195 .audiomux = { 2,0,0,0,1 },
1196 .pll = PLL_28,
1197 .tuner_type = 0,
1198 .tuner_addr = ADDR_UNSET,
1199},{
1200
1201/* ---- card 0x3c ---------------------------------- */
1202 /* Philip Blundell <philb@gnu.org> */
1203 .name = "Modular Technology MM100PCTV",
1204 .video_inputs = 2,
1205 .audio_inputs = 2,
1206 .tuner = 0,
1207 .svhs = -1,
1208 .gpiomask = 11,
1209 .muxsel = { 2, 3, 1, 1},
1210 .audiomux = { 2, 0, 0, 1, 8},
1211 .pll = PLL_35,
1212 .tuner_type = TUNER_TEMIC_PAL,
1213 .tuner_addr = ADDR_UNSET,
1214},{
1215 /* Adrian Cox <adrian@humboldt.co.uk */
1216 .name = "AG Electronics GMV1",
1217 .video_inputs = 2,
1218 .audio_inputs = 0,
1219 .tuner = -1,
1220 .svhs = 1,
1221 .gpiomask = 0xF,
1222 .muxsel = { 2, 2},
1223 .audiomux = { },
1224 .no_msp34xx = 1,
1225 .needs_tvaudio = 0,
1226 .pll = PLL_28,
1227 .tuner_type = -1,
1228 .tuner_addr = ADDR_UNSET,
1229},{
1230 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1231 new Easy TV BT878 version (model CPH061)
1232 special thanks to Informatica Mieres for providing the card */
1233 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1234 .video_inputs = 3,
1235 .audio_inputs = 2,
1236 .tuner = 0,
1237 .svhs = 2,
1238 .gpiomask = 0xFF,
1239 .muxsel = { 2, 3, 1, 0},
1240 .audiomux = { 1, 0, 4, 4, 9},
1241 .needs_tvaudio = 0,
1242 .pll = PLL_28,
1243 .tuner_type = TUNER_PHILIPS_PAL,
1244 .tuner_addr = ADDR_UNSET,
1245},{
1246 /* Lukas Gebauer <geby@volny.cz> */
1247 .name = "ATI TV-Wonder",
1248 .video_inputs = 3,
1249 .audio_inputs = 1,
1250 .tuner = 0,
1251 .svhs = 2,
1252 .gpiomask = 0xf03f,
1253 .muxsel = { 2, 3, 1, 0 },
1254 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1255 .pll = PLL_28,
1256 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1257 .tuner_addr = ADDR_UNSET,
1258},{
1259
1260/* ---- card 0x40 ---------------------------------- */
1261 /* Lukas Gebauer <geby@volny.cz> */
1262 .name = "ATI TV-Wonder VE",
1263 .video_inputs = 2,
1264 .audio_inputs = 1,
1265 .tuner = 0,
1266 .svhs = -1,
1267 .gpiomask = 1,
1268 .muxsel = { 2, 3, 0, 1},
1269 .audiomux = { 0, 0, 1, 0, 0},
1270 .no_msp34xx = 1,
1271 .pll = PLL_28,
1272 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1273 .tuner_addr = ADDR_UNSET,
1274},{
1275 /* DeeJay <deejay@westel900.net (2000S) */
1276 .name = "Lifeview FlyVideo 2000S LR90",
1277 .video_inputs = 3,
1278 .audio_inputs = 3,
1279 .tuner = 0,
1280 .svhs = 2,
1281 .gpiomask = 0x18e0,
1282 .muxsel = { 2, 3, 0, 1},
1283 /* Radio changed from 1e80 to 0x800 to make
1284 FlyVideo2000S in .hu happy (gm)*/
1285 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1286 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1287 .audio_hook = fv2000s_audio,
1288 .no_msp34xx = 1,
1289 .no_tda9875 = 1,
1290 .needs_tvaudio = 1,
1291 .pll = PLL_28,
1292 .tuner_type = 5,
1293 .tuner_addr = ADDR_UNSET,
1294},{
1295 .name = "Terratec TValueRadio",
1296 .video_inputs = 3,
1297 .audio_inputs = 1,
1298 .tuner = 0,
1299 .svhs = 2,
1300 .gpiomask = 0xffff00,
1301 .muxsel = { 2, 3, 1, 1},
1302 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1303 .needs_tvaudio = 1,
1304 .pll = PLL_28,
1305 .tuner_type = TUNER_PHILIPS_PAL,
1306 .tuner_addr = ADDR_UNSET,
1307 .has_radio = 1,
1308},{
1309 /* TANAKA Kei <peg00625@nifty.com> */
1310 .name = "IODATA GV-BCTV4/PCI",
1311 .video_inputs = 3,
1312 .audio_inputs = 1,
1313 .tuner = 0,
1314 .svhs = 2,
1315 .gpiomask = 0x010f00,
1316 .muxsel = {2, 3, 0, 0},
1317 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1318 .no_msp34xx = 1,
1319 .pll = PLL_28,
1320 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1321 .tuner_addr = ADDR_UNSET,
1322 .audio_hook = gvbctv3pci_audio,
1323},{
1324
1325/* ---- card 0x44 ---------------------------------- */
1326 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1327 /* try "insmod msp3400 simple=0" if you have
1328 * sound problems with this card. */
1329 .video_inputs = 4,
1330 .audio_inputs = 1,
1331 .tuner = 0,
1332 .svhs = -1,
1333 .gpiomask = 0x4f8a00,
1334 /* 0x100000: 1=MSP enabled (0=disable again)
1335 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1336 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1337 /* tvtuner, radio, external,internal, mute, stereo
1338 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1339 .muxsel = { 2, 3 ,0 ,1},
1340 .tuner_type = TUNER_MT2032,
1341 .tuner_addr = ADDR_UNSET,
1342 .pll = PLL_28,
1343 .has_radio = 1,
1344},{
1345 /* Philip Blundell <pb@nexus.co.uk> */
1346 .name = "Active Imaging AIMMS",
1347 .video_inputs = 1,
1348 .audio_inputs = 0,
1349 .tuner = -1,
1350 .tuner_type = -1,
1351 .tuner_addr = ADDR_UNSET,
1352 .pll = PLL_28,
1353 .muxsel = { 2 },
1354 .gpiomask = 0
1355},{
1356 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1357 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1358 .video_inputs = 3,
1359 .audio_inputs = 4,
1360 .tuner = 0,
1361 .svhs = 2,
1362 .gpiomask = 15,
1363 .muxsel = { 2, 3, 1, 1},
1364 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
1365 .needs_tvaudio = 1,
1366 .pll = PLL_28,
1367 .tuner_type = 25,
1368 .tuner_addr = ADDR_UNSET,
1369 .has_remote = 1,
1370 /* GPIO wiring:
1371 GPIO0: U4.A0 (hef4052bt)
1372 GPIO1: U4.A1
1373 GPIO2: U4.A1 (second hef4052bt)
1374 GPIO3: U4.nEN, U5.A0, A5.nEN
1375 GPIO8-15: vrd866b ?
1376 */ 784 */
1377},{ 785
1378 .name = "Lifeview FlyVideo 98EZ (capture only) LR51", 786 },
1379 .video_inputs = 4, 787 [BTTV_BOARD_PXC200] = {
1380 .audio_inputs = 0, 788 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
1381 .tuner = -1, 789 .name = "Imagenation PXC200",
1382 .svhs = 2, 790 .video_inputs = 5,
1383 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ 791 .audio_inputs = 1,
1384 .pll = PLL_28, 792 .tuner = -1,
1385 .no_msp34xx = 1, 793 .svhs = 1, /* was: 4 */
1386 .tuner_type = UNSET, 794 .gpiomask = 0,
1387 .tuner_addr = ADDR_UNSET, 795 .muxsel = { 2, 3, 1, 0, 0},
1388},{ 796 .audiomux = { 0 },
1389 797 .needs_tvaudio = 1,
1390/* ---- card 0x48 ---------------------------------- */ 798 .tuner_type = -1,
1391 /* Dariusz Kowalewski <darekk@automex.pl> */ 799 .tuner_addr = ADDR_UNSET,
1392 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", 800 .radio_addr = ADDR_UNSET,
1393 .video_inputs = 4, 801 .muxsel_hook = PXC200_muxsel,
1394 .audio_inputs = 1, 802
1395 .tuner = 0, 803 },
1396 .svhs = 2, 804 [BTTV_BOARD_FLYVIDEO_98] = {
1397 .gpiomask = 0x3f, 805 .name = "Lifeview FlyVideo 98 LR50",
1398 .muxsel = { 2, 3, 1, 1 }, 806 .video_inputs = 4,
1399 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, 807 .audio_inputs = 1,
1400 .needs_tvaudio = 1, 808 .tuner = 0,
1401 .no_msp34xx = 1, 809 .svhs = 2,
1402 .no_tda9875 = 1, 810 .gpiomask = 0x1800, /* 0x8dfe00 */
1403 .pll = PLL_28, 811 .muxsel = { 2, 3, 1, 1},
1404 .tuner_type = 5, 812 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
1405 .tuner_addr = ADDR_UNSET, 813 .pll = PLL_28,
1406 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ 814 .tuner_type = -1,
1407 .has_radio = 1, /* Note: not all cards have radio */ 815 .tuner_addr = ADDR_UNSET,
1408 .has_remote = 1, 816 .radio_addr = ADDR_UNSET,
1409 /* GPIO wiring: 817 },
1410 GPIO0: A0 hef4052 818 [BTTV_BOARD_IPROTV] = {
1411 GPIO1: A1 hef4052 819 .name = "Formac iProTV, Formac ProTV I (bt848)",
1412 GPIO3: nEN hef4052 820 .video_inputs = 4,
1413 GPIO8-15: vrd866b 821 .audio_inputs = 1,
1414 GPIO20,22,23: R30,R29,R28 822 .tuner = 0,
1415 */ 823 .svhs = 3,
1416},{ 824 .gpiomask = 1,
1417 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ 825 .muxsel = { 2, 3, 1, 1},
1418 /* you must jumper JP5 for the card to work */ 826 .audiomux = { 1, 0, 0, 0, 0 },
1419 .name = "Sensoray 311", 827 .pll = PLL_28,
1420 .video_inputs = 5, 828 .tuner_type = TUNER_PHILIPS_PAL,
1421 .audio_inputs = 0, 829 .tuner_addr = ADDR_UNSET,
1422 .tuner = -1, 830 .radio_addr = ADDR_UNSET,
1423 .svhs = 4, 831 },
1424 .gpiomask = 0, 832
1425 .muxsel = { 2, 3, 1, 0, 0}, 833 /* ---- card 0x20 ---------------------------------- */
1426 .audiomux = { 0 }, 834 [BTTV_BOARD_INTEL_C_S_PCI] = {
1427 .needs_tvaudio = 0, 835 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
1428 .tuner_type = -1, 836 .video_inputs = 4,
1429 .tuner_addr = ADDR_UNSET, 837 .audio_inputs = 0,
1430},{ 838 .tuner = -1,
1431 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ 839 .svhs = 2,
1432 .name = "RemoteVision MX (RV605)", 840 .gpiomask = 0,
1433 .video_inputs = 16, 841 .muxsel = { 2, 3, 1, 1},
1434 .audio_inputs = 0, 842 .audiomux = { 0 },
1435 .tuner = -1, 843 .needs_tvaudio = 0,
1436 .svhs = -1, 844 .tuner_type = 4,
1437 .gpiomask = 0x00, 845 .tuner_addr = ADDR_UNSET,
1438 .gpiomask2 = 0x07ff, 846 .radio_addr = ADDR_UNSET,
1439 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 847 },
1440 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, 848 [BTTV_BOARD_TERRATVALUE] = {
1441 .no_msp34xx = 1, 849 .name = "Terratec TerraTValue Version Bt878",
1442 .no_tda9875 = 1, 850 .video_inputs = 3,
1443 .tuner_type = -1, 851 .audio_inputs = 1,
1444 .tuner_addr = ADDR_UNSET, 852 .tuner = 0,
1445 .muxsel_hook = rv605_muxsel, 853 .svhs = 2,
1446},{ 854 .gpiomask = 0xffff00,
1447 .name = "Powercolor MTV878/ MTV878R/ MTV878F", 855 .muxsel = { 2, 3, 1, 1},
1448 .video_inputs = 3, 856 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
1449 .audio_inputs = 2, 857 .needs_tvaudio = 1,
1450 .tuner = 0, 858 .pll = PLL_28,
1451 .svhs = 2, 859 .tuner_type = TUNER_PHILIPS_PAL,
1452 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ 860 .tuner_addr = ADDR_UNSET,
1453 .muxsel = { 2, 1, 1, }, 861 .radio_addr = ADDR_UNSET,
1454 .audiomux = { 0, 1, 2, 2, 4 }, 862 },
1455 .needs_tvaudio = 0, 863 [BTTV_BOARD_WINFAST2000] = {
1456 .tuner_type = TUNER_PHILIPS_PAL, 864 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
1457 .tuner_addr = ADDR_UNSET, 865 .video_inputs = 4,
1458 .pll = PLL_28, 866 .audio_inputs = 1,
1459 .has_radio = 1, 867 .tuner = 0,
1460},{ 868 .svhs = 2,
1461 869 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
1462/* ---- card 0x4c ---------------------------------- */ 870 #if 0
1463 /* Masaki Suzuki <masaki@btree.org> */ 871 .gpiomask = 0xc33000,
1464 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", 872 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
1465 .video_inputs = 3, 873 #else
1466 .audio_inputs = 1, 874 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
1467 .tuner = 0, 875 .gpiomask = 0xb33000,
1468 .svhs = 2, 876 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
1469 .gpiomask = 0x140007, 877 #endif
1470 .muxsel = { 2, 3, 1, 1 }, 878 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
1471 .audiomux = { 0, 1, 2, 3, 4, 0 }, 879 gpio23 -- hef4052:nEnable (0x800000)
1472 .tuner_type = TUNER_PHILIPS_NTSC, 880 gpio12 -- hef4052:A1
1473 .tuner_addr = ADDR_UNSET, 881 gpio13 -- hef4052:A0
1474 .audio_hook = windvr_audio, 882 0x0000: external audio
1475},{ 883 0x1000: FM
1476 .name = "GrandTec Multi Capture Card (Bt878)", 884 0x2000: TV
1477 .video_inputs = 4, 885 0x3000: n.c.
1478 .audio_inputs = 0, 886 Note: There exists another variant "Winfast 2000" with tv stereo !?
1479 .tuner = -1, 887 Note: eeprom only contains FF and pci subsystem id 107d:6606
1480 .svhs = -1, 888 */
1481 .gpiomask = 0, 889 .needs_tvaudio = 0,
1482 .muxsel = { 2, 3, 1, 0 }, 890 .pll = PLL_28,
1483 .audiomux = { 0 }, 891 .has_radio = 1,
1484 .needs_tvaudio = 0, 892 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
1485 .no_msp34xx = 1, 893 .tuner_addr = ADDR_UNSET,
1486 .pll = PLL_28, 894 .radio_addr = ADDR_UNSET,
1487 .tuner_type = -1, 895 .audio_hook = winfast2000_audio,
1488 .tuner_addr = ADDR_UNSET, 896 .has_remote = 1,
1489},{ 897 },
1490 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", 898 [BTTV_BOARD_CHRONOS_VS2] = {
1491 .video_inputs = 4, 899 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
1492 .audio_inputs = 3, 900 .video_inputs = 4,
1493 .tuner = 0, 901 .audio_inputs = 3,
1494 .svhs = 2, 902 .tuner = 0,
1495 .gpiomask = 7, 903 .svhs = 2,
1496 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ 904 .gpiomask = 0x1800,
1497 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! 905 .muxsel = { 2, 3, 1, 1},
1498 * This card lacks external Audio In, so we mute it on Ext. & Int. 906 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
1499 * The PCB can take a sbx1637/sbx1673, wiring unknown. 907 .pll = PLL_28,
1500 * This card lacks PCI subsystem ID, sigh. 908 .tuner_type = -1,
1501 * audiomux=1: lower volume, 2+3: mute 909 .tuner_addr = ADDR_UNSET,
1502 * btwincap uses 0x80000/0x80003 910 .radio_addr = ADDR_UNSET,
1503 */ 911 },
1504 .needs_tvaudio = 0, 912
1505 .no_msp34xx = 1, 913 /* ---- card 0x24 ---------------------------------- */
1506 .pll = PLL_28, 914 [BTTV_BOARD_TYPHOON_TVIEW] = {
1507 .tuner_type = 5, 915 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
1508 .tuner_addr = ADDR_UNSET, 916 .video_inputs = 4,
1509 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and 917 .audio_inputs = 3,
1510 radio signal strength indicators work fine. */ 918 .tuner = 0,
1511 .has_radio = 1, 919 .svhs = 2,
1512 /* GPIO Info: 920 .gpiomask = 0x1800,
1513 GPIO0,1: HEF4052 A0,A1 921 .muxsel = { 2, 3, 1, 1},
1514 GPIO2: HEF4052 nENABLE 922 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1515 GPIO3-7: n.c. 923 .pll = PLL_28,
1516 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] 924 .tuner_type = -1,
1517 GPIO14,15: ?? 925 .tuner_addr = ADDR_UNSET,
1518 GPIO16-21: n.c. 926 .radio_addr = ADDR_UNSET,
1519 GPIO22,23: ?? 927 .has_radio = 1,
1520 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ 928 },
1521},{ 929 [BTTV_BOARD_PXELVWPLTVPRO] = {
1522 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ 930 .name = "Prolink PixelView PlayTV pro",
1523 .name = "DSP Design TCVIDEO", 931 .video_inputs = 3,
1524 .video_inputs = 4, 932 .audio_inputs = 1,
1525 .svhs = -1, 933 .tuner = 0,
1526 .muxsel = { 2, 3, 1, 0}, 934 .svhs = 2,
1527 .pll = PLL_28, 935 .gpiomask = 0xff,
1528 .tuner_type = -1, 936 .muxsel = { 2, 3, 1, 1 },
1529 .tuner_addr = ADDR_UNSET, 937 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
1530},{ 938 .no_msp34xx = 1,
1531 939 .pll = PLL_28,
1532 /* ---- card 0x50 ---------------------------------- */ 940 .tuner_type = -1,
1533 .name = "Hauppauge WinTV PVR", 941 .tuner_addr = ADDR_UNSET,
1534 .video_inputs = 4, 942 .radio_addr = ADDR_UNSET,
1535 .audio_inputs = 1, 943 },
1536 .tuner = 0, 944 [BTTV_BOARD_MAGICTVIEW063] = {
1537 .svhs = 2, 945 .name = "Askey CPH06X TView99",
1538 .muxsel = { 2, 0, 1, 1}, 946 .video_inputs = 4,
1539 .needs_tvaudio = 1, 947 .audio_inputs = 1,
1540 .pll = PLL_28, 948 .tuner = 0,
1541 .tuner_type = -1, 949 .svhs = 2,
1542 .tuner_addr = ADDR_UNSET, 950 .gpiomask = 0x551e00,
1543 951 .muxsel = { 2, 3, 1, 0},
1544 .gpiomask = 7, 952 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
1545 .audiomux = {7}, 953 .needs_tvaudio = 1,
1546},{ 954 .pll = PLL_28,
1547 .name = "IODATA GV-BCTV5/PCI", 955 .tuner_type = 1,
1548 .video_inputs = 3, 956 .tuner_addr = ADDR_UNSET,
1549 .audio_inputs = 1, 957 .radio_addr = ADDR_UNSET,
1550 .tuner = 0, 958 .has_remote = 1,
1551 .svhs = 2, 959 },
1552 .gpiomask = 0x0f0f80, 960 [BTTV_BOARD_PINNACLE] = {
1553 .muxsel = {2, 3, 1, 0}, 961 .name = "Pinnacle PCTV Studio/Rave",
1554 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, 962 .video_inputs = 3,
1555 .no_msp34xx = 1, 963 .audio_inputs = 1,
1556 .pll = PLL_28, 964 .tuner = 0,
1557 .tuner_type = TUNER_PHILIPS_NTSC_M, 965 .svhs = 2,
1558 .tuner_addr = ADDR_UNSET, 966 .gpiomask = 0x03000F,
1559 .audio_hook = gvbctv5pci_audio, 967 .muxsel = { 2, 3, 1, 1},
1560 .has_radio = 1, 968 .audiomux = { 2, 0xd0001, 0, 0, 1},
1561},{ 969 .needs_tvaudio = 0,
1562 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ 970 .pll = PLL_28,
1563 .video_inputs = 4, /* id-inputs-clock */ 971 .tuner_type = -1,
1564 .audio_inputs = 0, 972 .tuner_addr = ADDR_UNSET,
1565 .tuner = -1, 973 .radio_addr = ADDR_UNSET,
1566 .svhs = 3, 974 },
1567 .muxsel = { 3, 2, 0, 1 }, 975
1568 .pll = PLL_28, 976 /* ---- card 0x28 ---------------------------------- */
1569 .tuner_type = -1, 977 [BTTV_BOARD_STB2] = {
1570 .tuner_addr = ADDR_UNSET, 978 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
1571 .no_msp34xx = 1, 979 .video_inputs = 3,
1572 .no_tda9875 = 1, 980 .audio_inputs = 1,
1573 .no_tda7432 = 1, 981 .tuner = 0,
1574},{ 982 .svhs = 2,
1575 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ 983 .gpiomask = 7,
1576 .video_inputs = 3, 984 .muxsel = { 2, 3, 1, 1},
1577 .audio_inputs = 0, 985 .audiomux = { 4, 0, 2, 3, 1},
1578 .tuner = -1, 986 .no_msp34xx = 1,
1579 .svhs = 2, 987 .needs_tvaudio = 1,
1580 .muxsel = { 2, 3, 1 }, 988 .tuner_type = TUNER_PHILIPS_NTSC,
1581 .pll = PLL_28, 989 .tuner_addr = ADDR_UNSET,
1582 .tuner_type = -1, 990 .radio_addr = ADDR_UNSET,
1583 .tuner_addr = ADDR_UNSET, 991 .pll = PLL_28,
1584 .no_msp34xx = 1, 992 .has_radio = 1,
1585 .no_tda9875 = 1, 993 },
1586 .no_tda7432 = 1, 994 [BTTV_BOARD_AVPHONE98] = {
1587},{ 995 .name = "AVerMedia TVPhone 98",
1588 996 .video_inputs = 3,
1589 /* ---- card 0x54 ---------------------------------- */ 997 .audio_inputs = 4,
1590 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ 998 .tuner = 0,
1591 .video_inputs = 2, 999 .svhs = 2,
1592 .audio_inputs = 0, 1000 .gpiomask = 15,
1593 .tuner = -1, 1001 .muxsel = { 2, 3, 1, 1},
1594 .svhs = 1, 1002 .audiomux = { 13, 4, 11, 7, 0, 0},
1595 .muxsel = { 3, 1 }, 1003 .needs_tvaudio = 1,
1596 .pll = PLL_28, 1004 .pll = PLL_28,
1597 .tuner_type = -1, 1005 .tuner_type = -1,
1598 .tuner_addr = ADDR_UNSET, 1006 .tuner_addr = ADDR_UNSET,
1599 .no_msp34xx = 1, 1007 .radio_addr = ADDR_UNSET,
1600 .no_tda9875 = 1, 1008 .has_radio = 1,
1601 .no_tda7432 = 1, 1009 .audio_hook = avermedia_tvphone_audio,
1602},{ 1010 },
1603 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ 1011 [BTTV_BOARD_PV951] = {
1604 .video_inputs = 1, 1012 .name = "ProVideo PV951", /* pic16c54 */
1605 .audio_inputs = 0, 1013 .video_inputs = 3,
1606 .tuner = -1, 1014 .audio_inputs = 1,
1607 .svhs = -1, 1015 .tuner = 0,
1608 .muxsel = { 0 }, 1016 .svhs = 2,
1609 .pll = PLL_28, 1017 .gpiomask = 0,
1610 .tuner_type = -1, 1018 .muxsel = { 2, 3, 1, 1},
1611 .tuner_addr = ADDR_UNSET, 1019 .audiomux = { 0, 0, 0, 0, 0},
1612 .no_msp34xx = 1, 1020 .needs_tvaudio = 1,
1613 .no_tda9875 = 1, 1021 .no_msp34xx = 1,
1614 .no_tda7432 = 1, 1022 .pll = PLL_28,
1615},{ 1023 .tuner_type = 1,
1616 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ 1024 .tuner_addr = ADDR_UNSET,
1617 .video_inputs = 2, 1025 .radio_addr = ADDR_UNSET,
1618 .audio_inputs = 0, 1026 },
1619 .tuner = -1, 1027 [BTTV_BOARD_ONAIR_TV] = {
1620 .svhs = 1, 1028 .name = "Little OnAir TV",
1621 .muxsel = { 0, 1 }, 1029 .video_inputs = 3,
1622 .pll = PLL_28, 1030 .audio_inputs = 1,
1623 .tuner_type = -1, 1031 .tuner = 0,
1624 .tuner_addr = ADDR_UNSET, 1032 .svhs = 2,
1625 .no_msp34xx = 1, 1033 .gpiomask = 0xe00b,
1626 .no_tda9875 = 1, 1034 .muxsel = {2, 3, 1, 1},
1627 .no_tda7432 = 1, 1035 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
1628},{ 1036 .no_msp34xx = 1,
1629 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ 1037 .tuner_type = -1,
1630 .video_inputs = 1, 1038 .tuner_addr = ADDR_UNSET,
1631 .audio_inputs = 1, 1039 .radio_addr = ADDR_UNSET,
1632 .tuner = -1, 1040 },
1633 .svhs = -1, 1041
1634 .muxsel = { 0 }, 1042 /* ---- card 0x2c ---------------------------------- */
1635 .pll = PLL_28, 1043 [BTTV_BOARD_SIGMA_TVII_FM] = {
1636 .tuner_type = UNSET, 1044 .name = "Sigma TVII-FM",
1637 .tuner_addr = ADDR_UNSET, 1045 .video_inputs = 2,
1638 .no_msp34xx = 1, 1046 .audio_inputs = 1,
1639 .no_tda9875 = 1, 1047 .tuner = 0,
1640 .no_tda7432 = 1, 1048 .svhs = -1,
1641},{ 1049 .gpiomask = 3,
1642 1050 .muxsel = {2, 3, 1, 1},
1643 /* ---- card 0x58 ---------------------------------- */ 1051 .audiomux = {1, 1, 0, 2, 3},
1644 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ 1052 .no_msp34xx = 1,
1645 .video_inputs = 2, 1053 .pll = PLL_NONE,
1646 .audio_inputs = 1, 1054 .tuner_type = -1,
1647 .tuner = -1, 1055 .tuner_addr = ADDR_UNSET,
1648 .svhs = 1, 1056 .radio_addr = ADDR_UNSET,
1649 .muxsel = { 0, 1 }, 1057 },
1650 .pll = PLL_28, 1058 [BTTV_BOARD_MATRIX_VISION2] = {
1651 .tuner_type = UNSET, 1059 .name = "MATRIX-Vision MV-Delta 2",
1652 .tuner_addr = ADDR_UNSET, 1060 .video_inputs = 5,
1653 .no_msp34xx = 1, 1061 .audio_inputs = 1,
1654 .no_tda9875 = 1, 1062 .tuner = -1,
1655 .no_tda7432 = 1, 1063 .svhs = 3,
1656},{ 1064 .gpiomask = 0,
1657 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1065 .muxsel = { 2, 3, 1, 0, 0},
1658 .video_inputs = 2, 1066 .audiomux = {0 },
1659 .audio_inputs = 1, 1067 .no_msp34xx = 1,
1660 .tuner = -1, 1068 .pll = PLL_28,
1661 .svhs = 1, 1069 .tuner_type = -1,
1662 .muxsel = { 2, 3 }, 1070 .tuner_addr = ADDR_UNSET,
1663 .pll = PLL_28, 1071 .radio_addr = ADDR_UNSET,
1664 .tuner_type = UNSET, 1072 },
1665 .tuner_addr = ADDR_UNSET, 1073 [BTTV_BOARD_ZOLTRIX_GENIE] = {
1666 .no_msp34xx = 1, 1074 .name = "Zoltrix Genie TV/FM",
1667 .no_tda9875 = 1, 1075 .video_inputs = 3,
1668 .no_tda7432 = 1, 1076 .audio_inputs = 1,
1669},{ 1077 .tuner = 0,
1670 .name = "Osprey 500", /* 500 */ 1078 .svhs = 2,
1671 .video_inputs = 2, 1079 .gpiomask = 0xbcf03f,
1672 .audio_inputs = 1, 1080 .muxsel = { 2, 3, 1, 1},
1673 .tuner = -1, 1081 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
1674 .svhs = 1, 1082 .no_msp34xx = 1,
1675 .muxsel = { 2, 3 }, 1083 .pll = PLL_28,
1676 .pll = PLL_28, 1084 .tuner_type = 21,
1677 .tuner_type = -1, 1085 .tuner_addr = ADDR_UNSET,
1678 .tuner_addr = ADDR_UNSET, 1086 .radio_addr = ADDR_UNSET,
1679 .no_msp34xx = 1, 1087 },
1680 .no_tda9875 = 1, 1088 [BTTV_BOARD_TERRATVRADIO] = {
1681 .no_tda7432 = 1, 1089 .name = "Terratec TV/Radio+",
1682},{ 1090 .video_inputs = 3,
1683 .name = "Osprey 540", /* 540 */ 1091 .audio_inputs = 1,
1684 .video_inputs = 4, 1092 .tuner = 0,
1685 .audio_inputs = 1, 1093 .svhs = 2,
1686 .tuner = -1, 1094 .gpiomask = 0x70000,
1687 .pll = PLL_28, 1095 .muxsel = { 2, 3, 1, 1},
1688 .tuner_type = -1, 1096 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
1689 .tuner_addr = ADDR_UNSET, 1097 .needs_tvaudio = 1,
1690 .no_msp34xx = 1, 1098 .no_msp34xx = 1,
1691 .no_tda9875 = 1, 1099 .pll = PLL_35,
1692 .no_tda7432 = 1, 1100 .tuner_type = 1,
1693},{ 1101 .tuner_addr = ADDR_UNSET,
1694 1102 .radio_addr = ADDR_UNSET,
1695 /* ---- card 0x5C ---------------------------------- */ 1103 .has_radio = 1,
1696 .name = "Osprey 2000", /* 2000 */ 1104 },
1697 .video_inputs = 2, 1105
1698 .audio_inputs = 1, 1106 /* ---- card 0x30 ---------------------------------- */
1699 .tuner = -1, 1107 [BTTV_BOARD_DYNALINK] = {
1700 .svhs = 1, 1108 .name = "Askey CPH03x/ Dynalink Magic TView",
1701 .muxsel = { 2, 3 }, 1109 .video_inputs = 3,
1702 .pll = PLL_28, 1110 .audio_inputs = 1,
1703 .tuner_type = UNSET, 1111 .tuner = 0,
1704 .tuner_addr = ADDR_UNSET, 1112 .svhs = 2,
1705 .no_msp34xx = 1, 1113 .gpiomask = 15,
1706 .no_tda9875 = 1, 1114 .muxsel = { 2, 3, 1, 1},
1707 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ 1115 .audiomux = {2,0,0,0,1},
1708},{ 1116 .needs_tvaudio = 1,
1709 /* M G Berberich <berberic@forwiss.uni-passau.de> */ 1117 .pll = PLL_28,
1710 .name = "IDS Eagle", 1118 .tuner_type = -1,
1711 .video_inputs = 4, 1119 .tuner_addr = ADDR_UNSET,
1712 .audio_inputs = 0, 1120 .radio_addr = ADDR_UNSET,
1713 .tuner = -1, 1121 },
1714 .tuner_type = -1, 1122 [BTTV_BOARD_GVBCTV3PCI] = {
1715 .tuner_addr = ADDR_UNSET, 1123 .name = "IODATA GV-BCTV3/PCI",
1716 .svhs = -1, 1124 .video_inputs = 3,
1717 .gpiomask = 0, 1125 .audio_inputs = 1,
1718 .muxsel = { 0, 1, 2, 3 }, 1126 .tuner = 0,
1719 .muxsel_hook = eagle_muxsel, 1127 .svhs = 2,
1720 .no_msp34xx = 1, 1128 .gpiomask = 0x010f00,
1721 .no_tda9875 = 1, 1129 .muxsel = {2, 3, 0, 0},
1722 .pll = PLL_28, 1130 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1723},{ 1131 .no_msp34xx = 1,
1724 .name = "Pinnacle PCTV Sat", 1132 .pll = PLL_28,
1725 .video_inputs = 2, 1133 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1726 .audio_inputs = 0, 1134 .tuner_addr = ADDR_UNSET,
1727 .svhs = 1, 1135 .radio_addr = ADDR_UNSET,
1728 .tuner = -1, 1136 .audio_hook = gvbctv3pci_audio,
1729 .tuner_type = -1, 1137 },
1730 .tuner_addr = ADDR_UNSET, 1138 [BTTV_BOARD_PXELVWPLTVPAK] = {
1731 .no_msp34xx = 1, 1139 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1732 .no_tda9875 = 1, 1140 .video_inputs = 5,
1733 .no_tda7432 = 1, 1141 .audio_inputs = 1,
1734 .gpiomask = 0x01, 1142 .tuner = 0,
1735 .audiomux = { 0, 0, 0, 0, 1 }, 1143 .svhs = 3,
1736 .muxsel = { 3, 0, 1, 2}, 1144 .gpiomask = 0xAA0000,
1737 .needs_tvaudio = 0, 1145 .muxsel = { 2,3,1,1,-1 },
1738 .pll = PLL_28, 1146 .digital_mode = DIGITAL_MODE_CAMERA,
1739 .no_gpioirq = 1, 1147 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1740 .has_dvb = 1, 1148 .no_msp34xx = 1,
1741},{ 1149 .pll = PLL_28,
1742 .name = "Formac ProTV II (bt878)", 1150 .tuner_type = TUNER_PHILIPS_PAL_I,
1743 .video_inputs = 4, 1151 .tuner_addr = ADDR_UNSET,
1744 .audio_inputs = 1, 1152 .radio_addr = ADDR_UNSET,
1745 .tuner = 0, 1153 .has_remote = 1,
1746 .svhs = 3, 1154 /* GPIO wiring: (different from Rev.4C !)
1747 .gpiomask = 2, 1155 GPIO17: U4.A0 (first hef4052bt)
1748 /* TV, Comp1, Composite over SVID con, SVID */ 1156 GPIO19: U4.A1
1749 .muxsel = { 2, 3, 1, 1}, 1157 GPIO20: U5.A1 (second hef4052bt)
1750 .audiomux = { 2, 2, 0, 0, 0 }, 1158 GPIO21: U4.nEN
1751 .pll = PLL_28, 1159 GPIO22: BT832 Reset Line
1752 .has_radio = 1, 1160 GPIO23: A5,A0, U5,nEN
1753 .tuner_type = TUNER_PHILIPS_PAL, 1161 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1754 .tuner_addr = ADDR_UNSET, 1162 */
1755/* sound routing: 1163 },
1756 GPIO=0x00,0x01,0x03: mute (?) 1164 [BTTV_BOARD_EAGLE] = {
1757 0x02: both TV and radio (tuner: FM1216/I) 1165 .name = "Eagle Wireless Capricorn2 (bt878A)",
1758 The card has onboard audio connectors labeled "cdrom" and "board", 1166 .video_inputs = 4,
1759 not soldered here, though unknown wiring. 1167 .audio_inputs = 1,
1760 Card lacks: external audio in, pci subsystem id. 1168 .tuner = 0,
1761*/ 1169 .svhs = 2,
1762},{ 1170 .gpiomask = 7,
1763 1171 .muxsel = { 2, 0, 1, 1},
1764 /* ---- card 0x60 ---------------------------------- */ 1172 .audiomux = { 0, 1, 2, 3, 4},
1765 .name = "MachTV", 1173 .pll = PLL_28,
1766 .video_inputs = 3, 1174 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1767 .audio_inputs = 1, 1175 .tuner_addr = ADDR_UNSET,
1768 .tuner = 0, 1176 .radio_addr = ADDR_UNSET,
1769 .svhs = -1, 1177 },
1770 .gpiomask = 7, 1178
1771 .muxsel = { 2, 3, 1, 1}, 1179 /* ---- card 0x34 ---------------------------------- */
1772 .audiomux = { 0, 1, 2, 3, 4}, 1180 [BTTV_BOARD_PINNACLEPRO] = {
1773 .needs_tvaudio = 1, 1181 /* David Härdeman <david@2gen.com> */
1774 .tuner_type = 5, 1182 .name = "Pinnacle PCTV Studio Pro",
1775 .tuner_addr = ADDR_UNSET, 1183 .video_inputs = 4,
1776 .pll = 1, 1184 .audio_inputs = 1,
1777},{ 1185 .tuner = 0,
1778 .name = "Euresys Picolo", 1186 .svhs = 3,
1779 .video_inputs = 3, 1187 .gpiomask = 0x03000F,
1780 .audio_inputs = 0, 1188 .muxsel = { 2, 3, 1, 1},
1781 .tuner = -1, 1189 .audiomux = { 1, 0xd0001, 0, 0, 10},
1782 .svhs = 2, 1190 /* sound path (5 sources):
1783 .gpiomask = 0, 1191 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1784 .no_msp34xx = 1, 1192 0= ext. Audio IN
1785 .no_tda9875 = 1, 1193 1= from MUX2
1786 .no_tda7432 = 1, 1194 2= Mono TV sound from Tuner
1787 .muxsel = { 2, 0, 1}, 1195 3= not connected
1788 .pll = PLL_28, 1196 MUX2 (mask 0x30000):
1789 .tuner_type = UNSET, 1197 0,2,3= from MSP34xx
1790 .tuner_addr = ADDR_UNSET, 1198 1= FM stereo Radio from Tuner */
1791},{ 1199 .needs_tvaudio = 0,
1792 /* Luc Van Hoeylandt <luc@e-magic.be> */ 1200 .pll = PLL_28,
1793 .name = "ProVideo PV150", /* 0x4f */ 1201 .tuner_type = -1,
1794 .video_inputs = 2, 1202 .tuner_addr = ADDR_UNSET,
1795 .audio_inputs = 0, 1203 .radio_addr = ADDR_UNSET,
1796 .tuner = -1, 1204 },
1797 .svhs = -1, 1205 [BTTV_BOARD_TVIEW_RDS_FM] = {
1798 .gpiomask = 0, 1206 /* Claas Langbehn <claas@bigfoot.com>,
1799 .muxsel = { 2, 3 }, 1207 Sven Grothklags <sven@upb.de> */
1800 .audiomux = { 0 }, 1208 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1801 .needs_tvaudio = 0, 1209 .video_inputs = 4,
1802 .no_msp34xx = 1, 1210 .audio_inputs = 3,
1803 .pll = PLL_28, 1211 .tuner = 0,
1804 .tuner_type = UNSET, 1212 .svhs = 2,
1805 .tuner_addr = ADDR_UNSET, 1213 .gpiomask = 0x1c,
1806},{ 1214 .muxsel = { 2, 3, 1, 1},
1807 /* Hiroshi Takekawa <sian@big.or.jp> */ 1215 .audiomux = { 0, 0, 0x10, 8, 4 },
1808 /* This card lacks subsystem ID */ 1216 .needs_tvaudio = 1,
1809 .name = "AD-TVK503", /* 0x63 */ 1217 .pll = PLL_28,
1810 .video_inputs = 4, 1218 .tuner_type = TUNER_PHILIPS_PAL,
1811 .audio_inputs = 1, 1219 .tuner_addr = ADDR_UNSET,
1812 .tuner = 0, 1220 .radio_addr = ADDR_UNSET,
1813 .svhs = 2, 1221 .has_radio = 1,
1814 .gpiomask = 0x001e8007, 1222 },
1815 .muxsel = { 2, 3, 1, 0 }, 1223 [BTTV_BOARD_LIFETEC_9415] = {
1816 /* Tuner, Radio, external, internal, off, on */ 1224 /* Tim Röstermundt <rosterm@uni-muenster.de>
1817 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, 1225 in de.comp.os.unix.linux.hardware:
1818 .needs_tvaudio = 0, 1226 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1819 .no_msp34xx = 1, 1227 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1820 .pll = PLL_28, 1228 options tuner type=5 */
1821 .tuner_type = 2, 1229 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1822 .tuner_addr = ADDR_UNSET, 1230 .video_inputs = 4,
1823 .audio_hook = adtvk503_audio, 1231 .audio_inputs = 1,
1824},{ 1232 .tuner = 0,
1825 1233 .svhs = 2,
1826 /* ---- card 0x64 ---------------------------------- */ 1234 .gpiomask = 0x18e0,
1827 .name = "Hercules Smart TV Stereo", 1235 .muxsel = { 2, 3, 1, 1},
1828 .video_inputs = 4, 1236 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1829 .audio_inputs = 1, 1237 /* For cards with tda9820/tda9821:
1830 .tuner = 0, 1238 0x0000: Tuner normal stereo
1831 .svhs = 2, 1239 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1832 .gpiomask = 0x00, 1240 0x0880: Tuner A2 stereo */
1833 .muxsel = { 2, 3, 1, 1 }, 1241 .pll = PLL_28,
1834 .needs_tvaudio = 1, 1242 .tuner_type = -1,
1835 .no_msp34xx = 1, 1243 .tuner_addr = ADDR_UNSET,
1836 .pll = PLL_28, 1244 .radio_addr = ADDR_UNSET,
1837 .tuner_type = 5, 1245 },
1838 .tuner_addr = ADDR_UNSET, 1246 [BTTV_BOARD_BESTBUY_EASYTV] = {
1839 /* Notes: 1247 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1840 - card lacks subsystem ID 1248 old Easy TV BT848 version (model CPH031) */
1841 - stereo variant w/ daughter board with tda9874a @0xb0 1249 .name = "Askey CPH031/ BESTBUY Easy TV",
1842 - Audio Routing: 1250 .video_inputs = 4,
1843 always from tda9874 independent of GPIO (?) 1251 .audio_inputs = 1,
1844 external line in: unknown 1252 .tuner = 0,
1845 - Other chips: em78p156elp @ 0x96 (probably IR remote control) 1253 .svhs = 2,
1846 hef4053 (instead 4052) for unknown function 1254 .gpiomask = 0xF,
1847 */ 1255 .muxsel = { 2, 3, 1, 0},
1848},{ 1256 .audiomux = { 2, 0, 0, 0, 10},
1849 .name = "Pace TV & Radio Card", 1257 .needs_tvaudio = 0,
1850 .video_inputs = 4, 1258 .pll = PLL_28,
1851 .audio_inputs = 1, 1259 .tuner_type = TUNER_TEMIC_PAL,
1852 .tuner = 0, 1260 .tuner_addr = ADDR_UNSET,
1853 .svhs = 2, 1261 .radio_addr = ADDR_UNSET,
1854 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ 1262 },
1855 .gpiomask = 0, 1263
1856 .no_tda9875 = 1, 1264 /* ---- card 0x38 ---------------------------------- */
1857 .no_tda7432 = 1, 1265 [BTTV_BOARD_FLYVIDEO_98FM] = {
1858 .tuner_type = 1, 1266 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1859 .tuner_addr = ADDR_UNSET, 1267 .name = "Lifeview FlyVideo 98FM LR50",
1860 .has_radio = 1, 1268 .video_inputs = 4,
1861 .pll = PLL_28, 1269 .audio_inputs = 3,
1862 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id 1270 .tuner = 0,
1863 only internal line out: (4pin header) RGGL 1271 .svhs = 2,
1864 Radio must be decoded by msp3410d (not routed through)*/ 1272 .gpiomask = 0x1800,
1865 /* 1273 .muxsel = { 2, 3, 1, 1},
1866 .digital_mode = DIGITAL_MODE_CAMERA, todo! 1274 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1867 */ 1275 .pll = PLL_28,
1868},{ 1276 .tuner_type = 5,
1869 /* Chris Willing <chris@vislab.usyd.edu.au> */ 1277 .tuner_addr = ADDR_UNSET,
1870 .name = "IVC-200", 1278 .radio_addr = ADDR_UNSET,
1871 .video_inputs = 1, 1279 },
1872 .audio_inputs = 0, 1280 /* This is the ultimate cheapo capture card
1873 .tuner = -1, 1281 * just a BT848A on a small PCB!
1874 .tuner_type = -1, 1282 * Steve Hosgood <steve@equiinet.com> */
1875 .tuner_addr = ADDR_UNSET, 1283 [BTTV_BOARD_GRANDTEC] = {
1876 .svhs = -1, 1284 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1877 .gpiomask = 0xdf, 1285 .video_inputs = 2,
1878 .muxsel = { 2 }, 1286 .audio_inputs = 0,
1879 .pll = PLL_28, 1287 .tuner = -1,
1880},{ 1288 .svhs = 1,
1881 .name = "Grand X-Guard / Trust 814PCI", 1289 .gpiomask = 0,
1882 .video_inputs = 16, 1290 .muxsel = { 3, 1 },
1883 .audio_inputs = 0, 1291 .audiomux = { 0 },
1884 .tuner = -1, 1292 .needs_tvaudio = 0,
1885 .svhs = -1, 1293 .no_msp34xx = 1,
1886 .tuner_type = 4, 1294 .pll = PLL_35,
1887 .tuner_addr = ADDR_UNSET, 1295 .tuner_type = -1,
1888 .gpiomask2 = 0xff, 1296 .tuner_addr = ADDR_UNSET,
1889 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, 1297 .radio_addr = ADDR_UNSET,
1890 .muxsel_hook = xguard_muxsel, 1298 },
1891 .no_msp34xx = 1, 1299 [BTTV_BOARD_ASKEY_CPH060] = {
1892 .no_tda9875 = 1, 1300 /* Daniel Herrington <daniel.herrington@home.com> */
1893 .no_tda7432 = 1, 1301 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1894 .pll = PLL_28, 1302 .video_inputs = 3,
1895},{ 1303 .audio_inputs = 1,
1896 1304 .tuner = 0,
1897 /* ---- card 0x68 ---------------------------------- */ 1305 .svhs = 2,
1898 .name = "Nebula Electronics DigiTV", 1306 .gpiomask = 0xe00,
1899 .video_inputs = 1, 1307 .muxsel = { 2, 3, 1, 1},
1900 .tuner = -1, 1308 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1901 .svhs = -1, 1309 .needs_tvaudio = 1,
1902 .muxsel = { 2, 3, 1, 0}, 1310 .pll = PLL_28,
1903 .no_msp34xx = 1, 1311 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1904 .no_tda9875 = 1, 1312 .tuner_addr = ADDR_UNSET,
1905 .no_tda7432 = 1, 1313 .radio_addr = ADDR_UNSET,
1906 .pll = PLL_28, 1314 },
1907 .tuner_type = -1, 1315 [BTTV_BOARD_ASKEY_CPH03X] = {
1908 .tuner_addr = ADDR_UNSET, 1316 /* Matti Mottus <mottus@physic.ut.ee> */
1909 .has_dvb = 1, 1317 .name = "Askey CPH03x TV Capturer",
1910 .no_gpioirq = 1, 1318 .video_inputs = 4,
1911},{ 1319 .audio_inputs = 1,
1912 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 1320 .tuner = 0,
1913 .name = "ProVideo PV143", 1321 .svhs = 2,
1914 .video_inputs = 4, 1322 .gpiomask = 0x03000F,
1915 .audio_inputs = 0, 1323 .muxsel = { 2, 3, 1, 0},
1916 .tuner = -1, 1324 .audiomux = { 2,0,0,0,1 },
1917 .svhs = -1, 1325 .pll = PLL_28,
1918 .gpiomask = 0, 1326 .tuner_type = 0,
1919 .muxsel = { 2, 3, 1, 0 }, 1327 .tuner_addr = ADDR_UNSET,
1920 .audiomux = { 0 }, 1328 .radio_addr = ADDR_UNSET,
1921 .needs_tvaudio = 0, 1329 },
1922 .no_msp34xx = 1, 1330
1923 .pll = PLL_28, 1331 /* ---- card 0x3c ---------------------------------- */
1924 .tuner_type = -1, 1332 [BTTV_BOARD_MM100PCTV] = {
1925 .tuner_addr = ADDR_UNSET, 1333 /* Philip Blundell <philb@gnu.org> */
1926},{ 1334 .name = "Modular Technology MM100PCTV",
1927 /* M.Klahr@phytec.de */ 1335 .video_inputs = 2,
1928 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 1336 .audio_inputs = 2,
1929 .video_inputs = 4, 1337 .tuner = 0,
1930 .audio_inputs = 0, 1338 .svhs = -1,
1931 .tuner = -1, /* card has no tuner */ 1339 .gpiomask = 11,
1932 .svhs = 3, 1340 .muxsel = { 2, 3, 1, 1},
1933 .gpiomask = 0x00, 1341 .audiomux = { 2, 0, 0, 1, 8},
1934 .muxsel = { 2, 3, 1, 0}, 1342 .pll = PLL_35,
1935 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1343 .tuner_type = TUNER_TEMIC_PAL,
1936 .needs_tvaudio = 1, 1344 .tuner_addr = ADDR_UNSET,
1937 .pll = PLL_28, 1345 .radio_addr = ADDR_UNSET,
1938 .tuner_type = -1, 1346 },
1939 .tuner_addr = ADDR_UNSET, 1347 [BTTV_BOARD_GMV1] = {
1940},{ 1348 /* Adrian Cox <adrian@humboldt.co.uk */
1941 .name = "PHYTEC VD-009-X1 Combi (bt878)", 1349 .name = "AG Electronics GMV1",
1942 .video_inputs = 4, 1350 .video_inputs = 2,
1943 .audio_inputs = 0, 1351 .audio_inputs = 0,
1944 .tuner = -1, /* card has no tuner */ 1352 .tuner = -1,
1945 .svhs = 3, 1353 .svhs = 1,
1946 .gpiomask = 0x00, 1354 .gpiomask = 0xF,
1947 .muxsel = { 2, 3, 1, 1}, 1355 .muxsel = { 2, 2},
1948 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1356 .audiomux = { },
1949 .needs_tvaudio = 1, 1357 .no_msp34xx = 1,
1950 .pll = PLL_28, 1358 .needs_tvaudio = 0,
1951 .tuner_type = -1, 1359 .pll = PLL_28,
1952 .tuner_addr = ADDR_UNSET, 1360 .tuner_type = -1,
1953},{ 1361 .tuner_addr = ADDR_UNSET,
1954 1362 .radio_addr = ADDR_UNSET,
1955 /* ---- card 0x6c ---------------------------------- */ 1363 },
1956 .name = "PHYTEC VD-009 MiniDIN (bt878)", 1364 [BTTV_BOARD_BESTBUY_EASYTV2] = {
1957 .video_inputs = 10, 1365 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1958 .audio_inputs = 0, 1366 new Easy TV BT878 version (model CPH061)
1959 .tuner = -1, /* card has no tuner */ 1367 special thanks to Informatica Mieres for providing the card */
1960 .svhs = 9, 1368 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1961 .gpiomask = 0x00, 1369 .video_inputs = 3,
1962 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1370 .audio_inputs = 2,
1963 via the upper nibble of muxsel. here: used for 1371 .tuner = 0,
1964 xternal video-mux */ 1372 .svhs = 2,
1965 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, 1373 .gpiomask = 0xFF,
1966 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1374 .muxsel = { 2, 3, 1, 0},
1967 .needs_tvaudio = 1, 1375 .audiomux = { 1, 0, 4, 4, 9},
1968 .pll = PLL_28, 1376 .needs_tvaudio = 0,
1969 .tuner_type = -1, 1377 .pll = PLL_28,
1970 .tuner_addr = ADDR_UNSET, 1378 .tuner_type = TUNER_PHILIPS_PAL,
1971},{ 1379 .tuner_addr = ADDR_UNSET,
1972 .name = "PHYTEC VD-009 Combi (bt878)", 1380 .radio_addr = ADDR_UNSET,
1973 .video_inputs = 10, 1381 },
1974 .audio_inputs = 0, 1382 [BTTV_BOARD_ATI_TVWONDER] = {
1975 .tuner = -1, /* card has no tuner */ 1383 /* Lukas Gebauer <geby@volny.cz> */
1976 .svhs = 9, 1384 .name = "ATI TV-Wonder",
1977 .gpiomask = 0x00, 1385 .video_inputs = 3,
1978 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1386 .audio_inputs = 1,
1979 via the upper nibble of muxsel. here: used for 1387 .tuner = 0,
1980 xternal video-mux */ 1388 .svhs = 2,
1981 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, 1389 .gpiomask = 0xf03f,
1982 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1390 .muxsel = { 2, 3, 1, 0 },
1983 .needs_tvaudio = 1, 1391 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1984 .pll = PLL_28, 1392 .pll = PLL_28,
1985 .tuner_type = -1, 1393 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1986 .tuner_addr = ADDR_UNSET, 1394 .tuner_addr = ADDR_UNSET,
1987},{ 1395 .radio_addr = ADDR_UNSET,
1988 .name = "IVC-100", 1396 },
1989 .video_inputs = 4, 1397
1990 .audio_inputs = 0, 1398 /* ---- card 0x40 ---------------------------------- */
1991 .tuner = -1, 1399 [BTTV_BOARD_ATI_TVWONDERVE] = {
1992 .tuner_type = -1, 1400 /* Lukas Gebauer <geby@volny.cz> */
1993 .tuner_addr = ADDR_UNSET, 1401 .name = "ATI TV-Wonder VE",
1994 .svhs = -1, 1402 .video_inputs = 2,
1995 .gpiomask = 0xdf, 1403 .audio_inputs = 1,
1996 .muxsel = { 2, 3, 1, 0 }, 1404 .tuner = 0,
1997 .pll = PLL_28, 1405 .svhs = -1,
1998},{ 1406 .gpiomask = 1,
1999 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ 1407 .muxsel = { 2, 3, 0, 1},
2000 .name = "IVC-120G", 1408 .audiomux = { 0, 0, 1, 0, 0},
2001 .video_inputs = 16, 1409 .no_msp34xx = 1,
2002 .audio_inputs = 0, /* card has no audio */ 1410 .pll = PLL_28,
2003 .tuner = -1, /* card has no tuner */ 1411 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
2004 .tuner_type = -1, 1412 .tuner_addr = ADDR_UNSET,
2005 .tuner_addr = ADDR_UNSET, 1413 .radio_addr = ADDR_UNSET,
2006 .svhs = -1, /* card has no svhs */ 1414 },
2007 .needs_tvaudio = 0, 1415 [BTTV_BOARD_FLYVIDEO2000] = {
2008 .no_msp34xx = 1, 1416 /* DeeJay <deejay@westel900.net (2000S) */
2009 .no_tda9875 = 1, 1417 .name = "Lifeview FlyVideo 2000S LR90",
2010 .no_tda7432 = 1, 1418 .video_inputs = 3,
2011 .gpiomask = 0x00, 1419 .audio_inputs = 3,
2012 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 1420 .tuner = 0,
2013 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, 1421 .svhs = 2,
2014 .muxsel_hook = ivc120_muxsel, 1422 .gpiomask = 0x18e0,
2015 .pll = PLL_28, 1423 .muxsel = { 2, 3, 0, 1},
2016},{ 1424 /* Radio changed from 1e80 to 0x800 to make
2017 1425 FlyVideo2000S in .hu happy (gm)*/
2018 /* ---- card 0x70 ---------------------------------- */ 1426 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
2019 .name = "pcHDTV HD-2000 TV", 1427 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
2020 .video_inputs = 4, 1428 .audio_hook = fv2000s_audio,
2021 .audio_inputs = 1, 1429 .no_msp34xx = 1,
2022 .tuner = 0, 1430 .no_tda9875 = 1,
2023 .svhs = 2, 1431 .needs_tvaudio = 1,
2024 .muxsel = { 2, 3, 1, 0}, 1432 .pll = PLL_28,
2025 .tuner_type = TUNER_PHILIPS_ATSC, 1433 .tuner_type = 5,
2026 .tuner_addr = ADDR_UNSET, 1434 .tuner_addr = ADDR_UNSET,
2027 .has_dvb = 1, 1435 .radio_addr = ADDR_UNSET,
2028},{ 1436 },
2029 .name = "Twinhan DST + clones", 1437 [BTTV_BOARD_TERRATVALUER] = {
2030 .no_msp34xx = 1, 1438 .name = "Terratec TValueRadio",
2031 .no_tda9875 = 1, 1439 .video_inputs = 3,
2032 .no_tda7432 = 1, 1440 .audio_inputs = 1,
2033 .tuner_type = TUNER_ABSENT, 1441 .tuner = 0,
2034 .tuner_addr = ADDR_UNSET, 1442 .svhs = 2,
2035 .no_video = 1, 1443 .gpiomask = 0xffff00,
2036 .has_dvb = 1, 1444 .muxsel = { 2, 3, 1, 1},
2037},{ 1445 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
2038 .name = "Winfast VC100", 1446 .needs_tvaudio = 1,
2039 .video_inputs = 3, 1447 .pll = PLL_28,
2040 .audio_inputs = 0, 1448 .tuner_type = TUNER_PHILIPS_PAL,
2041 .svhs = 1, 1449 .tuner_addr = ADDR_UNSET,
2042 .tuner = -1, 1450 .radio_addr = ADDR_UNSET,
2043 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ 1451 .has_radio = 1,
2044 .no_msp34xx = 1, 1452 },
2045 .no_tda9875 = 1, 1453 [BTTV_BOARD_GVBCTV4PCI] = {
2046 .no_tda7432 = 1, 1454 /* TANAKA Kei <peg00625@nifty.com> */
2047 .tuner_type = TUNER_ABSENT, 1455 .name = "IODATA GV-BCTV4/PCI",
2048 .tuner_addr = ADDR_UNSET, 1456 .video_inputs = 3,
2049 .pll = PLL_28, 1457 .audio_inputs = 1,
2050},{ 1458 .tuner = 0,
2051 .name = "Teppro TEV-560/InterVision IV-560", 1459 .svhs = 2,
2052 .video_inputs = 3, 1460 .gpiomask = 0x010f00,
2053 .audio_inputs = 1, 1461 .muxsel = {2, 3, 0, 0},
2054 .tuner = 0, 1462 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
2055 .svhs = 2, 1463 .no_msp34xx = 1,
2056 .gpiomask = 3, 1464 .pll = PLL_28,
2057 .muxsel = { 2, 3, 1, 1}, 1465 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
2058 .audiomux = { 1, 1, 1, 1, 0}, 1466 .tuner_addr = ADDR_UNSET,
2059 .needs_tvaudio = 1, 1467 .radio_addr = ADDR_UNSET,
2060 .tuner_type = TUNER_PHILIPS_PAL, 1468 .audio_hook = gvbctv3pci_audio,
2061 .tuner_addr = ADDR_UNSET, 1469 },
2062 .pll = PLL_35, 1470
2063},{ 1471 /* ---- card 0x44 ---------------------------------- */
2064 1472 [BTTV_BOARD_VOODOOTV_FM] = {
2065 /* ---- card 0x74 ---------------------------------- */ 1473 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
2066 .name = "SIMUS GVC1100", 1474 /* try "insmod msp3400 simple=0" if you have
2067 .video_inputs = 4, 1475 * sound problems with this card. */
2068 .audio_inputs = 0, 1476 .video_inputs = 4,
2069 .tuner = -1, 1477 .audio_inputs = 1,
2070 .svhs = -1, 1478 .tuner = 0,
2071 .tuner_type = -1, 1479 .svhs = -1,
2072 .tuner_addr = ADDR_UNSET, 1480 .gpiomask = 0x4f8a00,
2073 .pll = PLL_28, 1481 /* 0x100000: 1=MSP enabled (0=disable again)
2074 .muxsel = { 2, 2, 2, 2}, 1482 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
2075 .gpiomask = 0x3F, 1483 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
2076 .muxsel_hook = gvc1100_muxsel, 1484 /* tvtuner, radio, external,internal, mute, stereo
2077},{ 1485 * tuner, Composit, SVid, Composit-on-Svid-adapter */
2078 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ 1486 .muxsel = { 2, 3 ,0 ,1},
2079 .name = "NGS NGSTV+", 1487 .tuner_type = TUNER_MT2032,
2080 .video_inputs = 3, 1488 .tuner_addr = ADDR_UNSET,
2081 .tuner = 0, 1489 .radio_addr = ADDR_UNSET,
2082 .svhs = 2, 1490 .pll = PLL_28,
2083 .gpiomask = 0x008007, 1491 .has_radio = 1,
2084 .muxsel = {2, 3, 0, 0}, 1492 },
2085 .audiomux = {0, 0, 0, 0, 0x000003, 0}, 1493 [BTTV_BOARD_AIMMS] = {
2086 .pll = PLL_28, 1494 /* Philip Blundell <pb@nexus.co.uk> */
2087 .tuner_type = TUNER_PHILIPS_PAL, 1495 .name = "Active Imaging AIMMS",
2088 .tuner_addr = ADDR_UNSET, 1496 .video_inputs = 1,
2089 .has_remote = 1, 1497 .audio_inputs = 0,
2090},{ 1498 .tuner = -1,
2091 /* http://linuxmedialabs.com */ 1499 .tuner_type = -1,
2092 .name = "LMLBT4", 1500 .tuner_addr = ADDR_UNSET,
2093 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ 1501 .radio_addr = ADDR_UNSET,
2094 .audio_inputs = 0, 1502 .pll = PLL_28,
2095 .tuner = -1, 1503 .muxsel = { 2 },
2096 .svhs = -1, 1504 .gpiomask = 0
2097 .muxsel = { 2, 3, 1, 0 }, 1505 },
2098 .no_msp34xx = 1, 1506 [BTTV_BOARD_PV_BT878P_PLUS] = {
2099 .no_tda9875 = 1, 1507 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
2100 .no_tda7432 = 1, 1508 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
2101 .needs_tvaudio = 0, 1509 .video_inputs = 3,
2102 .tuner_type = -1, 1510 .audio_inputs = 4,
2103 .tuner_addr = ADDR_UNSET, 1511 .tuner = 0,
2104},{ 1512 .svhs = 2,
2105 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ 1513 .gpiomask = 15,
2106 .name = "Tekram M205 PRO", 1514 .muxsel = { 2, 3, 1, 1},
2107 .video_inputs = 3, 1515 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
2108 .audio_inputs = 1, 1516 .needs_tvaudio = 1,
2109 .tuner = 0, 1517 .pll = PLL_28,
2110 .tuner_type = TUNER_PHILIPS_PAL, 1518 .tuner_type = 25,
2111 .tuner_addr = ADDR_UNSET, 1519 .tuner_addr = ADDR_UNSET,
2112 .svhs = 2, 1520 .radio_addr = ADDR_UNSET,
2113 .needs_tvaudio = 0, 1521 .has_remote = 1,
2114 .gpiomask = 0x68, 1522 /* GPIO wiring:
2115 .muxsel = { 2, 3, 1}, 1523 GPIO0: U4.A0 (hef4052bt)
2116 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, 1524 GPIO1: U4.A1
2117 .pll = PLL_28, 1525 GPIO2: U4.A1 (second hef4052bt)
2118},{ 1526 GPIO3: U4.nEN, U5.A0, A5.nEN
2119 1527 GPIO8-15: vrd866b ?
2120 /* ---- card 0x78 ---------------------------------- */ 1528 */
2121 /* Javier Cendan Ares <jcendan@lycos.es> */ 1529 },
2122 /* bt878 TV + FM without subsystem ID */ 1530 [BTTV_BOARD_FLYVIDEO98EZ] = {
2123 .name = "Conceptronic CONTVFMi", 1531 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
2124 .video_inputs = 3, 1532 .video_inputs = 4,
2125 .audio_inputs = 1, 1533 .audio_inputs = 0,
2126 .tuner = 0, 1534 .tuner = -1,
2127 .svhs = 2, 1535 .svhs = 2,
2128 .gpiomask = 0x008007, 1536 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
2129 .muxsel = { 2, 3, 1, 1 }, 1537 .pll = PLL_28,
2130 .audiomux = { 0, 1, 2, 2, 3 }, 1538 .no_msp34xx = 1,
2131 .needs_tvaudio = 0, 1539 .tuner_type = UNSET,
2132 .pll = PLL_28, 1540 .tuner_addr = ADDR_UNSET,
2133 .tuner_type = TUNER_PHILIPS_PAL, 1541 .radio_addr = ADDR_UNSET,
2134 .tuner_addr = ADDR_UNSET, 1542 },
2135 .has_remote = 1, 1543
2136 .has_radio = 1, 1544 /* ---- card 0x48 ---------------------------------- */
2137},{ 1545 [BTTV_BOARD_PV_BT878P_9B] = {
2138 /*Eric DEBIEF <debief@telemsa.com>*/ 1546 /* Dariusz Kowalewski <darekk@automex.pl> */
2139 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ 1547 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
2140 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ 1548 .video_inputs = 4,
2141 /*0x79 in bttv.h*/ 1549 .audio_inputs = 1,
2142 .name = "Euresys Picolo Tetra", 1550 .tuner = 0,
2143 .video_inputs = 4, 1551 .svhs = 2,
2144 .audio_inputs = 0, 1552 .gpiomask = 0x3f,
2145 .tuner = -1, 1553 .muxsel = { 2, 3, 1, 1 },
2146 .svhs = -1, 1554 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
2147 .gpiomask = 0, 1555 .needs_tvaudio = 1,
2148 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ 1556 .no_msp34xx = 1,
2149 .no_msp34xx = 1, 1557 .no_tda9875 = 1,
2150 .no_tda9875 = 1, 1558 .pll = PLL_28,
2151 .no_tda7432 = 1, 1559 .tuner_type = 5,
2152 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ 1560 .tuner_addr = ADDR_UNSET,
2153 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1561 .radio_addr = ADDR_UNSET,
2154 .pll = PLL_28, 1562 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
2155 .needs_tvaudio = 0, 1563 .has_radio = 1, /* Note: not all cards have radio */
2156 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ 1564 .has_remote = 1,
2157 .tuner_type = -1, 1565 /* GPIO wiring:
2158 .tuner_addr = ADDR_UNSET, 1566 GPIO0: A0 hef4052
2159},{ 1567 GPIO1: A1 hef4052
2160 /* Spirit TV Tuner from http://spiritmodems.com.au */ 1568 GPIO3: nEN hef4052
2161 /* Stafford Goodsell <surge@goliath.homeunix.org> */ 1569 GPIO8-15: vrd866b
2162 .name = "Spirit TV Tuner", 1570 GPIO20,22,23: R30,R29,R28
2163 .video_inputs = 3, 1571 */
2164 .audio_inputs = 1, 1572 },
2165 .tuner = 0, 1573 [BTTV_BOARD_SENSORAY311] = {
2166 .svhs = 2, 1574 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
2167 .gpiomask = 0x0000000f, 1575 /* you must jumper JP5 for the card to work */
2168 .muxsel = { 2, 1, 1 }, 1576 .name = "Sensoray 311",
2169 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, 1577 .video_inputs = 5,
2170 .tuner_type = TUNER_TEMIC_PAL, 1578 .audio_inputs = 0,
2171 .tuner_addr = ADDR_UNSET, 1579 .tuner = -1,
2172 .no_msp34xx = 1, 1580 .svhs = 4,
2173 .no_tda9875 = 1, 1581 .gpiomask = 0,
2174},{ 1582 .muxsel = { 2, 3, 1, 0, 0},
2175 /* Wolfram Joost <wojo@frokaschwei.de> */ 1583 .audiomux = { 0 },
2176 .name = "AVerMedia AVerTV DVB-T 771", 1584 .needs_tvaudio = 0,
2177 .video_inputs = 2, 1585 .tuner_type = -1,
2178 .svhs = 1, 1586 .tuner_addr = ADDR_UNSET,
2179 .tuner = -1, 1587 .radio_addr = ADDR_UNSET,
2180 .tuner_type = TUNER_ABSENT, 1588 },
2181 .tuner_addr = ADDR_UNSET, 1589 [BTTV_BOARD_RV605] = {
2182 .muxsel = { 3 , 3 }, 1590 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
2183 .no_msp34xx = 1, 1591 .name = "RemoteVision MX (RV605)",
2184 .no_tda9875 = 1, 1592 .video_inputs = 16,
2185 .no_tda7432 = 1, 1593 .audio_inputs = 0,
2186 .pll = PLL_28, 1594 .tuner = -1,
2187 .has_dvb = 1, 1595 .svhs = -1,
2188 .no_gpioirq = 1, 1596 .gpiomask = 0x00,
2189 .has_remote = 1, 1597 .gpiomask2 = 0x07ff,
2190},{ 1598 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
2191 /* ---- card 0x7c ---------------------------------- */ 1599 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
2192 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ 1600 .no_msp34xx = 1,
2193 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ 1601 .no_tda9875 = 1,
2194 .name = "AverMedia AverTV DVB-T 761", 1602 .tuner_type = -1,
2195 .video_inputs = 2, 1603 .tuner_addr = ADDR_UNSET,
2196 .tuner = -1, 1604 .radio_addr = ADDR_UNSET,
2197 .svhs = 1, 1605 .muxsel_hook = rv605_muxsel,
2198 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ 1606 },
2199 .no_msp34xx = 1, 1607 [BTTV_BOARD_POWERCLR_MTV878] = {
2200 .no_tda9875 = 1, 1608 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
2201 .no_tda7432 = 1, 1609 .video_inputs = 3,
2202 .pll = PLL_28, 1610 .audio_inputs = 2,
2203 .tuner_type = -1, 1611 .tuner = 0,
2204 .tuner_addr = ADDR_UNSET, 1612 .svhs = 2,
2205 .has_dvb = 1, 1613 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
2206 .no_gpioirq = 1, 1614 .muxsel = { 2, 1, 1, },
2207 .has_remote = 1, 1615 .audiomux = { 0, 1, 2, 2, 4 },
2208},{ 1616 .needs_tvaudio = 0,
2209 /* andre.schwarz@matrix-vision.de */ 1617 .tuner_type = TUNER_PHILIPS_PAL,
2210 .name = "MATRIX Vision Sigma-SQ", 1618 .tuner_addr = ADDR_UNSET,
2211 .video_inputs = 16, 1619 .radio_addr = ADDR_UNSET,
2212 .audio_inputs = 0, 1620 .pll = PLL_28,
2213 .tuner = -1, 1621 .has_radio = 1,
2214 .svhs = -1, 1622 },
2215 .gpiomask = 0x0, 1623
2216 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 1624 /* ---- card 0x4c ---------------------------------- */
2217 3, 3, 3, 3, 3, 3, 3, 3 }, 1625 [BTTV_BOARD_WINDVR] = {
2218 .muxsel_hook = sigmaSQ_muxsel, 1626 /* Masaki Suzuki <masaki@btree.org> */
2219 .audiomux = { 0 }, 1627 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
2220 .no_msp34xx = 1, 1628 .video_inputs = 3,
2221 .pll = PLL_28, 1629 .audio_inputs = 1,
2222 .tuner_type = -1, 1630 .tuner = 0,
2223 .tuner_addr = ADDR_UNSET, 1631 .svhs = 2,
2224},{ 1632 .gpiomask = 0x140007,
2225 /* andre.schwarz@matrix-vision.de */ 1633 .muxsel = { 2, 3, 1, 1 },
2226 .name = "MATRIX Vision Sigma-SLC", 1634 .audiomux = { 0, 1, 2, 3, 4, 0 },
2227 .video_inputs = 4, 1635 .tuner_type = TUNER_PHILIPS_NTSC,
2228 .audio_inputs = 0, 1636 .tuner_addr = ADDR_UNSET,
2229 .tuner = -1, 1637 .radio_addr = ADDR_UNSET,
2230 .svhs = -1, 1638 .audio_hook = windvr_audio,
2231 .gpiomask = 0x0, 1639 },
2232 .muxsel = { 2, 2, 2, 2 }, 1640 [BTTV_BOARD_GRANDTEC_MULTI] = {
2233 .muxsel_hook = sigmaSLC_muxsel, 1641 .name = "GrandTec Multi Capture Card (Bt878)",
2234 .audiomux = { 0 }, 1642 .video_inputs = 4,
2235 .no_msp34xx = 1, 1643 .audio_inputs = 0,
2236 .pll = PLL_28, 1644 .tuner = -1,
2237 .tuner_type = -1, 1645 .svhs = -1,
2238 .tuner_addr = ADDR_UNSET, 1646 .gpiomask = 0,
2239},{ 1647 .muxsel = { 2, 3, 1, 0 },
2240 /* BTTV_APAC_VIEWCOMP */ 1648 .audiomux = { 0 },
2241 /* Attila Kondoros <attila.kondoros@chello.hu> */ 1649 .needs_tvaudio = 0,
2242 /* bt878 TV + FM 0x00000000 subsystem ID */ 1650 .no_msp34xx = 1,
2243 .name = "APAC Viewcomp 878(AMAX)", 1651 .pll = PLL_28,
2244 .video_inputs = 2, 1652 .tuner_type = -1,
2245 .audio_inputs = 1, 1653 .tuner_addr = ADDR_UNSET,
2246 .tuner = 0, 1654 .radio_addr = ADDR_UNSET,
2247 .svhs = -1, 1655 },
2248 .gpiomask = 0xFF, 1656 [BTTV_BOARD_KWORLD] = {
2249 .muxsel = { 2, 3, 1, 1}, 1657 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
2250 .audiomux = { 2, 0, 0, 0, 10}, 1658 .video_inputs = 4,
2251 .needs_tvaudio = 0, 1659 .audio_inputs = 3,
2252 .pll = PLL_28, 1660 .tuner = 0,
2253 .tuner_type = TUNER_PHILIPS_PAL, 1661 .svhs = 2,
2254 .tuner_addr = ADDR_UNSET, 1662 .gpiomask = 7,
2255 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ 1663 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
2256 .has_radio = 1, /* not every card has radio */ 1664 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
2257},{ 1665 * This card lacks external Audio In, so we mute it on Ext. & Int.
2258 1666 * The PCB can take a sbx1637/sbx1673, wiring unknown.
2259 /* ---- card 0x80 ---------------------------------- */ 1667 * This card lacks PCI subsystem ID, sigh.
2260 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ 1668 * audiomux=1: lower volume, 2+3: mute
2261 .name = "DViCO FusionHDTV DVB-T Lite", 1669 * btwincap uses 0x80000/0x80003
2262 .tuner = -1, 1670 */
2263 .no_msp34xx = 1, 1671 .needs_tvaudio = 0,
2264 .no_tda9875 = 1, 1672 .no_msp34xx = 1,
2265 .no_tda7432 = 1, 1673 .pll = PLL_28,
2266 .pll = PLL_28, 1674 .tuner_type = 5,
2267 .no_video = 1, 1675 .tuner_addr = ADDR_UNSET,
2268 .has_dvb = 1, 1676 .radio_addr = ADDR_UNSET,
2269 .tuner_type = -1, 1677 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
2270 .tuner_addr = ADDR_UNSET, 1678 radio signal strength indicators work fine. */
2271},{ 1679 .has_radio = 1,
2272 /* Steven <photon38@pchome.com.tw> */ 1680 /* GPIO Info:
2273 .name = "V-Gear MyVCD", 1681 GPIO0,1: HEF4052 A0,A1
2274 .video_inputs = 3, 1682 GPIO2: HEF4052 nENABLE
2275 .audio_inputs = 1, 1683 GPIO3-7: n.c.
2276 .tuner = 0, 1684 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
2277 .svhs = 2, 1685 GPIO14,15: ??
2278 .gpiomask = 0x3f, 1686 GPIO16-21: n.c.
2279 .muxsel = {2, 3, 1, 0}, 1687 GPIO22,23: ??
2280 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, 1688 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
2281 .no_msp34xx = 1, 1689 },
2282 .pll = PLL_28, 1690 [BTTV_BOARD_DSP_TCVIDEO] = {
2283 .tuner_type = TUNER_PHILIPS_NTSC_M, 1691 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
2284 .tuner_addr = ADDR_UNSET, 1692 .name = "DSP Design TCVIDEO",
2285 .has_radio = 0, 1693 .video_inputs = 4,
2286},{ 1694 .svhs = -1,
2287 /* Rick C <cryptdragoon@gmail.com> */ 1695 .muxsel = { 2, 3, 1, 0},
2288 .name = "Super TV Tuner", 1696 .pll = PLL_28,
2289 .video_inputs = 4, 1697 .tuner_type = -1,
2290 .audio_inputs = 1, 1698 .tuner_addr = ADDR_UNSET,
2291 .tuner = 0, 1699 .radio_addr = ADDR_UNSET,
2292 .svhs = 2, 1700 },
2293 .muxsel = { 2, 3, 1, 0}, 1701
2294 .tuner_type = TUNER_PHILIPS_NTSC, 1702 /* ---- card 0x50 ---------------------------------- */
2295 .tuner_addr = ADDR_UNSET, 1703 [BTTV_BOARD_HAUPPAUGEPVR] = {
2296 .gpiomask = 0x008007, 1704 .name = "Hauppauge WinTV PVR",
2297 .audiomux = { 0, 0x000001,0,0, 0}, 1705 .video_inputs = 4,
2298 .needs_tvaudio = 1, 1706 .audio_inputs = 1,
2299 .has_radio = 1, 1707 .tuner = 0,
2300},{ 1708 .svhs = 2,
2301 /* Chris Fanning <video4linux@haydon.net> */ 1709 .muxsel = { 2, 0, 1, 1},
2302 .name = "Tibet Systems 'Progress DVR' CS16", 1710 .needs_tvaudio = 1,
2303 .video_inputs = 16, 1711 .pll = PLL_28,
2304 .audio_inputs = 0, 1712 .tuner_type = -1,
2305 .tuner = -1, 1713 .tuner_addr = ADDR_UNSET,
2306 .svhs = -1, 1714 .radio_addr = ADDR_UNSET,
2307 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 1715
2308 .pll = PLL_28, 1716 .gpiomask = 7,
2309 .no_msp34xx = 1, 1717 .audiomux = {7},
2310 .no_tda9875 = 1, 1718 },
2311 .no_tda7432 = 1, 1719 [BTTV_BOARD_GVBCTV5PCI] = {
2312 .tuner_type = -1, 1720 .name = "IODATA GV-BCTV5/PCI",
2313 .tuner_addr = ADDR_UNSET, 1721 .video_inputs = 3,
2314 .muxsel_hook = tibetCS16_muxsel, 1722 .audio_inputs = 1,
2315}, 1723 .tuner = 0,
2316{ 1724 .svhs = 2,
2317 /* Bill Brack <wbrack@mmm.com.hk> */ 1725 .gpiomask = 0x0f0f80,
2318 /* 1726 .muxsel = {2, 3, 1, 0},
2319 * Note that, because of the card's wiring, the "master" 1727 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
2320 * BT878A chip (i.e. the one which controls the analog switch 1728 .no_msp34xx = 1,
2321 * and must use this card type) is the 2nd one detected. The 1729 .pll = PLL_28,
2322 * other 3 chips should use card type 0x85, whose description 1730 .tuner_type = TUNER_PHILIPS_NTSC_M,
2323 * follows this one. There is a EEPROM on the card (which is 1731 .tuner_addr = ADDR_UNSET,
2324 * connected to the I2C of one of those other chips), but is 1732 .radio_addr = ADDR_UNSET,
2325 * not currently handled. There is also a facility for a 1733 .audio_hook = gvbctv5pci_audio,
2326 * "monitor", which is also not currently implemented. 1734 .has_radio = 1,
2327 */ 1735 },
2328 .name = "Kodicom 4400R (master)", 1736 [BTTV_BOARD_OSPREY1x0] = {
2329 .video_inputs = 16, 1737 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
2330 .audio_inputs = 0, 1738 .video_inputs = 4, /* id-inputs-clock */
2331 .tuner = -1, 1739 .audio_inputs = 0,
2332 .tuner_type = -1, 1740 .tuner = -1,
2333 .tuner_addr = ADDR_UNSET, 1741 .svhs = 3,
2334 .svhs = -1, 1742 .muxsel = { 3, 2, 0, 1 },
2335 /* GPIO bits 0-9 used for analog switch: 1743 .pll = PLL_28,
2336 * 00 - 03: camera selector 1744 .tuner_type = -1,
2337 * 04 - 06: channel (controller) selector 1745 .tuner_addr = ADDR_UNSET,
2338 * 07: data (1->on, 0->off) 1746 .radio_addr = ADDR_UNSET,
2339 * 08: strobe 1747 .no_msp34xx = 1,
2340 * 09: reset 1748 .no_tda9875 = 1,
2341 * bit 16 is input from sync separator for the channel 1749 .no_tda7432 = 1,
2342 */ 1750 },
2343 .gpiomask = 0x0003ff, 1751 [BTTV_BOARD_OSPREY1x0_848] = {
2344 .no_gpioirq = 1, 1752 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
2345 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1753 .video_inputs = 3,
2346 .pll = PLL_28, 1754 .audio_inputs = 0,
2347 .no_msp34xx = 1, 1755 .tuner = -1,
2348 .no_tda7432 = 1, 1756 .svhs = 2,
2349 .no_tda9875 = 1, 1757 .muxsel = { 2, 3, 1 },
2350 .muxsel_hook = kodicom4400r_muxsel, 1758 .pll = PLL_28,
2351}, 1759 .tuner_type = -1,
2352{ 1760 .tuner_addr = ADDR_UNSET,
2353 /* Bill Brack <wbrack@mmm.com.hk> */ 1761 .radio_addr = ADDR_UNSET,
2354 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the 1762 .no_msp34xx = 1,
2355 * one which controls the analog switch, and must use the card type) 1763 .no_tda9875 = 1,
2356 * is the 2nd one detected. The other 3 chips should use this card 1764 .no_tda7432 = 1,
2357 * type 1765 },
1766
1767 /* ---- card 0x54 ---------------------------------- */
1768 [BTTV_BOARD_OSPREY101_848] = {
1769 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1770 .video_inputs = 2,
1771 .audio_inputs = 0,
1772 .tuner = -1,
1773 .svhs = 1,
1774 .muxsel = { 3, 1 },
1775 .pll = PLL_28,
1776 .tuner_type = -1,
1777 .tuner_addr = ADDR_UNSET,
1778 .radio_addr = ADDR_UNSET,
1779 .no_msp34xx = 1,
1780 .no_tda9875 = 1,
1781 .no_tda7432 = 1,
1782 },
1783 [BTTV_BOARD_OSPREY1x1] = {
1784 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1785 .video_inputs = 1,
1786 .audio_inputs = 0,
1787 .tuner = -1,
1788 .svhs = -1,
1789 .muxsel = { 0 },
1790 .pll = PLL_28,
1791 .tuner_type = -1,
1792 .tuner_addr = ADDR_UNSET,
1793 .radio_addr = ADDR_UNSET,
1794 .no_msp34xx = 1,
1795 .no_tda9875 = 1,
1796 .no_tda7432 = 1,
1797 },
1798 [BTTV_BOARD_OSPREY1x1_SVID] = {
1799 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1800 .video_inputs = 2,
1801 .audio_inputs = 0,
1802 .tuner = -1,
1803 .svhs = 1,
1804 .muxsel = { 0, 1 },
1805 .pll = PLL_28,
1806 .tuner_type = -1,
1807 .tuner_addr = ADDR_UNSET,
1808 .radio_addr = ADDR_UNSET,
1809 .no_msp34xx = 1,
1810 .no_tda9875 = 1,
1811 .no_tda7432 = 1,
1812 },
1813 [BTTV_BOARD_OSPREY2xx] = {
1814 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1815 .video_inputs = 1,
1816 .audio_inputs = 1,
1817 .tuner = -1,
1818 .svhs = -1,
1819 .muxsel = { 0 },
1820 .pll = PLL_28,
1821 .tuner_type = UNSET,
1822 .tuner_addr = ADDR_UNSET,
1823 .radio_addr = ADDR_UNSET,
1824 .no_msp34xx = 1,
1825 .no_tda9875 = 1,
1826 .no_tda7432 = 1,
1827 },
1828
1829 /* ---- card 0x58 ---------------------------------- */
1830 [BTTV_BOARD_OSPREY2x0_SVID] = {
1831 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1832 .video_inputs = 2,
1833 .audio_inputs = 1,
1834 .tuner = -1,
1835 .svhs = 1,
1836 .muxsel = { 0, 1 },
1837 .pll = PLL_28,
1838 .tuner_type = UNSET,
1839 .tuner_addr = ADDR_UNSET,
1840 .radio_addr = ADDR_UNSET,
1841 .no_msp34xx = 1,
1842 .no_tda9875 = 1,
1843 .no_tda7432 = 1,
1844 },
1845 [BTTV_BOARD_OSPREY2x0] = {
1846 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1847 .video_inputs = 2,
1848 .audio_inputs = 1,
1849 .tuner = -1,
1850 .svhs = 1,
1851 .muxsel = { 2, 3 },
1852 .pll = PLL_28,
1853 .tuner_type = UNSET,
1854 .tuner_addr = ADDR_UNSET,
1855 .radio_addr = ADDR_UNSET,
1856 .no_msp34xx = 1,
1857 .no_tda9875 = 1,
1858 .no_tda7432 = 1,
1859 },
1860 [BTTV_BOARD_OSPREY500] = {
1861 .name = "Osprey 500", /* 500 */
1862 .video_inputs = 2,
1863 .audio_inputs = 1,
1864 .tuner = -1,
1865 .svhs = 1,
1866 .muxsel = { 2, 3 },
1867 .pll = PLL_28,
1868 .tuner_type = -1,
1869 .tuner_addr = ADDR_UNSET,
1870 .radio_addr = ADDR_UNSET,
1871 .no_msp34xx = 1,
1872 .no_tda9875 = 1,
1873 .no_tda7432 = 1,
1874 },
1875 [BTTV_BOARD_OSPREY540] = {
1876 .name = "Osprey 540", /* 540 */
1877 .video_inputs = 4,
1878 .audio_inputs = 1,
1879 .tuner = -1,
1880 #if 0 /* TODO ... */
1881 .svhs = OSPREY540_SVID_ANALOG,
1882 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1883 [OSPREY540_SVID_ANALOG] = 3, },
1884 #endif
1885 .pll = PLL_28,
1886 .tuner_type = -1,
1887 .tuner_addr = ADDR_UNSET,
1888 .radio_addr = ADDR_UNSET,
1889 .no_msp34xx = 1,
1890 .no_tda9875 = 1,
1891 .no_tda7432 = 1,
1892 #if 0 /* TODO ... */
1893 .muxsel_hook = osprey_540_muxsel,
1894 .picture_hook = osprey_540_set_picture,
1895 #endif
1896 },
1897
1898 /* ---- card 0x5C ---------------------------------- */
1899 [BTTV_BOARD_OSPREY2000] = {
1900 .name = "Osprey 2000", /* 2000 */
1901 .video_inputs = 2,
1902 .audio_inputs = 1,
1903 .tuner = -1,
1904 .svhs = 1,
1905 .muxsel = { 2, 3 },
1906 .pll = PLL_28,
1907 .tuner_type = UNSET,
1908 .tuner_addr = ADDR_UNSET,
1909 .radio_addr = ADDR_UNSET,
1910 .no_msp34xx = 1,
1911 .no_tda9875 = 1,
1912 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1913 },
1914 [BTTV_BOARD_IDS_EAGLE] = {
1915 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1916 .name = "IDS Eagle",
1917 .video_inputs = 4,
1918 .audio_inputs = 0,
1919 .tuner = -1,
1920 .tuner_type = -1,
1921 .tuner_addr = ADDR_UNSET,
1922 .radio_addr = ADDR_UNSET,
1923 .svhs = -1,
1924 .gpiomask = 0,
1925 .muxsel = { 0, 1, 2, 3 },
1926 .muxsel_hook = eagle_muxsel,
1927 .no_msp34xx = 1,
1928 .no_tda9875 = 1,
1929 .pll = PLL_28,
1930 },
1931 [BTTV_BOARD_PINNACLESAT] = {
1932 .name = "Pinnacle PCTV Sat",
1933 .video_inputs = 2,
1934 .audio_inputs = 0,
1935 .svhs = 1,
1936 .tuner = -1,
1937 .tuner_type = -1,
1938 .tuner_addr = ADDR_UNSET,
1939 .radio_addr = ADDR_UNSET,
1940 .no_msp34xx = 1,
1941 .no_tda9875 = 1,
1942 .no_tda7432 = 1,
1943 .muxsel = { 3, 0, 1, 2},
1944 .pll = PLL_28,
1945 .no_gpioirq = 1,
1946 .has_dvb = 1,
1947 },
1948 [BTTV_BOARD_FORMAC_PROTV] = {
1949 .name = "Formac ProTV II (bt878)",
1950 .video_inputs = 4,
1951 .audio_inputs = 1,
1952 .tuner = 0,
1953 .svhs = 3,
1954 .gpiomask = 2,
1955 /* TV, Comp1, Composite over SVID con, SVID */
1956 .muxsel = { 2, 3, 1, 1},
1957 .audiomux = { 2, 2, 0, 0, 0 },
1958 .pll = PLL_28,
1959 .has_radio = 1,
1960 .tuner_type = TUNER_PHILIPS_PAL,
1961 .tuner_addr = ADDR_UNSET,
1962 .radio_addr = ADDR_UNSET,
1963 /* sound routing:
1964 GPIO=0x00,0x01,0x03: mute (?)
1965 0x02: both TV and radio (tuner: FM1216/I)
1966 The card has onboard audio connectors labeled "cdrom" and "board",
1967 not soldered here, though unknown wiring.
1968 Card lacks: external audio in, pci subsystem id.
2358 */ 1969 */
2359 .name = "Kodicom 4400R (slave)", 1970 },
2360 .video_inputs = 16, 1971
2361 .audio_inputs = 0, 1972 /* ---- card 0x60 ---------------------------------- */
2362 .tuner = -1, 1973 [BTTV_BOARD_MACHTV] = {
2363 .tuner_type = -1, 1974 .name = "MachTV",
2364 .tuner_addr = ADDR_UNSET, 1975 .video_inputs = 3,
2365 .svhs = -1, 1976 .audio_inputs = 1,
2366 .gpiomask = 0x010000, 1977 .tuner = 0,
2367 .no_gpioirq = 1, 1978 .svhs = -1,
2368 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1979 .gpiomask = 7,
2369 .pll = PLL_28, 1980 .muxsel = { 2, 3, 1, 1},
2370 .no_msp34xx = 1, 1981 .audiomux = { 0, 1, 2, 3, 4},
2371 .no_tda7432 = 1, 1982 .needs_tvaudio = 1,
2372 .no_tda9875 = 1, 1983 .tuner_type = 5,
2373 .muxsel_hook = kodicom4400r_muxsel, 1984 .tuner_addr = ADDR_UNSET,
2374}, 1985 .radio_addr = ADDR_UNSET,
2375{ 1986 .pll = PLL_28,
2376 /* ---- card 0x86---------------------------------- */ 1987 },
2377 /* Michael Henson <mhenson@clarityvi.com> */ 1988 [BTTV_BOARD_EURESYS_PICOLO] = {
2378 /* Adlink RTV24 with special unlock codes */ 1989 .name = "Euresys Picolo",
2379 .name = "Adlink RTV24", 1990 .video_inputs = 3,
2380 .video_inputs = 4, 1991 .audio_inputs = 0,
2381 .audio_inputs = 1, 1992 .tuner = -1,
2382 .tuner = 0, 1993 .svhs = 2,
2383 .svhs = 2, 1994 .gpiomask = 0,
2384 .muxsel = { 2, 3, 1, 0}, 1995 .no_msp34xx = 1,
2385 .tuner_type = -1, 1996 .no_tda9875 = 1,
2386 .tuner_addr = ADDR_UNSET, 1997 .no_tda7432 = 1,
2387 .pll = PLL_28, 1998 .muxsel = { 2, 0, 1},
2388}, 1999 .pll = PLL_28,
2389{ 2000 .tuner_type = UNSET,
2390 /* ---- card 0x87---------------------------------- */ 2001 .tuner_addr = ADDR_UNSET,
2391 /* Michael Krufky <mkrufky@m1k.net> */ 2002 .radio_addr = ADDR_UNSET,
2392 .name = "DViCO FusionHDTV 5 Lite", 2003 },
2393 .tuner = 0, 2004 [BTTV_BOARD_PV150] = {
2394 .tuner_type = TUNER_LG_TDVS_H062F, 2005 /* Luc Van Hoeylandt <luc@e-magic.be> */
2395 .tuner_addr = ADDR_UNSET, 2006 .name = "ProVideo PV150", /* 0x4f */
2396 .video_inputs = 3, 2007 .video_inputs = 2,
2397 .audio_inputs = 1, 2008 .audio_inputs = 0,
2398 .svhs = 2, 2009 .tuner = -1,
2399 .muxsel = { 2, 3, 1 }, 2010 .svhs = -1,
2400 .gpiomask = 0x00e00007, 2011 .gpiomask = 0,
2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, 2012 .muxsel = { 2, 3 },
2402 .no_msp34xx = 1, 2013 .audiomux = { 0 },
2403 .no_tda9875 = 1, 2014 .needs_tvaudio = 0,
2404 .no_tda7432 = 1, 2015 .no_msp34xx = 1,
2405},{ 2016 .pll = PLL_28,
2406 /* ---- card 0x88---------------------------------- */ 2017 .tuner_type = UNSET,
2407 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ 2018 .tuner_addr = ADDR_UNSET,
2408 .name = "Acorp Y878F", 2019 .radio_addr = ADDR_UNSET,
2409 .video_inputs = 3, 2020 },
2410 .audio_inputs = 1, 2021 [BTTV_BOARD_AD_TVK503] = {
2411 .tuner = 0, 2022 /* Hiroshi Takekawa <sian@big.or.jp> */
2412 .svhs = 2, 2023 /* This card lacks subsystem ID */
2413 .gpiomask = 0x01fe00, 2024 .name = "AD-TVK503", /* 0x63 */
2414 .muxsel = { 2, 3, 1, 1}, 2025 .video_inputs = 4,
2415 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 2026 .audio_inputs = 1,
2416 .needs_tvaudio = 1, 2027 .tuner = 0,
2417 .pll = PLL_28, 2028 .svhs = 2,
2418 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, 2029 .gpiomask = 0x001e8007,
2419 .tuner_addr = 0xc1 >>1, 2030 .muxsel = { 2, 3, 1, 0 },
2420 .has_radio = 1, 2031 /* Tuner, Radio, external, internal, off, on */
2421}}; 2032 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
2033 .needs_tvaudio = 0,
2034 .no_msp34xx = 1,
2035 .pll = PLL_28,
2036 .tuner_type = 2,
2037 .tuner_addr = ADDR_UNSET,
2038 .radio_addr = ADDR_UNSET,
2039 .audio_hook = adtvk503_audio,
2040 },
2041
2042 /* ---- card 0x64 ---------------------------------- */
2043 [BTTV_BOARD_HERCULES_SM_TV] = {
2044 .name = "Hercules Smart TV Stereo",
2045 .video_inputs = 4,
2046 .audio_inputs = 1,
2047 .tuner = 0,
2048 .svhs = 2,
2049 .gpiomask = 0x00,
2050 .muxsel = { 2, 3, 1, 1 },
2051 .needs_tvaudio = 1,
2052 .no_msp34xx = 1,
2053 .pll = PLL_28,
2054 .tuner_type = 5,
2055 .tuner_addr = ADDR_UNSET,
2056 .radio_addr = ADDR_UNSET,
2057 /* Notes:
2058 - card lacks subsystem ID
2059 - stereo variant w/ daughter board with tda9874a @0xb0
2060 - Audio Routing:
2061 always from tda9874 independent of GPIO (?)
2062 external line in: unknown
2063 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
2064 hef4053 (instead 4052) for unknown function
2065 */
2066 },
2067 [BTTV_BOARD_PACETV] = {
2068 .name = "Pace TV & Radio Card",
2069 .video_inputs = 4,
2070 .audio_inputs = 1,
2071 .tuner = 0,
2072 .svhs = 2,
2073 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
2074 .gpiomask = 0,
2075 .no_tda9875 = 1,
2076 .no_tda7432 = 1,
2077 .tuner_type = 1,
2078 .tuner_addr = ADDR_UNSET,
2079 .radio_addr = ADDR_UNSET,
2080 .has_radio = 1,
2081 .pll = PLL_28,
2082 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
2083 only internal line out: (4pin header) RGGL
2084 Radio must be decoded by msp3410d (not routed through)*/
2085 /*
2086 .digital_mode = DIGITAL_MODE_CAMERA, todo!
2087 */
2088 },
2089 [BTTV_BOARD_IVC200] = {
2090 /* Chris Willing <chris@vislab.usyd.edu.au> */
2091 .name = "IVC-200",
2092 .video_inputs = 1,
2093 .audio_inputs = 0,
2094 .tuner = -1,
2095 .tuner_type = -1,
2096 .tuner_addr = ADDR_UNSET,
2097 .radio_addr = ADDR_UNSET,
2098 .svhs = -1,
2099 .gpiomask = 0xdf,
2100 .muxsel = { 2 },
2101 .pll = PLL_28,
2102 },
2103 [BTTV_BOARD_XGUARD] = {
2104 .name = "Grand X-Guard / Trust 814PCI",
2105 .video_inputs = 16,
2106 .audio_inputs = 0,
2107 .tuner = -1,
2108 .svhs = -1,
2109 .tuner_type = 4,
2110 .tuner_addr = ADDR_UNSET,
2111 .radio_addr = ADDR_UNSET,
2112 .gpiomask2 = 0xff,
2113 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
2114 .muxsel_hook = xguard_muxsel,
2115 .no_msp34xx = 1,
2116 .no_tda9875 = 1,
2117 .no_tda7432 = 1,
2118 .pll = PLL_28,
2119 },
2120
2121 /* ---- card 0x68 ---------------------------------- */
2122 [BTTV_BOARD_NEBULA_DIGITV] = {
2123 .name = "Nebula Electronics DigiTV",
2124 .video_inputs = 1,
2125 .tuner = -1,
2126 .svhs = -1,
2127 .muxsel = { 2, 3, 1, 0},
2128 .no_msp34xx = 1,
2129 .no_tda9875 = 1,
2130 .no_tda7432 = 1,
2131 .pll = PLL_28,
2132 .tuner_type = -1,
2133 .tuner_addr = ADDR_UNSET,
2134 .radio_addr = ADDR_UNSET,
2135 .has_dvb = 1,
2136 .no_gpioirq = 1,
2137 },
2138 [BTTV_BOARD_PV143] = {
2139 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
2140 .name = "ProVideo PV143",
2141 .video_inputs = 4,
2142 .audio_inputs = 0,
2143 .tuner = -1,
2144 .svhs = -1,
2145 .gpiomask = 0,
2146 .muxsel = { 2, 3, 1, 0 },
2147 .audiomux = { 0 },
2148 .needs_tvaudio = 0,
2149 .no_msp34xx = 1,
2150 .pll = PLL_28,
2151 .tuner_type = -1,
2152 .tuner_addr = ADDR_UNSET,
2153 .radio_addr = ADDR_UNSET,
2154 },
2155 [BTTV_BOARD_VD009X1_MINIDIN] = {
2156 /* M.Klahr@phytec.de */
2157 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
2158 .video_inputs = 4,
2159 .audio_inputs = 0,
2160 .tuner = -1, /* card has no tuner */
2161 .svhs = 3,
2162 .gpiomask = 0x00,
2163 .muxsel = { 2, 3, 1, 0},
2164 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2165 .needs_tvaudio = 1,
2166 .pll = PLL_28,
2167 .tuner_type = -1,
2168 .tuner_addr = ADDR_UNSET,
2169 .radio_addr = ADDR_UNSET,
2170 },
2171 [BTTV_BOARD_VD009X1_COMBI] = {
2172 .name = "PHYTEC VD-009-X1 Combi (bt878)",
2173 .video_inputs = 4,
2174 .audio_inputs = 0,
2175 .tuner = -1, /* card has no tuner */
2176 .svhs = 3,
2177 .gpiomask = 0x00,
2178 .muxsel = { 2, 3, 1, 1},
2179 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2180 .needs_tvaudio = 1,
2181 .pll = PLL_28,
2182 .tuner_type = -1,
2183 .tuner_addr = ADDR_UNSET,
2184 .radio_addr = ADDR_UNSET,
2185 },
2186
2187 /* ---- card 0x6c ---------------------------------- */
2188 [BTTV_BOARD_VD009_MINIDIN] = {
2189 .name = "PHYTEC VD-009 MiniDIN (bt878)",
2190 .video_inputs = 10,
2191 .audio_inputs = 0,
2192 .tuner = -1, /* card has no tuner */
2193 .svhs = 9,
2194 .gpiomask = 0x00,
2195 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2196 via the upper nibble of muxsel. here: used for
2197 xternal video-mux */
2198 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
2199 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2200 .needs_tvaudio = 1,
2201 .pll = PLL_28,
2202 .tuner_type = -1,
2203 .tuner_addr = ADDR_UNSET,
2204 .radio_addr = ADDR_UNSET,
2205 },
2206 [BTTV_BOARD_VD009_COMBI] = {
2207 .name = "PHYTEC VD-009 Combi (bt878)",
2208 .video_inputs = 10,
2209 .audio_inputs = 0,
2210 .tuner = -1, /* card has no tuner */
2211 .svhs = 9,
2212 .gpiomask = 0x00,
2213 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2214 via the upper nibble of muxsel. here: used for
2215 xternal video-mux */
2216 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
2217 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2218 .needs_tvaudio = 1,
2219 .pll = PLL_28,
2220 .tuner_type = -1,
2221 .tuner_addr = ADDR_UNSET,
2222 .radio_addr = ADDR_UNSET,
2223 },
2224 [BTTV_BOARD_IVC100] = {
2225 .name = "IVC-100",
2226 .video_inputs = 4,
2227 .audio_inputs = 0,
2228 .tuner = -1,
2229 .tuner_type = -1,
2230 .tuner_addr = ADDR_UNSET,
2231 .radio_addr = ADDR_UNSET,
2232 .svhs = -1,
2233 .gpiomask = 0xdf,
2234 .muxsel = { 2, 3, 1, 0 },
2235 .pll = PLL_28,
2236 },
2237 [BTTV_BOARD_IVC120] = {
2238 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
2239 .name = "IVC-120G",
2240 .video_inputs = 16,
2241 .audio_inputs = 0, /* card has no audio */
2242 .tuner = -1, /* card has no tuner */
2243 .tuner_type = -1,
2244 .tuner_addr = ADDR_UNSET,
2245 .radio_addr = ADDR_UNSET,
2246 .svhs = -1, /* card has no svhs */
2247 .needs_tvaudio = 0,
2248 .no_msp34xx = 1,
2249 .no_tda9875 = 1,
2250 .no_tda7432 = 1,
2251 .gpiomask = 0x00,
2252 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2253 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
2254 .muxsel_hook = ivc120_muxsel,
2255 .pll = PLL_28,
2256 },
2257
2258 /* ---- card 0x70 ---------------------------------- */
2259 [BTTV_BOARD_PC_HDTV] = {
2260 .name = "pcHDTV HD-2000 TV",
2261 .video_inputs = 4,
2262 .audio_inputs = 1,
2263 .tuner = 0,
2264 .svhs = 2,
2265 .muxsel = { 2, 3, 1, 0},
2266 .tuner_type = TUNER_PHILIPS_ATSC,
2267 .tuner_addr = ADDR_UNSET,
2268 .radio_addr = ADDR_UNSET,
2269 .has_dvb = 1,
2270 },
2271 [BTTV_BOARD_TWINHAN_DST] = {
2272 .name = "Twinhan DST + clones",
2273 .no_msp34xx = 1,
2274 .no_tda9875 = 1,
2275 .no_tda7432 = 1,
2276 .tuner_type = TUNER_ABSENT,
2277 .tuner_addr = ADDR_UNSET,
2278 .radio_addr = ADDR_UNSET,
2279 .no_video = 1,
2280 .has_dvb = 1,
2281 },
2282 [BTTV_BOARD_WINFASTVC100] = {
2283 .name = "Winfast VC100",
2284 .video_inputs = 3,
2285 .audio_inputs = 0,
2286 .svhs = 1,
2287 .tuner = -1,
2288 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
2289 .no_msp34xx = 1,
2290 .no_tda9875 = 1,
2291 .no_tda7432 = 1,
2292 .tuner_type = TUNER_ABSENT,
2293 .tuner_addr = ADDR_UNSET,
2294 .radio_addr = ADDR_UNSET,
2295 .pll = PLL_28,
2296 },
2297 [BTTV_BOARD_TEV560] = {
2298 .name = "Teppro TEV-560/InterVision IV-560",
2299 .video_inputs = 3,
2300 .audio_inputs = 1,
2301 .tuner = 0,
2302 .svhs = 2,
2303 .gpiomask = 3,
2304 .muxsel = { 2, 3, 1, 1},
2305 .audiomux = { 1, 1, 1, 1, 0},
2306 .needs_tvaudio = 1,
2307 .tuner_type = TUNER_PHILIPS_PAL,
2308 .tuner_addr = ADDR_UNSET,
2309 .radio_addr = ADDR_UNSET,
2310 .pll = PLL_35,
2311 },
2312
2313 /* ---- card 0x74 ---------------------------------- */
2314 [BTTV_BOARD_SIMUS_GVC1100] = {
2315 .name = "SIMUS GVC1100",
2316 .video_inputs = 4,
2317 .audio_inputs = 0,
2318 .tuner = -1,
2319 .svhs = -1,
2320 .tuner_type = -1,
2321 .tuner_addr = ADDR_UNSET,
2322 .radio_addr = ADDR_UNSET,
2323 .pll = PLL_28,
2324 .muxsel = { 2, 2, 2, 2},
2325 .gpiomask = 0x3F,
2326 .muxsel_hook = gvc1100_muxsel,
2327 },
2328 [BTTV_BOARD_NGSTV_PLUS] = {
2329 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
2330 .name = "NGS NGSTV+",
2331 .video_inputs = 3,
2332 .tuner = 0,
2333 .svhs = 2,
2334 .gpiomask = 0x008007,
2335 .muxsel = {2, 3, 0, 0},
2336 .audiomux = {0, 0, 0, 0, 0x000003, 0},
2337 .pll = PLL_28,
2338 .tuner_type = TUNER_PHILIPS_PAL,
2339 .tuner_addr = ADDR_UNSET,
2340 .radio_addr = ADDR_UNSET,
2341 .has_remote = 1,
2342 },
2343 [BTTV_BOARD_LMLBT4] = {
2344 /* http://linuxmedialabs.com */
2345 .name = "LMLBT4",
2346 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
2347 .audio_inputs = 0,
2348 .tuner = -1,
2349 .svhs = -1,
2350 .muxsel = { 2, 3, 1, 0 },
2351 .no_msp34xx = 1,
2352 .no_tda9875 = 1,
2353 .no_tda7432 = 1,
2354 .needs_tvaudio = 0,
2355 .tuner_type = -1,
2356 .tuner_addr = ADDR_UNSET,
2357 .radio_addr = ADDR_UNSET,
2358 },
2359 [BTTV_BOARD_TEKRAM_M205] = {
2360 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2361 .name = "Tekram M205 PRO",
2362 .video_inputs = 3,
2363 .audio_inputs = 1,
2364 .tuner = 0,
2365 .tuner_type = TUNER_PHILIPS_PAL,
2366 .tuner_addr = ADDR_UNSET,
2367 .radio_addr = ADDR_UNSET,
2368 .svhs = 2,
2369 .needs_tvaudio = 0,
2370 .gpiomask = 0x68,
2371 .muxsel = { 2, 3, 1},
2372 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2373 .pll = PLL_28,
2374 },
2375
2376 /* ---- card 0x78 ---------------------------------- */
2377 [BTTV_BOARD_CONTVFMI] = {
2378 /* Javier Cendan Ares <jcendan@lycos.es> */
2379 /* bt878 TV + FM without subsystem ID */
2380 .name = "Conceptronic CONTVFMi",
2381 .video_inputs = 3,
2382 .audio_inputs = 1,
2383 .tuner = 0,
2384 .svhs = 2,
2385 .gpiomask = 0x008007,
2386 .muxsel = { 2, 3, 1, 1 },
2387 .audiomux = { 0, 1, 2, 2, 3 },
2388 .needs_tvaudio = 0,
2389 .pll = PLL_28,
2390 .tuner_type = TUNER_PHILIPS_PAL,
2391 .tuner_addr = ADDR_UNSET,
2392 .radio_addr = ADDR_UNSET,
2393 .has_remote = 1,
2394 .has_radio = 1,
2395 },
2396 [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
2397 /*Eric DEBIEF <debief@telemsa.com>*/
2398 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2399 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
2400 /*0x79 in bttv.h*/
2401 .name = "Euresys Picolo Tetra",
2402 .video_inputs = 4,
2403 .audio_inputs = 0,
2404 .tuner = -1,
2405 .svhs = -1,
2406 .gpiomask = 0,
2407 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2408 .no_msp34xx = 1,
2409 .no_tda9875 = 1,
2410 .no_tda7432 = 1,
2411 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2412 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2413 .pll = PLL_28,
2414 .needs_tvaudio = 0,
2415 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2416 .tuner_type = -1,
2417 .tuner_addr = ADDR_UNSET,
2418 .radio_addr = ADDR_UNSET,
2419 },
2420 [BTTV_BOARD_SPIRIT_TV] = {
2421 /* Spirit TV Tuner from http://spiritmodems.com.au */
2422 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2423 .name = "Spirit TV Tuner",
2424 .video_inputs = 3,
2425 .audio_inputs = 1,
2426 .tuner = 0,
2427 .svhs = 2,
2428 .gpiomask = 0x0000000f,
2429 .muxsel = { 2, 1, 1 },
2430 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2431 .tuner_type = TUNER_TEMIC_PAL,
2432 .tuner_addr = ADDR_UNSET,
2433 .radio_addr = ADDR_UNSET,
2434 .no_msp34xx = 1,
2435 .no_tda9875 = 1,
2436 },
2437 [BTTV_BOARD_AVDVBT_771] = {
2438 /* Wolfram Joost <wojo@frokaschwei.de> */
2439 .name = "AVerMedia AVerTV DVB-T 771",
2440 .video_inputs = 2,
2441 .svhs = 1,
2442 .tuner = -1,
2443 .tuner_type = TUNER_ABSENT,
2444 .tuner_addr = ADDR_UNSET,
2445 .radio_addr = ADDR_UNSET,
2446 .muxsel = { 3 , 3 },
2447 .no_msp34xx = 1,
2448 .no_tda9875 = 1,
2449 .no_tda7432 = 1,
2450 .pll = PLL_28,
2451 .has_dvb = 1,
2452 .no_gpioirq = 1,
2453 .has_remote = 1,
2454 },
2455 /* ---- card 0x7c ---------------------------------- */
2456 [BTTV_BOARD_AVDVBT_761] = {
2457 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2458 /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
2459 .name = "AverMedia AverTV DVB-T 761",
2460 .video_inputs = 2,
2461 .tuner = -1,
2462 .svhs = 1,
2463 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2464 .no_msp34xx = 1,
2465 .no_tda9875 = 1,
2466 .no_tda7432 = 1,
2467 .pll = PLL_28,
2468 .tuner_type = -1,
2469 .tuner_addr = ADDR_UNSET,
2470 .radio_addr = ADDR_UNSET,
2471 .has_dvb = 1,
2472 .no_gpioirq = 1,
2473 .has_remote = 1,
2474 },
2475 [BTTV_BOARD_MATRIX_VISIONSQ] = {
2476 /* andre.schwarz@matrix-vision.de */
2477 .name = "MATRIX Vision Sigma-SQ",
2478 .video_inputs = 16,
2479 .audio_inputs = 0,
2480 .tuner = -1,
2481 .svhs = -1,
2482 .gpiomask = 0x0,
2483 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2484 3, 3, 3, 3, 3, 3, 3, 3 },
2485 .muxsel_hook = sigmaSQ_muxsel,
2486 .audiomux = { 0 },
2487 .no_msp34xx = 1,
2488 .pll = PLL_28,
2489 .tuner_type = -1,
2490 .tuner_addr = ADDR_UNSET,
2491 .radio_addr = ADDR_UNSET,
2492 },
2493 [BTTV_BOARD_MATRIX_VISIONSLC] = {
2494 /* andre.schwarz@matrix-vision.de */
2495 .name = "MATRIX Vision Sigma-SLC",
2496 .video_inputs = 4,
2497 .audio_inputs = 0,
2498 .tuner = -1,
2499 .svhs = -1,
2500 .gpiomask = 0x0,
2501 .muxsel = { 2, 2, 2, 2 },
2502 .muxsel_hook = sigmaSLC_muxsel,
2503 .audiomux = { 0 },
2504 .no_msp34xx = 1,
2505 .pll = PLL_28,
2506 .tuner_type = -1,
2507 .tuner_addr = ADDR_UNSET,
2508 .radio_addr = ADDR_UNSET,
2509 },
2510 /* BTTV_BOARD_APAC_VIEWCOMP */
2511 [BTTV_BOARD_APAC_VIEWCOMP] = {
2512 /* Attila Kondoros <attila.kondoros@chello.hu> */
2513 /* bt878 TV + FM 0x00000000 subsystem ID */
2514 .name = "APAC Viewcomp 878(AMAX)",
2515 .video_inputs = 2,
2516 .audio_inputs = 1,
2517 .tuner = 0,
2518 .svhs = -1,
2519 .gpiomask = 0xFF,
2520 .muxsel = { 2, 3, 1, 1},
2521 .audiomux = { 2, 0, 0, 0, 10},
2522 .needs_tvaudio = 0,
2523 .pll = PLL_28,
2524 .tuner_type = TUNER_PHILIPS_PAL,
2525 .tuner_addr = ADDR_UNSET,
2526 .radio_addr = ADDR_UNSET,
2527 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2528 .has_radio = 1, /* not every card has radio */
2529 },
2530
2531 /* ---- card 0x80 ---------------------------------- */
2532 [BTTV_BOARD_DVICO_DVBT_LITE] = {
2533 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2534 .name = "DViCO FusionHDTV DVB-T Lite",
2535 .tuner = -1,
2536 .no_msp34xx = 1,
2537 .no_tda9875 = 1,
2538 .no_tda7432 = 1,
2539 .pll = PLL_28,
2540 .no_video = 1,
2541 .has_dvb = 1,
2542 .tuner_type = -1,
2543 .tuner_addr = ADDR_UNSET,
2544 .radio_addr = ADDR_UNSET,
2545 },
2546 [BTTV_BOARD_VGEAR_MYVCD] = {
2547 /* Steven <photon38@pchome.com.tw> */
2548 .name = "V-Gear MyVCD",
2549 .video_inputs = 3,
2550 .audio_inputs = 1,
2551 .tuner = 0,
2552 .svhs = 2,
2553 .gpiomask = 0x3f,
2554 .muxsel = {2, 3, 1, 0},
2555 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2556 .no_msp34xx = 1,
2557 .pll = PLL_28,
2558 .tuner_type = TUNER_PHILIPS_NTSC_M,
2559 .tuner_addr = ADDR_UNSET,
2560 .radio_addr = ADDR_UNSET,
2561 .has_radio = 0,
2562 #if 0
2563 .has_remote = 1,
2564 #endif
2565 },
2566 [BTTV_BOARD_SUPER_TV] = {
2567 /* Rick C <cryptdragoon@gmail.com> */
2568 .name = "Super TV Tuner",
2569 .video_inputs = 4,
2570 .audio_inputs = 1,
2571 .tuner = 0,
2572 .svhs = 2,
2573 .muxsel = { 2, 3, 1, 0},
2574 .tuner_type = TUNER_PHILIPS_NTSC,
2575 .tuner_addr = ADDR_UNSET,
2576 .radio_addr = ADDR_UNSET,
2577 .gpiomask = 0x008007,
2578 .audiomux = { 0, 0x000001,0,0, 0},
2579 .needs_tvaudio = 1,
2580 .has_radio = 1,
2581 },
2582 [BTTV_BOARD_TIBET_CS16] = {
2583 /* Chris Fanning <video4linux@haydon.net> */
2584 .name = "Tibet Systems 'Progress DVR' CS16",
2585 .video_inputs = 16,
2586 .audio_inputs = 0,
2587 .tuner = -1,
2588 .svhs = -1,
2589 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2590 .pll = PLL_28,
2591 .no_msp34xx = 1,
2592 .no_tda9875 = 1,
2593 .no_tda7432 = 1,
2594 .tuner_type = -1,
2595 .tuner_addr = ADDR_UNSET,
2596 .radio_addr = ADDR_UNSET,
2597 .muxsel_hook = tibetCS16_muxsel,
2598 },
2599 [BTTV_BOARD_KODICOM_4400R] = {
2600 /* Bill Brack <wbrack@mmm.com.hk> */
2601 /*
2602 * Note that, because of the card's wiring, the "master"
2603 * BT878A chip (i.e. the one which controls the analog switch
2604 * and must use this card type) is the 2nd one detected. The
2605 * other 3 chips should use card type 0x85, whose description
2606 * follows this one. There is a EEPROM on the card (which is
2607 * connected to the I2C of one of those other chips), but is
2608 * not currently handled. There is also a facility for a
2609 * "monitor", which is also not currently implemented.
2610 */
2611 .name = "Kodicom 4400R (master)",
2612 .video_inputs = 16,
2613 .audio_inputs = 0,
2614 .tuner = -1,
2615 .tuner_type = -1,
2616 .tuner_addr = ADDR_UNSET,
2617 .radio_addr = ADDR_UNSET,
2618 .svhs = -1,
2619 /* GPIO bits 0-9 used for analog switch:
2620 * 00 - 03: camera selector
2621 * 04 - 06: channel (controller) selector
2622 * 07: data (1->on, 0->off)
2623 * 08: strobe
2624 * 09: reset
2625 * bit 16 is input from sync separator for the channel
2626 */
2627 .gpiomask = 0x0003ff,
2628 .no_gpioirq = 1,
2629 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2630 .pll = PLL_28,
2631 .no_msp34xx = 1,
2632 .no_tda7432 = 1,
2633 .no_tda9875 = 1,
2634 .muxsel_hook = kodicom4400r_muxsel,
2635 },
2636 [BTTV_BOARD_KODICOM_4400R_SL] = {
2637 /* Bill Brack <wbrack@mmm.com.hk> */
2638 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2639 * one which controls the analog switch, and must use the card type)
2640 * is the 2nd one detected. The other 3 chips should use this card
2641 * type
2642 */
2643 .name = "Kodicom 4400R (slave)",
2644 .video_inputs = 16,
2645 .audio_inputs = 0,
2646 .tuner = -1,
2647 .tuner_type = -1,
2648 .tuner_addr = ADDR_UNSET,
2649 .radio_addr = ADDR_UNSET,
2650 .svhs = -1,
2651 .gpiomask = 0x010000,
2652 .no_gpioirq = 1,
2653 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2654 .pll = PLL_28,
2655 .no_msp34xx = 1,
2656 .no_tda7432 = 1,
2657 .no_tda9875 = 1,
2658 .muxsel_hook = kodicom4400r_muxsel,
2659 },
2660 /* ---- card 0x86---------------------------------- */
2661 [BTTV_BOARD_ADLINK_RTV24] = {
2662 /* Michael Henson <mhenson@clarityvi.com> */
2663 /* Adlink RTV24 with special unlock codes */
2664 .name = "Adlink RTV24",
2665 .video_inputs = 4,
2666 .audio_inputs = 1,
2667 .tuner = 0,
2668 .svhs = 2,
2669 .muxsel = { 2, 3, 1, 0},
2670 .tuner_type = -1,
2671 .tuner_addr = ADDR_UNSET,
2672 .radio_addr = ADDR_UNSET,
2673 .pll = PLL_28,
2674 },
2675 /* ---- card 0x87---------------------------------- */
2676 [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
2677 /* Michael Krufky <mkrufky@m1k.net> */
2678 .name = "DViCO FusionHDTV 5 Lite",
2679 .tuner = 0,
2680 .tuner_type = TUNER_LG_TDVS_H062F,
2681 .tuner_addr = ADDR_UNSET,
2682 .radio_addr = ADDR_UNSET,
2683 .video_inputs = 3,
2684 .audio_inputs = 1,
2685 .svhs = 2,
2686 .muxsel = { 2, 3, 1 },
2687 .gpiomask = 0x00e00007,
2688 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
2689 .no_msp34xx = 1,
2690 .no_tda9875 = 1,
2691 .no_tda7432 = 1,
2692 .has_dvb = 1,
2693 },
2694 /* ---- card 0x88---------------------------------- */
2695 [BTTV_BOARD_ACORP_Y878F] = {
2696 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2697 .name = "Acorp Y878F",
2698 .video_inputs = 3,
2699 .audio_inputs = 1,
2700 .tuner = 0,
2701 .svhs = 2,
2702 .gpiomask = 0x01fe00,
2703 .muxsel = { 2, 3, 1, 1},
2704 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
2705 .needs_tvaudio = 1,
2706 .pll = PLL_28,
2707 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2708 .tuner_addr = 0xc1 >>1,
2709 .radio_addr = 0xc1 >>1,
2710 .has_radio = 1,
2711 },
2712 /* ---- card 0x89 ---------------------------------- */
2713 [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
2714 .name = "Conceptronic CTVFMi v2",
2715 .video_inputs = 3,
2716 .audio_inputs = 1,
2717 .tuner = 0,
2718 .svhs = 2,
2719 .gpiomask = 0x001c0007,
2720 .muxsel = { 2, 3, 1, 1 },
2721 .audiomux = { 0, 1, 2, 2, 3 },
2722 .needs_tvaudio = 0,
2723 .pll = PLL_28,
2724 .tuner_type = TUNER_TENA_9533_DI,
2725 .tuner_addr = ADDR_UNSET,
2726 .radio_addr = ADDR_UNSET,
2727 .has_remote = 1,
2728 .has_radio = 1,
2729 },
2730 /* ---- card 0x8a ---------------------------------- */
2731 [BTTV_BOARD_PV_BT878P_2E] = {
2732 .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
2733 .video_inputs = 5,
2734 .audio_inputs = 1,
2735 .tuner = 0,
2736 .svhs = 3,
2737 .gpiomask = 0x01fe00,
2738 .muxsel = { 2,3,1,1,-1 },
2739 .digital_mode = DIGITAL_MODE_CAMERA,
2740 .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 },
2741 .no_msp34xx = 1,
2742 .pll = PLL_28,
2743 .tuner_type = TUNER_LG_PAL_FM,
2744 .tuner_addr = ADDR_UNSET,
2745 .radio_addr = ADDR_UNSET,
2746 .has_remote = 1,
2747 },
2748 /* ---- card 0x8b ---------------------------------- */
2749 [BTTV_BOARD_PV_M4900] = {
2750 /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
2751 .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
2752 .video_inputs = 3,
2753 .audio_inputs = 1,
2754 .tuner = 0,
2755 .svhs = 2,
2756 .gpiomask = 0x3f,
2757 .muxsel = { 2, 3, 1, 1 },
2758 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
2759 .no_msp34xx = 1,
2760 .pll = PLL_28,
2761 .tuner_type = TUNER_YMEC_TVF_5533MF,
2762 .tuner_addr = ADDR_UNSET,
2763 .radio_addr = ADDR_UNSET,
2764 .has_radio = 1,
2765 .has_remote = 1,
2766 },
2767 /* ---- card 0x8c ---------------------------------- */
2768 [BTTV_BOARD_OSPREY440] = {
2769 .name = "Osprey 440",
2770 .video_inputs = 1,
2771 .audio_inputs = 1,
2772 .tuner = -1,
2773 .svhs = 1,
2774 .muxsel = { 2 },
2775 .pll = PLL_28,
2776 .tuner_type = UNSET,
2777 .tuner_addr = ADDR_UNSET,
2778 .radio_addr = ADDR_UNSET,
2779 .no_msp34xx = 1,
2780 .no_tda9875 = 1,
2781 .no_tda7432 = 1,
2782 },
2783 /* ---- card 0x8d ---------------------------------- */
2784 [BTTV_BOARD_ASOUND_SKYEYE] = {
2785 .name = "Asound Skyeye PCTV",
2786 .video_inputs = 3,
2787 .audio_inputs = 1,
2788 .tuner = 0,
2789 .svhs = 2,
2790 .gpiomask = 15,
2791 .muxsel = { 2, 3, 1, 1},
2792 .audiomux = {2,0,0,0,1},
2793 .needs_tvaudio = 1,
2794 .pll = PLL_28,
2795 .tuner_type = 2,
2796 .tuner_addr = ADDR_UNSET,
2797 .radio_addr = ADDR_UNSET,
2798 },
2799
2800};
2422 2801
2423static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2802static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2424 2803
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv)
2461 btv->c.nr, btv->cardid & 0xffff, 2840 btv->c.nr, btv->cardid & 0xffff,
2462 (btv->cardid >> 16) & 0xffff); 2841 (btv->cardid >> 16) & 0xffff);
2463 printk(KERN_DEBUG "please mail id, board name and " 2842 printk(KERN_DEBUG "please mail id, board name and "
2464 "the correct card= insmod option to kraxel@bytesex.org\n"); 2843 "the correct card= insmod option to video4linux-list@redhat.com\n");
2465 } 2844 }
2466 } 2845 }
2467 2846
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2510 int type = -1; 2889 int type = -1;
2511 2890
2512 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) 2891 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2513 type = BTTV_MODTEC_205; 2892 type = BTTV_BOARD_MODTEC_205;
2514 else if (0 == strncmp(eeprom_data+20,"Picolo",7)) 2893 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2515 type = BTTV_EURESYS_PICOLO; 2894 type = BTTV_BOARD_EURESYS_PICOLO;
2516 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) 2895 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2517 type = BTTV_HAUPPAUGE; /* old bt848 */ 2896 type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
2518 2897
2519 if (-1 != type) { 2898 if (-1 != type) {
2520 btv->c.type = type; 2899 btv->c.type = type;
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv)
2548 switch(ttype) { 2927 switch(ttype) {
2549 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ 2928 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
2550 break; 2929 break;
2551 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ 2930 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
2552 break; 2931 break;
2553 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ 2932 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
2554 break; 2933 break;
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv)
2564 has_radio = gpio & 0x400000; 2943 has_radio = gpio & 0x400000;
2565 /* unknown 0x200000; 2944 /* unknown 0x200000;
2566 * unknown2 0x100000; */ 2945 * unknown2 0x100000; */
2567 is_capture_only = !(gpio & 0x008000); /* GPIO15 */ 2946 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
2568 has_tda9820_tda9821 = !(gpio & 0x004000); 2947 has_tda9820_tda9821 = !(gpio & 0x004000);
2569 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ 2948 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
2570 /* 2949 /*
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2601 char *info; 2980 char *info;
2602 2981
2603 gpio_inout(0xffffff, 0); 2982 gpio_inout(0xffffff, 0);
2604 gpio = gpio_read(); 2983 gpio = gpio_read();
2605 id = ((gpio>>10) & 63) -1; 2984 id = ((gpio>>10) & 63) -1;
2606 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); 2985 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2607 if (id < 32) { 2986 if (id < 32) {
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2620 btv->has_radio = 0; 2999 btv->has_radio = 0;
2621 } 3000 }
2622 if (-1 != msp) { 3001 if (-1 != msp) {
2623 if (btv->c.type == BTTV_MIRO) 3002 if (btv->c.type == BTTV_BOARD_MIRO)
2624 btv->c.type = BTTV_MIROPRO; 3003 btv->c.type = BTTV_BOARD_MIROPRO;
2625 if (btv->c.type == BTTV_PINNACLE) 3004 if (btv->c.type == BTTV_BOARD_PINNACLE)
2626 btv->c.type = BTTV_PINNACLEPRO; 3005 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2627 } 3006 }
2628 printk(KERN_INFO 3007 printk(KERN_INFO
2629 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", 3008 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2664 break; 3043 break;
2665 } 3044 }
2666 if (-1 != msp) 3045 if (-1 != msp)
2667 btv->c.type = BTTV_PINNACLEPRO; 3046 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2668 printk(KERN_INFO 3047 printk(KERN_INFO
2669 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", 3048 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2670 btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); 3049 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
2712 3091
2713static void gvc1100_muxsel(struct bttv *btv, unsigned int input) 3092static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2714{ 3093{
2715 static const int masks[] = {0x30, 0x01, 0x12, 0x23}; 3094 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2716 gpio_write(masks[input%4]); 3095 gpio_write(masks[input%4]);
2717} 3096}
2718 3097
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv)
2778void __devinit bttv_init_card1(struct bttv *btv) 3157void __devinit bttv_init_card1(struct bttv *btv)
2779{ 3158{
2780 switch (btv->c.type) { 3159 switch (btv->c.type) {
2781 case BTTV_HAUPPAUGE: 3160 case BTTV_BOARD_HAUPPAUGE:
2782 case BTTV_HAUPPAUGE878: 3161 case BTTV_BOARD_HAUPPAUGE878:
2783 boot_msp34xx(btv,5); 3162 boot_msp34xx(btv,5);
2784 break; 3163 break;
2785 case BTTV_VOODOOTV_FM: 3164 case BTTV_BOARD_VOODOOTV_FM:
2786 boot_msp34xx(btv,20); 3165 boot_msp34xx(btv,20);
2787 break; 3166 break;
2788 case BTTV_AVERMEDIA98: 3167 case BTTV_BOARD_AVERMEDIA98:
2789 boot_msp34xx(btv,11); 3168 boot_msp34xx(btv,11);
2790 break; 3169 break;
2791 case BTTV_HAUPPAUGEPVR: 3170 case BTTV_BOARD_HAUPPAUGEPVR:
2792 pvr_boot(btv); 3171 pvr_boot(btv);
2793 break; 3172 break;
2794 case BTTV_TWINHAN_DST: 3173 case BTTV_BOARD_TWINHAN_DST:
2795 case BTTV_AVDVBT_771: 3174 case BTTV_BOARD_AVDVBT_771:
3175 case BTTV_BOARD_PINNACLESAT:
2796 btv->use_i2c_hw = 1; 3176 btv->use_i2c_hw = 1;
2797 break; 3177 break;
2798 case BTTV_ADLINK_RTV24: 3178 case BTTV_BOARD_ADLINK_RTV24:
2799 init_RTV24( btv ); 3179 init_RTV24( btv );
2800 break; 3180 break;
2801 3181
2802 } 3182 }
2803 if (!bttv_tvcards[btv->c.type].has_dvb) 3183 if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv)
2810 int tda9887; 3190 int tda9887;
2811 int addr=ADDR_UNSET; 3191 int addr=ADDR_UNSET;
2812 3192
2813 btv->tuner_type = -1; 3193 btv->tuner_type = -1;
2814 3194
2815 if (BTTV_UNKNOWN == btv->c.type) { 3195 if (BTTV_BOARD_UNKNOWN == btv->c.type) {
2816 bttv_readee(btv,eeprom_data,0xa0); 3196 bttv_readee(btv,eeprom_data,0xa0);
2817 identify_by_eeprom(btv,eeprom_data); 3197 identify_by_eeprom(btv,eeprom_data);
2818 } 3198 }
2819 3199
2820 switch (btv->c.type) { 3200 switch (btv->c.type) {
2821 case BTTV_MIRO: 3201 case BTTV_BOARD_MIRO:
2822 case BTTV_MIROPRO: 3202 case BTTV_BOARD_MIROPRO:
2823 case BTTV_PINNACLE: 3203 case BTTV_BOARD_PINNACLE:
2824 case BTTV_PINNACLEPRO: 3204 case BTTV_BOARD_PINNACLEPRO:
2825 /* miro/pinnacle */ 3205 /* miro/pinnacle */
2826 miro_pinnacle_gpio(btv); 3206 miro_pinnacle_gpio(btv);
2827 break; 3207 break;
2828 case BTTV_FLYVIDEO_98: 3208 case BTTV_BOARD_FLYVIDEO_98:
2829 case BTTV_MAXI: 3209 case BTTV_BOARD_MAXI:
2830 case BTTV_LIFE_FLYKIT: 3210 case BTTV_BOARD_LIFE_FLYKIT:
2831 case BTTV_FLYVIDEO: 3211 case BTTV_BOARD_FLYVIDEO:
2832 case BTTV_TYPHOON_TVIEW: 3212 case BTTV_BOARD_TYPHOON_TVIEW:
2833 case BTTV_CHRONOS_VS2: 3213 case BTTV_BOARD_CHRONOS_VS2:
2834 case BTTV_FLYVIDEO_98FM: 3214 case BTTV_BOARD_FLYVIDEO_98FM:
2835 case BTTV_FLYVIDEO2000: 3215 case BTTV_BOARD_FLYVIDEO2000:
2836 case BTTV_FLYVIDEO98EZ: 3216 case BTTV_BOARD_FLYVIDEO98EZ:
2837 case BTTV_CONFERENCETV: 3217 case BTTV_BOARD_CONFERENCETV:
2838 case BTTV_LIFETEC_9415: 3218 case BTTV_BOARD_LIFETEC_9415:
2839 flyvideo_gpio(btv); 3219 flyvideo_gpio(btv);
2840 break; 3220 break;
2841 case BTTV_HAUPPAUGE: 3221 case BTTV_BOARD_HAUPPAUGE:
2842 case BTTV_HAUPPAUGE878: 3222 case BTTV_BOARD_HAUPPAUGE878:
2843 case BTTV_HAUPPAUGEPVR: 3223 case BTTV_BOARD_HAUPPAUGEPVR:
2844 /* pick up some config infos from the eeprom */ 3224 /* pick up some config infos from the eeprom */
2845 bttv_readee(btv,eeprom_data,0xa0); 3225 bttv_readee(btv,eeprom_data,0xa0);
2846 hauppauge_eeprom(btv); 3226 hauppauge_eeprom(btv);
2847 break; 3227 break;
2848 case BTTV_AVERMEDIA98: 3228 case BTTV_BOARD_AVERMEDIA98:
2849 case BTTV_AVPHONE98: 3229 case BTTV_BOARD_AVPHONE98:
2850 bttv_readee(btv,eeprom_data,0xa0); 3230 bttv_readee(btv,eeprom_data,0xa0);
2851 avermedia_eeprom(btv); 3231 avermedia_eeprom(btv);
2852 break; 3232 break;
2853 case BTTV_PXC200: 3233 case BTTV_BOARD_PXC200:
2854 init_PXC200(btv); 3234 init_PXC200(btv);
2855 break; 3235 break;
2856 case BTTV_PICOLO_TETRA_CHIP: 3236 case BTTV_BOARD_PICOLO_TETRA_CHIP:
2857 picolo_tetra_init(btv); 3237 picolo_tetra_init(btv);
2858 break; 3238 break;
2859 case BTTV_VHX: 3239 case BTTV_BOARD_VHX:
2860 btv->has_radio = 1; 3240 btv->has_radio = 1;
2861 btv->has_matchbox = 1; 3241 btv->has_matchbox = 1;
2862 btv->mbox_we = 0x20; 3242 btv->mbox_we = 0x20;
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv)
2865 btv->mbox_data = 0x10; 3245 btv->mbox_data = 0x10;
2866 btv->mbox_mask = 0x38; 3246 btv->mbox_mask = 0x38;
2867 break; 3247 break;
2868 case BTTV_VOBIS_BOOSTAR: 3248 case BTTV_BOARD_VOBIS_BOOSTAR:
2869 case BTTV_TERRATV: 3249 case BTTV_BOARD_TERRATV:
2870 terratec_active_radio_upgrade(btv); 3250 terratec_active_radio_upgrade(btv);
2871 break; 3251 break;
2872 case BTTV_MAGICTVIEW061: 3252 case BTTV_BOARD_MAGICTVIEW061:
2873 if (btv->cardid == 0x3002144f) { 3253 if (btv->cardid == 0x3002144f) {
2874 btv->has_radio=1; 3254 btv->has_radio=1;
2875 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); 3255 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2876 } 3256 }
2877 break; 3257 break;
2878 case BTTV_STB2: 3258 case BTTV_BOARD_STB2:
2879 if (btv->cardid == 0x3060121a) { 3259 if (btv->cardid == 0x3060121a) {
2880 /* Fix up entry for 3DFX VoodooTV 100, 3260 /* Fix up entry for 3DFX VoodooTV 100,
2881 which is an OEM STB card variant. */ 3261 which is an OEM STB card variant. */
2882 btv->has_radio=0; 3262 btv->has_radio=0;
2883 btv->tuner_type=TUNER_TEMIC_NTSC; 3263 btv->tuner_type=TUNER_TEMIC_NTSC;
2884 } 3264 }
2885 break; 3265 break;
2886 case BTTV_OSPREY1x0: 3266 case BTTV_BOARD_OSPREY1x0:
2887 case BTTV_OSPREY1x0_848: 3267 case BTTV_BOARD_OSPREY1x0_848:
2888 case BTTV_OSPREY101_848: 3268 case BTTV_BOARD_OSPREY101_848:
2889 case BTTV_OSPREY1x1: 3269 case BTTV_BOARD_OSPREY1x1:
2890 case BTTV_OSPREY1x1_SVID: 3270 case BTTV_BOARD_OSPREY1x1_SVID:
2891 case BTTV_OSPREY2xx: 3271 case BTTV_BOARD_OSPREY2xx:
2892 case BTTV_OSPREY2x0_SVID: 3272 case BTTV_BOARD_OSPREY2x0_SVID:
2893 case BTTV_OSPREY2x0: 3273 case BTTV_BOARD_OSPREY2x0:
2894 case BTTV_OSPREY500: 3274 case BTTV_BOARD_OSPREY500:
2895 case BTTV_OSPREY540: 3275 case BTTV_BOARD_OSPREY540:
2896 case BTTV_OSPREY2000: 3276 case BTTV_BOARD_OSPREY2000:
2897 bttv_readee(btv,eeprom_data,0xa0); 3277 bttv_readee(btv,eeprom_data,0xa0);
2898 osprey_eeprom(btv); 3278 osprey_eeprom(btv);
2899 break; 3279 break;
2900 case BTTV_IDS_EAGLE: 3280 case BTTV_BOARD_IDS_EAGLE:
2901 init_ids_eagle(btv); 3281 init_ids_eagle(btv);
2902 break; 3282 break;
2903 case BTTV_MODTEC_205: 3283 case BTTV_BOARD_MODTEC_205:
2904 bttv_readee(btv,eeprom_data,0xa0); 3284 bttv_readee(btv,eeprom_data,0xa0);
2905 modtec_eeprom(btv); 3285 modtec_eeprom(btv);
2906 break; 3286 break;
2907 case BTTV_LMLBT4: 3287 case BTTV_BOARD_LMLBT4:
2908 init_lmlbt4x(btv); 3288 init_lmlbt4x(btv);
2909 break; 3289 break;
2910 case BTTV_TIBET_CS16: 3290 case BTTV_BOARD_TIBET_CS16:
2911 tibetCS16_init(btv); 3291 tibetCS16_init(btv);
2912 break; 3292 break;
2913 case BTTV_KODICOM_4400R: 3293 case BTTV_BOARD_KODICOM_4400R:
2914 kodicom4400r_init(btv); 3294 kodicom4400r_init(btv);
2915 break; 3295 break;
2916 } 3296 }
2917 3297
2918 /* pll configuration */ 3298 /* pll configuration */
2919 if (!(btv->id==848 && btv->revision==0x11)) { 3299 if (!(btv->id==848 && btv->revision==0x11)) {
2920 /* defaults from card list */ 3300 /* defaults from card list */
2921 if (PLL_28 == bttv_tvcards[btv->c.type].pll) { 3301 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2922 btv->pll.pll_ifreq=28636363; 3302 btv->pll.pll_ifreq=28636363;
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2927 btv->pll.pll_crystal=BT848_IFORM_XT1; 3307 btv->pll.pll_crystal=BT848_IFORM_XT1;
2928 } 3308 }
2929 /* insmod options can override */ 3309 /* insmod options can override */
2930 switch (pll[btv->c.nr]) { 3310 switch (pll[btv->c.nr]) {
2931 case 0: /* none */ 3311 case 0: /* none */
2932 btv->pll.pll_crystal = 0; 3312 btv->pll.pll_crystal = 0;
2933 btv->pll.pll_ifreq = 0; 3313 btv->pll.pll_ifreq = 0;
2934 btv->pll.pll_ofreq = 0; 3314 btv->pll.pll_ofreq = 0;
2935 break; 3315 break;
2936 case 1: /* 28 MHz */ 3316 case 1: /* 28 MHz */
2937 case 28: 3317 case 28:
2938 btv->pll.pll_ifreq = 28636363; 3318 btv->pll.pll_ifreq = 28636363;
2939 btv->pll.pll_ofreq = 0; 3319 btv->pll.pll_ofreq = 0;
2940 btv->pll.pll_crystal = BT848_IFORM_XT0; 3320 btv->pll.pll_crystal = BT848_IFORM_XT0;
2941 break; 3321 break;
2942 case 2: /* 35 MHz */ 3322 case 2: /* 35 MHz */
2943 case 35: 3323 case 35:
2944 btv->pll.pll_ifreq = 35468950; 3324 btv->pll.pll_ifreq = 35468950;
2945 btv->pll.pll_ofreq = 0; 3325 btv->pll.pll_ofreq = 0;
2946 btv->pll.pll_crystal = BT848_IFORM_XT1; 3326 btv->pll.pll_crystal = BT848_IFORM_XT1;
2947 break; 3327 break;
2948 } 3328 }
2949 } 3329 }
2950 btv->pll.pll_current = -1; 3330 btv->pll.pll_current = -1;
2951 3331
2952 /* tuner configuration (from card list / autodetect / insmod option) */ 3332 /* tuner configuration (from card list / autodetect / insmod option) */
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2955 3335
2956 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 3336 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2957 if(UNSET == btv->tuner_type) 3337 if(UNSET == btv->tuner_type)
2958 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; 3338 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2959 if (UNSET != tuner[btv->c.nr]) 3339 if (UNSET != tuner[btv->c.nr])
2960 btv->tuner_type = tuner[btv->c.nr]; 3340 btv->tuner_type = tuner[btv->c.nr];
2961 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); 3341 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2962 if (btv->pinnacle_id != UNSET) 3342
2963 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
2964 &btv->pinnacle_id);
2965 if (btv->tuner_type != UNSET) { 3343 if (btv->tuner_type != UNSET) {
2966 struct tuner_setup tun_setup; 3344 struct tuner_setup tun_setup;
2967 3345
2968 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 3346 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
2969 tun_setup.type = btv->tuner_type; 3347 tun_setup.type = btv->tuner_type;
2970 tun_setup.addr = addr; 3348 tun_setup.addr = addr;
2971 3349
2972 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 3350 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
2973 } 3351 }
2974 3352
3353 if (btv->pinnacle_id != UNSET) {
3354 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
3355 &btv->pinnacle_id);
3356 }
3357
2975 btv->svhs = bttv_tvcards[btv->c.type].svhs; 3358 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2976 if (svhs[btv->c.nr] != UNSET) 3359 if (svhs[btv->c.nr] != UNSET)
2977 btv->svhs = svhs[btv->c.nr]; 3360 btv->svhs = svhs[btv->c.nr];
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
2982 btv->has_radio=1; 3365 btv->has_radio=1;
2983 if (bttv_tvcards[btv->c.type].has_remote) 3366 if (bttv_tvcards[btv->c.type].has_remote)
2984 btv->has_remote=1; 3367 btv->has_remote=1;
2985 if (bttv_tvcards[btv->c.type].no_gpioirq) 3368 if (!bttv_tvcards[btv->c.type].no_gpioirq)
2986 btv->gpioirq=0; 3369 btv->gpioirq=1;
2987 if (bttv_tvcards[btv->c.type].audio_hook) 3370 if (bttv_tvcards[btv->c.type].audio_hook)
2988 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; 3371 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2989 3372
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
3024 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && 3407 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3025 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) 3408 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
3026 tda9887 = 1; 3409 tda9887 = 1;
3410 /* Hybrid DVB card, DOES have a tda9887 */
3411 if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
3412 tda9887 = 1;
3027 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || 3413 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
3028 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || 3414 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
3029 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || 3415 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv)
3045 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { 3431 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
3046 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; 3432 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
3047 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3433 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3048 btv->c.nr,&eeprom_data[0x1e]); 3434 btv->c.nr,&eeprom_data[0x1e]);
3049 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { 3435 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
3050 btv->tuner_type=TUNER_PHILIPS_NTSC; 3436 btv->tuner_type=TUNER_PHILIPS_NTSC;
3051 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3437 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3052 btv->c.nr,&eeprom_data[0x1e]); 3438 btv->c.nr,&eeprom_data[0x1e]);
3053 } else { 3439 } else {
3054 printk("bttv%d: Modtec: Unknown TunerString: %s\n", 3440 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
3055 btv->c.nr,&eeprom_data[0x1e]); 3441 btv->c.nr,&eeprom_data[0x1e]);
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
3114static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) 3500static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3115{ 3501{
3116 u32 n; 3502 u32 n;
3117 u8 bits; 3503 u8 bits;
3118 int i; 3504 int i;
3119 3505
3120 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); 3506 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3150 3536
3151static int __devinit pvr_boot(struct bttv *btv) 3537static int __devinit pvr_boot(struct bttv *btv)
3152{ 3538{
3153 const struct firmware *fw_entry; 3539 const struct firmware *fw_entry;
3154 int rc; 3540 int rc;
3155 3541
3156 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); 3542 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
3157 if (rc != 0) { 3543 if (rc != 0) {
3158 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", 3544 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
3159 btv->c.nr); 3545 btv->c.nr);
3160 return rc; 3546 return rc;
3161 } 3547 }
3162 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); 3548 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
3163 printk(KERN_INFO "bttv%d: altera firmware upload %s\n", 3549 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
3164 btv->c.nr, (rc < 0) ? "failed" : "ok"); 3550 btv->c.nr, (rc < 0) ? "failed" : "ok");
3165 release_firmware(fw_entry); 3551 release_firmware(fw_entry);
3166 return rc; 3552 return rc;
3167} 3553}
3168 3554
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3176 unsigned long serial = 0; 3562 unsigned long serial = 0;
3177 3563
3178 if (btv->c.type == 0) { 3564 if (btv->c.type == 0) {
3179 /* this might be an antique... check for MMAC label in eeprom */ 3565 /* this might be an antique... check for MMAC label in eeprom */
3180 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { 3566 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3181 unsigned char checksum = 0; 3567 unsigned char checksum = 0;
3182 for (i =0; i<21; i++) 3568 for (i =0; i<21; i++)
3183 checksum += ee[i]; 3569 checksum += ee[i];
3184 if (checksum != ee[21]) 3570 if (checksum != ee[21])
3185 return; 3571 return;
3186 btv->c.type = BTTV_OSPREY1x0_848; 3572 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3187 for (i = 12; i < 21; i++) 3573 for (i = 12; i < 21; i++)
3188 serial *= 10, serial += ee[i] - '0'; 3574 serial *= 10, serial += ee[i] - '0';
3189 } 3575 }
3190 } else { 3576 } else {
3191 unsigned short type; 3577 unsigned short type;
3192 int offset = 4*16; 3578 int offset = 4*16;
3193 3579
3194 for(; offset < 8*16; offset += 16) { 3580 for(; offset < 8*16; offset += 16) {
3195 unsigned short checksum = 0; 3581 unsigned short checksum = 0;
3196 /* verify the checksum */ 3582 /* verify the checksum */
3197 for(i = 0; i<14; i++) checksum += ee[i+offset]; 3583 for(i = 0; i<14; i++) checksum += ee[i+offset];
3198 checksum = ~checksum; /* no idea why */ 3584 checksum = ~checksum; /* no idea why */
3199 if ((((checksum>>8)&0x0FF) == ee[offset+14]) && 3585 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3200 ((checksum & 0x0FF) == ee[offset+15])) { 3586 ((checksum & 0x0FF) == ee[offset+15])) {
3201 break; 3587 break;
3202 } 3588 }
3203 } 3589 }
3204 3590
3205 if (offset >= 8*16) 3591 if (offset >= 8*16)
3206 return; 3592 return;
3207 3593
3208 /* found a valid descriptor */ 3594 /* found a valid descriptor */
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3212 3598
3213 /* 848 based */ 3599 /* 848 based */
3214 case 0x0004: 3600 case 0x0004:
3215 btv->c.type = BTTV_OSPREY1x0_848; 3601 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3216 break; 3602 break;
3217 case 0x0005: 3603 case 0x0005:
3218 btv->c.type = BTTV_OSPREY101_848; 3604 btv->c.type = BTTV_BOARD_OSPREY101_848;
3219 break; 3605 break;
3220 3606
3221 /* 878 based */ 3607 /* 878 based */
3222 case 0x0012: 3608 case 0x0012:
3223 case 0x0013: 3609 case 0x0013:
3224 btv->c.type = BTTV_OSPREY1x0; 3610 btv->c.type = BTTV_BOARD_OSPREY1x0;
3225 break; 3611 break;
3226 case 0x0014: 3612 case 0x0014:
3227 case 0x0015: 3613 case 0x0015:
3228 btv->c.type = BTTV_OSPREY1x1; 3614 btv->c.type = BTTV_BOARD_OSPREY1x1;
3229 break; 3615 break;
3230 case 0x0016: 3616 case 0x0016:
3231 case 0x0017: 3617 case 0x0017:
3232 case 0x0020: 3618 case 0x0020:
3233 btv->c.type = BTTV_OSPREY1x1_SVID; 3619 btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
3234 break; 3620 break;
3235 case 0x0018: 3621 case 0x0018:
3236 case 0x0019: 3622 case 0x0019:
3237 case 0x001E: 3623 case 0x001E:
3238 case 0x001F: 3624 case 0x001F:
3239 btv->c.type = BTTV_OSPREY2xx; 3625 btv->c.type = BTTV_BOARD_OSPREY2xx;
3240 break; 3626 break;
3241 case 0x001A: 3627 case 0x001A:
3242 case 0x001B: 3628 case 0x001B:
3243 btv->c.type = BTTV_OSPREY2x0_SVID; 3629 btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
3244 break; 3630 break;
3245 case 0x0040: 3631 case 0x0040:
3246 btv->c.type = BTTV_OSPREY500; 3632 btv->c.type = BTTV_BOARD_OSPREY500;
3247 break; 3633 break;
3248 case 0x0050: 3634 case 0x0050:
3249 case 0x0056: 3635 case 0x0056:
3250 btv->c.type = BTTV_OSPREY540; 3636 btv->c.type = BTTV_BOARD_OSPREY540;
3251 /* bttv_osprey_540_init(btv); */ 3637 /* bttv_osprey_540_init(btv); */
3252 break; 3638 break;
3253 case 0x0060: 3639 case 0x0060:
3254 case 0x0070: 3640 case 0x0070:
3255 btv->c.type = BTTV_OSPREY2x0; 3641 btv->c.type = BTTV_BOARD_OSPREY2x0;
3256 /* enable output on select control lines */ 3642 /* enable output on select control lines */
3257 gpio_inout(0xffffff,0x000303); 3643 gpio_inout(0xffffff,0x000303);
3258 break; 3644 break;
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3274/* AVermedia specific stuff, from bktr_card.c */ 3660/* AVermedia specific stuff, from bktr_card.c */
3275 3661
3276static int tuner_0_table[] = { 3662static int tuner_0_table[] = {
3277 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, 3663 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3278 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, 3664 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3279 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, 3665 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3280 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, 3666 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3281 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, 3667 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3282 TUNER_PHILIPS_FM1216ME_MK3 }; 3668 TUNER_PHILIPS_FM1216ME_MK3 };
3283 3669
3284static int tuner_1_table[] = { 3670static int tuner_1_table[] = {
3285 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, 3671 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3286 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3672 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3287 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3673 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3288 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ 3674 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3289 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; 3675 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3290 3676
3291static void __devinit avermedia_eeprom(struct bttv *btv) 3677static void __devinit avermedia_eeprom(struct bttv *btv)
3292{ 3678{
3293 int tuner_make,tuner_tv_fm,tuner_format,tuner=0; 3679 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3294 3680
3295 tuner_make = (eeprom_data[0x41] & 0x7); 3681 tuner_make = (eeprom_data[0x41] & 0x7);
3296 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; 3682 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3297 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; 3683 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3298 btv->has_remote = (eeprom_data[0x42] & 0x01); 3684 btv->has_remote = (eeprom_data[0x42] & 0x01);
3299 3685
3300 if (tuner_make == 0 || tuner_make == 2) 3686 if (tuner_make == 0 || tuner_make == 2)
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3325{ 3711{
3326 /* fix up our card entry */ 3712 /* fix up our card entry */
3327 if(norm==VIDEO_MODE_NTSC) { 3713 if(norm==VIDEO_MODE_NTSC) {
3328 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; 3714 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff;
3329 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; 3715 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff;
3330 dprintk("bttv_tda9880_setnorm to NTSC\n"); 3716 dprintk("bttv_tda9880_setnorm to NTSC\n");
3331 } 3717 }
3332 else { 3718 else {
3333 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; 3719 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff;
3334 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; 3720 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff;
3335 dprintk("bttv_tda9880_setnorm to PAL\n"); 3721 dprintk("bttv_tda9880_setnorm to PAL\n");
3336 } 3722 }
3337 /* set GPIO according */ 3723 /* set GPIO according */
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3342 3728
3343/* 3729/*
3344 * reset/enable the MSP on some Hauppauge cards 3730 * reset/enable the MSP on some Hauppauge cards
3345 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! 3731 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3346 * 3732 *
3347 * Hauppauge: pin 5 3733 * Hauppauge: pin 5
3348 * Voodoo: pin 20 3734 * Voodoo: pin 20
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3353 3739
3354 gpio_inout(mask,mask); 3740 gpio_inout(mask,mask);
3355 gpio_bits(mask,0); 3741 gpio_bits(mask,0);
3356 udelay(2500); 3742 udelay(2500);
3357 gpio_bits(mask,mask); 3743 gpio_bits(mask,mask);
3358 3744
3359 if (bttv_gpio) 3745 if (bttv_gpio)
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv)
3429 udelay(10); 3815 udelay(10);
3430 gpio_write(1<<2); 3816 gpio_write(1<<2);
3431 3817
3432 for (i = 0; i < ARRAY_SIZE(vals); i++) { 3818 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3433 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); 3819 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3434 if (tmp != -1) { 3820 if (tmp != -1) {
3435 printk(KERN_INFO 3821 printk(KERN_INFO
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3872static void 4258static void
3873lt9415_audio(struct bttv *btv, struct video_audio *v, int set) 4259lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3874{ 4260{
3875 int val = 0; 4261 int val = 0;
3876 4262
3877 if (gpio_read() & 0x4000) { 4263 if (gpio_read() & 0x4000) {
3878 v->mode = VIDEO_SOUND_MONO; 4264 v->mode = VIDEO_SOUND_MONO;
3879 return; 4265 return;
3880 } 4266 }
3881 4267
3882 if (set) { 4268 if (set) {
3883 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ 4269 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3884 val = 0x0080; 4270 val = 0x0080;
3885 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ 4271 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3886 val = 0x0880; 4272 val = 0x0880;
3887 if ((v->mode & VIDEO_SOUND_LANG1) || 4273 if ((v->mode & VIDEO_SOUND_LANG1) ||
3888 (v->mode & VIDEO_SOUND_MONO)) 4274 (v->mode & VIDEO_SOUND_MONO))
3889 val = 0; 4275 val = 0;
3890 gpio_bits(0x0880, val); 4276 gpio_bits(0x0880, val);
3891 if (bttv_gpio) 4277 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"lt9415"); 4278 bttv_gpio_tracking(btv,"lt9415");
3893 } else { 4279 } else {
3894 /* autodetect doesn't work with this card :-( */ 4280 /* autodetect doesn't work with this card :-( */
3895 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4281 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3896 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4282 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3897 return; 4283 return;
3898 } 4284 }
3899} 4285}
3900 4286
3901/* TDA9821 on TerraTV+ Bt848, Bt878 */ 4287/* TDA9821 on TerraTV+ Bt848, Bt878 */
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
4018static void 4404static void
4019windvr_audio(struct bttv *btv, struct video_audio *v, int set) 4405windvr_audio(struct bttv *btv, struct video_audio *v, int set)
4020{ 4406{
4021 unsigned long val = 0; 4407 unsigned long val = 0;
4022 4408
4023 if (set) { 4409 if (set) {
4024 if (v->mode & VIDEO_SOUND_MONO) 4410 if (v->mode & VIDEO_SOUND_MONO)
4025 val = 0x040000; 4411 val = 0x040000;
4026 if (v->mode & VIDEO_SOUND_LANG1) 4412 if (v->mode & VIDEO_SOUND_LANG1)
4027 val = 0; 4413 val = 0;
4028 if (v->mode & VIDEO_SOUND_LANG2) 4414 if (v->mode & VIDEO_SOUND_LANG2)
4029 val = 0x100000; 4415 val = 0x100000;
4030 if (v->mode & VIDEO_SOUND_STEREO) 4416 if (v->mode & VIDEO_SOUND_STEREO)
4031 val = 0; 4417 val = 0;
4032 if (val) { 4418 if (val) {
4033 gpio_bits(0x140000, val); 4419 gpio_bits(0x140000, val);
4034 if (bttv_gpio) 4420 if (bttv_gpio)
4035 bttv_gpio_tracking(btv,"windvr"); 4421 bttv_gpio_tracking(btv,"windvr");
4036 } 4422 }
4037 } else { 4423 } else {
4038 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4424 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4039 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4425 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4040 } 4426 }
4041} 4427}
4042 4428
4043/* 4429/*
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv)
4280static void xguard_muxsel(struct bttv *btv, unsigned int input) 4666static void xguard_muxsel(struct bttv *btv, unsigned int input)
4281{ 4667{
4282 static const int masks[] = { 4668 static const int masks[] = {
4283 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, 4669 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4284 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, 4670 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4285 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, 4671 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4286 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, 4672 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4287 }; 4673 };
4288 gpio_write(masks[input%16]); 4674 gpio_write(masks[input%16]);
4289} 4675}
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4388 4774
4389static void PXC200_muxsel(struct bttv *btv, unsigned int input) 4775static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4390{ 4776{
4391 int rc; 4777 int rc;
4392 long mux; 4778 long mux;
4393 int bitmask; 4779 int bitmask;
4394 unsigned char buf[2]; 4780 unsigned char buf[2];
4395 4781
4396 /* Read PIC config to determine if this is a PXC200F */ 4782 /* Read PIC config to determine if this is a PXC200F */
4397 /* PX_I2C_CMD_CFG*/ 4783 /* PX_I2C_CMD_CFG*/
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4421 /* bitmask=0x30f; */ 4807 /* bitmask=0x30f; */
4422 bitmask=0x302; 4808 bitmask=0x302;
4423 /* check whether we have a PXC200A */ 4809 /* check whether we have a PXC200A */
4424 if (btv->cardid == PX_PXC200A_CARDID) { 4810 if (btv->cardid == PX_PXC200A_CARDID) {
4425 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ 4811 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4426 bitmask |= 7<<4; /* the DAC */ 4812 bitmask |= 7<<4; /* the DAC */
4427 } 4813 }
4428 btwrite(bitmask, BT848_GPIO_OUT_EN); 4814 btwrite(bitmask, BT848_GPIO_OUT_EN);
4429 4815
4430 bitmask = btread(BT848_GPIO_DATA); 4816 bitmask = btread(BT848_GPIO_DATA);
4431 if (btv->cardid == PX_PXC200A_CARDID) 4817 if (btv->cardid == PX_PXC200A_CARDID)
4432 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); 4818 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4433 else /* older device */ 4819 else /* older device */
4434 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); 4820 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4441 * 4827 *
4442 * needed because bttv-driver sets mux before calling this function 4828 * needed because bttv-driver sets mux before calling this function
4443 */ 4829 */
4444 if (btv->cardid == PX_PXC200A_CARDID) 4830 if (btv->cardid == PX_PXC200A_CARDID)
4445 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); 4831 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4446 else /* older device */ 4832 else /* older device */
4447 btand(~BT848_IFORM_MUXSEL,BT848_IFORM); 4833 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void)
4485 } 4871 }
4486 if (UNSET != latency) 4872 if (UNSET != latency)
4487 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); 4873 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4488 4874 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
4489 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4490 PCI_DEVICE_ID_INTEL_82441, dev))) { 4875 PCI_DEVICE_ID_INTEL_82441, dev))) {
4491 unsigned char b; 4876 unsigned char b;
4492 pci_read_config_byte(dev, 0x53, &b); 4877 pci_read_config_byte(dev, 0x53, &b);
4493 if (bttv_debug) 4878 if (bttv_debug)
4494 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " 4879 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void)
4498 4883
4499int __devinit bttv_handle_chipset(struct bttv *btv) 4884int __devinit bttv_handle_chipset(struct bttv *btv)
4500{ 4885{
4501 unsigned char command; 4886 unsigned char command;
4502 4887
4503 if (!triton1 && !vsfx && UNSET == latency) 4888 if (!triton1 && !vsfx && UNSET == latency)
4504 return 0; 4889 return 0;
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv)
4519 btv->triton1 = BT848_INT_ETBF; 4904 btv->triton1 = BT848_INT_ETBF;
4520 } else { 4905 } else {
4521 /* bt878 has a bit in the pci config space for it */ 4906 /* bt878 has a bit in the pci config space for it */
4522 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); 4907 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4523 if (triton1) 4908 if (triton1)
4524 command |= BT878_EN_TBFX; 4909 command |= BT878_EN_TBFX;
4525 if (vsfx) 4910 if (vsfx)
4526 command |= BT878_EN_VSFX; 4911 command |= BT878_EN_VSFX;
4527 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); 4912 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4528 } 4913 }
4529 if (UNSET != latency) 4914 if (UNSET != latency)
4530 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); 4915 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4531 return 0; 4916 return 0;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index d538a994ff04..0005741d5514 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
3 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> 5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
6 & Marcus Metzler <mocm@thp.uni-koeln.de> 6 & Marcus Metzler <mocm@thp.uni-koeln.de>
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> 7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8 8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is 9 some v4l2 code lines are taken from Justin's bttv2 driver which is
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] =
192 192
193const struct bttv_tvnorm bttv_tvnorms[] = { 193const struct bttv_tvnorm bttv_tvnorms[] = {
194 /* PAL-BDGHI */ 194 /* PAL-BDGHI */
195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ 195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ 196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
197 { 197 {
198 .v4l2_id = V4L2_STD_PAL, 198 .v4l2_id = V4L2_STD_PAL,
199 .name = "PAL", 199 .name = "PAL",
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv)
806 btv->c.nr,table_idx); 806 btv->c.nr,table_idx);
807 807
808 /* timing change...reset timing generator address */ 808 /* timing change...reset timing generator address */
809 btwrite(0x00, BT848_TGCTRL); 809 btwrite(0x00, BT848_TGCTRL);
810 btwrite(0x02, BT848_TGCTRL); 810 btwrite(0x02, BT848_TGCTRL);
811 btwrite(0x00, BT848_TGCTRL); 811 btwrite(0x00, BT848_TGCTRL);
812 812
813 len=SRAM_Table[table_idx][0]; 813 len=SRAM_Table[table_idx][0];
814 for(i = 1; i <= len; i++) 814 for(i = 1; i <= len; i++)
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue)
847 847
848 /* -128 to 127 */ 848 /* -128 to 127 */
849 value = (hue >> 8) - 128; 849 value = (hue >> 8) - 128;
850 btwrite(value & 0xff, BT848_HUE); 850 btwrite(value & 0xff, BT848_HUE);
851} 851}
852 852
853static void bt848_contrast(struct bttv *btv, int cont) 853static void bt848_contrast(struct bttv *btv, int cont)
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont)
859 /* 0-511 */ 859 /* 0-511 */
860 value = (cont >> 7); 860 value = (cont >> 7);
861 hibit = (value >> 6) & 4; 861 hibit = (value >> 6) & 4;
862 btwrite(value & 0xff, BT848_CONTRAST_LO); 862 btwrite(value & 0xff, BT848_CONTRAST_LO);
863 btaor(hibit, ~4, BT848_E_CONTROL); 863 btaor(hibit, ~4, BT848_E_CONTROL);
864 btaor(hibit, ~4, BT848_O_CONTROL); 864 btaor(hibit, ~4, BT848_O_CONTROL);
865} 865}
866 866
867static void bt848_sat(struct bttv *btv, int color) 867static void bt848_sat(struct bttv *btv, int color)
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color)
873 /* 0-511 for the color */ 873 /* 0-511 for the color */
874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; 874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; 875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
876 hibits = (val_u >> 7) & 2; 876 hibits = (val_u >> 7) & 2;
877 hibits |= (val_v >> 8) & 1; 877 hibits |= (val_v >> 8) & 1;
878 btwrite(val_u & 0xff, BT848_SAT_U_LO); 878 btwrite(val_u & 0xff, BT848_SAT_U_LO);
879 btwrite(val_v & 0xff, BT848_SAT_V_LO); 879 btwrite(val_v & 0xff, BT848_SAT_V_LO);
880 btaor(hibits, ~3, BT848_E_CONTROL); 880 btaor(hibits, ~3, BT848_E_CONTROL);
881 btaor(hibits, ~3, BT848_O_CONTROL); 881 btaor(hibits, ~3, BT848_O_CONTROL);
882} 882}
883 883
884/* ----------------------------------------------------------------------- */ 884/* ----------------------------------------------------------------------- */
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input)
891 if (input >= bttv_tvcards[btv->c.type].video_inputs) 891 if (input >= bttv_tvcards[btv->c.type].video_inputs)
892 return -EINVAL; 892 return -EINVAL;
893 893
894 /* needed by RemoteVideo MX */ 894 /* needed by RemoteVideo MX */
895 mask2 = bttv_tvcards[btv->c.type].gpiomask2; 895 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
896 if (mask2) 896 if (mask2)
897 gpio_inout(mask2,mask2); 897 gpio_inout(mask2,mask2);
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv)
964 c.norm = btv->tvnorm; 964 c.norm = btv->tvnorm;
965 c.channel = btv->input; 965 c.channel = btv->input;
966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); 966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
967 if (btv->c.type == BTTV_VOODOOTV_FM) 967 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
968 bttv_tda9880_setnorm(btv,c.norm); 968 bttv_tda9880_setnorm(btv,c.norm);
969} 969}
970 970
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
988 bt848A_set_timing(btv); 988 bt848A_set_timing(btv);
989 989
990 switch (btv->c.type) { 990 switch (btv->c.type) {
991 case BTTV_VOODOOTV_FM: 991 case BTTV_BOARD_VOODOOTV_FM:
992 bttv_tda9880_setnorm(btv,norm); 992 bttv_tda9880_setnorm(btv,norm);
993 break; 993 break;
994 } 994 }
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv)
1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); 1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); 1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1057 1057
1058 /* set planar and packed mode trigger points and */ 1058 /* set planar and packed mode trigger points and */
1059 /* set rising edge of inverted GPINTR pin as irq trigger */ 1059 /* set rising edge of inverted GPINTR pin as irq trigger */
1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32| 1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1061 BT848_GPIO_DMA_CTL_PLTP1_16| 1061 BT848_GPIO_DMA_CTL_PLTP1_16|
1062 BT848_GPIO_DMA_CTL_PLTP23_16| 1062 BT848_GPIO_DMA_CTL_PLTP23_16|
1063 BT848_GPIO_DMA_CTL_GPINTC| 1063 BT848_GPIO_DMA_CTL_GPINTC|
1064 BT848_GPIO_DMA_CTL_GPINTI, 1064 BT848_GPIO_DMA_CTL_GPINTI,
1065 BT848_GPIO_DMA_CTL); 1065 BT848_GPIO_DMA_CTL);
1066 1066
1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; 1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1068 btwrite(val, BT848_E_SCLOOP); 1068 btwrite(val, BT848_E_SCLOOP);
1069 btwrite(val, BT848_O_SCLOOP); 1069 btwrite(val, BT848_O_SCLOOP);
1070 1070
1071 btwrite(0x20, BT848_E_VSCALE_HI); 1071 btwrite(0x20, BT848_E_VSCALE_HI);
1072 btwrite(0x20, BT848_O_VSCALE_HI); 1072 btwrite(0x20, BT848_O_VSCALE_HI);
1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), 1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1074 BT848_ADC); 1074 BT848_ADC);
1075 1075
1076 btwrite(whitecrush_upper, BT848_WC_UP); 1076 btwrite(whitecrush_upper, BT848_WC_UP);
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv)
1089 bt848_contrast(btv, btv->contrast); 1089 bt848_contrast(btv, btv->contrast);
1090 bt848_sat(btv, btv->saturation); 1090 bt848_sat(btv, btv->saturation);
1091 1091
1092 /* interrupt */ 1092 /* interrupt */
1093 init_irqreg(btv); 1093 init_irqreg(btv);
1094} 1094}
1095 1095
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
1105 spin_unlock_irqrestore(&btv->s_lock,flags); 1105 spin_unlock_irqrestore(&btv->s_lock,flags);
1106 1106
1107 init_bt848(btv); 1107 init_bt848(btv);
1108 btv->pll.pll_current = -1; 1108 btv->pll.pll_current = -1;
1109 set_input(btv,btv->input); 1109 set_input(btv,btv->input);
1110} 1110}
1111 1111
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1398/* video4linux (1) interface */ 1398/* video4linux (1) interface */
1399 1399
1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, 1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1401 const struct bttv_format *fmt, 1401 const struct bttv_format *fmt,
1402 unsigned int width, unsigned int height, 1402 unsigned int width, unsigned int height,
1403 enum v4l2_field field) 1403 enum v4l2_field field)
1404{ 1404{
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = {
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) 1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{ 1522{
1523 switch (cmd) { 1523 switch (cmd) {
1524 case BTTV_VERSION: 1524 case BTTV_VERSION:
1525 return BTTV_VERSION_CODE; 1525 return BTTV_VERSION_CODE;
1526 1526
1527 /* *** v4l1 *** ************************************************ */ 1527 /* *** v4l1 *** ************************************************ */
1528 case VIDIOCGFREQ: 1528 case VIDIOCGFREQ:
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1576 return 0; 1576 return 0;
1577 } 1577 }
1578 1578
1579 case VIDIOCGCHAN: 1579 case VIDIOCGCHAN:
1580 { 1580 {
1581 struct video_channel *v = arg; 1581 struct video_channel *v = arg;
1582 unsigned int channel = v->channel; 1582 unsigned int channel = v->channel;
1583 1583
1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1585 return -EINVAL; 1585 return -EINVAL;
1586 v->tuners=0; 1586 v->tuners=0;
1587 v->flags = VIDEO_VC_AUDIO; 1587 v->flags = VIDEO_VC_AUDIO;
1588 v->type = VIDEO_TYPE_CAMERA; 1588 v->type = VIDEO_TYPE_CAMERA;
1589 v->norm = btv->tvnorm; 1589 v->norm = btv->tvnorm;
1590 if (channel == bttv_tvcards[btv->c.type].tuner) { 1590 if (channel == bttv_tvcards[btv->c.type].tuner) {
1591 strcpy(v->name,"Television"); 1591 strcpy(v->name,"Television");
1592 v->flags|=VIDEO_VC_TUNER; 1592 v->flags|=VIDEO_VC_TUNER;
1593 v->type=VIDEO_TYPE_TV; 1593 v->type=VIDEO_TYPE_TV;
1594 v->tuners=1; 1594 v->tuners=1;
1595 } else if (channel == btv->svhs) { 1595 } else if (channel == btv->svhs) {
1596 strcpy(v->name,"S-Video"); 1596 strcpy(v->name,"S-Video");
1597 } else { 1597 } else {
1598 sprintf(v->name,"Composite%d",channel); 1598 sprintf(v->name,"Composite%d",channel);
1599 } 1599 }
1600 return 0; 1600 return 0;
1601 } 1601 }
1602 case VIDIOCSCHAN: 1602 case VIDIOCSCHAN:
1603 { 1603 {
1604 struct video_channel *v = arg; 1604 struct video_channel *v = arg;
1605 unsigned int channel = v->channel; 1605 unsigned int channel = v->channel;
1606 1606
1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1623 return 0; 1623 return 0;
1624 } 1624 }
1625 1625
1626 case VIDIOCGAUDIO: 1626 case VIDIOCGAUDIO:
1627 { 1627 {
1628 struct video_audio *v = arg; 1628 struct video_audio *v = arg;
1629 1629
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1728 } else if (i->index == btv->svhs) { 1728 } else if (i->index == btv->svhs) {
1729 sprintf(i->name, "S-Video"); 1729 sprintf(i->name, "S-Video");
1730 } else { 1730 } else {
1731 sprintf(i->name,"Composite%d",i->index); 1731 sprintf(i->name,"Composite%d",i->index);
1732 } 1732 }
1733 if (i->index == btv->input) { 1733 if (i->index == btv->input) {
1734 __u32 dstatus = btread(BT848_DSTATUS); 1734 __u32 dstatus = btread(BT848_DSTATUS);
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1851 up(&btv->lock); 1851 up(&btv->lock);
1852 return 0; 1852 return 0;
1853 } 1853 }
1854 case VIDIOC_LOG_STATUS:
1855 {
1856 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
1857 return 0;
1858 }
1854 1859
1855 default: 1860 default:
1856 return -ENOIOCTLCMD; 1861 return -ENOIOCTLCMD;
@@ -2163,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2163 if (0 != retval) 2168 if (0 != retval)
2164 return retval; 2169 return retval;
2165 if (locked_btres(fh->btv, RESOURCE_VBI)) 2170 if (locked_btres(fh->btv, RESOURCE_VBI))
2166 return -EBUSY; 2171 return -EBUSY;
2167 bttv_vbi_try_fmt(fh,f); 2172 bttv_vbi_try_fmt(fh,f);
2168 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); 2173 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2169 bttv_vbi_get_fmt(fh,f); 2174 bttv_vbi_get_fmt(fh,f);
@@ -2201,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2201 bttv_reinit_bt848(btv); 2206 bttv_reinit_bt848(btv);
2202 2207
2203 switch (cmd) { 2208 switch (cmd) {
2204 case VIDIOCSFREQ: 2209 case VIDIOCSFREQ:
2205 case VIDIOCSTUNER: 2210 case VIDIOCSTUNER:
2206 case VIDIOCSCHAN: 2211 case VIDIOCSCHAN:
2207 case VIDIOC_S_CTRL: 2212 case VIDIOC_S_CTRL:
2208 case VIDIOC_S_STD: 2213 case VIDIOC_S_STD:
2209 case VIDIOC_S_INPUT: 2214 case VIDIOC_S_INPUT:
@@ -2219,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2219 /* *** v4l1 *** ************************************************ */ 2224 /* *** v4l1 *** ************************************************ */
2220 case VIDIOCGCAP: 2225 case VIDIOCGCAP:
2221 { 2226 {
2222 struct video_capability *cap = arg; 2227 struct video_capability *cap = arg;
2223 2228
2224 memset(cap,0,sizeof(*cap)); 2229 memset(cap,0,sizeof(*cap));
2225 strcpy(cap->name,btv->video_dev->name); 2230 strcpy(cap->name,btv->video_dev->name);
2226 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 2231 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2227 /* vbi */ 2232 /* vbi */
2228 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; 2233 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2242,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2242 } 2247 }
2243 cap->channels = bttv_tvcards[btv->c.type].video_inputs; 2248 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2244 cap->audios = bttv_tvcards[btv->c.type].audio_inputs; 2249 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2245 return 0; 2250 return 0;
2246 } 2251 }
2247 2252
2248 case VIDIOCGPICT: 2253 case VIDIOCGPICT:
@@ -2291,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2291 bt848_hue(btv,pic->hue); 2296 bt848_hue(btv,pic->hue);
2292 bt848_sat(btv,pic->colour); 2297 bt848_sat(btv,pic->colour);
2293 up(&fh->cap.lock); 2298 up(&fh->cap.lock);
2294 return 0; 2299 return 0;
2295 } 2300 }
2296 2301
2297 case VIDIOCGWIN: 2302 case VIDIOCGWIN:
@@ -2352,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2352 unsigned long end; 2357 unsigned long end;
2353 2358
2354 if(!capable(CAP_SYS_ADMIN) && 2359 if(!capable(CAP_SYS_ADMIN) &&
2355 !capable(CAP_SYS_RAWIO)) 2360 !capable(CAP_SYS_RAWIO))
2356 return -EPERM; 2361 return -EPERM;
2357 end = (unsigned long)fbuf->base + 2362 end = (unsigned long)fbuf->base +
2358 fbuf->height * fbuf->bytesperline; 2363 fbuf->height * fbuf->bytesperline;
2359 down(&fh->cap.lock); 2364 down(&fh->cap.lock);
@@ -2427,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2427 } 2432 }
2428 2433
2429 /* switch over */ 2434 /* switch over */
2430 retval = bttv_switch_overlay(btv,fh,new); 2435 retval = bttv_switch_overlay(btv,fh,new);
2431 up(&fh->cap.lock); 2436 up(&fh->cap.lock);
2432 return retval; 2437 return retval;
2433 } 2438 }
@@ -2566,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2566 return 0; 2571 return 0;
2567 } 2572 }
2568 2573
2569 case BTTV_VERSION: 2574 case BTTV_VERSION:
2570 case VIDIOCGFREQ: 2575 case VIDIOCGFREQ:
2571 case VIDIOCSFREQ: 2576 case VIDIOCSFREQ:
2572 case VIDIOCGTUNER: 2577 case VIDIOCGTUNER:
2573 case VIDIOCSTUNER: 2578 case VIDIOCSTUNER:
2574 case VIDIOCGCHAN: 2579 case VIDIOCGCHAN:
2575 case VIDIOCSCHAN: 2580 case VIDIOCSCHAN:
2576 case VIDIOCGAUDIO: 2581 case VIDIOCGAUDIO:
2577 case VIDIOCSAUDIO: 2582 case VIDIOCSAUDIO:
2578 return bttv_common_ioctls(btv,cmd,arg); 2583 return bttv_common_ioctls(btv,cmd,arg);
@@ -2584,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2584 2589
2585 if (0 == v4l2) 2590 if (0 == v4l2)
2586 return -EINVAL; 2591 return -EINVAL;
2587 strcpy(cap->driver,"bttv"); 2592 strcpy(cap->driver,"bttv");
2588 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); 2593 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2589 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); 2594 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2590 cap->version = BTTV_VERSION_CODE; 2595 cap->version = BTTV_VERSION_CODE;
2591 cap->capabilities = 2596 cap->capabilities =
@@ -2856,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2856 case VIDIOC_S_TUNER: 2861 case VIDIOC_S_TUNER:
2857 case VIDIOC_G_FREQUENCY: 2862 case VIDIOC_G_FREQUENCY:
2858 case VIDIOC_S_FREQUENCY: 2863 case VIDIOC_S_FREQUENCY:
2864 case VIDIOC_LOG_STATUS:
2859 return bttv_common_ioctls(btv,cmd,arg); 2865 return bttv_common_ioctls(btv,cmd,arg);
2860 2866
2861 default: 2867 default:
@@ -3091,7 +3097,7 @@ static struct video_device bttv_video_template =
3091{ 3097{
3092 .name = "UNSET", 3098 .name = "UNSET",
3093 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| 3099 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3094 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 3100 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3095 .hardware = VID_HARDWARE_BT848, 3101 .hardware = VID_HARDWARE_BT848,
3096 .fops = &bttv_fops, 3102 .fops = &bttv_fops,
3097 .minor = -1, 3103 .minor = -1,
@@ -3137,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file)
3137 audio_mux(btv,AUDIO_RADIO); 3143 audio_mux(btv,AUDIO_RADIO);
3138 3144
3139 up(&btv->lock); 3145 up(&btv->lock);
3140 return 0; 3146 return 0;
3141} 3147}
3142 3148
3143static int radio_release(struct inode *inode, struct file *file) 3149static int radio_release(struct inode *inode, struct file *file)
@@ -3160,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
3160 switch (cmd) { 3166 switch (cmd) {
3161 case VIDIOCGCAP: 3167 case VIDIOCGCAP:
3162 { 3168 {
3163 struct video_capability *cap = arg; 3169 struct video_capability *cap = arg;
3164 3170
3165 memset(cap,0,sizeof(*cap)); 3171 memset(cap,0,sizeof(*cap));
3166 strcpy(cap->name,btv->radio_dev->name); 3172 strcpy(cap->name,btv->radio_dev->name);
3167 cap->type = VID_TYPE_TUNER; 3173 cap->type = VID_TYPE_TUNER;
3168 cap->channels = 1; 3174 cap->channels = 1;
3169 cap->audios = 1; 3175 cap->audios = 1;
3170 return 0; 3176 return 0;
3171 } 3177 }
3172 3178
3173 case VIDIOCGTUNER: 3179 case VIDIOCGTUNER:
3174 { 3180 {
3175 struct video_tuner *v = arg; 3181 struct video_tuner *v = arg;
3176 3182
3177 if(v->tuner) 3183 if(v->tuner)
3178 return -EINVAL; 3184 return -EINVAL;
3179 memset(v,0,sizeof(*v)); 3185 memset(v,0,sizeof(*v));
3180 strcpy(v->name, "Radio"); 3186 strcpy(v->name, "Radio");
3181 bttv_call_i2c_clients(btv,cmd,v); 3187 bttv_call_i2c_clients(btv,cmd,v);
3182 return 0; 3188 return 0;
3183 } 3189 }
3184 case VIDIOCSTUNER: 3190 case VIDIOCSTUNER:
3185 /* nothing to do */ 3191 /* nothing to do */
3186 return 0; 3192 return 0;
3187 3193
3188 case BTTV_VERSION: 3194 case BTTV_VERSION:
3189 case VIDIOCGFREQ: 3195 case VIDIOCGFREQ:
3190 case VIDIOCSFREQ: 3196 case VIDIOCSFREQ:
3191 case VIDIOCGAUDIO: 3197 case VIDIOCGAUDIO:
3192 case VIDIOCSAUDIO: 3198 case VIDIOCSAUDIO:
3193 return bttv_common_ioctls(btv,cmd,arg); 3199 return bttv_common_ioctls(btv,cmd,arg);
@@ -3693,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3693 } 3699 }
3694 3700
3695 if (astat&BT848_INT_VSYNC) 3701 if (astat&BT848_INT_VSYNC)
3696 btv->field_count++; 3702 btv->field_count++;
3697 3703
3698 if (astat & BT848_INT_GPINT) { 3704 if (astat & BT848_INT_GPINT) {
3699 wake_up(&btv->gpioq); 3705 wake_up(&btv->gpioq);
@@ -3705,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3705 wake_up(&btv->i2c_queue); 3711 wake_up(&btv->i2c_queue);
3706 } 3712 }
3707 3713
3708 if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) 3714 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3709 bttv_irq_switch_vbi(btv); 3715 bttv_irq_switch_vbi(btv);
3710 3716
3711 if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) 3717 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3712 bttv_irq_wakeup_top(btv); 3718 bttv_irq_wakeup_top(btv);
3713 3719
3714 if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) 3720 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3715 bttv_irq_switch_video(btv); 3721 bttv_irq_switch_video(btv);
3716 3722
3717 if ((astat & BT848_INT_HLOCK) && btv->opt_automute) 3723 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
@@ -3736,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3736 3742
3737 count++; 3743 count++;
3738 if (count > 4) { 3744 if (count > 4) {
3739 btwrite(0, BT848_INT_MASK); 3745
3740 printk(KERN_ERR 3746 if (count > 8 || !(astat & BT848_INT_GPINT)) {
3741 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); 3747 btwrite(0, BT848_INT_MASK);
3748
3749 printk(KERN_ERR
3750 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3751 } else {
3752 printk(KERN_ERR
3753 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3754
3755 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3756 BT848_INT_MASK);
3757 };
3758
3742 bttv_print_irqbits(stat,astat); 3759 bttv_print_irqbits(stat,astat);
3760
3743 printk("]\n"); 3761 printk("]\n");
3744 } 3762 }
3745 } 3763 }
@@ -3808,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
3808 3826
3809 /* video */ 3827 /* video */
3810 btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); 3828 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3811 if (NULL == btv->video_dev) 3829 if (NULL == btv->video_dev)
3812 goto err; 3830 goto err;
3813 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) 3831 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3814 goto err; 3832 goto err;
@@ -3818,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv)
3818 3836
3819 /* vbi */ 3837 /* vbi */
3820 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); 3838 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3821 if (NULL == btv->vbi_dev) 3839 if (NULL == btv->vbi_dev)
3822 goto err; 3840 goto err;
3823 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 3841 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3824 goto err; 3842 goto err;
3825 printk(KERN_INFO "bttv%d: registered device vbi%d\n", 3843 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3826 btv->c.nr,btv->vbi_dev->minor & 0x1f); 3844 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3827 3845
3828 if (!btv->has_radio) 3846 if (!btv->has_radio)
3829 return 0; 3847 return 0;
3830 /* radio */ 3848 /* radio */
3831 btv->radio_dev = vdev_init(btv, &radio_template, "radio"); 3849 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3832 if (NULL == btv->radio_dev) 3850 if (NULL == btv->radio_dev)
3833 goto err; 3851 goto err;
3834 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) 3852 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3835 goto err; 3853 goto err;
@@ -3850,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv)
3850static void pci_set_command(struct pci_dev *dev) 3868static void pci_set_command(struct pci_dev *dev)
3851{ 3869{
3852#if defined(__powerpc__) 3870#if defined(__powerpc__)
3853 unsigned int cmd; 3871 unsigned int cmd;
3854 3872
3855 pci_read_config_dword(dev, PCI_COMMAND, &cmd); 3873 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3856 cmd = (cmd | PCI_COMMAND_MEMORY ); 3874 cmd = (cmd | PCI_COMMAND_MEMORY );
3857 pci_write_config_dword(dev, PCI_COMMAND, cmd); 3875 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3858#endif 3876#endif
3859} 3877}
3860 3878
@@ -3868,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3868 if (bttv_num == BTTV_MAX) 3886 if (bttv_num == BTTV_MAX)
3869 return -ENOMEM; 3887 return -ENOMEM;
3870 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); 3888 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3871 btv=&bttvs[bttv_num]; 3889 btv=&bttvs[bttv_num];
3872 memset(btv,0,sizeof(*btv)); 3890 memset(btv,0,sizeof(*btv));
3873 btv->c.nr = bttv_num; 3891 btv->c.nr = bttv_num;
3874 sprintf(btv->c.name,"bttv%d",btv->c.nr); 3892 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3875 3893
3876 /* initialize structs / fill in defaults */ 3894 /* initialize structs / fill in defaults */
3877 init_MUTEX(&btv->lock); 3895 init_MUTEX(&btv->lock);
3878 init_MUTEX(&btv->reslock); 3896 init_MUTEX(&btv->reslock);
3879 spin_lock_init(&btv->s_lock); 3897 spin_lock_init(&btv->s_lock);
3880 spin_lock_init(&btv->gpio_lock); 3898 spin_lock_init(&btv->gpio_lock);
3881 init_waitqueue_head(&btv->gpioq); 3899 init_waitqueue_head(&btv->gpioq);
3882 init_waitqueue_head(&btv->i2c_queue); 3900 init_waitqueue_head(&btv->i2c_queue);
3883 INIT_LIST_HEAD(&btv->c.subs); 3901 INIT_LIST_HEAD(&btv->c.subs);
3884 INIT_LIST_HEAD(&btv->capture); 3902 INIT_LIST_HEAD(&btv->capture);
3885 INIT_LIST_HEAD(&btv->vcapture); 3903 INIT_LIST_HEAD(&btv->vcapture);
3886 v4l2_prio_init(&btv->prio); 3904 v4l2_prio_init(&btv->prio);
3887 3905
3888 init_timer(&btv->timeout); 3906 init_timer(&btv->timeout);
3889 btv->timeout.function = bttv_irq_timeout; 3907 btv->timeout.function = bttv_irq_timeout;
3890 btv->timeout.data = (unsigned long)btv; 3908 btv->timeout.data = (unsigned long)btv;
3891 3909
3892 btv->i2c_rc = -1; 3910 btv->i2c_rc = -1;
3893 btv->tuner_type = UNSET; 3911 btv->tuner_type = UNSET;
3894 btv->pinnacle_id = UNSET; 3912 btv->pinnacle_id = UNSET;
3895 btv->new_input = UNSET; 3913 btv->new_input = UNSET;
3896 btv->gpioirq = 1;
3897 btv->has_radio=radio[btv->c.nr]; 3914 btv->has_radio=radio[btv->c.nr];
3898 3915
3899 /* pci stuff (init, get irq/mmio, ... */ 3916 /* pci stuff (init, get irq/mmio, ... */
3900 btv->c.pci = dev; 3917 btv->c.pci = dev;
3901 btv->id = dev->device; 3918 btv->id = dev->device;
3902 if (pci_enable_device(dev)) { 3919 if (pci_enable_device(dev)) {
3903 printk(KERN_WARNING "bttv%d: Can't enable device.\n", 3920 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3904 btv->c.nr); 3921 btv->c.nr);
3905 return -EIO; 3922 return -EIO;
3906 } 3923 }
3907 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { 3924 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
3908 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", 3925 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3909 btv->c.nr); 3926 btv->c.nr);
3910 return -EIO; 3927 return -EIO;
3911 } 3928 }
3912 if (!request_mem_region(pci_resource_start(dev,0), 3929 if (!request_mem_region(pci_resource_start(dev,0),
3913 pci_resource_len(dev,0), 3930 pci_resource_len(dev,0),
3914 btv->c.name)) { 3931 btv->c.name)) {
3915 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", 3932 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3916 btv->c.nr, pci_resource_start(dev,0)); 3933 btv->c.nr, pci_resource_start(dev,0));
3917 return -EBUSY; 3934 return -EBUSY;
3918 } 3935 }
3919 pci_set_master(dev); 3936 pci_set_master(dev);
3920 pci_set_command(dev); 3937 pci_set_command(dev);
3921 pci_set_drvdata(dev,btv); 3938 pci_set_drvdata(dev,btv);
3922 3939
3923 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 3940 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3924 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 3941 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3925 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 3942 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3926 bttv_num,btv->id, btv->revision, pci_name(dev)); 3943 bttv_num,btv->id, btv->revision, pci_name(dev));
3927 printk("irq: %d, latency: %d, mmio: 0x%lx\n", 3944 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3928 btv->c.pci->irq, lat, pci_resource_start(dev,0)); 3945 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3929 schedule(); 3946 schedule();
3930 3947
@@ -3935,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3935 goto fail1; 3952 goto fail1;
3936 } 3953 }
3937 3954
3938 /* identify card */ 3955 /* identify card */
3939 bttv_idcard(btv); 3956 bttv_idcard(btv);
3940 3957
3941 /* disable irqs, register irq handler */ 3958 /* disable irqs, register irq handler */
3942 btwrite(0, BT848_INT_MASK); 3959 btwrite(0, BT848_INT_MASK);
3943 result = request_irq(btv->c.pci->irq, bttv_irq, 3960 result = request_irq(btv->c.pci->irq, bttv_irq,
3944 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); 3961 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3945 if (result < 0) { 3962 if (result < 0) {
3946 printk(KERN_ERR "bttv%d: can't get IRQ %d\n", 3963 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3947 bttv_num,btv->c.pci->irq); 3964 bttv_num,btv->c.pci->irq);
3948 goto fail1; 3965 goto fail1;
3949 } 3966 }
3950 3967
3951 if (0 != bttv_handle_chipset(btv)) { 3968 if (0 != bttv_handle_chipset(btv)) {
3952 result = -EIO; 3969 result = -EIO;
3953 goto fail2; 3970 goto fail2;
3954 } 3971 }
3955 3972
3956 /* init options from insmod args */ 3973 /* init options from insmod args */
3957 btv->opt_combfilter = combfilter; 3974 btv->opt_combfilter = combfilter;
@@ -3977,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3977 btv->input = 0; 3994 btv->input = 0;
3978 3995
3979 /* initialize hardware */ 3996 /* initialize hardware */
3980 if (bttv_gpio) 3997 if (bttv_gpio)
3981 bttv_gpio_tracking(btv,"pre-init"); 3998 bttv_gpio_tracking(btv,"pre-init");
3982 3999
3983 bttv_risc_init_main(btv); 4000 bttv_risc_init_main(btv);
3984 init_bt848(btv); 4001 init_bt848(btv);
3985 4002
3986 /* gpio */ 4003 /* gpio */
3987 btwrite(0x00, BT848_GPIO_REG_INP); 4004 btwrite(0x00, BT848_GPIO_REG_INP);
3988 btwrite(0x00, BT848_GPIO_OUT_EN); 4005 btwrite(0x00, BT848_GPIO_OUT_EN);
3989 if (bttv_verbose) 4006 if (bttv_verbose)
3990 bttv_gpio_tracking(btv,"init"); 4007 bttv_gpio_tracking(btv,"init");
3991 4008
3992 /* needs to be done before i2c is registered */ 4009 /* needs to be done before i2c is registered */
3993 bttv_init_card1(btv); 4010 bttv_init_card1(btv);
3994 4011
3995 /* register i2c + gpio */ 4012 /* register i2c + gpio */
3996 init_bttv_i2c(btv); 4013 init_bttv_i2c(btv);
3997 4014
3998 /* some card-specific stuff (needs working i2c) */ 4015 /* some card-specific stuff (needs working i2c) */
3999 bttv_init_card2(btv); 4016 bttv_init_card2(btv);
4000 init_irqreg(btv); 4017 init_irqreg(btv);
4001 4018
4002 /* register video4linux + input */ 4019 /* register video4linux + input */
4003 if (!bttv_tvcards[btv->c.type].no_video) { 4020 if (!bttv_tvcards[btv->c.type].no_video) {
4004 bttv_register_video(btv); 4021 bttv_register_video(btv);
4005 bt848_bright(btv,32768); 4022 bt848_bright(btv,32768);
@@ -4018,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4018 4035
4019 /* everything is fine */ 4036 /* everything is fine */
4020 bttv_num++; 4037 bttv_num++;
4021 return 0; 4038 return 0;
4022 4039
4023 fail2: 4040 fail2:
4024 free_irq(btv->c.pci->irq,btv); 4041 free_irq(btv->c.pci->irq,btv);
4025 4042
4026 fail1: 4043 fail1:
4027 if (btv->bt848_mmio) 4044 if (btv->bt848_mmio)
@@ -4034,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4034 4051
4035static void __devexit bttv_remove(struct pci_dev *pci_dev) 4052static void __devexit bttv_remove(struct pci_dev *pci_dev)
4036{ 4053{
4037 struct bttv *btv = pci_get_drvdata(pci_dev); 4054 struct bttv *btv = pci_get_drvdata(pci_dev);
4038 4055
4039 if (bttv_verbose) 4056 if (bttv_verbose)
4040 printk("bttv%d: unloading\n",btv->c.nr); 4057 printk("bttv%d: unloading\n",btv->c.nr);
4041 4058
4042 /* shutdown everything (DMA+IRQs) */ 4059 /* shutdown everything (DMA+IRQs) */
4043 btand(~15, BT848_GPIO_DMA_CTL); 4060 btand(~15, BT848_GPIO_DMA_CTL);
4044 btwrite(0, BT848_INT_MASK); 4061 btwrite(0, BT848_INT_MASK);
4045 btwrite(~0x0, BT848_INT_STAT); 4062 btwrite(~0x0, BT848_INT_STAT);
@@ -4052,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4052 wake_up(&btv->gpioq); 4069 wake_up(&btv->gpioq);
4053 bttv_sub_del_devices(&btv->c); 4070 bttv_sub_del_devices(&btv->c);
4054 4071
4055 /* unregister i2c_bus + input */ 4072 /* unregister i2c_bus + input */
4056 fini_bttv_i2c(btv); 4073 fini_bttv_i2c(btv);
4057 4074
4058 /* unregister video4linux */ 4075 /* unregister video4linux */
@@ -4062,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4062 btcx_riscmem_free(btv->c.pci,&btv->main); 4079 btcx_riscmem_free(btv->c.pci,&btv->main);
4063 4080
4064 /* free ressources */ 4081 /* free ressources */
4065 free_irq(btv->c.pci->irq,btv); 4082 free_irq(btv->c.pci->irq,btv);
4066 iounmap(btv->bt848_mmio); 4083 iounmap(btv->bt848_mmio);
4067 release_mem_region(pci_resource_start(btv->c.pci,0), 4084 release_mem_region(pci_resource_start(btv->c.pci,0),
4068 pci_resource_len(btv->c.pci,0)); 4085 pci_resource_len(btv->c.pci,0));
4069 4086
4070 pci_set_drvdata(pci_dev, NULL); 4087 pci_set_drvdata(pci_dev, NULL);
4071 return; 4088 return;
4072} 4089}
4073 4090
4074static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) 4091static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4075{ 4092{
4076 struct bttv *btv = pci_get_drvdata(pci_dev); 4093 struct bttv *btv = pci_get_drvdata(pci_dev);
4077 struct bttv_buffer_set idle; 4094 struct bttv_buffer_set idle;
4078 unsigned long flags; 4095 unsigned long flags;
4079 4096
@@ -4108,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4108 4125
4109static int bttv_resume(struct pci_dev *pci_dev) 4126static int bttv_resume(struct pci_dev *pci_dev)
4110{ 4127{
4111 struct bttv *btv = pci_get_drvdata(pci_dev); 4128 struct bttv *btv = pci_get_drvdata(pci_dev);
4112 unsigned long flags; 4129 unsigned long flags;
4113 int err; 4130 int err;
4114 4131
@@ -4153,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev)
4153} 4170}
4154 4171
4155static struct pci_device_id bttv_pci_tbl[] = { 4172static struct pci_device_id bttv_pci_tbl[] = {
4156 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, 4173 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4157 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4158 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, 4175 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4159 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4160 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, 4177 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4161 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4162 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, 4179 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4163 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4164 {0,} 4181 {0,}
4165}; 4182};
4166 4183
4167MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); 4184MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4168 4185
4169static struct pci_driver bttv_pci_driver = { 4186static struct pci_driver bttv_pci_driver = {
4170 .name = "bttv", 4187 .name = "bttv",
4171 .id_table = bttv_pci_tbl, 4188 .id_table = bttv_pci_tbl,
4172 .probe = bttv_probe, 4189 .probe = bttv_probe,
4173 .remove = __devexit_p(bttv_remove), 4190 .remove = __devexit_p(bttv_remove),
4174 .suspend = bttv_suspend, 4191 .suspend = bttv_suspend,
4175 .resume = bttv_resume, 4192 .resume = bttv_resume,
4176}; 4193};
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 6b280c03e398..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -7,7 +7,7 @@
7 7
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e684df37eb0e..77619eb131f6 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -5,7 +5,7 @@
5 bttv - Bt848 frame grabber driver 5 bttv - Bt848 frame grabber driver
6 6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 & Marcus Metzler (mocm@thp.uni-koeln.de) 8 & Marcus Metzler (mocm@thp.uni-koeln.de)
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
237 err: 237 err:
238 if (i2c_debug) 238 if (i2c_debug)
239 printk(" ERR: %d\n",retval); 239 printk(" ERR: %d\n",retval);
240 return retval; 240 return retval;
241} 241}
242 242
243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = {
290 290
291static int attach_inform(struct i2c_client *client) 291static int attach_inform(struct i2c_client *client)
292{ 292{
293 struct bttv *btv = i2c_get_adapdata(client->adapter); 293 struct bttv *btv = i2c_get_adapdata(client->adapter);
294 int addr=ADDR_UNSET;
295
296
297 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
298 addr = bttv_tvcards[btv->c.type].tuner_addr;
299
294 300
295 if (bttv_debug) 301 if (bttv_debug)
296 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", 302 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client)
300 return 0; 306 return 0;
301 307
302 if (btv->tuner_type != UNSET) { 308 if (btv->tuner_type != UNSET) {
303 struct tuner_setup tun_setup; 309 struct tuner_setup tun_setup;
310
311 if ((addr==ADDR_UNSET) ||
312 (addr==client->addr)) {
304 313
305 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 314 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
306 tun_setup.type = btv->tuner_type; 315 tun_setup.type = btv->tuner_type;
307 tun_setup.addr = ADDR_UNSET; 316 tun_setup.addr = addr;
317 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
318 }
308 319
309 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
310 } 320 }
311 321
312 if (btv->pinnacle_id != UNSET) 322 return 0;
313 client->driver->command(client,AUDC_CONFIG_PINNACLE,
314 &btv->pinnacle_id);
315 return 0;
316} 323}
317 324
318void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) 325void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = {
330/* read I2C */ 337/* read I2C */
331int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 338int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
332{ 339{
333 unsigned char buffer = 0; 340 unsigned char buffer = 0;
334 341
335 if (0 != btv->i2c_rc) 342 if (0 != btv->i2c_rc)
336 return -1; 343 return -1;
337 if (bttv_verbose && NULL != probe_for) 344 if (bttv_verbose && NULL != probe_for)
338 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", 345 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
339 btv->c.nr,probe_for,addr); 346 btv->c.nr,probe_for,addr);
340 btv->i2c_client.addr = addr >> 1; 347 btv->i2c_client.addr = addr >> 1;
341 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 348 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
342 if (NULL != probe_for) { 349 if (NULL != probe_for) {
343 if (bttv_verbose) 350 if (bttv_verbose)
344 printk("not found\n"); 351 printk("not found\n");
345 } else 352 } else
346 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", 353 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
347 btv->c.nr,addr); 354 btv->c.nr,addr);
348 return -1; 355 return -1;
349 } 356 }
350 if (bttv_verbose && NULL != probe_for) 357 if (bttv_verbose && NULL != probe_for)
351 printk("found\n"); 358 printk("found\n");
352 return buffer; 359 return buffer;
353} 360}
354 361
355/* write I2C */ 362/* write I2C */
356int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 363int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
357 unsigned char b2, int both) 364 unsigned char b2, int both)
358{ 365{
359 unsigned char buffer[2]; 366 unsigned char buffer[2];
360 int bytes = both ? 2 : 1; 367 int bytes = both ? 2 : 1;
361 368
362 if (0 != btv->i2c_rc) 369 if (0 != btv->i2c_rc)
363 return -1; 370 return -1;
364 btv->i2c_client.addr = addr >> 1; 371 btv->i2c_client.addr = addr >> 1;
365 buffer[0] = b1; 372 buffer[0] = b1;
366 buffer[1] = b2; 373 buffer[1] = b2;
367 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 374 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
368 return -1; 375 return -1;
369 return 0; 376 return 0;
370} 377}
371 378
372/* read EEPROM content */ 379/* read EEPROM content */
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
431 "bt%d #%d [%s]", btv->id, btv->c.nr, 438 "bt%d #%d [%s]", btv->id, btv->c.nr,
432 btv->use_i2c_hw ? "hw" : "sw"); 439 btv->use_i2c_hw ? "hw" : "sw");
433 440
434 i2c_set_adapdata(&btv->c.i2c_adap, btv); 441 i2c_set_adapdata(&btv->c.i2c_adap, btv);
435 btv->i2c_client.adapter = &btv->c.i2c_adap; 442 btv->i2c_client.adapter = &btv->c.i2c_adap;
436 443
437#ifdef I2C_CLASS_TV_ANALOG 444#ifdef I2C_CLASS_TV_ANALOG
438 if (bttv_tvcards[btv->c.type].no_video) 445 if (bttv_tvcards[btv->c.type].no_video)
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index e8aada772b89..19b564ab0e92 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,13 +1,13 @@
1/* 1/*
2 2
3 bttv-if.c -- old gpio interface to other kernel modules 3 bttv-if.c -- old gpio interface to other kernel modules
4 don't use in new code, will go away in 2.7 4 don't use in new code, will go away in 2.7
5 have a look at bttv-gpio.c instead. 5 have a look at bttv-gpio.c instead.
6 6
7 bttv - Bt848 frame grabber driver 7 bttv - Bt848 frame grabber driver
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index a5ed99b89445..b40e9734bf08 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
74 } 74 }
75 if (bpl <= sg_dma_len(sg)-offset) { 75 if (bpl <= sg_dma_len(sg)-offset) {
76 /* fits into current chunk */ 76 /* fits into current chunk */
77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
78 BT848_RISC_EOL|bpl); 78 BT848_RISC_EOL|bpl);
79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
80 offset+=bpl; 80 offset+=bpl;
81 } else { 81 } else {
82 /* scanline needs to be splitted */ 82 /* scanline needs to be splitted */
83 todo = bpl; 83 todo = bpl;
84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
85 (sg_dma_len(sg)-offset)); 85 (sg_dma_len(sg)-offset));
86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
87 todo -= (sg_dma_len(sg)-offset); 87 todo -= (sg_dma_len(sg)-offset);
88 offset = 0; 88 offset = 0;
89 sg++; 89 sg++;
90 while (todo > sg_dma_len(sg)) { 90 while (todo > sg_dma_len(sg)) {
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE| 91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
92 sg_dma_len(sg)); 92 sg_dma_len(sg));
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 93 *(rp++)=cpu_to_le32(sg_dma_address(sg));
94 todo -= sg_dma_len(sg); 94 todo -= sg_dma_len(sg);
95 sg++; 95 sg++;
96 } 96 }
97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| 97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
98 todo); 98 todo);
99 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 99 *(rp++)=cpu_to_le32(sg_dma_address(sg));
100 offset += todo; 100 offset += todo;
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
201 ri |= BT848_RISC_EOL; 201 ri |= BT848_RISC_EOL;
202 202
203 /* write risc instruction */ 203 /* write risc instruction */
204 *(rp++)=cpu_to_le32(ri | ylen); 204 *(rp++)=cpu_to_le32(ri | ylen);
205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | 205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
206 (ylen >> hshift)); 206 (ylen >> hshift));
207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); 207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
208 yoffset += ylen; 208 yoffset += ylen;
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
319 int width, int height, int interleaved, int norm) 319 int width, int height, int interleaved, int norm)
320{ 320{
321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; 321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
322 u32 xsf, sr; 322 u32 xsf, sr;
323 int vdelay; 323 int vdelay;
324 324
325 int swidth = tvnorm->swidth; 325 int swidth = tvnorm->swidth;
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
334 334
335 vdelay = tvnorm->vdelay; 335 vdelay = tvnorm->vdelay;
336 336
337 xsf = (width*scaledtwidth)/swidth; 337 xsf = (width*scaledtwidth)/swidth;
338 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 338 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
339 geo->hdelay = tvnorm->hdelayx1; 339 geo->hdelay = tvnorm->hdelayx1;
340 geo->hdelay = (geo->hdelay*width)/swidth; 340 geo->hdelay = (geo->hdelay*width)/swidth;
341 geo->hdelay &= 0x3fe; 341 geo->hdelay &= 0x3fe;
342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
343 geo->vscale = (0x10000UL-sr) & 0x1fff; 343 geo->vscale = (0x10000UL-sr) & 0x1fff;
344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
347 geo->vdelay = vdelay; 347 geo->vdelay = vdelay;
348 geo->width = width; 348 geo->width = width;
349 geo->sheight = tvnorm->sheight; 349 geo->sheight = tvnorm->sheight;
350 geo->vtotal = tvnorm->vtotal; 350 geo->vtotal = tvnorm->vtotal;
351 351
352 if (btv->opt_combfilter) { 352 if (btv->opt_combfilter) {
353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
354 geo->comb = (width < 769) ? 1 : 0; 354 geo->comb = (width < 769) ? 1 : 0;
355 } else { 355 } else {
356 geo->vtc = 0; 356 geo->vtc = 0;
357 geo->comb = 0; 357 geo->comb = 0;
358 } 358 }
359} 359}
360 360
361static void 361static void
362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
363{ 363{
364 int off = odd ? 0x80 : 0x00; 364 int off = odd ? 0x80 : 0x00;
365 365
366 if (geo->comb) 366 if (geo->comb)
367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
368 else 368 else
369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
370 370
371 btwrite(geo->vtc, BT848_E_VTC+off); 371 btwrite(geo->vtc, BT848_E_VTC+off);
372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
380 btwrite(geo->crop, BT848_E_CROP+off); 380 btwrite(geo->crop, BT848_E_CROP+off);
381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
383} 383}
384 384
385/* ---------------------------------------------------------- */ 385/* ---------------------------------------------------------- */
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override)
420 } else { 420 } else {
421 del_timer(&btv->timeout); 421 del_timer(&btv->timeout);
422 } 422 }
423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
424 424
425 btaor(capctl, ~0x0f, BT848_CAP_CTL); 425 btaor(capctl, ~0x0f, BT848_CAP_CTL);
426 if (capctl) { 426 if (capctl) {
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override)
432 } else { 432 } else {
433 if (!btv->dma_on) 433 if (!btv->dma_on)
434 return; 434 return;
435 btand(~3, BT848_GPIO_DMA_CTL); 435 btand(~3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 0; 436 btv->dma_on = 0;
437 } 437 }
438 return; 438 return;
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv)
460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
462 462
463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
464 BT848_FIFO_STATUS_VRO); 464 BT848_FIFO_STATUS_VRO);
465 btv->main.cpu[9] = cpu_to_le32(0); 465 btv->main.cpu[9] = cpu_to_le32(0);
466 466
467 /* bottom field */ 467 /* bottom field */
468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
472 472
473 /* jump back to top field */ 473 /* jump back to top field */
474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
476 476
477 return 0; 477 return 0;
478} 478}
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index d254e90e3bb9..124ea41dada4 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -20,123 +20,148 @@
20/* ---------------------------------------------------------- */ 20/* ---------------------------------------------------------- */
21/* exported by bttv-cards.c */ 21/* exported by bttv-cards.c */
22 22
23#define BTTV_UNKNOWN 0x00 23#define BTTV_BOARD_UNKNOWN 0x00
24#define BTTV_MIRO 0x01 24#define BTTV_BOARD_MIRO 0x01
25#define BTTV_HAUPPAUGE 0x02 25#define BTTV_BOARD_HAUPPAUGE 0x02
26#define BTTV_STB 0x03 26#define BTTV_BOARD_STB 0x03
27#define BTTV_INTEL 0x04 27#define BTTV_BOARD_INTEL 0x04
28#define BTTV_DIAMOND 0x05 28#define BTTV_BOARD_DIAMOND 0x05
29#define BTTV_AVERMEDIA 0x06 29#define BTTV_BOARD_AVERMEDIA 0x06
30#define BTTV_MATRIX_VISION 0x07 30#define BTTV_BOARD_MATRIX_VISION 0x07
31#define BTTV_FLYVIDEO 0x08 31#define BTTV_BOARD_FLYVIDEO 0x08
32#define BTTV_TURBOTV 0x09 32#define BTTV_BOARD_TURBOTV 0x09
33#define BTTV_HAUPPAUGE878 0x0a 33#define BTTV_BOARD_HAUPPAUGE878 0x0a
34#define BTTV_MIROPRO 0x0b 34#define BTTV_BOARD_MIROPRO 0x0b
35#define BTTV_ADSTECH_TV 0x0c 35#define BTTV_BOARD_ADSTECH_TV 0x0c
36#define BTTV_AVERMEDIA98 0x0d 36#define BTTV_BOARD_AVERMEDIA98 0x0d
37#define BTTV_VHX 0x0e 37#define BTTV_BOARD_VHX 0x0e
38#define BTTV_ZOLTRIX 0x0f 38#define BTTV_BOARD_ZOLTRIX 0x0f
39#define BTTV_PIXVIEWPLAYTV 0x10 39#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
40#define BTTV_WINVIEW_601 0x11 40#define BTTV_BOARD_WINVIEW_601 0x11
41#define BTTV_AVEC_INTERCAP 0x12 41#define BTTV_BOARD_AVEC_INTERCAP 0x12
42#define BTTV_LIFE_FLYKIT 0x13 42#define BTTV_BOARD_LIFE_FLYKIT 0x13
43#define BTTV_CEI_RAFFLES 0x14 43#define BTTV_BOARD_CEI_RAFFLES 0x14
44#define BTTV_CONFERENCETV 0x15 44#define BTTV_BOARD_CONFERENCETV 0x15
45#define BTTV_PHOEBE_TVMAS 0x16 45#define BTTV_BOARD_PHOEBE_TVMAS 0x16
46#define BTTV_MODTEC_205 0x17 46#define BTTV_BOARD_MODTEC_205 0x17
47#define BTTV_MAGICTVIEW061 0x18 47#define BTTV_BOARD_MAGICTVIEW061 0x18
48#define BTTV_VOBIS_BOOSTAR 0x19 48#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
49#define BTTV_HAUPPAUG_WCAM 0x1a 49#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
50#define BTTV_MAXI 0x1b 50#define BTTV_BOARD_MAXI 0x1b
51#define BTTV_TERRATV 0x1c 51#define BTTV_BOARD_TERRATV 0x1c
52#define BTTV_PXC200 0x1d 52#define BTTV_BOARD_PXC200 0x1d
53#define BTTV_FLYVIDEO_98 0x1e 53#define BTTV_BOARD_FLYVIDEO_98 0x1e
54#define BTTV_IPROTV 0x1f 54#define BTTV_BOARD_IPROTV 0x1f
55#define BTTV_INTEL_C_S_PCI 0x20 55#define BTTV_BOARD_INTEL_C_S_PCI 0x20
56#define BTTV_TERRATVALUE 0x21 56#define BTTV_BOARD_TERRATVALUE 0x21
57#define BTTV_WINFAST2000 0x22 57#define BTTV_BOARD_WINFAST2000 0x22
58#define BTTV_CHRONOS_VS2 0x23 58#define BTTV_BOARD_CHRONOS_VS2 0x23
59#define BTTV_TYPHOON_TVIEW 0x24 59#define BTTV_BOARD_TYPHOON_TVIEW 0x24
60#define BTTV_PXELVWPLTVPRO 0x25 60#define BTTV_BOARD_PXELVWPLTVPRO 0x25
61#define BTTV_MAGICTVIEW063 0x26 61#define BTTV_BOARD_MAGICTVIEW063 0x26
62#define BTTV_PINNACLE 0x27 62#define BTTV_BOARD_PINNACLE 0x27
63#define BTTV_STB2 0x28 63#define BTTV_BOARD_STB2 0x28
64#define BTTV_AVPHONE98 0x29 64#define BTTV_BOARD_AVPHONE98 0x29
65#define BTTV_PV951 0x2a 65#define BTTV_BOARD_PV951 0x2a
66#define BTTV_ONAIR_TV 0x2b 66#define BTTV_BOARD_ONAIR_TV 0x2b
67#define BTTV_SIGMA_TVII_FM 0x2c 67#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
68#define BTTV_MATRIX_VISION2 0x2d 68#define BTTV_BOARD_MATRIX_VISION2 0x2d
69#define BTTV_ZOLTRIX_GENIE 0x2e 69#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
70#define BTTV_TERRATVRADIO 0x2f 70#define BTTV_BOARD_TERRATVRADIO 0x2f
71#define BTTV_DYNALINK 0x30 71#define BTTV_BOARD_DYNALINK 0x30
72#define BTTV_GVBCTV3PCI 0x31 72#define BTTV_BOARD_GVBCTV3PCI 0x31
73#define BTTV_PXELVWPLTVPAK 0x32 73#define BTTV_BOARD_PXELVWPLTVPAK 0x32
74#define BTTV_EAGLE 0x33 74#define BTTV_BOARD_EAGLE 0x33
75#define BTTV_PINNACLEPRO 0x34 75#define BTTV_BOARD_PINNACLEPRO 0x34
76#define BTTV_TVIEW_RDS_FM 0x35 76#define BTTV_BOARD_TVIEW_RDS_FM 0x35
77#define BTTV_LIFETEC_9415 0x36 77#define BTTV_BOARD_LIFETEC_9415 0x36
78#define BTTV_BESTBUY_EASYTV 0x37 78#define BTTV_BOARD_BESTBUY_EASYTV 0x37
79#define BTTV_FLYVIDEO_98FM 0x38 79#define BTTV_BOARD_FLYVIDEO_98FM 0x38
80#define BTTV_GMV1 0x3d 80#define BTTV_BOARD_GRANDTEC 0x39
81#define BTTV_BESTBUY_EASYTV2 0x3e 81#define BTTV_BOARD_ASKEY_CPH060 0x3a
82#define BTTV_ATI_TVWONDER 0x3f 82#define BTTV_BOARD_ASKEY_CPH03X 0x3b
83#define BTTV_ATI_TVWONDERVE 0x40 83#define BTTV_BOARD_MM100PCTV 0x3c
84#define BTTV_FLYVIDEO2000 0x41 84#define BTTV_BOARD_GMV1 0x3d
85#define BTTV_TERRATVALUER 0x42 85#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
86#define BTTV_GVBCTV4PCI 0x43 86#define BTTV_BOARD_ATI_TVWONDER 0x3f
87#define BTTV_VOODOOTV_FM 0x44 87#define BTTV_BOARD_ATI_TVWONDERVE 0x40
88#define BTTV_AIMMS 0x45 88#define BTTV_BOARD_FLYVIDEO2000 0x41
89#define BTTV_PV_BT878P_PLUS 0x46 89#define BTTV_BOARD_TERRATVALUER 0x42
90#define BTTV_FLYVIDEO98EZ 0x47 90#define BTTV_BOARD_GVBCTV4PCI 0x43
91#define BTTV_PV_BT878P_9B 0x48 91#define BTTV_BOARD_VOODOOTV_FM 0x44
92#define BTTV_SENSORAY311 0x49 92#define BTTV_BOARD_AIMMS 0x45
93#define BTTV_RV605 0x4a 93#define BTTV_BOARD_PV_BT878P_PLUS 0x46
94#define BTTV_WINDVR 0x4c 94#define BTTV_BOARD_FLYVIDEO98EZ 0x47
95#define BTTV_GRANDTEC 0x4d 95#define BTTV_BOARD_PV_BT878P_9B 0x48
96#define BTTV_KWORLD 0x4e 96#define BTTV_BOARD_SENSORAY311 0x49
97#define BTTV_HAUPPAUGEPVR 0x50 97#define BTTV_BOARD_RV605 0x4a
98#define BTTV_GVBCTV5PCI 0x51 98#define BTTV_BOARD_POWERCLR_MTV878 0x4b
99#define BTTV_OSPREY1x0 0x52 99#define BTTV_BOARD_WINDVR 0x4c
100#define BTTV_OSPREY1x0_848 0x53 100#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
101#define BTTV_OSPREY101_848 0x54 101#define BTTV_BOARD_KWORLD 0x4e
102#define BTTV_OSPREY1x1 0x55 102#define BTTV_BOARD_DSP_TCVIDEO 0x4f
103#define BTTV_OSPREY1x1_SVID 0x56 103#define BTTV_BOARD_HAUPPAUGEPVR 0x50
104#define BTTV_OSPREY2xx 0x57 104#define BTTV_BOARD_GVBCTV5PCI 0x51
105#define BTTV_OSPREY2x0_SVID 0x58 105#define BTTV_BOARD_OSPREY1x0 0x52
106#define BTTV_OSPREY2x0 0x59 106#define BTTV_BOARD_OSPREY1x0_848 0x53
107#define BTTV_OSPREY500 0x5a 107#define BTTV_BOARD_OSPREY101_848 0x54
108#define BTTV_OSPREY540 0x5b 108#define BTTV_BOARD_OSPREY1x1 0x55
109#define BTTV_OSPREY2000 0x5c 109#define BTTV_BOARD_OSPREY1x1_SVID 0x56
110#define BTTV_IDS_EAGLE 0x5d 110#define BTTV_BOARD_OSPREY2xx 0x57
111#define BTTV_PINNACLESAT 0x5e 111#define BTTV_BOARD_OSPREY2x0_SVID 0x58
112#define BTTV_FORMAC_PROTV 0x5f 112#define BTTV_BOARD_OSPREY2x0 0x59
113#define BTTV_EURESYS_PICOLO 0x61 113#define BTTV_BOARD_OSPREY500 0x5a
114#define BTTV_PV150 0x62 114#define BTTV_BOARD_OSPREY540 0x5b
115#define BTTV_AD_TVK503 0x63 115#define BTTV_BOARD_OSPREY2000 0x5c
116#define BTTV_IVC200 0x66 116#define BTTV_BOARD_IDS_EAGLE 0x5d
117#define BTTV_XGUARD 0x67 117#define BTTV_BOARD_PINNACLESAT 0x5e
118#define BTTV_NEBULA_DIGITV 0x68 118#define BTTV_BOARD_FORMAC_PROTV 0x5f
119#define BTTV_PV143 0x69 119#define BTTV_BOARD_MACHTV 0x60
120#define BTTV_IVC100 0x6e 120#define BTTV_BOARD_EURESYS_PICOLO 0x61
121#define BTTV_IVC120 0x6f 121#define BTTV_BOARD_PV150 0x62
122#define BTTV_PC_HDTV 0x70 122#define BTTV_BOARD_AD_TVK503 0x63
123#define BTTV_TWINHAN_DST 0x71 123#define BTTV_BOARD_HERCULES_SM_TV 0x64
124#define BTTV_WINFASTVC100 0x72 124#define BTTV_BOARD_PACETV 0x65
125#define BTTV_SIMUS_GVC1100 0x74 125#define BTTV_BOARD_IVC200 0x66
126#define BTTV_NGSTV_PLUS 0x75 126#define BTTV_BOARD_XGUARD 0x67
127#define BTTV_LMLBT4 0x76 127#define BTTV_BOARD_NEBULA_DIGITV 0x68
128#define BTTV_PICOLO_TETRA_CHIP 0x79 128#define BTTV_BOARD_PV143 0x69
129#define BTTV_AVDVBT_771 0x7b 129#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
130#define BTTV_AVDVBT_761 0x7c 130#define BTTV_BOARD_VD009X1_COMBI 0x6b
131#define BTTV_MATRIX_VISIONSQ 0x7d 131#define BTTV_BOARD_VD009_MINIDIN 0x6c
132#define BTTV_MATRIX_VISIONSLC 0x7e 132#define BTTV_BOARD_VD009_COMBI 0x6d
133#define BTTV_APAC_VIEWCOMP 0x7f 133#define BTTV_BOARD_IVC100 0x6e
134#define BTTV_DVICO_DVBT_LITE 0x80 134#define BTTV_BOARD_IVC120 0x6f
135#define BTTV_TIBET_CS16 0x83 135#define BTTV_BOARD_PC_HDTV 0x70
136#define BTTV_KODICOM_4400R 0x84 136#define BTTV_BOARD_TWINHAN_DST 0x71
137#define BTTV_ADLINK_RTV24 0x86 137#define BTTV_BOARD_WINFASTVC100 0x72
138#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 138#define BTTV_BOARD_TEV560 0x73
139#define BTTV_ACORP_Y878F 0x88 139#define BTTV_BOARD_SIMUS_GVC1100 0x74
140#define BTTV_BOARD_NGSTV_PLUS 0x75
141#define BTTV_BOARD_LMLBT4 0x76
142#define BTTV_BOARD_TEKRAM_M205 0x77
143#define BTTV_BOARD_CONTVFMI 0x78
144#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
145#define BTTV_BOARD_SPIRIT_TV 0x7a
146#define BTTV_BOARD_AVDVBT_771 0x7b
147#define BTTV_BOARD_AVDVBT_761 0x7c
148#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
149#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
150#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
151#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
152#define BTTV_BOARD_VGEAR_MYVCD 0x81
153#define BTTV_BOARD_SUPER_TV 0x82
154#define BTTV_BOARD_TIBET_CS16 0x83
155#define BTTV_BOARD_KODICOM_4400R 0x84
156#define BTTV_BOARD_KODICOM_4400R_SL 0x85
157#define BTTV_BOARD_ADLINK_RTV24 0x86
158#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
159#define BTTV_BOARD_ACORP_Y878F 0x88
160#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
161#define BTTV_BOARD_PV_BT878P_2E 0x8a
162#define BTTV_BOARD_PV_M4900 0x8b
163#define BTTV_BOARD_OSPREY440 0x8c
164#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
140 165
141/* i2c address list */ 166/* i2c address list */
142#define I2C_TSA5522 0xc2 167#define I2C_TSA5522 0xc2
@@ -177,7 +202,7 @@ struct bttv_core {
177 struct list_head subs; /* struct bttv_sub_device */ 202 struct list_head subs; /* struct bttv_sub_device */
178 203
179 /* device config */ 204 /* device config */
180 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ 205 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
181 unsigned int type; /* card type (pointer into tvcards[]) */ 206 unsigned int type; /* card type (pointer into tvcards[]) */
182 char name[8]; /* dev name */ 207 char name[8]; /* dev name */
183}; 208};
@@ -186,16 +211,16 @@ struct bttv;
186 211
187struct tvcard 212struct tvcard
188{ 213{
189 char *name; 214 char *name;
190 unsigned int video_inputs; 215 unsigned int video_inputs;
191 unsigned int audio_inputs; 216 unsigned int audio_inputs;
192 unsigned int tuner; 217 unsigned int tuner;
193 unsigned int svhs; 218 unsigned int svhs;
194 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO 219 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
195 u32 gpiomask; 220 u32 gpiomask;
196 u32 muxsel[16]; 221 u32 muxsel[16];
197 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 222 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
198 u32 gpiomask2; /* GPIO MUX mask */ 223 u32 gpiomask2; /* GPIO MUX mask */
199 224
200 /* i2c audio flags */ 225 /* i2c audio flags */
201 unsigned int no_msp34xx:1; 226 unsigned int no_msp34xx:1;
@@ -218,6 +243,7 @@ struct tvcard
218 243
219 unsigned int tuner_type; 244 unsigned int tuner_type;
220 unsigned int tuner_addr; 245 unsigned int tuner_addr;
246 unsigned int radio_addr;
221 247
222 unsigned int has_radio; 248 unsigned int has_radio;
223 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); 249 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
246 interface below for new code */ 272 interface below for new code */
247 273
248/* returns card type + card ID (for bt878-based ones) 274/* returns card type + card ID (for bt878-based ones)
249 for possible values see lines below beginning with #define BTTV_UNKNOWN 275 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
250 returns negative value if error occurred 276 returns negative value if error occurred
251*/ 277*/
252extern int bttv_get_cardinfo(unsigned int card, int *type, 278extern int bttv_get_cardinfo(unsigned int card, int *type,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index e0e7c7a84bc5..386f546f7d11 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -77,14 +77,14 @@
77struct bttv_tvnorm { 77struct bttv_tvnorm {
78 int v4l2_id; 78 int v4l2_id;
79 char *name; 79 char *name;
80 u32 Fsc; 80 u32 Fsc;
81 u16 swidth, sheight; /* scaled standard width, height */ 81 u16 swidth, sheight; /* scaled standard width, height */
82 u16 totalwidth; 82 u16 totalwidth;
83 u8 adelay, bdelay, iform; 83 u8 adelay, bdelay, iform;
84 u32 scaledtwidth; 84 u32 scaledtwidth;
85 u16 hdelayx1, hactivex1; 85 u16 hdelayx1, hactivex1;
86 u16 vdelay; 86 u16 vdelay;
87 u8 vbipack; 87 u8 vbipack;
88 u16 vtotal; 88 u16 vtotal;
89 int sram; 89 int sram;
90}; 90};
@@ -267,8 +267,8 @@ struct bttv {
267 267
268 /* card configuration info */ 268 /* card configuration info */
269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */ 269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
270 unsigned int tuner_type; /* tuner chip type */ 270 unsigned int tuner_type; /* tuner chip type */
271 unsigned int pinnacle_id; 271 unsigned int pinnacle_id;
272 unsigned int svhs; 272 unsigned int svhs;
273 struct bttv_pll_info pll; 273 struct bttv_pll_info pll;
274 int triton1; 274 int triton1;
@@ -301,9 +301,9 @@ struct bttv {
301 301
302 /* locking */ 302 /* locking */
303 spinlock_t s_lock; 303 spinlock_t s_lock;
304 struct semaphore lock; 304 struct semaphore lock;
305 int resources; 305 int resources;
306 struct semaphore reslock; 306 struct semaphore reslock;
307#ifdef VIDIOC_G_PRIORITY 307#ifdef VIDIOC_G_PRIORITY
308 struct v4l2_prio_state prio; 308 struct v4l2_prio_state prio;
309#endif 309#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
new file mode 100644
index 000000000000..780b352ec119
--- /dev/null
+++ b/drivers/media/video/cs53l32a.c
@@ -0,0 +1,240 @@
1/*
2 * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
3 * Copyright (C) 2005 Martin Vaughan
4 *
5 * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/ioctl.h>
26#include <asm/uaccess.h>
27#include <linux/i2c.h>
28#include <linux/i2c-id.h>
29#include <linux/videodev.h>
30#include <media/audiochip.h>
31
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan");
34MODULE_LICENSE("GPL");
35
36static int debug = 0;
37
38module_param(debug, bool, 0644);
39
40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
41
42#define cs53l32a_dbg(fmt, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
46 i2c_adapter_id(client->adapter), client->addr , ## arg); \
47 } while (0)
48
49#define cs53l32a_err(fmt, arg...) do { \
50 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
51 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
52#define cs53l32a_info(fmt, arg...) do { \
53 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
54 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
55
56static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
57
58
59I2C_CLIENT_INSMOD;
60
61/* ----------------------------------------------------------------------- */
62
63static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value)
64{
65 return i2c_smbus_write_byte_data(client, reg, value);
66}
67
68static int cs53l32a_read(struct i2c_client *client, u8 reg)
69{
70 return i2c_smbus_read_byte_data(client, reg);
71}
72
73static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
74 void *arg)
75{
76 int *input = arg;
77
78 switch (cmd) {
79 case AUDC_SET_INPUT:
80 switch (*input) {
81 case AUDIO_TUNER:
82 cs53l32a_write(client, 0x01, 0x01);
83 break;
84 case AUDIO_EXTERN:
85 cs53l32a_write(client, 0x01, 0x21);
86 break;
87 case AUDIO_MUTE:
88 cs53l32a_write(client, 0x03, 0xF0);
89 break;
90 case AUDIO_UNMUTE:
91 cs53l32a_write(client, 0x03, 0x30);
92 break;
93 default:
94 cs53l32a_err("Invalid input %d.\n", *input);
95 return -EINVAL;
96 }
97 break;
98
99 case VIDIOC_S_CTRL:
100 {
101 struct v4l2_control *ctrl = arg;
102
103 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
104 return -EINVAL;
105 if (ctrl->value > 12 || ctrl->value < -90)
106 return -EINVAL;
107 cs53l32a_write(client, 0x04, (u8) ctrl->value);
108 cs53l32a_write(client, 0x05, (u8) ctrl->value);
109 break;
110 }
111
112 case VIDIOC_LOG_STATUS:
113 {
114 u8 v = cs53l32a_read(client, 0x01);
115 u8 m = cs53l32a_read(client, 0x03);
116
117 cs53l32a_info("Input: %s%s\n",
118 v == 0x21 ? "external line in" : "tuner",
119 (m & 0xC0) ? " (muted)" : "");
120 break;
121 }
122
123 default:
124 return -EINVAL;
125 }
126 return 0;
127}
128
129/* ----------------------------------------------------------------------- */
130
131/* i2c implementation */
132
133/*
134 * Generic i2c probe
135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
136 */
137
138static struct i2c_driver i2c_driver;
139
140static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
141{
142 struct i2c_client *client;
143 int i;
144
145 /* Check if the adapter supports the needed features */
146 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
147 return 0;
148
149 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
150 if (client == 0)
151 return -ENOMEM;
152
153 memset(client, 0, sizeof(struct i2c_client));
154 client->addr = address;
155 client->adapter = adapter;
156 client->driver = &i2c_driver;
157 client->flags = I2C_CLIENT_ALLOW_USE;
158 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
159
160 cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
161
162 for (i = 1; i <= 7; i++) {
163 u8 v = cs53l32a_read(client, i);
164
165 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
166 }
167
168 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
169
170 cs53l32a_write(client, 0x01, (u8) 0x21);
171 cs53l32a_write(client, 0x02, (u8) 0x29);
172 cs53l32a_write(client, 0x03, (u8) 0x30);
173 cs53l32a_write(client, 0x04, (u8) 0x00);
174 cs53l32a_write(client, 0x05, (u8) 0x00);
175 cs53l32a_write(client, 0x06, (u8) 0x00);
176 cs53l32a_write(client, 0x07, (u8) 0x00);
177
178 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
179
180 for (i = 1; i <= 7; i++) {
181 u8 v = cs53l32a_read(client, i);
182
183 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
184 }
185
186 i2c_attach_client(client);
187
188 return 0;
189}
190
191static int cs53l32a_probe(struct i2c_adapter *adapter)
192{
193#ifdef I2C_CLASS_TV_ANALOG
194 if (adapter->class & I2C_CLASS_TV_ANALOG)
195#else
196 if (adapter->id == I2C_HW_B_BT848)
197#endif
198 return i2c_probe(adapter, &addr_data, cs53l32a_attach);
199 return 0;
200}
201
202static int cs53l32a_detach(struct i2c_client *client)
203{
204 int err;
205
206 err = i2c_detach_client(client);
207 if (err) {
208 return err;
209 }
210 kfree(client);
211
212 return 0;
213}
214
215/* ----------------------------------------------------------------------- */
216
217/* i2c implementation */
218static struct i2c_driver i2c_driver = {
219 .name = "cs53l32a",
220 .id = I2C_DRIVERID_CS53L32A,
221 .flags = I2C_DF_NOTIFY,
222 .attach_adapter = cs53l32a_probe,
223 .detach_client = cs53l32a_detach,
224 .command = cs53l32a_command,
225 .owner = THIS_MODULE,
226};
227
228
229static int __init cs53l32a_init_module(void)
230{
231 return i2c_add_driver(&i2c_driver);
232}
233
234static void __exit cs53l32a_cleanup_module(void)
235{
236 i2c_del_driver(&i2c_driver);
237}
238
239module_init(cs53l32a_init_module);
240module_exit(cs53l32a_cleanup_module);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
new file mode 100644
index 000000000000..41818b6205b3
--- /dev/null
+++ b/drivers/media/video/cx88/Kconfig
@@ -0,0 +1,91 @@
1config VIDEO_CX88
2 tristate "Conexant 2388x (bt878 successor) support"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_TUNER
9 select VIDEO_TVEEPROM
10 select VIDEO_IR
11 ---help---
12 This is a video4linux driver for Conexant 2388x based
13 TV cards.
14
15 To compile this driver as a module, choose M here: the
16 module will be called cx8800
17
18config VIDEO_CX88_DVB
19 tristate "DVB/ATSC Support for cx2388x based TV cards"
20 depends on VIDEO_CX88 && DVB_CORE
21 select VIDEO_BUF_DVB
22 ---help---
23 This adds support for DVB/ATSC cards based on the
24 Connexant 2388x chip.
25
26 To compile this driver as a module, choose M here: the
27 module will be called cx88-dvb.
28
29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them.
31
32config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards"
34 default y
35 depends on VIDEO_CX88_DVB
36 select DVB_MT352
37 select DVB_OR51132
38 select DVB_CX22702
39 select DVB_LGDT330X
40 select DVB_NXT200X
41 ---help---
42 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and
44 only include support for the hardware that you need, choose N here.
45
46 If you are unsure, choose Y.
47
48config VIDEO_CX88_DVB_MT352
49 tristate "Zarlink MT352 DVB-T Support"
50 default m
51 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
52 select DVB_MT352
53 ---help---
54 This adds DVB-T support for cards based on the
55 Connexant 2388x chip and the MT352 demodulator.
56
57config VIDEO_CX88_DVB_OR51132
58 tristate "OR51132 ATSC Support"
59 default m
60 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_OR51132
62 ---help---
63 This adds ATSC 8VSB and QAM64/256 support for cards based on the
64 Connexant 2388x chip and the OR51132 demodulator.
65
66config VIDEO_CX88_DVB_CX22702
67 tristate "Conexant CX22702 DVB-T Support"
68 default m
69 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
70 select DVB_CX22702
71 ---help---
72 This adds DVB-T support for cards based on the
73 Connexant 2388x chip and the CX22702 demodulator.
74
75config VIDEO_CX88_DVB_LGDT330X
76 tristate "LG Electronics DT3302/DT3303 ATSC Support"
77 default m
78 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
79 select DVB_LGDT330X
80 ---help---
81 This adds ATSC 8VSB and QAM64/256 support for cards based on the
82 Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
83
84config VIDEO_CX88_DVB_NXT200X
85 tristate "NXT2002/NXT2004 ATSC Support"
86 default m
87 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
88 select DVB_NXT200X
89 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 107e48645e3a..0df40b773454 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
12ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
13 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
14endif
12ifneq ($(CONFIG_DVB_CX22702),n) 15ifneq ($(CONFIG_DVB_CX22702),n)
13 EXTRA_CFLAGS += -DHAVE_CX22702=1 16 EXTRA_CFLAGS += -DHAVE_CX22702=1
14endif 17endif
@@ -21,3 +24,6 @@ endif
21ifneq ($(CONFIG_DVB_MT352),n) 24ifneq ($(CONFIG_DVB_MT352),n)
22 EXTRA_CFLAGS += -DHAVE_MT352=1 25 EXTRA_CFLAGS += -DHAVE_MT352=1
23endif 26endif
27ifneq ($(CONFIG_DVB_NXT200X),n)
28 EXTRA_CFLAGS += -DHAVE_NXT200X=1
29endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..4ae3f78cccf2 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 8; 41static unsigned int mpegbufs = 32;
42module_param(mpegbufs,int,0644); 42module_param(mpegbufs,int,0644);
43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); 43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
44 44
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value)
436 436
437static int memory_read(struct cx88_core *core, u32 address, u32 *value) 437static int memory_read(struct cx88_core *core, u32 address, u32 *value)
438{ 438{
439 int retval; 439 int retval;
440 u32 val; 440 u32 val;
441 441
442 /* Warning: address is dword address (4 bytes) */ 442 /* Warning: address is dword address (4 bytes) */
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
605 u32 *dataptr; 605 u32 *dataptr;
606 606
607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); 609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); 610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
611 msleep(1); 611 msleep(1);
612 retval |= register_write(dev->core, IVTV_REG_APU, 0); 612 retval |= register_write(dev->core, IVTV_REG_APU, 0);
613 613
614 if (retval < 0) 614 if (retval < 0)
615 dprintk(0, "Error with register_write\n"); 615 dprintk(0, "Error with register_write\n");
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
657 release_firmware(firmware); 657 release_firmware(firmware);
658 dprintk(0, "Firmware upload successful.\n"); 658 dprintk(0, "Firmware upload successful.\n");
659 659
660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
661 retval |= register_read(dev->core, IVTV_REG_SPU, &value); 661 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); 662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
663 msleep(1); 663 msleep(1);
664 664
665 retval |= register_read(dev->core, IVTV_REG_VPU, &value); 665 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); 666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
667 667
668 if (retval < 0) 668 if (retval < 0)
669 dprintk(0, "Error with register_write\n"); 669 dprintk(0, "Error with register_write\n");
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
683================================================================================================================= 683=================================================================================================================
684*DB: "DirectBurn" 684*DB: "DirectBurn"
685*/ 685*/
686static void blackbird_codec_settings(struct cx8802_dev *dev) 686
687static struct blackbird_dnr default_dnr_params = {
688 .mode = BLACKBIRD_DNR_BITS_MANUAL,
689 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
690 .spatial = 0,
691 .temporal = 0
692};
693static struct v4l2_mpeg_compression default_mpeg_params = {
694 .st_type = V4L2_MPEG_PS_2,
695 .st_bitrate = {
696 .mode = V4L2_BITRATE_CBR,
697 .min = 0,
698 .target = 0,
699 .max = 0
700 },
701 .ts_pid_pmt = 16,
702 .ts_pid_audio = 260,
703 .ts_pid_video = 256,
704 .ts_pid_pcr = 259,
705 .ps_size = 0,
706 .au_type = V4L2_MPEG_AU_2_II,
707 .au_bitrate = {
708 .mode = V4L2_BITRATE_CBR,
709 .min = 224,
710 .target = 224,
711 .max = 224
712 },
713 .au_sample_rate = 44100,
714 .au_pesid = 0,
715 .vi_type = V4L2_MPEG_VI_2,
716 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
717 .vi_bitrate = {
718 .mode = V4L2_BITRATE_CBR,
719 .min = 4000,
720 .target = 4500,
721 .max = 6000
722 },
723 .vi_frame_rate = 25,
724 .vi_frames_per_gop = 15,
725 .vi_bframes_count = 2,
726 .vi_pesid = 0,
727 .closed_gops = 0,
728 .pulldown = 0
729};
730
731static enum blackbird_stream_type mpeg_stream_types[] = {
732 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
733 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
734 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
735 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
736};
737static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
738 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
739 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
740 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
741 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
742};
743static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
744 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
745 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
746 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
747};
748/* find the best layer I/II bitrate to fit a given numeric value */
749struct bitrate_bits {
750 u32 bits; /* layer bits for the best fit */
751 u32 rate; /* actual numeric value for the layer best fit */
752};
753struct bitrate_approximation {
754 u32 target; /* numeric value of the rate we want */
755 struct bitrate_bits layer[2];
756};
757static struct bitrate_approximation mpeg_audio_bitrates[] = {
758 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
759 { 0, { { 0, 0, }, { 0, 0, }, }, },
760 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
761 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
762 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
763 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
764 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
765 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
766 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
767 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
768 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
769 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
770 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
771 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
772 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
773 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
774 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
775 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
776 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778};
779static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
780
781static void blackbird_set_default_params(struct cx8802_dev *dev)
687{ 782{
688 int bitrate_mode = 1; 783 struct v4l2_mpeg_compression *params = &dev->params;
689 int bitrate = 7500000; 784 u32 au_params;
690 int bitrate_peak = 7500000;
691 bitrate_mode = BLACKBIRD_VIDEO_CBR;
692 bitrate = 4000*1024;
693 bitrate_peak = 4000*1024;
694 785
695 /* assign stream type */ 786 /* assign stream type */
696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 787 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
697 788 params->st_type = V4L2_MPEG_PS_2;
698 /* assign output port */ 789 if( params->st_type == V4L2_MPEG_SS_1 )
699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 790 params->vi_type = V4L2_MPEG_VI_1;
791 else
792 params->vi_type = V4L2_MPEG_VI_2;
793 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
700 794
701 /* assign framerate */ 795 /* assign framerate */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); 796 if( params->vi_frame_rate <= 25 )
703 797 {
704 /* assign frame size */ 798 params->vi_frame_rate = 25;
705 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, 799 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
706 dev->height, dev->width); 800 }
801 else
802 {
803 params->vi_frame_rate = 30;
804 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
805 }
707 806
708 /* assign aspect ratio */ 807 /* assign aspect ratio */
709 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); 808 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
710 809 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
711 /* assign bitrates */ 810 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
712 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
713 bitrate_mode, /* mode */
714 bitrate, /* bps */
715 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
716 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
717 811
718 /* assign gop properties */ 812 /* assign gop properties */
719 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); 813 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
814
815 /* assign gop closure */
816 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
720 817
721 /* assign 3 2 pulldown */ 818 /* assign 3 2 pulldown */
722 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); 819 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
820
821 /* make sure the params are within bounds */
822 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
823 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
824 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
825 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
826 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
827 params->au_bitrate.mode = V4L2_BITRATE_NONE;
723 828
724 /* assign audio properties */ 829 /* assign audio properties */
725 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 830 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
726 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 831 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
727 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
728 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
729 BLACKBIRD_AUDIO_BITS_44100HZ |
730 BLACKBIRD_AUDIO_BITS_LAYER_2 |
731 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
732 BLACKBIRD_AUDIO_BITS_STEREO |
733 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ 832 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
734 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | 833 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
735 BLACKBIRD_AUDIO_BITS_CRC_OFF | 834 BLACKBIRD_AUDIO_BITS_CRC_OFF |
736 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | 835 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
737 BLACKBIRD_AUDIO_BITS_COPY 836 BLACKBIRD_AUDIO_BITS_COPY |
738 ); 837 0;
838 if( params->au_sample_rate <= 32000 )
839 {
840 params->au_sample_rate = 32000;
841 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
842 }
843 else if( params->au_sample_rate <= 44100 )
844 {
845 params->au_sample_rate = 44100;
846 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
847 }
848 else
849 {
850 params->au_sample_rate = 48000;
851 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
852 }
853 if( params->au_type == V4L2_MPEG_AU_2_I )
854 {
855 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
856 }
857 else
858 {
859 /* TODO: try to handle the other formats more gracefully */
860 params->au_type = V4L2_MPEG_AU_2_II;
861 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
862 }
863 if( params->au_bitrate.mode )
864 {
865 int layer;
866
867 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
868 params->au_bitrate.max = params->vi_bitrate.target;
869 else
870 params->au_bitrate.target = params->vi_bitrate.max;
871
872 layer = params->au_type;
873 if( params->au_bitrate.target == 0 )
874 {
875 /* TODO: use the minimum possible bitrate instead of 0 ? */
876 au_params |= 0;
877 }
878 else if( params->au_bitrate.target >=
879 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
880 {
881 /* clamp the bitrate to the max supported by the standard */
882 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
883 params->au_bitrate.max = params->au_bitrate.target;
884 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
885 }
886 else
887 {
888 /* round up to the nearest supported bitrate */
889 int i;
890 for(i = 1; i < BITRATES_SIZE; i++)
891 {
892 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
893 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
894 {
895 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
896 params->au_bitrate.max = params->au_bitrate.target;
897 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
898 break;
899 }
900 }
901 }
902 }
903 else
904 {
905 /* TODO: ??? */
906 params->au_bitrate.target = params->au_bitrate.max = 0;
907 au_params |= 0;
908 }
909 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
910
911 /* assign bitrates */
912 if( params->vi_bitrate.mode )
913 {
914 /* bitrate is set, let's figure out the cbr/vbr mess */
915 if( params->vi_bitrate.max < params->vi_bitrate.target )
916 {
917 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
918 params->vi_bitrate.max = params->vi_bitrate.target;
919 else
920 params->vi_bitrate.target = params->vi_bitrate.max;
921 }
922 }
923 else
924 {
925 if( params->st_bitrate.max < params->st_bitrate.target )
926 {
927 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
928 params->st_bitrate.target = params->st_bitrate.max;
929 else
930 params->st_bitrate.max = params->st_bitrate.target;
931 }
932 /* calculate vi_bitrate = st_bitrate - au_bitrate */
933 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
934 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
935 }
936 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
937 mpeg_video_bitrates[params->vi_bitrate.mode],
938 params->vi_bitrate.target * 1000, /* kbps -> bps */
939 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
940 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
941
942 /* TODO: implement the stream ID stuff:
943 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
944 ps_size, au_pesid, vi_pesid
945 */
946}
947#define CHECK_PARAM( name ) ( dev->params.name != params->name )
948#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
949#define UPDATE_PARAM( name ) dev->params.name = params->name
950void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
951{
952 u32 au_params;
953
954 /* assign stream type */
955 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
956 params->st_type = V4L2_MPEG_PS_2;
957 if( params->st_type == V4L2_MPEG_SS_1 )
958 params->vi_type = V4L2_MPEG_VI_1;
959 else
960 params->vi_type = V4L2_MPEG_VI_2;
961 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
962 {
963 UPDATE_PARAM( st_type );
964 UPDATE_PARAM( vi_type );
965 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
966 }
967
968 /* assign framerate */
969 if( params->vi_frame_rate <= 25 )
970 params->vi_frame_rate = 25;
971 else
972 params->vi_frame_rate = 30;
973 IF_PARAM( vi_frame_rate )
974 {
975 UPDATE_PARAM( vi_frame_rate );
976 if( params->vi_frame_rate == 25 )
977 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
978 else
979 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
980 }
981
982 /* assign aspect ratio */
983 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
984 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
985 IF_PARAM( vi_aspect_ratio )
986 {
987 UPDATE_PARAM( vi_aspect_ratio );
988 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
989 }
990
991 /* assign gop properties */
992 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
993 {
994 UPDATE_PARAM( vi_frames_per_gop );
995 UPDATE_PARAM( vi_bframes_count );
996 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
997 }
739 998
740 /* assign gop closure */ 999 /* assign gop closure */
741 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); 1000 IF_PARAM( closed_gops )
1001 {
1002 UPDATE_PARAM( closed_gops );
1003 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
1004 }
1005
1006 /* assign 3 2 pulldown */
1007 IF_PARAM( pulldown )
1008 {
1009 UPDATE_PARAM( pulldown );
1010 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1011 }
1012
1013 /* make sure the params are within bounds */
1014 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1015 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1016 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1017 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1018 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1019 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1020
1021 /* assign audio properties */
1022 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1023 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1024 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1025 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1026 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1027 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1028 BLACKBIRD_AUDIO_BITS_COPY |
1029 0;
1030 if( params->au_sample_rate < 32000 )
1031 {
1032 params->au_sample_rate = 32000;
1033 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1034 }
1035 else if( params->au_sample_rate < 44100 )
1036 {
1037 params->au_sample_rate = 44100;
1038 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1039 }
1040 else
1041 {
1042 params->au_sample_rate = 48000;
1043 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1044 }
1045 if( params->au_type == V4L2_MPEG_AU_2_I )
1046 {
1047 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1048 }
1049 else
1050 {
1051 /* TODO: try to handle the other formats more gracefully */
1052 params->au_type = V4L2_MPEG_AU_2_II;
1053 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1054 }
1055 if( params->au_bitrate.mode )
1056 {
1057 int layer;
1058
1059 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1060 params->au_bitrate.max = params->vi_bitrate.target;
1061 else
1062 params->au_bitrate.target = params->vi_bitrate.max;
1063
1064 layer = params->au_type;
1065 if( params->au_bitrate.target == 0 )
1066 {
1067 /* TODO: use the minimum possible bitrate instead of 0 ? */
1068 au_params |= 0;
1069 }
1070 else if( params->au_bitrate.target >=
1071 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1072 {
1073 /* clamp the bitrate to the max supported by the standard */
1074 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1075 params->au_bitrate.max = params->au_bitrate.target;
1076 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1077 }
1078 else
1079 {
1080 /* round up to the nearest supported bitrate */
1081 int i;
1082 for(i = 1; i < BITRATES_SIZE; i++)
1083 {
1084 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1085 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1086 {
1087 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1088 params->au_bitrate.max = params->au_bitrate.target;
1089 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1090 break;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 {
1097 /* TODO: ??? */
1098 params->au_bitrate.target = params->au_bitrate.max = 0;
1099 au_params |= 0;
1100 }
1101 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1102 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1103 || CHECK_PARAM( au_bitrate.target )
1104 )
1105 {
1106 UPDATE_PARAM( au_type );
1107 UPDATE_PARAM( au_sample_rate );
1108 UPDATE_PARAM( au_bitrate );
1109 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1110 }
1111
1112 /* assign bitrates */
1113 if( params->vi_bitrate.mode )
1114 {
1115 /* bitrate is set, let's figure out the cbr/vbr mess */
1116 if( params->vi_bitrate.max < params->vi_bitrate.target )
1117 {
1118 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1119 params->vi_bitrate.max = params->vi_bitrate.target;
1120 else
1121 params->vi_bitrate.target = params->vi_bitrate.max;
1122 }
1123 }
1124 else
1125 {
1126 if( params->st_bitrate.max < params->st_bitrate.target )
1127 {
1128 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1129 params->st_bitrate.target = params->st_bitrate.max;
1130 else
1131 params->st_bitrate.max = params->st_bitrate.target;
1132 }
1133 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1134 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1135 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1136 }
1137 UPDATE_PARAM( st_bitrate );
1138 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1139 || CHECK_PARAM( vi_bitrate.target )
1140 )
1141 {
1142 UPDATE_PARAM( vi_bitrate );
1143 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1144 mpeg_video_bitrates[params->vi_bitrate.mode],
1145 params->vi_bitrate.target * 1000, /* kbps -> bps */
1146 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1147 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1148 }
742 1149
1150 /* TODO: implement the stream ID stuff:
1151 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1152 ps_size, au_pesid, vi_pesid
1153 */
1154 UPDATE_PARAM( ts_pid_pmt );
1155 UPDATE_PARAM( ts_pid_audio );
1156 UPDATE_PARAM( ts_pid_video );
1157 UPDATE_PARAM( ts_pid_pcr );
1158 UPDATE_PARAM( ps_size );
1159 UPDATE_PARAM( au_pesid );
1160 UPDATE_PARAM( vi_pesid );
1161}
743 1162
1163static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1164{
744 /* assign dnr filter mode */ 1165 /* assign dnr filter mode */
1166 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1167 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1168 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1169 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
745 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, 1170 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
746 BLACKBIRD_DNR_BITS_MANUAL, 1171 dev->dnr_params.mode,
747 BLACKBIRD_MEDIAN_FILTER_DISABLED 1172 dev->dnr_params.type
748 ); 1173 );
749 1174
750 /* assign dnr filter props*/ 1175 /* assign dnr filter props*/
751 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); 1176 if( dev->dnr_params.spatial > 15 )
1177 dev->dnr_params.spatial = 15;
1178 if( dev->dnr_params.temporal > 31 )
1179 dev->dnr_params.temporal = 31;
1180 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1181 dev->dnr_params.spatial,
1182 dev->dnr_params.temporal
1183 );
1184}
1185#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1186#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1187void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1188{
1189 /* assign dnr filter mode */
1190 /* clamp values */
1191 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1192 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1193 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1194 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1195 /* check if the params actually changed */
1196 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1197 {
1198 UPDATE_DNR_PARAM( mode );
1199 UPDATE_DNR_PARAM( type );
1200 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1201 }
1202
1203 /* assign dnr filter props*/
1204 if( dnr_params->spatial > 15 )
1205 dnr_params->spatial = 15;
1206 if( dnr_params->temporal > 31 )
1207 dnr_params->temporal = 31;
1208 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1209 {
1210 UPDATE_DNR_PARAM( spatial );
1211 UPDATE_DNR_PARAM( temporal );
1212 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1213 }
1214}
1215
1216static void blackbird_codec_settings(struct cx8802_dev *dev)
1217{
1218
1219 /* assign output port */
1220 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1221
1222 /* assign frame size */
1223 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1224 dev->height, dev->width);
752 1225
753 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 1226 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
754 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); 1227 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
755 1228
756 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ 1229 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
757 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, 1230 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
758 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, 1231 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
759 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ 1232 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
760 ); 1233 );
761 1234
762 /* assign frame drop rate */ 1235 /* assign frame drop rate */
763 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ 1236 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1237
1238 blackbird_set_default_params(dev);
1239 blackbird_set_default_dnr_params(dev);
764} 1240}
765 1241
766static int blackbird_initialize_codec(struct cx8802_dev *dev) 1242static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
851 struct cx8802_fh *fh = q->priv_data; 1327 struct cx8802_fh *fh = q->priv_data;
852 1328
853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ 1329 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
854 fh->dev->ts_packet_count = 32; /* was: 100 */ 1330 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
855 1331
856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 1332 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
857 if (0 == *count) 1333 *count = fh->dev->ts_packet_count;
858 *count = mpegbufs;
859 if (*count < 2)
860 *count = 2;
861 if (*count > 32)
862 *count = 32;
863 return 0; 1334 return 0;
864} 1335}
865 1336
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
868 enum v4l2_field field) 1339 enum v4l2_field field)
869{ 1340{
870 struct cx8802_fh *fh = q->priv_data; 1341 struct cx8802_fh *fh = q->priv_data;
871 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); 1342 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
872} 1343}
873 1344
874static void 1345static void
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
920 V4L2_CAP_VIDEO_CAPTURE | 1391 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE | 1392 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING | 1393 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0; 1394 0;
926 if (UNSET != core->tuner_type) 1395 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER; 1396 cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
941 1410
942 memset(f,0,sizeof(*f)); 1411 memset(f,0,sizeof(*f));
943 f->index = index; 1412 f->index = index;
944 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 1413 strlcpy(f->description, "MPEG", sizeof(f->description));
945 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1414 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
946 f->pixelformat = V4L2_PIX_FMT_MPEG; 1415 f->pixelformat = V4L2_PIX_FMT_MPEG;
947 return 0; 1416 return 0;
948 } 1417 }
949 case VIDIOC_G_FMT: 1418 case VIDIOC_G_FMT:
950 case VIDIOC_S_FMT:
951 case VIDIOC_TRY_FMT:
952 { 1419 {
953 /* FIXME -- quick'n'dirty for exactly one size ... */
954 struct v4l2_format *f = arg; 1420 struct v4l2_format *f = arg;
955 1421
956 memset(f,0,sizeof(*f)); 1422 memset(f,0,sizeof(*f));
957 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1423 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1424 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1425 f->fmt.pix.bytesperline = 0;
1426 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
1427 f->fmt.pix.colorspace = 0;
958 f->fmt.pix.width = dev->width; 1428 f->fmt.pix.width = dev->width;
959 f->fmt.pix.height = dev->height; 1429 f->fmt.pix.height = dev->height;
1430 f->fmt.pix.field = fh->mpegq.field;
1431 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1432 dev->width, dev->height, fh->mpegq.field );
1433 return 0;
1434 }
1435 case VIDIOC_TRY_FMT:
1436 {
1437 struct v4l2_format *f = arg;
1438
1439 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1440 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1441 f->fmt.pix.bytesperline = 0;
1442 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
1443 f->fmt.pix.colorspace = 0;
1444 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1445 dev->width, dev->height, fh->mpegq.field );
1446 return 0;
1447 }
1448 case VIDIOC_S_FMT:
1449 {
1450 struct v4l2_format *f = arg;
1451
1452 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1453 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0; 1454 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; 1455 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
964 f->fmt.pix.colorspace = 0; 1456 f->fmt.pix.colorspace = 0;
1457 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1458 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
965 return 0; 1459 return 0;
966 } 1460 }
967 1461
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
985 case VIDIOC_STREAMOFF: 1479 case VIDIOC_STREAMOFF:
986 return videobuf_streamoff(&fh->mpegq); 1480 return videobuf_streamoff(&fh->mpegq);
987 1481
1482 /* --- mpeg compression -------------------------------------- */
1483 case VIDIOC_G_MPEGCOMP:
1484 {
1485 struct v4l2_mpeg_compression *f = arg;
1486
1487 memcpy(f,&dev->params,sizeof(*f));
1488 return 0;
1489 }
1490 case VIDIOC_S_MPEGCOMP:
1491 {
1492 struct v4l2_mpeg_compression *f = arg;
1493
1494 blackbird_set_params(dev, f);
1495 return 0;
1496 }
1497
988 default: 1498 default:
989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); 1499 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
990 } 1500 }
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
1034 file->private_data = fh; 1544 file->private_data = fh;
1035 fh->dev = dev; 1545 fh->dev = dev;
1036 1546
1037 /* FIXME: locking against other video device */
1038 cx88_set_scale(dev->core, dev->width, dev->height,
1039 V4L2_FIELD_INTERLACED);
1040
1041 videobuf_queue_init(&fh->mpegq, &blackbird_qops, 1547 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
1042 dev->pci, &dev->slock, 1548 dev->pci, &dev->slock,
1043 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1549 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1044 V4L2_FIELD_TOP, 1550 V4L2_FIELD_INTERLACED,
1045 sizeof(struct cx88_buffer), 1551 sizeof(struct cx88_buffer),
1046 fh); 1552 fh);
1553
1554 /* FIXME: locking against other video device */
1555 cx88_set_scale(dev->core, dev->width, dev->height,
1556 fh->mpegq.field);
1557
1047 return 0; 1558 return 0;
1048} 1559}
1049 1560
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1173 dev->core = core; 1684 dev->core = core;
1174 dev->width = 720; 1685 dev->width = 720;
1175 dev->height = 576; 1686 dev->height = 576;
1687 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1688 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1176 1689
1177 err = cx8802_init_common(dev); 1690 err = cx8802_init_common(dev);
1178 if (0 != err) 1691 if (0 != err)
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1199 1712
1200static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1713static void __devexit blackbird_remove(struct pci_dev *pci_dev)
1201{ 1714{
1202 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 1715 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
1203 1716
1204 /* blackbird */ 1717 /* blackbird */
1205 blackbird_unregister_video(dev); 1718 blackbird_unregister_video(dev);
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1215 { 1728 {
1216 .vendor = 0x14f1, 1729 .vendor = 0x14f1,
1217 .device = 0x8802, 1730 .device = 0x8802,
1218 .subvendor = PCI_ANY_ID, 1731 .subvendor = PCI_ANY_ID,
1219 .subdevice = PCI_ANY_ID, 1732 .subdevice = PCI_ANY_ID,
1220 },{ 1733 },{
1221 /* --- end of list --- */ 1734 /* --- end of list --- */
1222 } 1735 }
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1224MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 1737MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
1225 1738
1226static struct pci_driver blackbird_pci_driver = { 1739static struct pci_driver blackbird_pci_driver = {
1227 .name = "cx88-blackbird", 1740 .name = "cx88-blackbird",
1228 .id_table = cx8802_pci_tbl, 1741 .id_table = cx8802_pci_tbl,
1229 .probe = blackbird_probe, 1742 .probe = blackbird_probe,
1230 .remove = __devexit_p(blackbird_remove), 1743 .remove = __devexit_p(blackbird_remove),
1231 .suspend = cx8802_suspend_common, 1744 .suspend = cx8802_suspend_common,
1232 .resume = cx8802_resume_common, 1745 .resume = cx8802_resume_common,
1233}; 1746};
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini);
1257 1770
1258EXPORT_SYMBOL(cx88_ioctl_hook); 1771EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator); 1772EXPORT_SYMBOL(cx88_ioctl_translator);
1773EXPORT_SYMBOL(blackbird_set_params);
1774EXPORT_SYMBOL(blackbird_set_dnr_params);
1260 1775
1261/* ----------------------------------------------------------- */ 1776/* ----------------------------------------------------------- */
1262/* 1777/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4da91d535a5b..f2268631b7c0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = {
126 .input = {{ 126 .input = {{
127 .type = CX88_VMUX_TELEVISION, 127 .type = CX88_VMUX_TELEVISION,
128 .vmux = 0, 128 .vmux = 0,
129 .gpio0 = 0x03ff, 129 .gpio0 = 0x03ff,
130 },{ 130 },{
131 .type = CX88_VMUX_COMPOSITE1, 131 .type = CX88_VMUX_COMPOSITE1,
132 .vmux = 1, 132 .vmux = 1,
133 .gpio0 = 0x03fe, 133 .gpio0 = 0x03fe,
134 },{ 134 },{
135 .type = CX88_VMUX_SVIDEO, 135 .type = CX88_VMUX_SVIDEO,
136 .vmux = 2, 136 .vmux = 2,
137 .gpio0 = 0x03fe, 137 .gpio0 = 0x03fe,
138 }}, 138 }},
139 }, 139 },
140 [CX88_BOARD_WINFAST2000XP_EXPERT] = { 140 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
141 .name = "Leadtek Winfast 2000XP Expert", 141 .name = "Leadtek Winfast 2000XP Expert",
142 .tuner_type = TUNER_PHILIPS_4IN1, 142 .tuner_type = TUNER_PHILIPS_4IN1,
143 .radio_type = UNSET, 143 .radio_type = UNSET,
144 .tuner_addr = ADDR_UNSET, 144 .tuner_addr = ADDR_UNSET,
145 .radio_addr = ADDR_UNSET, 145 .radio_addr = ADDR_UNSET,
146 .tda9887_conf = TDA9887_PRESENT, 146 .tda9887_conf = TDA9887_PRESENT,
147 .input = {{ 147 .input = {{
148 .type = CX88_VMUX_TELEVISION, 148 .type = CX88_VMUX_TELEVISION,
149 .vmux = 0, 149 .vmux = 0,
150 .gpio0 = 0x00F5e700, 150 .gpio0 = 0x00F5e700,
151 .gpio1 = 0x00003004, 151 .gpio1 = 0x00003004,
152 .gpio2 = 0x00F5e700, 152 .gpio2 = 0x00F5e700,
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = {
165 .gpio1 = 0x00003004, 165 .gpio1 = 0x00003004,
166 .gpio2 = 0x00F5c700, 166 .gpio2 = 0x00F5c700,
167 .gpio3 = 0x02000000, 167 .gpio3 = 0x02000000,
168 }}, 168 }},
169 .radio = { 169 .radio = {
170 .type = CX88_RADIO, 170 .type = CX88_RADIO,
171 .gpio0 = 0x00F5d700, 171 .gpio0 = 0x00F5d700,
172 .gpio1 = 0x00003004, 172 .gpio1 = 0x00003004,
173 .gpio2 = 0x00F5d700, 173 .gpio2 = 0x00F5d700,
174 .gpio3 = 0x02000000, 174 .gpio3 = 0x02000000,
175 }, 175 },
176 }, 176 },
177 [CX88_BOARD_AVERTV_303] = { 177 [CX88_BOARD_AVERTV_STUDIO_303] = {
178 .name = "AverTV Studio 303 (M126)", 178 .name = "AverTV Studio 303 (M126)",
179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
180 .radio_type = UNSET, 180 .radio_type = UNSET,
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = {
206 .radio_type = UNSET, 206 .radio_type = UNSET,
207 .tuner_addr = ADDR_UNSET, 207 .tuner_addr = ADDR_UNSET,
208 .radio_addr = ADDR_UNSET, 208 .radio_addr = ADDR_UNSET,
209 .tda9887_conf = TDA9887_PRESENT, 209 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
210 .input = {{ 210 .input = {{
211 .type = CX88_VMUX_TELEVISION, 211 .type = CX88_VMUX_TELEVISION,
212 .vmux = 0, 212 .vmux = 0,
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = {
214 .gpio1 = 0x000080c0, 214 .gpio1 = 0x000080c0,
215 .gpio2 = 0x0000ff40, 215 .gpio2 = 0x0000ff40,
216 },{ 216 },{
217 .type = CX88_VMUX_COMPOSITE1, 217 .type = CX88_VMUX_COMPOSITE1,
218 .vmux = 1, 218 .vmux = 1,
219 .gpio0 = 0x000040bf, 219 .gpio0 = 0x000040bf,
220 .gpio1 = 0x000080c0, 220 .gpio1 = 0x000080c0,
221 .gpio2 = 0x0000ff40, 221 .gpio2 = 0x0000ff40,
222 },{ 222 },{
223 .type = CX88_VMUX_SVIDEO, 223 .type = CX88_VMUX_SVIDEO,
224 .vmux = 2, 224 .vmux = 2,
225 .gpio0 = 0x000040bf, 225 .gpio0 = 0x000040bf,
226 .gpio1 = 0x000080c0, 226 .gpio1 = 0x000080c0,
227 .gpio2 = 0x0000ff40, 227 .gpio2 = 0x0000ff40,
228 }}, 228 }},
229 .radio = { 229 .radio = {
230 .type = CX88_RADIO, 230 .type = CX88_RADIO,
231 }, 231 },
232 }, 232 },
233 [CX88_BOARD_WINFAST_DV2000] = { 233 [CX88_BOARD_WINFAST_DV2000] = {
234 .name = "Leadtek Winfast DV2000", 234 .name = "Leadtek Winfast DV2000",
235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
236 .radio_type = UNSET, 236 .radio_type = UNSET,
237 .tuner_addr = ADDR_UNSET, 237 .tuner_addr = ADDR_UNSET,
238 .radio_addr = ADDR_UNSET, 238 .radio_addr = ADDR_UNSET,
239 .tda9887_conf = TDA9887_PRESENT, 239 .tda9887_conf = TDA9887_PRESENT,
240 .input = {{ 240 .input = {{
241 .type = CX88_VMUX_TELEVISION, 241 .type = CX88_VMUX_TELEVISION,
242 .vmux = 0, 242 .vmux = 0,
243 .gpio0 = 0x0035e700, 243 .gpio0 = 0x0035e700,
244 .gpio1 = 0x00003004, 244 .gpio1 = 0x00003004,
245 .gpio2 = 0x0035e700, 245 .gpio2 = 0x0035e700,
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = {
260 .gpio2 = 0x02000000, 260 .gpio2 = 0x02000000,
261 .gpio3 = 0x02000000, 261 .gpio3 = 0x02000000,
262 }}, 262 }},
263 .radio = { 263 .radio = {
264 .type = CX88_RADIO, 264 .type = CX88_RADIO,
265 .gpio0 = 0x0035d700, 265 .gpio0 = 0x0035d700,
266 .gpio1 = 0x00007004, 266 .gpio1 = 0x00007004,
267 .gpio2 = 0x0035d700, 267 .gpio2 = 0x0035d700,
268 .gpio3 = 0x02000000, 268 .gpio3 = 0x02000000,
269 }, 269 },
270 }, 270 },
271 [CX88_BOARD_LEADTEK_PVR2000] = { 271 [CX88_BOARD_LEADTEK_PVR2000] = {
272 // gpio values for PAL version from regspy by DScaler 272 // gpio values for PAL version from regspy by DScaler
273 .name = "Leadtek PVR 2000", 273 .name = "Leadtek PVR 2000",
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = {
296 .blackbird = 1, 296 .blackbird = 1,
297 }, 297 },
298 [CX88_BOARD_IODATA_GVVCP3PCI] = { 298 [CX88_BOARD_IODATA_GVVCP3PCI] = {
299 .name = "IODATA GV-VCP3/PCI", 299 .name = "IODATA GV-VCP3/PCI",
300 .tuner_type = TUNER_ABSENT, 300 .tuner_type = TUNER_ABSENT,
301 .radio_type = UNSET, 301 .radio_type = UNSET,
302 .tuner_addr = ADDR_UNSET, 302 .tuner_addr = ADDR_UNSET,
303 .radio_addr = ADDR_UNSET, 303 .radio_addr = ADDR_UNSET,
304 .input = {{ 304 .input = {{
305 .type = CX88_VMUX_COMPOSITE1, 305 .type = CX88_VMUX_COMPOSITE1,
306 .vmux = 0, 306 .vmux = 0,
307 },{ 307 },{
308 .type = CX88_VMUX_COMPOSITE2, 308 .type = CX88_VMUX_COMPOSITE2,
309 .vmux = 1, 309 .vmux = 1,
310 },{ 310 },{
311 .type = CX88_VMUX_SVIDEO, 311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2, 312 .vmux = 2,
313 }}, 313 }},
314 }, 314 },
315 [CX88_BOARD_PROLINK_PLAYTVPVR] = { 315 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
316 .name = "Prolink PlayTV PVR", 316 .name = "Prolink PlayTV PVR",
317 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 317 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
318 .radio_type = UNSET, 318 .radio_type = UNSET,
319 .tuner_addr = ADDR_UNSET, 319 .tuner_addr = ADDR_UNSET,
320 .radio_addr = ADDR_UNSET, 320 .radio_addr = ADDR_UNSET,
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = {
348 .type = CX88_VMUX_TELEVISION, 348 .type = CX88_VMUX_TELEVISION,
349 .vmux = 0, 349 .vmux = 0,
350 .gpio0 = 0x0000fde6, 350 .gpio0 = 0x0000fde6,
351 },{ 351 },{
352 .type = CX88_VMUX_SVIDEO, 352 .type = CX88_VMUX_SVIDEO,
353 .vmux = 2, 353 .vmux = 2,
354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? 354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
355 }}, 355 }},
356 .radio = { 356 .radio = {
357 .type = CX88_RADIO, 357 .type = CX88_RADIO,
358 .gpio0 = 0x0000fde2, 358 .gpio0 = 0x0000fde2,
359 }, 359 },
360 .blackbird = 1, 360 .blackbird = 1,
361 }, 361 },
362 [CX88_BOARD_MSI_TVANYWHERE] = { 362 [CX88_BOARD_MSI_TVANYWHERE] = {
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = {
372 .gpio0 = 0x00000fbf, 372 .gpio0 = 0x00000fbf,
373 .gpio2 = 0x0000fc08, 373 .gpio2 = 0x0000fc08,
374 },{ 374 },{
375 .type = CX88_VMUX_COMPOSITE1, 375 .type = CX88_VMUX_COMPOSITE1,
376 .vmux = 1, 376 .vmux = 1,
377 .gpio0 = 0x00000fbf, 377 .gpio0 = 0x00000fbf,
378 .gpio2 = 0x0000fc68, 378 .gpio2 = 0x0000fc68,
379 },{ 379 },{
380 .type = CX88_VMUX_SVIDEO, 380 .type = CX88_VMUX_SVIDEO,
381 .vmux = 2, 381 .vmux = 2,
382 .gpio0 = 0x00000fbf, 382 .gpio0 = 0x00000fbf,
383 .gpio2 = 0x0000fc68, 383 .gpio2 = 0x0000fc68,
384 }}, 384 }},
385 }, 385 },
386 [CX88_BOARD_KWORLD_DVB_T] = { 386 [CX88_BOARD_KWORLD_DVB_T] = {
387 .name = "KWorld/VStream XPert DVB-T", 387 .name = "KWorld/VStream XPert DVB-T",
388 .tuner_type = TUNER_ABSENT, 388 .tuner_type = TUNER_ABSENT,
389 .radio_type = UNSET, 389 .radio_type = UNSET,
390 .tuner_addr = ADDR_UNSET, 390 .tuner_addr = ADDR_UNSET,
391 .radio_addr = ADDR_UNSET, 391 .radio_addr = ADDR_UNSET,
392 .input = {{ 392 .input = {{
393 .type = CX88_VMUX_COMPOSITE1, 393 .type = CX88_VMUX_COMPOSITE1,
394 .vmux = 1, 394 .vmux = 1,
395 .gpio0 = 0x0700, 395 .gpio0 = 0x0700,
396 .gpio2 = 0x0101, 396 .gpio2 = 0x0101,
397 },{ 397 },{
398 .type = CX88_VMUX_SVIDEO, 398 .type = CX88_VMUX_SVIDEO,
399 .vmux = 2, 399 .vmux = 2,
400 .gpio0 = 0x0700, 400 .gpio0 = 0x0700,
401 .gpio2 = 0x0101, 401 .gpio2 = 0x0101,
402 }}, 402 }},
403 .dvb = 1, 403 .dvb = 1,
404 }, 404 },
405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = {
425 .radio_type = UNSET, 425 .radio_type = UNSET,
426 .tuner_addr = ADDR_UNSET, 426 .tuner_addr = ADDR_UNSET,
427 .radio_addr = ADDR_UNSET, 427 .radio_addr = ADDR_UNSET,
428 .input = {{ 428 .input = {{
429 .type = CX88_VMUX_TELEVISION, 429 .type = CX88_VMUX_TELEVISION,
430 .vmux = 0, 430 .vmux = 0,
431 .gpio0 = 0x07f8, 431 .gpio0 = 0x07f8,
432 },{ 432 },{
433 .type = CX88_VMUX_DEBUG, 433 .type = CX88_VMUX_DEBUG,
434 .vmux = 0, 434 .vmux = 0,
435 .gpio0 = 0x07f9, // mono from tuner chip 435 .gpio0 = 0x07f9, // mono from tuner chip
436 },{ 436 },{
437 .type = CX88_VMUX_COMPOSITE1, 437 .type = CX88_VMUX_COMPOSITE1,
438 .vmux = 1, 438 .vmux = 1,
439 .gpio0 = 0x000007fa, 439 .gpio0 = 0x000007fa,
440 },{ 440 },{
441 .type = CX88_VMUX_SVIDEO, 441 .type = CX88_VMUX_SVIDEO,
442 .vmux = 2, 442 .vmux = 2,
443 .gpio0 = 0x000007fa, 443 .gpio0 = 0x000007fa,
444 }}, 444 }},
445 .radio = { 445 .radio = {
446 .type = CX88_RADIO, 446 .type = CX88_RADIO,
447 .gpio0 = 0x000007f8, 447 .gpio0 = 0x000007f8,
448 }, 448 },
449 }, 449 },
450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { 450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
451 .name = "DViCO FusionHDTV 3 Gold-Q", 451 .name = "DViCO FusionHDTV 3 Gold-Q",
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = {
489 }}, 489 }},
490 .dvb = 1, 490 .dvb = 1,
491 }, 491 },
492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
493 .name = "Hauppauge Nova-T DVB-T", 493 .name = "Hauppauge Nova-T DVB-T",
494 .tuner_type = TUNER_ABSENT, 494 .tuner_type = TUNER_ABSENT,
495 .radio_type = UNSET, 495 .radio_type = UNSET,
496 .tuner_addr = ADDR_UNSET, 496 .tuner_addr = ADDR_UNSET,
497 .radio_addr = ADDR_UNSET, 497 .radio_addr = ADDR_UNSET,
498 .input = {{ 498 .input = {{
499 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
500 .vmux = 0, 500 .vmux = 0,
501 }}, 501 }},
502 .dvb = 1, 502 .dvb = 1,
503 }, 503 },
504 [CX88_BOARD_CONEXANT_DVB_T1] = { 504 [CX88_BOARD_CONEXANT_DVB_T1] = {
505 .name = "Conexant DVB-T reference design", 505 .name = "Conexant DVB-T reference design",
506 .tuner_type = TUNER_ABSENT, 506 .tuner_type = TUNER_ABSENT,
507 .radio_type = UNSET, 507 .radio_type = UNSET,
508 .tuner_addr = ADDR_UNSET, 508 .tuner_addr = ADDR_UNSET,
509 .radio_addr = ADDR_UNSET, 509 .radio_addr = ADDR_UNSET,
510 .input = {{ 510 .input = {{
511 .type = CX88_VMUX_DVB, 511 .type = CX88_VMUX_DVB,
512 .vmux = 0, 512 .vmux = 0,
513 }}, 513 }},
514 .dvb = 1, 514 .dvb = 1,
515 }, 515 },
516 [CX88_BOARD_PROVIDEO_PV259] = { 516 [CX88_BOARD_PROVIDEO_PV259] = {
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = {
543 .dvb = 1, 543 .dvb = 1,
544 }, 544 },
545 [CX88_BOARD_DNTV_LIVE_DVB_T] = { 545 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
546 .name = "digitalnow DNTV Live! DVB-T", 546 .name = "digitalnow DNTV Live! DVB-T",
547 .tuner_type = TUNER_ABSENT, 547 .tuner_type = TUNER_ABSENT,
548 .radio_type = UNSET, 548 .radio_type = UNSET,
549 .tuner_addr = ADDR_UNSET, 549 .tuner_addr = ADDR_UNSET,
550 .radio_addr = ADDR_UNSET, 550 .radio_addr = ADDR_UNSET,
551 .input = {{ 551 .input = {{
552 .type = CX88_VMUX_COMPOSITE1, 552 .type = CX88_VMUX_COMPOSITE1,
553 .vmux = 1, 553 .vmux = 1,
554 .gpio0 = 0x00000700, 554 .gpio0 = 0x00000700,
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = {
705 .gpio0 = 0xbf60, 705 .gpio0 = 0xbf60,
706 }, 706 },
707 }, 707 },
708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
709 .name = "DViCO FusionHDTV 3 Gold-T", 709 .name = "DViCO FusionHDTV 3 Gold-T",
710 .tuner_type = TUNER_THOMSON_DTT7611, 710 .tuner_type = TUNER_THOMSON_DTT7611,
711 .radio_type = UNSET, 711 .radio_type = UNSET,
712 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
713 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
714 .input = {{ 714 .input = {{
715 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
716 .vmux = 0, 716 .vmux = 0,
717 .gpio0 = 0x97ed, 717 .gpio0 = 0x97ed,
718 },{ 718 },{
719 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
720 .vmux = 1, 720 .vmux = 1,
721 .gpio0 = 0x97e9, 721 .gpio0 = 0x97e9,
722 },{ 722 },{
723 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
724 .vmux = 2, 724 .vmux = 2,
725 .gpio0 = 0x97e9, 725 .gpio0 = 0x97e9,
726 }}, 726 }},
727 .dvb = 1, 727 .dvb = 1,
728 }, 728 },
729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = { 729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
730 .name = "ADS Tech Instant TV DVB-T PCI", 730 .name = "ADS Tech Instant TV DVB-T PCI",
731 .tuner_type = TUNER_ABSENT, 731 .tuner_type = TUNER_ABSENT,
732 .radio_type = UNSET, 732 .radio_type = UNSET,
733 .tuner_addr = ADDR_UNSET, 733 .tuner_addr = ADDR_UNSET,
734 .radio_addr = ADDR_UNSET, 734 .radio_addr = ADDR_UNSET,
735 .input = {{ 735 .input = {{
736 .type = CX88_VMUX_COMPOSITE1, 736 .type = CX88_VMUX_COMPOSITE1,
737 .vmux = 1, 737 .vmux = 1,
738 .gpio0 = 0x0700, 738 .gpio0 = 0x0700,
739 .gpio2 = 0x0101, 739 .gpio2 = 0x0101,
740 },{ 740 },{
741 .type = CX88_VMUX_SVIDEO, 741 .type = CX88_VMUX_SVIDEO,
742 .vmux = 2, 742 .vmux = 2,
743 .gpio0 = 0x0700, 743 .gpio0 = 0x0700,
744 .gpio2 = 0x0101, 744 .gpio2 = 0x0101,
745 }}, 745 }},
746 .dvb = 1, 746 .dvb = 1,
747 }, 747 },
748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { 748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = {
762 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
763 .tda9887_conf = TDA9887_PRESENT, 763 .tda9887_conf = TDA9887_PRESENT,
764 .input = {{ 764 .input = {{
765 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
766 .vmux = 0, 766 .vmux = 0,
767 .gpio0 = 0x87fd, 767 .gpio0 = 0x87fd,
768 },{ 768 },{
769 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
770 .vmux = 1, 770 .vmux = 1,
771 .gpio0 = 0x87f9, 771 .gpio0 = 0x87f9,
772 },{ 772 },{
773 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
774 .vmux = 2, 774 .vmux = 2,
775 .gpio0 = 0x87f9, 775 .gpio0 = 0x87f9,
776 }}, 776 }},
777 .dvb = 1,
778 },
779 [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
780 .name = "AverMedia UltraTV Media Center PCI 550",
781 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
782 .radio_type = UNSET,
783 .tuner_addr = ADDR_UNSET,
784 .radio_addr = ADDR_UNSET,
785 .tda9887_conf = TDA9887_PRESENT,
786 .blackbird = 1,
787 .input = {{
788 .type = CX88_VMUX_COMPOSITE1,
789 .vmux = 0,
790 .gpio0 = 0x0000cd73,
791 },{
792 .type = CX88_VMUX_SVIDEO,
793 .vmux = 1,
794 .gpio0 = 0x0000cd73,
795 },{
796 .type = CX88_VMUX_TELEVISION,
797 .vmux = 3,
798 .gpio0 = 0x0000cdb3,
799 }},
800 .radio = {
801 .type = CX88_RADIO,
802 .vmux = 2,
803 .gpio0 = 0x0000cdf3,
804 },
805 },
806 [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
807 /* Alexander Wold <awold@bigfoot.com> */
808 .name = "Kworld V-Stream Xpert DVD",
809 .tuner_type = UNSET,
810 .input = {{
811 .type = CX88_VMUX_COMPOSITE1,
812 .vmux = 1,
813 .gpio0 = 0x03000000,
814 .gpio1 = 0x01000000,
815 .gpio2 = 0x02000000,
816 .gpio3 = 0x00100000,
817 },{
818 .type = CX88_VMUX_SVIDEO,
819 .vmux = 2,
820 .gpio0 = 0x03000000,
821 .gpio1 = 0x01000000,
822 .gpio2 = 0x02000000,
823 .gpio3 = 0x00100000,
824 }},
825 },
826 [CX88_BOARD_ATI_HDTVWONDER] = {
827 .name = "ATI HDTV Wonder",
828 .tuner_type = TUNER_PHILIPS_TUV1236D,
829 .radio_type = UNSET,
830 .tuner_addr = ADDR_UNSET,
831 .radio_addr = ADDR_UNSET,
832 .input = {{
833 .type = CX88_VMUX_TELEVISION,
834 .vmux = 0,
835 .gpio0 = 0x00000ff7,
836 .gpio1 = 0x000000ff,
837 .gpio2 = 0x00000001,
838 .gpio3 = 0x00000000,
839 },{
840 .type = CX88_VMUX_COMPOSITE1,
841 .vmux = 1,
842 .gpio0 = 0x00000ffe,
843 .gpio1 = 0x000000ff,
844 .gpio2 = 0x00000001,
845 .gpio3 = 0x00000000,
846 },{
847 .type = CX88_VMUX_SVIDEO,
848 .vmux = 2,
849 .gpio0 = 0x00000ffe,
850 .gpio1 = 0x000000ff,
851 .gpio2 = 0x00000001,
852 .gpio3 = 0x00000000,
853 }},
777 .dvb = 1, 854 .dvb = 1,
778 }, 855 },
856 [CX88_BOARD_WINFAST_DTV1000] = {
857 .name = "WinFast DTV1000-T",
858 .tuner_type = TUNER_ABSENT,
859 .radio_type = UNSET,
860 .tuner_addr = ADDR_UNSET,
861 .radio_addr = ADDR_UNSET,
862 .input = {{
863 .type = CX88_VMUX_DVB,
864 .vmux = 0,
865 }},
866 .dvb = 1,
867 },
868 [CX88_BOARD_AVERTV_303] = {
869 .name = "AVerTV 303 (M126)",
870 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
871 .radio_type = UNSET,
872 .tuner_addr = ADDR_UNSET,
873 .radio_addr = ADDR_UNSET,
874 .tda9887_conf = TDA9887_PRESENT,
875 .input = {{
876 .type = CX88_VMUX_TELEVISION,
877 .vmux = 0,
878 .gpio0 = 0x00ff,
879 .gpio1 = 0xe09f,
880 .gpio2 = 0x0010,
881 .gpio3 = 0x0000,
882 },{
883 .type = CX88_VMUX_COMPOSITE1,
884 .vmux = 1,
885 .gpio0 = 0x00ff,
886 .gpio1 = 0xe05f,
887 .gpio2 = 0x0010,
888 .gpio3 = 0x0000,
889 },{
890 .type = CX88_VMUX_SVIDEO,
891 .vmux = 2,
892 .gpio0 = 0x00ff,
893 .gpio1 = 0xe05f,
894 .gpio2 = 0x0010,
895 .gpio3 = 0x0000,
896 }},
897 },
779}; 898};
780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 899const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
781 900
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = {
804 .subdevice = 0x00f8, 923 .subdevice = 0x00f8,
805 .card = CX88_BOARD_ATI_WONDER_PRO, 924 .card = CX88_BOARD_ATI_WONDER_PRO,
806 },{ 925 },{
807 .subvendor = 0x107d, 926 .subvendor = 0x107d,
808 .subdevice = 0x6611, 927 .subdevice = 0x6611,
809 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 928 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
929 },{
930 .subvendor = 0x107d,
931 .subdevice = 0x6613, /* NTSC */
932 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
810 },{ 933 },{
811 .subvendor = 0x107d, 934 .subvendor = 0x107d,
812 .subdevice = 0x6613, /* NTSC */ 935 .subdevice = 0x6620,
813 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 936 .card = CX88_BOARD_WINFAST_DV2000,
937 },{
938 .subvendor = 0x107d,
939 .subdevice = 0x663b,
940 .card = CX88_BOARD_LEADTEK_PVR2000,
814 },{ 941 },{
815 .subvendor = 0x107d, 942 .subvendor = 0x107d,
816 .subdevice = 0x6620, 943 .subdevice = 0x663C,
817 .card = CX88_BOARD_WINFAST_DV2000, 944 .card = CX88_BOARD_LEADTEK_PVR2000,
818 },{ 945 },{
819 .subvendor = 0x107d,
820 .subdevice = 0x663b,
821 .card = CX88_BOARD_LEADTEK_PVR2000,
822 },{
823 .subvendor = 0x107d,
824 .subdevice = 0x663C,
825 .card = CX88_BOARD_LEADTEK_PVR2000,
826 },{
827 .subvendor = 0x1461, 946 .subvendor = 0x1461,
828 .subdevice = 0x000b, 947 .subdevice = 0x000b,
829 .card = CX88_BOARD_AVERTV_303, 948 .card = CX88_BOARD_AVERTV_STUDIO_303,
830 },{ 949 },{
831 .subvendor = 0x1462, 950 .subvendor = 0x1462,
832 .subdevice = 0x8606, 951 .subdevice = 0x8606,
833 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, 952 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
834 },{ 953 },{
835 .subvendor = 0x10fc, 954 .subvendor = 0x10fc,
836 .subdevice = 0xd003, 955 .subdevice = 0xd003,
837 .card = CX88_BOARD_IODATA_GVVCP3PCI, 956 .card = CX88_BOARD_IODATA_GVVCP3PCI,
838 },{ 957 },{
839 .subvendor = 0x1043, 958 .subvendor = 0x1043,
840 .subdevice = 0x4823, /* with mpeg encoder */ 959 .subdevice = 0x4823, /* with mpeg encoder */
841 .card = CX88_BOARD_ASUS_PVR_416, 960 .card = CX88_BOARD_ASUS_PVR_416,
842 },{ 961 },{
843 .subvendor = 0x17de, 962 .subvendor = 0x17de,
844 .subdevice = 0x08a6, 963 .subdevice = 0x08a6,
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = {
852 .subdevice = 0xd820, 971 .subdevice = 0xd820,
853 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, 972 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
854 },{ 973 },{
855 .subvendor = 0x18AC, 974 .subvendor = 0x18ac,
856 .subdevice = 0xDB00, 975 .subdevice = 0xdb00,
857 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 976 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
858 },{ 977 },{
859 .subvendor = 0x0070, 978 .subvendor = 0x0070,
860 .subdevice = 0x9002, 979 .subdevice = 0x9002,
861 .card = CX88_BOARD_HAUPPAUGE_DVB_T1, 980 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
862 },{ 981 },{
863 .subvendor = 0x14f1, 982 .subvendor = 0x14f1,
864 .subdevice = 0x0187, 983 .subdevice = 0x0187,
865 .card = CX88_BOARD_CONEXANT_DVB_T1, 984 .card = CX88_BOARD_CONEXANT_DVB_T1,
866 },{ 985 },{
867 .subvendor = 0x1540, 986 .subvendor = 0x1540,
868 .subdevice = 0x2580, 987 .subdevice = 0x2580,
869 .card = CX88_BOARD_PROVIDEO_PV259, 988 .card = CX88_BOARD_PROVIDEO_PV259,
870 },{ 989 },{
871 .subvendor = 0x18AC, 990 .subvendor = 0x18ac,
872 .subdevice = 0xDB10, 991 .subdevice = 0xdb10,
873 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 992 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
874 },{ 993 },{
875 .subvendor = 0x1554, 994 .subvendor = 0x1554,
876 .subdevice = 0x4811, 995 .subdevice = 0x4811,
877 .card = CX88_BOARD_PIXELVIEW, 996 .card = CX88_BOARD_PIXELVIEW,
878 },{ 997 },{
879 .subvendor = 0x7063, 998 .subvendor = 0x7063,
880 .subdevice = 0x3000, /* HD-3000 card */ 999 .subdevice = 0x3000, /* HD-3000 card */
881 .card = CX88_BOARD_PCHDTV_HD3000, 1000 .card = CX88_BOARD_PCHDTV_HD3000,
882 },{ 1001 },{
883 .subvendor = 0x17DE, 1002 .subvendor = 0x17de,
884 .subdevice = 0xA8A6, 1003 .subdevice = 0xa8a6,
885 .card = CX88_BOARD_DNTV_LIVE_DVB_T, 1004 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
886 },{ 1005 },{
887 .subvendor = 0x0070, 1006 .subvendor = 0x0070,
888 .subdevice = 0x2801, 1007 .subdevice = 0x2801,
889 .card = CX88_BOARD_HAUPPAUGE_ROSLYN, 1008 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
890 },{ 1009 },{
891 .subvendor = 0x14F1, 1010 .subvendor = 0x14f1,
892 .subdevice = 0x0342, 1011 .subdevice = 0x0342,
893 .card = CX88_BOARD_DIGITALLOGIC_MEC, 1012 .card = CX88_BOARD_DIGITALLOGIC_MEC,
894 },{ 1013 },{
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = {
899 .subvendor = 0x1421, 1018 .subvendor = 0x1421,
900 .subdevice = 0x0334, 1019 .subdevice = 0x0334,
901 .card = CX88_BOARD_ADSTECH_DVB_T_PCI, 1020 .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
902 },{ 1021 },{
903 .subvendor = 0x153b, 1022 .subvendor = 0x153b,
904 .subdevice = 0x1166, 1023 .subdevice = 0x1166,
905 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, 1024 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
906 },{ 1025 },{
907 .subvendor = 0x18ac, 1026 .subvendor = 0x18ac,
908 .subdevice = 0xd500, 1027 .subdevice = 0xd500,
909 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, 1028 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
1029 },{
1030 .subvendor = 0x1461,
1031 .subdevice = 0x8011,
1032 .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
1033 },{
1034 .subvendor = PCI_VENDOR_ID_ATI,
1035 .subdevice = 0xa101,
1036 .card = CX88_BOARD_ATI_HDTVWONDER,
1037 },{
1038 .subvendor = 0x107d,
1039 .subdevice = 0x665f,
1040 .card = CX88_BOARD_WINFAST_DTV1000,
1041 },{
1042 .subvendor = 0x1461,
1043 .subdevice = 0x000a,
1044 .card = CX88_BOARD_AVERTV_303,
910 }, 1045 },
911}; 1046};
912const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1047const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core)
1108 cx_clear(MO_GP0_IO, 0x00000007); 1243 cx_clear(MO_GP0_IO, 0x00000007);
1109 cx_set(MO_GP2_IO, 0x00000101); 1244 cx_set(MO_GP2_IO, 0x00000101);
1110 break; 1245 break;
1246 case CX88_BOARD_ATI_HDTVWONDER:
1247 if (0 == core->i2c_rc) {
1248 /* enable tuner */
1249 int i;
1250 u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
1251 core->i2c_client.addr = 0x0a;
1252
1253 for (i = 0; i < 5; i++)
1254 if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
1255 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
1256 core->name, i);
1257 }
1258 break;
1111 } 1259 }
1112 if (cx88_boards[core->board].radio.type == CX88_RADIO) 1260 if (cx88_boards[core->board].radio.type == CX88_RADIO)
1113 core->has_radio = 1; 1261 core->has_radio = 1;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index dc5c5c1f3461..eb806af17182 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -31,7 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/videodev.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37 37
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
153 } 153 }
154 if (bpl <= sg_dma_len(sg)-offset) { 154 if (bpl <= sg_dma_len(sg)-offset) {
155 /* fits into current chunk */ 155 /* fits into current chunk */
156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); 156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
158 offset+=bpl; 158 offset+=bpl;
159 } else { 159 } else {
160 /* scanline needs to be splitted */ 160 /* scanline needs to be splitted */
161 todo = bpl; 161 todo = bpl;
162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| 162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
163 (sg_dma_len(sg)-offset)); 163 (sg_dma_len(sg)-offset));
164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
165 todo -= (sg_dma_len(sg)-offset); 165 todo -= (sg_dma_len(sg)-offset);
166 offset = 0; 166 offset = 0;
167 sg++; 167 sg++;
168 while (todo > sg_dma_len(sg)) { 168 while (todo > sg_dma_len(sg)) {
169 *(rp++)=cpu_to_le32(RISC_WRITE| 169 *(rp++)=cpu_to_le32(RISC_WRITE|
170 sg_dma_len(sg)); 170 sg_dma_len(sg));
171 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 171 *(rp++)=cpu_to_le32(sg_dma_address(sg));
172 todo -= sg_dma_len(sg); 172 todo -= sg_dma_len(sg);
173 sg++; 173 sg++;
174 } 174 }
175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); 175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
176 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 176 *(rp++)=cpu_to_le32(sg_dma_address(sg));
177 offset += todo; 177 offset += todo;
178 } 178 }
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = {
309 .name = "video y / packed", 309 .name = "video y / packed",
310 .cmds_start = 0x180040, 310 .cmds_start = 0x180040,
311 .ctrl_start = 0x180400, 311 .ctrl_start = 0x180400,
312 .cdt = 0x180400 + 64, 312 .cdt = 0x180400 + 64,
313 .fifo_start = 0x180c00, 313 .fifo_start = 0x180c00,
314 .fifo_size = 0x002800, 314 .fifo_size = 0x002800,
315 .ptr1_reg = MO_DMA21_PTR1, 315 .ptr1_reg = MO_DMA21_PTR1,
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = {
321 .name = "video u", 321 .name = "video u",
322 .cmds_start = 0x180080, 322 .cmds_start = 0x180080,
323 .ctrl_start = 0x1804a0, 323 .ctrl_start = 0x1804a0,
324 .cdt = 0x1804a0 + 64, 324 .cdt = 0x1804a0 + 64,
325 .fifo_start = 0x183400, 325 .fifo_start = 0x183400,
326 .fifo_size = 0x000800, 326 .fifo_size = 0x000800,
327 .ptr1_reg = MO_DMA22_PTR1, 327 .ptr1_reg = MO_DMA22_PTR1,
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = {
333 .name = "video v", 333 .name = "video v",
334 .cmds_start = 0x1800c0, 334 .cmds_start = 0x1800c0,
335 .ctrl_start = 0x180540, 335 .ctrl_start = 0x180540,
336 .cdt = 0x180540 + 64, 336 .cdt = 0x180540 + 64,
337 .fifo_start = 0x183c00, 337 .fifo_start = 0x183c00,
338 .fifo_size = 0x000800, 338 .fifo_size = 0x000800,
339 .ptr1_reg = MO_DMA23_PTR1, 339 .ptr1_reg = MO_DMA23_PTR1,
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = {
345 .name = "vbi", 345 .name = "vbi",
346 .cmds_start = 0x180100, 346 .cmds_start = 0x180100,
347 .ctrl_start = 0x1805e0, 347 .ctrl_start = 0x1805e0,
348 .cdt = 0x1805e0 + 64, 348 .cdt = 0x1805e0 + 64,
349 .fifo_start = 0x184400, 349 .fifo_start = 0x184400,
350 .fifo_size = 0x001000, 350 .fifo_size = 0x001000,
351 .ptr1_reg = MO_DMA24_PTR1, 351 .ptr1_reg = MO_DMA24_PTR1,
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = {
357 .name = "audio from", 357 .name = "audio from",
358 .cmds_start = 0x180140, 358 .cmds_start = 0x180140,
359 .ctrl_start = 0x180680, 359 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 360 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 361 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 362 .fifo_size = 0x000200,
363 .ptr1_reg = MO_DMA25_PTR1, 363 .ptr1_reg = MO_DMA25_PTR1,
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = {
369 .name = "audio to", 369 .name = "audio to",
370 .cmds_start = 0x180180, 370 .cmds_start = 0x180180,
371 .ctrl_start = 0x180720, 371 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 372 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 373 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 374 .fifo_size = 0x000200, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 375 .ptr1_reg = MO_DMA26_PTR1,
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
431/* ------------------------------------------------------------------ */ 431/* ------------------------------------------------------------------ */
432/* debug helper code */ 432/* debug helper code */
433 433
434int cx88_risc_decode(u32 risc) 434static int cx88_risc_decode(u32 risc)
435{ 435{
436 static char *instr[16] = { 436 static char *instr[16] = {
437 [ RISC_SYNC >> 28 ] = "sync", 437 [ RISC_SYNC >> 28 ] = "sync",
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core)
845 return 0; 845 return 0;
846 846
847 if (V4L2_STD_PAL_BG & norm->id) { 847 if (V4L2_STD_PAL_BG & norm->id) {
848 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; 848 core->tvaudio = WW_BG;
849 849
850 } else if (V4L2_STD_PAL_DK & norm->id) { 850 } else if (V4L2_STD_PAL_DK & norm->id) {
851 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; 851 core->tvaudio = WW_DK;
852 852
853 } else if (V4L2_STD_PAL_I & norm->id) { 853 } else if (V4L2_STD_PAL_I & norm->id) {
854 core->tvaudio = WW_NICAM_I; 854 core->tvaudio = WW_I;
855 855
856 } else if (V4L2_STD_SECAM_L & norm->id) { 856 } else if (V4L2_STD_SECAM_L & norm->id) {
857 core->tvaudio = WW_SYSTEM_L_AM; 857 core->tvaudio = WW_L;
858 858
859 } else if (V4L2_STD_SECAM_DK & norm->id) { 859 } else if (V4L2_STD_SECAM_DK & norm->id) {
860 core->tvaudio = WW_A2_DK; 860 core->tvaudio = WW_DK;
861 861
862 } else if ((V4L2_STD_NTSC_M & norm->id) || 862 } else if ((V4L2_STD_NTSC_M & norm->id) ||
863 (V4L2_STD_PAL_M & norm->id)) { 863 (V4L2_STD_PAL_M & norm->id)) {
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1137 if (!core->radio_addr) 1137 if (!core->radio_addr)
1138 core->radio_addr = cx88_boards[core->board].radio_addr; 1138 core->radio_addr = cx88_boards[core->board].radio_addr;
1139 1139
1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", 1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1141 core->tuner_type, core->tuner_addr<<1, 1141 core->tuner_type, core->tuner_addr<<1,
1142 core->radio_type, core->radio_addr<<1); 1142 core->radio_type, core->radio_addr<<1);
1143 1143
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1146 /* init hardware */ 1146 /* init hardware */
1147 cx88_reset(core); 1147 cx88_reset(core);
1148 cx88_i2c_init(core,pci); 1148 cx88_i2c_init(core,pci);
1149 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1149 cx88_card_setup(core); 1150 cx88_card_setup(core);
1150 cx88_ir_init(core,pci); 1151 cx88_ir_init(core,pci);
1151 1152
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4334744652de..9cce91ec334b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/file.h> 29#include <linux/file.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "cx88.h" 32#include "cx88.h"
34#include "dvb-pll.h" 33#include "dvb-pll.h"
35 34
@@ -46,6 +45,9 @@
46#ifdef HAVE_LGDT330X 45#ifdef HAVE_LGDT330X
47# include "lgdt330x.h" 46# include "lgdt330x.h"
48#endif 47#endif
48#ifdef HAVE_NXT200X
49# include "nxt200x.h"
50#endif
49 51
50MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
51MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
78 enum v4l2_field field) 80 enum v4l2_field field)
79{ 81{
80 struct cx8802_dev *dev = q->priv_data; 82 struct cx8802_dev *dev = q->priv_data;
81 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb); 83 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
82} 84}
83 85
84static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 86static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129 static u8 reset [] = { 0x50, 0x80 }; 131 static u8 reset [] = { 0x50, 0x80 };
130 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 132 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
131 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 133 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
132 0x00, 0xFF, 0x00, 0x40, 0x40 }; 134 0x00, 0xFF, 0x00, 0x40, 0x40 };
133 static u8 dntv_extra[] = { 0xB5, 0x7A }; 135 static u8 dntv_extra[] = { 0xB5, 0x7A };
134 static u8 capt_range_cfg[] = { 0x75, 0x32 }; 136 static u8 capt_range_cfg[] = { 0x75, 0x32 };
135 137
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
285}; 287};
286#endif 288#endif
287 289
290#ifdef HAVE_NXT200X
291static int nxt200x_set_ts_param(struct dvb_frontend* fe,
292 int is_punctured)
293{
294 struct cx8802_dev *dev= fe->dvb->priv;
295 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
296 return 0;
297}
298
299static int nxt200x_set_pll_input(u8* buf, int input)
300{
301 if (input)
302 buf[3] |= 0x08;
303 else
304 buf[3] &= ~0x08;
305 return 0;
306}
307
308static struct nxt200x_config ati_hdtvwonder = {
309 .demod_address = 0x0a,
310 .pll_address = 0x61,
311 .pll_desc = &dvb_pll_tuv1236d,
312 .set_pll_input = nxt200x_set_pll_input,
313 .set_ts_params = nxt200x_set_ts_param,
314};
315#endif
316
288static int dvb_register(struct cx8802_dev *dev) 317static int dvb_register(struct cx8802_dev *dev)
289{ 318{
290 /* init struct videobuf_dvb */ 319 /* init struct videobuf_dvb */
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev)
300 break; 329 break;
301 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
302 case CX88_BOARD_CONEXANT_DVB_T1: 331 case CX88_BOARD_CONEXANT_DVB_T1:
332 case CX88_BOARD_WINFAST_DTV1000:
303 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
304 &dev->core->i2c_adap); 334 &dev->core->i2c_adap);
305 break; 335 break;
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev)
385 } 415 }
386 break; 416 break;
387#endif 417#endif
418#ifdef HAVE_NXT200X
419 case CX88_BOARD_ATI_HDTVWONDER:
420 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
421 &dev->core->i2c_adap);
422 break;
423#endif
388 default: 424 default:
389 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
390 dev->core->name); 426 dev->core->name);
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
403 /* Put the analog decoder in standby to keep it quiet */ 439 /* Put the analog decoder in standby to keep it quiet */
404 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 440 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
405 441
442 /* Put the analog decoder in standby to keep it quiet */
443 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
444
406 /* register everything */ 445 /* register everything */
407 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 446 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
408} 447}
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
461 500
462static void __devexit dvb_remove(struct pci_dev *pci_dev) 501static void __devexit dvb_remove(struct pci_dev *pci_dev)
463{ 502{
464 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 503 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
465 504
466 /* dvb */ 505 /* dvb */
467 videobuf_dvb_unregister(&dev->dvb); 506 videobuf_dvb_unregister(&dev->dvb);
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
476 { 515 {
477 .vendor = 0x14f1, 516 .vendor = 0x14f1,
478 .device = 0x8802, 517 .device = 0x8802,
479 .subvendor = PCI_ANY_ID, 518 .subvendor = PCI_ANY_ID,
480 .subdevice = PCI_ANY_ID, 519 .subdevice = PCI_ANY_ID,
481 },{ 520 },{
482 /* --- end of list --- */ 521 /* --- end of list --- */
483 } 522 }
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
485MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 524MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
486 525
487static struct pci_driver dvb_pci_driver = { 526static struct pci_driver dvb_pci_driver = {
488 .name = "cx88-dvb", 527 .name = "cx88-dvb",
489 .id_table = cx8802_pci_tbl, 528 .id_table = cx8802_pci_tbl,
490 .probe = dvb_probe, 529 .probe = dvb_probe,
491 .remove = __devexit_p(dvb_remove), 530 .remove = __devexit_p(dvb_remove),
492 .suspend = cx8802_suspend_common, 531 .suspend = cx8802_suspend_common,
493 .resume = cx8802_resume_common, 532 .resume = cx8802_resume_common,
494}; 533};
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 761cebd40dbd..9790d412f192 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -3,7 +3,7 @@
3 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 & Marcus Metzler (mocm@thp.uni-koeln.de) 6 & Marcus Metzler (mocm@thp.uni-koeln.de)
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net> 7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
9 9
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data)
90 90
91static int attach_inform(struct i2c_client *client) 91static int attach_inform(struct i2c_client *client)
92{ 92{
93 struct tuner_setup tun_setup; 93 struct tuner_setup tun_setup;
94 struct cx88_core *core = i2c_get_adapdata(client->adapter); 94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95 95
96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client)
98 if (!client->driver->command) 98 if (!client->driver->command)
99 return 0; 99 return 0;
100 100
101 if (core->radio_type != UNSET) { 101 if (core->radio_type != UNSET) {
102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { 102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
103 tun_setup.mode_mask = T_RADIO; 103 tun_setup.mode_mask = T_RADIO;
104 tun_setup.type = core->radio_type; 104 tun_setup.type = core->radio_type;
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client)
106 106
107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); 107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
108 } 108 }
109 } 109 }
110 if (core->tuner_type != UNSET) { 110 if (core->tuner_type != UNSET) {
111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { 111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
112 112
113 tun_setup.mode_mask = T_ANALOG_TV; 113 tun_setup.mode_mask = T_ANALOG_TV;
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client)
116 116
117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); 117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
118 } 118 }
119 } 119 }
120 120
121 if (core->tda9887_conf) 121 if (core->tda9887_conf)
122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); 122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = {
159}; 159};
160 160
161static struct i2c_client cx8800_i2c_client_template = { 161static struct i2c_client cx8800_i2c_client_template = {
162 .name = "cx88xx internal", 162 .name = "cx88xx internal",
163}; 163};
164 164
165static char *i2c_devs[128] = { 165static char *i2c_devs[128] = {
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
202 202
203 core->i2c_adap.dev.parent = &pci->dev; 203 core->i2c_adap.dev.parent = &pci->dev;
204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); 204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
205 core->i2c_algo.data = core; 205 core->i2c_algo.data = core;
206 i2c_set_adapdata(&core->i2c_adap,core); 206 i2c_set_adapdata(&core->i2c_adap,core);
207 core->i2c_adap.algo_data = &core->i2c_algo; 207 core->i2c_adap.algo_data = &core->i2c_algo;
208 core->i2c_client.adapter = &core->i2c_adap; 208 core->i2c_client.adapter = &core->i2c_adap;
209 209
210 cx8800_bit_setscl(core,1); 210 cx8800_bit_setscl(core,1);
211 cx8800_bit_setsda(core,1); 211 cx8800_bit_setsda(core,1);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index c27fe4c36f69..38b12ebaa49e 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -553,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core)
553 553
554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
555 ir_dprintk("pulse distance decoded wrong address\n"); 555 ir_dprintk("pulse distance decoded wrong address\n");
556 break; 556 break;
557 } 557 }
558 558
559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ 559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index ee2300e1ae0b..35e6d0c2b872 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
54{ 54{
55 struct cx88_core *core = dev->core; 55 struct cx88_core *core = dev->core;
56 56
57 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); 57 dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
58 58
59 /* setup fifo + format */ 59 /* setup fifo + format */
60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
158 158
159/* ------------------------------------------------------------------ */ 159/* ------------------------------------------------------------------ */
160 160
161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) 161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
162 enum v4l2_field field)
162{ 163{
163 int size = dev->ts_packet_size * dev->ts_packet_count; 164 int size = dev->ts_packet_size * dev->ts_packet_count;
164 int rc; 165 int rc;
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
171 buf->vb.width = dev->ts_packet_size; 172 buf->vb.width = dev->ts_packet_size;
172 buf->vb.height = dev->ts_packet_count; 173 buf->vb.height = dev->ts_packet_count;
173 buf->vb.size = size; 174 buf->vb.size = size;
174 buf->vb.field = V4L2_FIELD_TOP; 175 buf->vb.field = field /*V4L2_FIELD_TOP*/;
175 176
176 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) 177 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
177 goto fail; 178 goto fail;
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
315 spin_unlock(&dev->slock); 316 spin_unlock(&dev->slock);
316 } 317 }
317 318
318 /* other general errors */ 319 /* other general errors */
319 if (status & 0x1f0100) { 320 if (status & 0x1f0100) {
320 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); 321 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
321 spin_lock(&dev->slock); 322 spin_lock(&dev->slock);
322 cx8802_stop_dma(dev); 323 cx8802_stop_dma(dev);
323 cx8802_restart_queue(dev,&dev->mpegq); 324 cx8802_restart_queue(dev,&dev->mpegq);
324 spin_unlock(&dev->slock); 325 spin_unlock(&dev->slock);
325 } 326 }
326} 327}
327 328
328#define MAX_IRQ_LOOP 10 329#define MAX_IRQ_LOOP 10
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 } 379 }
379 380
380 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 381 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
381 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 382 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
382 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 383 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
383 "latency: %d, mmio: 0x%lx\n", dev->core->name, 384 "latency: %d, mmio: 0x%lx\n", dev->core->name,
384 pci_name(dev->pci), dev->pci_rev, dev->pci->irq, 385 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
385 dev->pci_lat,pci_resource_start(dev->pci,0)); 386 dev->pci_lat,pci_resource_start(dev->pci,0));
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
429 430
430int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) 431int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
431{ 432{
432 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 433 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
433 struct cx88_core *core = dev->core; 434 struct cx88_core *core = dev->core;
434 435
435 /* stop mpeg dma */ 436 /* stop mpeg dma */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 0a3a62fc9bbb..d3bf5b17b1d4 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -3,9 +3,9 @@
3 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 2001 Michael Eskin 6 2001 Michael Eskin
7 2002 Yurij Sysoev <yurij@naturesoft.net> 7 2002 Yurij Sysoev <yurij@naturesoft.net>
8 2003 Gerd Knorr <kraxel@bytesex.org> 8 2003 Gerd Knorr <kraxel@bytesex.org>
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
@@ -728,13 +728,13 @@
728#define ColorFormatGamma 0x1000 728#define ColorFormatGamma 0x1000
729 729
730#define Interlaced 0x1 730#define Interlaced 0x1
731#define NonInterlaced 0x0 731#define NonInterlaced 0x0
732 732
733#define FieldEven 0x1 733#define FieldEven 0x1
734#define FieldOdd 0x0 734#define FieldOdd 0x0
735 735
736#define TGReadWriteMode 0x0 736#define TGReadWriteMode 0x0
737#define TGEnableMode 0x1 737#define TGEnableMode 0x1
738 738
739#define DV_CbAlign 0x0 739#define DV_CbAlign 0x0
740#define DV_Y0Align 0x1 740#define DV_Y0Align 0x1
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 2765acee0285..6d9bec1c583b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -57,39 +57,38 @@
57#include "cx88.h" 57#include "cx88.h"
58 58
59static unsigned int audio_debug = 0; 59static unsigned int audio_debug = 0;
60module_param(audio_debug,int,0644); 60module_param(audio_debug, int, 0644);
61MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); 61MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
62 62
63#define dprintk(fmt, arg...) if (audio_debug) \ 63#define dprintk(fmt, arg...) if (audio_debug) \
64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) 64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
65 65
66/* ----------------------------------------------------------- */ 66/* ----------------------------------------------------------- */
67 67
68static char *aud_ctl_names[64] = 68static char *aud_ctl_names[64] = {
69{ 69 [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
70 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", 70 [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
71 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", 71 [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
72 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", 72 [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
73 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", 73 [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
74 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", 74 [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
75 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", 75 [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
76 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", 76 [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
77 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", 77 [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
78 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", 78 [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
79 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", 79 [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
80 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", 80 [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
81 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", 81 [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
82 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", 82 [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
83 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", 83 [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
84 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", 84 [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
85 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", 85 [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
86 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", 86 [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
87 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", 87 [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
88 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", 88 [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
89 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", 89 [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
90 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", 90 [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
91 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", 91 [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
92 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
93}; 92};
94 93
95struct rlist { 94struct rlist {
@@ -97,8 +96,7 @@ struct rlist {
97 u32 val; 96 u32 val;
98}; 97};
99 98
100static void set_audio_registers(struct cx88_core *core, 99static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
101 const struct rlist *l)
102{ 100{
103 int i; 101 int i;
104 102
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core,
119 } 117 }
120} 118}
121 119
122static void set_audio_start(struct cx88_core *core, 120static void set_audio_start(struct cx88_core *core, u32 mode)
123 u32 mode)
124{ 121{
125 // mute 122 // mute
126 cx_write(AUD_VOL_CTL, (1 << 6)); 123 cx_write(AUD_VOL_CTL, (1 << 6));
127 124
128 // start programming 125 // start programming
129 cx_write(AUD_CTL, 0x0000); 126 cx_write(MO_AUD_DMACNTRL, 0x0000);
130 cx_write(AUD_INIT, mode); 127 msleep(100);
131 cx_write(AUD_INIT_LD, 0x0001); 128 //cx_write(AUD_CTL, 0x0000);
132 cx_write(AUD_SOFT_RESET, 0x0001); 129 cx_write(AUD_INIT, mode);
130 cx_write(AUD_INIT_LD, 0x0001);
131 cx_write(AUD_SOFT_RESET, 0x0001);
133} 132}
134 133
135static void set_audio_finish(struct cx88_core *core, u32 ctl) 134static void set_audio_finish(struct cx88_core *core, u32 ctl)
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
148 cx_write(AUD_I2SCNTL, 0); 147 cx_write(AUD_I2SCNTL, 0);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 148 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else { 149 } else {
151 ctl |= EN_DAC_ENABLE; 150 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl); 151 cx_write(AUD_CTL, ctl);
153 } 152 }
154 153
155 /* finish programming */ 154 /* finish programming */
156 cx_write(AUD_SOFT_RESET, 0x0000); 155 cx_write(AUD_SOFT_RESET, 0x0000);
156 cx_write(MO_AUD_DMACNTRL, 0x0003);
157 157
158 /* unmute */ 158 /* unmute */
159 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
162 162
163/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
164 164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
166 u32 mode)
166{ 167{
167 static const struct rlist btsc[] = { 168 static const struct rlist btsc[] = {
168 { AUD_AFE_12DB_EN, 0x00000001 }, 169 {AUD_AFE_12DB_EN, 0x00000001},
169 { AUD_OUT1_SEL, 0x00000013 }, 170 {AUD_OUT1_SEL, 0x00000013},
170 { AUD_OUT1_SHIFT, 0x00000000 }, 171 {AUD_OUT1_SHIFT, 0x00000000},
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 172 {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
172 { AUD_DMD_RA_DDS, 0x00c3e7aa }, 173 {AUD_DMD_RA_DDS, 0x00c3e7aa},
173 { AUD_DBX_IN_GAIN, 0x00004734 }, 174 {AUD_DBX_IN_GAIN, 0x00004734},
174 { AUD_DBX_WBE_GAIN, 0x00004640 }, 175 {AUD_DBX_WBE_GAIN, 0x00004640},
175 { AUD_DBX_SE_GAIN, 0x00008d31 }, 176 {AUD_DBX_SE_GAIN, 0x00008d31},
176 { AUD_DCOC_0_SRC, 0x0000001a }, 177 {AUD_DCOC_0_SRC, 0x0000001a},
177 { AUD_IIR1_4_SEL, 0x00000021 }, 178 {AUD_IIR1_4_SEL, 0x00000021},
178 { AUD_DCOC_PASS_IN, 0x00000003 }, 179 {AUD_DCOC_PASS_IN, 0x00000003},
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 180 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 181 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 182 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 183 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
183 { AUD_DN0_FREQ, 0x0000283b }, 184 {AUD_DN0_FREQ, 0x0000283b},
184 { AUD_DN2_SRC_SEL, 0x00000008 }, 185 {AUD_DN2_SRC_SEL, 0x00000008},
185 { AUD_DN2_FREQ, 0x00003000 }, 186 {AUD_DN2_FREQ, 0x00003000},
186 { AUD_DN2_AFC, 0x00000002 }, 187 {AUD_DN2_AFC, 0x00000002},
187 { AUD_DN2_SHFT, 0x00000000 }, 188 {AUD_DN2_SHFT, 0x00000000},
188 { AUD_IIR2_2_SEL, 0x00000020 }, 189 {AUD_IIR2_2_SEL, 0x00000020},
189 { AUD_IIR2_2_SHIFT, 0x00000000 }, 190 {AUD_IIR2_2_SHIFT, 0x00000000},
190 { AUD_IIR2_3_SEL, 0x0000001f }, 191 {AUD_IIR2_3_SEL, 0x0000001f},
191 { AUD_IIR2_3_SHIFT, 0x00000000 }, 192 {AUD_IIR2_3_SHIFT, 0x00000000},
192 { AUD_CRDC1_SRC_SEL, 0x000003ce }, 193 {AUD_CRDC1_SRC_SEL, 0x000003ce},
193 { AUD_CRDC1_SHIFT, 0x00000000 }, 194 {AUD_CRDC1_SHIFT, 0x00000000},
194 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 195 {AUD_CORDIC_SHIFT_1, 0x00000007},
195 { AUD_DCOC_1_SRC, 0x0000001b }, 196 {AUD_DCOC_1_SRC, 0x0000001b},
196 { AUD_DCOC1_SHIFT, 0x00000000 }, 197 {AUD_DCOC1_SHIFT, 0x00000000},
197 { AUD_RDSI_SEL, 0x00000008 }, 198 {AUD_RDSI_SEL, 0x00000008},
198 { AUD_RDSQ_SEL, 0x00000008 }, 199 {AUD_RDSQ_SEL, 0x00000008},
199 { AUD_RDSI_SHIFT, 0x00000000 }, 200 {AUD_RDSI_SHIFT, 0x00000000},
200 { AUD_RDSQ_SHIFT, 0x00000000 }, 201 {AUD_RDSQ_SHIFT, 0x00000000},
201 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 202 {AUD_POLYPH80SCALEFAC, 0x00000003},
202 { /* end of list */ }, 203 { /* end of list */ },
203 }; 204 };
204 static const struct rlist btsc_sap[] = { 205 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 }, 206 {AUD_AFE_12DB_EN, 0x00000001},
206 { AUD_DBX_IN_GAIN, 0x00007200 }, 207 {AUD_DBX_IN_GAIN, 0x00007200},
207 { AUD_DBX_WBE_GAIN, 0x00006200 }, 208 {AUD_DBX_WBE_GAIN, 0x00006200},
208 { AUD_DBX_SE_GAIN, 0x00006200 }, 209 {AUD_DBX_SE_GAIN, 0x00006200},
209 { AUD_IIR1_1_SEL, 0x00000000 }, 210 {AUD_IIR1_1_SEL, 0x00000000},
210 { AUD_IIR1_3_SEL, 0x00000001 }, 211 {AUD_IIR1_3_SEL, 0x00000001},
211 { AUD_DN1_SRC_SEL, 0x00000007 }, 212 {AUD_DN1_SRC_SEL, 0x00000007},
212 { AUD_IIR1_4_SHIFT, 0x00000006 }, 213 {AUD_IIR1_4_SHIFT, 0x00000006},
213 { AUD_IIR2_1_SHIFT, 0x00000000 }, 214 {AUD_IIR2_1_SHIFT, 0x00000000},
214 { AUD_IIR2_2_SHIFT, 0x00000000 }, 215 {AUD_IIR2_2_SHIFT, 0x00000000},
215 { AUD_IIR3_0_SHIFT, 0x00000000 }, 216 {AUD_IIR3_0_SHIFT, 0x00000000},
216 { AUD_IIR3_1_SHIFT, 0x00000000 }, 217 {AUD_IIR3_1_SHIFT, 0x00000000},
217 { AUD_IIR3_0_SEL, 0x0000000d }, 218 {AUD_IIR3_0_SEL, 0x0000000d},
218 { AUD_IIR3_1_SEL, 0x0000000e }, 219 {AUD_IIR3_1_SEL, 0x0000000e},
219 { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, 220 {AUD_DEEMPH1_SRC_SEL, 0x00000014},
220 { AUD_DEEMPH1_SHIFT, 0x00000000 }, 221 {AUD_DEEMPH1_SHIFT, 0x00000000},
221 { AUD_DEEMPH1_G0, 0x00004000 }, 222 {AUD_DEEMPH1_G0, 0x00004000},
222 { AUD_DEEMPH1_A0, 0x00000000 }, 223 {AUD_DEEMPH1_A0, 0x00000000},
223 { AUD_DEEMPH1_B0, 0x00000000 }, 224 {AUD_DEEMPH1_B0, 0x00000000},
224 { AUD_DEEMPH1_A1, 0x00000000 }, 225 {AUD_DEEMPH1_A1, 0x00000000},
225 { AUD_DEEMPH1_B1, 0x00000000 }, 226 {AUD_DEEMPH1_B1, 0x00000000},
226 { AUD_OUT0_SEL, 0x0000003f }, 227 {AUD_OUT0_SEL, 0x0000003f},
227 { AUD_OUT1_SEL, 0x0000003f }, 228 {AUD_OUT1_SEL, 0x0000003f},
228 { AUD_DN1_AFC, 0x00000002 }, 229 {AUD_DN1_AFC, 0x00000002},
229 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 230 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
230 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 231 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
231 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 232 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
232 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 233 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
233 { AUD_IIR1_0_SEL, 0x0000001d }, 234 {AUD_IIR1_0_SEL, 0x0000001d},
234 { AUD_IIR1_2_SEL, 0x0000001e }, 235 {AUD_IIR1_2_SEL, 0x0000001e},
235 { AUD_IIR2_1_SEL, 0x00000002 }, 236 {AUD_IIR2_1_SEL, 0x00000002},
236 { AUD_IIR2_2_SEL, 0x00000004 }, 237 {AUD_IIR2_2_SEL, 0x00000004},
237 { AUD_IIR3_2_SEL, 0x0000000f }, 238 {AUD_IIR3_2_SEL, 0x0000000f},
238 { AUD_DCOC2_SHIFT, 0x00000001 }, 239 {AUD_DCOC2_SHIFT, 0x00000001},
239 { AUD_IIR3_2_SHIFT, 0x00000001 }, 240 {AUD_IIR3_2_SHIFT, 0x00000001},
240 { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, 241 {AUD_DEEMPH0_SRC_SEL, 0x00000014},
241 { AUD_CORDIC_SHIFT_1, 0x00000006 }, 242 {AUD_CORDIC_SHIFT_1, 0x00000006},
242 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, 243 {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
243 { AUD_DMD_RA_DDS, 0x00f696e6 }, 244 {AUD_DMD_RA_DDS, 0x00f696e6},
244 { AUD_IIR2_3_SEL, 0x00000025 }, 245 {AUD_IIR2_3_SEL, 0x00000025},
245 { AUD_IIR1_4_SEL, 0x00000021 }, 246 {AUD_IIR1_4_SEL, 0x00000021},
246 { AUD_DN1_FREQ, 0x0000c965 }, 247 {AUD_DN1_FREQ, 0x0000c965},
247 { AUD_DCOC_PASS_IN, 0x00000003 }, 248 {AUD_DCOC_PASS_IN, 0x00000003},
248 { AUD_DCOC_0_SRC, 0x0000001a }, 249 {AUD_DCOC_0_SRC, 0x0000001a},
249 { AUD_DCOC_1_SRC, 0x0000001b }, 250 {AUD_DCOC_1_SRC, 0x0000001b},
250 { AUD_DCOC1_SHIFT, 0x00000000 }, 251 {AUD_DCOC1_SHIFT, 0x00000000},
251 { AUD_RDSI_SEL, 0x00000009 }, 252 {AUD_RDSI_SEL, 0x00000009},
252 { AUD_RDSQ_SEL, 0x00000009 }, 253 {AUD_RDSQ_SEL, 0x00000009},
253 { AUD_RDSI_SHIFT, 0x00000000 }, 254 {AUD_RDSI_SHIFT, 0x00000000},
254 { AUD_RDSQ_SHIFT, 0x00000000 }, 255 {AUD_RDSQ_SHIFT, 0x00000000},
255 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 256 {AUD_POLYPH80SCALEFAC, 0x00000003},
256 { /* end of list */ }, 257 { /* end of list */ },
257 }; 258 };
258 259
259 mode |= EN_FMRADIO_EN_RDS; 260 mode |= EN_FMRADIO_EN_RDS;
260 261
261 if (sap) { 262 if (sap) {
262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 263 dprintk("%s SAP (status: unknown)\n", __FUNCTION__);
263 set_audio_start(core, SEL_SAP); 264 set_audio_start(core, SEL_SAP);
264 set_audio_registers(core, btsc_sap); 265 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode); 266 set_audio_finish(core, mode);
266 } else { 267 } else {
267 dprintk("%s (status: known-good)\n",__FUNCTION__); 268 dprintk("%s (status: known-good)\n", __FUNCTION__);
268 set_audio_start(core, SEL_BTSC); 269 set_audio_start(core, SEL_BTSC);
269 set_audio_registers(core, btsc); 270 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode); 271 set_audio_finish(core, mode);
271 } 272 }
272} 273}
273 274
274 275static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
276{ 276{
277 /* This is probably weird.. 277 static const struct rlist nicam_l[] = {
278 * Let's operate and find out. */ 278 {AUD_AFE_12DB_EN, 0x00000001},
279 279 {AUD_RATE_ADJ1, 0x00000060},
280 static const struct rlist nicam_l_mono[] = { 280 {AUD_RATE_ADJ2, 0x000000F9},
281 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 {AUD_RATE_ADJ3, 0x000001CC},
282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 {AUD_RATE_ADJ4, 0x000002B3},
283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 {AUD_RATE_ADJ5, 0x00000726},
284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
285 285 {AUD_DEEMPHDENOM2_R, 0x00000000},
286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 {AUD_ERRLOGPERIOD_R, 0x00000064},
287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
288 { AUD_QAM_MODE, 0x00 }, 288 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
290 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 {AUD_POLYPH80SCALEFAC, 0x00000003},
291 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 {AUD_DMD_RA_DDS, 0x00C00000},
292 292 {AUD_PLL_INT, 0x0000001E},
293 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 {AUD_PLL_DDS, 0x00000000},
294 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 {AUD_PLL_FRAC, 0x0000E542},
295 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 {AUD_START_TIMER, 0x00000000},
296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 {AUD_DEEMPHNUMER1_R, 0x000353DE},
297 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 {AUD_DEEMPHNUMER2_R, 0x000001B1},
298 { AUD_FM_MODE_ENABLE, 0x7 }, 298 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
299 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
300 { AUD_AFE_12DB_EN, 0x1 }, 300 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
301 { AAGC_GAIN, 0x0 }, 301 {AUD_QAM_MODE, 0x05},
302 { AAGC_HYST, 0x18 }, 302 {AUD_PHACC_FREQ_8MSB, 0x34},
303 { AAGC_DEF, 0x20 }, 303 {AUD_PHACC_FREQ_8LSB, 0x4C},
304 { AUD_DN0_FREQ, 0x0 }, 304 {AUD_DEEMPHGAIN_R, 0x00006680},
305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 {AUD_RATE_THRES_DMD, 0x000000C0},
306 { AUD_DCOC_0_SRC, 0x21 },
307 { AUD_IIR1_0_SEL, 0x0 },
308 { AUD_IIR1_0_SHIFT, 0x7 },
309 { AUD_IIR1_1_SEL, 0x2 },
310 { AUD_IIR1_1_SHIFT, 0x0 },
311 { AUD_DCOC_1_SRC, 0x3 },
312 { AUD_DCOC1_SHIFT, 0x0 },
313 { AUD_DCOC_PASS_IN, 0x0 },
314 { AUD_IIR1_2_SEL, 0x23 },
315 { AUD_IIR1_2_SHIFT, 0x0 },
316 { AUD_IIR1_3_SEL, 0x4 },
317 { AUD_IIR1_3_SHIFT, 0x7 },
318 { AUD_IIR1_4_SEL, 0x5 },
319 { AUD_IIR1_4_SHIFT, 0x7 },
320 { AUD_IIR3_0_SEL, 0x7 },
321 { AUD_IIR3_0_SHIFT, 0x0 },
322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
323 { AUD_DEEMPH0_SHIFT, 0x0 },
324 { AUD_DEEMPH0_G0, 0x7000 },
325 { AUD_DEEMPH0_A0, 0x0 },
326 { AUD_DEEMPH0_B0, 0x0 },
327 { AUD_DEEMPH0_A1, 0x0 },
328 { AUD_DEEMPH0_B1, 0x0 },
329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
330 { AUD_DEEMPH1_SHIFT, 0x0 },
331 { AUD_DEEMPH1_G0, 0x7000 },
332 { AUD_DEEMPH1_A0, 0x0 },
333 { AUD_DEEMPH1_B0, 0x0 },
334 { AUD_DEEMPH1_A1, 0x0 },
335 { AUD_DEEMPH1_B1, 0x0 },
336 { AUD_OUT0_SEL, 0x3F },
337 { AUD_OUT1_SEL, 0x3F },
338 { AUD_DMD_RA_DDS, 0x0F5C285 },
339 { AUD_PLL_INT, 0x1E },
340 { AUD_PLL_DDS, 0x0 },
341 { AUD_PLL_FRAC, 0x0E542 },
342
343 // setup QAM registers
344 { AUD_RATE_ADJ1, 0x00000100 },
345 { AUD_RATE_ADJ2, 0x00000200 },
346 { AUD_RATE_ADJ3, 0x00000300 },
347 { AUD_RATE_ADJ4, 0x00000400 },
348 { AUD_RATE_ADJ5, 0x00000500 },
349 { AUD_RATE_THRES_DMD, 0x000000C0 },
350 { /* end of list */ }, 306 { /* end of list */ },
351 }; 307 };
352 308
353 static const struct rlist nicam_l[] = { 309 static const struct rlist nicam_bgdki_common[] = {
354 // setup QAM registers 310 {AUD_AFE_12DB_EN, 0x00000001},
355 { AUD_RATE_ADJ1, 0x00000060 }, 311 {AUD_RATE_ADJ1, 0x00000010},
356 { AUD_RATE_ADJ2, 0x000000F9 }, 312 {AUD_RATE_ADJ2, 0x00000040},
357 { AUD_RATE_ADJ3, 0x000001CC }, 313 {AUD_RATE_ADJ3, 0x00000100},
358 { AUD_RATE_ADJ4, 0x000002B3 }, 314 {AUD_RATE_ADJ4, 0x00000400},
359 { AUD_RATE_ADJ5, 0x00000726 }, 315 {AUD_RATE_ADJ5, 0x00001000},
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 }, 316 //{ AUD_DMD_RA_DDS, 0x00c0d5ce },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 317 {AUD_ERRLOGPERIOD_R, 0x00000fff},
362 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 318 {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 319 {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 320 {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 321 {AUD_POLYPH80SCALEFAC, 0x00000003},
366 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 322 {AUD_DEEMPHGAIN_R, 0x000023c2},
367 { AUD_DMD_RA_DDS, 0x00C00000 }, 323 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
368 { AUD_PLL_INT, 0x0000001E }, 324 {AUD_DEEMPHNUMER2_R, 0x0003023e},
369 { AUD_PLL_DDS, 0x00000000 }, 325 {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
370 { AUD_PLL_FRAC, 0x0000E542 }, 326 {AUD_DEEMPHDENOM2_R, 0x00000000},
371 { AUD_START_TIMER, 0x00000000 }, 327 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
372 { AUD_DEEMPHNUMER1_R, 0x000353DE }, 328 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 }, 329 {AUD_QAM_MODE, 0x05},
374 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
375 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
376 { AUD_QAM_MODE, 0x05 },
377 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
378 { AUD_PHACC_FREQ_8MSB, 0x34 },
379 { AUD_PHACC_FREQ_8LSB, 0x4C },
380 { AUD_DEEMPHGAIN_R, 0x00006680 },
381 { AUD_RATE_THRES_DMD, 0x000000C0 },
382 { /* end of list */ }, 330 { /* end of list */ },
383 } ; 331 };
384 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
385
386 if (!stereo) {
387 /* AM Mono */
388 set_audio_start(core, SEL_A2);
389 set_audio_registers(core, nicam_l_mono);
390 set_audio_finish(core, EN_A2_FORCE_MONO1);
391 } else {
392 /* Nicam Stereo */
393 set_audio_start(core, SEL_NICAM);
394 set_audio_registers(core, nicam_l);
395 set_audio_finish(core, 0x1924); /* FIXME */
396 }
397}
398 332
399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 333 static const struct rlist nicam_i[] = {
400{ 334 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
401 static const struct rlist pal_i_fm_mono[] = { 335 {AUD_PHACC_FREQ_8MSB, 0x3a},
402 {AUD_ERRLOGPERIOD_R, 0x00000064}, 336 {AUD_PHACC_FREQ_8LSB, 0x93},
403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 337 { /* end of list */ },
404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
409 {AUD_QAM_MODE, 0x05},
410 {AUD_PHACC_FREQ_8MSB, 0x3a},
411 {AUD_PHACC_FREQ_8LSB, 0x93},
412 {AUD_DMD_RA_DDS, 0x002a4f2f},
413 {AUD_PLL_INT, 0x0000001e},
414 {AUD_PLL_DDS, 0x00000004},
415 {AUD_PLL_FRAC, 0x0000e542},
416 {AUD_RATE_ADJ1, 0x00000100},
417 {AUD_RATE_ADJ2, 0x00000200},
418 {AUD_RATE_ADJ3, 0x00000300},
419 {AUD_RATE_ADJ4, 0x00000400},
420 {AUD_RATE_ADJ5, 0x00000500},
421 {AUD_THR_FR, 0x00000000},
422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
423 {AUD_PILOT_BQD_1_K1, 0x00551340},
424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
426 {AUD_PILOT_BQD_1_K4, 0x00400000},
427 {AUD_PILOT_BQD_2_K0, 0x00040000},
428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
429 {AUD_PILOT_BQD_2_K2, 0x00400000},
430 {AUD_PILOT_BQD_2_K3, 0x00000000},
431 {AUD_PILOT_BQD_2_K4, 0x00000000},
432 {AUD_MODE_CHG_TIMER, 0x00000060},
433 {AUD_AFE_12DB_EN, 0x00000001},
434 {AAGC_HYST, 0x0000000a},
435 {AUD_CORDIC_SHIFT_0, 0x00000007},
436 {AUD_CORDIC_SHIFT_1, 0x00000007},
437 {AUD_C1_UP_THR, 0x00007000},
438 {AUD_C1_LO_THR, 0x00005400},
439 {AUD_C2_UP_THR, 0x00005400},
440 {AUD_C2_LO_THR, 0x00003000},
441 {AUD_DCOC_0_SRC, 0x0000001a},
442 {AUD_DCOC0_SHIFT, 0x00000000},
443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
445 {AUD_DCOC_PASS_IN, 0x00000003},
446 {AUD_IIR3_0_SEL, 0x00000021},
447 {AUD_DN2_AFC, 0x00000002},
448 {AUD_DCOC_1_SRC, 0x0000001b},
449 {AUD_DCOC1_SHIFT, 0x00000000},
450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
452 {AUD_IIR3_1_SEL, 0x00000023},
453 {AUD_DN0_FREQ, 0x000035a3},
454 {AUD_DN2_FREQ, 0x000029c7},
455 {AUD_CRDC0_SRC_SEL, 0x00000511},
456 {AUD_IIR1_0_SEL, 0x00000001},
457 {AUD_IIR1_1_SEL, 0x00000000},
458 {AUD_IIR3_2_SEL, 0x00000003},
459 {AUD_IIR3_2_SHIFT, 0x00000000},
460 {AUD_IIR3_0_SEL, 0x00000002},
461 {AUD_IIR2_0_SEL, 0x00000021},
462 {AUD_IIR2_0_SHIFT, 0x00000002},
463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
465 {AUD_POLYPH80SCALEFAC, 0x00000001},
466 {AUD_START_TIMER, 0x00000000},
467 { /* end of list */ },
468 };
469
470 static const struct rlist pal_i_nicam[] = {
471 { AUD_RATE_ADJ1, 0x00000010 },
472 { AUD_RATE_ADJ2, 0x00000040 },
473 { AUD_RATE_ADJ3, 0x00000100 },
474 { AUD_RATE_ADJ4, 0x00000400 },
475 { AUD_RATE_ADJ5, 0x00001000 },
476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
491 { AUD_QAM_MODE, 0x05 },
492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
493 { AUD_PHACC_FREQ_8MSB, 0x3a },
494 { AUD_PHACC_FREQ_8LSB, 0x93 },
495 { /* end of list */ },
496 }; 338 };
497 339
498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 340 static const struct rlist nicam_default[] = {
341 {AUD_PDF_DDS_CNST_BYTE0, 0x16},
342 {AUD_PHACC_FREQ_8MSB, 0x34},
343 {AUD_PHACC_FREQ_8LSB, 0x4c},
344 { /* end of list */ },
345 };
499 346
500 if (!stereo) { 347 set_audio_start(core,SEL_NICAM);
501 /* FM Mono */ 348 switch (core->tvaudio) {
502 set_audio_start(core, SEL_A2); 349 case WW_L:
503 set_audio_registers(core, pal_i_fm_mono); 350 dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__);
504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 351 set_audio_registers(core, nicam_l);
505 } else { 352 break;
506 /* Nicam Stereo */ 353 case WW_I:
507 set_audio_start(core, SEL_NICAM); 354 dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
508 set_audio_registers(core, pal_i_nicam); 355 set_audio_registers(core, nicam_bgdki_common);
509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 356 set_audio_registers(core, nicam_i);
510 } 357 break;
358 default:
359 dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
360 set_audio_registers(core, nicam_bgdki_common);
361 set_audio_registers(core, nicam_default);
362 break;
363 };
364
365 mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
366 set_audio_finish(core, mode);
511} 367}
512 368
513static void set_audio_standard_A2(struct cx88_core *core, u32 mode) 369static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
514{ 370{
515 static const struct rlist a2_common[] = { 371 static const struct rlist a2_bgdk_common[] = {
516 {AUD_ERRLOGPERIOD_R, 0x00000064}, 372 {AUD_ERRLOGPERIOD_R, 0x00000064},
517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 373 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 374 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 375 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
520 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 376 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
521 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 377 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
522 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 378 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
523 {AUD_QAM_MODE, 0x05}, 379 {AUD_QAM_MODE, 0x05},
524 {AUD_PHACC_FREQ_8MSB, 0x34}, 380 {AUD_PHACC_FREQ_8MSB, 0x34},
525 {AUD_PHACC_FREQ_8LSB, 0x4c}, 381 {AUD_PHACC_FREQ_8LSB, 0x4c},
526 {AUD_RATE_ADJ1, 0x00000100}, 382 {AUD_RATE_ADJ1, 0x00000100},
527 {AUD_RATE_ADJ2, 0x00000200}, 383 {AUD_RATE_ADJ2, 0x00000200},
528 {AUD_RATE_ADJ3, 0x00000300}, 384 {AUD_RATE_ADJ3, 0x00000300},
529 {AUD_RATE_ADJ4, 0x00000400}, 385 {AUD_RATE_ADJ4, 0x00000400},
530 {AUD_RATE_ADJ5, 0x00000500}, 386 {AUD_RATE_ADJ5, 0x00000500},
531 {AUD_THR_FR, 0x00000000}, 387 {AUD_THR_FR, 0x00000000},
532 {AAGC_HYST, 0x0000001a}, 388 {AAGC_HYST, 0x0000001a},
533 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 389 {AUD_PILOT_BQD_1_K0, 0x0000755b},
534 {AUD_PILOT_BQD_1_K1, 0x00551340}, 390 {AUD_PILOT_BQD_1_K1, 0x00551340},
535 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 391 {AUD_PILOT_BQD_1_K2, 0x006d30be},
536 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 392 {AUD_PILOT_BQD_1_K3, 0xffd394af},
537 {AUD_PILOT_BQD_1_K4, 0x00400000}, 393 {AUD_PILOT_BQD_1_K4, 0x00400000},
538 {AUD_PILOT_BQD_2_K0, 0x00040000}, 394 {AUD_PILOT_BQD_2_K0, 0x00040000},
539 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 395 {AUD_PILOT_BQD_2_K1, 0x002a4841},
540 {AUD_PILOT_BQD_2_K2, 0x00400000}, 396 {AUD_PILOT_BQD_2_K2, 0x00400000},
541 {AUD_PILOT_BQD_2_K3, 0x00000000}, 397 {AUD_PILOT_BQD_2_K3, 0x00000000},
542 {AUD_PILOT_BQD_2_K4, 0x00000000}, 398 {AUD_PILOT_BQD_2_K4, 0x00000000},
543 {AUD_MODE_CHG_TIMER, 0x00000040}, 399 {AUD_MODE_CHG_TIMER, 0x00000040},
544 {AUD_AFE_12DB_EN, 0x00000001}, 400 {AUD_AFE_12DB_EN, 0x00000001},
545 {AUD_CORDIC_SHIFT_0, 0x00000007}, 401 {AUD_CORDIC_SHIFT_0, 0x00000007},
546 {AUD_CORDIC_SHIFT_1, 0x00000007}, 402 {AUD_CORDIC_SHIFT_1, 0x00000007},
547 {AUD_DEEMPH0_G0, 0x00000380}, 403 {AUD_DEEMPH0_G0, 0x00000380},
548 {AUD_DEEMPH1_G0, 0x00000380}, 404 {AUD_DEEMPH1_G0, 0x00000380},
549 {AUD_DCOC_0_SRC, 0x0000001a}, 405 {AUD_DCOC_0_SRC, 0x0000001a},
550 {AUD_DCOC0_SHIFT, 0x00000000}, 406 {AUD_DCOC0_SHIFT, 0x00000000},
551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 407 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 408 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
553 {AUD_DCOC_PASS_IN, 0x00000003}, 409 {AUD_DCOC_PASS_IN, 0x00000003},
554 {AUD_IIR3_0_SEL, 0x00000021}, 410 {AUD_IIR3_0_SEL, 0x00000021},
555 {AUD_DN2_AFC, 0x00000002}, 411 {AUD_DN2_AFC, 0x00000002},
556 {AUD_DCOC_1_SRC, 0x0000001b}, 412 {AUD_DCOC_1_SRC, 0x0000001b},
557 {AUD_DCOC1_SHIFT, 0x00000000}, 413 {AUD_DCOC1_SHIFT, 0x00000000},
558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 414 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 415 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
560 {AUD_IIR3_1_SEL, 0x00000023}, 416 {AUD_IIR3_1_SEL, 0x00000023},
561 {AUD_RDSI_SEL, 0x00000017}, 417 {AUD_RDSI_SEL, 0x00000017},
562 {AUD_RDSI_SHIFT, 0x00000000}, 418 {AUD_RDSI_SHIFT, 0x00000000},
563 {AUD_RDSQ_SEL, 0x00000017}, 419 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000}, 420 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e}, 421 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000}, 422 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542}, 423 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001}, 424 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000}, 425 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ }, 426 { /* end of list */ },
571 }; 427 };
572 428
573 static const struct rlist a2_bg[] = { 429 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f}, 430 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000}, 431 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400}, 432 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400}, 433 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000}, 434 {AUD_C2_LO_THR, 0x00003000},
579 { /* end of list */ }, 435 { /* end of list */ },
580 }; 436 };
581 437
582 static const struct rlist a2_dk[] = { 438 static const struct rlist a2_dk[] = {
583 {AUD_DMD_RA_DDS, 0x002a4f2f}, 439 {AUD_DMD_RA_DDS, 0x002a4f2f},
584 {AUD_C1_UP_THR, 0x00007000}, 440 {AUD_C1_UP_THR, 0x00007000},
585 {AUD_C1_LO_THR, 0x00005400}, 441 {AUD_C1_LO_THR, 0x00005400},
586 {AUD_C2_UP_THR, 0x00005400}, 442 {AUD_C2_UP_THR, 0x00005400},
587 {AUD_C2_LO_THR, 0x00003000}, 443 {AUD_C2_LO_THR, 0x00003000},
588 {AUD_DN0_FREQ, 0x00003a1c}, 444 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0}, 445 {AUD_DN2_FREQ, 0x0000d2e0},
590 { /* end of list */ }, 446 { /* end of list */ },
591 }; 447 };
592/* unknown, probably NTSC-M */ 448
593 static const struct rlist a2_m[] = { 449 static const struct rlist a1_i[] = {
594 {AUD_DMD_RA_DDS, 0x002a0425}, 450 {AUD_ERRLOGPERIOD_R, 0x00000064},
595 {AUD_C1_UP_THR, 0x00003c00}, 451 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
596 {AUD_C1_LO_THR, 0x00003000}, 452 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
597 {AUD_C2_UP_THR, 0x00006000}, 453 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
598 {AUD_C2_LO_THR, 0x00003c00}, 454 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
599 {AUD_DEEMPH0_A0, 0x00007a80}, 455 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
600 {AUD_DEEMPH1_A0, 0x00007a80}, 456 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
601 {AUD_DEEMPH0_G0, 0x00001200}, 457 {AUD_QAM_MODE, 0x05},
602 {AUD_DEEMPH1_G0, 0x00001200}, 458 {AUD_PHACC_FREQ_8MSB, 0x3a},
603 {AUD_DN0_FREQ, 0x0000283b}, 459 {AUD_PHACC_FREQ_8LSB, 0x93},
604 {AUD_DN1_FREQ, 0x00003418}, 460 {AUD_DMD_RA_DDS, 0x002a4f2f},
605 {AUD_DN2_FREQ, 0x000029c7}, 461 {AUD_PLL_INT, 0x0000001e},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540}, 462 {AUD_PLL_DDS, 0x00000004},
463 {AUD_PLL_FRAC, 0x0000e542},
464 {AUD_RATE_ADJ1, 0x00000100},
465 {AUD_RATE_ADJ2, 0x00000200},
466 {AUD_RATE_ADJ3, 0x00000300},
467 {AUD_RATE_ADJ4, 0x00000400},
468 {AUD_RATE_ADJ5, 0x00000500},
469 {AUD_THR_FR, 0x00000000},
470 {AUD_PILOT_BQD_1_K0, 0x0000755b},
471 {AUD_PILOT_BQD_1_K1, 0x00551340},
472 {AUD_PILOT_BQD_1_K2, 0x006d30be},
473 {AUD_PILOT_BQD_1_K3, 0xffd394af},
474 {AUD_PILOT_BQD_1_K4, 0x00400000},
475 {AUD_PILOT_BQD_2_K0, 0x00040000},
476 {AUD_PILOT_BQD_2_K1, 0x002a4841},
477 {AUD_PILOT_BQD_2_K2, 0x00400000},
478 {AUD_PILOT_BQD_2_K3, 0x00000000},
479 {AUD_PILOT_BQD_2_K4, 0x00000000},
480 {AUD_MODE_CHG_TIMER, 0x00000060},
481 {AUD_AFE_12DB_EN, 0x00000001},
482 {AAGC_HYST, 0x0000000a},
483 {AUD_CORDIC_SHIFT_0, 0x00000007},
484 {AUD_CORDIC_SHIFT_1, 0x00000007},
485 {AUD_C1_UP_THR, 0x00007000},
486 {AUD_C1_LO_THR, 0x00005400},
487 {AUD_C2_UP_THR, 0x00005400},
488 {AUD_C2_LO_THR, 0x00003000},
489 {AUD_DCOC_0_SRC, 0x0000001a},
490 {AUD_DCOC0_SHIFT, 0x00000000},
491 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
492 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
493 {AUD_DCOC_PASS_IN, 0x00000003},
494 {AUD_IIR3_0_SEL, 0x00000021},
495 {AUD_DN2_AFC, 0x00000002},
496 {AUD_DCOC_1_SRC, 0x0000001b},
497 {AUD_DCOC1_SHIFT, 0x00000000},
498 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
499 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
500 {AUD_IIR3_1_SEL, 0x00000023},
501 {AUD_DN0_FREQ, 0x000035a3},
502 {AUD_DN2_FREQ, 0x000029c7},
503 {AUD_CRDC0_SRC_SEL, 0x00000511},
504 {AUD_IIR1_0_SEL, 0x00000001},
505 {AUD_IIR1_1_SEL, 0x00000000},
506 {AUD_IIR3_2_SEL, 0x00000003},
507 {AUD_IIR3_2_SHIFT, 0x00000000},
508 {AUD_IIR3_0_SEL, 0x00000002},
509 {AUD_IIR2_0_SEL, 0x00000021},
510 {AUD_IIR2_0_SHIFT, 0x00000002},
511 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
512 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
513 {AUD_POLYPH80SCALEFAC, 0x00000001},
514 {AUD_START_TIMER, 0x00000000},
607 { /* end of list */ }, 515 { /* end of list */ },
608 }; 516 };
609 517
610 static const struct rlist a2_deemph50[] = { 518 static const struct rlist am_l[] = {
611 {AUD_DEEMPH0_G0, 0x00000380}, 519 {AUD_ERRLOGPERIOD_R, 0x00000064},
612 {AUD_DEEMPH1_G0, 0x00000380}, 520 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
613 {AUD_DEEMPHGAIN_R, 0x000011e1}, 521 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, 522 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
615 {AUD_DEEMPHNUMER2_R, 0x0003023c}, 523 {AUD_PDF_DDS_CNST_BYTE2, 0x48},
616 { /* end of list */ }, 524 {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
525 {AUD_QAM_MODE, 0x00},
526 {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
527 {AUD_PHACC_FREQ_8MSB, 0x3a},
528 {AUD_PHACC_FREQ_8LSB, 0x4a},
529 {AUD_DEEMPHGAIN_R, 0x00006680},
530 {AUD_DEEMPHNUMER1_R, 0x000353DE},
531 {AUD_DEEMPHNUMER2_R, 0x000001B1},
532 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
533 {AUD_DEEMPHDENOM2_R, 0x00000000},
534 {AUD_FM_MODE_ENABLE, 0x00000007},
535 {AUD_POLYPH80SCALEFAC, 0x00000003},
536 {AUD_AFE_12DB_EN, 0x00000001},
537 {AAGC_GAIN, 0x00000000},
538 {AAGC_HYST, 0x00000018},
539 {AAGC_DEF, 0x00000020},
540 {AUD_DN0_FREQ, 0x00000000},
541 {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
542 {AUD_DCOC_0_SRC, 0x00000021},
543 {AUD_IIR1_0_SEL, 0x00000000},
544 {AUD_IIR1_0_SHIFT, 0x00000007},
545 {AUD_IIR1_1_SEL, 0x00000002},
546 {AUD_IIR1_1_SHIFT, 0x00000000},
547 {AUD_DCOC_1_SRC, 0x00000003},
548 {AUD_DCOC1_SHIFT, 0x00000000},
549 {AUD_DCOC_PASS_IN, 0x00000000},
550 {AUD_IIR1_2_SEL, 0x00000023},
551 {AUD_IIR1_2_SHIFT, 0x00000000},
552 {AUD_IIR1_3_SEL, 0x00000004},
553 {AUD_IIR1_3_SHIFT, 0x00000007},
554 {AUD_IIR1_4_SEL, 0x00000005},
555 {AUD_IIR1_4_SHIFT, 0x00000007},
556 {AUD_IIR3_0_SEL, 0x00000007},
557 {AUD_IIR3_0_SHIFT, 0x00000000},
558 {AUD_DEEMPH0_SRC_SEL, 0x00000011},
559 {AUD_DEEMPH0_SHIFT, 0x00000000},
560 {AUD_DEEMPH0_G0, 0x00007000},
561 {AUD_DEEMPH0_A0, 0x00000000},
562 {AUD_DEEMPH0_B0, 0x00000000},
563 {AUD_DEEMPH0_A1, 0x00000000},
564 {AUD_DEEMPH0_B1, 0x00000000},
565 {AUD_DEEMPH1_SRC_SEL, 0x00000011},
566 {AUD_DEEMPH1_SHIFT, 0x00000000},
567 {AUD_DEEMPH1_G0, 0x00007000},
568 {AUD_DEEMPH1_A0, 0x00000000},
569 {AUD_DEEMPH1_B0, 0x00000000},
570 {AUD_DEEMPH1_A1, 0x00000000},
571 {AUD_DEEMPH1_B1, 0x00000000},
572 {AUD_OUT0_SEL, 0x0000003F},
573 {AUD_OUT1_SEL, 0x0000003F},
574 {AUD_DMD_RA_DDS, 0x00F5C285},
575 {AUD_PLL_INT, 0x0000001E},
576 {AUD_PLL_DDS, 0x00000000},
577 {AUD_PLL_FRAC, 0x0000E542},
578 {AUD_RATE_ADJ1, 0x00000100},
579 {AUD_RATE_ADJ2, 0x00000200},
580 {AUD_RATE_ADJ3, 0x00000300},
581 {AUD_RATE_ADJ4, 0x00000400},
582 {AUD_RATE_ADJ5, 0x00000500},
583 {AUD_RATE_THRES_DMD, 0x000000C0},
584 { /* end of list */ },
617 }; 585 };
618 586
619 static const struct rlist a2_deemph75[] = { 587 static const struct rlist a2_deemph50[] = {
620 {AUD_DEEMPH0_G0, 0x00000480}, 588 {AUD_DEEMPH0_G0, 0x00000380},
621 {AUD_DEEMPH1_G0, 0x00000480}, 589 {AUD_DEEMPH1_G0, 0x00000380},
622 {AUD_DEEMPHGAIN_R, 0x00009000}, 590 {AUD_DEEMPHGAIN_R, 0x000011e1},
623 {AUD_DEEMPHNUMER1_R, 0x000353de}, 591 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1}, 592 {AUD_DEEMPHNUMER2_R, 0x0003023c},
625 { /* end of list */ }, 593 { /* end of list */ },
626 }; 594 };
627 595
628 set_audio_start(core, SEL_A2); 596 set_audio_start(core, SEL_A2);
629 set_audio_registers(core, a2_common);
630 switch (core->tvaudio) { 597 switch (core->tvaudio) {
631 case WW_A2_BG: 598 case WW_BG:
632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 599 dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__);
633 set_audio_registers(core, a2_bg); 600 set_audio_registers(core, a2_bgdk_common);
634 set_audio_registers(core, a2_deemph50); 601 set_audio_registers(core, a2_bg);
602 set_audio_registers(core, a2_deemph50);
635 break; 603 break;
636 case WW_A2_DK: 604 case WW_DK:
637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 605 dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__);
638 set_audio_registers(core, a2_dk); 606 set_audio_registers(core, a2_bgdk_common);
639 set_audio_registers(core, a2_deemph50); 607 set_audio_registers(core, a2_dk);
608 set_audio_registers(core, a2_deemph50);
640 break; 609 break;
641 case WW_A2_M: 610 case WW_I:
642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 611 dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__);
643 set_audio_registers(core, a2_m); 612 set_audio_registers(core, a1_i);
644 set_audio_registers(core, a2_deemph75); 613 set_audio_registers(core, a2_deemph50);
614 break;
615 case WW_L:
616 dprintk("%s AM-L (status: devel)\n", __FUNCTION__);
617 set_audio_registers(core, am_l);
618 break;
619 default:
620 dprintk("%s Warning: wrong value\n", __FUNCTION__);
621 return;
645 break; 622 break;
646 }; 623 };
647 624
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
656 633
657 { /* end of list */ }, 634 { /* end of list */ },
658 }; 635 };
659 dprintk("%s (status: unknown)\n",__FUNCTION__); 636 dprintk("%s (status: unknown)\n", __FUNCTION__);
660 637
661 set_audio_start(core, SEL_EIAJ); 638 set_audio_start(core, SEL_EIAJ);
662 set_audio_registers(core, eiaj); 639 set_audio_registers(core, eiaj);
663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO); 640 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
664} 641}
665 642
666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 643static void set_audio_standard_FM(struct cx88_core *core,
644 enum cx88_deemph_type deemph)
667{ 645{
668 static const struct rlist fm_deemph_50[] = { 646 static const struct rlist fm_deemph_50[] = {
669 { AUD_DEEMPH0_G0, 0x0C45 }, 647 {AUD_DEEMPH0_G0, 0x0C45},
670 { AUD_DEEMPH0_A0, 0x6262 }, 648 {AUD_DEEMPH0_A0, 0x6262},
671 { AUD_DEEMPH0_B0, 0x1C29 }, 649 {AUD_DEEMPH0_B0, 0x1C29},
672 { AUD_DEEMPH0_A1, 0x3FC66}, 650 {AUD_DEEMPH0_A1, 0x3FC66},
673 { AUD_DEEMPH0_B1, 0x399A }, 651 {AUD_DEEMPH0_B1, 0x399A},
674 652
675 { AUD_DEEMPH1_G0, 0x0D80 }, 653 {AUD_DEEMPH1_G0, 0x0D80},
676 { AUD_DEEMPH1_A0, 0x6262 }, 654 {AUD_DEEMPH1_A0, 0x6262},
677 { AUD_DEEMPH1_B0, 0x1C29 }, 655 {AUD_DEEMPH1_B0, 0x1C29},
678 { AUD_DEEMPH1_A1, 0x3FC66}, 656 {AUD_DEEMPH1_A1, 0x3FC66},
679 { AUD_DEEMPH1_B1, 0x399A}, 657 {AUD_DEEMPH1_B1, 0x399A},
680 658
681 { AUD_POLYPH80SCALEFAC, 0x0003}, 659 {AUD_POLYPH80SCALEFAC, 0x0003},
682 { /* end of list */ }, 660 { /* end of list */ },
683 }; 661 };
684 static const struct rlist fm_deemph_75[] = { 662 static const struct rlist fm_deemph_75[] = {
685 { AUD_DEEMPH0_G0, 0x091B }, 663 {AUD_DEEMPH0_G0, 0x091B},
686 { AUD_DEEMPH0_A0, 0x6B68 }, 664 {AUD_DEEMPH0_A0, 0x6B68},
687 { AUD_DEEMPH0_B0, 0x11EC }, 665 {AUD_DEEMPH0_B0, 0x11EC},
688 { AUD_DEEMPH0_A1, 0x3FC66}, 666 {AUD_DEEMPH0_A1, 0x3FC66},
689 { AUD_DEEMPH0_B1, 0x399A }, 667 {AUD_DEEMPH0_B1, 0x399A},
690 668
691 { AUD_DEEMPH1_G0, 0x0AA0 }, 669 {AUD_DEEMPH1_G0, 0x0AA0},
692 { AUD_DEEMPH1_A0, 0x6B68 }, 670 {AUD_DEEMPH1_A0, 0x6B68},
693 { AUD_DEEMPH1_B0, 0x11EC }, 671 {AUD_DEEMPH1_B0, 0x11EC},
694 { AUD_DEEMPH1_A1, 0x3FC66}, 672 {AUD_DEEMPH1_A1, 0x3FC66},
695 { AUD_DEEMPH1_B1, 0x399A}, 673 {AUD_DEEMPH1_B1, 0x399A},
696 674
697 { AUD_POLYPH80SCALEFAC, 0x0003}, 675 {AUD_POLYPH80SCALEFAC, 0x0003},
698 { /* end of list */ }, 676 { /* end of list */ },
699 }; 677 };
700 678
701 /* It is enough to leave default values? */ 679 /* It is enough to leave default values? */
702 static const struct rlist fm_no_deemph[] = { 680 static const struct rlist fm_no_deemph[] = {
703 681
704 { AUD_POLYPH80SCALEFAC, 0x0003}, 682 {AUD_POLYPH80SCALEFAC, 0x0003},
705 { /* end of list */ }, 683 { /* end of list */ },
706 }; 684 };
707 685
708 dprintk("%s (status: unknown)\n",__FUNCTION__); 686 dprintk("%s (status: unknown)\n", __FUNCTION__);
709 set_audio_start(core, SEL_FMRADIO); 687 set_audio_start(core, SEL_FMRADIO);
710 688
711 switch (deemph) 689 switch (deemph) {
712 { 690 case FM_NO_DEEMPH:
713 case FM_NO_DEEMPH: 691 set_audio_registers(core, fm_no_deemph);
714 set_audio_registers(core, fm_no_deemph); 692 break;
715 break;
716 693
717 case FM_DEEMPH_50: 694 case FM_DEEMPH_50:
718 set_audio_registers(core, fm_deemph_50); 695 set_audio_registers(core, fm_deemph_50);
719 break; 696 break;
720 697
721 case FM_DEEMPH_75: 698 case FM_DEEMPH_75:
722 set_audio_registers(core, fm_deemph_75); 699 set_audio_registers(core, fm_deemph_75);
723 break; 700 break;
724 } 701 }
725 702
726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); 703 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
728 705
729/* ----------------------------------------------------------- */ 706/* ----------------------------------------------------------- */
730 707
708int cx88_detect_nicam(struct cx88_core *core)
709{
710 int i, j = 0;
711
712 dprintk("start nicam autodetect.\n");
713
714 for (i = 0; i < 6; i++) {
715 /* if bit1=1 then nicam is detected */
716 j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
717
718 /* 3x detected: absolutly sure now */
719 if (j == 3) {
720 dprintk("nicam is detected.\n");
721 return 1;
722 }
723
724 /* wait a little bit for next reading status */
725 msleep(10);
726 }
727
728 dprintk("nicam is not detected.\n");
729 return 0;
730}
731
731void cx88_set_tvaudio(struct cx88_core *core) 732void cx88_set_tvaudio(struct cx88_core *core)
732{ 733{
733 switch (core->tvaudio) { 734 switch (core->tvaudio) {
734 case WW_BTSC: 735 case WW_BTSC:
735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); 736 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
736 break; 737 break;
737 case WW_NICAM_BGDKL: 738 case WW_BG:
738 set_audio_standard_NICAM_L(core,0); 739 case WW_DK:
739 break; 740 case WW_I:
740 case WW_NICAM_I: 741 case WW_L:
741 set_audio_standard_PAL_I(core,0); 742 /* prepare all dsp registers */
742 break; 743 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
743 case WW_A2_BG: 744
744 case WW_A2_DK: 745 /* set nicam mode - otherwise
745 case WW_A2_M: 746 AUD_NICAM_STATUS2 contains wrong values */
746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 747 set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
748 if (0 == cx88_detect_nicam(core)) {
749 /* fall back to fm / am mono */
750 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
751 core->use_nicam = 0;
752 } else {
753 core->use_nicam = 1;
754 }
747 break; 755 break;
748 case WW_EIAJ: 756 case WW_EIAJ:
749 set_audio_standard_EIAJ(core); 757 set_audio_standard_EIAJ(core);
750 break; 758 break;
751 case WW_FM: 759 case WW_FM:
752 set_audio_standard_FM(core,FM_NO_DEEMPH); 760 set_audio_standard_FM(core, FM_NO_DEEMPH);
753 break;
754 case WW_SYSTEM_L_AM:
755 set_audio_standard_NICAM_L(core, 1);
756 break; 761 break;
757 case WW_NONE: 762 case WW_NONE:
758 default: 763 default:
759 printk("%s/0: unknown tv audio mode [%d]\n", 764 printk("%s/0: unknown tv audio mode [%d]\n",
760 core->name, core->tvaudio); 765 core->name, core->tvaudio);
761 break; 766 break;
762 } 767 }
763 return; 768 return;
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core)
766void cx88_newstation(struct cx88_core *core) 771void cx88_newstation(struct cx88_core *core)
767{ 772{
768 core->audiomode_manual = UNSET; 773 core->audiomode_manual = UNSET;
769
770 switch (core->tvaudio) {
771 case WW_SYSTEM_L_AM:
772 /* try nicam ... */
773 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
774 set_audio_standard_NICAM_L(core, 1);
775 break;
776 }
777} 774}
778 775
779void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 776void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
780{ 777{
781 static char *m[] = {"stereo", "dual mono", "mono", "sap"}; 778 static char *m[] = { "stereo", "dual mono", "mono", "sap" };
782 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; 779 static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
783 u32 reg,mode,pilot; 780 u32 reg, mode, pilot;
784 781
785 reg = cx_read(AUD_STATUS); 782 reg = cx_read(AUD_STATUS);
786 mode = reg & 0x03; 783 mode = reg & 0x03;
787 pilot = (reg >> 2) & 0x03; 784 pilot = (reg >> 2) & 0x03;
788 785
789 if (core->astat != reg) 786 if (core->astat != reg)
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
800 797
801# if 0 798# if 0
802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 799 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 800 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
804 t->rxsubchans = V4L2_TUNER_SUB_MONO; 801 t->rxsubchans = V4L2_TUNER_SUB_MONO;
805 t->audmode = V4L2_TUNER_MODE_MONO; 802 t->audmode = V4L2_TUNER_MODE_MONO;
806 803
807 switch (core->tvaudio) { 804 switch (core->tvaudio) {
808 case WW_BTSC: 805 case WW_BTSC:
809 t->capability = V4L2_TUNER_CAP_STEREO | 806 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP;
810 V4L2_TUNER_CAP_SAP;
811 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 807 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
812 if (1 == pilot) { 808 if (1 == pilot) {
813 /* SAP */ 809 /* SAP */
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
819 case WW_A2_M: 815 case WW_A2_M:
820 if (1 == pilot) { 816 if (1 == pilot) {
821 /* stereo */ 817 /* stereo */
822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 818 t->rxsubchans =
819 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
823 if (0 == mode) 820 if (0 == mode)
824 t->audmode = V4L2_TUNER_MODE_STEREO; 821 t->audmode = V4L2_TUNER_MODE_STEREO;
825 } 822 }
826 if (2 == pilot) { 823 if (2 == pilot) {
827 /* dual language -- FIXME */ 824 /* dual language -- FIXME */
828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 825 t->rxsubchans =
826 V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
829 t->audmode = V4L2_TUNER_MODE_LANG1; 827 t->audmode = V4L2_TUNER_MODE_LANG1;
830 } 828 }
831 break; 829 break;
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
840 t->audmode = V4L2_TUNER_MODE_STEREO; 838 t->audmode = V4L2_TUNER_MODE_STEREO;
841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 839 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
842 } 840 }
843 break ; 841 break;
844 default: 842 default:
845 /* nothing */ 843 /* nothing */
846 break; 844 break;
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
851 849
852void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) 850void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
853{ 851{
854 u32 ctl = UNSET; 852 u32 ctl = UNSET;
855 u32 mask = UNSET; 853 u32 mask = UNSET;
856 854
857 if (manual) { 855 if (manual) {
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
879 break; 877 break;
880 } 878 }
881 break; 879 break;
882 case WW_A2_BG: 880 case WW_BG:
883 case WW_A2_DK: 881 case WW_DK:
884 case WW_A2_M: 882 case WW_I:
885 switch (mode) { 883 case WW_L:
886 case V4L2_TUNER_MODE_MONO: 884 if (1 == core->use_nicam) {
887 case V4L2_TUNER_MODE_LANG1: 885 switch (mode) {
888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 886 case V4L2_TUNER_MODE_MONO:
889 break; 887 case V4L2_TUNER_MODE_LANG1:
890 case V4L2_TUNER_MODE_LANG2: 888 set_audio_standard_NICAM(core,
891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2); 889 EN_NICAM_FORCE_MONO1);
892 break; 890 break;
893 case V4L2_TUNER_MODE_STEREO: 891 case V4L2_TUNER_MODE_LANG2:
894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO); 892 set_audio_standard_NICAM(core,
895 break; 893 EN_NICAM_FORCE_MONO2);
896 } 894 break;
897 break; 895 case V4L2_TUNER_MODE_STEREO:
898 case WW_NICAM_BGDKL: 896 set_audio_standard_NICAM(core,
899 switch (mode) { 897 EN_NICAM_FORCE_STEREO);
900 case V4L2_TUNER_MODE_MONO: 898 break;
901 ctl = EN_NICAM_FORCE_MONO1; 899 }
902 mask = 0x3f; 900 } else {
903 break; 901 if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
904 case V4L2_TUNER_MODE_LANG1: 902 /* fall back to fm / am mono */
905 ctl = EN_NICAM_AUTO_MONO2; 903 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
906 mask = 0x3f; 904 } else {
907 break; 905 /* TODO: Add A2 autodection */
908 case V4L2_TUNER_MODE_STEREO: 906 switch (mode) {
909 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR; 907 case V4L2_TUNER_MODE_MONO:
910 mask = 0x93f; 908 case V4L2_TUNER_MODE_LANG1:
911 break; 909 set_audio_standard_A2(core,
912 } 910 EN_A2_FORCE_MONO1);
913 break; 911 break;
914 case WW_SYSTEM_L_AM: 912 case V4L2_TUNER_MODE_LANG2:
915 switch (mode) { 913 set_audio_standard_A2(core,
916 case V4L2_TUNER_MODE_MONO: 914 EN_A2_FORCE_MONO2);
917 case V4L2_TUNER_MODE_LANG1: /* FIXME */ 915 break;
918 set_audio_standard_NICAM_L(core, 0); 916 case V4L2_TUNER_MODE_STEREO:
919 break; 917 set_audio_standard_A2(core,
920 case V4L2_TUNER_MODE_STEREO: 918 EN_A2_FORCE_STEREO);
921 set_audio_standard_NICAM_L(core, 1); 919 break;
922 break; 920 }
923 } 921 }
924 break;
925 case WW_NICAM_I:
926 switch (mode) {
927 case V4L2_TUNER_MODE_MONO:
928 case V4L2_TUNER_MODE_LANG1:
929 set_audio_standard_PAL_I(core, 0);
930 break;
931 case V4L2_TUNER_MODE_STEREO:
932 set_audio_standard_PAL_I(core, 1);
933 break;
934 } 922 }
935 break; 923 break;
936 case WW_FM: 924 case WW_FM:
937 switch (mode) { 925 switch (mode) {
938 case V4L2_TUNER_MODE_MONO: 926 case V4L2_TUNER_MODE_MONO:
939 ctl = EN_FMRADIO_FORCE_MONO; 927 ctl = EN_FMRADIO_FORCE_MONO;
940 mask = 0x3f; 928 mask = 0x3f;
941 break; 929 break;
942 case V4L2_TUNER_MODE_STEREO: 930 case V4L2_TUNER_MODE_STEREO:
943 ctl = EN_FMRADIO_AUTO_STEREO; 931 ctl = EN_FMRADIO_AUTO_STEREO;
944 mask = 0x3f; 932 mask = 0x3f;
945 break; 933 break;
946 } 934 }
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data)
970 break; 958 break;
971 959
972 /* just monitor the audio status for now ... */ 960 /* just monitor the audio status for now ... */
973 memset(&t,0,sizeof(t)); 961 memset(&t, 0, sizeof(t));
974 cx88_get_stereo(core,&t); 962 cx88_get_stereo(core, &t);
975 963
976 if (UNSET != core->audiomode_manual) 964 if (UNSET != core->audiomode_manual)
977 /* manually set, don't do anything. */ 965 /* manually set, don't do anything. */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 3dbc074fb515..24a48f8a48c1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -34,6 +34,9 @@
34 34
35#include "cx88.h" 35#include "cx88.h"
36 36
37/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h>
39
37MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = {
100 .id = V4L2_STD_PAL_I, 103 .id = V4L2_STD_PAL_I,
101 .cxiformat = VideoFormatPAL, 104 .cxiformat = VideoFormatPAL,
102 .cxoformat = 0x181f0008, 105 .cxoformat = 0x181f0008,
103 },{ 106 },{
104 .name = "PAL-M", 107 .name = "PAL-M",
105 .id = V4L2_STD_PAL_M, 108 .id = V4L2_STD_PAL_M,
106 .cxiformat = VideoFormatPALM, 109 .cxiformat = VideoFormatPALM,
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
470 struct list_head *item; 473 struct list_head *item;
471 474
472 if (!list_empty(&q->active)) { 475 if (!list_empty(&q->active)) {
473 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 476 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
474 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 477 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
475 buf, buf->vb.i); 478 buf, buf->vb.i);
476 start_video_dma(dev, q, buf); 479 start_video_dma(dev, q, buf);
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
486 for (;;) { 489 for (;;) {
487 if (list_empty(&q->queued)) 490 if (list_empty(&q->queued))
488 return 0; 491 return 0;
489 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); 492 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
490 if (NULL == prev) { 493 if (NULL == prev) {
491 list_del(&buf->vb.queue); 494 list_del(&buf->vb.queue);
492 list_add_tail(&buf->vb.queue,&q->active); 495 list_add_tail(&buf->vb.queue,&q->active);
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file)
783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 786 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
784 } 787 }
785 788
786 return 0; 789 return 0;
787} 790}
788 791
789static ssize_t 792static ssize_t
790video_read(struct file *file, char *data, size_t count, loff_t *ppos) 793video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
791{ 794{
792 struct cx8800_fh *fh = file->private_data; 795 struct cx8800_fh *fh = file->private_data;
793 796
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
922{ 925{
923 /* struct cx88_core *core = dev->core; */ 926 /* struct cx88_core *core = dev->core; */
924 struct cx88_ctrl *c = NULL; 927 struct cx88_ctrl *c = NULL;
925 u32 v_sat_value; 928 u32 v_sat_value;
926 u32 value; 929 u32 value;
927 int i; 930 int i;
928 931
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1187 struct v4l2_format *f = arg; 1190 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f); 1191 return cx8800_try_fmt(dev,fh,f);
1189 } 1192 }
1190 1193#ifdef HAVE_V4L1
1191 /* --- streaming capture ------------------------------------- */ 1194 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF: 1195 case VIDIOCGMBUF:
1193 { 1196 {
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1213 } 1216 }
1214 return 0; 1217 return 0;
1215 } 1218 }
1219#endif
1216 case VIDIOC_REQBUFS: 1220 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg); 1221 return videobuf_reqbufs(get_queue(fh), arg);
1218 1222
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1244 res_free(dev,fh,res); 1248 res_free(dev,fh,res);
1245 return 0; 1249 return 0;
1246 } 1250 }
1247
1248 default: 1251 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); 1252 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 } 1253 }
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1252} 1255}
1253 1256
1254int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, 1257int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1255 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) 1258 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
1256{ 1259{
1257 int err; 1260 int err;
1258 1261
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1259 if (video_debug > 1) 1263 if (video_debug > 1)
1260 cx88_print_ioctl(core->name,cmd); 1264 cx88_print_ioctl(core->name,cmd);
1261 printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
1262 cx88_print_ioctl(core->name,cmd);
1263 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1264 1265
1265 switch (cmd) { 1266 switch (cmd) {
1266 /* ---------- tv norms ---------- */ 1267 /* ---------- tv norms ---------- */
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1401 1402
1402 cx88_get_stereo(core ,t); 1403 cx88_get_stereo(core ,t);
1403 reg = cx_read(MO_DEVICE_STATUS); 1404 reg = cx_read(MO_DEVICE_STATUS);
1404 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; 1405 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1405 return 0; 1406 return 0;
1406 } 1407 }
1407 case VIDIOC_S_TUNER: 1408 case VIDIOC_S_TUNER:
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1488 struct v4l2_capability *cap = arg; 1489 struct v4l2_capability *cap = arg;
1489 1490
1490 memset(cap,0,sizeof(*cap)); 1491 memset(cap,0,sizeof(*cap));
1491 strcpy(cap->driver, "cx8800"); 1492 strcpy(cap->driver, "cx8800");
1492 strlcpy(cap->card, cx88_boards[core->board].name, 1493 strlcpy(cap->card, cx88_boards[core->board].name,
1493 sizeof(cap->card)); 1494 sizeof(cap->card));
1494 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1495 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1505 1506
1506 memset(t,0,sizeof(*t)); 1507 memset(t,0,sizeof(*t));
1507 strcpy(t->name, "Radio"); 1508 strcpy(t->name, "Radio");
1509 t->type = V4L2_TUNER_RADIO;
1508 1510
1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); 1511 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1510 return 0; 1512 return 0;
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1539 *id = 0; 1541 *id = 0;
1540 return 0; 1542 return 0;
1541 } 1543 }
1544#ifdef HAVE_V4L1
1542 case VIDIOCSTUNER: 1545 case VIDIOCSTUNER:
1543 { 1546 {
1544 struct video_tuner *v = arg; 1547 struct video_tuner *v = arg;
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v); 1552 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1550 return 0; 1553 return 0;
1551 } 1554 }
1555#endif
1552 case VIDIOC_S_TUNER: 1556 case VIDIOC_S_TUNER:
1553 { 1557 {
1554 struct v4l2_tuner *t = arg; 1558 struct v4l2_tuner *t = arg;
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1829 1833
1830 /* print pci info */ 1834 /* print pci info */
1831 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1832 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1833 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1834 "latency: %d, mmio: 0x%lx\n", core->name, 1838 "latency: %d, mmio: 0x%lx\n", core->name,
1835 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 1839 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1836 dev->pci_lat,pci_resource_start(pci_dev,0)); 1840 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -1946,7 +1950,7 @@ fail_free:
1946 1950
1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1951static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1948{ 1952{
1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1953 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core; 1954 struct cx88_core *core = dev->core;
1951 1955
1952 /* stop thread */ 1956 /* stop thread */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f48dd4353568..b19d3a9e2298 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -22,7 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <linux/videodev.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27 27
28#include <media/tuner.h> 28#include <media/tuner.h>
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[];
148#define CX88_BOARD_PIXELVIEW 3 148#define CX88_BOARD_PIXELVIEW 3
149#define CX88_BOARD_ATI_WONDER_PRO 4 149#define CX88_BOARD_ATI_WONDER_PRO 4
150#define CX88_BOARD_WINFAST2000XP_EXPERT 5 150#define CX88_BOARD_WINFAST2000XP_EXPERT 5
151#define CX88_BOARD_AVERTV_303 6 151#define CX88_BOARD_AVERTV_STUDIO_303 6
152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
153#define CX88_BOARD_WINFAST_DV2000 8 153#define CX88_BOARD_WINFAST_DV2000 8
154#define CX88_BOARD_LEADTEK_PVR2000 9 154#define CX88_BOARD_LEADTEK_PVR2000 9
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[];
174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29 174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
177#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
178#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36
177 182
178enum cx88_itype { 183enum cx88_itype {
179 CX88_VMUX_COMPOSITE1 = 1, 184 CX88_VMUX_COMPOSITE1 = 1,
@@ -203,8 +208,8 @@ struct cx88_board {
203 int tda9887_conf; 208 int tda9887_conf;
204 struct cx88_input input[MAX_CX88_INPUT]; 209 struct cx88_input input[MAX_CX88_INPUT];
205 struct cx88_input radio; 210 struct cx88_input radio;
206 int blackbird:1; 211 unsigned int blackbird:1;
207 int dvb:1; 212 unsigned int dvb:1;
208}; 213};
209 214
210struct cx88_subid { 215struct cx88_subid {
@@ -255,8 +260,8 @@ struct cx88_core {
255 /* pci stuff */ 260 /* pci stuff */
256 int pci_bus; 261 int pci_bus;
257 int pci_slot; 262 int pci_slot;
258 u32 __iomem *lmmio; 263 u32 __iomem *lmmio;
259 u8 __iomem *bmmio; 264 u8 __iomem *bmmio;
260 u32 shadow[SHADOW_MAX]; 265 u32 shadow[SHADOW_MAX];
261 int pci_irqmask; 266 int pci_irqmask;
262 267
@@ -287,6 +292,7 @@ struct cx88_core {
287 u32 audiomode_current; 292 u32 audiomode_current;
288 u32 input; 293 u32 input;
289 u32 astat; 294 u32 astat;
295 u32 use_nicam;
290 296
291 /* IR remote control state */ 297 /* IR remote control state */
292 struct cx88_IR *ir; 298 struct cx88_IR *ir;
@@ -370,6 +376,14 @@ struct cx8802_suspend_state {
370 int disabled; 376 int disabled;
371}; 377};
372 378
379/* TODO: move this to struct v4l2_mpeg_compression ? */
380struct blackbird_dnr {
381 u32 mode;
382 u32 type;
383 u32 spatial;
384 u32 temporal;
385};
386
373struct cx8802_dev { 387struct cx8802_dev {
374 struct cx88_core *core; 388 struct cx88_core *core;
375 spinlock_t slock; 389 spinlock_t slock;
@@ -400,6 +414,10 @@ struct cx8802_dev {
400 414
401 /* for switching modulation types */ 415 /* for switching modulation types */
402 unsigned char ts_gen_cntrl; 416 unsigned char ts_gen_cntrl;
417
418 /* mpeg params */
419 struct v4l2_mpeg_compression params;
420 struct blackbird_dnr dnr_params;
403}; 421};
404 422
405/* ----------------------------------------------------------- */ 423/* ----------------------------------------------------------- */
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core);
514 532
515#define WW_NONE 1 533#define WW_NONE 1
516#define WW_BTSC 2 534#define WW_BTSC 2
517#define WW_NICAM_I 3 535#define WW_BG 3
518#define WW_NICAM_BGDKL 4 536#define WW_DK 4
519#define WW_A1 5 537#define WW_I 5
520#define WW_A2_BG 6 538#define WW_L 6
521#define WW_A2_DK 7 539#define WW_EIAJ 7
522#define WW_A2_M 8 540#define WW_I2SPT 8
523#define WW_EIAJ 9 541#define WW_FM 9
524#define WW_SYSTEM_L_AM 10
525#define WW_I2SPT 11
526#define WW_FM 12
527 542
528void cx88_set_tvaudio(struct cx88_core *core); 543void cx88_set_tvaudio(struct cx88_core *core);
529void cx88_newstation(struct cx88_core *core); 544void cx88_newstation(struct cx88_core *core);
530void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); 545void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
531void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); 546void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
532int cx88_audio_thread(void *data); 547int cx88_audio_thread(void *data);
548int cx88_detect_nicam(struct cx88_core *core);
533 549
534/* ----------------------------------------------------------- */ 550/* ----------------------------------------------------------- */
535/* cx88-input.c */ 551/* cx88-input.c */
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core);
541/* ----------------------------------------------------------- */ 557/* ----------------------------------------------------------- */
542/* cx88-mpeg.c */ 558/* cx88-mpeg.c */
543 559
544int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); 560int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
561 enum v4l2_field field);
545void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); 562void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
546void cx8802_cancel_buffers(struct cx8802_dev *dev); 563void cx8802_cancel_buffers(struct cx8802_dev *dev);
547 564
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, 579extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg); 580 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); 581extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
582void blackbird_set_params(struct cx8802_dev *dev,
583 struct v4l2_mpeg_compression *params);
584void blackbird_set_dnr_params(struct cx8802_dev *dev,
585 struct blackbird_dnr* dnr_params);
565 586
566/* 587/*
567 * Local variables: 588 * Local variables:
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
new file mode 100644
index 000000000000..885fd0170086
--- /dev/null
+++ b/drivers/media/video/em28xx/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_EM28XX
2 tristate "Empia EM2800/2820/2840 USB video capture support"
3 depends on VIDEO_DEV && USB && I2C
4 select VIDEO_BUF
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 ---help---
9 This is a video4linux driver for Empia 28xx based TV cards.
10
11 To compile this driver as a module, choose M here: the
12 module will be called em28xx
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
new file mode 100644
index 000000000000..da457a05b0dd
--- /dev/null
+++ b/drivers/media/video/em28xx/Makefile
@@ -0,0 +1,6 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o
3
4obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
5
6EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
new file mode 100644
index 000000000000..57779e63f35d
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -0,0 +1,292 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/usb.h>
30#include <media/tuner.h>
31#include <media/audiochip.h>
32#include <media/tveeprom.h>
33#include "msp3400.h"
34
35#include "em28xx.h"
36
37struct em28xx_board em28xx_boards[] = {
38 [EM2800_BOARD_UNKNOWN] = {
39 .name = "Unknown EM2800 video grabber",
40 .is_em2800 = 1,
41 .vchannels = 2,
42 .norm = VIDEO_MODE_PAL,
43 .tda9887_conf = TDA9887_PRESENT,
44 .has_tuner = 1,
45 .decoder = EM28XX_SAA7113,
46 .input = {{
47 .type = EM28XX_VMUX_COMPOSITE1,
48 .vmux = 0,
49 .amux = 1,
50 },{
51 .type = EM28XX_VMUX_SVIDEO,
52 .vmux = 9,
53 .amux = 1,
54 }},
55 },
56 [EM2820_BOARD_UNKNOWN] = {
57 .name = "Unknown EM2820/2840 video grabber",
58 .is_em2800 = 0,
59 .vchannels = 2,
60 .norm = VIDEO_MODE_PAL,
61 .tda9887_conf = TDA9887_PRESENT,
62 .has_tuner = 1,
63 .decoder = EM28XX_SAA7113,
64 .input = {{
65 .type = EM28XX_VMUX_COMPOSITE1,
66 .vmux = 0,
67 .amux = 1,
68 },{
69 .type = EM28XX_VMUX_SVIDEO,
70 .vmux = 9,
71 .amux = 1,
72 }},
73 },
74 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
75 .name = "Terratec Cinergy 250 USB",
76 .vchannels = 3,
77 .norm = VIDEO_MODE_PAL,
78 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
79 .tda9887_conf = TDA9887_PRESENT,
80 .has_tuner = 1,
81 .decoder = EM28XX_SAA7113,
82 .input = {{
83 .type = EM28XX_VMUX_TELEVISION,
84 .vmux = 2,
85 .amux = 0,
86 },{
87 .type = EM28XX_VMUX_COMPOSITE1,
88 .vmux = 0,
89 .amux = 1,
90 },{
91 .type = EM28XX_VMUX_SVIDEO,
92 .vmux = 9,
93 .amux = 1,
94 }},
95 },
96 [EM2820_BOARD_PINNACLE_USB_2] = {
97 .name = "Pinnacle PCTV USB 2",
98 .vchannels = 3,
99 .norm = VIDEO_MODE_PAL,
100 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
101 .tda9887_conf = TDA9887_PRESENT,
102 .has_tuner = 1,
103 .decoder = EM28XX_SAA7113,
104 .input = {{
105 .type = EM28XX_VMUX_TELEVISION,
106 .vmux = 2,
107 .amux = 0,
108 },{
109 .type = EM28XX_VMUX_COMPOSITE1,
110 .vmux = 0,
111 .amux = 1,
112 },{
113 .type = EM28XX_VMUX_SVIDEO,
114 .vmux = 9,
115 .amux = 1,
116 }},
117 },
118 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
119 .name = "Hauppauge WinTV USB 2",
120 .vchannels = 3,
121 .norm = VIDEO_MODE_NTSC,
122 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
123 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
124 .has_tuner = 1,
125 .decoder = EM28XX_TVP5150,
126 .has_msp34xx = 1,
127 /*FIXME: S-Video not tested */
128 .input = {{
129 .type = EM28XX_VMUX_TELEVISION,
130 .vmux = 0,
131 .amux = 6,
132 },{
133 .type = EM28XX_VMUX_SVIDEO,
134 .vmux = 2,
135 .amux = 1,
136 }},
137 },
138 [EM2820_BOARD_MSI_VOX_USB_2] = {
139 .name = "MSI VOX USB 2.0",
140 .vchannels = 3,
141 .norm = VIDEO_MODE_PAL,
142 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
143 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
144 .has_tuner = 1,
145 .decoder = EM28XX_SAA7114,
146 .input = {{
147 .type = EM28XX_VMUX_TELEVISION,
148 .vmux = 4,
149 .amux = 0,
150 },{
151 .type = EM28XX_VMUX_COMPOSITE1,
152 .vmux = 0,
153 .amux = 1,
154 },{
155 .type = EM28XX_VMUX_SVIDEO,
156 .vmux = 9,
157 .amux = 1,
158 }},
159 },
160 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
161 .name = "Terratec Cinergy 200 USB",
162 .is_em2800 = 1,
163 .vchannels = 3,
164 .norm = VIDEO_MODE_PAL,
165 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
166 .tda9887_conf = TDA9887_PRESENT,
167 .has_tuner = 1,
168 .decoder = EM28XX_SAA7113,
169 .input = {{
170 .type = EM28XX_VMUX_TELEVISION,
171 .vmux = 2,
172 .amux = 0,
173 },{
174 .type = EM28XX_VMUX_COMPOSITE1,
175 .vmux = 0,
176 .amux = 1,
177 },{
178 .type = EM28XX_VMUX_SVIDEO,
179 .vmux = 9,
180 .amux = 1,
181 }},
182 },
183 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
184 .name = "Leadtek Winfast USB II",
185 .is_em2800 = 1,
186 .vchannels = 3,
187 .norm = VIDEO_MODE_PAL,
188 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
189 .tda9887_conf = TDA9887_PRESENT,
190 .has_tuner = 1,
191 .decoder = EM28XX_SAA7113,
192 .input = {{
193 .type = EM28XX_VMUX_TELEVISION,
194 .vmux = 2,
195 .amux = 0,
196 },{
197 .type = EM28XX_VMUX_COMPOSITE1,
198 .vmux = 0,
199 .amux = 1,
200 },{
201 .type = EM28XX_VMUX_SVIDEO,
202 .vmux = 9,
203 .amux = 1,
204 }},
205 },
206 [EM2800_BOARD_KWORLD_USB2800] = {
207 .name = "Kworld USB2800",
208 .is_em2800 = 1,
209 .vchannels = 3,
210 .norm = VIDEO_MODE_PAL,
211 .tuner_type = TUNER_PHILIPS_ATSC,
212 .tda9887_conf = TDA9887_PRESENT,
213 .has_tuner = 1,
214 .decoder = EM28XX_SAA7113,
215 .input = {{
216 .type = EM28XX_VMUX_TELEVISION,
217 .vmux = 2,
218 .amux = 0,
219 },{
220 .type = EM28XX_VMUX_COMPOSITE1,
221 .vmux = 0,
222 .amux = 1,
223 },{
224 .type = EM28XX_VMUX_SVIDEO,
225 .vmux = 9,
226 .amux = 1,
227 }},
228 },
229 [EM2820_BOARD_PINNACLE_DVC_90] = {
230 .name = "Pinnacle Dazzle DVC 90",
231 .vchannels = 3,
232 .norm = VIDEO_MODE_PAL,
233 .has_tuner = 0,
234 .decoder = EM28XX_SAA7113,
235 .input = {{
236 .type = EM28XX_VMUX_COMPOSITE1,
237 .vmux = 0,
238 .amux = 1,
239 },{
240 .type = EM28XX_VMUX_SVIDEO,
241 .vmux = 9,
242 .amux = 1,
243 }},
244 },
245};
246const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
247
248/* table of devices that work with this driver */
249struct usb_device_id em28xx_id_table [] = {
250 { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
251 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
252 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
253 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
254 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
255 { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
256 { },
257};
258
259void em28xx_card_setup(struct em28xx *dev)
260{
261 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv;
264 struct v4l2_audioout ao;
265#ifdef CONFIG_MODULES
266 request_module("tveeprom");
267 request_module("ir-kbd-i2c");
268 request_module("msp3400");
269#endif
270 /* Call first TVeeprom */
271
272 dev->i2c_client.addr = 0xa0 >> 1;
273 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
274
275 dev->tuner_type= tv.tuner_type;
276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
277 dev->has_msp34xx=1;
278 memset (&ao,0,sizeof(ao));
279
280 ao.index=2;
281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else
284 dev->has_msp34xx=0;
285 }
286}
287
288EXPORT_SYMBOL(em28xx_boards);
289EXPORT_SYMBOL(em28xx_bcount);
290EXPORT_SYMBOL(em28xx_id_table);
291
292MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
new file mode 100644
index 000000000000..d54bc0127484
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -0,0 +1,817 @@
1/*
2 em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/usb.h>
29#include <linux/vmalloc.h>
30
31#include "em28xx.h"
32
33/* #define ENABLE_DEBUG_ISOC_FRAMES */
34
35unsigned int core_debug;
36module_param(core_debug,int,0644);
37MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
38
39#define em28xx_coredbg(fmt, arg...) do {\
40 if (core_debug) \
41 printk(KERN_INFO "%s %s :"fmt, \
42 dev->name, __FUNCTION__ , ##arg); } while (0)
43
44unsigned int reg_debug;
45module_param(reg_debug,int,0644);
46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
47
48#define em28xx_regdbg(fmt, arg...) do {\
49 if (reg_debug) \
50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __FUNCTION__ , ##arg); } while (0)
52
53unsigned int isoc_debug;
54module_param(isoc_debug,int,0644);
55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
56
57#define em28xx_isocdbg(fmt, arg...) do {\
58 if (isoc_debug) \
59 printk(KERN_INFO "%s %s :"fmt, \
60 dev->name, __FUNCTION__ , ##arg); } while (0)
61
62static int alt = EM28XX_PINOUT;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65
66/* ------------------------------------------------------------------ */
67/* debug help functions */
68
69static const char *v4l1_ioctls[] = {
70 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
71 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
72 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
73 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
74 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
75#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
76
77static const char *v4l2_ioctls[] = {
78 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
79 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
80 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
81 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
82 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
83 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
84 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
85 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
86 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
87 "S_MODULATOR"
88};
89#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
90
91void em28xx_print_ioctl(char *name, unsigned int cmd)
92{
93 char *dir;
94
95 switch (_IOC_DIR(cmd)) {
96 case _IOC_NONE: dir = "--"; break;
97 case _IOC_READ: dir = "r-"; break;
98 case _IOC_WRITE: dir = "-w"; break;
99 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
100 default: dir = "??"; break;
101 }
102 switch (_IOC_TYPE(cmd)) {
103 case 'v':
104 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
105 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
106 v4l1_ioctls[_IOC_NR(cmd)] : "???");
107 break;
108 case 'V':
109 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
110 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
111 v4l2_ioctls[_IOC_NR(cmd)] : "???");
112 break;
113 default:
114 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
115 name, cmd, dir, _IOC_NR(cmd));
116 }
117}
118
119static void *rvmalloc(size_t size)
120{
121 void *mem;
122 unsigned long adr;
123
124 size = PAGE_ALIGN(size);
125
126 mem = vmalloc_32((unsigned long)size);
127 if (!mem)
128 return NULL;
129
130 memset(mem, 0, size);
131
132 adr = (unsigned long)mem;
133 while (size > 0) {
134 SetPageReserved(vmalloc_to_page((void *)adr));
135 adr += PAGE_SIZE;
136 size -= PAGE_SIZE;
137 }
138
139 return mem;
140}
141
142static void rvfree(void *mem, size_t size)
143{
144 unsigned long adr;
145
146 if (!mem)
147 return;
148
149 size = PAGE_ALIGN(size);
150
151 adr = (unsigned long)mem;
152 while (size > 0) {
153 ClearPageReserved(vmalloc_to_page((void *)adr));
154 adr += PAGE_SIZE;
155 size -= PAGE_SIZE;
156 }
157
158 vfree(mem);
159}
160
161/*
162 * em28xx_request_buffers()
163 * allocate a number of buffers
164 */
165u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
166{
167 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
168 void *buff = NULL;
169 u32 i;
170 em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
171 if (count > EM28XX_NUM_FRAMES)
172 count = EM28XX_NUM_FRAMES;
173
174 dev->num_frames = count;
175 while (dev->num_frames > 0) {
176 if ((buff = rvmalloc(dev->num_frames * imagesize)))
177 break;
178 dev->num_frames--;
179 }
180
181 for (i = 0; i < dev->num_frames; i++) {
182 dev->frame[i].bufmem = buff + i * imagesize;
183 dev->frame[i].buf.index = i;
184 dev->frame[i].buf.m.offset = i * imagesize;
185 dev->frame[i].buf.length = dev->frame_size;
186 dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
187 dev->frame[i].buf.sequence = 0;
188 dev->frame[i].buf.field = V4L2_FIELD_NONE;
189 dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
190 dev->frame[i].buf.flags = 0;
191 }
192 return dev->num_frames;
193}
194
195/*
196 * em28xx_queue_unusedframes()
197 * add all frames that are not currently in use to the inbuffer queue
198 */
199void em28xx_queue_unusedframes(struct em28xx *dev)
200{
201 unsigned long lock_flags;
202 u32 i;
203
204 for (i = 0; i < dev->num_frames; i++)
205 if (dev->frame[i].state == F_UNUSED) {
206 dev->frame[i].state = F_QUEUED;
207 spin_lock_irqsave(&dev->queue_lock, lock_flags);
208 list_add_tail(&dev->frame[i].frame, &dev->inqueue);
209 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
210 }
211}
212
213/*
214 * em28xx_release_buffers()
215 * free frame buffers
216 */
217void em28xx_release_buffers(struct em28xx *dev)
218{
219 if (dev->num_frames) {
220 rvfree(dev->frame[0].bufmem,
221 dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
222 dev->num_frames = 0;
223 }
224}
225
226/*
227 * em28xx_read_reg_req()
228 * reads data from the usb device specifying bRequest
229 */
230int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
231 char *buf, int len)
232{
233 int ret, byte;
234
235 em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
236
237 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
238 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
239 0x0000, reg, buf, len, HZ);
240
241 if (reg_debug){
242 printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
243 for (byte = 0; byte < len; byte++) {
244 printk(" %02x", buf[byte]);
245 }
246 printk("\n");
247 }
248
249 return ret;
250}
251
252/*
253 * em28xx_read_reg_req()
254 * reads data from the usb device specifying bRequest
255 */
256int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
257{
258 u8 val;
259 int ret;
260
261 em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
262
263 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
264 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
265 0x0000, reg, &val, 1, HZ);
266
267 if (reg_debug)
268 printk(ret < 0 ? " failed!\n" : "%02x\n", val);
269
270 if (ret < 0)
271 return ret;
272
273 return val;
274}
275
276int em28xx_read_reg(struct em28xx *dev, u16 reg)
277{
278 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
279}
280
281/*
282 * em28xx_write_regs_req()
283 * sends data to the usb device, specifying bRequest
284 */
285int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
286 int len)
287{
288 int ret;
289
290 /*usb_control_msg seems to expect a kmalloced buffer */
291 unsigned char *bufs = kmalloc(len, GFP_KERNEL);
292
293 em28xx_regdbg("req=%02x reg=%02x:", req, reg);
294
295 if (reg_debug) {
296 int i;
297 for (i = 0; i < len; ++i)
298 printk (" %02x", (unsigned char)buf[i]);
299 printk ("\n");
300 }
301
302 if (!bufs)
303 return -ENOMEM;
304 memcpy(bufs, buf, len);
305 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
306 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
307 0x0000, reg, bufs, len, HZ);
308 mdelay(5); /* FIXME: magic number */
309 kfree(bufs);
310 return ret;
311}
312
313int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
314{
315 return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
316}
317
318/*
319 * em28xx_write_reg_bits()
320 * sets only some bits (specified by bitmask) of a register, by first reading
321 * the actual value
322 */
323int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
324 u8 bitmask)
325{
326 int oldval;
327 u8 newval;
328 if ((oldval = em28xx_read_reg(dev, reg)) < 0)
329 return oldval;
330 newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
331 return em28xx_write_regs(dev, reg, &newval, 1);
332}
333
334/*
335 * em28xx_write_ac97()
336 * write a 16 bit value to the specified AC97 address (LSB first!)
337 */
338int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
339{
340 int ret;
341 u8 addr = reg & 0x7f;
342 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
343 return ret;
344 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
345 return ret;
346 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
347 return ret;
348 else if (((u8) ret) & 0x01) {
349 em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
350 }
351 return 0;
352}
353
354int em28xx_audio_analog_set(struct em28xx *dev)
355{
356 char s[2] = { 0x00, 0x00 };
357 s[0] |= 0x1f - dev->volume;
358 s[1] |= 0x1f - dev->volume;
359 if (dev->mute)
360 s[1] |= 0x80;
361 return em28xx_write_ac97(dev, MASTER_AC97, s);
362}
363
364
365int em28xx_colorlevels_set_default(struct em28xx *dev)
366{
367 em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */
368 em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */
369 em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */
370 em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
371 em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
372 em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);
373
374 em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
375 em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
376 em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
377 em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
378 em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
379 em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
380 return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
381}
382
383int em28xx_capture_start(struct em28xx *dev, int start)
384{
385 int ret;
386 /* FIXME: which is the best order? */
387 /* video registers are sampled by VREF */
388 if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
389 0x10)) < 0)
390 return ret;
391 /* enable video capture */
392 return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
393}
394
395int em28xx_outfmt_set_yuv422(struct em28xx *dev)
396{
397 em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
398 em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
399 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
400}
401
402int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
403 u8 ymax)
404{
405 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
406
407 em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
408 em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
409 em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
410 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
411}
412
413int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
414 u16 width, u16 height)
415{
416 u8 cwidth = width;
417 u8 cheight = height;
418 u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
419
420 em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
421 (height | (overflow & 1) << 8));
422
423 em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
424 em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
425 em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
426 em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
427 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
428}
429
430int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
431{
432 u8 mode;
433 /* the em2800 scaler only supports scaling down to 50% */
434 if(dev->is_em2800)
435 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
436 else {
437 u8 buf[2];
438 buf[0] = h;
439 buf[1] = h >> 8;
440 em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
441 buf[0] = v;
442 buf[1] = v >> 8;
443 em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
444 /* it seems that both H and V scalers must be active to work correctly */
445 mode = (h || v)? 0x30: 0x00;
446 }
447 return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
448}
449
450/* FIXME: this only function read values from dev */
451int em28xx_resolution_set(struct em28xx *dev)
452{
453 int width, height;
454 width = norm_maxw(dev);
455 height = norm_maxh(dev) >> 1;
456
457 em28xx_outfmt_set_yuv422(dev);
458 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
459 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
460 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
461}
462
463
464/******************* isoc transfer handling ****************************/
465
466#ifdef ENABLE_DEBUG_ISOC_FRAMES
467static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
468{
469 int len = 0;
470 int ntrans = 0;
471 int i;
472
473 printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
474 urb->start_frame, urb->number_of_packets,
475 urb->error_count);
476 for (i = 0; i < urb->number_of_packets; i++) {
477 unsigned char *buf =
478 urb->transfer_buffer +
479 urb->iso_frame_desc[i].offset;
480 int alen = urb->iso_frame_desc[i].actual_length;
481 if (alen > 0) {
482 if (buf[0] == 0x88) {
483 ntrans++;
484 len += alen;
485 } else if (buf[0] == 0x22) {
486 printk(KERN_DEBUG
487 "= l=%d nt=%d bpp=%d\n",
488 len - 4 * ntrans, ntrans,
489 ntrans == 0 ? 0 : len / ntrans);
490 ntrans = 1;
491 len = alen;
492 } else
493 printk(KERN_DEBUG "!\n");
494 }
495 printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i,
496 urb->iso_frame_desc[i].status,
497 urb->iso_frame_desc[i].actual_length,
498 (unsigned int)
499 *((unsigned char *)(urb->transfer_buffer +
500 urb->iso_frame_desc[i].
501 offset)));
502 }
503}
504#endif
505
506static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
507 unsigned long *lock_flags, unsigned char buf)
508{
509 if (!(buf & 0x01)) {
510 if ((*f)->state == F_GRABBING) {
511 /*previous frame is incomplete */
512 if ((*f)->fieldbytesused < dev->field_size) {
513 (*f)->state = F_ERROR;
514 em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
515 dev->field_size-(*f)->fieldbytesused);
516 } else {
517 (*f)->state = F_DONE;
518 (*f)->buf.bytesused = dev->frame_size;
519 }
520 }
521 if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
522 /* move current frame to outqueue and get next free buffer from inqueue */
523 spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
524 list_move_tail(&(*f)->frame, &dev->outqueue);
525 if (!list_empty(&dev->inqueue))
526 (*f) = list_entry(dev-> inqueue.next,
527 struct em28xx_frame_t,frame);
528 else
529 (*f) = NULL;
530 spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
531 }
532 if (!(*f)) {
533 em28xx_isocdbg ("new frame but no buffer is free");
534 return -1;
535 }
536 do_gettimeofday(&(*f)->buf.timestamp);
537 (*f)->buf.sequence = ++dev->frame_count;
538 (*f)->buf.field = V4L2_FIELD_INTERLACED;
539 (*f)->state = F_GRABBING;
540 (*f)->buf.bytesused = 0;
541 (*f)->top_field = 1;
542 (*f)->fieldbytesused = 0;
543 } else {
544 /* acquiring bottom field */
545 if ((*f)->state == F_GRABBING) {
546 if (!(*f)->top_field) {
547 (*f)->state = F_ERROR;
548 em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
549 } else if ((*f)-> fieldbytesused < dev->field_size - 172) {
550 (*f)->state = F_ERROR;
551 em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
552 dev->field_size-(*f)->fieldbytesused);
553 } else {
554 (*f)->top_field = 0;
555 (*f)->fieldbytesused = 0;
556 }
557 }
558 }
559 return (0);
560}
561
562static inline void em28xx_isoc_video_copy(struct em28xx *dev,
563 struct em28xx_frame_t **f, unsigned char *buf, int len)
564{
565 void *fieldstart, *startwrite, *startread;
566 int linesdone, currlinedone, offset, lencopy,remain;
567
568 if(dev->frame_size != (*f)->buf.length){
569 em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
570 return;
571 }
572
573 if ((*f)->fieldbytesused + len > dev->field_size)
574 len =dev->field_size - (*f)->fieldbytesused;
575
576 if (buf[0] != 0x88 && buf[0] != 0x22) {
577 em28xx_isocdbg("frame is not complete\n");
578 startread = buf;
579 len+=4;
580 } else
581 startread = buf + 4;
582
583 remain = len;
584
585 if ((*f)->top_field)
586 fieldstart = (*f)->bufmem;
587 else
588 fieldstart = (*f)->bufmem + dev->bytesperline;
589
590 linesdone = (*f)->fieldbytesused / dev->bytesperline;
591 currlinedone = (*f)->fieldbytesused % dev->bytesperline;
592 offset = linesdone * dev->bytesperline * 2 + currlinedone;
593 startwrite = fieldstart + offset;
594 lencopy = dev->bytesperline - currlinedone;
595 lencopy = lencopy > remain ? remain : lencopy;
596
597 memcpy(startwrite, startread, lencopy);
598 remain -= lencopy;
599
600 while (remain > 0) {
601 startwrite += lencopy + dev->bytesperline;
602 startread += lencopy;
603 if (dev->bytesperline > remain)
604 lencopy = remain;
605 else
606 lencopy = dev->bytesperline;
607
608 memcpy(startwrite, startread, lencopy);
609 remain -= lencopy;
610 }
611
612 (*f)->fieldbytesused += len;
613}
614
615/*
616 * em28xx_isoIrq()
617 * handles the incoming isoc urbs and fills the frames from our inqueue
618 */
619void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
620{
621 struct em28xx *dev = urb->context;
622 int i, status;
623 struct em28xx_frame_t **f;
624 unsigned long lock_flags;
625
626 if (!dev)
627 return;
628#ifdef ENABLE_DEBUG_ISOC_FRAMES
629 if (isoc_debug>1)
630 em28xx_isoc_dump(urb, regs);
631#endif
632
633 if (urb->status == -ENOENT)
634 return;
635
636 f = &dev->frame_current;
637
638 if (dev->stream == STREAM_INTERRUPT) {
639 dev->stream = STREAM_OFF;
640 if ((*f))
641 (*f)->state = F_QUEUED;
642 em28xx_isocdbg("stream interrupted");
643 wake_up_interruptible(&dev->wait_stream);
644 }
645
646 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
647 return;
648
649 if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
650 if (!(*f))
651 (*f) = list_entry(dev->inqueue.next,
652 struct em28xx_frame_t, frame);
653
654 for (i = 0; i < urb->number_of_packets; i++) {
655 unsigned char *buf = urb->transfer_buffer +
656 urb->iso_frame_desc[i].offset;
657 int len = urb->iso_frame_desc[i].actual_length - 4;
658
659 if (urb->iso_frame_desc[i].status) {
660 em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
661 urb->iso_frame_desc[i].actual_length,
662 urb->iso_frame_desc[i].status);
663 if (urb->iso_frame_desc[i].status != -EPROTO)
664 continue;
665 }
666 if (urb->iso_frame_desc[i].actual_length <= 0) {
667 em28xx_isocdbg("packet %d is empty",i);
668 continue;
669 }
670 if (urb->iso_frame_desc[i].actual_length >
671 dev->max_pkt_size) {
672 em28xx_isocdbg("packet bigger than packet size");
673 continue;
674 }
675 /*new frame */
676 if (buf[0] == 0x22 && buf[1] == 0x5a) {
677 em28xx_isocdbg("Video frame, length=%i!",len);
678
679 if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
680 break;
681 } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
682 em28xx_isocdbg("VBI HEADER!!!");
683 }
684
685 /* actual copying */
686 if ((*f)->state == F_GRABBING) {
687 em28xx_isoc_video_copy(dev,f,buf, len);
688 }
689 }
690 }
691
692 for (i = 0; i < urb->number_of_packets; i++) {
693 urb->iso_frame_desc[i].status = 0;
694 urb->iso_frame_desc[i].actual_length = 0;
695 }
696
697 urb->status = 0;
698 if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
699 em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
700 dev->state |= DEV_MISCONFIGURED;
701 }
702 wake_up_interruptible(&dev->wait_frame);
703 return;
704}
705
706/*
707 * em28xx_uninit_isoc()
708 * deallocates the buffers and urbs allocated during em28xx_init_iosc()
709 */
710void em28xx_uninit_isoc(struct em28xx *dev)
711{
712 int i;
713
714 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
715 if (dev->urb[i]) {
716 usb_kill_urb(dev->urb[i]);
717 if (dev->transfer_buffer[i]){
718 usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
719 }
720 usb_free_urb(dev->urb[i]);
721 }
722 dev->urb[i] = NULL;
723 dev->transfer_buffer[i] = NULL;
724 }
725 em28xx_capture_start(dev, 0);
726}
727
728/*
729 * em28xx_init_isoc()
730 * allocates transfer buffers and submits the urbs for isoc transfer
731 */
732int em28xx_init_isoc(struct em28xx *dev)
733{
734 /* change interface to 3 which allowes the biggest packet sizes */
735 int i, errCode;
736 const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
737
738 /* reset streaming vars */
739 dev->frame_current = NULL;
740 dev->frame_count = 0;
741
742 /* allocate urbs */
743 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
744 struct urb *urb;
745 int j, k;
746 /* allocate transfer buffer */
747 urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
748 if (!urb){
749 em28xx_errdev("cannot alloc urb %i\n", i);
750 em28xx_uninit_isoc(dev);
751 return -ENOMEM;
752 }
753 dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
754 if (!dev->transfer_buffer[i]) {
755 em28xx_errdev
756 ("unable to allocate %i bytes for transfer buffer %i\n",
757 sb_size, i);
758 em28xx_uninit_isoc(dev);
759 return -ENOMEM;
760 }
761 memset(dev->transfer_buffer[i], 0, sb_size);
762 urb->dev = dev->udev;
763 urb->context = dev;
764 urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
765 urb->transfer_flags = URB_ISO_ASAP;
766 urb->interval = 1;
767 urb->transfer_buffer = dev->transfer_buffer[i];
768 urb->complete = em28xx_isocIrq;
769 urb->number_of_packets = EM28XX_NUM_PACKETS;
770 urb->transfer_buffer_length = sb_size;
771 for (j = k = 0; j < EM28XX_NUM_PACKETS;
772 j++, k += dev->max_pkt_size) {
773 urb->iso_frame_desc[j].offset = k;
774 urb->iso_frame_desc[j].length =
775 dev->max_pkt_size;
776 }
777 dev->urb[i] = urb;
778 }
779
780 /* submit urbs */
781 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
782 errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
783 if (errCode) {
784 em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
785 errCode);
786 em28xx_uninit_isoc(dev);
787 return errCode;
788 }
789 }
790
791 return 0;
792}
793
794int em28xx_set_alternate(struct em28xx *dev)
795{
796 int errCode, prev_alt = dev->alt;
797 dev->alt = alt;
798 if (dev->alt == 0) {
799 int i;
800 for(i=0;i< dev->num_alt; i++)
801 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
802 dev->alt=i;
803 }
804
805 if (dev->alt != prev_alt) {
806 dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
807 em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
808 dev->max_pkt_size);
809 errCode = usb_set_interface(dev->udev, 0, dev->alt);
810 if (errCode < 0) {
811 em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
812 dev->alt, errCode);
813 return errCode;
814 }
815 }
816 return 0;
817}
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
new file mode 100644
index 000000000000..b32d9852f34c
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -0,0 +1,586 @@
1/*
2 em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
28#include <linux/video_decoder.h>
29
30#include "em28xx.h"
31#include <media/tuner.h>
32
33/* ----------------------------------------------------------- */
34
35static unsigned int i2c_scan = 0;
36module_param(i2c_scan, int, 0444);
37MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
38
39static unsigned int i2c_debug = 0;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
44 printk(fmt , ##args); } while (0)
45#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
46 printk(KERN_DEBUG "%s at %s: " fmt, \
47 dev->name, __FUNCTION__ , ##args); } while (0)
48
49/*
50 * em2800_i2c_send_max4()
51 * send up to 4 bytes to the i2c device
52 */
53static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
54 char *buf, int len)
55{
56 int ret;
57 int write_timeout;
58 unsigned char b2[6];
59 BUG_ON(len < 1 || len > 4);
60 b2[5] = 0x80 + len - 1;
61 b2[4] = addr;
62 b2[3] = buf[0];
63 if (len > 1)
64 b2[2] = buf[1];
65 if (len > 2)
66 b2[1] = buf[2];
67 if (len > 3)
68 b2[0] = buf[3];
69
70 ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
71 if (ret != 2 + len) {
72 em28xx_warn("writting to i2c device failed (error=%i)\n", ret);
73 return -EIO;
74 }
75 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
76 write_timeout -= 5) {
77 ret = dev->em28xx_read_reg(dev, 0x05);
78 if (ret == 0x80 + len - 1)
79 return len;
80 mdelay(5);
81 }
82 em28xx_warn("i2c write timed out\n");
83 return -EIO;
84}
85
86/*
87 * em2800_i2c_send_bytes()
88 */
89static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
90 short len)
91{
92 char *bufPtr = buf;
93 int ret;
94 int wrcount = 0;
95 int count;
96 int maxLen = 4;
97 struct em28xx *dev = (struct em28xx *)data;
98 while (len > 0) {
99 count = (len > maxLen) ? maxLen : len;
100 ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
101 if (ret > 0) {
102 len -= count;
103 bufPtr += count;
104 wrcount += count;
105 } else
106 return (ret < 0) ? ret : -EFAULT;
107 }
108 return wrcount;
109}
110
111/*
112 * em2800_i2c_check_for_device()
113 * check if there is a i2c_device at the supplied address
114 */
115static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
116{
117 char msg;
118 int ret;
119 int write_timeout;
120 msg = addr;
121 ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
122 if (ret < 0) {
123 em28xx_warn("setting i2c device address failed (error=%i)\n",
124 ret);
125 return ret;
126 }
127 msg = 0x84;
128 ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
129 if (ret < 0) {
130 em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
131 return ret;
132 }
133 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
134 write_timeout -= 5) {
135 unsigned msg = dev->em28xx_read_reg(dev, 0x5);
136 if (msg == 0x94)
137 return -ENODEV;
138 else if (msg == 0x84)
139 return 0;
140 mdelay(5);
141 }
142 return -ENODEV;
143}
144
145/*
146 * em2800_i2c_recv_bytes()
147 * read from the i2c device
148 */
149static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
150 char *buf, int len)
151{
152 int ret;
153 /* check for the device and set i2c read address */
154 ret = em2800_i2c_check_for_device(dev, addr);
155 if (ret) {
156 em28xx_warn
157 ("preparing read at i2c address 0x%x failed (error=%i)\n",
158 addr, ret);
159 return ret;
160 }
161 ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
162 if (ret < 0) {
163 em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
164 addr, ret);
165 return ret;
166 }
167 return ret;
168}
169
170/*
171 * em28xx_i2c_send_bytes()
172 * untested for more than 4 bytes
173 */
174static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
175 short len, int stop)
176{
177 int wrcount = 0;
178 struct em28xx *dev = (struct em28xx *)data;
179
180 wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
181
182 return wrcount;
183}
184
185/*
186 * em28xx_i2c_recv_bytes()
187 * read a byte from the i2c device
188 */
189static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
190 char *buf, int len)
191{
192 int ret;
193 ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
194 if (ret < 0) {
195 em28xx_warn("reading i2c device failed (error=%i)\n", ret);
196 return ret;
197 }
198 if (dev->em28xx_read_reg(dev, 0x5) != 0)
199 return -ENODEV;
200 return ret;
201}
202
203/*
204 * em28xx_i2c_check_for_device()
205 * check if there is a i2c_device at the supplied address
206 */
207static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
208{
209 char msg;
210 int ret;
211 msg = addr;
212
213 ret = dev->em28xx_read_reg_req(dev, 2, addr);
214 if (ret < 0) {
215 em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
216 return ret;
217 }
218 if (dev->em28xx_read_reg(dev, 0x5) != 0)
219 return -ENODEV;
220 return 0;
221}
222
223/*
224 * em28xx_i2c_xfer()
225 * the main i2c transfer function
226 */
227static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
228 struct i2c_msg msgs[], int num)
229{
230 struct em28xx *dev = i2c_adap->algo_data;
231 int addr, rc, i, byte;
232
233 if (num <= 0)
234 return 0;
235 for (i = 0; i < num; i++) {
236 addr = msgs[i].addr << 1;
237 dprintk2(2,"%s %s addr=%x len=%d:",
238 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
239 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
240 if (!msgs[i].len) { /* no len: check only for device presence */
241 if (dev->is_em2800)
242 rc = em2800_i2c_check_for_device(dev, addr);
243 else
244 rc = em28xx_i2c_check_for_device(dev, addr);
245 if (rc < 0) {
246 dprintk2(2," no device\n");
247 return rc;
248 }
249
250 } else if (msgs[i].flags & I2C_M_RD) {
251 /* read bytes */
252 if (dev->is_em2800)
253 rc = em2800_i2c_recv_bytes(dev, addr,
254 msgs[i].buf,
255 msgs[i].len);
256 else
257 rc = em28xx_i2c_recv_bytes(dev, addr,
258 msgs[i].buf,
259 msgs[i].len);
260 if (i2c_debug>=2) {
261 for (byte = 0; byte < msgs[i].len; byte++) {
262 printk(" %02x", msgs[i].buf[byte]);
263 }
264 }
265 } else {
266 /* write bytes */
267 if (i2c_debug>=2) {
268 for (byte = 0; byte < msgs[i].len; byte++)
269 printk(" %02x", msgs[i].buf[byte]);
270 }
271 if (dev->is_em2800)
272 rc = em2800_i2c_send_bytes(dev, addr,
273 msgs[i].buf,
274 msgs[i].len);
275 else
276 rc = em28xx_i2c_send_bytes(dev, addr,
277 msgs[i].buf,
278 msgs[i].len,
279 i == num - 1);
280 if (rc < 0)
281 goto err;
282 }
283 if (i2c_debug>=2)
284 printk("\n");
285 }
286
287 return num;
288 err:
289 dprintk2(2," ERROR: %i\n", rc);
290 return rc;
291}
292
293static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
294{
295 unsigned char buf, *p = eedata;
296 struct em28xx_eeprom *em_eeprom = (void *)eedata;
297 int i, err, size = len, block;
298
299 dev->i2c_client.addr = 0xa0 >> 1;
300
301 /* Check if board has eeprom */
302 err = i2c_master_recv(&dev->i2c_client, &buf, 0);
303 if (err < 0)
304 return -1;
305
306 buf = 0;
307 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
308 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
309 dev->name, err);
310 return -1;
311 }
312 while (size > 0) {
313 if (size > 16)
314 block = 16;
315 else
316 block = size;
317
318 if (block !=
319 (err = i2c_master_recv(&dev->i2c_client, p, block))) {
320 printk(KERN_WARNING
321 "%s: i2c eeprom read error (err=%d)\n",
322 dev->name, err);
323 return -1;
324 }
325 size -= block;
326 p += block;
327 }
328 for (i = 0; i < len; i++) {
329 if (0 == (i % 16))
330 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
331 printk(" %02x", eedata[i]);
332 if (15 == (i % 16))
333 printk("\n");
334 }
335
336 printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id);
337 printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID,
338 em_eeprom->product_ID);
339
340 switch (em_eeprom->chip_conf >> 4 & 0x3) {
341 case 0:
342 printk(KERN_INFO "No audio on board.\n");
343 break;
344 case 1:
345 printk(KERN_INFO "AC97 audio (5 sample rates)\n");
346 break;
347 case 2:
348 printk(KERN_INFO "I2S audio, sample rate=32k\n");
349 break;
350 case 3:
351 printk(KERN_INFO "I2S audio, 3 sample rates\n");
352 break;
353 }
354
355 if (em_eeprom->chip_conf & 1 << 3)
356 printk(KERN_INFO "USB Remote wakeup capable\n");
357
358 if (em_eeprom->chip_conf & 1 << 2)
359 printk(KERN_INFO "USB Self power capable\n");
360
361 switch (em_eeprom->chip_conf & 0x3) {
362 case 0:
363 printk(KERN_INFO "500mA max power\n");
364 break;
365 case 1:
366 printk(KERN_INFO "400mA max power\n");
367 break;
368 case 2:
369 printk(KERN_INFO "300mA max power\n");
370 break;
371 case 3:
372 printk(KERN_INFO "200mA max power\n");
373 break;
374 }
375 printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
376 em_eeprom->string_idx_table,em_eeprom->string1,
377 em_eeprom->string2,em_eeprom->string3);
378
379 return 0;
380}
381
382/* ----------------------------------------------------------- */
383
384/*
385 * algo_control()
386 */
387static int algo_control(struct i2c_adapter *adapter,
388 unsigned int cmd, unsigned long arg)
389{
390 return 0;
391}
392
393/*
394 * functionality()
395 */
396static u32 functionality(struct i2c_adapter *adap)
397{
398 return I2C_FUNC_SMBUS_EMUL;
399}
400
401#ifndef I2C_PEC
402static void inc_use(struct i2c_adapter *adap)
403{
404 MOD_INC_USE_COUNT;
405}
406
407static void dec_use(struct i2c_adapter *adap)
408{
409 MOD_DEC_USE_COUNT;
410}
411#endif
412
413static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
414{
415 struct em28xx *dev = client->adapter->algo_data;
416 struct tuner_setup tun_setup;
417
418 if (dev->has_tuner) {
419 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
420 tun_setup.type = dev->tuner_type;
421 tun_setup.addr = dev->tuner_addr;
422
423 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
424 }
425
426 return (0);
427}
428
429/*
430 * attach_inform()
431 * gets called when a device attaches to the i2c bus
432 * does some basic configuration
433 */
434static int attach_inform(struct i2c_client *client)
435{
436 struct em28xx *dev = client->adapter->algo_data;
437
438 switch (client->addr << 1) {
439 case 0x86:
440 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
441 break;
442 case 0x42:
443 dprintk1(1,"attach_inform: saa7114 detected.\n");
444 break;
445 case 0x4a:
446 dprintk1(1,"attach_inform: saa7113 detected.\n");
447 break;
448 case 0xa0:
449 dprintk1(1,"attach_inform: eeprom detected.\n");
450 break;
451 case 0x60:
452 case 0x8e:
453 {
454 struct IR_i2c *ir = i2c_get_clientdata(client);
455 dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
456 em28xx_set_ir(dev,ir);
457 break;
458 }
459 case 0x80:
460 case 0x88:
461 dprintk1(1,"attach_inform: msp34xx detected.\n");
462 break;
463 case 0xb8:
464 case 0xba:
465 dprintk1(1,"attach_inform: tvp5150 detected.\n");
466 break;
467 default:
468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
469 dev->tuner_addr = client->addr;
470 em28xx_set_tuner(-1, client);
471 }
472
473 return 0;
474}
475
476static struct i2c_algorithm em28xx_algo = {
477 .master_xfer = em28xx_i2c_xfer,
478 .algo_control = algo_control,
479 .functionality = functionality,
480};
481
482static struct i2c_adapter em28xx_adap_template = {
483#ifdef I2C_PEC
484 .owner = THIS_MODULE,
485#else
486 .inc_use = inc_use,
487 .dec_use = dec_use,
488#endif
489#ifdef I2C_CLASS_TV_ANALOG
490 .class = I2C_CLASS_TV_ANALOG,
491#endif
492 .name = "em28xx",
493 .id = I2C_HW_B_EM28XX,
494 .algo = &em28xx_algo,
495 .client_register = attach_inform,
496};
497
498static struct i2c_client em28xx_client_template = {
499 .name = "em28xx internal",
500 .flags = I2C_CLIENT_ALLOW_USE,
501};
502
503/* ----------------------------------------------------------- */
504
505/*
506 * i2c_devs
507 * incomplete list of known devices
508 */
509static char *i2c_devs[128] = {
510 [0x4a >> 1] = "saa7113h",
511 [0x60 >> 1] = "remote IR sensor",
512 [0x8e >> 1] = "remote IR sensor",
513 [0x86 >> 1] = "tda9887",
514 [0x80 >> 1] = "msp34xx",
515 [0x88 >> 1] = "msp34xx",
516 [0xa0 >> 1] = "eeprom",
517 [0xb8 >> 1] = "tvp5150a",
518 [0xba >> 1] = "tvp5150a",
519 [0xc0 >> 1] = "tuner (analog)",
520 [0xc2 >> 1] = "tuner (analog)",
521 [0xc4 >> 1] = "tuner (analog)",
522 [0xc6 >> 1] = "tuner (analog)",
523};
524
525/*
526 * do_i2c_scan()
527 * check i2c address range for devices
528 */
529static void do_i2c_scan(char *name, struct i2c_client *c)
530{
531 unsigned char buf;
532 int i, rc;
533
534 for (i = 0; i < 128; i++) {
535 c->addr = i;
536 rc = i2c_master_recv(c, &buf, 0);
537 if (rc < 0)
538 continue;
539 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
540 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
541 }
542}
543
544/*
545 * em28xx_i2c_call_clients()
546 * send commands to all attached i2c devices
547 */
548void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
549{
550 BUG_ON(NULL == dev->i2c_adap.algo_data);
551 i2c_clients_command(&dev->i2c_adap, cmd, arg);
552}
553
554/*
555 * em28xx_i2c_register()
556 * register i2c bus
557 */
558int em28xx_i2c_register(struct em28xx *dev)
559{
560 BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
561 BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
562 dev->i2c_adap = em28xx_adap_template;
563 dev->i2c_adap.dev.parent = &dev->udev->dev;
564 strcpy(dev->i2c_adap.name, dev->name);
565 dev->i2c_adap.algo_data = dev;
566 i2c_add_adapter(&dev->i2c_adap);
567
568 dev->i2c_client = em28xx_client_template;
569 dev->i2c_client.adapter = &dev->i2c_adap;
570
571 em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
572
573 if (i2c_scan)
574 do_i2c_scan(dev->name, &dev->i2c_client);
575 return 0;
576}
577
578/*
579 * em28xx_i2c_unregister()
580 * unregister i2c_bus
581 */
582int em28xx_i2c_unregister(struct em28xx *dev)
583{
584 i2c_del_adapter(&dev->i2c_adap);
585 return 0;
586}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..32c49df58adc
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,184 @@
1/*
2 handle em28xx IR remotes via linux kernel input layer.
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/input.h>
31#include <linux/usb.h>
32
33#include "em28xx.h"
34
35static unsigned int disable_ir = 0;
36module_param(disable_ir, int, 0444);
37MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
38
39static unsigned int ir_debug = 0;
40module_param(ir_debug, int, 0644);
41MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
42
43#define dprintk(fmt, arg...) if (ir_debug) \
44 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
45
46/* ---------------------------------------------------------------------- */
47
48static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
49 [ 0x01 ] = KEY_CHANNEL,
50 [ 0x02 ] = KEY_SELECT,
51 [ 0x03 ] = KEY_MUTE,
52 [ 0x04 ] = KEY_POWER,
53 [ 0x05 ] = KEY_KP1,
54 [ 0x06 ] = KEY_KP2,
55 [ 0x07 ] = KEY_KP3,
56 [ 0x08 ] = KEY_CHANNELUP,
57 [ 0x09 ] = KEY_KP4,
58 [ 0x0a ] = KEY_KP5,
59 [ 0x0b ] = KEY_KP6,
60 [ 0x0c ] = KEY_CHANNELDOWN,
61 [ 0x0d ] = KEY_KP7,
62 [ 0x0e ] = KEY_KP8,
63 [ 0x0f ] = KEY_KP9,
64 [ 0x10 ] = KEY_VOLUMEUP,
65 [ 0x11 ] = KEY_KP0,
66 [ 0x12 ] = KEY_MENU,
67 [ 0x13 ] = KEY_PRINT,
68 [ 0x14 ] = KEY_VOLUMEDOWN,
69 [ 0x16 ] = KEY_PAUSE,
70 [ 0x18 ] = KEY_RECORD,
71 [ 0x19 ] = KEY_REWIND,
72 [ 0x1a ] = KEY_PLAY,
73 [ 0x1b ] = KEY_FORWARD,
74 [ 0x1c ] = KEY_BACKSPACE,
75 [ 0x1e ] = KEY_STOP,
76 [ 0x40 ] = KEY_ZOOM,
77};
78
79/* ----------------------------------------------------------------------- */
80
81static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
82{
83 unsigned char b;
84
85 /* poll IR chip */
86 if (1 != i2c_master_recv(&ir->c,&b,1)) {
87 dprintk("read error\n");
88 return -EIO;
89 }
90
91 /* it seems that 0xFE indicates that a button is still hold
92 down, while 0xff indicates that no button is hold
93 down. 0xfe sequences are sometimes interrupted by 0xFF */
94
95 dprintk("key %02x\n", b);
96
97 if (b == 0xff)
98 return 0;
99
100 if (b == 0xfe)
101 /* keep old data */
102 return 1;
103
104 *ir_key = b;
105 *ir_raw = b;
106 return 1;
107}
108
109
110static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
111{
112 unsigned char buf[2];
113 unsigned char code;
114
115 /* poll IR chip */
116 if (2 != i2c_master_recv(&ir->c,buf,2))
117 return -EIO;
118
119 /* Does eliminate repeated parity code */
120 if (buf[1]==0xff)
121 return 0;
122
123 /* avoid fast reapeating */
124 if (buf[1]==ir->old)
125 return 0;
126 ir->old=buf[1];
127
128 /* Rearranges bits to the right order */
129 code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
130 ((buf[0]&0x02)<<3) | /* 0001 0000 */
131 ((buf[0]&0x04)<<1) | /* 0000 1000 */
132 ((buf[0]&0x08)>>1) | /* 0000 0100 */
133 ((buf[0]&0x10)>>3) | /* 0000 0010 */
134 ((buf[0]&0x20)>>5); /* 0000 0001 */
135
136 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
137
138 /* return key */
139 *ir_key = code;
140 *ir_raw = code;
141 return 1;
142}
143
144/* ----------------------------------------------------------------------- */
145void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
146{
147 if (disable_ir) {
148 ir->get_key=NULL;
149 return ;
150 }
151
152 /* detect & configure */
153 switch (dev->model) {
154 case (EM2800_BOARD_UNKNOWN):
155 break;
156 case (EM2820_BOARD_UNKNOWN):
157 break;
158 case (EM2800_BOARD_TERRATEC_CINERGY_200):
159 case (EM2820_BOARD_TERRATEC_CINERGY_250):
160 ir->ir_codes = ir_codes_em_terratec;
161 ir->get_key = get_key_terratec;
162 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
163 break;
164 case (EM2820_BOARD_PINNACLE_USB_2):
165 break;
166 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
167 ir->ir_codes = ir_codes_hauppauge_new;
168 ir->get_key = get_key_em_haup;
169 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)");
170 break;
171 case (EM2820_BOARD_MSI_VOX_USB_2):
172 break;
173 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
174 break;
175 case (EM2800_BOARD_KWORLD_USB2800):
176 break;
177 }
178}
179
180/* ----------------------------------------------------------------------
181 * Local variables:
182 * c-basic-offset: 8
183 * End:
184 */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
new file mode 100644
index 000000000000..57c1826b928e
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -0,0 +1,1933 @@
1/*
2 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/usb.h>
29#include <linux/i2c.h>
30#include <linux/version.h>
31#include <linux/video_decoder.h>
32
33#include "em28xx.h"
34#include <media/tuner.h>
35
36#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
37 "Markus Rechberger <mrechberger@gmail.com>, " \
38 "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
39 "Sascha Sommer <saschasommer@freenet.de>"
40
41#define DRIVER_NAME "em28xx"
42#define DRIVER_DESC "Empia em28xx based USB video device driver"
43#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
44
45#define em28xx_videodbg(fmt, arg...) do {\
46 if (video_debug) \
47 printk(KERN_INFO "%s %s :"fmt, \
48 dev->name, __FUNCTION__ , ##arg); } while (0)
49
50MODULE_AUTHOR(DRIVER_AUTHOR);
51MODULE_DESCRIPTION(DRIVER_DESC);
52MODULE_LICENSE("GPL");
53
54static LIST_HEAD(em28xx_devlist);
55
56static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card,"card type");
59
60static int tuner = -1;
61module_param(tuner, int, 0444);
62MODULE_PARM_DESC(tuner, "tuner type");
63
64static unsigned int video_debug = 0;
65module_param(video_debug,int,0644);
66MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
67
68/* supported tv norms */
69static struct em28xx_tvnorm tvnorms[] = {
70 {
71 .name = "PAL",
72 .id = V4L2_STD_PAL,
73 .mode = VIDEO_MODE_PAL,
74 }, {
75 .name = "NTSC",
76 .id = V4L2_STD_NTSC,
77 .mode = VIDEO_MODE_NTSC,
78 }, {
79 .name = "SECAM",
80 .id = V4L2_STD_SECAM,
81 .mode = VIDEO_MODE_SECAM,
82 }, {
83 .name = "PAL-M",
84 .id = V4L2_STD_PAL_M,
85 .mode = VIDEO_MODE_PAL,
86 }
87};
88
89static const unsigned char saa7114_i2c_init[] = {
90 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
91 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
92 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
93 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
94 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
95 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
96 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
97 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
98 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
99 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
100 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
101 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
102 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
103 0xbe,0x00,0xbf,0x00
104};
105
106#define TVNORMS ARRAY_SIZE(tvnorms)
107
108/* supported controls */
109static struct v4l2_queryctrl em28xx_qctrl[] = {
110 {
111 .id = V4L2_CID_BRIGHTNESS,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Brightness",
114 .minimum = -128,
115 .maximum = 127,
116 .step = 1,
117 .default_value = 0,
118 .flags = 0,
119 },{
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0x0,
124 .maximum = 0x1f,
125 .step = 0x1,
126 .default_value = 0x10,
127 .flags = 0,
128 },{
129 .id = V4L2_CID_SATURATION,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Saturation",
132 .minimum = 0x0,
133 .maximum = 0x1f,
134 .step = 0x1,
135 .default_value = 0x10,
136 .flags = 0,
137 },{
138 .id = V4L2_CID_AUDIO_VOLUME,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Volume",
141 .minimum = 0x0,
142 .maximum = 0x1f,
143 .step = 0x1,
144 .default_value = 0x1f,
145 .flags = 0,
146 },{
147 .id = V4L2_CID_AUDIO_MUTE,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Mute",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 1,
154 .flags = 0,
155 },{
156 .id = V4L2_CID_RED_BALANCE,
157 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Red chroma balance",
159 .minimum = -128,
160 .maximum = 127,
161 .step = 1,
162 .default_value = 0,
163 .flags = 0,
164 },{
165 .id = V4L2_CID_BLUE_BALANCE,
166 .type = V4L2_CTRL_TYPE_INTEGER,
167 .name = "Blue chroma balance",
168 .minimum = -128,
169 .maximum = 127,
170 .step = 1,
171 .default_value = 0,
172 .flags = 0,
173 },{
174 .id = V4L2_CID_GAMMA,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gamma",
177 .minimum = 0x0,
178 .maximum = 0x3f,
179 .step = 0x1,
180 .default_value = 0x20,
181 .flags = 0,
182 }
183};
184
185static struct usb_driver em28xx_usb_driver;
186
187static DECLARE_MUTEX(em28xx_sysfs_lock);
188static DECLARE_RWSEM(em28xx_disconnect);
189
190/********************* v4l2 interface ******************************************/
191
192static inline unsigned long kvirt_to_pa(unsigned long adr)
193{
194 unsigned long kva, ret;
195
196 kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
197 kva |= adr & (PAGE_SIZE - 1);
198 ret = __pa(kva);
199 return ret;
200}
201
202/*
203 * em28xx_config()
204 * inits registers with sane defaults
205 */
206static int em28xx_config(struct em28xx *dev)
207{
208
209 /* Sets I2C speed to 100 KHz */
210 em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
211
212 /* enable vbi capturing */
213 em28xx_audio_usb_mute(dev, 1);
214 dev->mute = 1; /* maybe not the right place... */
215 dev->volume = 0x1f;
216 em28xx_audio_analog_set(dev);
217 em28xx_audio_analog_setup(dev);
218 em28xx_outfmt_set_yuv422(dev);
219 em28xx_colorlevels_set_default(dev);
220 em28xx_compression_disable(dev);
221
222 return 0;
223}
224
225/*
226 * em28xx_config_i2c()
227 * configure i2c attached devices
228 */
229void em28xx_config_i2c(struct em28xx *dev)
230{
231 struct v4l2_frequency f;
232 struct video_decoder_init em28xx_vdi = {.data = NULL };
233
234
235 /* configure decoder */
236 if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
237 em28xx_vdi.data=saa7114_i2c_init;
238 em28xx_vdi.len=sizeof(saa7114_i2c_init);
239 }
240
241
242 em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
243 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
244/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
245/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
246/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
247/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
248
249 /* configure tuner */
250 f.tuner = 0;
251 f.type = V4L2_TUNER_ANALOG_TV;
252 f.frequency = 9076; /* FIXME:remove magic number */
253 dev->ctl_freq = f.frequency;
254 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
255
256 /* configure tda9887 */
257
258
259/* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
260}
261
262/*
263 * em28xx_empty_framequeues()
264 * prepare queues for incoming and outgoing frames
265 */
266static void em28xx_empty_framequeues(struct em28xx *dev)
267{
268 u32 i;
269
270 INIT_LIST_HEAD(&dev->inqueue);
271 INIT_LIST_HEAD(&dev->outqueue);
272
273 for (i = 0; i < EM28XX_NUM_FRAMES; i++) {
274 dev->frame[i].state = F_UNUSED;
275 dev->frame[i].buf.bytesused = 0;
276 }
277}
278
279static void video_mux(struct em28xx *dev, int index)
280{
281 int input, ainput;
282
283 input = INPUT(index)->vmux;
284 dev->ctl_input = index;
285 dev->ctl_ainput = INPUT(index)->amux;
286
287 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
288
289
290 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
291
292 if (dev->has_msp34xx) {
293 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
294 ainput = EM28XX_AUDIO_SRC_TUNER;
295 em28xx_audio_source(dev, ainput);
296 } else {
297 switch (dev->ctl_ainput) {
298 case 0:
299 ainput = EM28XX_AUDIO_SRC_TUNER;
300 break;
301 default:
302 ainput = EM28XX_AUDIO_SRC_LINE;
303 }
304 em28xx_audio_source(dev, ainput);
305 }
306}
307
308/*
309 * em28xx_v4l2_open()
310 * inits the device and starts isoc transfer
311 */
312static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
313{
314 int minor = iminor(inode);
315 int errCode = 0;
316 struct em28xx *h,*dev = NULL;
317 struct list_head *list;
318
319 list_for_each(list,&em28xx_devlist) {
320 h = list_entry(list, struct em28xx, devlist);
321 if (h->vdev->minor == minor) {
322 dev = h;
323 }
324 }
325
326 filp->private_data=dev;
327
328
329 em28xx_videodbg("users=%d\n", dev->users);
330
331 if (!down_read_trylock(&em28xx_disconnect))
332 return -ERESTARTSYS;
333
334 if (dev->users) {
335 em28xx_warn("this driver can be opened only once\n");
336 up_read(&em28xx_disconnect);
337 return -EBUSY;
338 }
339
340/* if(dev->vbi_dev->minor == minor){
341 dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
342 }*/
343 if (dev->vdev->minor == minor) {
344 dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
345 }
346
347 init_MUTEX(&dev->fileop_lock); /* to 1 == available */
348 spin_lock_init(&dev->queue_lock);
349 init_waitqueue_head(&dev->wait_frame);
350 init_waitqueue_head(&dev->wait_stream);
351
352 down(&dev->lock);
353
354 em28xx_set_alternate(dev);
355
356 dev->width = norm_maxw(dev);
357 dev->height = norm_maxh(dev);
358 dev->frame_size = dev->width * dev->height * 2;
359 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
360 dev->bytesperline = dev->width * 2;
361 dev->hscale = 0;
362 dev->vscale = 0;
363
364 em28xx_capture_start(dev, 1);
365 em28xx_resolution_set(dev);
366
367 /* start the transfer */
368 errCode = em28xx_init_isoc(dev);
369 if (errCode)
370 goto err;
371
372 dev->users++;
373 filp->private_data = dev;
374 dev->io = IO_NONE;
375 dev->stream = STREAM_OFF;
376 dev->num_frames = 0;
377
378 /* prepare queues */
379 em28xx_empty_framequeues(dev);
380
381 dev->state |= DEV_INITIALIZED;
382
383 video_mux(dev, 0);
384
385 err:
386 up(&dev->lock);
387 up_read(&em28xx_disconnect);
388 return errCode;
389}
390
391/*
392 * em28xx_realease_resources()
393 * unregisters the v4l2,i2c and usb devices
394 * called when the device gets disconected or at module unload
395*/
396static void em28xx_release_resources(struct em28xx *dev)
397{
398 down(&em28xx_sysfs_lock);
399
400 em28xx_info("V4L2 device /dev/video%d deregistered\n",
401 dev->vdev->minor);
402 list_del(&dev->devlist);
403 video_unregister_device(dev->vdev);
404/* video_unregister_device(dev->vbi_dev); */
405 em28xx_i2c_unregister(dev);
406 usb_put_dev(dev->udev);
407 up(&em28xx_sysfs_lock);
408}
409
410/*
411 * em28xx_v4l2_close()
412 * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
413 */
414static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
415{
416 int errCode;
417 struct em28xx *dev=filp->private_data;
418
419 em28xx_videodbg("users=%d\n", dev->users);
420
421 down(&dev->lock);
422
423 em28xx_uninit_isoc(dev);
424
425 em28xx_release_buffers(dev);
426
427 /* the device is already disconnect, free the remaining resources */
428 if (dev->state & DEV_DISCONNECTED) {
429 em28xx_release_resources(dev);
430 up(&dev->lock);
431 kfree(dev);
432 return 0;
433 }
434
435 /* set alternate 0 */
436 dev->alt = 0;
437 em28xx_videodbg("setting alternate 0\n");
438 errCode = usb_set_interface(dev->udev, 0, 0);
439 if (errCode < 0) {
440 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
441 errCode);
442 }
443
444 dev->users--;
445 wake_up_interruptible_nr(&dev->open, 1);
446 up(&dev->lock);
447 return 0;
448}
449
450/*
451 * em28xx_v4l2_read()
452 * will allocate buffers when called for the first time
453 */
454static ssize_t
455em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
456 loff_t * f_pos)
457{
458 struct em28xx_frame_t *f, *i;
459 unsigned long lock_flags;
460 int ret = 0;
461 struct em28xx *dev = filp->private_data;
462
463 if (down_interruptible(&dev->fileop_lock))
464 return -ERESTARTSYS;
465
466 if (dev->state & DEV_DISCONNECTED) {
467 em28xx_videodbg("device not present\n");
468 up(&dev->fileop_lock);
469 return -ENODEV;
470 }
471
472 if (dev->state & DEV_MISCONFIGURED) {
473 em28xx_videodbg("device misconfigured; close and open it again\n");
474 up(&dev->fileop_lock);
475 return -EIO;
476 }
477
478 if (dev->io == IO_MMAP) {
479 em28xx_videodbg ("IO method is set to mmap; close and open"
480 " the device again to choose the read method\n");
481 up(&dev->fileop_lock);
482 return -EINVAL;
483 }
484
485 if (dev->io == IO_NONE) {
486 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
487 em28xx_errdev("read failed, not enough memory\n");
488 up(&dev->fileop_lock);
489 return -ENOMEM;
490 }
491 dev->io = IO_READ;
492 dev->stream = STREAM_ON;
493 em28xx_queue_unusedframes(dev);
494 }
495
496 if (!count) {
497 up(&dev->fileop_lock);
498 return 0;
499 }
500
501 if (list_empty(&dev->outqueue)) {
502 if (filp->f_flags & O_NONBLOCK) {
503 up(&dev->fileop_lock);
504 return -EAGAIN;
505 }
506 ret = wait_event_interruptible
507 (dev->wait_frame,
508 (!list_empty(&dev->outqueue)) ||
509 (dev->state & DEV_DISCONNECTED));
510 if (ret) {
511 up(&dev->fileop_lock);
512 return ret;
513 }
514 if (dev->state & DEV_DISCONNECTED) {
515 up(&dev->fileop_lock);
516 return -ENODEV;
517 }
518 }
519
520 f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame);
521
522 spin_lock_irqsave(&dev->queue_lock, lock_flags);
523 list_for_each_entry(i, &dev->outqueue, frame)
524 i->state = F_UNUSED;
525 INIT_LIST_HEAD(&dev->outqueue);
526 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
527
528 em28xx_queue_unusedframes(dev);
529
530 if (count > f->buf.length)
531 count = f->buf.length;
532
533 if (copy_to_user(buf, f->bufmem, count)) {
534 up(&dev->fileop_lock);
535 return -EFAULT;
536 }
537 *f_pos += count;
538
539 up(&dev->fileop_lock);
540
541 return count;
542}
543
544/*
545 * em28xx_v4l2_poll()
546 * will allocate buffers when called for the first time
547 */
548static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
549{
550 unsigned int mask = 0;
551 struct em28xx *dev = filp->private_data;
552
553 if (down_interruptible(&dev->fileop_lock))
554 return POLLERR;
555
556 if (dev->state & DEV_DISCONNECTED) {
557 em28xx_videodbg("device not present\n");
558 } else if (dev->state & DEV_MISCONFIGURED) {
559 em28xx_videodbg("device is misconfigured; close and open it again\n");
560 } else {
561 if (dev->io == IO_NONE) {
562 if (!em28xx_request_buffers
563 (dev, EM28XX_NUM_READ_FRAMES)) {
564 em28xx_warn
565 ("poll() failed, not enough memory\n");
566 } else {
567 dev->io = IO_READ;
568 dev->stream = STREAM_ON;
569 }
570 }
571
572 if (dev->io == IO_READ) {
573 em28xx_queue_unusedframes(dev);
574 poll_wait(filp, &dev->wait_frame, wait);
575
576 if (!list_empty(&dev->outqueue))
577 mask |= POLLIN | POLLRDNORM;
578
579 up(&dev->fileop_lock);
580
581 return mask;
582 }
583 }
584
585 up(&dev->fileop_lock);
586 return POLLERR;
587}
588
589/*
590 * em28xx_vm_open()
591 */
592static void em28xx_vm_open(struct vm_area_struct *vma)
593{
594 struct em28xx_frame_t *f = vma->vm_private_data;
595 f->vma_use_count++;
596}
597
598/*
599 * em28xx_vm_close()
600 */
601static void em28xx_vm_close(struct vm_area_struct *vma)
602{
603 /* NOTE: buffers are not freed here */
604 struct em28xx_frame_t *f = vma->vm_private_data;
605 f->vma_use_count--;
606}
607
608static struct vm_operations_struct em28xx_vm_ops = {
609 .open = em28xx_vm_open,
610 .close = em28xx_vm_close,
611};
612
613/*
614 * em28xx_v4l2_mmap()
615 */
616static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
617{
618 unsigned long size = vma->vm_end - vma->vm_start,
619 start = vma->vm_start, pos, page;
620 u32 i;
621
622 struct em28xx *dev = filp->private_data;
623
624 if (down_interruptible(&dev->fileop_lock))
625 return -ERESTARTSYS;
626
627 if (dev->state & DEV_DISCONNECTED) {
628 em28xx_videodbg("mmap: device not present\n");
629 up(&dev->fileop_lock);
630 return -ENODEV;
631 }
632
633 if (dev->state & DEV_MISCONFIGURED) {
634 em28xx_videodbg ("mmap: Device is misconfigured; close and "
635 "open it again\n");
636 up(&dev->fileop_lock);
637 return -EIO;
638 }
639
640 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
641 size != PAGE_ALIGN(dev->frame[0].buf.length)) {
642 up(&dev->fileop_lock);
643 return -EINVAL;
644 }
645
646 for (i = 0; i < dev->num_frames; i++) {
647 if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
648 break;
649 }
650 if (i == dev->num_frames) {
651 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
652 up(&dev->fileop_lock);
653 return -EINVAL;
654 }
655
656 /* VM_IO is eventually going to replace PageReserved altogether */
657 vma->vm_flags |= VM_IO;
658 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
659
660 pos = (unsigned long)dev->frame[i].bufmem;
661 while (size > 0) { /* size is page-aligned */
662 page = vmalloc_to_pfn((void *)pos);
663 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
664 vma->vm_page_prot)) {
665 em28xx_videodbg("mmap: rename page map failed\n");
666 up(&dev->fileop_lock);
667 return -EAGAIN;
668 }
669 start += PAGE_SIZE;
670 pos += PAGE_SIZE;
671 size -= PAGE_SIZE;
672 }
673
674 vma->vm_ops = &em28xx_vm_ops;
675 vma->vm_private_data = &dev->frame[i];
676
677 em28xx_vm_open(vma);
678 up(&dev->fileop_lock);
679 return 0;
680}
681
682/*
683 * em28xx_get_ctrl()
684 * return the current saturation, brightness or contrast, mute state
685 */
686static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
687{
688 s32 tmp;
689 switch (ctrl->id) {
690 case V4L2_CID_AUDIO_MUTE:
691 ctrl->value = dev->mute;
692 return 0;
693 case V4L2_CID_AUDIO_VOLUME:
694 ctrl->value = dev->volume;
695 return 0;
696 case V4L2_CID_BRIGHTNESS:
697 if ((tmp = em28xx_brightness_get(dev)) < 0)
698 return -EIO;
699 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
700 return 0;
701 case V4L2_CID_CONTRAST:
702 if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
703 return -EIO;
704 return 0;
705 case V4L2_CID_SATURATION:
706 if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
707 return -EIO;
708 return 0;
709 case V4L2_CID_RED_BALANCE:
710 if ((tmp = em28xx_v_balance_get(dev)) < 0)
711 return -EIO;
712 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
713 return 0;
714 case V4L2_CID_BLUE_BALANCE:
715 if ((tmp = em28xx_u_balance_get(dev)) < 0)
716 return -EIO;
717 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
718 return 0;
719 case V4L2_CID_GAMMA:
720 if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
721 return -EIO;
722 return 0;
723 default:
724 return -EINVAL;
725 }
726}
727
728/*
729 * em28xx_set_ctrl()
730 * mute or set new saturation, brightness or contrast
731 */
732static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
733{
734 switch (ctrl->id) {
735 case V4L2_CID_AUDIO_MUTE:
736 if (ctrl->value != dev->mute) {
737 dev->mute = ctrl->value;
738 em28xx_audio_usb_mute(dev, ctrl->value);
739 return em28xx_audio_analog_set(dev);
740 }
741 return 0;
742 case V4L2_CID_AUDIO_VOLUME:
743 dev->volume = ctrl->value;
744 return em28xx_audio_analog_set(dev);
745 case V4L2_CID_BRIGHTNESS:
746 return em28xx_brightness_set(dev, ctrl->value);
747 case V4L2_CID_CONTRAST:
748 return em28xx_contrast_set(dev, ctrl->value);
749 case V4L2_CID_SATURATION:
750 return em28xx_saturation_set(dev, ctrl->value);
751 case V4L2_CID_RED_BALANCE:
752 return em28xx_v_balance_set(dev, ctrl->value);
753 case V4L2_CID_BLUE_BALANCE:
754 return em28xx_u_balance_set(dev, ctrl->value);
755 case V4L2_CID_GAMMA:
756 return em28xx_gamma_set(dev, ctrl->value);
757 default:
758 return -EINVAL;
759 }
760}
761
762/*
763 * em28xx_stream_interrupt()
764 * stops streaming
765 */
766static int em28xx_stream_interrupt(struct em28xx *dev)
767{
768 int ret = 0;
769
770 /* stop reading from the device */
771
772 dev->stream = STREAM_INTERRUPT;
773 ret = wait_event_timeout(dev->wait_stream,
774 (dev->stream == STREAM_OFF) ||
775 (dev->state & DEV_DISCONNECTED),
776 EM28XX_URB_TIMEOUT);
777 if (dev->state & DEV_DISCONNECTED)
778 return -ENODEV;
779 else if (ret) {
780 dev->state |= DEV_MISCONFIGURED;
781 em28xx_videodbg("device is misconfigured; close and "
782 "open /dev/video%d again\n", dev->vdev->minor);
783 return ret;
784 }
785
786 return 0;
787}
788
789static int em28xx_set_norm(struct em28xx *dev, int width, int height)
790{
791 unsigned int hscale, vscale;
792 unsigned int maxh, maxw;
793
794 maxw = norm_maxw(dev);
795 maxh = norm_maxh(dev);
796
797 /* width must even because of the YUYV format */
798 /* height must be even because of interlacing */
799 height &= 0xfffe;
800 width &= 0xfffe;
801
802 if (height < 32)
803 height = 32;
804 if (height > maxh)
805 height = maxh;
806 if (width < 48)
807 width = 48;
808 if (width > maxw)
809 width = maxw;
810
811 if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
812 hscale = 0x3fff;
813 width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
814
815 if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
816 vscale = 0x3fff;
817 height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
818
819 /* set new image size */
820 dev->width = width;
821 dev->height = height;
822 dev->frame_size = dev->width * dev->height * 2;
823 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
824 dev->bytesperline = dev->width * 2;
825 dev->hscale = hscale;
826 dev->vscale = vscale;
827
828 em28xx_resolution_set(dev);
829
830 return 0;
831}
832
833/*
834 * em28xx_v4l2_do_ioctl()
835 * This function is _not_ called directly, but from
836 * em28xx_v4l2_ioctl. Userspace
837 * copying is done already, arg is a kernel pointer.
838 */
839static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
840 struct em28xx *dev, unsigned int cmd, void *arg,
841 v4l2_kioctl driver_ioctl)
842{
843 int ret;
844
845 switch (cmd) {
846 /* ---------- tv norms ---------- */
847 case VIDIOC_ENUMSTD:
848 {
849 struct v4l2_standard *e = arg;
850 unsigned int i;
851
852 i = e->index;
853 if (i >= TVNORMS)
854 return -EINVAL;
855 ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
856 tvnorms[e->index].name);
857 e->index = i;
858 if (ret < 0)
859 return ret;
860 return 0;
861 }
862 case VIDIOC_G_STD:
863 {
864 v4l2_std_id *id = arg;
865
866 *id = dev->tvnorm->id;
867 return 0;
868 }
869 case VIDIOC_S_STD:
870 {
871 v4l2_std_id *id = arg;
872 unsigned int i;
873
874 for (i = 0; i < TVNORMS; i++)
875 if (*id == tvnorms[i].id)
876 break;
877 if (i == TVNORMS)
878 for (i = 0; i < TVNORMS; i++)
879 if (*id & tvnorms[i].id)
880 break;
881 if (i == TVNORMS)
882 return -EINVAL;
883
884 down(&dev->lock);
885 dev->tvnorm = &tvnorms[i];
886
887 em28xx_set_norm(dev, dev->width, dev->height);
888
889/*
890 dev->width=norm_maxw(dev);
891 dev->height=norm_maxh(dev);
892 dev->frame_size=dev->width*dev->height*2;
893 dev->field_size=dev->frame_size>>1;
894 dev->bytesperline=dev->width*2;
895 dev->hscale=0;
896 dev->vscale=0;
897
898 em28xx_resolution_set(dev);
899*/
900/*
901 em28xx_uninit_isoc(dev);
902 em28xx_set_alternate(dev);
903 em28xx_capture_start(dev, 1);
904 em28xx_resolution_set(dev);
905 em28xx_init_isoc(dev);
906*/
907 em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
908 &tvnorms[i].mode);
909 em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
910 &dev->tvnorm->id);
911
912 up(&dev->lock);
913
914 return 0;
915 }
916
917 /* ------ input switching ---------- */
918 case VIDIOC_ENUMINPUT:
919 {
920 struct v4l2_input *i = arg;
921 unsigned int n;
922 static const char *iname[] = {
923 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
924 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
925 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
926 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
927 [EM28XX_VMUX_SVIDEO] = "S-Video",
928 [EM28XX_VMUX_TELEVISION] = "Television",
929 [EM28XX_VMUX_CABLE] = "Cable TV",
930 [EM28XX_VMUX_DVB] = "DVB",
931 [EM28XX_VMUX_DEBUG] = "for debug only",
932 };
933
934 n = i->index;
935 if (n >= MAX_EM28XX_INPUT)
936 return -EINVAL;
937 if (0 == INPUT(n)->type)
938 return -EINVAL;
939 memset(i, 0, sizeof(*i));
940 i->index = n;
941 i->type = V4L2_INPUT_TYPE_CAMERA;
942 strcpy(i->name, iname[INPUT(n)->type]);
943 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
944 (EM28XX_VMUX_CABLE == INPUT(n)->type))
945 i->type = V4L2_INPUT_TYPE_TUNER;
946 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
947 i->std |= tvnorms[n].id;
948 return 0;
949 }
950
951 case VIDIOC_G_INPUT:
952 {
953 int *i = arg;
954 *i = dev->ctl_input;
955
956 return 0;
957 }
958
959 case VIDIOC_S_INPUT:
960 {
961 int *index = arg;
962
963 if (*index >= MAX_EM28XX_INPUT)
964 return -EINVAL;
965 if (0 == INPUT(*index)->type)
966 return -EINVAL;
967
968 down(&dev->lock);
969 video_mux(dev, *index);
970 up(&dev->lock);
971
972 return 0;
973 }
974
975 case VIDIOC_G_AUDIO:
976 {
977 struct v4l2_audio *a = arg;
978 unsigned int index = a->index;
979
980 if (a->index > 1)
981 return -EINVAL;
982 memset(a, 0, sizeof(*a));
983 index = dev->ctl_ainput;
984
985 if (index == 0) {
986 strcpy(a->name, "Television");
987 } else {
988 strcpy(a->name, "Line In");
989 }
990 a->capability = V4L2_AUDCAP_STEREO;
991 a->index = index;
992 return 0;
993 }
994
995 case VIDIOC_S_AUDIO:
996 {
997 struct v4l2_audio *a = arg;
998 if (a->index != dev->ctl_ainput)
999 return -EINVAL;
1000
1001 return 0;
1002 }
1003
1004 /* --- controls ---------------------------------------------- */
1005 case VIDIOC_QUERYCTRL:
1006 {
1007 struct v4l2_queryctrl *qc = arg;
1008 u8 i, n;
1009 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1010 for (i = 0; i < n; i++)
1011 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1012 memcpy(qc, &(em28xx_qctrl[i]),
1013 sizeof(*qc));
1014 return 0;
1015 }
1016
1017 return -EINVAL;
1018 }
1019
1020 case VIDIOC_G_CTRL:
1021 {
1022 struct v4l2_control *ctrl = arg;
1023
1024
1025 return em28xx_get_ctrl(dev, ctrl);
1026 }
1027
1028 case VIDIOC_S_CTRL_OLD: /* ??? */
1029 case VIDIOC_S_CTRL:
1030 {
1031 struct v4l2_control *ctrl = arg;
1032 u8 i, n;
1033
1034
1035 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1036 for (i = 0; i < n; i++)
1037 if (ctrl->id == em28xx_qctrl[i].id) {
1038 if (ctrl->value <
1039 em28xx_qctrl[i].minimum
1040 || ctrl->value >
1041 em28xx_qctrl[i].maximum)
1042 return -ERANGE;
1043
1044 return em28xx_set_ctrl(dev, ctrl);
1045 }
1046 return -EINVAL;
1047 }
1048
1049 /* --- tuner ioctls ------------------------------------------ */
1050 case VIDIOC_G_TUNER:
1051 {
1052 struct v4l2_tuner *t = arg;
1053 int status = 0;
1054
1055 if (0 != t->index)
1056 return -EINVAL;
1057
1058 memset(t, 0, sizeof(*t));
1059 strcpy(t->name, "Tuner");
1060 t->type = V4L2_TUNER_ANALOG_TV;
1061 t->capability = V4L2_TUNER_CAP_NORM;
1062 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1063/* t->signal = 0xffff;*/
1064/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
1065 /* No way to get signal strength? */
1066 down(&dev->lock);
1067 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1068 &status);
1069 up(&dev->lock);
1070 t->signal =
1071 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1072
1073 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
1074 t->afc);
1075 return 0;
1076 }
1077 case VIDIOC_S_TUNER:
1078 {
1079 struct v4l2_tuner *t = arg;
1080 int status = 0;
1081
1082 if (0 != t->index)
1083 return -EINVAL;
1084 memset(t, 0, sizeof(*t));
1085 strcpy(t->name, "Tuner");
1086 t->type = V4L2_TUNER_ANALOG_TV;
1087 t->capability = V4L2_TUNER_CAP_NORM;
1088 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1089/* t->signal = 0xffff; */
1090 /* No way to get signal strength? */
1091 down(&dev->lock);
1092 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1093 &status);
1094 up(&dev->lock);
1095 t->signal =
1096 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1097
1098 em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
1099 t->signal, t->afc);
1100 return 0;
1101 }
1102 case VIDIOC_G_FREQUENCY:
1103 {
1104 struct v4l2_frequency *f = arg;
1105
1106 memset(f, 0, sizeof(*f));
1107 f->type = V4L2_TUNER_ANALOG_TV;
1108 f->frequency = dev->ctl_freq;
1109
1110 return 0;
1111 }
1112 case VIDIOC_S_FREQUENCY:
1113 {
1114 struct v4l2_frequency *f = arg;
1115
1116 if (0 != f->tuner)
1117 return -EINVAL;
1118
1119 if (V4L2_TUNER_ANALOG_TV != f->type)
1120 return -EINVAL;
1121
1122 down(&dev->lock);
1123 dev->ctl_freq = f->frequency;
1124 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1125 up(&dev->lock);
1126 return 0;
1127 }
1128
1129 case VIDIOC_CROPCAP:
1130 {
1131 struct v4l2_cropcap *cc = arg;
1132
1133 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1134 return -EINVAL;
1135 cc->bounds.left = 0;
1136 cc->bounds.top = 0;
1137 cc->bounds.width = dev->width;
1138 cc->bounds.height = dev->height;
1139 cc->defrect = cc->bounds;
1140 cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
1141 cc->pixelaspect.denominator = 59;
1142 return 0;
1143 }
1144 case VIDIOC_STREAMON:
1145 {
1146 int *type = arg;
1147
1148 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1149 || dev->io != IO_MMAP)
1150 return -EINVAL;
1151
1152 if (list_empty(&dev->inqueue))
1153 return -EINVAL;
1154
1155 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
1156
1157 em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
1158
1159 return 0;
1160 }
1161 case VIDIOC_STREAMOFF:
1162 {
1163 int *type = arg;
1164 int ret;
1165
1166 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1167 || dev->io != IO_MMAP)
1168 return -EINVAL;
1169
1170 if (dev->stream == STREAM_ON) {
1171 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1172 if ((ret = em28xx_stream_interrupt(dev)))
1173 return ret;
1174 }
1175 em28xx_empty_framequeues(dev);
1176
1177 return 0;
1178 }
1179 default:
1180 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1181 driver_ioctl);
1182 }
1183 return 0;
1184}
1185
1186/*
1187 * em28xx_v4l2_do_ioctl()
1188 * This function is _not_ called directly, but from
1189 * em28xx_v4l2_ioctl. Userspace
1190 * copying is done already, arg is a kernel pointer.
1191 */
1192static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1193 unsigned int cmd, void *arg)
1194{
1195 struct em28xx *dev = filp->private_data;
1196
1197 if (!dev)
1198 return -ENODEV;
1199
1200 if (video_debug > 1)
1201 em28xx_print_ioctl(dev->name,cmd);
1202
1203 switch (cmd) {
1204
1205 /* --- capabilities ------------------------------------------ */
1206 case VIDIOC_QUERYCAP:
1207 {
1208 struct v4l2_capability *cap = arg;
1209
1210 memset(cap, 0, sizeof(*cap));
1211 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1212 strlcpy(cap->card, em28xx_boards[dev->model].name,
1213 sizeof(cap->card));
1214 strlcpy(cap->bus_info, dev->udev->dev.bus_id,
1215 sizeof(cap->bus_info));
1216 cap->version = EM28XX_VERSION_CODE;
1217 cap->capabilities =
1218 V4L2_CAP_VIDEO_CAPTURE |
1219 V4L2_CAP_AUDIO |
1220 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1221 if (dev->has_tuner)
1222 cap->capabilities |= V4L2_CAP_TUNER;
1223 return 0;
1224 }
1225
1226 /* --- capture ioctls ---------------------------------------- */
1227 case VIDIOC_ENUM_FMT:
1228 {
1229 struct v4l2_fmtdesc *fmtd = arg;
1230
1231 if (fmtd->index != 0)
1232 return -EINVAL;
1233 memset(fmtd, 0, sizeof(*fmtd));
1234 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 strcpy(fmtd->description, "Packed YUY2");
1236 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1237 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1238 return 0;
1239 }
1240
1241 case VIDIOC_G_FMT:
1242 {
1243 struct v4l2_format *format = arg;
1244
1245 em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
1246 format->type ==
1247 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1248 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1249 V4L2_BUF_TYPE_VBI_CAPTURE ?
1250 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1251 "not supported");
1252
1253 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1254 return -EINVAL;
1255
1256 format->fmt.pix.width = dev->width;
1257 format->fmt.pix.height = dev->height;
1258 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1259 format->fmt.pix.bytesperline = dev->bytesperline;
1260 format->fmt.pix.sizeimage = dev->frame_size;
1261 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1262 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
1263
1264 em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
1265 dev->height);
1266 return 0;
1267 }
1268
1269 case VIDIOC_TRY_FMT:
1270 case VIDIOC_S_FMT:
1271 {
1272 struct v4l2_format *format = arg;
1273 u32 i;
1274 int ret = 0;
1275 int width = format->fmt.pix.width;
1276 int height = format->fmt.pix.height;
1277 unsigned int hscale, vscale;
1278 unsigned int maxh, maxw;
1279
1280 maxw = norm_maxw(dev);
1281 maxh = norm_maxh(dev);
1282
1283/* int both_fields; */
1284
1285 em28xx_videodbg("%s: type=%s\n",
1286 cmd ==
1287 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1288 "VIDIOC_S_FMT",
1289 format->type ==
1290 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1291 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1292 V4L2_BUF_TYPE_VBI_CAPTURE ?
1293 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1294 "not supported");
1295
1296 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1297 return -EINVAL;
1298
1299 em28xx_videodbg("%s: requested %dx%d\n",
1300 cmd ==
1301 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1302 "VIDIOC_S_FMT", format->fmt.pix.width,
1303 format->fmt.pix.height);
1304
1305 /* FIXME: Move some code away from here */
1306 /* width must even because of the YUYV format */
1307 /* height must be even because of interlacing */
1308 height &= 0xfffe;
1309 width &= 0xfffe;
1310
1311 if (height < 32)
1312 height = 32;
1313 if (height > maxh)
1314 height = maxh;
1315 if (width < 48)
1316 width = 48;
1317 if (width > maxw)
1318 width = maxw;
1319
1320 if(dev->is_em2800){
1321 /* the em2800 can only scale down to 50% */
1322 if(height % (maxh / 2))
1323 height=maxh;
1324 if(width % (maxw / 2))
1325 width=maxw;
1326 /* according to empiatech support */
1327 /* the MaxPacketSize is to small to support */
1328 /* framesizes larger than 640x480 @ 30 fps */
1329 /* or 640x576 @ 25 fps. As this would cut */
1330 /* of a part of the image we prefer */
1331 /* 360x576 or 360x480 for now */
1332 if(width == maxw && height == maxh)
1333 width /= 2;
1334 }
1335
1336 if ((hscale =
1337 (((unsigned long)maxw) << 12) / width - 4096L) >=
1338 0x4000)
1339 hscale = 0x3fff;
1340 width =
1341 (((unsigned long)maxw) << 12) / (hscale + 4096L);
1342
1343 if ((vscale =
1344 (((unsigned long)maxh) << 12) / height - 4096L) >=
1345 0x4000)
1346 vscale = 0x3fff;
1347 height =
1348 (((unsigned long)maxh) << 12) / (vscale + 4096L);
1349
1350 format->fmt.pix.width = width;
1351 format->fmt.pix.height = height;
1352 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1353 format->fmt.pix.bytesperline = width * 2;
1354 format->fmt.pix.sizeimage = width * 2 * height;
1355 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1356 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
1357
1358 em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
1359 cmd ==
1360 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1361 "VIDIOC_S_FMT", format->fmt.pix.width,
1362 format->fmt.pix.height, hscale, vscale);
1363
1364 if (cmd == VIDIOC_TRY_FMT)
1365 return 0;
1366
1367 for (i = 0; i < dev->num_frames; i++)
1368 if (dev->frame[i].vma_use_count) {
1369 em28xx_videodbg("VIDIOC_S_FMT failed. "
1370 "Unmap the buffers first.\n");
1371 return -EINVAL;
1372 }
1373
1374 /* stop io in case it is already in progress */
1375 if (dev->stream == STREAM_ON) {
1376 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
1377 if ((ret = em28xx_stream_interrupt(dev)))
1378 return ret;
1379 }
1380
1381 em28xx_release_buffers(dev);
1382 dev->io = IO_NONE;
1383
1384 /* set new image size */
1385 dev->width = width;
1386 dev->height = height;
1387 dev->frame_size = dev->width * dev->height * 2;
1388 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
1389 dev->bytesperline = dev->width * 2;
1390 dev->hscale = hscale;
1391 dev->vscale = vscale;
1392/* dev->both_fileds = both_fileds; */
1393 em28xx_uninit_isoc(dev);
1394 em28xx_set_alternate(dev);
1395 em28xx_capture_start(dev, 1);
1396 em28xx_resolution_set(dev);
1397 em28xx_init_isoc(dev);
1398
1399 return 0;
1400 }
1401
1402 /* --- streaming capture ------------------------------------- */
1403 case VIDIOC_REQBUFS:
1404 {
1405 struct v4l2_requestbuffers *rb = arg;
1406 u32 i;
1407 int ret;
1408
1409 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1410 rb->memory != V4L2_MEMORY_MMAP)
1411 return -EINVAL;
1412
1413 if (dev->io == IO_READ) {
1414 em28xx_videodbg ("method is set to read;"
1415 " close and open the device again to"
1416 " choose the mmap I/O method\n");
1417 return -EINVAL;
1418 }
1419
1420 for (i = 0; i < dev->num_frames; i++)
1421 if (dev->frame[i].vma_use_count) {
1422 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
1423 return -EINVAL;
1424 }
1425
1426 if (dev->stream == STREAM_ON) {
1427 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1428 if ((ret = em28xx_stream_interrupt(dev)))
1429 return ret;
1430 }
1431
1432 em28xx_empty_framequeues(dev);
1433
1434 em28xx_release_buffers(dev);
1435 if (rb->count)
1436 rb->count =
1437 em28xx_request_buffers(dev, rb->count);
1438
1439 dev->frame_current = NULL;
1440
1441 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1442 rb->count);
1443 dev->io = rb->count ? IO_MMAP : IO_NONE;
1444 return 0;
1445 }
1446
1447 case VIDIOC_QUERYBUF:
1448 {
1449 struct v4l2_buffer *b = arg;
1450
1451 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1452 b->index >= dev->num_frames || dev->io != IO_MMAP)
1453 return -EINVAL;
1454
1455 memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
1456
1457 if (dev->frame[b->index].vma_use_count) {
1458 b->flags |= V4L2_BUF_FLAG_MAPPED;
1459 }
1460 if (dev->frame[b->index].state == F_DONE)
1461 b->flags |= V4L2_BUF_FLAG_DONE;
1462 else if (dev->frame[b->index].state != F_UNUSED)
1463 b->flags |= V4L2_BUF_FLAG_QUEUED;
1464 return 0;
1465 }
1466 case VIDIOC_QBUF:
1467 {
1468 struct v4l2_buffer *b = arg;
1469 unsigned long lock_flags;
1470
1471 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1472 b->index >= dev->num_frames || dev->io != IO_MMAP) {
1473 return -EINVAL;
1474 }
1475
1476 if (dev->frame[b->index].state != F_UNUSED) {
1477 return -EAGAIN;
1478 }
1479 dev->frame[b->index].state = F_QUEUED;
1480
1481 /* add frame to fifo */
1482 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1483 list_add_tail(&dev->frame[b->index].frame,
1484 &dev->inqueue);
1485 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1486
1487 return 0;
1488 }
1489 case VIDIOC_DQBUF:
1490 {
1491 struct v4l2_buffer *b = arg;
1492 struct em28xx_frame_t *f;
1493 unsigned long lock_flags;
1494 int ret = 0;
1495
1496 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1497 || dev->io != IO_MMAP)
1498 return -EINVAL;
1499
1500 if (list_empty(&dev->outqueue)) {
1501 if (dev->stream == STREAM_OFF)
1502 return -EINVAL;
1503 if (filp->f_flags & O_NONBLOCK)
1504 return -EAGAIN;
1505 ret = wait_event_interruptible
1506 (dev->wait_frame,
1507 (!list_empty(&dev->outqueue)) ||
1508 (dev->state & DEV_DISCONNECTED));
1509 if (ret)
1510 return ret;
1511 if (dev->state & DEV_DISCONNECTED)
1512 return -ENODEV;
1513 }
1514
1515 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1516 f = list_entry(dev->outqueue.next,
1517 struct em28xx_frame_t, frame);
1518 list_del(dev->outqueue.next);
1519 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1520
1521 f->state = F_UNUSED;
1522 memcpy(b, &f->buf, sizeof(*b));
1523
1524 if (f->vma_use_count)
1525 b->flags |= V4L2_BUF_FLAG_MAPPED;
1526
1527 return 0;
1528 }
1529 default:
1530 return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
1531 em28xx_video_do_ioctl);
1532 }
1533 return 0;
1534}
1535
1536/*
1537 * em28xx_v4l2_ioctl()
1538 * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl()
1539 */
1540static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1541 unsigned int cmd, unsigned long arg)
1542{
1543 int ret = 0;
1544 struct em28xx *dev = filp->private_data;
1545
1546 if (down_interruptible(&dev->fileop_lock))
1547 return -ERESTARTSYS;
1548
1549 if (dev->state & DEV_DISCONNECTED) {
1550 em28xx_errdev("v4l2 ioctl: device not present\n");
1551 up(&dev->fileop_lock);
1552 return -ENODEV;
1553 }
1554
1555 if (dev->state & DEV_MISCONFIGURED) {
1556 em28xx_errdev
1557 ("v4l2 ioctl: device is misconfigured; close and open it again\n");
1558 up(&dev->fileop_lock);
1559 return -EIO;
1560 }
1561
1562 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
1563
1564 up(&dev->fileop_lock);
1565
1566 return ret;
1567}
1568
1569static struct file_operations em28xx_v4l_fops = {
1570 .owner = THIS_MODULE,
1571 .open = em28xx_v4l2_open,
1572 .release = em28xx_v4l2_close,
1573 .ioctl = em28xx_v4l2_ioctl,
1574 .read = em28xx_v4l2_read,
1575 .poll = em28xx_v4l2_poll,
1576 .mmap = em28xx_v4l2_mmap,
1577 .llseek = no_llseek,
1578};
1579
1580/******************************** usb interface *****************************************/
1581
1582/*
1583 * em28xx_init_dev()
1584 * allocates and inits the device structs, registers i2c bus and v4l device
1585 */
1586static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1587 int minor, int model)
1588{
1589 struct em28xx *dev = *devhandle;
1590 int retval = -ENOMEM;
1591 int errCode, i;
1592 unsigned int maxh, maxw;
1593
1594 dev->udev = udev;
1595 dev->model = model;
1596 init_MUTEX(&dev->lock);
1597 init_waitqueue_head(&dev->open);
1598
1599 dev->em28xx_write_regs = em28xx_write_regs;
1600 dev->em28xx_read_reg = em28xx_read_reg;
1601 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1602 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1603 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1604 dev->is_em2800 = em28xx_boards[model].is_em2800;
1605 dev->has_tuner = em28xx_boards[model].has_tuner;
1606 dev->has_msp34xx = em28xx_boards[model].has_msp34xx;
1607 dev->tda9887_conf = em28xx_boards[model].tda9887_conf;
1608 dev->decoder = em28xx_boards[model].decoder;
1609
1610 if (tuner >= 0)
1611 dev->tuner_type = tuner;
1612 else
1613 dev->tuner_type = em28xx_boards[model].tuner_type;
1614
1615 dev->video_inputs = em28xx_boards[model].vchannels;
1616
1617 for (i = 0; i < TVNORMS; i++)
1618 if (em28xx_boards[model].norm == tvnorms[i].mode)
1619 break;
1620 if (i == TVNORMS)
1621 i = 0;
1622
1623 dev->tvnorm = &tvnorms[i]; /* set default norm */
1624
1625 em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name);
1626
1627 maxw = norm_maxw(dev);
1628 maxh = norm_maxh(dev);
1629
1630 /* set default image size */
1631 dev->width = maxw;
1632 dev->height = maxh;
1633 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1634 dev->field_size = dev->width * dev->height;
1635 dev->frame_size =
1636 dev->interlaced ? dev->field_size << 1 : dev->field_size;
1637 dev->bytesperline = dev->width * 2;
1638 dev->hscale = 0;
1639 dev->vscale = 0;
1640 dev->ctl_input = 2;
1641
1642 /* setup video picture settings for saa7113h */
1643 memset(&dev->vpic, 0, sizeof(dev->vpic));
1644 dev->vpic.colour = 128 << 8;
1645 dev->vpic.hue = 128 << 8;
1646 dev->vpic.brightness = 128 << 8;
1647 dev->vpic.contrast = 192 << 8;
1648 dev->vpic.whiteness = 128 << 8; /* This one isn't used */
1649 dev->vpic.depth = 16;
1650 dev->vpic.palette = VIDEO_PALETTE_YUV422;
1651
1652#ifdef CONFIG_MODULES
1653 /* request some modules */
1654 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
1655 request_module("saa711x");
1656 if (dev->decoder == EM28XX_TVP5150)
1657 request_module("tvp5150");
1658 if (dev->has_tuner)
1659 request_module("tuner");
1660 if (dev->tda9887_conf)
1661 request_module("tda9887");
1662#endif
1663 errCode = em28xx_config(dev);
1664 if (errCode) {
1665 em28xx_errdev("error configuring device\n");
1666 kfree(dev);
1667 return -ENOMEM;
1668 }
1669
1670 down(&dev->lock);
1671 /* register i2c bus */
1672 em28xx_i2c_register(dev);
1673
1674 /* Do board specific init and eeprom reading */
1675 em28xx_card_setup(dev);
1676
1677 /* configure the device */
1678 em28xx_config_i2c(dev);
1679
1680 up(&dev->lock);
1681
1682 errCode = em28xx_config(dev);
1683
1684#ifdef CONFIG_MODULES
1685 if (dev->has_msp34xx)
1686 request_module("msp3400");
1687#endif
1688 /* allocate and fill v4l2 device struct */
1689 dev->vdev = video_device_alloc();
1690 if (NULL == dev->vdev) {
1691 em28xx_errdev("cannot allocate video_device.\n");
1692 kfree(dev);
1693 return -ENOMEM;
1694 }
1695
1696 dev->vdev->type = VID_TYPE_CAPTURE;
1697 if (dev->has_tuner)
1698 dev->vdev->type |= VID_TYPE_TUNER;
1699 dev->vdev->hardware = 0;
1700 dev->vdev->fops = &em28xx_v4l_fops;
1701 dev->vdev->minor = -1;
1702 dev->vdev->dev = &dev->udev->dev;
1703 dev->vdev->release = video_device_release;
1704 snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
1705 "em28xx video");
1706 list_add_tail(&dev->devlist,&em28xx_devlist);
1707
1708 /* register v4l2 device */
1709 down(&dev->lock);
1710 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
1711 em28xx_errdev("unable to register video device (error=%i).\n",
1712 retval);
1713 up(&dev->lock);
1714 list_del(&dev->devlist);
1715 video_device_release(dev->vdev);
1716 kfree(dev);
1717 return -ENODEV;
1718 }
1719 if (dev->has_msp34xx) {
1720 /* Send a reset to other chips via gpio */
1721 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1722 udelay(2500);
1723 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1724 udelay(2500);
1725
1726 }
1727 video_mux(dev, 0);
1728
1729 up(&dev->lock);
1730
1731 em28xx_info("V4L2 device registered as /dev/video%d\n",
1732 dev->vdev->minor);
1733
1734 return 0;
1735}
1736
1737/*
1738 * em28xx_usb_probe()
1739 * checks for supported devices
1740 */
1741static int em28xx_usb_probe(struct usb_interface *interface,
1742 const struct usb_device_id *id)
1743{
1744 const struct usb_endpoint_descriptor *endpoint;
1745 struct usb_device *udev;
1746 struct usb_interface *uif;
1747 struct em28xx *dev = NULL;
1748 int retval = -ENODEV;
1749 int model,i,nr,ifnum;
1750
1751 udev = usb_get_dev(interface_to_usbdev(interface));
1752 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1753
1754
1755 /* Don't register audio interfaces */
1756 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1757 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
1758 udev->descriptor.idVendor,udev->descriptor.idProduct,
1759 ifnum,
1760 interface->altsetting[0].desc.bInterfaceClass);
1761 return -ENODEV;
1762 }
1763
1764 em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
1765 udev->descriptor.idVendor,udev->descriptor.idProduct,
1766 ifnum,
1767 interface->altsetting[0].desc.bInterfaceClass);
1768
1769 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1770
1771 /* check if the the device has the iso in endpoint at the correct place */
1772 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1773 USB_ENDPOINT_XFER_ISOC) {
1774 em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
1775 return -ENODEV;
1776 }
1777 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
1778 em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
1779 return -ENODEV;
1780 }
1781
1782 model=id->driver_info;
1783 nr=interface->minor;
1784
1785 if (nr>EM28XX_MAXBOARDS) {
1786 printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
1787 return -ENOMEM;
1788 }
1789
1790 /* allocate memory for our device state and initialize it */
1791 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1792 if (dev == NULL) {
1793 em28xx_err(DRIVER_NAME ": out of memory!\n");
1794 return -ENOMEM;
1795 }
1796 memset(dev, 0, sizeof(*dev));
1797
1798 /* compute alternate max packet sizes */
1799 uif = udev->actconfig->interface[0];
1800
1801 dev->num_alt=uif->num_altsetting;
1802 printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
1803// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
1804 dev->alt_max_pkt_size = kmalloc(32*
1805 dev->num_alt,GFP_KERNEL);
1806 if (dev->alt_max_pkt_size == NULL) {
1807 em28xx_err(DRIVER_NAME ": out of memory!\n");
1808 return -ENOMEM;
1809 }
1810
1811 for (i = 0; i < dev->num_alt ; i++) {
1812 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1813 wMaxPacketSize);
1814 dev->alt_max_pkt_size[i] =
1815 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1816 printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
1817 dev->alt_max_pkt_size[i]);
1818 }
1819
1820 snprintf(dev->name, 29, "em28xx #%d", nr);
1821
1822 if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
1823 model=card[nr];
1824
1825 if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
1826 printk( "%s: Your board has no eeprom inside it and thus can't\n"
1827 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1828 "%s: workaround that. Redirect complaints to the vendor of\n"
1829 "%s: the TV card. Best regards,\n"
1830 "%s: -- tux\n",
1831 dev->name,dev->name,dev->name,dev->name,dev->name);
1832 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1833 dev->name);
1834 for (i = 0; i < em28xx_bcount; i++) {
1835 printk("%s: card=%d -> %s\n",
1836 dev->name, i, em28xx_boards[i].name);
1837 }
1838 }
1839
1840 /* allocate device struct */
1841 retval = em28xx_init_dev(&dev, udev, nr, model);
1842 if (retval)
1843 return retval;
1844
1845 em28xx_info("Found %s\n", em28xx_boards[model].name);
1846
1847 /* save our data pointer in this interface device */
1848 usb_set_intfdata(interface, dev);
1849 return 0;
1850}
1851
1852/*
1853 * em28xx_usb_disconnect()
1854 * called when the device gets diconencted
1855 * video device will be unregistered on v4l2_close in case it is still open
1856 */
1857static void em28xx_usb_disconnect(struct usb_interface *interface)
1858{
1859 struct em28xx *dev = usb_get_intfdata(interface);
1860 usb_set_intfdata(interface, NULL);
1861
1862 if (!dev)
1863 return;
1864
1865 down_write(&em28xx_disconnect);
1866
1867 down(&dev->lock);
1868
1869 em28xx_info("disconnecting %s\n", dev->vdev->name);
1870
1871 wake_up_interruptible_all(&dev->open);
1872
1873 if (dev->users) {
1874 em28xx_warn
1875 ("device /dev/video%d is open! Deregistration and memory "
1876 "deallocation are deferred on close.\n", dev->vdev->minor);
1877 dev->state |= DEV_MISCONFIGURED;
1878 em28xx_uninit_isoc(dev);
1879 dev->state |= DEV_DISCONNECTED;
1880 wake_up_interruptible(&dev->wait_frame);
1881 wake_up_interruptible(&dev->wait_stream);
1882 } else {
1883 dev->state |= DEV_DISCONNECTED;
1884 em28xx_release_resources(dev);
1885 }
1886
1887 up(&dev->lock);
1888
1889 if (!dev->users) {
1890 kfree(dev->alt_max_pkt_size);
1891 kfree(dev);
1892 }
1893
1894 up_write(&em28xx_disconnect);
1895}
1896
1897static struct usb_driver em28xx_usb_driver = {
1898 .owner = THIS_MODULE,
1899 .name = "em28xx",
1900 .probe = em28xx_usb_probe,
1901 .disconnect = em28xx_usb_disconnect,
1902 .id_table = em28xx_id_table,
1903};
1904
1905static int __init em28xx_module_init(void)
1906{
1907 int result;
1908
1909 printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
1910 (EM28XX_VERSION_CODE >> 16) & 0xff,
1911 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
1912#ifdef SNAPSHOT
1913 printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
1914 SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
1915#endif
1916
1917 /* register this driver with the USB subsystem */
1918 result = usb_register(&em28xx_usb_driver);
1919 if (result)
1920 em28xx_err(DRIVER_NAME
1921 " usb_register failed. Error number %d.\n", result);
1922
1923 return result;
1924}
1925
1926static void __exit em28xx_module_exit(void)
1927{
1928 /* deregister this driver with the USB subsystem */
1929 usb_deregister(&em28xx_usb_driver);
1930}
1931
1932module_init(em28xx_module_init);
1933module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
new file mode 100644
index 000000000000..5c7a41ce69f3
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -0,0 +1,513 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7
8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#ifndef _EM28XX_H
26#define _EM28XX_H
27
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <media/ir-kbd-i2c.h>
31
32/* Boards supported by driver */
33
34#define EM2800_BOARD_UNKNOWN 0
35#define EM2820_BOARD_UNKNOWN 1
36#define EM2820_BOARD_TERRATEC_CINERGY_250 2
37#define EM2820_BOARD_PINNACLE_USB_2 3
38#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
39#define EM2820_BOARD_MSI_VOX_USB_2 5
40#define EM2800_BOARD_TERRATEC_CINERGY_200 6
41#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
42#define EM2800_BOARD_KWORLD_USB2800 8
43#define EM2820_BOARD_PINNACLE_DVC_90 9
44
45#define UNSET -1
46
47/* maximum number of em28xx boards */
48#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
49
50/* maximum number of frames that can be queued */
51#define EM28XX_NUM_FRAMES 5
52/* number of frames that get used for v4l2_read() */
53#define EM28XX_NUM_READ_FRAMES 2
54
55/* number of buffers for isoc transfers */
56#define EM28XX_NUM_BUFS 5
57
58/* number of packets for each buffer
59 windows requests only 40 packets .. so we better do the same
60 this is what I found out for all alternate numbers there!
61 */
62#define EM28XX_NUM_PACKETS 40
63
64/* default alternate; 0 means choose the best */
65#define EM28XX_PINOUT 0
66
67#define EM28XX_INTERLACED_DEFAULT 1
68
69/*
70#define (use usbview if you want to get the other alternate number infos)
71#define
72#define alternate number 2
73#define Endpoint Address: 82
74 Direction: in
75 Attribute: 1
76 Type: Isoc
77 Max Packet Size: 1448
78 Interval: 125us
79
80 alternate number 7
81
82 Endpoint Address: 82
83 Direction: in
84 Attribute: 1
85 Type: Isoc
86 Max Packet Size: 3072
87 Interval: 125us
88*/
89
90/* time to wait when stopping the isoc transfer */
91#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
92
93/* time in msecs to wait for i2c writes to finish */
94#define EM2800_I2C_WRITE_TIMEOUT 20
95
96/* the various frame states */
97enum em28xx_frame_state {
98 F_UNUSED = 0,
99 F_QUEUED,
100 F_GRABBING,
101 F_DONE,
102 F_ERROR,
103};
104
105/* stream states */
106enum em28xx_stream_state {
107 STREAM_OFF,
108 STREAM_INTERRUPT,
109 STREAM_ON,
110};
111
112/* frames */
113struct em28xx_frame_t {
114 void *bufmem;
115 struct v4l2_buffer buf;
116 enum em28xx_frame_state state;
117 struct list_head frame;
118 unsigned long vma_use_count;
119 int top_field;
120 int fieldbytesused;
121};
122
123/* io methods */
124enum em28xx_io_method {
125 IO_NONE,
126 IO_READ,
127 IO_MMAP,
128};
129
130/* inputs */
131
132#define MAX_EM28XX_INPUT 4
133enum enum28xx_itype {
134 EM28XX_VMUX_COMPOSITE1 = 1,
135 EM28XX_VMUX_COMPOSITE2,
136 EM28XX_VMUX_COMPOSITE3,
137 EM28XX_VMUX_COMPOSITE4,
138 EM28XX_VMUX_SVIDEO,
139 EM28XX_VMUX_TELEVISION,
140 EM28XX_VMUX_CABLE,
141 EM28XX_VMUX_DVB,
142 EM28XX_VMUX_DEBUG,
143 EM28XX_RADIO,
144};
145
146struct em28xx_input {
147 enum enum28xx_itype type;
148 unsigned int vmux;
149 unsigned int amux;
150};
151
152#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
153
154enum em28xx_decoder {
155 EM28XX_TVP5150,
156 EM28XX_SAA7113,
157 EM28XX_SAA7114
158};
159
160struct em28xx_board {
161 char *name;
162 int vchannels;
163 int norm;
164 int tuner_type;
165
166 /* i2c flags */
167 unsigned int is_em2800;
168 unsigned int tda9887_conf;
169
170 unsigned int has_tuner:1;
171 unsigned int has_msp34xx:1;
172
173 enum em28xx_decoder decoder;
174
175 struct em28xx_input input[MAX_EM28XX_INPUT];
176};
177
178struct em28xx_eeprom {
179 u32 id; /* 0x9567eb1a */
180 u16 vendor_ID;
181 u16 product_ID;
182
183 u16 chip_conf;
184
185 u16 board_conf;
186
187 u16 string1, string2, string3;
188
189 u8 string_idx_table;
190};
191
192/* device states */
193enum em28xx_dev_state {
194 DEV_INITIALIZED = 0x01,
195 DEV_DISCONNECTED = 0x02,
196 DEV_MISCONFIGURED = 0x04,
197};
198
199/* tvnorms */
200struct em28xx_tvnorm {
201 char *name;
202 v4l2_std_id id;
203 /* mode for saa7113h */
204 int mode;
205};
206
207/* main device struct */
208struct em28xx {
209 /* generic device properties */
210 char name[30]; /* name (including minor) of the device */
211 int model; /* index in the device_data struct */
212 unsigned int is_em2800;
213 int video_inputs; /* number of video inputs */
214 struct list_head devlist;
215 unsigned int has_tuner:1;
216 unsigned int has_msp34xx:1;
217 unsigned int has_tda9887:1;
218
219 enum em28xx_decoder decoder;
220
221 int tuner_type; /* type of the tuner */
222 int tuner_addr; /* tuner address */
223 int tda9887_conf;
224 /* i2c i/o */
225 struct i2c_adapter i2c_adap;
226 struct i2c_client i2c_client;
227 /* video for linux */
228 int users; /* user count for exclusive use */
229 struct video_device *vdev; /* video for linux device struct */
230 struct video_picture vpic; /* picture settings only used to init saa7113h */
231 struct em28xx_tvnorm *tvnorm; /* selected tv norm */
232 int ctl_freq; /* selected frequency */
233 unsigned int ctl_input; /* selected input */
234 unsigned int ctl_ainput; /* slected audio input */
235 int mute;
236 int volume;
237 /* frame properties */
238 struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
239 int num_frames; /* number of frames currently in use */
240 unsigned int frame_count; /* total number of transfered frames */
241 struct em28xx_frame_t *frame_current; /* the frame that is being filled */
242 int width; /* current frame width */
243 int height; /* current frame height */
244 int frame_size; /* current frame size */
245 int field_size; /* current field size */
246 int bytesperline;
247 int hscale; /* horizontal scale factor (see datasheet) */
248 int vscale; /* vertical scale factor (see datasheet) */
249 int interlaced; /* 1=interlace fileds, 0=just top fileds */
250 int type;
251
252 /* states */
253 enum em28xx_dev_state state;
254 enum em28xx_stream_state stream;
255 enum em28xx_io_method io;
256 /* locks */
257 struct semaphore lock, fileop_lock;
258 spinlock_t queue_lock;
259 struct list_head inqueue, outqueue;
260 wait_queue_head_t open, wait_frame, wait_stream;
261 struct video_device *vbi_dev;
262
263 unsigned char eedata[256];
264
265 /* usb transfer */
266 struct usb_device *udev; /* the usb device */
267 int alt; /* alternate */
268 int max_pkt_size; /* max packet size of isoc transaction */
269 int num_alt; /* Number of alternative settings */
270 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
271 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
272 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
273 /* helper funcs that call usb_control_msg */
274 int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf,
275 int len);
276 int (*em28xx_read_reg) (struct em28xx * dev, u16 reg);
277 int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg,
278 char *buf, int len);
279 int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg,
280 char *buf, int len);
281 int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
282};
283
284/* Provided by em28xx-i2c.c */
285
286void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
287int em28xx_i2c_register(struct em28xx *dev);
288int em28xx_i2c_unregister(struct em28xx *dev);
289
290/* Provided by em28xx-input.c */
291
292void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
293
294/* Provided by em28xx-core.c */
295
296void em28xx_print_ioctl(char *name, unsigned int cmd);
297
298u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
299void em28xx_queue_unusedframes(struct em28xx *dev);
300void em28xx_release_buffers(struct em28xx *dev);
301
302int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
303 char *buf, int len);
304int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
305int em28xx_read_reg(struct em28xx *dev, u16 reg);
306int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
307 int len);
308int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
309int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
310 u8 bitmask);
311int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
312int em28xx_audio_analog_set(struct em28xx *dev);
313int em28xx_colorlevels_set_default(struct em28xx *dev);
314int em28xx_capture_start(struct em28xx *dev, int start);
315int em28xx_outfmt_set_yuv422(struct em28xx *dev);
316int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
317 u8 ymax);
318int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
319 u16 width, u16 height);
320int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
321int em28xx_resolution_set(struct em28xx *dev);
322void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
323int em28xx_init_isoc(struct em28xx *dev);
324void em28xx_uninit_isoc(struct em28xx *dev);
325int em28xx_set_alternate(struct em28xx *dev);
326
327/* Provided by em28xx-cards.c */
328extern int em2800_variant_detect(struct usb_device* udev,int model);
329extern void em28xx_card_setup(struct em28xx *dev);
330extern struct em28xx_board em28xx_boards[];
331extern struct usb_device_id em28xx_id_table[];
332extern const unsigned int em28xx_bcount;
333
334/* em28xx registers */
335#define CHIPID_REG 0x0a
336#define USBSUSP_REG 0x0c /* */
337
338#define AUDIOSRC_REG 0x0e
339#define XCLK_REG 0x0f
340
341#define VINMODE_REG 0x10
342#define VINCTRL_REG 0x11
343#define VINENABLE_REG 0x12 /* */
344
345#define GAMMA_REG 0x14
346#define RGAIN_REG 0x15
347#define GGAIN_REG 0x16
348#define BGAIN_REG 0x17
349#define ROFFSET_REG 0x18
350#define GOFFSET_REG 0x19
351#define BOFFSET_REG 0x1a
352
353#define OFLOW_REG 0x1b
354#define HSTART_REG 0x1c
355#define VSTART_REG 0x1d
356#define CWIDTH_REG 0x1e
357#define CHEIGHT_REG 0x1f
358
359#define YGAIN_REG 0x20
360#define YOFFSET_REG 0x21
361#define UVGAIN_REG 0x22
362#define UOFFSET_REG 0x23
363#define VOFFSET_REG 0x24
364#define SHARPNESS_REG 0x25
365
366#define COMPR_REG 0x26
367#define OUTFMT_REG 0x27
368
369#define XMIN_REG 0x28
370#define XMAX_REG 0x29
371#define YMIN_REG 0x2a
372#define YMAX_REG 0x2b
373
374#define HSCALELOW_REG 0x30
375#define HSCALEHIGH_REG 0x31
376#define VSCALELOW_REG 0x32
377#define VSCALEHIGH_REG 0x33
378
379#define AC97LSB_REG 0x40
380#define AC97MSB_REG 0x41
381#define AC97ADDR_REG 0x42
382#define AC97BUSY_REG 0x43
383
384/* em202 registers */
385#define MASTER_AC97 0x02
386#define VIDEO_AC97 0x14
387
388/* register settings */
389#define EM28XX_AUDIO_SRC_TUNER 0xc0
390#define EM28XX_AUDIO_SRC_LINE 0x80
391
392/* printk macros */
393
394#define em28xx_err(fmt, arg...) do {\
395 printk(KERN_ERR fmt , ##arg); } while (0)
396
397#define em28xx_errdev(fmt, arg...) do {\
398 printk(KERN_ERR "%s: "fmt,\
399 dev->name , ##arg); } while (0)
400
401#define em28xx_info(fmt, arg...) do {\
402 printk(KERN_INFO "%s: "fmt,\
403 dev->name , ##arg); } while (0)
404#define em28xx_warn(fmt, arg...) do {\
405 printk(KERN_WARNING "%s: "fmt,\
406 dev->name , ##arg); } while (0)
407
408inline static int em28xx_audio_source(struct em28xx *dev, int input)
409{
410 return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
411}
412
413inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
414{
415 return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
416}
417
418inline static int em28xx_audio_analog_setup(struct em28xx *dev)
419{
420 /* unmute video mixer with default volume level */
421 return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
422}
423
424inline static int em28xx_compression_disable(struct em28xx *dev)
425{
426 /* side effect of disabling scaler and mixer */
427 return em28xx_write_regs(dev, COMPR_REG, "\x00", 1);
428}
429
430inline static int em28xx_contrast_get(struct em28xx *dev)
431{
432 return em28xx_read_reg(dev, YGAIN_REG) & 0x1f;
433}
434
435inline static int em28xx_brightness_get(struct em28xx *dev)
436{
437 return em28xx_read_reg(dev, YOFFSET_REG);
438}
439
440inline static int em28xx_saturation_get(struct em28xx *dev)
441{
442 return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f;
443}
444
445inline static int em28xx_u_balance_get(struct em28xx *dev)
446{
447 return em28xx_read_reg(dev, UOFFSET_REG);
448}
449
450inline static int em28xx_v_balance_get(struct em28xx *dev)
451{
452 return em28xx_read_reg(dev, VOFFSET_REG);
453}
454
455inline static int em28xx_gamma_get(struct em28xx *dev)
456{
457 return em28xx_read_reg(dev, GAMMA_REG) & 0x3f;
458}
459
460inline static int em28xx_contrast_set(struct em28xx *dev, s32 val)
461{
462 u8 tmp = (u8) val;
463 return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1);
464}
465
466inline static int em28xx_brightness_set(struct em28xx *dev, s32 val)
467{
468 u8 tmp = (u8) val;
469 return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1);
470}
471
472inline static int em28xx_saturation_set(struct em28xx *dev, s32 val)
473{
474 u8 tmp = (u8) val;
475 return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1);
476}
477
478inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val)
479{
480 u8 tmp = (u8) val;
481 return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1);
482}
483
484inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val)
485{
486 u8 tmp = (u8) val;
487 return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1);
488}
489
490inline static int em28xx_gamma_set(struct em28xx *dev, s32 val)
491{
492 u8 tmp = (u8) val;
493 return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1);
494}
495
496/*FIXME: maxw should be dependent of alt mode */
497inline static unsigned int norm_maxw(struct em28xx *dev)
498{
499 switch(dev->model){
500 case (EM2820_BOARD_MSI_VOX_USB_2): return(640);
501 default: return(720);
502 }
503}
504
505inline static unsigned int norm_maxh(struct em28xx *dev)
506{
507 switch(dev->model){
508 case (EM2820_BOARD_MSI_VOX_USB_2): return(480);
509 default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480;
510 }
511}
512
513#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index 234151e48edc..ed81934ef3cd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -156,6 +156,71 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
156 156
157/* ---------------------------------------------------------------------- */ 157/* ---------------------------------------------------------------------- */
158 158
159/* Ricardo Cerqueira <v4l@cerqueira.org> */
160/* Weird matching, since the remote has "uncommon" keys */
161
162static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
163
164 [ 30 ] = KEY_POWER, // power
165 [ 7 ] = KEY_MEDIA, // source
166 [ 28 ] = KEY_SEARCH, // scan
167
168/* FIXME: duplicate keycodes?
169 *
170 * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
171 * The GPIO values are
172 * 6397fb for both "Scan <" and "CH -",
173 * 639ffb for "Scan >" and "CH+",
174 * 6384fb for "Tune <" and "<<<",
175 * 638cfb for "Tune >" and ">>>", regardless of the mask.
176 *
177 * [ 23 ] = KEY_BACK, // fm scan <<
178 * [ 31 ] = KEY_FORWARD, // fm scan >>
179 *
180 * [ 4 ] = KEY_LEFT, // fm tuning <
181 * [ 12 ] = KEY_RIGHT, // fm tuning >
182 *
183 * For now, these four keys are disabled. Pressing them will generate
184 * the CH+/CH-/<<</>>> events
185 */
186
187 [ 3 ] = KEY_TUNER, // TV/FM
188
189 [ 0 ] = KEY_RECORD,
190 [ 8 ] = KEY_STOP,
191 [ 17 ] = KEY_PLAY,
192
193 [ 26 ] = KEY_PLAYPAUSE, // freeze
194 [ 25 ] = KEY_ZOOM, // zoom
195 [ 15 ] = KEY_TEXT, // min
196
197 [ 1 ] = KEY_KP1,
198 [ 11 ] = KEY_KP2,
199 [ 27 ] = KEY_KP3,
200 [ 5 ] = KEY_KP4,
201 [ 9 ] = KEY_KP5,
202 [ 21 ] = KEY_KP6,
203 [ 6 ] = KEY_KP7,
204 [ 10 ] = KEY_KP8,
205 [ 18 ] = KEY_KP9,
206 [ 2 ] = KEY_KP0,
207 [ 16 ] = KEY_LAST, // +100
208 [ 19 ] = KEY_LIST, // recall
209
210 [ 31 ] = KEY_CHANNELUP, // chn down
211 [ 23 ] = KEY_CHANNELDOWN, // chn up
212 [ 22 ] = KEY_VOLUMEUP, // vol down
213 [ 20 ] = KEY_VOLUMEDOWN, // vol up
214
215 [ 4 ] = KEY_KPMINUS, // <<<
216 [ 14 ] = KEY_SETUP, // function
217 [ 12 ] = KEY_KPPLUS, // >>>
218
219 [ 13 ] = KEY_GOTO, // mts
220 [ 29 ] = KEY_REFRESH, // reset
221 [ 24 ] = KEY_MUTE // mute/unmute
222};
223
159struct IR { 224struct IR {
160 struct bttv_sub_device *sub; 225 struct bttv_sub_device *sub;
161 struct input_dev *input; 226 struct input_dev *input;
@@ -282,53 +347,59 @@ static int ir_probe(struct device *dev)
282 347
283 /* detect & configure */ 348 /* detect & configure */
284 switch (sub->core->type) { 349 switch (sub->core->type) {
285 case BTTV_AVERMEDIA: 350 case BTTV_BOARD_AVERMEDIA:
286 case BTTV_AVPHONE98: 351 case BTTV_BOARD_AVPHONE98:
287 case BTTV_AVERMEDIA98: 352 case BTTV_BOARD_AVERMEDIA98:
288 ir_codes = ir_codes_avermedia; 353 ir_codes = ir_codes_avermedia;
289 ir->mask_keycode = 0xf88000; 354 ir->mask_keycode = 0xf88000;
290 ir->mask_keydown = 0x010000; 355 ir->mask_keydown = 0x010000;
291 ir->polling = 50; // ms 356 ir->polling = 50; // ms
292 break; 357 break;
293 358
294 case BTTV_AVDVBT_761: 359 case BTTV_BOARD_AVDVBT_761:
295 case BTTV_AVDVBT_771: 360 case BTTV_BOARD_AVDVBT_771:
296 ir_codes = ir_codes_avermedia_dvbt; 361 ir_codes = ir_codes_avermedia_dvbt;
297 ir->mask_keycode = 0x0f00c0; 362 ir->mask_keycode = 0x0f00c0;
298 ir->mask_keydown = 0x000020; 363 ir->mask_keydown = 0x000020;
299 ir->polling = 50; // ms 364 ir->polling = 50; // ms
300 break; 365 break;
301 366
302 case BTTV_PXELVWPLTVPAK: 367 case BTTV_BOARD_PXELVWPLTVPAK:
303 ir_codes = ir_codes_pixelview; 368 ir_codes = ir_codes_pixelview;
304 ir->mask_keycode = 0x003e00; 369 ir->mask_keycode = 0x003e00;
305 ir->mask_keyup = 0x010000; 370 ir->mask_keyup = 0x010000;
306 ir->polling = 50; // ms 371 ir->polling = 50; // ms
307 break; 372 break;
308 case BTTV_PV_BT878P_9B: 373 case BTTV_BOARD_PV_BT878P_9B:
309 case BTTV_PV_BT878P_PLUS: 374 case BTTV_BOARD_PV_BT878P_PLUS:
310 ir_codes = ir_codes_pixelview; 375 ir_codes = ir_codes_pixelview;
311 ir->mask_keycode = 0x001f00; 376 ir->mask_keycode = 0x001f00;
312 ir->mask_keyup = 0x008000; 377 ir->mask_keyup = 0x008000;
313 ir->polling = 50; // ms 378 ir->polling = 50; // ms
314 break; 379 break;
315 380
316 case BTTV_WINFAST2000: 381 case BTTV_BOARD_WINFAST2000:
317 ir_codes = ir_codes_winfast; 382 ir_codes = ir_codes_winfast;
318 ir->mask_keycode = 0x1f8; 383 ir->mask_keycode = 0x1f8;
319 break; 384 break;
320 case BTTV_MAGICTVIEW061: 385 case BTTV_BOARD_MAGICTVIEW061:
321 case BTTV_MAGICTVIEW063: 386 case BTTV_BOARD_MAGICTVIEW063:
322 ir_codes = ir_codes_winfast; 387 ir_codes = ir_codes_winfast;
323 ir->mask_keycode = 0x0008e000; 388 ir->mask_keycode = 0x0008e000;
324 ir->mask_keydown = 0x00200000; 389 ir->mask_keydown = 0x00200000;
325 break; 390 break;
326 case BTTV_APAC_VIEWCOMP: 391 case BTTV_BOARD_APAC_VIEWCOMP:
327 ir_codes = ir_codes_apac_viewcomp; 392 ir_codes = ir_codes_apac_viewcomp;
328 ir->mask_keycode = 0x001f00; 393 ir->mask_keycode = 0x001f00;
329 ir->mask_keyup = 0x008000; 394 ir->mask_keyup = 0x008000;
330 ir->polling = 50; // ms 395 ir->polling = 50; // ms
331 break; 396 break;
397 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
398 ir_codes = ir_codes_conceptronic;
399 ir->mask_keycode = 0x001F00;
400 ir->mask_keyup = 0x006000;
401 ir->polling = 50; // ms
402 break;
332 } 403 }
333 if (NULL == ir_codes) { 404 if (NULL == ir_codes) {
334 kfree(ir); 405 kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 9703d3d351f9..0085567a1421 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -8,6 +8,8 @@
8 * Christoph Bartelmus <lirc@bartelmus.de> 8 * Christoph Bartelmus <lirc@bartelmus.de>
9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by 9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
10 * Ulrich Mueller <ulrich.mueller42@web.de> 10 * Ulrich Mueller <ulrich.mueller42@web.de>
11 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -37,10 +39,9 @@
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/i2c.h> 40#include <linux/i2c.h>
39#include <linux/workqueue.h> 41#include <linux/workqueue.h>
40
41#include <asm/semaphore.h> 42#include <asm/semaphore.h>
42
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44#include <media/ir-kbd-i2c.h>
44 45
45/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
46static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
81 [ 28 ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
82}; 83};
83 84
84static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
85 [ 0x3 ] = KEY_POWER,
86 [ 0x6f ] = KEY_MUTE,
87 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
88
89 [ 0x11 ] = KEY_KP0,
90 [ 0x4 ] = KEY_KP1,
91 [ 0x5 ] = KEY_KP2,
92 [ 0x6 ] = KEY_KP3,
93 [ 0x8 ] = KEY_KP4,
94 [ 0x9 ] = KEY_KP5,
95 [ 0xa ] = KEY_KP6,
96 [ 0xc ] = KEY_KP7,
97 [ 0xd ] = KEY_KP8,
98 [ 0xe ] = KEY_KP9,
99 [ 0x12 ] = KEY_KPDOT, /* 100+ */
100
101 [ 0x7 ] = KEY_VOLUMEUP,
102 [ 0xb ] = KEY_VOLUMEDOWN,
103 [ 0x1a ] = KEY_KPPLUS,
104 [ 0x18 ] = KEY_KPMINUS,
105 [ 0x15 ] = KEY_UP,
106 [ 0x1d ] = KEY_DOWN,
107 [ 0xf ] = KEY_CHANNELUP,
108 [ 0x13 ] = KEY_CHANNELDOWN,
109 [ 0x48 ] = KEY_ZOOM,
110
111 [ 0x1b ] = KEY_VIDEO, /* Video source */
112 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
113 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
114
115 [ 0x4b ] = KEY_RECORD,
116 [ 0x46 ] = KEY_PLAY,
117 [ 0x45 ] = KEY_PAUSE, /* Pause */
118 [ 0x44 ] = KEY_STOP,
119 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
120 [ 0x42 ] = KEY_REWIND, /* Backward ? */
121
122};
123
124struct IR {
125 struct i2c_client c;
126 struct input_dev *input;
127 struct ir_input_state ir;
128
129 struct work_struct work;
130 struct timer_list timer;
131 char phys[32];
132 int (*get_key)(struct IR*, u32*, u32*);
133};
134
135/* ----------------------------------------------------------------------- */ 85/* ----------------------------------------------------------------------- */
136/* insmod parameters */ 86/* insmod parameters */
137 87
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
144 94
145/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
146 96
147static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 97static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
148{ 98{
149 unsigned char buf[3]; 99 unsigned char buf[3];
150 int start, toggle, dev, code; 100 int start, toggle, dev, code;
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
171 return 1; 121 return 1;
172} 122}
173 123
174static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 124static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
175{ 125{
176 unsigned char b; 126 unsigned char b;
177 127
178 /* poll IR chip */ 128 /* poll IR chip */
179 if (1 != i2c_master_recv(&ir->c,&b,1)) { 129 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
185 return 1; 135 return 1;
186} 136}
187 137
188static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 138static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
189{ 139{
190 unsigned char b; 140 unsigned char b;
191 141
192 /* poll IR chip */ 142 /* poll IR chip */
193 if (1 != i2c_master_recv(&ir->c,&b,1)) { 143 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 155 return 1;
206} 156}
207 157
208static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 158static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 159{
210 unsigned char b; 160 unsigned char b;
211 161
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
216 } 166 }
217 167
218 /* it seems that 0xFE indicates that a button is still hold 168 /* it seems that 0xFE indicates that a button is still hold
219 down, while 0xFF indicates that no button is hold 169 down, while 0xff indicates that no button is hold
220 down. 0xFE sequences are sometimes interrupted by 0xFF */ 170 down. 0xfe sequences are sometimes interrupted by 0xFF */
221 171
222 dprintk(2,"key %02x\n", b); 172 dprintk(2,"key %02x\n", b);
223 173
224 if (b == 0xFF) 174 if (b == 0xff)
225 return 0; 175 return 0;
226 176
227 if (b == 0xFE) 177 if (b == 0xfe)
228 /* keep old data */ 178 /* keep old data */
229 return 1; 179 return 1;
230 180
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
233 return 1; 183 return 1;
234} 184}
235 185
236static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
237{
238 unsigned char b;
239
240 /* poll IR chip */
241 if (1 != i2c_master_recv(&ir->c,&b,1)) {
242 dprintk(1,"read error\n");
243 return -EIO;
244 }
245
246 /* no button press */
247 if (b==0)
248 return 0;
249
250 /* repeating */
251 if (b & 0x80)
252 return 1;
253
254 *ir_key = b;
255 *ir_raw = b;
256 return 1;
257}
258/* ----------------------------------------------------------------------- */ 186/* ----------------------------------------------------------------------- */
259 187
260static void ir_key_poll(struct IR *ir) 188static void ir_key_poll(struct IR_i2c *ir)
261{ 189{
262 static u32 ir_key, ir_raw; 190 static u32 ir_key, ir_raw;
263 int rc; 191 int rc;
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir)
278 206
279static void ir_timer(unsigned long data) 207static void ir_timer(unsigned long data)
280{ 208{
281 struct IR *ir = (struct IR*)data; 209 struct IR_i2c *ir = (struct IR_i2c*)data;
282 schedule_work(&ir->work); 210 schedule_work(&ir->work);
283} 211}
284 212
285static void ir_work(void *data) 213static void ir_work(void *data)
286{ 214{
287 struct IR *ir = data; 215 struct IR_i2c *ir = data;
288 ir_key_poll(ir); 216 ir_key_poll(ir);
289 mod_timer(&ir->timer, jiffies+HZ/10); 217 mod_timer(&ir->timer, jiffies+HZ/10);
290} 218}
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client);
297static int ir_probe(struct i2c_adapter *adap); 225static int ir_probe(struct i2c_adapter *adap);
298 226
299static struct i2c_driver driver = { 227static struct i2c_driver driver = {
300 .name = "ir remote kbd driver", 228 .name = "ir remote kbd driver",
301 .id = I2C_DRIVERID_EXP3, /* FIXME */ 229 .id = I2C_DRIVERID_EXP3, /* FIXME */
302 .flags = I2C_DF_NOTIFY, 230 .flags = I2C_DF_NOTIFY,
303 .attach_adapter = ir_probe, 231 .attach_adapter = ir_probe,
304 .detach_client = ir_detach, 232 .detach_client = ir_detach,
305}; 233};
306 234
307static struct i2c_client client_template = 235static struct i2c_client client_template =
308{ 236{
309 .name = "unset", 237 .name = "unset",
310 .driver = &driver 238 .driver = &driver
311}; 239};
312 240
313static int ir_attach(struct i2c_adapter *adap, int addr, 241static int ir_attach(struct i2c_adapter *adap, int addr,
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
316 IR_KEYTAB_TYPE *ir_codes = NULL; 244 IR_KEYTAB_TYPE *ir_codes = NULL;
317 char *name; 245 char *name;
318 int ir_type; 246 int ir_type;
319 struct IR *ir; 247 struct IR_i2c *ir;
320 struct input_dev *input_dev; 248 struct input_dev *input_dev;
321 249
322 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 250 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
323 input_dev = input_allocate_device(); 251 input_dev = input_allocate_device();
324 if (!ir || !input_dev) { 252 if (!ir || !input_dev) {
325 kfree(ir); 253 kfree(ir);
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
361 ir_codes = ir_codes_empty; 289 ir_codes = ir_codes_empty;
362 break; 290 break;
363 case 0x7a: 291 case 0x7a:
364 name = "Purple TV"; 292 case 0x47:
365 ir->get_key = get_key_purpletv; 293 /* Handled by saa7134-input */
294 name = "SAA713x remote";
366 ir_type = IR_TYPE_OTHER; 295 ir_type = IR_TYPE_OTHER;
367 ir_codes = ir_codes_purpletv;
368 break; 296 break;
369 default: 297 default:
370 /* shouldn't happen */ 298 /* shouldn't happen */
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
373 return -1; 301 return -1;
374 } 302 }
375 303
376 /* register i2c device */ 304 /* Sets name */
377 i2c_attach_client(&ir->c);
378 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 305 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
306 ir->ir_codes=ir_codes;
307
308 /* register i2c device
309 * At device register, IR codes may be changed to be
310 * board dependent.
311 */
312 i2c_attach_client(&ir->c);
313
314 /* If IR not supported or disabled, unregisters driver */
315 if (ir->get_key == NULL) {
316 i2c_detach_client(&ir->c);
317 kfree(ir);
318 return -1;
319 }
320
321 /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
379 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 322 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
380 ir->c.adapter->dev.bus_id, 323 ir->c.adapter->dev.bus_id,
381 ir->c.dev.bus_id); 324 ir->c.dev.bus_id);
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
386 input_dev->name = ir->c.name; 329 input_dev->name = ir->c.name;
387 input_dev->phys = ir->phys; 330 input_dev->phys = ir->phys;
388 331
332 /* register event device */
389 input_register_device(ir->input); 333 input_register_device(ir->input);
390 334
391 /* start polling via eventd */ 335 /* start polling via eventd */
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
400 344
401static int ir_detach(struct i2c_client *client) 345static int ir_detach(struct i2c_client *client)
402{ 346{
403 struct IR *ir = i2c_get_clientdata(client); 347 struct IR_i2c *ir = i2c_get_clientdata(client);
404 348
405 /* kill outstanding polls */ 349 /* kill outstanding polls */
406 del_timer(&ir->timer); 350 del_timer(&ir->timer);
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap)
428 */ 372 */
429 373
430 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 374 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
431 static const int probe_saa7134[] = { 0x7a, -1 }; 375 static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
376 static const int probe_em28XX[] = { 0x30, 0x47, -1 };
432 const int *probe = NULL; 377 const int *probe = NULL;
433 struct i2c_client c; char buf; int i,rc; 378 struct i2c_client c;
379 unsigned char buf;
380 int i,rc;
434 381
435 switch (adap->id) { 382 switch (adap->id) {
436 case I2C_HW_B_BT848: 383 case I2C_HW_B_BT848:
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap)
439 case I2C_HW_SAA7134: 386 case I2C_HW_SAA7134:
440 probe = probe_saa7134; 387 probe = probe_saa7134;
441 break; 388 break;
389 case I2C_HW_B_EM28XX:
390 probe = probe_em28XX;
391 break;
442 } 392 }
443 if (NULL == probe) 393 if (NULL == probe)
444 return 0; 394 return 0;
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap)
447 c.adapter = adap; 397 c.adapter = adap;
448 for (i = 0; -1 != probe[i]; i++) { 398 for (i = 0; -1 != probe[i]; i++) {
449 c.addr = probe[i]; 399 c.addr = probe[i];
450 rc = i2c_master_recv(&c,&buf,1); 400 rc = i2c_master_recv(&c,&buf,0);
451 dprintk(1,"probe 0x%02x @ %s: %s\n", 401 dprintk(1,"probe 0x%02x @ %s: %s\n",
452 probe[i], adap->name, 402 probe[i], adap->name,
453 (1 == rc) ? "yes" : "no"); 403 (0 == rc) ? "yes" : "no");
454 if (1 == rc) { 404 if (0 == rc) {
455 ir_attach(adap,probe[i],0,0); 405 ir_attach(adap,probe[i],0,0);
456 break; 406 break;
457 } 407 }
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index e75e7948fd9d..a23fb0338986 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -54,9 +54,41 @@
54#include <asm/pgtable.h> 54#include <asm/pgtable.h>
55 55
56#include <media/audiochip.h> 56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h" 57#include "msp3400.h"
59 58
59#define msp3400_dbg(fmt, arg...) \
60 do { \
61 if (debug) \
62 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
63 i2c_adapter_id(client->adapter), client->addr , ## arg); \
64 } while (0)
65
66/* Medium volume debug. */
67#define msp3400_dbg_mediumvol(fmt, arg...) \
68 do { \
69 if (debug >= 2) \
70 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
71 i2c_adapter_id(client->adapter), client->addr , ## arg); \
72 } while (0)
73
74/* High volume debug. Use with care. */
75#define msp3400_dbg_highvol(fmt, arg...) \
76 do { \
77 if (debug >= 16) \
78 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
79 i2c_adapter_id(client->adapter), client->addr , ## arg); \
80 } while (0)
81
82#define msp3400_err(fmt, arg...) do { \
83 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
84 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
85#define msp3400_warn(fmt, arg...) do { \
86 printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
87 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
88#define msp3400_info(fmt, arg...) do { \
89 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
90 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
91
60#define OPMODE_AUTO -1 92#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0 93#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ 94#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
@@ -73,15 +105,26 @@ static int dolby = 0;
73 105
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual 106static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */ 107 (msp34xxg only) 0x00a0-0x03c0 */
108#define DFP_COUNT 0x41
109static const int bl_dfp[] = {
110 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
111 0x0b, 0x0d, 0x0e, 0x10
112};
113
114#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
76 115
77struct msp3400c { 116struct msp3400c {
78 int rev1,rev2; 117 int rev1,rev2;
79 118
80 int opmode; 119 int opmode;
120 int nicam;
81 int mode; 121 int mode;
82 int norm; 122 int norm;
123 int stereo;
83 int nicam_on; 124 int nicam_on;
84 int acb; 125 int acb;
126 int in_scart;
127 int i2s_mode;
85 int main, second; /* sound carrier */ 128 int main, second; /* sound carrier */
86 int input; 129 int input;
87 int source; /* see msp34xxg_set_source */ 130 int source; /* see msp34xxg_set_source */
@@ -91,9 +134,12 @@ struct msp3400c {
91 int rxsubchans; 134 int rxsubchans;
92 135
93 int muted; 136 int muted;
94 int volume, balance; 137 int left, right; /* volume */
95 int bass, treble; 138 int bass, treble;
96 139
140 /* shadow register set */
141 int dfp_regs[DFP_COUNT];
142
97 /* thread */ 143 /* thread */
98 struct task_struct *kthread; 144 struct task_struct *kthread;
99 wait_queue_head_t wq; 145 wait_queue_head_t wq;
@@ -101,6 +147,8 @@ struct msp3400c {
101 int watch_stereo:1; 147 int watch_stereo:1;
102}; 148};
103 149
150#define MIN(a,b) (((a)>(b))?(b):(a))
151#define MAX(a,b) (((a)>(b))?(a):(b))
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) 152#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') 153#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') 154#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
@@ -110,9 +158,6 @@ struct msp3400c {
110 158
111/* ---------------------------------------------------------------------- */ 159/* ---------------------------------------------------------------------- */
112 160
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */ 161/* read-only */
117module_param(opmode, int, 0444); 162module_param(opmode, int, 0444);
118 163
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau
132MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); 177MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
133MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); 178MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
134 179
135
136MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
137MODULE_AUTHOR("Gerd Knorr");
138MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
139
140/* ---------------------------------------------------------------------- */ 180/* ---------------------------------------------------------------------- */
141 181
142#define I2C_MSP3400C 0x80 182#define I2C_MSP3400C 0x80
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = {
153}; 193};
154I2C_CLIENT_INSMOD; 194I2C_CLIENT_INSMOD;
155 195
196MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
197MODULE_AUTHOR("Gerd Knorr");
198MODULE_LICENSE("GPL");
199
156/* ----------------------------------------------------------------------- */ 200/* ----------------------------------------------------------------------- */
157/* functions for talking to the MSP3400C Sound processor */ 201/* functions for talking to the MSP3400C Sound processor */
158 202
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client)
172 { client->addr, I2C_M_RD, 2, read }, 216 { client->addr, I2C_M_RD, 2, read },
173 }; 217 };
174 218
219 msp3400_dbg_highvol("msp3400c_reset\n");
175 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || 220 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
176 (1 != i2c_transfer(client->adapter,&reset[1],1)) || 221 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
177 (2 != i2c_transfer(client->adapter,test,2)) ) { 222 (2 != i2c_transfer(client->adapter,test,2)) ) {
178 printk(KERN_ERR "msp3400: chip reset failed\n"); 223 msp3400_err("chip reset failed\n");
179 return -1; 224 return -1;
180 } 225 }
181 return 0; 226 return 0;
182} 227}
183 228
184static int 229static int msp3400c_read(struct i2c_client *client, int dev, int addr)
185msp3400c_read(struct i2c_client *client, int dev, int addr)
186{ 230{
187 int err; 231 int err,retval;
232
233 unsigned char write[3];
234 unsigned char read[2];
235 struct i2c_msg msgs[2] = {
236 { client->addr, 0, 3, write },
237 { client->addr, I2C_M_RD, 2, read }
238 };
188 239
189 unsigned char write[3]; 240 write[0] = dev+1;
190 unsigned char read[2]; 241 write[1] = addr >> 8;
191 struct i2c_msg msgs[2] = { 242 write[2] = addr & 0xff;
192 { client->addr, 0, 3, write },
193 { client->addr, I2C_M_RD, 2, read }
194 };
195 write[0] = dev+1;
196 write[1] = addr >> 8;
197 write[2] = addr & 0xff;
198 243
199 for (err = 0; err < 3;) { 244 for (err = 0; err < 3;) {
200 if (2 == i2c_transfer(client->adapter,msgs,2)) 245 if (2 == i2c_transfer(client->adapter,msgs,2))
201 break; 246 break;
202 err++; 247 err++;
203 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", 248 msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
204 err, dev, addr); 249 dev, addr);
205 msleep(10); 250 current->state = TASK_INTERRUPTIBLE;
251 schedule_timeout(msecs_to_jiffies(10));
206 } 252 }
207 if (3 == err) { 253 if (3 == err) {
208 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 254 msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
209 msp3400c_reset(client); 255 msp3400c_reset(client);
210 return -1; 256 return -1;
211 } 257 }
212 return read[0] << 8 | read[1]; 258 retval = read[0] << 8 | read[1];
259 msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
260 return retval;
213} 261}
214 262
215static int 263static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
216msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
217{ 264{
218 int err; 265 int err;
219 unsigned char buffer[5]; 266 unsigned char buffer[5];
220 267
221 buffer[0] = dev; 268 buffer[0] = dev;
222 buffer[1] = addr >> 8; 269 buffer[1] = addr >> 8;
223 buffer[2] = addr & 0xff; 270 buffer[2] = addr & 0xff;
224 buffer[3] = val >> 8; 271 buffer[3] = val >> 8;
225 buffer[4] = val & 0xff; 272 buffer[4] = val & 0xff;
226 273
274 msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
227 for (err = 0; err < 3;) { 275 for (err = 0; err < 3;) {
228 if (5 == i2c_master_send(client, buffer, 5)) 276 if (5 == i2c_master_send(client, buffer, 5))
229 break; 277 break;
230 err++; 278 err++;
231 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", 279 msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
232 err, dev, addr); 280 dev, addr);
233 msleep(10); 281 current->state = TASK_INTERRUPTIBLE;
282 schedule_timeout(msecs_to_jiffies(10));
234 } 283 }
235 if (3 == err) { 284 if (3 == err) {
236 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 285 msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
237 msp3400c_reset(client); 286 msp3400c_reset(client);
238 return -1; 287 return -1;
239 } 288 }
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM {
266 int dfp_src; 315 int dfp_src;
267 int dfp_matrix; 316 int dfp_matrix;
268} msp_init_data[] = { 317} msp_init_data[] = {
269 /* AM (for carrier detect / msp3400) */ 318 { /* AM (for carrier detect / msp3400) */
270 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, 319 {75, 19, 36, 35, 39, 40},
271 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 320 {75, 19, 36, 35, 39, 40},
272 0x00d0, 0x0500, 0x0020, 0x3000}, 321 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
273 322 0x00d0, 0x0500, 0x0020, 0x3000
274 /* AM (for carrier detect / msp3410) */ 323 },{ /* AM (for carrier detect / msp3410) */
275 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, 324 {-1, -1, -8, 2, 59, 126},
276 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 325 {-1, -1, -8, 2, 59, 126},
277 0x00d0, 0x0100, 0x0020, 0x3000}, 326 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
278 327 0x00d0, 0x0100, 0x0020, 0x3000
279 /* FM Radio */ 328 },{ /* FM Radio */
280 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, 329 {-8, -8, 4, 6, 78, 107},
281 MSP_CARRIER(10.7), MSP_CARRIER(10.7), 330 {-8, -8, 4, 6, 78, 107},
282 0x00d0, 0x0480, 0x0020, 0x3000 }, 331 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
283 332 0x00d0, 0x0480, 0x0020, 0x3000
284 /* Terrestial FM-mono + FM-stereo */ 333 },{ /* Terrestial FM-mono + FM-stereo */
285 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, 334 {3, 18, 27, 48, 66, 72},
286 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 335 {3, 18, 27, 48, 66, 72},
287 0x00d0, 0x0480, 0x0030, 0x3000}, 336 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
288 337 0x00d0, 0x0480, 0x0030, 0x3000
289 /* Sat FM-mono */ 338 },{ /* Sat FM-mono */
290 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, 339 { 1, 9, 14, 24, 33, 37},
291 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 340 { 3, 18, 27, 48, 66, 72},
292 0x00c6, 0x0480, 0x0000, 0x3000}, 341 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
293 342 0x00c6, 0x0480, 0x0000, 0x3000
294 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ 343 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
295 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, 344 {-2, -8, -10, 10, 50, 86},
296 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 345 {3, 18, 27, 48, 66, 72},
297 0x00d0, 0x0040, 0x0120, 0x3000}, 346 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
298 347 0x00d0, 0x0040, 0x0120, 0x3000
299 /* NICAM/FM -- I (6.0/6.552) */ 348 },{ /* NICAM/FM -- I (6.0/6.552) */
300 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, 349 {2, 4, -6, -4, 40, 94},
301 MSP_CARRIER(6.0), MSP_CARRIER(6.0), 350 {3, 18, 27, 48, 66, 72},
302 0x00d0, 0x0040, 0x0120, 0x3000}, 351 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
303 352 0x00d0, 0x0040, 0x0120, 0x3000
304 /* NICAM/AM -- L (6.5/5.85) */ 353 },{ /* NICAM/AM -- L (6.5/5.85) */
305 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, 354 {-2, -8, -10, 10, 50, 86},
306 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 355 {-4, -12, -9, 23, 79, 126},
307 0x00c6, 0x0140, 0x0120, 0x7c03}, 356 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
357 0x00c6, 0x0140, 0x0120, 0x7c03
358 },
308}; 359};
309 360
310struct CARRIER_DETECT { 361struct CARRIER_DETECT {
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
338 389
339#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) 390#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
340 391
341/* ----------------------------------------------------------------------- */ 392/* ----------------------------------------------------------------------- *
393 * bits 9 8 5 - SCART DSP input Select:
394 * 0 0 0 - SCART 1 to DSP input (reset position)
395 * 0 1 0 - MONO to DSP input
396 * 1 0 0 - SCART 2 to DSP input
397 * 1 1 1 - Mute DSP input
398 *
399 * bits 11 10 6 - SCART 1 Output Select:
400 * 0 0 0 - undefined (reset position)
401 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
402 * 1 0 0 - MONO input to SCART 1 Output
403 * 1 1 0 - SCART 1 DA to SCART 1 Output
404 * 0 0 1 - SCART 2 DA to SCART 1 Output
405 * 0 1 1 - SCART 1 Input to SCART 1 Output
406 * 1 1 1 - Mute SCART 1 Output
407 *
408 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
409 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
410 * 0 1 0 - SCART 1 Input to SCART 2 Output
411 * 1 0 0 - MONO input to SCART 2 Output
412 * 0 0 1 - SCART 2 DA to SCART 2 Output
413 * 0 1 1 - SCART 2 Input to SCART 2 Output
414 * 1 1 0 - Mute SCART 2 Output
415 *
416 * Bits 4 to 0 should be zero.
417 * ----------------------------------------------------------------------- */
342 418
343static int scarts[3][9] = { 419static int scarts[3][9] = {
344 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 420 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
345 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 421 /* SCART DSP Input select */
346 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 422 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
347 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 423 /* SCART1 Output select */
424 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
425 /* SCART2 Output select */
426 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
348}; 427};
349 428
350static char *scart_names[] = { 429static char *scart_names[] = {
351 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" 430 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
352}; 431};
353 432
354static void 433static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
355msp3400c_set_scart(struct i2c_client *client, int in, int out)
356{ 434{
357 struct msp3400c *msp = i2c_get_clientdata(client); 435 struct msp3400c *msp = i2c_get_clientdata(client);
358 436
359 if (-1 == scarts[out][in]) 437 msp->in_scart=in;
360 return; 438
439 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
440 if (-1 == scarts[out][in])
441 return;
361 442
362 dprintk(KERN_DEBUG 443 msp->acb &= ~scarts[out][SCART_MASK];
363 "msp34xx: scart switch: %s => %d\n",scart_names[in],out); 444 msp->acb |= scarts[out][in];
364 msp->acb &= ~scarts[out][SCART_MASK]; 445 } else
365 msp->acb |= scarts[out][in]; 446 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
366 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); 447
448 msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
449 scart_names[in], out, msp->acb);
450 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
451
452 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
453 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
367} 454}
368 455
369/* ------------------------------------------------------------------------ */ 456/* ------------------------------------------------------------------------ */
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
378} 465}
379 466
380static void msp3400c_setvolume(struct i2c_client *client, 467static void msp3400c_setvolume(struct i2c_client *client,
381 int muted, int volume, int balance) 468 int muted, int left, int right)
382{ 469 {
383 int val = 0, bal = 0; 470 int vol = 0, val = 0, balance = 0;
384 471
385 if (!muted) { 472 if (!muted) {
386 /* 0x7f instead if 0x73 here has sound quality issues, 473 /* 0x7f instead if 0x73 here has sound quality issues,
387 * probably due to overmodulation + clipping ... */ 474 * probably due to overmodulation + clipping ... */
388 val = (volume * 0x73 / 65535) << 8; 475 vol = (left > right) ? left : right;
476 val = (vol * 0x73 / 65535) << 8;
389 } 477 }
390 if (val) { 478 if (vol > 0) {
391 bal = (balance / 256) - 128; 479 balance = ((right - left) * 127) / vol;
392 } 480 }
393 dprintk(KERN_DEBUG 481
394 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", 482 msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
395 muted ? "on" : "off", volume, balance, val>>8, bal); 483 muted ? "on" : "off", left, right, val >> 8, balance);
396 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ 484 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
397 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ 485 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
398 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, 486 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
399 muted ? 0x01 : (val | 0x01)); 487 muted ? 0x1 : (val | 0x1));
400 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); 488 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
401} 489}
402 490
403static void msp3400c_setbass(struct i2c_client *client, int bass) 491static void msp3400c_setbass(struct i2c_client *client, int bass)
404{ 492{
405 int val = ((bass-32768) * 0x60 / 65535) << 8; 493 int val = ((bass-32768) * 0x60 / 65535) << 8;
406 494
407 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); 495 msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
408 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ 496 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
409} 497}
410 498
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
412{ 500{
413 int val = ((treble-32768) * 0x60 / 65535) << 8; 501 int val = ((treble-32768) * 0x60 / 65535) << 8;
414 502
415 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); 503 msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
416 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ 504 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
417} 505}
418 506
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
421 struct msp3400c *msp = i2c_get_clientdata(client); 509 struct msp3400c *msp = i2c_get_clientdata(client);
422 int i; 510 int i;
423 511
424 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); 512 msp3400_dbg("setmode: %d\n",type);
425 msp->mode = type; 513 msp->mode = type;
426 msp->audmode = V4L2_TUNER_MODE_MONO; 514 msp->audmode = V4L2_TUNER_MODE_MONO;
427 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 515 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
474 } 562 }
475} 563}
476 564
477static int best_audio_mode(int rxsubchans) 565/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
566static int best_video_sound(int rxsubchans)
478{ 567{
479 if (rxsubchans & V4L2_TUNER_SUB_STEREO) 568 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
480 return V4L2_TUNER_MODE_STEREO; 569 return V4L2_TUNER_MODE_STEREO;
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans)
486} 575}
487 576
488/* turn on/off nicam + stereo */ 577/* turn on/off nicam + stereo */
489static void msp3400c_set_audmode(struct i2c_client *client, int audmode) 578static void msp3400c_setstereo(struct i2c_client *client, int mode)
490{ 579{
491 static char *strmode[16] = { 580 static char *strmode[] = { "0", "mono", "stereo", "3",
492#if __GNUC__ >= 3 581 "lang1", "5", "6", "7", "lang2"
493 [ 0 ... 15 ] = "invalid",
494#endif
495 [ V4L2_TUNER_MODE_MONO ] = "mono",
496 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
497 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
498 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
499 }; 582 };
500 struct msp3400c *msp = i2c_get_clientdata(client); 583 struct msp3400c *msp = i2c_get_clientdata(client);
501 int nicam=0; /* channel source: FM/AM or nicam */ 584 int nicam = 0; /* channel source: FM/AM or nicam */
502 int src=0; 585 int src = 0;
503 586
504 BUG_ON(msp->opmode == OPMODE_SIMPLER); 587 if (IS_MSP34XX_G(msp)) {
505 msp->audmode = audmode; 588 /* this method would break everything, let's make sure
589 * it's never called
590 */
591 msp3400_dbg
592 ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
593 mode);
594 return;
595 }
506 596
507 /* switch demodulator */ 597 /* switch demodulator */
508 switch (msp->mode) { 598 switch (msp->mode) {
509 case MSP_MODE_FM_TERRA: 599 case MSP_MODE_FM_TERRA:
510 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", 600 msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
511 strmode[audmode]);
512 msp3400c_setcarrier(client,msp->second,msp->main); 601 msp3400c_setcarrier(client,msp->second,msp->main);
513 switch (audmode) { 602 switch (mode) {
514 case V4L2_TUNER_MODE_STEREO: 603 case V4L2_TUNER_MODE_STEREO:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); 604 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
516 break; 605 break;
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
522 } 611 }
523 break; 612 break;
524 case MSP_MODE_FM_SAT: 613 case MSP_MODE_FM_SAT:
525 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", 614 msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
526 strmode[audmode]); 615 switch (mode) {
527 switch (audmode) {
528 case V4L2_TUNER_MODE_MONO: 616 case V4L2_TUNER_MODE_MONO:
529 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); 617 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
530 break; 618 break;
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
542 case MSP_MODE_FM_NICAM1: 630 case MSP_MODE_FM_NICAM1:
543 case MSP_MODE_FM_NICAM2: 631 case MSP_MODE_FM_NICAM2:
544 case MSP_MODE_AM_NICAM: 632 case MSP_MODE_AM_NICAM:
545 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", 633 msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
546 strmode[audmode]);
547 msp3400c_setcarrier(client,msp->second,msp->main); 634 msp3400c_setcarrier(client,msp->second,msp->main);
548 if (msp->nicam_on) 635 if (msp->nicam_on)
549 nicam=0x0100; 636 nicam=0x0100;
550 break; 637 break;
551 case MSP_MODE_BTSC: 638 case MSP_MODE_BTSC:
552 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", 639 msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
553 strmode[audmode]);
554 nicam=0x0300; 640 nicam=0x0300;
555 break; 641 break;
556 case MSP_MODE_EXTERN: 642 case MSP_MODE_EXTERN:
557 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", 643 msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
558 strmode[audmode]);
559 nicam = 0x0200; 644 nicam = 0x0200;
560 break; 645 break;
561 case MSP_MODE_FM_RADIO: 646 case MSP_MODE_FM_RADIO:
562 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", 647 msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
563 strmode[audmode]);
564 break; 648 break;
565 default: 649 default:
566 dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); 650 msp3400_dbg("mono setstereo\n");
567 return; 651 return;
568 } 652 }
569 653
570 /* switch audio */ 654 /* switch audio */
571 switch (audmode) { 655 switch (best_video_sound(mode)) {
572 case V4L2_TUNER_MODE_STEREO: 656 case V4L2_TUNER_MODE_STEREO:
573 src = 0x0020 | nicam; 657 src = 0x0020 | nicam;
574 break; 658 break;
575 case V4L2_TUNER_MODE_MONO: 659 case V4L2_TUNER_MODE_MONO:
576 if (msp->mode == MSP_MODE_AM_NICAM) { 660 if (msp->mode == MSP_MODE_AM_NICAM) {
577 dprintk("msp3400: switching to AM mono\n"); 661 msp3400_dbg("switching to AM mono\n");
578 /* AM mono decoding is handled by tuner, not MSP chip */ 662 /* AM mono decoding is handled by tuner, not MSP chip */
579 /* SCART switching control register */ 663 /* SCART switching control register */
580 msp3400c_set_scart(client,SCART_MONO,0); 664 msp3400c_set_scart(client,SCART_MONO,0);
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
588 src = 0x0010 | nicam; 672 src = 0x0010 | nicam;
589 break; 673 break;
590 } 674 }
591 dprintk(KERN_DEBUG 675 msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
592 "msp3400: setstereo final source/matrix = 0x%x\n", src);
593 676
594 if (dolby) { 677 if (dolby) {
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); 678 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
605} 688}
606 689
607static void 690static void
608msp3400c_print_mode(struct msp3400c *msp) 691msp3400c_print_mode(struct i2c_client *client)
609{ 692{
693 struct msp3400c *msp = i2c_get_clientdata(client);
694
610 if (msp->main == msp->second) { 695 if (msp->main == msp->second) {
611 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", 696 msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
612 msp->main/910000,(msp->main/910)%1000); 697 msp->main/910000,(msp->main/910)%1000);
613 } else { 698 } else {
614 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", 699 msp3400_dbg("main sound carrier: %d.%03d MHz\n",
615 msp->main/910000,(msp->main/910)%1000); 700 msp->main/910000,(msp->main/910)%1000);
616 } 701 }
617 if (msp->mode == MSP_MODE_FM_NICAM1 || 702 if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
618 msp->mode == MSP_MODE_FM_NICAM2) 703 msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
619 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
620 msp->second/910000,(msp->second/910)%1000); 704 msp->second/910000,(msp->second/910)%1000);
621 if (msp->mode == MSP_MODE_AM_NICAM) 705 if (msp->mode == MSP_MODE_AM_NICAM)
622 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", 706 msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
623 msp->second/910000,(msp->second/910)%1000); 707 msp->second/910000,(msp->second/910)%1000);
624 if (msp->mode == MSP_MODE_FM_TERRA && 708 if (msp->mode == MSP_MODE_FM_TERRA &&
625 msp->main != msp->second) { 709 msp->main != msp->second) {
626 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", 710 msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
627 msp->second/910000,(msp->second/910)%1000); 711 msp->second/910000,(msp->second/910)%1000);
628 } 712 }
629} 713}
630 714
715#define MSP3400_MAX 4
716static struct i2c_client *msps[MSP3400_MAX];
717static void msp3400c_restore_dfp(struct i2c_client *client)
718{
719 struct msp3400c *msp = i2c_get_clientdata(client);
720 int i;
721
722 for (i = 0; i < DFP_COUNT; i++) {
723 if (-1 == msp->dfp_regs[i])
724 continue;
725 msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
726 }
727}
728
729/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
730static int msp3400c_write_dfp_with_default(struct i2c_client *client,
731 int addr, int default_value)
732{
733 struct msp3400c *msp = i2c_get_clientdata(client);
734 int value = default_value;
735 if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
736 value = msp->dfp_regs[addr];
737 return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
738}
739
631/* ----------------------------------------------------------------------- */ 740/* ----------------------------------------------------------------------- */
632 741
633struct REGISTER_DUMP { 742struct REGISTER_DUMP {
@@ -635,8 +744,15 @@ struct REGISTER_DUMP {
635 char *name; 744 char *name;
636}; 745};
637 746
638static int 747struct REGISTER_DUMP d1[] = {
639autodetect_stereo(struct i2c_client *client) 748 {0x007e, "autodetect"},
749 {0x0023, "C_AD_BITS "},
750 {0x0038, "ADD_BITS "},
751 {0x003e, "CIB_BITS "},
752 {0x0057, "ERROR_RATE"},
753};
754
755static int autodetect_stereo(struct i2c_client *client)
640{ 756{
641 struct msp3400c *msp = i2c_get_clientdata(client); 757 struct msp3400c *msp = i2c_get_clientdata(client);
642 int val; 758 int val;
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client)
649 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); 765 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
650 if (val > 32767) 766 if (val > 32767)
651 val -= 65536; 767 val -= 65536;
652 dprintk(KERN_DEBUG 768 msp3400_dbg("stereo detect register: %d\n",val);
653 "msp34xx: stereo detect register: %d\n",val);
654 if (val > 4096) { 769 if (val > 4096) {
655 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; 770 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
656 } else if (val < -4096) { 771 } else if (val < -4096) {
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client)
664 case MSP_MODE_FM_NICAM2: 779 case MSP_MODE_FM_NICAM2:
665 case MSP_MODE_AM_NICAM: 780 case MSP_MODE_AM_NICAM:
666 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); 781 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
667 dprintk(KERN_DEBUG 782 msp3400_dbg("nicam sync=%d, mode=%d\n",
668 "msp34xx: nicam sync=%d, mode=%d\n",
669 val & 1, (val & 0x1e) >> 1); 783 val & 1, (val & 0x1e) >> 1);
670 784
671 if (val & 1) { 785 if (val & 1) {
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client)
698 break; 812 break;
699 case MSP_MODE_BTSC: 813 case MSP_MODE_BTSC:
700 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); 814 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
701 dprintk(KERN_DEBUG 815 msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
703 val, 816 val,
704 (val & 0x0002) ? "no" : "yes", 817 (val & 0x0002) ? "no" : "yes",
705 (val & 0x0004) ? "no" : "yes", 818 (val & 0x0004) ? "no" : "yes",
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client)
713 } 826 }
714 if (rxsubchans != msp->rxsubchans) { 827 if (rxsubchans != msp->rxsubchans) {
715 update = 1; 828 update = 1;
716 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", 829 msp3400_dbg("watch: rxsubchans %d => %d\n",
717 msp->rxsubchans,rxsubchans); 830 msp->rxsubchans,rxsubchans);
718 msp->rxsubchans = rxsubchans; 831 msp->rxsubchans = rxsubchans;
719 } 832 }
720 if (newnicam != msp->nicam_on) { 833 if (newnicam != msp->nicam_on) {
721 update = 1; 834 update = 1;
722 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", 835 msp3400_dbg("watch: nicam %d => %d\n",
723 msp->nicam_on,newnicam); 836 msp->nicam_on,newnicam);
724 msp->nicam_on = newnicam; 837 msp->nicam_on = newnicam;
725 } 838 }
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client)
756{ 869{
757 struct msp3400c *msp = i2c_get_clientdata(client); 870 struct msp3400c *msp = i2c_get_clientdata(client);
758 871
759 if (autodetect_stereo(client)) 872 if (autodetect_stereo(client)) {
760 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); 873 if (msp->stereo & V4L2_TUNER_MODE_STEREO)
874 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
875 else if (msp->stereo & VIDEO_SOUND_LANG1)
876 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
877 else
878 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
879 }
880
761 if (once) 881 if (once)
762 msp->watch_stereo = 0; 882 msp->watch_stereo = 0;
763} 883}
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data)
769 struct CARRIER_DETECT *cd; 889 struct CARRIER_DETECT *cd;
770 int count, max1,max2,val1,val2, val,this; 890 int count, max1,max2,val1,val2, val,this;
771 891
772 printk("msp3400: kthread started\n"); 892 msp3400_info("msp3400 daemon started\n");
773 for (;;) { 893 for (;;) {
774 d2printk("msp3400: thread: sleep\n"); 894 msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
775 msp34xx_sleep(msp,-1); 895 msp34xx_sleep(msp,-1);
776 d2printk("msp3400: thread: wakeup\n"); 896 msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
777 897
778 restart: 898 restart:
779 dprintk("msp3410: thread: restart scan\n"); 899 msp3400_dbg("thread: restart scan\n");
780 msp->restart = 0; 900 msp->restart = 0;
781 if (kthread_should_stop()) 901 if (kthread_should_stop())
782 break; 902 break;
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data)
784 if (VIDEO_MODE_RADIO == msp->norm || 904 if (VIDEO_MODE_RADIO == msp->norm ||
785 MSP_MODE_EXTERN == msp->mode) { 905 MSP_MODE_EXTERN == msp->mode) {
786 /* no carrier scan, just unmute */ 906 /* no carrier scan, just unmute */
787 printk("msp3400: thread: no carrier scan\n"); 907 msp3400_info("thread: no carrier scan\n");
788 msp3400c_setvolume(client, msp->muted, 908 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
789 msp->volume, msp->balance);
790 continue; 909 continue;
791 } 910 }
792 911
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data)
802 goto restart; 921 goto restart;
803 922
804 /* carrier detect pass #1 -- main carrier */ 923 /* carrier detect pass #1 -- main carrier */
805 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); 924 cd = carrier_detect_main;
925 count = CARRIER_COUNT(carrier_detect_main);
806 926
807 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 927 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
808 /* autodetect doesn't work well with AM ... */ 928 /* autodetect doesn't work well with AM ... */
809 max1 = 3; 929 max1 = 3;
810 count = 0; 930 count = 0;
811 dprintk("msp3400: AM sound override\n"); 931 msp3400_dbg("AM sound override\n");
812 } 932 }
813 933
814 for (this = 0; this < count; this++) { 934 for (this = 0; this < count; this++) {
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data)
820 val -= 65536; 940 val -= 65536;
821 if (val1 < val) 941 if (val1 < val)
822 val1 = val, max1 = this; 942 val1 = val, max1 = this;
823 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); 943 msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
824 } 944 }
825 945
826 /* carrier detect pass #2 -- second (stereo) carrier */ 946 /* carrier detect pass #2 -- second (stereo) carrier */
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data)
836 case 0: /* 4.5 */ 956 case 0: /* 4.5 */
837 case 2: /* 6.0 */ 957 case 2: /* 6.0 */
838 default: 958 default:
839 cd = NULL; count = 0; 959 cd = NULL;
960 count = 0;
840 break; 961 break;
841 } 962 }
842 963
843 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 964 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
844 /* autodetect doesn't work well with AM ... */ 965 /* autodetect doesn't work well with AM ... */
845 cd = NULL; count = 0; max2 = 0; 966 cd = NULL;
967 count = 0;
968 max2 = 0;
846 } 969 }
847 for (this = 0; this < count; this++) { 970 for (this = 0; this < count; this++) {
848 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); 971 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data)
853 val -= 65536; 976 val -= 65536;
854 if (val2 < val) 977 if (val2 < val)
855 val2 = val, max2 = this; 978 val2 = val, max2 = this;
856 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); 979 msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
857 } 980 }
858 981
859 /* programm the msp3400 according to the results */ 982 /* programm the msp3400 according to the results */
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data)
865 msp->second = carrier_detect_55[max2].cdo; 988 msp->second = carrier_detect_55[max2].cdo;
866 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 989 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
867 msp->nicam_on = 0; 990 msp->nicam_on = 0;
868 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 991 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
869 msp->watch_stereo = 1; 992 msp->watch_stereo = 1;
870 } else if (max2 == 1 && HAVE_NICAM(msp)) { 993 } else if (max2 == 1 && HAVE_NICAM(msp)) {
871 /* B/G NICAM */ 994 /* B/G NICAM */
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data)
892 msp->second = carrier_detect_65[max2].cdo; 1015 msp->second = carrier_detect_65[max2].cdo;
893 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 1016 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
894 msp->nicam_on = 0; 1017 msp->nicam_on = 0;
895 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1018 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
896 msp->watch_stereo = 1; 1019 msp->watch_stereo = 1;
897 } else if (max2 == 0 && 1020 } else if (max2 == 0 &&
898 msp->norm == VIDEO_MODE_SECAM) { 1021 msp->norm == VIDEO_MODE_SECAM) {
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data)
900 msp->second = carrier_detect_65[max2].cdo; 1023 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_AM_NICAM); 1024 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
902 msp->nicam_on = 0; 1025 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1026 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
904 msp3400c_setcarrier(client, msp->second, msp->main); 1027 msp3400c_setcarrier(client, msp->second, msp->main);
905 /* volume prescale for SCART (AM mono input) */ 1028 /* volume prescale for SCART (AM mono input) */
906 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); 1029 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data)
924 msp->nicam_on = 0; 1047 msp->nicam_on = 0;
925 msp3400c_setcarrier(client, msp->second, msp->main); 1048 msp3400c_setcarrier(client, msp->second, msp->main);
926 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1049 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
927 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1050 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
928 break; 1051 break;
929 } 1052 }
930 1053
931 /* unmute */ 1054 /* unmute */
932 msp3400c_setvolume(client, msp->muted, 1055 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
933 msp->volume, msp->balance); 1056 msp3400c_restore_dfp(client);
1057
934 if (debug) 1058 if (debug)
935 msp3400c_print_mode(msp); 1059 msp3400c_print_mode(client);
936 1060
937 /* monitor tv audio mode */ 1061 /* monitor tv audio mode */
938 while (msp->watch_stereo) { 1062 while (msp->watch_stereo) {
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data)
941 watch_stereo(client); 1065 watch_stereo(client);
942 } 1066 }
943 } 1067 }
944 dprintk(KERN_DEBUG "msp3400: thread: exit\n"); 1068 msp3400_dbg("thread: exit\n");
945 return 0; 1069 return 0;
946} 1070}
947 1071
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode)
985 return "unknown"; 1109 return "unknown";
986} 1110}
987 1111
988static int msp34xx_modus(int norm) 1112static int msp34xx_modus(struct i2c_client *client, int norm)
989{ 1113{
990 switch (norm) { 1114 switch (norm) {
991 case VIDEO_MODE_PAL: 1115 case VIDEO_MODE_PAL:
1116 msp3400_dbg("video mode selected to PAL\n");
1117
992#if 1 1118#if 1
993 /* experimental: not sure this works with all chip versions */ 1119 /* experimental: not sure this works with all chip versions */
994 return 0x7003; 1120 return 0x7003;
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm)
997 return 0x1003; 1123 return 0x1003;
998#endif 1124#endif
999 case VIDEO_MODE_NTSC: /* BTSC */ 1125 case VIDEO_MODE_NTSC: /* BTSC */
1126 msp3400_dbg("video mode selected to NTSC\n");
1000 return 0x2003; 1127 return 0x2003;
1001 case VIDEO_MODE_SECAM: 1128 case VIDEO_MODE_SECAM:
1129 msp3400_dbg("video mode selected to SECAM\n");
1002 return 0x0003; 1130 return 0x0003;
1003 case VIDEO_MODE_RADIO: 1131 case VIDEO_MODE_RADIO:
1132 msp3400_dbg("video mode selected to Radio\n");
1004 return 0x0003; 1133 return 0x0003;
1005 case VIDEO_MODE_AUTO: 1134 case VIDEO_MODE_AUTO:
1135 msp3400_dbg("video mode selected to Auto\n");
1006 return 0x2003; 1136 return 0x2003;
1007 default: 1137 default:
1008 return 0x0003; 1138 return 0x0003;
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data)
1031 struct msp3400c *msp = i2c_get_clientdata(client); 1161 struct msp3400c *msp = i2c_get_clientdata(client);
1032 int mode,val,i,std; 1162 int mode,val,i,std;
1033 1163
1034 printk("msp3410: daemon started\n"); 1164 msp3400_info("msp3410 daemon started\n");
1035 for (;;) { 1165 for (;;) {
1036 d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); 1166 msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
1037 msp34xx_sleep(msp,-1); 1167 msp34xx_sleep(msp,-1);
1038 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); 1168 msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
1039 1169
1040 restart: 1170 restart:
1041 dprintk("msp3410: thread: restart scan\n"); 1171 msp3400_dbg("thread: restart scan\n");
1042 msp->restart = 0; 1172 msp->restart = 0;
1043 if (kthread_should_stop()) 1173 if (kthread_should_stop())
1044 break; 1174 break;
1045 1175
1046 if (msp->mode == MSP_MODE_EXTERN) { 1176 if (msp->mode == MSP_MODE_EXTERN) {
1047 /* no carrier scan needed, just unmute */ 1177 /* no carrier scan needed, just unmute */
1048 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); 1178 msp3400_dbg("thread: no carrier scan\n");
1049 msp3400c_setvolume(client, msp->muted, 1179 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1050 msp->volume, msp->balance);
1051 continue; 1180 continue;
1052 } 1181 }
1053 1182
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data)
1059 goto restart; 1188 goto restart;
1060 1189
1061 /* start autodetect */ 1190 /* start autodetect */
1062 mode = msp34xx_modus(msp->norm); 1191 mode = msp34xx_modus(client, msp->norm);
1063 std = msp34xx_standard(msp->norm); 1192 std = msp34xx_standard(msp->norm);
1064 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); 1193 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1065 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); 1194 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1066 msp->watch_stereo = 0; 1195 msp->watch_stereo = 0;
1067 1196
1068 if (debug) 1197 if (debug)
1069 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", 1198 msp3400_dbg("setting mode: %s (0x%04x)\n",
1070 msp34xx_standard_mode_name(std) ,std); 1199 msp34xx_standard_mode_name(std) ,std);
1071 1200
1072 if (std != 1) { 1201 if (std != 1) {
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data)
1082 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); 1211 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1083 if (val < 0x07ff) 1212 if (val < 0x07ff)
1084 break; 1213 break;
1085 dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); 1214 msp3400_dbg("detection still in progress\n");
1086 } 1215 }
1087 } 1216 }
1088 for (i = 0; modelist[i].name != NULL; i++) 1217 for (i = 0; modelist[i].name != NULL; i++)
1089 if (modelist[i].retval == val) 1218 if (modelist[i].retval == val)
1090 break; 1219 break;
1091 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", 1220 msp3400_dbg("current mode: %s (0x%04x)\n",
1092 modelist[i].name ? modelist[i].name : "unknown", 1221 modelist[i].name ? modelist[i].name : "unknown",
1093 val); 1222 val);
1094 msp->main = modelist[i].main; 1223 msp->main = modelist[i].main;
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data)
1096 1225
1097 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { 1226 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1098 /* autodetection has failed, let backup */ 1227 /* autodetection has failed, let backup */
1099 dprintk(KERN_DEBUG "msp3410: autodetection failed," 1228 msp3400_dbg("autodetection failed,"
1100 " switching to backup mode: %s (0x%04x)\n", 1229 " switching to backup mode: %s (0x%04x)\n",
1101 modelist[8].name ? modelist[8].name : "unknown",val); 1230 modelist[8].name ? modelist[8].name : "unknown",val);
1102 val = 0x0009; 1231 val = 0x0009;
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data)
1120 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1249 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1121 msp->nicam_on = 1; 1250 msp->nicam_on = 1;
1122 msp->watch_stereo = 1; 1251 msp->watch_stereo = 1;
1123 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1252 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1124 break; 1253 break;
1125 case 0x0009: 1254 case 0x0009:
1126 msp->mode = MSP_MODE_AM_NICAM; 1255 msp->mode = MSP_MODE_AM_NICAM;
1127 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1256 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1128 msp->nicam_on = 1; 1257 msp->nicam_on = 1;
1129 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); 1258 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1130 msp->watch_stereo = 1; 1259 msp->watch_stereo = 1;
1131 break; 1260 break;
1132 case 0x0020: /* BTSC */ 1261 case 0x0020: /* BTSC */
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data)
1135 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1264 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1136 msp->nicam_on = 0; 1265 msp->nicam_on = 0;
1137 msp->watch_stereo = 1; 1266 msp->watch_stereo = 1;
1138 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1267 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1139 break; 1268 break;
1140 case 0x0040: /* FM radio */ 1269 case 0x0040: /* FM radio */
1141 msp->mode = MSP_MODE_FM_RADIO; 1270 msp->mode = MSP_MODE_FM_RADIO;
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data)
1169 /* unmute, restore misc registers */ 1298 /* unmute, restore misc registers */
1170 msp3400c_setbass(client, msp->bass); 1299 msp3400c_setbass(client, msp->bass);
1171 msp3400c_settreble(client, msp->treble); 1300 msp3400c_settreble(client, msp->treble);
1172 msp3400c_setvolume(client, msp->muted, 1301 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1173 msp->volume, msp->balance); 1302 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1174 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); 1303 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1304 msp3400c_restore_dfp(client);
1175 1305
1176 /* monitor tv audio mode */ 1306 /* monitor tv audio mode */
1177 while (msp->watch_stereo) { 1307 while (msp->watch_stereo) {
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data)
1180 watch_stereo(client); 1310 watch_stereo(client);
1181 } 1311 }
1182 } 1312 }
1183 dprintk(KERN_DEBUG "msp3410: thread: exit\n"); 1313 msp3400_dbg("thread: exit\n");
1184 return 0; 1314 return 0;
1185} 1315}
1186 1316
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
1195/* (re-)initialize the msp34xxg, according to the current norm in msp->norm 1325/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1196 * return 0 if it worked, -1 if it failed 1326 * return 0 if it worked, -1 if it failed
1197 */ 1327 */
1198static int msp34xxg_init(struct i2c_client *client) 1328static int msp34xxg_reset(struct i2c_client *client)
1199{ 1329{
1200 struct msp3400c *msp = i2c_get_clientdata(client); 1330 struct msp3400c *msp = i2c_get_clientdata(client);
1201 int modus,std; 1331 int modus,std;
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client)
1210 0x0f20 /* mute DSP input, mute SCART 1 */)) 1340 0x0f20 /* mute DSP input, mute SCART 1 */))
1211 return -1; 1341 return -1;
1212 1342
1343 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1344
1213 /* step-by-step initialisation, as described in the manual */ 1345 /* step-by-step initialisation, as described in the manual */
1214 modus = msp34xx_modus(msp->norm); 1346 modus = msp34xx_modus(client, msp->norm);
1215 std = msp34xx_standard(msp->norm); 1347 std = msp34xx_standard(msp->norm);
1216 modus &= ~0x03; /* STATUS_CHANGE=0 */ 1348 modus &= ~0x03; /* STATUS_CHANGE=0 */
1217 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ 1349 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client)
1222 return -1; 1354 return -1;
1223 if (msp3400c_write(client, 1355 if (msp3400c_write(client,
1224 I2C_MSP3400C_DEM, 1356 I2C_MSP3400C_DEM,
1225 0x20/*stanard*/, 1357 0x20/*standard*/,
1226 std)) 1358 std))
1227 return -1; 1359 return -1;
1228 1360
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client)
1230 standard/audio autodetection right now */ 1362 standard/audio autodetection right now */
1231 msp34xxg_set_source(client, msp->source); 1363 msp34xxg_set_source(client, msp->source);
1232 1364
1233 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1365 if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
1234 0x0e, /* AM/FM Prescale */ 1366 0x3000
1235 0x3000 /* default: [15:8] 75khz deviation */)) 1367 /* default: [15:8] 75khz deviation */
1368 ))
1236 return -1; 1369 return -1;
1237 1370
1238 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1371 if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
1239 0x10, /* NICAM Prescale */ 1372 0x5a00
1240 0x5a00 /* default: 9db gain (as recommended) */)) 1373 /* default: 9db gain (as recommended) */
1374 ))
1241 return -1; 1375 return -1;
1242 1376
1243 if (msp3400c_write(client,
1244 I2C_MSP3400C_DEM,
1245 0x20, /* STANDARD SELECT */
1246 standard /* default: 0x01 for automatic standard select*/))
1247 return -1;
1248 return 0; 1377 return 0;
1249} 1378}
1250 1379
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data)
1254 struct msp3400c *msp = i2c_get_clientdata(client); 1383 struct msp3400c *msp = i2c_get_clientdata(client);
1255 int val, std, i; 1384 int val, std, i;
1256 1385
1257 printk("msp34xxg: daemon started\n"); 1386 msp3400_info("msp34xxg daemon started\n");
1258 msp->source = 1; /* default */ 1387 msp->source = 1; /* default */
1259 for (;;) { 1388 for (;;) {
1260 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); 1389 msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
1261 msp34xx_sleep(msp,-1); 1390 msp34xx_sleep(msp,-1);
1262 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); 1391 msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
1263 1392
1264 restart: 1393 restart:
1265 dprintk("msp34xxg: thread: restart scan\n"); 1394 msp3400_dbg("thread: restart scan\n");
1266 msp->restart = 0; 1395 msp->restart = 0;
1267 if (kthread_should_stop()) 1396 if (kthread_should_stop())
1268 break; 1397 break;
1269 1398
1270 /* setup the chip*/ 1399 /* setup the chip*/
1271 msp34xxg_init(client); 1400 msp34xxg_reset(client);
1272 std = standard; 1401 std = standard;
1273 if (std != 0x01) 1402 if (std != 0x01)
1274 goto unmute; 1403 goto unmute;
1275 1404
1276 /* watch autodetect */ 1405 /* watch autodetect */
1277 dprintk("msp34xxg: triggered autodetect, waiting for result\n"); 1406 msp3400_dbg("triggered autodetect, waiting for result\n");
1278 for (i = 0; i < 10; i++) { 1407 for (i = 0; i < 10; i++) {
1279 if (msp34xx_sleep(msp,100)) 1408 if (msp34xx_sleep(msp,100))
1280 goto restart; 1409 goto restart;
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data)
1285 std = val; 1414 std = val;
1286 break; 1415 break;
1287 } 1416 }
1288 dprintk("msp34xxg: detection still in progress\n"); 1417 msp3400_dbg("detection still in progress\n");
1289 } 1418 }
1290 if (0x01 == std) { 1419 if (0x01 == std) {
1291 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); 1420 msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
1292 continue; 1421 continue;
1293 } 1422 }
1294 1423
1295 unmute: 1424 unmute:
1296 dprintk("msp34xxg: current mode: %s (0x%04x)\n", 1425 msp3400_dbg("current mode: %s (0x%04x)\n",
1297 msp34xx_standard_mode_name(std), std); 1426 msp34xx_standard_mode_name(std), std);
1298 1427
1299 /* unmute: dispatch sound to scart output, set scart volume */ 1428 /* unmute: dispatch sound to scart output, set scart volume */
1300 dprintk("msp34xxg: unmute\n"); 1429 msp3400_dbg("unmute\n");
1301 1430
1302 msp3400c_setbass(client, msp->bass); 1431 msp3400c_setbass(client, msp->bass);
1303 msp3400c_settreble(client, msp->treble); 1432 msp3400c_settreble(client, msp->treble);
1304 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); 1433 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1305 1434
1306 /* restore ACB */ 1435 /* restore ACB */
1307 if (msp3400c_write(client, 1436 if (msp3400c_write(client,
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data)
1309 0x13, /* ACB */ 1438 0x13, /* ACB */
1310 msp->acb)) 1439 msp->acb))
1311 return -1; 1440 return -1;
1441
1442 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1312 } 1443 }
1313 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); 1444 msp3400_dbg("thread: exit\n");
1314 return 0; 1445 return 0;
1315} 1446}
1316 1447
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
1329 * for MONO (source==0) downmixing set bit[7:0] to 0x30 1460 * for MONO (source==0) downmixing set bit[7:0] to 0x30
1330 */ 1461 */
1331 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); 1462 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1332 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); 1463 msp3400_dbg("set source to %d (0x%x)\n", source, value);
1333 msp3400c_write(client, 1464 msp3400c_write(client,
1334 I2C_MSP3400C_DFP, 1465 I2C_MSP3400C_DFP,
1335 0x08, /* Loudspeaker Output */ 1466 0x08, /* Loudspeaker Output */
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
1380 * this is a problem, I'll handle SAP just like lang1/lang2. 1511 * this is a problem, I'll handle SAP just like lang1/lang2.
1381 */ 1512 */
1382 } 1513 }
1383 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", 1514 msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1384 status, is_stereo, is_bilingual, msp->rxsubchans); 1515 status, is_stereo, is_bilingual, msp->rxsubchans);
1385} 1516}
1386 1517
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client);
1427 1558
1428static struct i2c_driver driver = { 1559static struct i2c_driver driver = {
1429 .owner = THIS_MODULE, 1560 .owner = THIS_MODULE,
1430 .name = "i2c msp3400 driver", 1561 .name = "msp3400",
1431 .id = I2C_DRIVERID_MSP3400, 1562 .id = I2C_DRIVERID_MSP3400,
1432 .flags = I2C_DF_NOTIFY, 1563 .flags = I2C_DF_NOTIFY,
1433 .attach_adapter = msp_probe, 1564 .attach_adapter = msp_probe,
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template =
1449static int msp_attach(struct i2c_adapter *adap, int addr, int kind) 1580static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1450{ 1581{
1451 struct msp3400c *msp; 1582 struct msp3400c *msp;
1452 struct i2c_client *c; 1583 struct i2c_client *client = &client_template;
1453 int (*thread_func)(void *data) = NULL; 1584 int (*thread_func)(void *data) = NULL;
1585 int i;
1454 1586
1455 client_template.adapter = adap; 1587 client_template.adapter = adap;
1456 client_template.addr = addr; 1588 client_template.addr = addr;
1457 1589
1458 if (-1 == msp3400c_reset(&client_template)) { 1590 if (-1 == msp3400c_reset(&client_template)) {
1459 dprintk("msp34xx: no chip found\n"); 1591 msp3400_dbg("no chip found\n");
1460 return -1; 1592 return -1;
1461 } 1593 }
1462 1594
1463 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) 1595 if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1464 return -ENOMEM; 1596 return -ENOMEM;
1465 memcpy(c,&client_template,sizeof(struct i2c_client)); 1597 memcpy(client,&client_template,sizeof(struct i2c_client));
1466 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { 1598 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1467 kfree(c); 1599 kfree(client);
1468 return -ENOMEM; 1600 return -ENOMEM;
1469 } 1601 }
1470 1602
1471 memset(msp,0,sizeof(struct msp3400c)); 1603 memset(msp,0,sizeof(struct msp3400c));
1472 msp->volume = 58880; /* 0db gain */ 1604 msp->norm = VIDEO_MODE_NTSC;
1473 msp->balance = 32768; 1605 msp->left = 58880; /* 0db gain */
1474 msp->bass = 32768; 1606 msp->right = 58880; /* 0db gain */
1475 msp->treble = 32768; 1607 msp->bass = 32768;
1476 msp->input = -1; 1608 msp->treble = 32768;
1477 msp->muted = 1; 1609 msp->input = -1;
1478 1610 msp->muted = 0;
1479 i2c_set_clientdata(c, msp); 1611 msp->i2s_mode = 0;
1612 for (i = 0; i < DFP_COUNT; i++)
1613 msp->dfp_regs[i] = -1;
1614
1615 i2c_set_clientdata(client, msp);
1480 init_waitqueue_head(&msp->wq); 1616 init_waitqueue_head(&msp->wq);
1481 1617
1482 if (-1 == msp3400c_reset(c)) { 1618 if (-1 == msp3400c_reset(client)) {
1483 kfree(msp); 1619 kfree(msp);
1484 kfree(c); 1620 kfree(client);
1485 dprintk("msp34xx: no chip found\n"); 1621 msp3400_dbg("no chip found\n");
1486 return -1; 1622 return -1;
1487 } 1623 }
1488 1624
1489 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); 1625 msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
1490 if (-1 != msp->rev1) 1626 if (-1 != msp->rev1)
1491 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); 1627 msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
1492 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { 1628 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1493 kfree(msp); 1629 kfree(msp);
1494 kfree(c); 1630 kfree(client);
1495 dprintk("msp34xx: error while reading chip version\n"); 1631 msp3400_dbg("error while reading chip version\n");
1496 return -1; 1632 return -1;
1497 } 1633 }
1634 msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
1498 1635
1499 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); 1636 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1500 1637
1501 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", 1638 snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
1502 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', 1639 ((msp->rev1>>4)&0x0f) + '3',
1640 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
1503 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); 1641 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1504 1642
1505 msp->opmode = opmode; 1643 msp->opmode = opmode;
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1513 } 1651 }
1514 1652
1515 /* hello world :-) */ 1653 /* hello world :-) */
1516 printk(KERN_INFO "msp34xx: init: chip=%s", c->name); 1654 msp3400_info("chip=%s", client->name);
1517 if (HAVE_NICAM(msp)) 1655 if (HAVE_NICAM(msp))
1518 printk(" +nicam"); 1656 printk(" +nicam");
1519 if (HAVE_SIMPLE(msp)) 1657 if (HAVE_SIMPLE(msp))
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1542 1680
1543 /* startup control thread if needed */ 1681 /* startup control thread if needed */
1544 if (thread_func) { 1682 if (thread_func) {
1545 msp->kthread = kthread_run(thread_func, c, "msp34xx"); 1683 msp->kthread = kthread_run(thread_func, client, "msp34xx");
1684
1546 if (NULL == msp->kthread) 1685 if (NULL == msp->kthread)
1547 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); 1686 msp3400_warn("kernel_thread() failed\n");
1548 msp_wake_thread(c); 1687 msp_wake_thread(client);
1549 } 1688 }
1550 1689
1551 /* done */ 1690 /* done */
1552 i2c_attach_client(c); 1691 i2c_attach_client(client);
1692
1693 /* update our own array */
1694 for (i = 0; i < MSP3400_MAX; i++) {
1695 if (NULL == msps[i]) {
1696 msps[i] = client;
1697 break;
1698 }
1699 }
1700
1553 return 0; 1701 return 0;
1554} 1702}
1555 1703
1556static int msp_detach(struct i2c_client *client) 1704static int msp_detach(struct i2c_client *client)
1557{ 1705{
1558 struct msp3400c *msp = i2c_get_clientdata(client); 1706 struct msp3400c *msp = i2c_get_clientdata(client);
1707 int i;
1559 1708
1560 /* shutdown control thread */ 1709 /* shutdown control thread */
1561 if (msp->kthread >= 0) { 1710 if (msp->kthread) {
1562 msp->restart = 1; 1711 msp->restart = 1;
1563 kthread_stop(msp->kthread); 1712 kthread_stop(msp->kthread);
1564 } 1713 }
1565 msp3400c_reset(client); 1714 msp3400c_reset(client);
1715
1716 /* update our own array */
1717 for (i = 0; i < MSP3400_MAX; i++) {
1718 if (client == msps[i]) {
1719 msps[i] = NULL;
1720 break;
1721 }
1722 }
1566 1723
1567 i2c_detach_client(client); 1724 i2c_detach_client(client);
1725
1568 kfree(msp); 1726 kfree(msp);
1569 kfree(client); 1727 kfree(client);
1570 return 0; 1728 return 0;
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1640 case OPMODE_MANUAL: 1798 case OPMODE_MANUAL:
1641 case OPMODE_SIMPLE: 1799 case OPMODE_SIMPLE:
1642 msp->watch_stereo = 0; 1800 msp->watch_stereo = 0;
1643 msp3400c_set_audmode(client, audmode); 1801 msp3400c_setstereo(client, audmode);
1644 break; 1802 break;
1645 case OPMODE_SIMPLER: 1803 case OPMODE_SIMPLER:
1646 msp34xxg_set_audmode(client, audmode); 1804 msp34xxg_set_audmode(client, audmode);
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1648 } 1806 }
1649} 1807}
1650 1808
1809
1651static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 1810static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1652{ 1811{
1653 struct msp3400c *msp = i2c_get_clientdata(client); 1812 struct msp3400c *msp = i2c_get_clientdata(client);
1654 __u16 *sarg = arg; 1813 __u16 *sarg = arg;
1655 int scart = 0; 1814 int scart = 0;
1656 1815
1657 switch (cmd) { 1816 switch (cmd) {
1658 1817
1659 case AUDC_SET_INPUT: 1818 case AUDC_SET_INPUT:
1660 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); 1819 msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
1820
1661 if (*sarg == msp->input) 1821 if (*sarg == msp->input)
1662 break; 1822 break;
1663 msp->input = *sarg; 1823 msp->input = *sarg;
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1691 msp3400c_set_scart(client,scart,0); 1851 msp3400c_set_scart(client,scart,0);
1692 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); 1852 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1693 if (msp->opmode != OPMODE_SIMPLER) 1853 if (msp->opmode != OPMODE_SIMPLER)
1694 msp3400c_set_audmode(client, msp->audmode); 1854 msp3400c_setstereo(client, msp->audmode);
1695 } 1855 }
1696 msp_wake_thread(client); 1856 msp_wake_thread(client);
1697 break; 1857 break;
1698 1858
1699 case AUDC_SET_RADIO: 1859 case AUDC_SET_RADIO:
1700 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); 1860 msp3400_dbg("AUDC_SET_RADIO\n");
1701 msp->norm = VIDEO_MODE_RADIO; 1861 msp->norm = VIDEO_MODE_RADIO;
1702 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); 1862 msp3400_dbg("switching to radio mode\n");
1703 msp->watch_stereo = 0; 1863 msp->watch_stereo = 0;
1704 switch (msp->opmode) { 1864 switch (msp->opmode) {
1705 case OPMODE_MANUAL: 1865 case OPMODE_MANUAL:
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1707 msp3400c_setmode(client,MSP_MODE_FM_RADIO); 1867 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1708 msp3400c_setcarrier(client, MSP_CARRIER(10.7), 1868 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1709 MSP_CARRIER(10.7)); 1869 MSP_CARRIER(10.7));
1710 msp3400c_setvolume(client, msp->muted, 1870 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1711 msp->volume, msp->balance);
1712 break; 1871 break;
1713 case OPMODE_SIMPLE: 1872 case OPMODE_SIMPLE:
1714 case OPMODE_SIMPLER: 1873 case OPMODE_SIMPLER:
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1717 break; 1876 break;
1718 } 1877 }
1719 break; 1878 break;
1879 /* work-in-progress: hook to control the DFP registers */
1880 case MSP_SET_DFPREG:
1881 {
1882 struct msp_dfpreg *r = arg;
1883 int i;
1884
1885 if (r->reg < 0 || r->reg >= DFP_COUNT)
1886 return -EINVAL;
1887 for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
1888 if (r->reg == bl_dfp[i])
1889 return -EINVAL;
1890 msp->dfp_regs[r->reg] = r->value;
1891 msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
1892 return 0;
1893 }
1894 case MSP_GET_DFPREG:
1895 {
1896 struct msp_dfpreg *r = arg;
1897
1898 if (r->reg < 0 || r->reg >= DFP_COUNT)
1899 return -EINVAL;
1900 r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
1901 return 0;
1902 }
1720 1903
1721 /* --- v4l ioctls --- */ 1904 /* --- v4l ioctls --- */
1722 /* take care: bttv does userspace copying, we'll get a 1905 /* take care: bttv does userspace copying, we'll get a
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1725 { 1908 {
1726 struct video_audio *va = arg; 1909 struct video_audio *va = arg;
1727 1910
1728 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); 1911 msp3400_dbg("VIDIOCGAUDIO\n");
1729 va->flags |= VIDEO_AUDIO_VOLUME | 1912 va->flags |= VIDEO_AUDIO_VOLUME |
1730 VIDEO_AUDIO_BASS | 1913 VIDEO_AUDIO_BASS |
1731 VIDEO_AUDIO_TREBLE | 1914 VIDEO_AUDIO_TREBLE |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1733 if (msp->muted) 1916 if (msp->muted)
1734 va->flags |= VIDEO_AUDIO_MUTE; 1917 va->flags |= VIDEO_AUDIO_MUTE;
1735 1918
1736 va->volume = msp->volume; 1919 if (msp->muted)
1737 va->balance = (va->volume) ? msp->balance : 32768; 1920 va->flags |= VIDEO_AUDIO_MUTE;
1921 va->volume = MAX(msp->left, msp->right);
1922 va->balance = (32768 * MIN(msp->left, msp->right)) /
1923 (va->volume ? va->volume : 1);
1924 va->balance = (msp->left < msp->right) ?
1925 (65535 - va->balance) : va->balance;
1926 if (0 == va->volume)
1927 va->balance = 32768;
1738 va->bass = msp->bass; 1928 va->bass = msp->bass;
1739 va->treble = msp->treble; 1929 va->treble = msp->treble;
1740 1930
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1746 { 1936 {
1747 struct video_audio *va = arg; 1937 struct video_audio *va = arg;
1748 1938
1749 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); 1939 msp3400_dbg("VIDIOCSAUDIO\n");
1750 msp->muted = (va->flags & VIDEO_AUDIO_MUTE); 1940 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1751 msp->volume = va->volume; 1941 msp->left = (MIN(65536 - va->balance, 32768) *
1752 msp->balance = va->balance; 1942 va->volume) / 32768;
1943 msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
1753 msp->bass = va->bass; 1944 msp->bass = va->bass;
1754 msp->treble = va->treble; 1945 msp->treble = va->treble;
1755 1946 msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
1756 msp3400c_setvolume(client, msp->muted, 1947 va->volume);
1757 msp->volume, msp->balance); 1948 msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
1758 msp3400c_setbass(client,msp->bass); 1949 va->balance);
1759 msp3400c_settreble(client,msp->treble); 1950 msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
1951 va->flags);
1952 msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
1953 msp->left);
1954 msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
1955 msp->right);
1956 msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
1957 msp->bass);
1958 msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
1959 msp->treble);
1960 msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
1961 msp->mode);
1962 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1963 msp3400c_setbass(client, msp->bass);
1964 msp3400c_settreble(client, msp->treble);
1760 1965
1761 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) 1966 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1762 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); 1967 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1763 break; 1968 break;
1764 } 1969 }
1970
1765 case VIDIOCSCHAN: 1971 case VIDIOCSCHAN:
1766 { 1972 {
1767 struct video_channel *vc = arg; 1973 struct video_channel *vc = arg;
1768 1974
1769 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); 1975 msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
1770 msp->norm = vc->norm; 1976 msp->norm = vc->norm;
1771 msp_wake_thread(client); 1977 msp_wake_thread(client);
1772 break; 1978 break;
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1776 case VIDIOC_S_FREQUENCY: 1982 case VIDIOC_S_FREQUENCY:
1777 { 1983 {
1778 /* new channel -- kick audio carrier scan */ 1984 /* new channel -- kick audio carrier scan */
1779 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); 1985 msp3400_dbg("VIDIOCSFREQ\n");
1780 msp_wake_thread(client); 1986 msp_wake_thread(client);
1781 break; 1987 break;
1782 } 1988 }
1783 1989
1990 /* msp34xx specific */
1991 case MSP_SET_MATRIX:
1992 {
1993 struct msp_matrix *mspm = arg;
1994
1995 msp3400_dbg("MSP_SET_MATRIX\n");
1996 msp3400c_set_scart(client, mspm->input, mspm->output);
1997 break;
1998 }
1999
1784 /* --- v4l2 ioctls --- */ 2000 /* --- v4l2 ioctls --- */
2001 case VIDIOC_S_STD:
2002 {
2003 v4l2_std_id *id = arg;
2004
2005 /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
2006 if (*id & V4L2_STD_PAL) {
2007 msp->norm=VIDEO_MODE_PAL;
2008 } else if (*id & V4L2_STD_SECAM) {
2009 msp->norm=VIDEO_MODE_SECAM;
2010 } else {
2011 msp->norm=VIDEO_MODE_NTSC;
2012 }
2013
2014 msp_wake_thread(client);
2015 return 0;
2016 }
2017
2018 case VIDIOC_ENUMINPUT:
2019 {
2020 struct v4l2_input *i = arg;
2021
2022 if (i->index != 0)
2023 return -EINVAL;
2024
2025 i->type = V4L2_INPUT_TYPE_TUNER;
2026 switch (i->index) {
2027 case AUDIO_RADIO:
2028 strcpy(i->name,"Radio");
2029 break;
2030 case AUDIO_EXTERN_1:
2031 strcpy(i->name,"Extern 1");
2032 break;
2033 case AUDIO_EXTERN_2:
2034 strcpy(i->name,"Extern 2");
2035 break;
2036 case AUDIO_TUNER:
2037 strcpy(i->name,"Television");
2038 break;
2039 default:
2040 return -EINVAL;
2041 }
2042 return 0;
2043 }
2044
2045 case VIDIOC_G_AUDIO:
2046 {
2047 struct v4l2_audio *a = arg;
2048
2049 memset(a,0,sizeof(*a));
2050
2051 switch (a->index) {
2052 case AUDIO_RADIO:
2053 strcpy(a->name,"Radio");
2054 break;
2055 case AUDIO_EXTERN_1:
2056 strcpy(a->name,"Extern 1");
2057 break;
2058 case AUDIO_EXTERN_2:
2059 strcpy(a->name,"Extern 2");
2060 break;
2061 case AUDIO_TUNER:
2062 strcpy(a->name,"Television");
2063 break;
2064 default:
2065 return -EINVAL;
2066 }
2067
2068 msp_any_detect_stereo(client);
2069 if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
2070 a->capability=V4L2_AUDCAP_STEREO;
2071 }
2072
2073 break;
2074 }
2075 case VIDIOC_S_AUDIO:
2076 {
2077 struct v4l2_audio *sarg = arg;
2078
2079 switch (sarg->index) {
2080 case AUDIO_RADIO:
2081 /* Hauppauge uses IN2 for the radio */
2082 msp->mode = MSP_MODE_FM_RADIO;
2083 scart = SCART_IN2;
2084 break;
2085 case AUDIO_EXTERN_1:
2086 /* IN1 is often used for external input ... */
2087 msp->mode = MSP_MODE_EXTERN;
2088 scart = SCART_IN1;
2089 break;
2090 case AUDIO_EXTERN_2:
2091 /* ... sometimes it is IN2 through ;) */
2092 msp->mode = MSP_MODE_EXTERN;
2093 scart = SCART_IN2;
2094 break;
2095 case AUDIO_TUNER:
2096 msp->mode = -1;
2097 break;
2098 }
2099 if (scart) {
2100 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
2101 msp->audmode = V4L2_TUNER_MODE_STEREO;
2102 msp3400c_set_scart(client,scart,0);
2103 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
2104 }
2105 if (sarg->capability==V4L2_AUDCAP_STEREO) {
2106 msp->audmode = V4L2_TUNER_MODE_STEREO;
2107 } else {
2108 msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
2109 }
2110 msp_any_set_audmode(client, msp->audmode);
2111 msp_wake_thread(client);
2112 break;
2113 }
1785 case VIDIOC_G_TUNER: 2114 case VIDIOC_G_TUNER:
1786 { 2115 {
1787 struct v4l2_tuner *vt = arg; 2116 struct v4l2_tuner *vt = arg;
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1804 break; 2133 break;
1805 } 2134 }
1806 2135
1807 /* msp34xx specific */ 2136 case VIDIOC_G_AUDOUT:
1808 case MSP_SET_MATRIX:
1809 { 2137 {
1810 struct msp_matrix *mspm = arg; 2138 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2139 int idx=a->index;
2140
2141 memset(a,0,sizeof(*a));
2142
2143 switch (idx) {
2144 case 0:
2145 strcpy(a->name,"Scart1 Out");
2146 break;
2147 case 1:
2148 strcpy(a->name,"Scart2 Out");
2149 break;
2150 case 2:
2151 strcpy(a->name,"I2S Out");
2152 break;
2153 default:
2154 return -EINVAL;
2155 }
2156 break;
2157
2158 }
2159 case VIDIOC_S_AUDOUT:
2160 {
2161 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2162
2163 if (a->index<0||a->index>2)
2164 return -EINVAL;
2165
2166 if (a->index==2) {
2167 if (a->mode == V4L2_AUDMODE_32BITS)
2168 msp->i2s_mode=1;
2169 else
2170 msp->i2s_mode=0;
2171 }
2172 msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
2173 a->index,msp->i2s_mode);
2174 msp3400c_set_scart(client,msp->in_scart,a->index+1);
1811 2175
1812 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1813 msp3400c_set_scart(client, mspm->input, mspm->output);
1814 break; 2176 break;
1815 } 2177 }
1816 2178
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1823 2185
1824static int msp_suspend(struct device * dev, pm_message_t state) 2186static int msp_suspend(struct device * dev, pm_message_t state)
1825{ 2187{
1826 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2188 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1827 2189
1828 dprintk("msp34xx: suspend\n"); 2190 msp3400_dbg("msp34xx: suspend\n");
1829 msp3400c_reset(c); 2191 msp3400c_reset(client);
1830 return 0; 2192 return 0;
1831} 2193}
1832 2194
1833static int msp_resume(struct device * dev) 2195static int msp_resume(struct device * dev)
1834{ 2196{
1835 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2197 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1836 2198
1837 dprintk("msp34xx: resume\n"); 2199 msp3400_dbg("msp34xx: resume\n");
1838 msp_wake_thread(c); 2200 msp_wake_thread(client);
1839 return 0; 2201 return 0;
1840} 2202}
1841 2203
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 972aa5e0aeef..2180018f06de 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c,
76 unsigned int xogc) //all in Hz 76 unsigned int xogc) //all in Hz
77{ 77{
78 struct tuner *t = i2c_get_clientdata(c); 78 struct tuner *t = i2c_get_clientdata(c);
79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, 79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; 80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
81 81
82 fref= 5250 *1000; //5.25MHz 82 fref= 5250 *1000; //5.25MHz
83 desired_lo1=rfin+if1; 83 desired_lo1=rfin+if1;
84 84
85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); 85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
86 lo1n=lo1/8; 86 lo1n=lo1/8;
87 lo1a=lo1-(lo1n*8); 87 lo1a=lo1-(lo1n*8);
88 88
89 s=rfin/1000/1000+1090; 89 s=rfin/1000/1000+1090;
90 90
91 if(optimize_vco) { 91 if(optimize_vco) {
92 if(s>1890) sel=0; 92 if(s>1890) sel=0;
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c,
96 else sel=4; // >1090 96 else sel=4; // >1090
97 } 97 }
98 else { 98 else {
99 if(s>1790) sel=0; // <1958 99 if(s>1790) sel=0; // <1958
100 else if(s>1617) sel=1; 100 else if(s>1617) sel=1;
101 else if(s>1449) sel=2; 101 else if(s>1449) sel=2;
102 else if(s>1291) sel=3; 102 else if(s>1291) sel=3;
103 else sel=4; // >1090 103 else sel=4; // >1090
104 } 104 }
105 *ret_sel=sel; 105 *ret_sel=sel;
106 106
107 lo1freq=(lo1a+8*lo1n)*fref; 107 lo1freq=(lo1a+8*lo1n)*fref;
108 108
109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", 109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
110 rfin,lo1,lo1n,lo1a,sel,lo1freq); 110 rfin,lo1,lo1n,lo1a,sel,lo1freq);
111 111
112 desired_lo2=lo1freq-rfin-if2; 112 desired_lo2=lo1freq-rfin-if2;
113 lo2=(desired_lo2)/fref; 113 lo2=(desired_lo2)/fref;
114 lo2n=lo2/8; 114 lo2n=lo2/8;
115 lo2a=lo2-(lo2n*8); 115 lo2a=lo2-(lo2n*8);
116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith 116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; 117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
118 118
119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", 119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq); 120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
121 121
122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { 122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", 123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
124 lo1a, lo1n, lo2a,lo2n); 124 lo1a, lo1n, lo2a,lo2n);
125 return(-1); 125 return(-1);
126 } 126 }
127 127
128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); 128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
129 // should recalculate lo1 (one step up/down) 129 // should recalculate lo1 (one step up/down)
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c,
135 buf[3]=0x0f; //reserved 135 buf[3]=0x0f; //reserved
136 buf[4]=0x1f; 136 buf[4]=0x1f;
137 buf[5]=(lo2n-1) | (lo2a<<5); 137 buf[5]=(lo2n-1) | (lo2a<<5);
138 if(rfin >400*1000*1000) 138 if(rfin >400*1000*1000)
139 buf[6]=0xe4; 139 buf[6]=0xe4;
140 else 140 else
141 buf[6]=0xf4; // set PKEN per rev 1.2 141 buf[6]=0xf4; // set PKEN per rev 1.2
142 buf[7]=8+xogc; 142 buf[7]=8+xogc;
143 buf[8]=0xc3; //reserved 143 buf[8]=0xc3; //reserved
144 buf[9]=0x4e; //reserved 144 buf[9]=0x4e; //reserved
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); 168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
169 udelay(1000); 169 udelay(1000);
170 } 170 }
171 return lock; 171 return lock;
172} 172}
173 173
174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) 174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
202 202
203 buf[0]=0x0f; 203 buf[0]=0x0f;
204 buf[1]=sel; 204 buf[1]=sel;
205 i2c_master_send(c,buf,2); 205 i2c_master_send(c,buf,2);
206 lock=mt2032_check_lo_lock(c); 206 lock=mt2032_check_lo_lock(c);
207 return lock; 207 return lock;
208} 208}
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", 219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
220 rfin,if1,if2,from,to); 220 rfin,if1,if2,from,to);
221 221
222 buf[0]=0; 222 buf[0]=0;
223 ret=i2c_master_send(c,buf,1); 223 ret=i2c_master_send(c,buf,1);
224 i2c_master_recv(c,buf,21); 224 i2c_master_recv(c,buf,21);
225 225
226 buf[0]=0; 226 buf[0]=0;
227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); 227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
228 if (ret<0) 228 if (ret<0)
229 return; 229 return;
230 230
231 // send only the relevant registers per Rev. 1.2 231 // send only the relevant registers per Rev. 1.2
232 buf[0]=0; 232 buf[0]=0;
233 ret=i2c_master_send(c,buf,4); 233 ret=i2c_master_send(c,buf,4);
234 buf[5]=5; 234 buf[5]=5;
235 ret=i2c_master_send(c,buf+5,4); 235 ret=i2c_master_send(c,buf+5,4);
236 buf[11]=11; 236 buf[11]=11;
237 ret=i2c_master_send(c,buf+11,3); 237 ret=i2c_master_send(c,buf+11,3);
238 if(ret!=3) 238 if(ret!=3)
239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); 239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
240 240
241 // wait for PLLs to lock (per manual), retry LINT if not. 241 // wait for PLLs to lock (per manual), retry LINT if not.
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
253 mdelay(10); 253 mdelay(10);
254 buf[1]=8+t->xogc; 254 buf[1]=8+t->xogc;
255 i2c_master_send(c,buf,2); 255 i2c_master_send(c,buf,2);
256 } 256 }
257 257
258 if (lock!=6) 258 if (lock!=6)
259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); 259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
284 if2 = 38900*1000; 284 if2 = 38900*1000;
285 } 285 }
286 286
287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, 287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
288 1090*1000*1000, if2, from, to); 288 1090*1000*1000, if2, from, to);
289} 289}
290 290
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
294 int if2 = t->radio_if2; 294 int if2 = t->radio_if2;
295 295
296 // per Manual for FM tuning: first if center freq. 1085 MHz 296 // per Manual for FM tuning: first if center freq. 1085 MHz
297 mt2032_set_if_freq(c, freq * 1000 / 16, 297 mt2032_set_if_freq(c, freq * 1000 / 16,
298 1085*1000*1000,if2,if2,if2); 298 1085*1000*1000,if2,if2,if2);
299} 299}
300 300
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
302static int mt2032_init(struct i2c_client *c) 302static int mt2032_init(struct i2c_client *c)
303{ 303{
304 struct tuner *t = i2c_get_clientdata(c); 304 struct tuner *t = i2c_get_clientdata(c);
305 unsigned char buf[21]; 305 unsigned char buf[21];
306 int ret,xogc,xok=0; 306 int ret,xogc,xok=0;
307 307
308 // Initialize Registers per spec. 308 // Initialize Registers per spec.
309 buf[1]=2; // Index to register 2 309 buf[1]=2; // Index to register 2
310 buf[2]=0xff; 310 buf[2]=0xff;
311 buf[3]=0x0f; 311 buf[3]=0x0f;
312 buf[4]=0x1f; 312 buf[4]=0x1f;
313 ret=i2c_master_send(c,buf+1,4); 313 ret=i2c_master_send(c,buf+1,4);
314 314
315 buf[5]=6; // Index register 6 315 buf[5]=6; // Index register 6
316 buf[6]=0xe4; 316 buf[6]=0xe4;
317 buf[7]=0x8f; 317 buf[7]=0x8f;
318 buf[8]=0xc3; 318 buf[8]=0xc3;
319 buf[9]=0x4e; 319 buf[9]=0x4e;
320 buf[10]=0xec; 320 buf[10]=0xec;
321 ret=i2c_master_send(c,buf+5,6); 321 ret=i2c_master_send(c,buf+5,6);
322 322
323 buf[12]=13; // Index register 13 323 buf[12]=13; // Index register 13
324 buf[13]=0x32; 324 buf[13]=0x32;
325 ret=i2c_master_send(c,buf+12,2); 325 ret=i2c_master_send(c,buf+12,2);
326 326
327 // Adjust XOGC (register 7), wait for XOK 327 // Adjust XOGC (register 7), wait for XOK
328 xogc=7; 328 xogc=7;
329 do { 329 do {
330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
331 mdelay(10); 331 mdelay(10);
332 buf[0]=0x0e; 332 buf[0]=0x0e;
333 i2c_master_send(c,buf,1); 333 i2c_master_send(c,buf,1);
334 i2c_master_recv(c,buf,1); 334 i2c_master_recv(c,buf,1);
335 xok=buf[0]&0x01; 335 xok=buf[0]&0x01;
336 tuner_dbg("mt2032: xok = 0x%02x\n",xok); 336 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
337 if (xok == 1) break; 337 if (xok == 1) break;
338 338
339 xogc--; 339 xogc--;
340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
341 if (xogc == 3) { 341 if (xogc == 3) {
342 xogc=4; // min. 4 per spec 342 xogc=4; // min. 4 per spec
343 break; 343 break;
344 } 344 }
345 buf[0]=0x07; 345 buf[0]=0x07;
346 buf[1]=0x88 + xogc; 346 buf[1]=0x88 + xogc;
347 ret=i2c_master_send(c,buf,2); 347 ret=i2c_master_send(c,buf,2);
348 if (ret!=2) 348 if (ret!=2)
349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
350 } while (xok != 1 ); 350 } while (xok != 1 );
351 t->xogc=xogc; 351 t->xogc=xogc;
352 352
353 t->tv_freq = mt2032_set_tv_freq; 353 t->tv_freq = mt2032_set_tv_freq;
354 t->radio_freq = mt2032_set_radio_freq; 354 t->radio_freq = mt2032_set_radio_freq;
355 return(1); 355 return(1);
356} 356}
357 357
358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) 358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
426 } 426 }
427 427
428 ret=i2c_master_send(c,buf,6); 428 ret=i2c_master_send(c,buf,6);
429 if (ret!=6) 429 if (ret!=6)
430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); 430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
431} 431}
432 432
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
437 437
438 if (t->std & V4L2_STD_525_60) { 438 if (t->std & V4L2_STD_525_60) {
439 // NTSC 439 // NTSC
440 if2 = 45750*1000; 440 if2 = 45750*1000;
441 } else { 441 } else {
442 // PAL 442 // PAL
443 if2 = 38900*1000; 443 if2 = 38900*1000;
444 } 444 }
445 if (V4L2_TUNER_DIGITAL_TV == t->mode) { 445 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
446 // DVB (pinnacle 300i) 446 // DVB (pinnacle 300i)
447 if2 = 36150*1000; 447 if2 = 36150*1000;
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455 struct tuner *t = i2c_get_clientdata(c); 455 struct tuner *t = i2c_get_clientdata(c);
456 int if2 = t->radio_if2; 456 int if2 = t->radio_if2;
457 457
458 mt2050_set_if_freq(c, freq*62500, if2); 458 mt2050_set_if_freq(c, freq * 1000 / 16, if2);
459 mt2050_set_antenna(c, radio_antenna); 459 mt2050_set_antenna(c, radio_antenna);
460} 460}
461 461
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c)
487{ 487{
488 struct tuner *t = i2c_get_clientdata(c); 488 struct tuner *t = i2c_get_clientdata(c);
489 char *name; 489 char *name;
490 unsigned char buf[21]; 490 unsigned char buf[21];
491 int company_code; 491 int company_code;
492 492
493 memset(buf,0,sizeof(buf)); 493 memset(buf,0,sizeof(buf));
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c)
496 t->standby = NULL; 496 t->standby = NULL;
497 name = "unknown"; 497 name = "unknown";
498 498
499 i2c_master_send(c,buf,1); 499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21); 500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) { 501 if (tuner_debug) {
502 int i; 502 int i;
503 tuner_dbg("MT20xx hexdump:"); 503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) { 504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]); 505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" "); 506 if(((i+1)%8)==0) printk(" ");
507 } 507 }
508 printk("\n"); 508 printk("\n");
509 } 509 }
510 company_code = buf[0x11] << 8 | buf[0x12]; 510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]); 512 company_code,buf[0x13],buf[0x14]);
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c)
525 default: 525 default:
526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", 526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
527 name); 527 name);
528 return 0; 528 return 0;
529 } 529 }
530 530
531 strlcpy(c->name, name, sizeof(c->name)); 531 strlcpy(c->name, name, sizeof(c->name));
532 tuner_info("microtune %s found, OK\n",name); 532 tuner_info("microtune %s found, OK\n",name);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 72b70eb5da1d..dca3ddfd510f 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
31#include <linux/wait.h> 31#include <linux/wait.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33 33
34#include <media/id.h>
35 34
36#include "rds.h" 35#include "rds.h"
37 36
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
246 s->wr_index = 0; 245 s->wr_index = 0;
247 246
248 if (s->wr_index == s->rd_index) { 247 if (s->wr_index == s->rd_index) {
249 s->rd_index++; 248 s->rd_index += 3;
250 if (s->rd_index >= s->buf_size) 249 if (s->rd_index >= s->buf_size)
251 s->rd_index = 0; 250 s->rd_index = 0;
252 } else 251 } else
@@ -328,7 +327,7 @@ static void saa6588_work(void *data)
328 struct saa6588 *s = (struct saa6588 *)data; 327 struct saa6588 *s = (struct saa6588 *)data;
329 328
330 saa6588_i2c_poll(s); 329 saa6588_i2c_poll(s);
331 mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */ 330 mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
332} 331}
333 332
334static int saa6588_configure(struct saa6588 *s) 333static int saa6588_configure(struct saa6588 *s)
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap)
434 return i2c_probe(adap, &addr_data, saa6588_attach); 433 return i2c_probe(adap, &addr_data, saa6588_attach);
435#else 434#else
436 switch (adap->id) { 435 switch (adap->id) {
437 case I2C_ALGO_BIT | I2C_HW_B_BT848: 436 case I2C_HW_B_BT848:
438 case I2C_ALGO_BIT | I2C_HW_B_RIVA: 437 case I2C_HW_B_RIVA:
439 case I2C_ALGO_SAA7134: 438 case I2C_HW_SAA7134:
440 return i2c_probe(adap, &addr_data, saa6588_attach); 439 return i2c_probe(adap, &addr_data, saa6588_attach);
441 break; 440 break;
442 } 441 }
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
new file mode 100644
index 000000000000..9aa8827de2c3
--- /dev/null
+++ b/drivers/media/video/saa711x.c
@@ -0,0 +1,593 @@
1/*
2 * saa711x - Philips SAA711x video decoder driver version 0.0.1
3 *
4 * To do: Now, it handles only saa7113/7114. Should be improved to
5 * handle all Philips saa711x devices.
6 *
7 * Based on saa7113 driver from Dave Perks <dperks@ibm.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/kernel.h>
30#include <linux/major.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/pci.h>
34#include <linux/signal.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/segment.h>
40#include <linux/types.h>
41#include <asm/uaccess.h>
42#include <linux/videodev.h>
43
44MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
45MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
46MODULE_LICENSE("GPL");
47
48#include <linux/i2c.h>
49#include <linux/i2c-dev.h>
50
51#define I2C_NAME(s) (s)->name
52
53#include <linux/video_decoder.h>
54
55static int debug = 0;
56MODULE_PARM(debug, "i");
57MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
58
59
60#define dprintk(num, format, args...) \
61 do { \
62 if (debug >= num) \
63 printk(format , ##args); \
64 } while (0)
65
66/* ----------------------------------------------------------------------- */
67
68struct saa711x {
69 unsigned char reg[32];
70
71 int norm;
72 int input;
73 int enable;
74 int bright;
75 int contrast;
76 int hue;
77 int sat;
78};
79
80#define I2C_SAA7113 0x4A
81#define I2C_SAA7114 0x42
82
83/* ----------------------------------------------------------------------- */
84
85static inline int
86saa711x_write (struct i2c_client *client,
87 u8 reg,
88 u8 value)
89{
90 struct saa711x *decoder = i2c_get_clientdata(client);
91
92 decoder->reg[reg] = value;
93 return i2c_smbus_write_byte_data(client, reg, value);
94}
95
96static int
97saa711x_write_block (struct i2c_client *client,
98 const u8 *data,
99 unsigned int len)
100{
101 int ret = -1;
102 u8 reg;
103
104 /* the saa711x has an autoincrement function, use it if
105 * the adapter understands raw I2C */
106 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
107 /* do raw I2C, not smbus compatible */
108 struct saa711x *decoder = i2c_get_clientdata(client);
109 struct i2c_msg msg;
110 u8 block_data[32];
111
112 msg.addr = client->addr;
113 msg.flags = 0;
114 while (len >= 2) {
115 msg.buf = (char *) block_data;
116 msg.len = 0;
117 block_data[msg.len++] = reg = data[0];
118 do {
119 block_data[msg.len++] =
120 decoder->reg[reg++] = data[1];
121 len -= 2;
122 data += 2;
123 } while (len >= 2 && data[0] == reg &&
124 msg.len < 32);
125 if ((ret = i2c_transfer(client->adapter,
126 &msg, 1)) < 0)
127 break;
128 }
129 } else {
130 /* do some slow I2C emulation kind of thing */
131 while (len >= 2) {
132 reg = *data++;
133 if ((ret = saa711x_write(client, reg,
134 *data++)) < 0)
135 break;
136 len -= 2;
137 }
138 }
139
140 return ret;
141}
142
143static int
144saa711x_init_decoder (struct i2c_client *client,
145 struct video_decoder_init *init)
146{
147 return saa711x_write_block(client, init->data, init->len);
148}
149
150static inline int
151saa711x_read (struct i2c_client *client,
152 u8 reg)
153{
154 return i2c_smbus_read_byte_data(client, reg);
155}
156
157/* ----------------------------------------------------------------------- */
158
159static const unsigned char saa711x_i2c_init[] = {
160 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
161 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
162 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
163 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
164 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
165 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
166 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
167 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
168 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
169 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
170 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
171 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
172 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
173 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
174 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
175 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
176 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
177 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
178 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
179 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
180 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
181 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
182 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
183 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
184};
185
186static int
187saa711x_command (struct i2c_client *client,
188 unsigned int cmd,
189 void *arg)
190{
191 struct saa711x *decoder = i2c_get_clientdata(client);
192
193 switch (cmd) {
194
195 case 0:
196 case DECODER_INIT:
197 {
198 struct video_decoder_init *init = arg;
199 if (NULL != init)
200 return saa711x_init_decoder(client, init);
201 else {
202 struct video_decoder_init vdi;
203 vdi.data = saa711x_i2c_init;
204 vdi.len = sizeof(saa711x_i2c_init);
205 return saa711x_init_decoder(client, &vdi);
206 }
207 }
208
209 case DECODER_DUMP:
210 {
211 int i;
212
213 for (i = 0; i < 32; i += 16) {
214 int j;
215
216 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
217 for (j = 0; j < 16; ++j) {
218 printk(" %02x",
219 saa711x_read(client, i + j));
220 }
221 printk("\n");
222 }
223 }
224 break;
225
226 case DECODER_GET_CAPABILITIES:
227 {
228 struct video_decoder_capability *cap = arg;
229
230 cap->flags = VIDEO_DECODER_PAL |
231 VIDEO_DECODER_NTSC |
232 VIDEO_DECODER_SECAM |
233 VIDEO_DECODER_AUTO |
234 VIDEO_DECODER_CCIR;
235 cap->inputs = 8;
236 cap->outputs = 1;
237 }
238 break;
239
240 case DECODER_GET_STATUS:
241 {
242 int *iarg = arg;
243 int status;
244 int res;
245
246 status = saa711x_read(client, 0x1f);
247 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
248 status);
249 res = 0;
250 if ((status & (1 << 6)) == 0) {
251 res |= DECODER_STATUS_GOOD;
252 }
253 switch (decoder->norm) {
254 case VIDEO_MODE_NTSC:
255 res |= DECODER_STATUS_NTSC;
256 break;
257 case VIDEO_MODE_PAL:
258 res |= DECODER_STATUS_PAL;
259 break;
260 case VIDEO_MODE_SECAM:
261 res |= DECODER_STATUS_SECAM;
262 break;
263 default:
264 case VIDEO_MODE_AUTO:
265 if ((status & (1 << 5)) != 0) {
266 res |= DECODER_STATUS_NTSC;
267 } else {
268 res |= DECODER_STATUS_PAL;
269 }
270 break;
271 }
272 if ((status & (1 << 0)) != 0) {
273 res |= DECODER_STATUS_COLOR;
274 }
275 *iarg = res;
276 }
277 break;
278
279 case DECODER_SET_GPIO:
280 {
281 int *iarg = arg;
282 if (0 != *iarg) {
283 saa711x_write(client, 0x11,
284 (decoder->reg[0x11] | 0x80));
285 } else {
286 saa711x_write(client, 0x11,
287 (decoder->reg[0x11] & 0x7f));
288 }
289 break;
290 }
291
292 case DECODER_SET_VBI_BYPASS:
293 {
294 int *iarg = arg;
295 if (0 != *iarg) {
296 saa711x_write(client, 0x13,
297 (decoder->reg[0x13] & 0xf0) | 0x0a);
298 } else {
299 saa711x_write(client, 0x13,
300 (decoder->reg[0x13] & 0xf0));
301 }
302 break;
303 }
304
305 case DECODER_SET_NORM:
306 {
307 int *iarg = arg;
308
309 switch (*iarg) {
310
311 case VIDEO_MODE_NTSC:
312 saa711x_write(client, 0x08,
313 (decoder->reg[0x08] & 0x3f) | 0x40);
314 saa711x_write(client, 0x0e,
315 (decoder->reg[0x0e] & 0x8f));
316 break;
317
318 case VIDEO_MODE_PAL:
319 saa711x_write(client, 0x08,
320 (decoder->reg[0x08] & 0x3f) | 0x00);
321 saa711x_write(client, 0x0e,
322 (decoder->reg[0x0e] & 0x8f));
323 break;
324
325 case VIDEO_MODE_SECAM:
326 saa711x_write(client, 0x08,
327 (decoder->reg[0x0e] & 0x3f) | 0x00);
328 saa711x_write(client, 0x0e,
329 (decoder->reg[0x0e] & 0x8f) | 0x50);
330 break;
331
332 case VIDEO_MODE_AUTO:
333 saa711x_write(client, 0x08,
334 (decoder->reg[0x08] & 0x3f) | 0x80);
335 saa711x_write(client, 0x0e,
336 (decoder->reg[0x0e] & 0x8f));
337 break;
338
339 default:
340 return -EINVAL;
341
342 }
343 decoder->norm = *iarg;
344 }
345 break;
346
347 case DECODER_SET_INPUT:
348 {
349 int *iarg = arg;
350 if (*iarg < 0 || *iarg > 9) {
351 return -EINVAL;
352 }
353 if (decoder->input != *iarg) {
354 decoder->input = *iarg;
355 /* select mode */
356 saa711x_write(client, 0x02,
357 (decoder->reg[0x02] & 0xf0) | decoder->input);
358 /* bypass chrominance trap for modes 4..7 */
359 saa711x_write(client, 0x09,
360 (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
361 }
362 }
363 break;
364
365 case DECODER_SET_OUTPUT:
366 {
367 int *iarg = arg;
368
369 /* not much choice of outputs */
370 if (*iarg != 0) {
371 return -EINVAL;
372 }
373 }
374 break;
375
376 case DECODER_ENABLE_OUTPUT:
377 {
378 int *iarg = arg;
379 int enable = (*iarg != 0);
380
381 if (decoder->enable != enable) {
382 decoder->enable = enable;
383
384 /* RJ: If output should be disabled (for
385 * playing videos), we also need a open PLL.
386 * The input is set to 0 (where no input
387 * source is connected), although this
388 * is not necessary.
389 *
390 * If output should be enabled, we have to
391 * reverse the above.
392 */
393
394 if (decoder->enable) {
395 saa711x_write(client, 0x02,
396 (decoder->
397 reg[0x02] & 0xf8) |
398 decoder->input);
399 saa711x_write(client, 0x08,
400 (decoder->reg[0x08] & 0xfb));
401 saa711x_write(client, 0x11,
402 (decoder->
403 reg[0x11] & 0xf3) | 0x0c);
404 } else {
405 saa711x_write(client, 0x02,
406 (decoder->reg[0x02] & 0xf8));
407 saa711x_write(client, 0x08,
408 (decoder->
409 reg[0x08] & 0xfb) | 0x04);
410 saa711x_write(client, 0x11,
411 (decoder->reg[0x11] & 0xf3));
412 }
413 }
414 }
415 break;
416
417 case DECODER_SET_PICTURE:
418 {
419 struct video_picture *pic = arg;
420
421 if (decoder->bright != pic->brightness) {
422 /* We want 0 to 255 we get 0-65535 */
423 decoder->bright = pic->brightness;
424 saa711x_write(client, 0x0a, decoder->bright >> 8);
425 }
426 if (decoder->contrast != pic->contrast) {
427 /* We want 0 to 127 we get 0-65535 */
428 decoder->contrast = pic->contrast;
429 saa711x_write(client, 0x0b,
430 decoder->contrast >> 9);
431 }
432 if (decoder->sat != pic->colour) {
433 /* We want 0 to 127 we get 0-65535 */
434 decoder->sat = pic->colour;
435 saa711x_write(client, 0x0c, decoder->sat >> 9);
436 }
437 if (decoder->hue != pic->hue) {
438 /* We want -128 to 127 we get 0-65535 */
439 decoder->hue = pic->hue;
440 saa711x_write(client, 0x0d,
441 (decoder->hue - 32768) >> 8);
442 }
443 }
444 break;
445
446 default:
447 return -EINVAL;
448 }
449
450 return 0;
451}
452
453/* ----------------------------------------------------------------------- */
454
455/*
456 * Generic i2c probe
457 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
458 */
459
460/* standard i2c insmod options */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7113>>1, /* saa7113 */
463 I2C_SAA7114>>1, /* saa7114 */
464 I2C_CLIENT_END
465};
466
467I2C_CLIENT_INSMOD;
468
469
470static struct i2c_driver i2c_driver_saa711x;
471
472static int
473saa711x_detect_client (struct i2c_adapter *adapter,
474 int address,
475 int kind)
476{
477 int i;
478 struct i2c_client *client;
479 struct saa711x *decoder;
480 struct video_decoder_init vdi;
481
482 dprintk(1,
483 KERN_INFO
484 "saa711x.c: detecting saa711x client on address 0x%x\n",
485 address << 1);
486
487 /* Check if the adapter supports the needed features */
488 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
489 return 0;
490
491 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
492 if (client == 0)
493 return -ENOMEM;
494 memset(client, 0, sizeof(struct i2c_client));
495 client->addr = address;
496 client->adapter = adapter;
497 client->driver = &i2c_driver_saa711x;
498 client->flags = I2C_CLIENT_ALLOW_USE;
499 strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
500 decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
501 if (decoder == NULL) {
502 kfree(client);
503 return -ENOMEM;
504 }
505 memset(decoder, 0, sizeof(struct saa711x));
506 decoder->norm = VIDEO_MODE_NTSC;
507 decoder->input = 0;
508 decoder->enable = 1;
509 decoder->bright = 32768;
510 decoder->contrast = 32768;
511 decoder->hue = 32768;
512 decoder->sat = 32768;
513 i2c_set_clientdata(client, decoder);
514
515 i = i2c_attach_client(client);
516 if (i) {
517 kfree(client);
518 kfree(decoder);
519 return i;
520 }
521
522 vdi.data = saa711x_i2c_init;
523 vdi.len = sizeof(saa711x_i2c_init);
524 i = saa711x_init_decoder(client, &vdi);
525 if (i < 0) {
526 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
527 I2C_NAME(client), i);
528 } else {
529 dprintk(1,
530 KERN_INFO
531 "%s_attach: chip version %x at address 0x%x\n",
532 I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
533 client->addr << 1);
534 }
535
536 return 0;
537}
538
539static int
540saa711x_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,
543 KERN_INFO
544 "saa711x.c: starting probe for adapter %s (0x%x)\n",
545 I2C_NAME(adapter), adapter->id);
546 return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
547}
548
549static int
550saa711x_detach_client (struct i2c_client *client)
551{
552 struct saa711x *decoder = i2c_get_clientdata(client);
553 int err;
554
555 err = i2c_detach_client(client);
556 if (err) {
557 return err;
558 }
559
560 kfree(decoder);
561 kfree(client);
562
563 return 0;
564}
565
566/* ----------------------------------------------------------------------- */
567
568static struct i2c_driver i2c_driver_saa711x = {
569 .owner = THIS_MODULE,
570 .name = "saa711x",
571
572 .id = I2C_DRIVERID_SAA711X,
573 .flags = I2C_DF_NOTIFY,
574
575 .attach_adapter = saa711x_attach_adapter,
576 .detach_client = saa711x_detach_client,
577 .command = saa711x_command,
578};
579
580static int __init
581saa711x_init (void)
582{
583 return i2c_add_driver(&i2c_driver_saa711x);
584}
585
586static void __exit
587saa711x_exit (void)
588{
589 i2c_del_driver(&i2c_driver_saa711x);
590}
591
592module_init(saa711x_init);
593module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
new file mode 100644
index 000000000000..624e8808a517
--- /dev/null
+++ b/drivers/media/video/saa7134/Kconfig
@@ -0,0 +1,68 @@
1config VIDEO_SAA7134
2 tristate "Philips SAA7134 support"
3 depends on VIDEO_DEV && PCI && I2C && SOUND
4 select VIDEO_BUF
5 select VIDEO_IR
6 select VIDEO_TUNER
7 select CRC32
8 ---help---
9 This is a video4linux driver for Philips SAA713x based
10 TV cards.
11
12 To compile this driver as a module, choose M here: the
13 module will be called saa7134.
14
15config VIDEO_SAA7134_DVB
16 tristate "DVB/ATSC Support for saa7134 based TV cards"
17 depends on VIDEO_SAA7134 && DVB_CORE
18 select VIDEO_BUF_DVB
19 ---help---
20 This adds support for DVB cards based on the
21 Philips saa7134 chip.
22
23 To compile this driver as a module, choose M here: the
24 module will be called saa7134-dvb.
25
26 You must also select one or more DVB demodulators.
27 If you are unsure which you need, choose all of them.
28
29config VIDEO_SAA7134_DVB_ALL_FRONTENDS
30 bool "Build all supported frontends for saa7134 based TV cards"
31 default y
32 depends on VIDEO_SAA7134_DVB
33 select DVB_MT352
34 select DVB_TDA1004X
35 select DVB_NXT200X
36 ---help---
37 This builds saa7134-dvb with all currently supported frontend
38 demodulators. If you wish to tweak your configuration, and
39 only include support for the hardware that you need, choose N here.
40
41 If you are unsure, choose Y.
42
43config VIDEO_SAA7134_DVB_MT352
44 tristate "Zarlink MT352 DVB-T Support"
45 default m
46 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
47 select DVB_MT352
48 ---help---
49 This adds DVB-T support for cards based on the
50 Philips saa7134 chip and the MT352 demodulator.
51
52config VIDEO_SAA7134_DVB_TDA1004X
53 tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
54 default m
55 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
56 select DVB_TDA1004X
57 ---help---
58 This adds DVB-T support for cards based on the
59 Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
60
61config VIDEO_SAA7134_DVB_NXT200X
62 tristate "NXT2002/NXT2004 ATSC Support"
63 default m
64 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
65 select DVB_NXT200X
66 ---help---
67 This adds ATSC 8VSB and QAM64/256 support for cards based on the
68 Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index b778ffd94e65..e0b28f0533af 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ 3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o 4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5 5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o 6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
7 saa6752hs.o saa7134-alsa.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 8obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8 9
9EXTRA_CFLAGS += -I$(src)/.. 10EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 12EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
13ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
14 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
15endif
12ifneq ($(CONFIG_DVB_MT352),n) 16ifneq ($(CONFIG_DVB_MT352),n)
13 EXTRA_CFLAGS += -DHAVE_MT352=1 17 EXTRA_CFLAGS += -DHAVE_MT352=1
14endif 18endif
15ifneq ($(CONFIG_DVB_TDA1004X),n) 19ifneq ($(CONFIG_DVB_TDA1004X),n)
16 EXTRA_CFLAGS += -DHAVE_TDA1004X=1 20 EXTRA_CFLAGS += -DHAVE_TDA1004X=1
17endif 21endif
22ifneq ($(CONFIG_DVB_NXT200X),n)
23 EXTRA_CFLAGS += -DHAVE_NXT200X=1
24endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 382911c6ef22..cdd1ed9c8065 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/crc32.h> 14#include <linux/crc32.h>
15 15
16#include <media/id.h>
17 16
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 17#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 18#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -57,6 +56,7 @@ struct saa6752hs_state {
57 struct i2c_client client; 56 struct i2c_client client;
58 struct v4l2_mpeg_compression params; 57 struct v4l2_mpeg_compression params;
59 enum saa6752hs_videoformat video_format; 58 enum saa6752hs_videoformat video_format;
59 v4l2_std_id standard;
60}; 60};
61 61
62enum saa6752hs_command { 62enum saa6752hs_command {
@@ -74,58 +74,58 @@ enum saa6752hs_command {
74/* ---------------------------------------------------------------------- */ 74/* ---------------------------------------------------------------------- */
75 75
76static u8 PAT[] = { 76static u8 PAT[] = {
77 0xc2, // i2c register 77 0xc2, /* i2c register */
78 0x00, // table number for encoder 78 0x00, /* table number for encoder */
79 79
80 0x47, // sync 80 0x47, /* sync */
81 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) 81 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
82 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 82 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
83 83
84 0x00, // PSI pointer to start of table 84 0x00, /* PSI pointer to start of table */
85 85
86 0x00, // tid(0) 86 0x00, /* tid(0) */
87 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13) 87 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
88 88
89 0x00, 0x01, // transport_stream_id(1) 89 0x00, 0x01, /* transport_stream_id(1) */
90 90
91 0xc1, // version_number(0), current_next_indicator(1) 91 0xc1, /* version_number(0), current_next_indicator(1) */
92 92
93 0x00, 0x00, // section_number(0), last_section_number(0) 93 0x00, 0x00, /* section_number(0), last_section_number(0) */
94 94
95 0x00, 0x01, // program_number(1) 95 0x00, 0x01, /* program_number(1) */
96 96
97 0xe0, 0x00, // PMT PID 97 0xe0, 0x00, /* PMT PID */
98 98
99 0x00, 0x00, 0x00, 0x00 // CRC32 99 0x00, 0x00, 0x00, 0x00 /* CRC32 */
100}; 100};
101 101
102static u8 PMT[] = { 102static u8 PMT[] = {
103 0xc2, // i2c register 103 0xc2, /* i2c register */
104 0x01, // table number for encoder 104 0x01, /* table number for encoder */
105 105
106 0x47, // sync 106 0x47, /* sync */
107 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid 107 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
108 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 108 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
109 109
110 0x00, // PSI pointer to start of table 110 0x00, /* PSI pointer to start of table */
111 111
112 0x02, // tid(2) 112 0x02, /* tid(2) */
113 0xb0, 0x17, // section_syntax_indicator(1), section_length(23) 113 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
114 114
115 0x00, 0x01, // program_number(1) 115 0x00, 0x01, /* program_number(1) */
116 116
117 0xc1, // version_number(0), current_next_indicator(1) 117 0xc1, /* version_number(0), current_next_indicator(1) */
118 118
119 0x00, 0x00, // section_number(0), last_section_number(0) 119 0x00, 0x00, /* section_number(0), last_section_number(0) */
120 120
121 0xe0, 0x00, // PCR_PID 121 0xe0, 0x00, /* PCR_PID */
122 122
123 0xf0, 0x00, // program_info_length(0) 123 0xf0, 0x00, /* program_info_length(0) */
124 124
125 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid 125 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
126 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid 126 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
127 127
128 0x00, 0x00, 0x00, 0x00 // CRC32 128 0x00, 0x00, 0x00, 0x00 /* CRC32 */
129}; 129};
130 130
131static struct v4l2_mpeg_compression param_defaults = 131static struct v4l2_mpeg_compression param_defaults =
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
166 unsigned long timeout; 166 unsigned long timeout;
167 int status = 0; 167 int status = 0;
168 168
169 // execute the command 169 /* execute the command */
170 switch(command) { 170 switch(command) {
171 case SAA6752HS_COMMAND_RESET: 171 case SAA6752HS_COMMAND_RESET:
172 buf[0] = 0x00; 172 buf[0] = 0x00;
173 break; 173 break;
174 174
175 case SAA6752HS_COMMAND_STOP: 175 case SAA6752HS_COMMAND_STOP:
176 buf[0] = 0x03; 176 buf[0] = 0x03;
177 break; 177 break;
178 178
179 case SAA6752HS_COMMAND_START: 179 case SAA6752HS_COMMAND_START:
180 buf[0] = 0x02; 180 buf[0] = 0x02;
181 break; 181 break;
182 182
183 case SAA6752HS_COMMAND_PAUSE: 183 case SAA6752HS_COMMAND_PAUSE:
184 buf[0] = 0x04; 184 buf[0] = 0x04;
185 break; 185 break;
186 186
187 case SAA6752HS_COMMAND_RECONFIGURE: 187 case SAA6752HS_COMMAND_RECONFIGURE:
188 buf[0] = 0x05; 188 buf[0] = 0x05;
189 break; 189 break;
190 190
191 case SAA6752HS_COMMAND_SLEEP: 191 case SAA6752HS_COMMAND_SLEEP:
192 buf[0] = 0x06; 192 buf[0] = 0x06;
193 break; 193 break;
194 194
195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE: 195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
196 buf[0] = 0x07; 196 buf[0] = 0x07;
197 break; 197 break;
198 198
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
200 return -EINVAL; 200 return -EINVAL;
201 } 201 }
202 202
203 // set it and wait for it to be so 203 /* set it and wait for it to be so */
204 i2c_master_send(client, buf, 1); 204 i2c_master_send(client, buf, 1);
205 timeout = jiffies + HZ * 3; 205 timeout = jiffies + HZ * 3;
206 for (;;) { 206 for (;;) {
207 // get the current status 207 /* get the current status */
208 buf[0] = 0x10; 208 buf[0] = 0x10;
209 i2c_master_send(client, buf, 1); 209 i2c_master_send(client, buf, 1);
210 i2c_master_recv(client, buf, 1); 210 i2c_master_recv(client, buf, 1);
211 211
212 if (!(buf[0] & 0x20)) 212 if (!(buf[0] & 0x20))
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
216 break; 216 break;
217 } 217 }
218 218
219 // wait a bit
220 msleep(10); 219 msleep(10);
221 } 220 }
222 221
223 // delay a bit to let encoder settle 222 /* delay a bit to let encoder settle */
224 msleep(50); 223 msleep(50);
225 224
226 // done 225 return status;
227 return status;
228} 226}
229 227
230 228
231static int saa6752hs_set_bitrate(struct i2c_client* client, 229static int saa6752hs_set_bitrate(struct i2c_client* client,
232 struct v4l2_mpeg_compression* params) 230 struct v4l2_mpeg_compression* params)
233{ 231{
234 u8 buf[3]; 232 u8 buf[3];
235 233
236 // set the bitrate mode 234 /* set the bitrate mode */
237 buf[0] = 0x71; 235 buf[0] = 0x71;
238 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; 236 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
239 i2c_master_send(client, buf, 2); 237 i2c_master_send(client, buf, 2);
240 238
241 // set the video bitrate 239 /* set the video bitrate */
242 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { 240 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
243 // set the target bitrate 241 /* set the target bitrate */
244 buf[0] = 0x80; 242 buf[0] = 0x80;
245 buf[1] = params->vi_bitrate.target >> 8; 243 buf[1] = params->vi_bitrate.target >> 8;
246 buf[2] = params->vi_bitrate.target & 0xff; 244 buf[2] = params->vi_bitrate.target & 0xff;
247 i2c_master_send(client, buf, 3); 245 i2c_master_send(client, buf, 3);
248 246
249 // set the max bitrate 247 /* set the max bitrate */
250 buf[0] = 0x81; 248 buf[0] = 0x81;
251 buf[1] = params->vi_bitrate.max >> 8; 249 buf[1] = params->vi_bitrate.max >> 8;
252 buf[2] = params->vi_bitrate.max & 0xff; 250 buf[2] = params->vi_bitrate.max & 0xff;
253 i2c_master_send(client, buf, 3); 251 i2c_master_send(client, buf, 3);
254 } else { 252 } else {
255 // set the target bitrate (no max bitrate for CBR) 253 /* set the target bitrate (no max bitrate for CBR) */
256 buf[0] = 0x81; 254 buf[0] = 0x81;
257 buf[1] = params->vi_bitrate.target >> 8; 255 buf[1] = params->vi_bitrate.target >> 8;
258 buf[2] = params->vi_bitrate.target & 0xff; 256 buf[2] = params->vi_bitrate.target & 0xff;
259 i2c_master_send(client, buf, 3); 257 i2c_master_send(client, buf, 3);
260 } 258 }
261 259
262 // set the audio bitrate 260 /* set the audio bitrate */
263 buf[0] = 0x94; 261 buf[0] = 0x94;
264 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; 262 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
265 i2c_master_send(client, buf, 2); 263 i2c_master_send(client, buf, 2);
266 264
267 // set the total bitrate 265 /* set the total bitrate */
268 buf[0] = 0xb1; 266 buf[0] = 0xb1;
269 buf[1] = params->st_bitrate.target >> 8; 267 buf[1] = params->st_bitrate.target >> 8;
270 buf[2] = params->st_bitrate.target & 0xff; 268 buf[2] = params->st_bitrate.target & 0xff;
271 i2c_master_send(client, buf, 3); 269 i2c_master_send(client, buf, 3);
272 270
273 // return success
274 return 0; 271 return 0;
275} 272}
276 273
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client)
376 373
377 h = i2c_get_clientdata(client); 374 h = i2c_get_clientdata(client);
378 375
379 // Set video format - must be done first as it resets other settings 376 /* Set video format - must be done first as it resets other settings */
380 buf[0] = 0x41; 377 buf[0] = 0x41;
381 buf[1] = h->video_format; 378 buf[1] = h->video_format;
382 i2c_master_send(client, buf, 2); 379 i2c_master_send(client, buf, 2);
383 380
384 // set bitrate 381 /* Set number of lines in input signal */
385 saa6752hs_set_bitrate(client, &h->params); 382 buf[0] = 0x40;
383 buf[1] = 0x00;
384 if (h->standard & V4L2_STD_525_60)
385 buf[1] = 0x01;
386 i2c_master_send(client, buf, 2);
387
388 /* set bitrate */
389 saa6752hs_set_bitrate(client, &h->params);
386 390
387 // Set GOP structure {3, 13} 391 /* Set GOP structure {3, 13} */
388 buf[0] = 0x72; 392 buf[0] = 0x72;
389 buf[1] = 0x03; 393 buf[1] = 0x03;
390 buf[2] = 0x0D; 394 buf[2] = 0x0D;
391 i2c_master_send(client,buf,3); 395 i2c_master_send(client,buf,3);
392 396
393 // Set minimum Q-scale {4} 397 /* Set minimum Q-scale {4} */
394 buf[0] = 0x82; 398 buf[0] = 0x82;
395 buf[1] = 0x04; 399 buf[1] = 0x04;
396 i2c_master_send(client,buf,2); 400 i2c_master_send(client,buf,2);
397 401
398 // Set maximum Q-scale {12} 402 /* Set maximum Q-scale {12} */
399 buf[0] = 0x83; 403 buf[0] = 0x83;
400 buf[1] = 0x0C; 404 buf[1] = 0x0C;
401 i2c_master_send(client,buf,2); 405 i2c_master_send(client,buf,2);
402 406
403 // Set Output Protocol 407 /* Set Output Protocol */
404 buf[0] = 0xD0; 408 buf[0] = 0xD0;
405 buf[1] = 0x81; 409 buf[1] = 0x81;
406 i2c_master_send(client,buf,2); 410 i2c_master_send(client,buf,2);
407 411
408 // Set video output stream format {TS} 412 /* Set video output stream format {TS} */
409 buf[0] = 0xB0; 413 buf[0] = 0xB0;
410 buf[1] = 0x05; 414 buf[1] = 0x05;
411 i2c_master_send(client,buf,2); 415 i2c_master_send(client,buf,2);
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client)
421 localPAT[sizeof(PAT) - 1] = crc & 0xFF; 425 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
422 426
423 /* compute PMT */ 427 /* compute PMT */
424 memcpy(localPMT, PMT, sizeof(PMT)); 428 memcpy(localPMT, PMT, sizeof(PMT));
425 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); 429 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
426 localPMT[4] = h->params.ts_pid_pmt & 0xff; 430 localPMT[4] = h->params.ts_pid_pmt & 0xff;
427 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); 431 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
428 localPMT[16] = h->params.ts_pid_pcr & 0xFF; 432 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
429 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); 433 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client)
436 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; 440 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
437 localPMT[sizeof(PMT) - 1] = crc & 0xFF; 441 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
438 442
439 // Set Audio PID 443 /* Set Audio PID */
440 buf[0] = 0xC1; 444 buf[0] = 0xC1;
441 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; 445 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
442 buf[2] = h->params.ts_pid_audio & 0xFF; 446 buf[2] = h->params.ts_pid_audio & 0xFF;
443 i2c_master_send(client,buf,3); 447 i2c_master_send(client,buf,3);
444 448
445 // Set Video PID 449 /* Set Video PID */
446 buf[0] = 0xC0; 450 buf[0] = 0xC0;
447 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; 451 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
448 buf[2] = h->params.ts_pid_video & 0xFF; 452 buf[2] = h->params.ts_pid_video & 0xFF;
449 i2c_master_send(client,buf,3); 453 i2c_master_send(client,buf,3);
450 454
451 // Set PCR PID 455 /* Set PCR PID */
452 buf[0] = 0xC4; 456 buf[0] = 0xC4;
453 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; 457 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
454 buf[2] = h->params.ts_pid_pcr & 0xFF; 458 buf[2] = h->params.ts_pid_pcr & 0xFF;
455 i2c_master_send(client,buf,3); 459 i2c_master_send(client,buf,3);
456 460
457 // Send SI tables 461 /* Send SI tables */
458 i2c_master_send(client,localPAT,sizeof(PAT)); 462 i2c_master_send(client,localPAT,sizeof(PAT));
459 i2c_master_send(client,localPMT,sizeof(PMT)); 463 i2c_master_send(client,localPMT,sizeof(PMT));
460 464
461 // mute then unmute audio. This removes buzzing artefacts 465 /* mute then unmute audio. This removes buzzing artefacts */
462 buf[0] = 0xa4; 466 buf[0] = 0xa4;
463 buf[1] = 1; 467 buf[1] = 1;
464 i2c_master_send(client, buf, 2); 468 i2c_master_send(client, buf, 2);
465 buf[1] = 0; 469 buf[1] = 0;
466 i2c_master_send(client, buf, 2); 470 i2c_master_send(client, buf, 2);
467 471
468 // start it going 472 /* start it going */
469 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); 473 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
470 474
471 // readout current state 475 /* readout current state */
472 buf[0] = 0xE1; 476 buf[0] = 0xE1;
473 buf[1] = 0xA7; 477 buf[1] = 0xA7;
474 buf[2] = 0xFE; 478 buf[2] = 0xFE;
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client)
477 i2c_master_send(client, buf, 5); 481 i2c_master_send(client, buf, 5);
478 i2c_master_recv(client, buf2, 4); 482 i2c_master_recv(client, buf2, 4);
479 483
480 // change aspect ratio 484 /* change aspect ratio */
481 buf[0] = 0xE0; 485 buf[0] = 0xE0;
482 buf[1] = 0xA7; 486 buf[1] = 0xA7;
483 buf[2] = 0xFE; 487 buf[2] = 0xFE;
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client)
498 buf[8] = buf2[3]; 502 buf[8] = buf2[3];
499 i2c_master_send(client, buf, 9); 503 i2c_master_send(client, buf, 9);
500 504
501 // return success
502 return 0; 505 return 0;
503} 506}
504 507
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
506{ 509{
507 struct saa6752hs_state *h; 510 struct saa6752hs_state *h;
508 511
509 printk("saa6752hs: chip found @ 0x%x\n", addr<<1); 512 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
510 513
511 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) 514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
512 return -ENOMEM; 515 return -ENOMEM;
513 memset(h,0,sizeof(*h)); 516 memset(h,0,sizeof(*h));
514 h->client = client_template; 517 h->client = client_template;
515 h->params = param_defaults; 518 h->params = param_defaults;
516 h->client.adapter = adap; 519 h->client.adapter = adap;
517 h->client.addr = addr; 520 h->client.addr = addr;
518 521
522 /* Assume 625 input lines */
523 h->standard = 0;
524
519 i2c_set_clientdata(&h->client, h); 525 i2c_set_clientdata(&h->client, h);
520 i2c_attach_client(&h->client); 526 i2c_attach_client(&h->client);
521 return 0; 527 return 0;
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
545 struct v4l2_mpeg_compression *params = arg; 551 struct v4l2_mpeg_compression *params = arg;
546 int err = 0; 552 int err = 0;
547 553
548 switch (cmd) { 554 switch (cmd) {
549 case VIDIOC_S_MPEGCOMP: 555 case VIDIOC_S_MPEGCOMP:
550 if (NULL == params) { 556 if (NULL == params) {
551 /* apply settings and start encoder */ 557 /* apply settings and start encoder */
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
559 break; 565 break;
560 case VIDIOC_G_FMT: 566 case VIDIOC_G_FMT:
561 { 567 {
562 struct v4l2_format *f = arg; 568 struct v4l2_format *f = arg;
563 569
564 if (h->video_format == SAA6752HS_VF_UNKNOWN) 570 if (h->video_format == SAA6752HS_VF_UNKNOWN)
565 h->video_format = SAA6752HS_VF_D1; 571 h->video_format = SAA6752HS_VF_D1;
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
576 saa6752hs_set_subsampling(client, f); 582 saa6752hs_set_subsampling(client, f);
577 break; 583 break;
578 } 584 }
585 case VIDIOC_S_STD:
586 h->standard = *((v4l2_std_id *) arg);
587 break;
579 default: 588 default:
580 /* nothing */ 589 /* nothing */
581 break; 590 break;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
new file mode 100644
index 000000000000..4f3c42354329
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -0,0 +1,1047 @@
1/*
2 * SAA713x ALSA support for V4L
3 *
4 *
5 * Caveats:
6 * - Volume doesn't work (it's always at max)
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, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/time.h>
27#include <linux/wait.h>
28#include <linux/moduleparam.h>
29#include <linux/module.h>
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/pcm.h>
33#include <sound/initval.h>
34
35#include "saa7134.h"
36#include "saa7134-reg.h"
37
38static unsigned int debug = 0;
39module_param(debug, int, 0644);
40MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
41
42/*
43 * Configuration macros
44 */
45
46/* defaults */
47#define MIXER_ADDR_TVTUNER 0
48#define MIXER_ADDR_LINE1 1
49#define MIXER_ADDR_LINE2 2
50#define MIXER_ADDR_LAST 2
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
58
59#define dprintk(fmt, arg...) if (debug) \
60 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
61
62/*
63 * Main chip structure
64 */
65typedef struct snd_card_saa7134 {
66 snd_card_t *card;
67 spinlock_t mixer_lock;
68 int mixer_volume[MIXER_ADDR_LAST+1][2];
69 int capture_source[MIXER_ADDR_LAST+1][2];
70 struct pci_dev *pci;
71 struct saa7134_dev *saadev;
72
73 unsigned long iobase;
74 int irq;
75
76 spinlock_t lock;
77} snd_card_saa7134_t;
78
79
80
81/*
82 * PCM structure
83 */
84
85typedef struct snd_card_saa7134_pcm {
86 struct saa7134_dev *saadev;
87
88 spinlock_t lock;
89 unsigned int pcm_size; /* buffer size */
90 unsigned int pcm_count; /* bytes per period */
91 unsigned int pcm_bps; /* bytes per second */
92 snd_pcm_substream_t *substream;
93} snd_card_saa7134_pcm_t;
94
95static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
96
97
98/*
99 * saa7134 DMA audio stop
100 *
101 * Called when the capture device is released or the buffer overflows
102 *
103 * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
104 * if we just share dsp_dma_stop and use it here
105 *
106 */
107
108static void saa7134_dma_stop(struct saa7134_dev *dev)
109
110{
111 dev->dmasound.dma_blk = -1;
112 dev->dmasound.dma_running = 0;
113 saa7134_set_dmabits(dev);
114}
115
116/*
117 * saa7134 DMA audio start
118 *
119 * Called when preparing the capture device for use
120 *
121 * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
122 * if we just share dsp_dma_start and use it here
123 *
124 */
125
126static void saa7134_dma_start(struct saa7134_dev *dev)
127{
128 dev->dmasound.dma_blk = 0;
129 dev->dmasound.dma_running = 1;
130 saa7134_set_dmabits(dev);
131}
132
133/*
134 * saa7134 audio DMA IRQ handler
135 *
136 * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
137 * Handles shifting between the 2 buffers, manages the read counters,
138 * and notifies ALSA when periods elapse
139 *
140 * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
141 *
142 */
143
144void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
145{
146 int next_blk, reg = 0;
147
148 spin_lock(&dev->slock);
149 if (UNSET == dev->dmasound.dma_blk) {
150 dprintk("irq: recording stopped\n");
151 goto done;
152 }
153 if (0 != (status & 0x0f000000))
154 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
155 if (0 == (status & 0x10000000)) {
156 /* odd */
157 if (0 == (dev->dmasound.dma_blk & 0x01))
158 reg = SAA7134_RS_BA1(6);
159 } else {
160 /* even */
161 if (1 == (dev->dmasound.dma_blk & 0x01))
162 reg = SAA7134_RS_BA2(6);
163 }
164 if (0 == reg) {
165 dprintk("irq: field oops [%s]\n",
166 (status & 0x10000000) ? "even" : "odd");
167 goto done;
168 }
169
170 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
171 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
172 dev->dmasound.bufsize, dev->dmasound.blocks);
173 snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
174 saa7134_dma_stop(dev);
175 goto done;
176 }
177
178 /* next block addr */
179 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
180 saa_writel(reg,next_blk * dev->dmasound.blksize);
181 if (debug > 2)
182 dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
183 (status & 0x10000000) ? "even" : "odd ", next_blk,
184 next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
185
186 /* update status & wake waiting readers */
187 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
188 dev->dmasound.read_count += dev->dmasound.blksize;
189
190 dev->dmasound.recording_on = reg;
191
192 if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
193 spin_unlock(&dev->slock);
194 snd_pcm_period_elapsed(dev->dmasound.substream);
195 spin_lock(&dev->slock);
196 }
197 done:
198 spin_unlock(&dev->slock);
199
200}
201
202/*
203 * IRQ request handler
204 *
205 * Runs along with saa7134's IRQ handler, discards anything that isn't
206 * DMA sound
207 *
208 */
209
210static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
211{
212 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
213 unsigned long report, status;
214 int loop, handled = 0;
215
216 for (loop = 0; loop < 10; loop++) {
217 report = saa_readl(SAA7134_IRQ_REPORT);
218 status = saa_readl(SAA7134_IRQ_STATUS);
219
220 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
221 handled = 1;
222 saa_writel(SAA7134_IRQ_REPORT,report);
223 saa7134_irq_alsa_done(dev, status);
224 } else {
225 goto out;
226 }
227 }
228
229 if (loop == 10) {
230 dprintk("error! looping IRQ!");
231 }
232
233out:
234 return IRQ_RETVAL(handled);
235}
236
237/*
238 * ALSA capture trigger
239 *
240 * - One of the ALSA capture callbacks.
241 *
242 * Called whenever a capture is started or stopped. Must be defined,
243 * but there's nothing we want to do here
244 *
245 */
246
247static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
248 int cmd)
249{
250 snd_pcm_runtime_t *runtime = substream->runtime;
251 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
252 struct saa7134_dev *dev=saapcm->saadev;
253 int err = 0;
254
255 spin_lock_irq(&dev->slock);
256 if (cmd == SNDRV_PCM_TRIGGER_START) {
257 /* start dma */
258 saa7134_dma_start(dev);
259 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
260 /* stop dma */
261 saa7134_dma_stop(dev);
262 } else {
263 err = -EINVAL;
264 }
265 spin_unlock_irq(&dev->slock);
266
267 return err;
268}
269
270/*
271 * DMA buffer config
272 *
273 * Sets the values that will later be used as the size of the buffer,
274 * size of the fragments, and total number of fragments.
275 * Must be called during the preparation stage, before memory is
276 * allocated
277 *
278 * - Copied verbatim from saa7134-oss. Can be dropped
279 * if we just share dsp_buffer_conf from OSS.
280 */
281
282static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
283{
284 if (blksize < 0x100)
285 blksize = 0x100;
286 if (blksize > 0x10000)
287 blksize = 0x10000;
288
289 if (blocks < 2)
290 blocks = 2;
291 if ((blksize * blocks) > 1024*1024)
292 blocks = 1024*1024 / blksize;
293
294 dev->dmasound.blocks = blocks;
295 dev->dmasound.blksize = blksize;
296 dev->dmasound.bufsize = blksize * blocks;
297
298 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
299 blocks,blksize,blksize * blocks / 1024);
300 return 0;
301}
302
303/*
304 * DMA buffer initialization
305 *
306 * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
307 * ALSA, but I was unable to use ALSA's own DMA, and had to force the
308 * usage of V4L's
309 *
310 * - Copied verbatim from saa7134-oss. Can be dropped
311 * if we just share dsp_buffer_init from OSS.
312 */
313
314static int dsp_buffer_init(struct saa7134_dev *dev)
315{
316 int err;
317
318 if (!dev->dmasound.bufsize)
319 BUG();
320 videobuf_dma_init(&dev->dmasound.dma);
321 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
322 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
323 if (0 != err)
324 return err;
325 return 0;
326}
327
328/*
329 * ALSA PCM preparation
330 *
331 * - One of the ALSA capture callbacks.
332 *
333 * Called right after the capture device is opened, this function configures
334 * the buffer using the previously defined functions, allocates the memory,
335 * sets up the hardware registers, and then starts the DMA. When this function
336 * returns, the audio should be flowing.
337 *
338 */
339
340static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
341{
342 snd_pcm_runtime_t *runtime = substream->runtime;
343 int err, bswap, sign;
344 u32 fmt, control;
345 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
346 struct saa7134_dev *dev;
347 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
348 unsigned int bps;
349 unsigned long size;
350 unsigned count;
351
352 size = snd_pcm_lib_buffer_bytes(substream);
353 count = snd_pcm_lib_period_bytes(substream);
354
355 saapcm->saadev->dmasound.substream = substream;
356 bps = runtime->rate * runtime->channels;
357 bps *= snd_pcm_format_width(runtime->format);
358 bps /= 8;
359 if (bps <= 0)
360 return -EINVAL;
361 saapcm->pcm_bps = bps;
362 saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
363 saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
364
365
366 dev=saa7134->saadev;
367
368 dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
369
370 err = dsp_buffer_init(dev);
371 if (0 != err)
372 goto fail2;
373
374 /* prepare buffer */
375 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
376 return err;
377 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
378 goto fail1;
379 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
380 dev->dmasound.dma.sglist,
381 dev->dmasound.dma.sglen,
382 0)))
383 goto fail2;
384
385
386
387 switch (runtime->format) {
388 case SNDRV_PCM_FORMAT_U8:
389 case SNDRV_PCM_FORMAT_S8:
390 fmt = 0x00;
391 break;
392 case SNDRV_PCM_FORMAT_U16_LE:
393 case SNDRV_PCM_FORMAT_U16_BE:
394 case SNDRV_PCM_FORMAT_S16_LE:
395 case SNDRV_PCM_FORMAT_S16_BE:
396 fmt = 0x01;
397 break;
398 default:
399 err = -EINVAL;
400 return 1;
401 }
402
403 switch (runtime->format) {
404 case SNDRV_PCM_FORMAT_S8:
405 case SNDRV_PCM_FORMAT_S16_LE:
406 case SNDRV_PCM_FORMAT_S16_BE:
407 sign = 1;
408 break;
409 default:
410 sign = 0;
411 break;
412 }
413
414 switch (runtime->format) {
415 case SNDRV_PCM_FORMAT_U16_BE:
416 case SNDRV_PCM_FORMAT_S16_BE:
417 bswap = 1; break;
418 default:
419 bswap = 0; break;
420 }
421
422 switch (dev->pci->device) {
423 case PCI_DEVICE_ID_PHILIPS_SAA7134:
424 if (1 == runtime->channels)
425 fmt |= (1 << 3);
426 if (2 == runtime->channels)
427 fmt |= (3 << 3);
428 if (sign)
429 fmt |= 0x04;
430
431 fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
432 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
433 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
434 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
435 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
436
437 break;
438 case PCI_DEVICE_ID_PHILIPS_SAA7133:
439 case PCI_DEVICE_ID_PHILIPS_SAA7135:
440 if (1 == runtime->channels)
441 fmt |= (1 << 4);
442 if (2 == runtime->channels)
443 fmt |= (2 << 4);
444 if (!sign)
445 fmt |= 0x04;
446 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
447 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
448 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
449 break;
450 }
451
452 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
453 runtime->format, runtime->channels, fmt,
454 bswap ? 'b' : '-');
455 /* dma: setup channel 6 (= AUDIO) */
456 control = SAA7134_RS_CONTROL_BURST_16 |
457 SAA7134_RS_CONTROL_ME |
458 (dev->dmasound.pt.dma >> 12);
459 if (bswap)
460 control |= SAA7134_RS_CONTROL_BSWAP;
461
462 /* I should be able to use runtime->dma_addr in the control
463 byte, but it doesn't work. So I allocate the DMA using the
464 V4L functions, and force ALSA to use that as the DMA area */
465
466 runtime->dma_area = dev->dmasound.dma.vmalloc;
467
468 saa_writel(SAA7134_RS_BA1(6),0);
469 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
470 saa_writel(SAA7134_RS_PITCH(6),0);
471 saa_writel(SAA7134_RS_CONTROL(6),control);
472
473 dev->dmasound.rate = runtime->rate;
474
475 return 0;
476 fail2:
477 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
478 fail1:
479 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
480 return err;
481
482
483}
484
485/*
486 * ALSA pointer fetching
487 *
488 * - One of the ALSA capture callbacks.
489 *
490 * Called whenever a period elapses, it must return the current hardware
491 * position of the buffer.
492 * Also resets the read counter used to prevent overruns
493 *
494 */
495
496static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
497{
498 snd_pcm_runtime_t *runtime = substream->runtime;
499 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
500 struct saa7134_dev *dev=saapcm->saadev;
501
502
503
504 if (dev->dmasound.read_count) {
505 dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
506 dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
507 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
508 dev->dmasound.read_offset = 0;
509 }
510
511 return bytes_to_frames(runtime, dev->dmasound.read_offset);
512}
513
514/*
515 * ALSA hardware capabilities definition
516 */
517
518static snd_pcm_hardware_t snd_card_saa7134_capture =
519{
520 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
521 SNDRV_PCM_INFO_BLOCK_TRANSFER |
522 SNDRV_PCM_INFO_MMAP_VALID),
523 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
524 SNDRV_PCM_FMTBIT_S16_BE | \
525 SNDRV_PCM_FMTBIT_S8 | \
526 SNDRV_PCM_FMTBIT_U8 | \
527 SNDRV_PCM_FMTBIT_U16_LE | \
528 SNDRV_PCM_FMTBIT_U16_BE,
529 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
530 .rate_min = 32000,
531 .rate_max = 48000,
532 .channels_min = 1,
533 .channels_max = 2,
534 .buffer_bytes_max = (256*1024),
535 .period_bytes_min = 64,
536 .period_bytes_max = (256*1024),
537 .periods_min = 2,
538 .periods_max = 1024,
539};
540
541static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
542{
543 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
544
545 kfree(saapcm);
546}
547
548
549/*
550 * ALSA hardware params
551 *
552 * - One of the ALSA capture callbacks.
553 *
554 * Called on initialization, right before the PCM preparation
555 * Usually used in ALSA to allocate the DMA, but since we don't use the
556 * ALSA DMA it does nothing
557 *
558 */
559
560static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
561 snd_pcm_hw_params_t * hw_params)
562{
563
564 return 0;
565
566
567}
568
569/*
570 * ALSA hardware release
571 *
572 * - One of the ALSA capture callbacks.
573 *
574 * Called after closing the device, but before snd_card_saa7134_capture_close
575 * Usually used in ALSA to free the DMA, but since we don't use the
576 * ALSA DMA I'm almost sure this isn't necessary.
577 *
578 */
579
580static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
581{
582 return 0;
583}
584
585/*
586 * DMA buffer release
587 *
588 * Called after closing the device, during snd_card_saa7134_capture_close
589 *
590 */
591
592static int dsp_buffer_free(struct saa7134_dev *dev)
593{
594 if (!dev->dmasound.blksize)
595 BUG();
596
597 videobuf_dma_free(&dev->dmasound.dma);
598
599 dev->dmasound.blocks = 0;
600 dev->dmasound.blksize = 0;
601 dev->dmasound.bufsize = 0;
602
603 return 0;
604}
605
606/*
607 * ALSA capture finish
608 *
609 * - One of the ALSA capture callbacks.
610 *
611 * Called after closing the device. It stops the DMA audio and releases
612 * the buffers
613 *
614 */
615
616static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
617{
618 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
619 struct saa7134_dev *dev = chip->saadev;
620
621 /* unlock buffer */
622 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
623 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
624
625 dsp_buffer_free(dev);
626 return 0;
627}
628
629/*
630 * ALSA capture start
631 *
632 * - One of the ALSA capture callbacks.
633 *
634 * Called when opening the device. It creates and populates the PCM
635 * structure
636 *
637 */
638
639static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
640{
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 snd_card_saa7134_pcm_t *saapcm;
643 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
644 struct saa7134_dev *dev = saa7134->saadev;
645 int err;
646
647 down(&dev->dmasound.lock);
648
649 dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
650 dev->dmasound.channels = 2;
651 dev->dmasound.read_count = 0;
652 dev->dmasound.read_offset = 0;
653
654 up(&dev->dmasound.lock);
655
656 saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
657 if (saapcm == NULL)
658 return -ENOMEM;
659 saapcm->saadev=saa7134->saadev;
660
661 spin_lock_init(&saapcm->lock);
662
663 saapcm->substream = substream;
664 runtime->private_data = saapcm;
665 runtime->private_free = snd_card_saa7134_runtime_free;
666 runtime->hw = snd_card_saa7134_capture;
667
668 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
669 return err;
670
671 return 0;
672}
673
674/*
675 * ALSA capture callbacks definition
676 */
677
678static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
679 .open = snd_card_saa7134_capture_open,
680 .close = snd_card_saa7134_capture_close,
681 .ioctl = snd_pcm_lib_ioctl,
682 .hw_params = snd_card_saa7134_hw_params,
683 .hw_free = snd_card_saa7134_hw_free,
684 .prepare = snd_card_saa7134_capture_prepare,
685 .trigger = snd_card_saa7134_capture_trigger,
686 .pointer = snd_card_saa7134_capture_pointer,
687};
688
689/*
690 * ALSA PCM setup
691 *
692 * Called when initializing the board. Sets up the name and hooks up
693 * the callbacks
694 *
695 */
696
697static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
698{
699 snd_pcm_t *pcm;
700 int err;
701
702 if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
703 return err;
704 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
705 pcm->private_data = saa7134;
706 pcm->info_flags = 0;
707 strcpy(pcm->name, "SAA7134 PCM");
708 return 0;
709}
710
711#define SAA713x_VOLUME(xname, xindex, addr) \
712{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
713 .info = snd_saa7134_volume_info, \
714 .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
715 .private_value = addr }
716
717static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
718{
719 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
720 uinfo->count = 2;
721 uinfo->value.integer.min = 0;
722 uinfo->value.integer.max = 20;
723 return 0;
724}
725
726static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
727{
728 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
729 int addr = kcontrol->private_value;
730
731 ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
732 ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
733 return 0;
734}
735
736static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
737{
738 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
739 unsigned long flags;
740 int change, addr = kcontrol->private_value;
741 int left, right;
742
743 left = ucontrol->value.integer.value[0];
744 if (left < 0)
745 left = 0;
746 if (left > 20)
747 left = 20;
748 right = ucontrol->value.integer.value[1];
749 if (right < 0)
750 right = 0;
751 if (right > 20)
752 right = 20;
753 spin_lock_irqsave(&chip->mixer_lock, flags);
754 change = chip->mixer_volume[addr][0] != left ||
755 chip->mixer_volume[addr][1] != right;
756 chip->mixer_volume[addr][0] = left;
757 chip->mixer_volume[addr][1] = right;
758 spin_unlock_irqrestore(&chip->mixer_lock, flags);
759 return change;
760}
761
762#define SAA713x_CAPSRC(xname, xindex, addr) \
763{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
764 .info = snd_saa7134_capsrc_info, \
765 .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
766 .private_value = addr }
767
768static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
769{
770 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
771 uinfo->count = 2;
772 uinfo->value.integer.min = 0;
773 uinfo->value.integer.max = 1;
774 return 0;
775}
776
777static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
778{
779 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
780 unsigned long flags;
781 int addr = kcontrol->private_value;
782
783 spin_lock_irqsave(&chip->mixer_lock, flags);
784 ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
785 ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
786 spin_unlock_irqrestore(&chip->mixer_lock, flags);
787 return 0;
788}
789
790static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
791{
792 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
793 unsigned long flags;
794 int change, addr = kcontrol->private_value;
795 int left, right;
796 u32 anabar, xbarin;
797 int analog_io, rate;
798 struct saa7134_dev *dev;
799
800 dev = chip->saadev;
801
802 left = ucontrol->value.integer.value[0] & 1;
803 right = ucontrol->value.integer.value[1] & 1;
804 spin_lock_irqsave(&chip->mixer_lock, flags);
805
806 change = chip->capture_source[addr][0] != left ||
807 chip->capture_source[addr][1] != right;
808 chip->capture_source[addr][0] = left;
809 chip->capture_source[addr][1] = right;
810 dev->dmasound.input=addr;
811 spin_unlock_irqrestore(&chip->mixer_lock, flags);
812
813
814 if (change) {
815 switch (dev->pci->device) {
816
817 case PCI_DEVICE_ID_PHILIPS_SAA7134:
818 switch (addr) {
819 case MIXER_ADDR_TVTUNER:
820 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
821 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
822 break;
823 case MIXER_ADDR_LINE1:
824 case MIXER_ADDR_LINE2:
825 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
826 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
827 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
828 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
829 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
830 break;
831 }
832
833 break;
834 case PCI_DEVICE_ID_PHILIPS_SAA7133:
835 case PCI_DEVICE_ID_PHILIPS_SAA7135:
836 xbarin = 0x03; // adc
837 anabar = 0;
838 switch (addr) {
839 case MIXER_ADDR_TVTUNER:
840 xbarin = 0; // Demodulator
841 anabar = 2; // DACs
842 break;
843 case MIXER_ADDR_LINE1:
844 anabar = 0; // aux1, aux1
845 break;
846 case MIXER_ADDR_LINE2:
847 anabar = 9; // aux2, aux2
848 break;
849 }
850
851 /* output xbar always main channel */
852 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
853
854 if (left || right) { // We've got data, turn the input on
855 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
856 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
857 } else {
858 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
859 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
860 }
861 break;
862 }
863 }
864
865 return change;
866}
867
868static snd_kcontrol_new_t snd_saa7134_controls[] = {
869SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
870SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
871SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
872SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
873SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
874SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
875};
876
877/*
878 * ALSA mixer setup
879 *
880 * Called when initializing the board. Sets up the name and hooks up
881 * the callbacks
882 *
883 */
884
885static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
886{
887 snd_card_t *card = chip->card;
888 unsigned int idx;
889 int err;
890
891 snd_assert(chip != NULL, return -EINVAL);
892 strcpy(card->mixername, "SAA7134 Mixer");
893
894 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
895 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
896 return err;
897 }
898 return 0;
899}
900
901static int snd_saa7134_free(snd_card_saa7134_t *chip)
902{
903 return 0;
904}
905
906static int snd_saa7134_dev_free(snd_device_t *device)
907{
908 snd_card_saa7134_t *chip = device->device_data;
909 return snd_saa7134_free(chip);
910}
911
912/*
913 * ALSA initialization
914 *
915 * Called by saa7134-core, it creates the basic structures and registers
916 * the ALSA devices
917 *
918 */
919
920int alsa_card_saa7134_create (struct saa7134_dev *saadev)
921{
922 static int dev;
923
924 snd_card_t *card;
925 snd_card_saa7134_t *chip;
926 int err;
927 static snd_device_ops_t ops = {
928 .dev_free = snd_saa7134_dev_free,
929 };
930
931
932 if (dev >= SNDRV_CARDS)
933 return -ENODEV;
934 if (!enable[dev])
935 return -ENODEV;
936
937 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
938
939 if (card == NULL)
940 return -ENOMEM;
941
942 strcpy(card->driver, "SAA7134");
943
944 /* Card "creation" */
945
946 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
947 if (chip == NULL) {
948 return -ENOMEM;
949 }
950
951 spin_lock_init(&chip->lock);
952 spin_lock_init(&chip->mixer_lock);
953
954 chip->saadev = saadev;
955
956 chip->card = card;
957
958 chip->pci = saadev->pci;
959 chip->irq = saadev->pci->irq;
960 chip->iobase = pci_resource_start(saadev->pci, 0);
961
962 err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
963 SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
964
965 if (err < 0) {
966 printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
967 saadev->name, saadev->pci->irq);
968 goto __nodev;
969 }
970
971 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
972 goto __nodev;
973 }
974
975 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
976 goto __nodev;
977
978 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
979 goto __nodev;
980
981 snd_card_set_dev(card, &chip->pci->dev);
982
983 /* End of "creation" */
984
985 strcpy(card->shortname, "SAA7134");
986 sprintf(card->longname, "%s at 0x%lx irq %d",
987 chip->saadev->name, chip->iobase, chip->irq);
988
989 if ((err = snd_card_register(card)) == 0) {
990 snd_saa7134_cards[dev] = card;
991 return 0;
992 }
993
994__nodev:
995 snd_card_free(card);
996 kfree(chip);
997 return err;
998}
999
1000/*
1001 * Module initializer
1002 *
1003 * Loops through present saa7134 cards, and assigns an ALSA device
1004 * to each one
1005 *
1006 */
1007
1008static int saa7134_alsa_init(void)
1009{
1010 struct saa7134_dev *saadev = NULL;
1011 struct list_head *list;
1012
1013 printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
1014
1015 list_for_each(list,&saa7134_devlist) {
1016 saadev = list_entry(list, struct saa7134_dev, devlist);
1017 alsa_card_saa7134_create(saadev);
1018 }
1019
1020 if (saadev == NULL)
1021 printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
1022
1023 return 0;
1024
1025}
1026
1027/*
1028 * Module destructor
1029 */
1030
1031void saa7134_alsa_exit(void)
1032{
1033 int idx;
1034
1035 for (idx = 0; idx < SNDRV_CARDS; idx++) {
1036 snd_card_free(snd_saa7134_cards[idx]);
1037 }
1038
1039 printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
1040
1041 return;
1042}
1043
1044module_init(saa7134_alsa_init);
1045module_exit(saa7134_alsa_exit);
1046MODULE_LICENSE("GPL");
1047MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index acc7a4335e23..663d03e5bc67 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = {
191 .amux = TV, 191 .amux = TV,
192 .tv = 1, 192 .tv = 1,
193 },{ 193 },{
194 .name = name_comp1, 194 .name = name_comp1, /* Composite signal on S-Video input */
195 .vmux = 0, 195 .vmux = 0,
196 .amux = LINE2, 196 .amux = LINE2,
197 },{ 197 },{
198 .name = name_comp2, /* Composite input */
199 .vmux = 3,
200 .amux = LINE2,
201 },{
198 .name = name_svideo, 202 .name = name_svideo,
199 .vmux = 8, 203 .vmux = 8,
200 .amux = LINE2, 204 .amux = LINE2,
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = {
2109 .gpio = 0x01, 2113 .gpio = 0x01,
2110 }, 2114 },
2111 }, 2115 },
2112}; 2116 [SAA7134_BOARD_BEHOLD_409FM] = {
2117 /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
2118 .name = "Beholder BeholdTV 409 FM",
2119 .audio_clock = 0x00187de7,
2120 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2121 .radio_type = UNSET,
2122 .tuner_addr = ADDR_UNSET,
2123 .radio_addr = ADDR_UNSET,
2124 .tda9887_conf = TDA9887_PRESENT,
2125 .inputs = {{
2126 .name = name_tv,
2127 .vmux = 3,
2128 .amux = TV,
2129 .tv = 1,
2130 },{
2131 .name = name_comp1,
2132 .vmux = 1,
2133 .amux = LINE1,
2134 },{
2135 .name = name_svideo,
2136 .vmux = 8,
2137 .amux = LINE1,
2138 }},
2139 .radio = {
2140 .name = name_radio,
2141 .amux = LINE2,
2142 },
2143 },
2144 [SAA7134_BOARD_GOTVIEW_7135] = {
2145 /* Mike Baikov <mike@baikov.com> */
2146 /* Andrey Cvetcov <ays14@yandex.ru> */
2147 .name = "GoTView 7135 PCI",
2148 .audio_clock = 0x00187de7,
2149 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2150 .radio_type = UNSET,
2151 .tuner_addr = ADDR_UNSET,
2152 .radio_addr = ADDR_UNSET,
2153 .tda9887_conf = TDA9887_PRESENT,
2154 .gpiomask = 0x00200003,
2155 .inputs = {{
2156 .name = name_tv,
2157 .vmux = 1,
2158 .amux = TV,
2159 .tv = 1,
2160 .gpio = 0x00200003,
2161 },{
2162 .name = name_tv_mono,
2163 .vmux = 1,
2164 .amux = LINE2,
2165 .gpio = 0x00200003,
2166 },{
2167 .name = name_comp1,
2168 .vmux = 3,
2169 .amux = LINE1,
2170 .gpio = 0x00200003,
2171 },{
2172 .name = name_svideo,
2173 .vmux = 8,
2174 .amux = LINE1,
2175 .gpio = 0x00200003,
2176 }},
2177 .radio = {
2178 .name = name_radio,
2179 .amux = LINE2,
2180 .gpio = 0x00200003,
2181 },
2182 .mute = {
2183 .name = name_mute,
2184 .amux = TV,
2185 .gpio = 0x00200003,
2186 },
2187 },
2188 [SAA7134_BOARD_PHILIPS_EUROPA] = {
2189 .name = "Philips EUROPA V3 reference design",
2190 .audio_clock = 0x00187de7,
2191 .tuner_type = TUNER_PHILIPS_TD1316,
2192 .radio_type = UNSET,
2193 .tuner_addr = 0x61,
2194 .radio_addr = ADDR_UNSET,
2195 .tda9887_conf = TDA9887_PRESENT,
2196 .mpeg = SAA7134_MPEG_DVB,
2197 .inputs = {{
2198 .name = name_tv,
2199 .vmux = 3,
2200 .amux = TV,
2201 .tv = 1,
2202 },{
2203 .name = name_comp1,
2204 .vmux = 0,
2205 .amux = LINE2,
2206 },{
2207 .name = name_svideo,
2208 .vmux = 8,
2209 .amux = LINE2,
2210 }},
2211 },
2212 [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
2213 .name = "Compro Videomate DVB-T300",
2214 .audio_clock = 0x00187de7,
2215 .tuner_type = TUNER_PHILIPS_TD1316,
2216 .radio_type = UNSET,
2217 .tuner_addr = 0x61,
2218 .radio_addr = ADDR_UNSET,
2219 .tda9887_conf = TDA9887_PRESENT,
2220 .mpeg = SAA7134_MPEG_DVB,
2221 .inputs = {{
2222 .name = name_tv,
2223 .vmux = 3,
2224 .amux = TV,
2225 .tv = 1,
2226 },{
2227 .name = name_comp1,
2228 .vmux = 1,
2229 .amux = LINE2,
2230 },{
2231 .name = name_svideo,
2232 .vmux = 8,
2233 .amux = LINE2,
2234 }},
2235 },
2236 [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
2237 .name = "Compro Videomate DVB-T200",
2238 .tuner_type = TUNER_ABSENT,
2239 .audio_clock = 0x00187de7,
2240 .radio_type = UNSET,
2241 .tuner_addr = ADDR_UNSET,
2242 .radio_addr = ADDR_UNSET,
2243 .mpeg = SAA7134_MPEG_DVB,
2244 .inputs = {{
2245 .name = name_comp1,
2246 .vmux = 0,
2247 .amux = LINE1,
2248 },{
2249 .name = name_svideo,
2250 .vmux = 8,
2251 .amux = LINE1,
2252 }},
2253 },
2254 [SAA7134_BOARD_RTD_VFG7350] = {
2255 .name = "RTD Embedded Technologies VFG7350",
2256 .audio_clock = 0x00200000,
2257 .tuner_type = TUNER_ABSENT,
2258 .radio_type = UNSET,
2259 .tuner_addr = ADDR_UNSET,
2260 .radio_addr = ADDR_UNSET,
2261 .inputs = {{
2262 .name = "Composite 0",
2263 .vmux = 0,
2264 .amux = LINE1,
2265 },{
2266 .name = "Composite 1",
2267 .vmux = 1,
2268 .amux = LINE2,
2269 },{
2270 .name = "Composite 2",
2271 .vmux = 2,
2272 .amux = LINE1,
2273 },{
2274 .name = "Composite 3",
2275 .vmux = 3,
2276 .amux = LINE2,
2277 },{
2278 .name = "S-Video 0",
2279 .vmux = 8,
2280 .amux = LINE1,
2281 },{
2282 .name = "S-Video 1",
2283 .vmux = 9,
2284 .amux = LINE2,
2285 }},
2286 .mpeg = SAA7134_MPEG_EMPRESS,
2287 .video_out = CCIR656,
2288 .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
2289 SET_CLOCK_NOT_DELAYED |
2290 SET_CLOCK_INVERTED |
2291 SET_VSYNC_OFF ),
2292 },
2293 [SAA7134_BOARD_RTD_VFG7330] = {
2294 .name = "RTD Embedded Technologies VFG7330",
2295 .audio_clock = 0x00200000,
2296 .tuner_type = TUNER_ABSENT,
2297 .radio_type = UNSET,
2298 .tuner_addr = ADDR_UNSET,
2299 .radio_addr = ADDR_UNSET,
2300 .inputs = {{
2301 .name = "Composite 0",
2302 .vmux = 0,
2303 .amux = LINE1,
2304 },{
2305 .name = "Composite 1",
2306 .vmux = 1,
2307 .amux = LINE2,
2308 },{
2309 .name = "Composite 2",
2310 .vmux = 2,
2311 .amux = LINE1,
2312 },{
2313 .name = "Composite 3",
2314 .vmux = 3,
2315 .amux = LINE2,
2316 },{
2317 .name = "S-Video 0",
2318 .vmux = 8,
2319 .amux = LINE1,
2320 },{
2321 .name = "S-Video 1",
2322 .vmux = 9,
2323 .amux = LINE2,
2324 }},
2325 },
2326 [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
2327 .name = "LifeView FlyTV Platinum Mini2",
2328 .audio_clock = 0x00200000,
2329 .tuner_type = TUNER_PHILIPS_TDA8290,
2330 .radio_type = UNSET,
2331 .tuner_addr = ADDR_UNSET,
2332 .radio_addr = ADDR_UNSET,
2113 2333
2334 .inputs = {{
2335 .name = name_tv,
2336 .vmux = 1,
2337 .amux = TV,
2338 .tv = 1,
2339 },{
2340 .name = name_comp1, /* Composite signal on S-Video input */
2341 .vmux = 0,
2342 .amux = LINE2,
2343 },{
2344 .name = name_comp2, /* Composite input */
2345 .vmux = 3,
2346 .amux = LINE2,
2347 },{
2348 .name = name_svideo,
2349 .vmux = 8,
2350 .amux = LINE2,
2351 }},
2352 },
2353 [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
2354 /* Michael Krufky <mkrufky@m1k.net>
2355 * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
2356 * AFAIK, there is no analog demod, thus,
2357 * no support for analog television.
2358 */
2359 .name = "AVerMedia AVerTVHD MCE A180",
2360 .audio_clock = 0x00187de7,
2361 .tuner_type = TUNER_ABSENT,
2362 .radio_type = UNSET,
2363 .tuner_addr = ADDR_UNSET,
2364 .radio_addr = ADDR_UNSET,
2365 .mpeg = SAA7134_MPEG_DVB,
2366 .inputs = {{
2367 .name = name_comp1,
2368 .vmux = 3,
2369 .amux = LINE2,
2370 },{
2371 .name = name_svideo,
2372 .vmux = 8,
2373 .amux = LINE2,
2374 }},
2375 },
2376 [SAA7134_BOARD_MONSTERTV_MOBILE] = {
2377 .name = "SKNet MonsterTV Mobile",
2378 .audio_clock = 0x00187de7,
2379 .tuner_type = TUNER_PHILIPS_TDA8290,
2380 .radio_type = UNSET,
2381 .tuner_addr = ADDR_UNSET,
2382 .radio_addr = ADDR_UNSET,
2383
2384 .inputs = {{
2385 .name = name_tv,
2386 .vmux = 1,
2387 .amux = TV,
2388 .tv = 1,
2389 },{
2390 .name = name_comp1,
2391 .vmux = 3,
2392 .amux = LINE1,
2393 },{
2394 .name = name_svideo,
2395 .vmux = 6,
2396 .amux = LINE1,
2397 }},
2398 },
2399 [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
2400 .name = "Pinnacle PCTV 110i (saa7133)",
2401 .audio_clock = 0x00187de7,
2402 .tuner_type = TUNER_PHILIPS_TDA8290,
2403 .radio_type = UNSET,
2404 .tuner_addr = ADDR_UNSET,
2405 .radio_addr = ADDR_UNSET,
2406 .gpiomask = 0x080200000,
2407 .inputs = {{
2408 .name = name_tv,
2409 .vmux = 4,
2410 .amux = TV,
2411 .tv = 1,
2412 },{
2413 .name = name_comp1,
2414 .vmux = 1,
2415 .amux = LINE2,
2416 },{
2417 .name = name_svideo,
2418 .vmux = 8,
2419 .amux = LINE2,
2420 }},
2421 .radio = {
2422 .name = name_radio,
2423 .amux = LINE1,
2424 },
2425 },
2426 [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
2427 .name = "ASUSTeK P7131 Dual",
2428 .audio_clock = 0x00187de7,
2429 .tuner_type = TUNER_PHILIPS_TDA8290,
2430 .radio_type = UNSET,
2431 .tuner_addr = ADDR_UNSET,
2432 .radio_addr = ADDR_UNSET,
2433 .gpiomask = 1 << 21,
2434 .mpeg = SAA7134_MPEG_DVB,
2435 .inputs = {{
2436 .name = name_tv,
2437 .vmux = 1,
2438 .amux = TV,
2439 .tv = 1,
2440 },{
2441 .name = name_comp1,
2442 .vmux = 3,
2443 .amux = LINE2,
2444 },{
2445 .name = name_svideo,
2446 .vmux = 8,
2447 .amux = LINE2,
2448 }},
2449 .radio = {
2450 .name = name_radio,
2451 .amux = TV,
2452 .gpio = 0x0200000,
2453 },
2454 },
2455 [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
2456 /* Paul Tom Zalac <pzalac@gmail.com> */
2457 /* Pavel Mihaylov <bin@bash.info> */
2458 .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
2459 /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
2460 .audio_clock = 0x00187de7,
2461 .tuner_type = TUNER_PHILIPS_TDA8290,
2462 .radio_type = UNSET,
2463 .tuner_addr = ADDR_UNSET,
2464 .radio_addr = ADDR_UNSET,
2465 .gpiomask = 0xe880c0,
2466 .inputs = {{
2467 .name = name_tv,
2468 .vmux = 3,
2469 .amux = TV,
2470 .tv = 1,
2471 },{
2472 .name = name_comp1,
2473 .vmux = 1,
2474 .amux = LINE1,
2475 },{
2476 .name = name_svideo,
2477 .vmux = 6,
2478 .amux = LINE1,
2479 }},
2480 .radio = {
2481 .name = name_radio,
2482 .amux = LINE2,
2483 },
2484 },
2485 [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
2486 /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
2487 .name = "ASUS Digimatrix TV",
2488 .audio_clock = 0x00200000,
2489 .tuner_type = TUNER_PHILIPS_FQ1216ME,
2490 .tda9887_conf = TDA9887_PRESENT,
2491 .radio_type = UNSET,
2492 .tuner_addr = ADDR_UNSET,
2493 .radio_addr = ADDR_UNSET,
2494 .inputs = {{
2495 .name = name_tv,
2496 .vmux = 1,
2497 .amux = TV,
2498 .tv = 1,
2499 },{
2500 .name = name_comp1,
2501 .vmux = 3,
2502 .amux = LINE1,
2503 },{
2504 .name = name_svideo,
2505 .vmux = 8,
2506 .amux = LINE1,
2507 }},
2508 },
2509 [SAA7134_BOARD_PHILIPS_TIGER] = {
2510 .name = "Philips Tiger reference design",
2511 .audio_clock = 0x00187de7,
2512 .tuner_type = TUNER_PHILIPS_TDA8290,
2513 .radio_type = UNSET,
2514 .tuner_addr = ADDR_UNSET,
2515 .radio_addr = ADDR_UNSET,
2516 .mpeg = SAA7134_MPEG_DVB,
2517 .inputs = {{
2518 .name = name_tv,
2519 .vmux = 1,
2520 .amux = TV,
2521 .tv = 1,
2522 },{
2523 .name = name_comp1,
2524 .vmux = 3,
2525 .amux = LINE1,
2526 },{
2527 .name = name_svideo,
2528 .vmux = 8,
2529 .amux = LINE1,
2530 }},
2531 },
2532};
2114 2533
2115const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2534const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
2116 2535
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = {
2145 },{ 2564 },{
2146 .vendor = PCI_VENDOR_ID_PHILIPS, 2565 .vendor = PCI_VENDOR_ID_PHILIPS,
2147 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2566 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2148 .subvendor = 0x153B, 2567 .subvendor = 0x153b,
2149 .subdevice = 0x1142, 2568 .subdevice = 0x1142,
2150 .driver_data = SAA7134_BOARD_CINERGY400, 2569 .driver_data = SAA7134_BOARD_CINERGY400,
2151 },{ 2570 },{
2152 .vendor = PCI_VENDOR_ID_PHILIPS, 2571 .vendor = PCI_VENDOR_ID_PHILIPS,
2153 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2572 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2154 .subvendor = 0x153B, 2573 .subvendor = 0x153b,
2155 .subdevice = 0x1143, 2574 .subdevice = 0x1143,
2156 .driver_data = SAA7134_BOARD_CINERGY600, 2575 .driver_data = SAA7134_BOARD_CINERGY600,
2157 },{ 2576 },{
2158 .vendor = PCI_VENDOR_ID_PHILIPS, 2577 .vendor = PCI_VENDOR_ID_PHILIPS,
2159 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2578 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2160 .subvendor = 0x153B, 2579 .subvendor = 0x153b,
2161 .subdevice = 0x1158, 2580 .subdevice = 0x1158,
2162 .driver_data = SAA7134_BOARD_CINERGY600_MK3, 2581 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
2163 },{ 2582 },{
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2193 },{ 2612 },{
2194 .vendor = PCI_VENDOR_ID_PHILIPS, 2613 .vendor = PCI_VENDOR_ID_PHILIPS,
2195 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2614 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2615 .subvendor = 0x14c0,
2616 .subdevice = 0x1212, /* minipci, LR1212 */
2617 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
2618 },{
2619 .vendor = PCI_VENDOR_ID_PHILIPS,
2620 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2621 .subvendor = 0x4e42,
2622 .subdevice = 0x0212, /* OEM minipci, LR212 */
2623 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
2624 },{
2625 .vendor = PCI_VENDOR_ID_PHILIPS,
2626 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2196 .subvendor = 0x5168, /* Animation Technologies (LifeView) */ 2627 .subvendor = 0x5168, /* Animation Technologies (LifeView) */
2197 .subdevice = 0x0214, /* Standard PCI, LR214WF */ 2628 .subdevice = 0x0214, /* Standard PCI, LR214WF */
2198 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, 2629 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
2369 },{ 2800 },{
2370 .vendor = PCI_VENDOR_ID_PHILIPS, 2801 .vendor = PCI_VENDOR_ID_PHILIPS,
2371 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 2802 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2372 .subvendor = 0x153B, 2803 .subvendor = 0x153b,
2373 .subdevice = 0x1152, 2804 .subdevice = 0x1152,
2374 .driver_data = SAA7134_BOARD_CINERGY200, 2805 .driver_data = SAA7134_BOARD_CINERGY200,
2375 },{ 2806 },{
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2434 .subvendor = 0x1421, 2865 .subvendor = 0x1421,
2435 .subdevice = 0x0350, /* PCI version */ 2866 .subdevice = 0x0350, /* PCI version */
2436 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2867 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2437
2438 },{ 2868 },{
2439 .vendor = PCI_VENDOR_ID_PHILIPS, 2869 .vendor = PCI_VENDOR_ID_PHILIPS,
2440 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2870 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2441 .subvendor = 0x1421, 2871 .subvendor = 0x1421,
2442 .subdevice = 0x0370, /* cardbus version */ 2872 .subdevice = 0x0370, /* cardbus version */
2443 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2873 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2874 },{
2875 .vendor = PCI_VENDOR_ID_PHILIPS,
2876 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2877 .subvendor = 0x1421,
2878 .subdevice = 0x1370, /* cardbus version */
2879 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2444 2880
2445 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ 2881 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
2446 .vendor = PCI_VENDOR_ID_PHILIPS, 2882 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = {
2459 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2895 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2460 .subvendor = 0x1043, 2896 .subvendor = 0x1043,
2461 .subdevice = 0x0210, /* mini pci PAL/SECAM version */ 2897 .subdevice = 0x0210, /* mini pci PAL/SECAM version */
2462 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX, 2898 .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
2463 2899
2464 },{ 2900 },{
2901 .vendor = PCI_VENDOR_ID_PHILIPS,
2902 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2903 .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
2904 .subdevice = 0x4091,
2905 .driver_data = SAA7134_BOARD_BEHOLD_409FM,
2906 },{
2907 .vendor = PCI_VENDOR_ID_PHILIPS,
2908 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2909 .subvendor = 0x5456, /* GoTView */
2910 .subdevice = 0x7135,
2911 .driver_data = SAA7134_BOARD_GOTVIEW_7135,
2912 },{
2913 .vendor = PCI_VENDOR_ID_PHILIPS,
2914 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2915 .subvendor = PCI_VENDOR_ID_PHILIPS,
2916 .subdevice = 0x2004,
2917 .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
2918 },{
2919 .vendor = PCI_VENDOR_ID_PHILIPS,
2920 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2921 .subvendor = 0x185b,
2922 .subdevice = 0xc900,
2923 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
2924 },{
2925 .vendor = PCI_VENDOR_ID_PHILIPS,
2926 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2927 .subvendor = 0x185b,
2928 .subdevice = 0xc901,
2929 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
2930 },{
2931 .vendor = PCI_VENDOR_ID_PHILIPS,
2932 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2933 .subvendor = 0x1435,
2934 .subdevice = 0x7350,
2935 .driver_data = SAA7134_BOARD_RTD_VFG7350,
2936 },{
2937 .vendor = PCI_VENDOR_ID_PHILIPS,
2938 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2939 .subvendor = 0x1435,
2940 .subdevice = 0x7330,
2941 .driver_data = SAA7134_BOARD_RTD_VFG7330,
2942 },{
2943 .vendor = PCI_VENDOR_ID_PHILIPS,
2944 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2945 .subvendor = 0x1461,
2946 .subdevice = 0x1044,
2947 .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
2948 },{
2949 .vendor = PCI_VENDOR_ID_PHILIPS,
2950 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2951 .subvendor = 0x1131,
2952 .subdevice = 0x4ee9,
2953 .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
2954 },{
2955 .vendor = PCI_VENDOR_ID_PHILIPS,
2956 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2957 .subvendor = 0x11bd,
2958 .subdevice = 0x002e,
2959 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
2960 },{
2961 .vendor = PCI_VENDOR_ID_PHILIPS,
2962 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2963 .subvendor = 0x1043,
2964 .subdevice = 0x4862,
2965 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
2966 },{
2967 .vendor = PCI_VENDOR_ID_PHILIPS,
2968 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2969 .subvendor = PCI_VENDOR_ID_PHILIPS,
2970 .subdevice = 0x2018,
2971 .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
2972 },{
2465 /* --- boards without eeprom + subsystem ID --- */ 2973 /* --- boards without eeprom + subsystem ID --- */
2466 .vendor = PCI_VENDOR_ID_PHILIPS, 2974 .vendor = PCI_VENDOR_ID_PHILIPS,
2467 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2975 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2530 switch (dev->board) { 3038 switch (dev->board) {
2531 case SAA7134_BOARD_FLYVIDEO2000: 3039 case SAA7134_BOARD_FLYVIDEO2000:
2532 case SAA7134_BOARD_FLYVIDEO3000: 3040 case SAA7134_BOARD_FLYVIDEO3000:
2533 dev->has_remote = 1; 3041 dev->has_remote = SAA7134_REMOTE_GPIO;
2534 board_flyvideo(dev); 3042 board_flyvideo(dev);
2535 break; 3043 break;
3044 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
2536 case SAA7134_BOARD_FLYTVPLATINUM_FM: 3045 case SAA7134_BOARD_FLYTVPLATINUM_FM:
2537 case SAA7134_BOARD_CINERGY400: 3046 case SAA7134_BOARD_CINERGY400:
2538 case SAA7134_BOARD_CINERGY600: 3047 case SAA7134_BOARD_CINERGY600:
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2550/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ 3059/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
2551 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 3060 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
2552 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 3061 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
3062 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3063 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
2553 case SAA7134_BOARD_MANLI_MTV001: 3064 case SAA7134_BOARD_MANLI_MTV001:
2554 case SAA7134_BOARD_MANLI_MTV002: 3065 case SAA7134_BOARD_MANLI_MTV002:
3066 case SAA7134_BOARD_BEHOLD_409FM:
2555 case SAA7134_BOARD_AVACSSMARTTV: 3067 case SAA7134_BOARD_AVACSSMARTTV:
2556 dev->has_remote = 1; 3068 case SAA7134_BOARD_GOTVIEW_7135:
3069 case SAA7134_BOARD_KWORLD_TERMINATOR:
3070 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
3071 dev->has_remote = SAA7134_REMOTE_GPIO;
2557 break; 3072 break;
2558 case SAA7134_BOARD_MD5044: 3073 case SAA7134_BOARD_MD5044:
2559 printk("%s: seems there are two different versions of the MD5044\n" 3074 printk("%s: seems there are two different versions of the MD5044\n"
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2565 /* power-up tuner chip */ 3080 /* power-up tuner chip */
2566 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); 3081 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
2567 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); 3082 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
2568 msleep(1); 3083 case SAA7134_BOARD_MONSTERTV_MOBILE:
3084 /* power-up tuner chip */
3085 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
3086 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
2569 break; 3087 break;
2570 case SAA7134_BOARD_FLYDVBTDUO: 3088 case SAA7134_BOARD_FLYDVBTDUO:
2571 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: 3089 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
2572 /* turn the fan on Hac: static for the time being */ 3090 /* turn the fan on */
2573 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); 3091 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
2574 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); 3092 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
2575 break; 3093 break;
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2579 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); 3097 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
2580 msleep(1); 3098 msleep(1);
2581 break; 3099 break;
3100 case SAA7134_BOARD_RTD_VFG7350:
3101
3102 /*
3103 * Make sure Production Test Register at offset 0x1D1 is cleared
3104 * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
3105 * prevents pin 105 from remaining low; keeping pin 105 low
3106 * continually resets the SAA6752 chip.
3107 */
3108
3109 saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
3110 break;
3111 /* i2c remotes */
3112 case SAA7134_BOARD_PINNACLE_PCTV_110i:
3113 case SAA7134_BOARD_UPMOST_PURPLE_TV:
3114 dev->has_remote = SAA7134_REMOTE_I2C;
3115 break;
2582 } 3116 }
2583 return 0; 3117 return 0;
2584} 3118}
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
2613 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); 3147 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
2614 } 3148 }
2615 break; 3149 break;
2616case SAA7134_BOARD_MD7134: 3150 case SAA7134_BOARD_MD7134:
2617 { 3151 {
2618 struct tuner_setup tun_setup; 3152 struct tuner_setup tun_setup;
2619 u8 subaddr; 3153 u8 subaddr;
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134:
2680 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); 3214 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
2681 } 3215 }
2682 break; 3216 break;
3217 case SAA7134_BOARD_PHILIPS_EUROPA:
3218 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3219 /* The Philips EUROPA based hybrid boards have the tuner connected through
3220 * the channel decoder. We have to make it transparent to find it
3221 */
3222 {
3223 struct tuner_setup tun_setup;
3224 u8 data[] = { 0x07, 0x02};
3225 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3226 i2c_transfer(&dev->i2c_adap, &msg, 1);
3227
3228 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3229 tun_setup.type = dev->tuner_type;
3230 tun_setup.addr = dev->tuner_addr;
3231
3232 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
3233 }
3234 break;
3235 case SAA7134_BOARD_PHILIPS_TIGER:
3236 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
3237 /* this is a hybrid board, initialize to analog mode */
3238 {
3239 u8 data[] = { 0x3c, 0x33, 0x68};
3240 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3241 i2c_transfer(&dev->i2c_adap, &msg, 1);
3242 }
3243 break;
2683 } 3244 }
2684 return 0; 3245 return 0;
2685} 3246}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index e5e36f3c6250..19b88744fb31 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
57module_param(oss, int, 0444); 57module_param(oss, int, 0444);
58MODULE_PARM_DESC(oss,"register oss devices (default: no)"); 58MODULE_PARM_DESC(oss,"register oss devices (default: no)");
59 59
60static unsigned int alsa = 0;
61module_param(alsa, int, 0444);
62MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
63
60static unsigned int latency = UNSET; 64static unsigned int latency = UNSET;
61module_param(latency, int, 0444); 65module_param(latency, int, 0444);
62MODULE_PARM_DESC(latency,"pci latency timer"); 66MODULE_PARM_DESC(latency,"pci latency timer");
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
190 194
191static int need_empress; 195static int need_empress;
192static int need_dvb; 196static int need_dvb;
197static int need_alsa;
193 198
194static int pending_call(struct notifier_block *self, unsigned long state, 199static int pending_call(struct notifier_block *self, unsigned long state,
195 void *module) 200 void *module)
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state,
197 if (module != THIS_MODULE || state != MODULE_STATE_LIVE) 202 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
198 return NOTIFY_DONE; 203 return NOTIFY_DONE;
199 204
200 if (need_empress) 205 if (need_empress)
201 request_module("saa7134-empress"); 206 request_module("saa7134-empress");
202 if (need_dvb) 207 if (need_dvb)
203 request_module("saa7134-dvb"); 208 request_module("saa7134-dvb");
209 if (need_alsa)
210 request_module("saa7134-alsa");
204 return NOTIFY_DONE; 211 return NOTIFY_DONE;
205} 212}
206 213
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
275 282
276int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) 283int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
277{ 284{
278 __le32 *cpu; 285 __le32 *cpu;
279 dma_addr_t dma_addr; 286 dma_addr_t dma_addr;
280 287
281 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); 288 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
282 if (NULL == cpu) 289 if (NULL == cpu)
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
436 ctrl |= SAA7134_MAIN_CTRL_TE0; 443 ctrl |= SAA7134_MAIN_CTRL_TE0;
437 irq |= SAA7134_IRQ1_INTE_RA0_1 | 444 irq |= SAA7134_IRQ1_INTE_RA0_1 |
438 SAA7134_IRQ1_INTE_RA0_0; 445 SAA7134_IRQ1_INTE_RA0_0;
439 cap = dev->video_q.curr->vb.field; 446 cap = dev->video_q.curr->vb.field;
440 } 447 }
441 448
442 /* video capture -- dma 1+2 (planar modes) */ 449 /* video capture -- dma 1+2 (planar modes) */
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
465 } 472 }
466 473
467 /* audio capture -- dma 3 */ 474 /* audio capture -- dma 3 */
468 if (dev->oss.dma_running) { 475 if (dev->dmasound.dma_running) {
469 ctrl |= SAA7134_MAIN_CTRL_TE6; 476 ctrl |= SAA7134_MAIN_CTRL_TE6;
470 irq |= SAA7134_IRQ1_INTE_RA3_1 | 477 irq |= SAA7134_IRQ1_INTE_RA3_1 |
471 SAA7134_IRQ1_INTE_RA3_0; 478 SAA7134_IRQ1_INTE_RA3_0;
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
570 dev->name); 577 dev->name);
571 goto out; 578 goto out;
572 } 579 }
580
581 /* If alsa support is active and we get a sound report, exit
582 and let the saa7134-alsa module deal with it */
583
584 if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
585 if (irq_debug > 1)
586 printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
587 dev->name);
588 goto out;
589 }
590
573 handled = 1; 591 handled = 1;
574 saa_writel(SAA7134_IRQ_REPORT,report); 592 saa_writel(SAA7134_IRQ_REPORT,report);
575 if (irq_debug) 593 if (irq_debug)
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
591 card_has_mpeg(dev)) 609 card_has_mpeg(dev))
592 saa7134_irq_ts_done(dev,status); 610 saa7134_irq_ts_done(dev,status);
593 611
594 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) 612 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
595 saa7134_irq_oss_done(dev,status); 613 if (oss) {
614 saa7134_irq_oss_done(dev,status);
615 }
616 }
596 617
597 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 618 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
598 SAA7134_IRQ_REPORT_GPIO18)) && 619 SAA7134_IRQ_REPORT_GPIO18)) &&
599 dev->remote) 620 dev->remote)
600 saa7134_input_irq(dev); 621 saa7134_input_irq(dev);
622
601 } 623 }
602 624
603 if (10 == loop) { 625 if (10 == loop) {
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
636 658
637 saa_writel(SAA7134_IRQ1, 0); 659 saa_writel(SAA7134_IRQ1, 0);
638 saa_writel(SAA7134_IRQ2, 0); 660 saa_writel(SAA7134_IRQ2, 0);
639 init_MUTEX(&dev->lock); 661 init_MUTEX(&dev->lock);
640 spin_lock_init(&dev->slock); 662 spin_lock_init(&dev->slock);
641 663
642 saa7134_track_gpio(dev,"pre-init"); 664 saa7134_track_gpio(dev,"pre-init");
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
646 saa7134_ts_init1(dev); 668 saa7134_ts_init1(dev);
647 saa7134_input_init1(dev); 669 saa7134_input_init1(dev);
648 670
649 switch (dev->pci->device) {
650 case PCI_DEVICE_ID_PHILIPS_SAA7134:
651 case PCI_DEVICE_ID_PHILIPS_SAA7133:
652 case PCI_DEVICE_ID_PHILIPS_SAA7135:
653 saa7134_oss_init1(dev);
654 break;
655 }
656
657 /* RAM FIFO config */ 671 /* RAM FIFO config */
658 saa_writel(SAA7134_FIFO_SIZE, 0x08070503); 672 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
659 saa_writel(SAA7134_THRESHOULD,0x02020202); 673 saa_writel(SAA7134_THRESHOULD,0x02020202);
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
668 SAA7134_MAIN_CTRL_ESFE | 682 SAA7134_MAIN_CTRL_ESFE |
669 SAA7134_MAIN_CTRL_EBDAC); 683 SAA7134_MAIN_CTRL_EBDAC);
670 684
685 /*
686 * Initialize OSS _after_ enabling audio clock PLL and audio processing.
687 * OSS initialization writes to registers via the audio DSP; these
688 * writes will fail unless the audio clock has been started. At worst,
689 * audio will not work.
690 */
691
692 switch (dev->pci->device) {
693 case PCI_DEVICE_ID_PHILIPS_SAA7134:
694 case PCI_DEVICE_ID_PHILIPS_SAA7133:
695 case PCI_DEVICE_ID_PHILIPS_SAA7135:
696 saa7134_oss_init1(dev);
697 break;
698 }
699
671 /* enable peripheral devices */ 700 /* enable peripheral devices */
672 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 701 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
673 702
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
687 saa7134_tvaudio_init2(dev); 716 saa7134_tvaudio_init2(dev);
688 717
689 /* enable IRQ's */ 718 /* enable IRQ's */
690 irq2_mask = 719 irq2_mask =
691 SAA7134_IRQ2_INTE_DEC3 | 720 SAA7134_IRQ2_INTE_DEC3 |
692 SAA7134_IRQ2_INTE_DEC2 | 721 SAA7134_IRQ2_INTE_DEC2 |
693 SAA7134_IRQ2_INTE_DEC1 | 722 SAA7134_IRQ2_INTE_DEC1 |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
695 SAA7134_IRQ2_INTE_PE | 724 SAA7134_IRQ2_INTE_PE |
696 SAA7134_IRQ2_INTE_AR; 725 SAA7134_IRQ2_INTE_AR;
697 726
698 if (dev->has_remote) 727 if (dev->has_remote == SAA7134_REMOTE_GPIO)
699 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | 728 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
700 SAA7134_IRQ2_INTE_GPIO18A | 729 SAA7134_IRQ2_INTE_GPIO18A |
701 SAA7134_IRQ2_INTE_GPIO16 ); 730 SAA7134_IRQ2_INTE_GPIO16 );
731 else if (dev->has_remote == SAA7134_REMOTE_I2C)
732 request_module("ir-kbd-i2c");
702 733
703 saa_writel(SAA7134_IRQ1, 0); 734 saa_writel(SAA7134_IRQ1, 0);
704 saa_writel(SAA7134_IRQ2, irq2_mask); 735 saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
872 903
873 /* print pci info */ 904 /* print pci info */
874 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 905 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
875 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 906 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
876 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 907 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
877 "latency: %d, mmio: 0x%lx\n", dev->name, 908 "latency: %d, mmio: 0x%lx\n", dev->name,
878 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 909 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
879 dev->pci_lat,pci_resource_start(pci_dev,0)); 910 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
897 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; 928 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
898 if (UNSET != tuner[dev->nr]) 929 if (UNSET != tuner[dev->nr])
899 dev->tuner_type = tuner[dev->nr]; 930 dev->tuner_type = tuner[dev->nr];
900 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 931 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
901 dev->name,pci_dev->subsystem_vendor, 932 dev->name,pci_dev->subsystem_vendor,
902 pci_dev->subsystem_device,saa7134_boards[dev->board].name, 933 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
903 dev->board, card[dev->nr] == dev->board ? 934 dev->board, card[dev->nr] == dev->board ?
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
947 request_module("tuner"); 978 request_module("tuner");
948 if (dev->tda9887_conf) 979 if (dev->tda9887_conf)
949 request_module("tda9887"); 980 request_module("tda9887");
950 if (card_is_empress(dev)) { 981 if (card_is_empress(dev)) {
951 request_module("saa6752hs"); 982 request_module("saa6752hs");
952 request_module_depend("saa7134-empress",&need_empress); 983 request_module_depend("saa7134-empress",&need_empress);
953 } 984 }
954 985
955 if (card_is_dvb(dev)) 986 if (card_is_dvb(dev))
956 request_module_depend("saa7134-dvb",&need_dvb); 987 request_module_depend("saa7134-dvb",&need_dvb);
957 988
989 if (!oss && alsa) {
990 dprintk("Requesting ALSA module\n");
991 request_module_depend("saa7134-alsa",&need_alsa);
992 }
993
994
958 v4l2_prio_init(&dev->prio); 995 v4l2_prio_init(&dev->prio);
959 996
960 /* register v4l devices */ 997 /* register v4l devices */
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
993 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1030 case PCI_DEVICE_ID_PHILIPS_SAA7133:
994 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1031 case PCI_DEVICE_ID_PHILIPS_SAA7135:
995 if (oss) { 1032 if (oss) {
996 err = dev->oss.minor_dsp = 1033 err = dev->dmasound.minor_dsp =
997 register_sound_dsp(&saa7134_dsp_fops, 1034 register_sound_dsp(&saa7134_dsp_fops,
998 dsp_nr[dev->nr]); 1035 dsp_nr[dev->nr]);
999 if (err < 0) { 1036 if (err < 0) {
1000 goto fail4; 1037 goto fail4;
1001 } 1038 }
1002 printk(KERN_INFO "%s: registered device dsp%d\n", 1039 printk(KERN_INFO "%s: registered device dsp%d\n",
1003 dev->name,dev->oss.minor_dsp >> 4); 1040 dev->name,dev->dmasound.minor_dsp >> 4);
1004 1041
1005 err = dev->oss.minor_mixer = 1042 err = dev->dmasound.minor_mixer =
1006 register_sound_mixer(&saa7134_mixer_fops, 1043 register_sound_mixer(&saa7134_mixer_fops,
1007 mixer_nr[dev->nr]); 1044 mixer_nr[dev->nr]);
1008 if (err < 0) 1045 if (err < 0)
1009 goto fail5; 1046 goto fail5;
1010 printk(KERN_INFO "%s: registered device mixer%d\n", 1047 printk(KERN_INFO "%s: registered device mixer%d\n",
1011 dev->name,dev->oss.minor_mixer >> 4); 1048 dev->name,dev->dmasound.minor_mixer >> 4);
1012 } 1049 }
1013 break; 1050 break;
1014 } 1051 }
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1035 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1072 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1036 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1073 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1037 if (oss) 1074 if (oss)
1038 unregister_sound_dsp(dev->oss.minor_dsp); 1075 unregister_sound_dsp(dev->dmasound.minor_dsp);
1039 break; 1076 break;
1040 } 1077 }
1041 fail4: 1078 fail4:
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1055 1092
1056static void __devexit saa7134_finidev(struct pci_dev *pci_dev) 1093static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1057{ 1094{
1058 struct saa7134_dev *dev = pci_get_drvdata(pci_dev); 1095 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1059 struct list_head *item; 1096 struct list_head *item;
1060 struct saa7134_mpeg_ops *mops; 1097 struct saa7134_mpeg_ops *mops;
1061 1098
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1093 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1130 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1094 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1131 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1095 if (oss) { 1132 if (oss) {
1096 unregister_sound_mixer(dev->oss.minor_mixer); 1133 unregister_sound_mixer(dev->dmasound.minor_mixer);
1097 unregister_sound_dsp(dev->oss.minor_dsp); 1134 unregister_sound_dsp(dev->dmasound.minor_dsp);
1098 } 1135 }
1099 break; 1136 break;
1100 } 1137 }
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister);
1149/* ----------------------------------------------------------- */ 1186/* ----------------------------------------------------------- */
1150 1187
1151static struct pci_driver saa7134_pci_driver = { 1188static struct pci_driver saa7134_pci_driver = {
1152 .name = "saa7134", 1189 .name = "saa7134",
1153 .id_table = saa7134_pci_tbl, 1190 .id_table = saa7134_pci_tbl,
1154 .probe = saa7134_initdev, 1191 .probe = saa7134_initdev,
1155 .remove = __devexit_p(saa7134_finidev), 1192 .remove = __devexit_p(saa7134_finidev),
1156}; 1193};
1157 1194
1158static int saa7134_init(void) 1195static int saa7134_init(void)
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
1188EXPORT_SYMBOL(saa7134_devlist); 1225EXPORT_SYMBOL(saa7134_devlist);
1189EXPORT_SYMBOL(saa7134_boards); 1226EXPORT_SYMBOL(saa7134_boards);
1190 1227
1228/* ----------------- For ALSA -------------------------------- */
1229
1230EXPORT_SYMBOL(saa7134_pgtable_free);
1231EXPORT_SYMBOL(saa7134_pgtable_build);
1232EXPORT_SYMBOL(saa7134_pgtable_alloc);
1233EXPORT_SYMBOL(saa7134_set_dmabits);
1234
1191/* ----------------------------------------------------------- */ 1235/* ----------------------------------------------------------- */
1192/* 1236/*
1193 * Local variables: 1237 * Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 639ae51a052d..e016480c3468 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "saa7134-reg.h" 32#include "saa7134-reg.h"
34#include "saa7134.h" 33#include "saa7134.h"
35 34
@@ -40,6 +39,10 @@
40#ifdef HAVE_TDA1004X 39#ifdef HAVE_TDA1004X
41# include "tda1004x.h" 40# include "tda1004x.h"
42#endif 41#endif
42#ifdef HAVE_NXT200X
43# include "nxt200x.h"
44# include "dvb-pll.h"
45#endif
43 46
44MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 47MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
45MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = {
151/* ------------------------------------------------------------------ */ 154/* ------------------------------------------------------------------ */
152 155
153#ifdef HAVE_TDA1004X 156#ifdef HAVE_TDA1004X
154static int philips_tu1216_pll_init(struct dvb_frontend *fe)
155{
156 struct saa7134_dev *dev = fe->dvb->priv;
157 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
158 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
159
160 /* setup PLL configuration */
161 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
162 return -EIO;
163 msleep(1);
164 157
165 return 0; 158static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
166}
167
168static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
169{ 159{
170 struct saa7134_dev *dev = fe->dvb->priv; 160 struct saa7134_dev *dev = fe->dvb->priv;
171 u8 tuner_buf[4]; 161 u8 tuner_buf[4];
172 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = 162 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
173 sizeof(tuner_buf) }; 163 sizeof(tuner_buf) };
174 int tuner_frequency = 0; 164 int tuner_frequency = 0;
175 u8 band, cp, filter; 165 u8 band, cp, filter;
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
242 232
243 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 233 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
244 return -EIO; 234 return -EIO;
235 msleep(1);
236 return 0;
237}
245 238
239static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
240{
241 struct saa7134_dev *dev = fe->dvb->priv;
242 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
243 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
244
245 /* setup PLL configuration */
246 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
247 return -EIO;
246 msleep(1); 248 msleep(1);
249
247 return 0; 250 return 0;
248} 251}
249 252
253/* ------------------------------------------------------------------ */
254
255static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
256{
257 return philips_tda6651_pll_init(0x60, fe);
258}
259
260static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
261{
262 return philips_tda6651_pll_set(0x60, fe, params);
263}
264
250static int philips_tu1216_request_firmware(struct dvb_frontend *fe, 265static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
251 const struct firmware **fw, char *name) 266 const struct firmware **fw, char *name)
252{ 267{
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
254 return request_firmware(fw, name, &dev->pci->dev); 269 return request_firmware(fw, name, &dev->pci->dev);
255} 270}
256 271
257static struct tda1004x_config philips_tu1216_config = { 272static struct tda1004x_config philips_tu1216_60_config = {
273
274 .demod_address = 0x8,
275 .invert = 1,
276 .invert_oclk = 0,
277 .xtal_freq = TDA10046_XTAL_4M,
278 .agc_config = TDA10046_AGC_DEFAULT,
279 .if_freq = TDA10046_FREQ_3617,
280 .pll_init = philips_tu1216_pll_60_init,
281 .pll_set = philips_tu1216_pll_60_set,
282 .pll_sleep = NULL,
283 .request_firmware = philips_tu1216_request_firmware,
284};
285
286/* ------------------------------------------------------------------ */
287
288static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
289{
290 return philips_tda6651_pll_init(0x61, fe);
291}
292
293static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
294{
295 return philips_tda6651_pll_set(0x61, fe, params);
296}
297
298static struct tda1004x_config philips_tu1216_61_config = {
258 299
259 .demod_address = 0x8, 300 .demod_address = 0x8,
260 .invert = 1, 301 .invert = 1,
261 .invert_oclk = 1, 302 .invert_oclk = 0,
262 .xtal_freq = TDA10046_XTAL_4M, 303 .xtal_freq = TDA10046_XTAL_4M,
263 .agc_config = TDA10046_AGC_DEFAULT, 304 .agc_config = TDA10046_AGC_DEFAULT,
264 .if_freq = TDA10046_FREQ_3617, 305 .if_freq = TDA10046_FREQ_3617,
265 .pll_init = philips_tu1216_pll_init, 306 .pll_init = philips_tu1216_pll_61_init,
266 .pll_set = philips_tu1216_pll_set, 307 .pll_set = philips_tu1216_pll_61_set,
267 .pll_sleep = NULL, 308 .pll_sleep = NULL,
268 .request_firmware = philips_tu1216_request_firmware, 309 .request_firmware = philips_tu1216_request_firmware,
269}; 310};
270 311
271/* ------------------------------------------------------------------ */ 312/* ------------------------------------------------------------------ */
272 313
314static int philips_europa_pll_init(struct dvb_frontend *fe)
315{
316 struct saa7134_dev *dev = fe->dvb->priv;
317 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
318 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
319
320 /* setup PLL configuration */
321 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
322 return -EIO;
323 msleep(1);
324
325 /* switch the board to dvb mode */
326 init_msg.addr = 0x43;
327 init_msg.len = 0x02;
328 msg[0] = 0x00;
329 msg[1] = 0x40;
330 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
331 return -EIO;
332
333 return 0;
334}
335
336static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
337{
338 return philips_tda6651_pll_set(0x61, fe, params);
339}
340
341static void philips_europa_analog(struct dvb_frontend *fe)
342{
343 struct saa7134_dev *dev = fe->dvb->priv;
344 /* this message actually turns the tuner back to analog mode */
345 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
346 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
347
348 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
349 msleep(1);
350
351 /* switch the board to analog mode */
352 analog_msg.addr = 0x43;
353 analog_msg.len = 0x02;
354 msg[0] = 0x00;
355 msg[1] = 0x14;
356 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
357}
358
359static struct tda1004x_config philips_europa_config = {
360
361 .demod_address = 0x8,
362 .invert = 0,
363 .invert_oclk = 0,
364 .xtal_freq = TDA10046_XTAL_4M,
365 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
366 .if_freq = TDA10046_FREQ_052,
367 .pll_init = philips_europa_pll_init,
368 .pll_set = philips_td1316_pll_set,
369 .pll_sleep = philips_europa_analog,
370 .request_firmware = NULL,
371};
372
373/* ------------------------------------------------------------------ */
273 374
274static int philips_fmd1216_pll_init(struct dvb_frontend *fe) 375static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
275{ 376{
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
382 return 0; 483 return 0;
383} 484}
384 485
385#ifdef HAVE_TDA1004X
386static struct tda1004x_config medion_cardbus = { 486static struct tda1004x_config medion_cardbus = {
387 .demod_address = 0x08, 487 .demod_address = 0x08,
388 .invert = 1, 488 .invert = 1,
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = {
395 .pll_sleep = philips_fmd1216_analog, 495 .pll_sleep = philips_fmd1216_analog,
396 .request_firmware = NULL, 496 .request_firmware = NULL,
397}; 497};
398#endif
399 498
400/* ------------------------------------------------------------------ */ 499/* ------------------------------------------------------------------ */
401 500
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
452 u8 tuner_buf[14]; 551 u8 tuner_buf[14];
453 552
454 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, 553 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
455 .len = sizeof(tuner_buf) }; 554 .len = sizeof(tuner_buf) };
456 int i, tuner_freq, if_freq; 555 int i, tuner_freq, if_freq;
457 u32 N; 556 u32 N;
458 switch (params->u.ofdm.bandwidth) { 557 switch (params->u.ofdm.bandwidth) {
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
511 struct saa7134_dev *dev = fe->dvb->priv; 610 struct saa7134_dev *dev = fe->dvb->priv;
512 static u8 tda827x_sleep[] = { 0x30, 0xd0}; 611 static u8 tda827x_sleep[] = { 0x30, 0xd0};
513 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, 612 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
514 .len = sizeof(tda827x_sleep) }; 613 .len = sizeof(tda827x_sleep) };
515 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 614 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
516} 615}
517 616
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = {
527 .pll_sleep = philips_tda827x_pll_sleep, 626 .pll_sleep = philips_tda827x_pll_sleep,
528 .request_firmware = NULL, 627 .request_firmware = NULL,
529}; 628};
629
630/* ------------------------------------------------------------------ */
631
632struct tda827xa_data {
633 u32 lomax;
634 u8 svco;
635 u8 spd;
636 u8 scr;
637 u8 sbs;
638 u8 gc3;
639};
640
641static struct tda827xa_data tda827xa_dvbt[] = {
642 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
643 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
644 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
645 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
646 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
647 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
648 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
649 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
650 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
651 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
652 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
653 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
654 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
655 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
656 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
657 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
658 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
659 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
660 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
661 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
662 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
663 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
664 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
665 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
666 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
667 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
668 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
669
670
671static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
672{
673 struct saa7134_dev *dev = fe->dvb->priv;
674 u8 tuner_buf[14];
675 unsigned char reg2[2];
676
677 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
678 int i, tuner_freq, if_freq;
679 u32 N;
680
681 switch (params->u.ofdm.bandwidth) {
682 case BANDWIDTH_6_MHZ:
683 if_freq = 4000000;
684 break;
685 case BANDWIDTH_7_MHZ:
686 if_freq = 4500000;
687 break;
688 default: /* 8 MHz or Auto */
689 if_freq = 5000000;
690 break;
691 }
692 tuner_freq = params->frequency + if_freq;
693
694 i = 0;
695 while (tda827xa_dvbt[i].lomax < tuner_freq) {
696 if(tda827xa_dvbt[i + 1].lomax == 0)
697 break;
698 i++;
699 }
700
701 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
702 tuner_buf[0] = 0; // subaddress
703 tuner_buf[1] = N >> 8;
704 tuner_buf[2] = N & 0xff;
705 tuner_buf[3] = 0;
706 tuner_buf[4] = 0x16;
707 tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
708 tda827xa_dvbt[i].sbs;
709 tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
710 tuner_buf[7] = 0x0c;
711 tuner_buf[8] = 0x06;
712 tuner_buf[9] = 0x24;
713 tuner_buf[10] = 0xff;
714 tuner_buf[11] = 0x60;
715 tuner_buf[12] = 0x00;
716 tuner_buf[13] = 0x39; // lpsel
717 msg.len = 14;
718 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
719 return -EIO;
720
721 msg.buf= reg2;
722 msg.len = 2;
723 reg2[0] = 0x60;
724 reg2[1] = 0x3c;
725 i2c_transfer(&dev->i2c_adap, &msg, 1);
726
727 reg2[0] = 0xa0;
728 reg2[1] = 0x40;
729 i2c_transfer(&dev->i2c_adap, &msg, 1);
730
731 msleep(2);
732 /* correct CP value */
733 reg2[0] = 0x30;
734 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
735 msg.len = 2;
736 i2c_transfer(&dev->i2c_adap, &msg, 1);
737
738 msleep(550);
739 reg2[0] = 0x50;
740 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
741 i2c_transfer(&dev->i2c_adap, &msg, 1);
742
743 return 0;
744
745}
746
747static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe)
748{
749 struct saa7134_dev *dev = fe->dvb->priv;
750 static u8 tda827xa_sleep[] = { 0x30, 0x90};
751 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
752 .len = sizeof(tda827xa_sleep) };
753 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
754
755}
756
757/* ------------------------------------------------------------------ */
758
759static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
760{
761 int ret;
762 struct saa7134_dev *dev = fe->dvb->priv;
763 static u8 tda8290_close[] = { 0x21, 0xc0};
764 static u8 tda8290_open[] = { 0x21, 0x80};
765 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
766 /* close tda8290 i2c bridge */
767 tda8290_msg.buf = tda8290_close;
768 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
769 if (ret != 1)
770 return -EIO;
771 msleep(20);
772 ret = philips_tda827xa_pll_set(0x61, fe, params);
773 if (ret != 0)
774 return ret;
775 /* open tda8290 i2c bridge */
776 tda8290_msg.buf = tda8290_open;
777 i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
778 return ret;
779};
780
781static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
782{
783 struct saa7134_dev *dev = fe->dvb->priv;
784 static u8 data[] = { 0x3c, 0x33, 0x6a};
785 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
786
787 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
788 return -EIO;
789 return 0;
790}
791
792static void philips_tiger_analog_mode(struct dvb_frontend *fe)
793{
794 struct saa7134_dev *dev = fe->dvb->priv;
795 static u8 data[] = { 0x3c, 0x33, 0x68};
796 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
797
798 i2c_transfer(&dev->i2c_adap, &msg, 1);
799 philips_tda827xa_pll_sleep( 0x61, fe);
800}
801
802static struct tda1004x_config philips_tiger_config = {
803 .demod_address = 0x08,
804 .invert = 1,
805 .invert_oclk = 0,
806 .xtal_freq = TDA10046_XTAL_16M,
807 .agc_config = TDA10046_AGC_TDA827X,
808 .if_freq = TDA10046_FREQ_045,
809 .pll_init = philips_tiger_dvb_mode,
810 .pll_set = philips_tiger_pll_set,
811 .pll_sleep = philips_tiger_analog_mode,
812 .request_firmware = NULL,
813};
814
815#endif
816
817/* ------------------------------------------------------------------ */
818
819#ifdef HAVE_NXT200X
820static struct nxt200x_config avertvhda180 = {
821 .demod_address = 0x0a,
822 .pll_address = 0x61,
823 .pll_desc = &dvb_pll_tdhu2,
824};
530#endif 825#endif
531 826
532/* ------------------------------------------------------------------ */ 827/* ------------------------------------------------------------------ */
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev)
558 &dev->i2c_adap); 853 &dev->i2c_adap);
559 break; 854 break;
560 case SAA7134_BOARD_PHILIPS_TOUGH: 855 case SAA7134_BOARD_PHILIPS_TOUGH:
561 dev->dvb.frontend = tda10046_attach(&philips_tu1216_config, 856 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
562 &dev->i2c_adap); 857 &dev->i2c_adap);
563 break; 858 break;
564 case SAA7134_BOARD_FLYDVBTDUO: 859 case SAA7134_BOARD_FLYDVBTDUO:
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev)
569 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 864 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
570 &dev->i2c_adap); 865 &dev->i2c_adap);
571 break; 866 break;
867 case SAA7134_BOARD_PHILIPS_EUROPA:
868 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
869 &dev->i2c_adap);
870 break;
871 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
872 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
873 &dev->i2c_adap);
874 break;
875 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
876 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
877 &dev->i2c_adap);
878 break;
879 case SAA7134_BOARD_PHILIPS_TIGER:
880 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
881 &dev->i2c_adap);
882 break;
883 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
884 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
885 &dev->i2c_adap);
886 break;
887#endif
888#ifdef HAVE_NXT200X
889 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
890 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
891 break;
572#endif 892#endif
573 default: 893 default:
574 printk("%s: Huh? unknown DVB card?\n",dev->name); 894 printk("%s: Huh? unknown DVB card?\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 77b627eb6483..e9ec69efb4c9 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
55 55
56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
57 msleep(10); 57 msleep(10);
58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
59 msleep(100); 59 msleep(100);
60 dev->empress_started = 0; 60 dev->empress_started = 0;
61} 61}
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
65 ts_reset_encoder(dev); 65 ts_reset_encoder(dev);
66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); 66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
67 dev->empress_started = 1; 67 dev->empress_started = 1;
68 return 0; 68 return 0;
69} 69}
70 70
71/* ------------------------------------------------------------------ */ 71/* ------------------------------------------------------------------ */
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
169 struct v4l2_capability *cap = arg; 169 struct v4l2_capability *cap = arg;
170 170
171 memset(cap,0,sizeof(*cap)); 171 memset(cap,0,sizeof(*cap));
172 strcpy(cap->driver, "saa7134"); 172 strcpy(cap->driver, "saa7134");
173 strlcpy(cap->card, saa7134_boards[dev->board].name, 173 strlcpy(cap->card, saa7134_boards[dev->board].name,
174 sizeof(cap->card)); 174 sizeof(cap->card));
175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 711aa8e85fac..7575043f0874 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
239 unsigned char data; 239 unsigned char data;
240 int addr,rc,i,byte; 240 int addr,rc,i,byte;
241 241
242 status = i2c_get_status(dev); 242 status = i2c_get_status(dev);
243 if (!i2c_is_idle(status)) 243 if (!i2c_is_idle(status))
244 if (!i2c_reset(dev)) 244 if (!i2c_reset(dev))
245 return -EIO; 245 return -EIO;
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
296 rc = -EIO; 296 rc = -EIO;
297 if (!i2c_is_busy_wait(dev)) 297 if (!i2c_is_busy_wait(dev))
298 goto err; 298 goto err;
299 status = i2c_get_status(dev); 299 status = i2c_get_status(dev);
300 if (i2c_is_error(status)) 300 if (i2c_is_error(status))
301 goto err; 301 goto err;
302 /* ensure that the bus is idle for at least one bit slot */ 302 /* ensure that the bus is idle for at least one bit slot */
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client)
335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
336 client->driver->name, client->addr, client->name); 336 client->driver->name, client->addr, client->name);
337 337
338 /* Am I an i2c remote control? */
339
340 switch (client->addr) {
341 case 0x7a:
342 case 0x47:
343 {
344 struct IR_i2c *ir = i2c_get_clientdata(client);
345 d1printk("%s i2c IR detected (%s).\n",
346 client->driver->name,ir->phys);
347 saa7134_set_i2c_ir(dev,ir);
348 break;
349 }
350 }
351
338 if (!client->driver->command) 352 if (!client->driver->command)
339 return 0; 353 return 0;
340 354
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client)
348 362
349 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); 363 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
350 } 364 }
351 } 365 }
352 366
353 if (tuner != UNSET) { 367 if (tuner != UNSET) {
354 368
355 tun_setup.type = tuner; 369 tun_setup.type = tuner;
356 tun_setup.addr = saa7134_boards[dev->board].tuner_addr; 370 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
357 371
358 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { 372 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
359 373
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client)
361 375
362 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); 376 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
363 } 377 }
364 } 378 }
365 379
366 client->driver->command(client, TDA9887_SET_CONFIG, &conf); 380 client->driver->command(client, TDA9887_SET_CONFIG, &conf);
367 381
368 return 0; 382 return 0;
369} 383}
370 384
371static struct i2c_algorithm saa7134_algo = { 385static struct i2c_algorithm saa7134_algo = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 242cb235cf92..329accda6d45 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39 39
40#define dprintk(fmt, arg...) if (ir_debug) \ 40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42#define i2cdprintk(fmt, arg...) if (ir_debug) \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
42 44
43/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
44 46
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
114/* Alfons Geser <a.geser@cox.net> 116/* Alfons Geser <a.geser@cox.net>
115 * updates from Job D. R. Borges <jobdrb@ig.com.br> */ 117 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
116static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { 118static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
117 [ 18 ] = KEY_POWER, 119 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR 120 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD 121 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music 122 [ 23 ] = KEY_AUDIO, // music
121 // DVR mode / DVD mode / music mode 123 // DVR mode / DVD mode / music mode
122 124
123 [ 27 ] = KEY_MUTE, // mute 125 [ 27 ] = KEY_MUTE, // mute
124 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek 126 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
125 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek 127 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
126 [ 22 ] = KEY_ZOOM, // full screen 128 [ 22 ] = KEY_ZOOM, // full screen
127 [ 28 ] = KEY_VIDEO, // video source / eject / delall 129 [ 28 ] = KEY_VIDEO, // video source / eject / delall
128 [ 29 ] = KEY_RESTART, // playback / angle / del 130 [ 29 ] = KEY_RESTART, // playback / angle / del
129 [ 47 ] = KEY_SEARCH, // scan / menu / playlist 131 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
130 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo 132 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
131 133
132 [ 49 ] = KEY_HELP, // help 134 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo 135 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel 136 [ 51 ] = KEY_ESC, // cancel
135 137
136 [ 12 ] = KEY_UP, // up 138 [ 12 ] = KEY_UP, // up
137 [ 16 ] = KEY_DOWN, // down 139 [ 16 ] = KEY_DOWN, // down
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
148 [ 45 ] = KEY_PLAY, // play 150 [ 45 ] = KEY_PLAY, // play
149 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle 151 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
150 152
151 [ 0 ] = KEY_KP0, 153 [ 0 ] = KEY_KP0,
152 [ 5 ] = KEY_KP1, 154 [ 5 ] = KEY_KP1,
153 [ 6 ] = KEY_KP2, 155 [ 6 ] = KEY_KP2,
154 [ 7 ] = KEY_KP3, 156 [ 7 ] = KEY_KP3,
155 [ 9 ] = KEY_KP4, 157 [ 9 ] = KEY_KP4,
156 [ 10 ] = KEY_KP5, 158 [ 10 ] = KEY_KP5,
157 [ 11 ] = KEY_KP6, 159 [ 11 ] = KEY_KP6,
158 [ 13 ] = KEY_KP7, 160 [ 13 ] = KEY_KP7,
159 [ 14 ] = KEY_KP8, 161 [ 14 ] = KEY_KP8,
160 [ 15 ] = KEY_KP9, 162 [ 15 ] = KEY_KP9,
161 163
162 [ 42 ] = KEY_VOLUMEUP, 164 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN, 165 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up 166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down 167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
166 168
167 [ 19 ] = KEY_KPENTER, // enter 169 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot) 170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
169}; 171};
170 172
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { 173static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
401 403
402 // 0x1d unused ? 404 // 0x1d unused ?
403}; 405};
404/* ---------------------------------------------------------------------- */ 406
407
408/* Mike Baikov <mike@baikov.com> */
409static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
410
411 [ 33 ] = KEY_POWER,
412 [ 105] = KEY_TV,
413 [ 51 ] = KEY_KP0,
414 [ 81 ] = KEY_KP1,
415 [ 49 ] = KEY_KP2,
416 [ 113] = KEY_KP3,
417 [ 59 ] = KEY_KP4,
418 [ 88 ] = KEY_KP5,
419 [ 65 ] = KEY_KP6,
420 [ 72 ] = KEY_KP7,
421 [ 48 ] = KEY_KP8,
422 [ 83 ] = KEY_KP9,
423 [ 115] = KEY_AGAIN, /* LOOP */
424 [ 10 ] = KEY_AUDIO,
425 [ 97 ] = KEY_PRINT, /* PREVIEW */
426 [ 122] = KEY_VIDEO,
427 [ 32 ] = KEY_CHANNELUP,
428 [ 64 ] = KEY_CHANNELDOWN,
429 [ 24 ] = KEY_VOLUMEDOWN,
430 [ 80 ] = KEY_VOLUMEUP,
431 [ 16 ] = KEY_MUTE,
432 [ 74 ] = KEY_SEARCH,
433 [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
434 [ 34 ] = KEY_RECORD,
435 [ 98 ] = KEY_STOP,
436 [ 120] = KEY_PLAY,
437 [ 57 ] = KEY_REWIND,
438 [ 89 ] = KEY_PAUSE,
439 [ 25 ] = KEY_FORWARD,
440 [ 9 ] = KEY_ZOOM,
441
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
446};
447
448static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
452
453 [ 0x11 ] = KEY_KP0,
454 [ 0x4 ] = KEY_KP1,
455 [ 0x5 ] = KEY_KP2,
456 [ 0x6 ] = KEY_KP3,
457 [ 0x8 ] = KEY_KP4,
458 [ 0x9 ] = KEY_KP5,
459 [ 0xa ] = KEY_KP6,
460 [ 0xc ] = KEY_KP7,
461 [ 0xd ] = KEY_KP8,
462 [ 0xe ] = KEY_KP9,
463 [ 0x12 ] = KEY_KPDOT, /* 100+ */
464
465 [ 0x7 ] = KEY_VOLUMEUP,
466 [ 0xb ] = KEY_VOLUMEDOWN,
467 [ 0x1a ] = KEY_KPPLUS,
468 [ 0x18 ] = KEY_KPMINUS,
469 [ 0x15 ] = KEY_UP,
470 [ 0x1d ] = KEY_DOWN,
471 [ 0xf ] = KEY_CHANNELUP,
472 [ 0x13 ] = KEY_CHANNELDOWN,
473 [ 0x48 ] = KEY_ZOOM,
474
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
478
479 [ 0x4b ] = KEY_RECORD,
480 [ 0x46 ] = KEY_PLAY,
481 [ 0x45 ] = KEY_PAUSE, /* Pause */
482 [ 0x44 ] = KEY_STOP,
483 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
484 [ 0x42 ] = KEY_REWIND, /* Backward ? */
485
486};
487
488static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
489 [ 0x59 ] = KEY_MUTE,
490 [ 0x4a ] = KEY_POWER,
491
492 [ 0x18 ] = KEY_TEXT,
493 [ 0x26 ] = KEY_TV,
494 [ 0x3d ] = KEY_PRINT,
495
496 [ 0x48 ] = KEY_RED,
497 [ 0x04 ] = KEY_GREEN,
498 [ 0x11 ] = KEY_YELLOW,
499 [ 0x00 ] = KEY_BLUE,
500
501 [ 0x2d ] = KEY_VOLUMEUP,
502 [ 0x1e ] = KEY_VOLUMEDOWN,
503
504 [ 0x49 ] = KEY_MENU,
505
506 [ 0x16 ] = KEY_CHANNELUP,
507 [ 0x17 ] = KEY_CHANNELDOWN,
508
509 [ 0x20 ] = KEY_UP,
510 [ 0x21 ] = KEY_DOWN,
511 [ 0x22 ] = KEY_LEFT,
512 [ 0x23 ] = KEY_RIGHT,
513 [ 0x0d ] = KEY_SELECT,
514
515
516
517 [ 0x08 ] = KEY_BACK,
518 [ 0x07 ] = KEY_REFRESH,
519
520 [ 0x2f ] = KEY_ZOOM,
521 [ 0x29 ] = KEY_RECORD,
522
523 [ 0x4b ] = KEY_PAUSE,
524 [ 0x4d ] = KEY_REWIND,
525 [ 0x2e ] = KEY_PLAY,
526 [ 0x4e ] = KEY_FORWARD,
527 [ 0x53 ] = KEY_PREVIOUS,
528 [ 0x4c ] = KEY_STOP,
529 [ 0x54 ] = KEY_NEXT,
530
531 [ 0x69 ] = KEY_KP0,
532 [ 0x6a ] = KEY_KP1,
533 [ 0x6b ] = KEY_KP2,
534 [ 0x6c ] = KEY_KP3,
535 [ 0x6d ] = KEY_KP4,
536 [ 0x6e ] = KEY_KP5,
537 [ 0x6f ] = KEY_KP6,
538 [ 0x70 ] = KEY_KP7,
539 [ 0x71 ] = KEY_KP8,
540 [ 0x72 ] = KEY_KP9,
541
542 [ 0x74 ] = KEY_CHANNEL,
543 [ 0x0a ] = KEY_BACKSPACE,
544};
545
546/* Mapping for the 28 key remote control as seen at
547 http://www.sednacomputer.com/photo/cardbus-tv.jpg
548 Pavel Mihaylov <bin@bash.info> */
549static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
550 [ 0 ] = KEY_KP0,
551 [ 1 ] = KEY_KP1,
552 [ 2 ] = KEY_KP2,
553 [ 3 ] = KEY_KP3,
554 [ 4 ] = KEY_KP4,
555 [ 5 ] = KEY_KP5,
556 [ 6 ] = KEY_KP6,
557 [ 7 ] = KEY_KP7,
558 [ 8 ] = KEY_KP8,
559 [ 9 ] = KEY_KP9,
560
561 [ 0x0a ] = KEY_AGAIN, /* Recall */
562 [ 0x0b ] = KEY_CHANNELUP,
563 [ 0x0c ] = KEY_VOLUMEUP,
564 [ 0x0d ] = KEY_MODE, /* Stereo */
565 [ 0x0e ] = KEY_STOP,
566 [ 0x0f ] = KEY_PREVIOUSSONG,
567 [ 0x10 ] = KEY_ZOOM,
568 [ 0x11 ] = KEY_TUNER, /* Source */
569 [ 0x12 ] = KEY_POWER,
570 [ 0x13 ] = KEY_MUTE,
571 [ 0x15 ] = KEY_CHANNELDOWN,
572 [ 0x18 ] = KEY_VOLUMEDOWN,
573 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
574 [ 0x1a ] = KEY_NEXTSONG,
575 [ 0x1b ] = KEY_TEXT, /* Time Shift */
576 [ 0x1c ] = KEY_RADIO, /* FM Radio */
577 [ 0x1d ] = KEY_RECORD,
578 [ 0x1e ] = KEY_PAUSE,
579};
580
581
582/* -------------------- GPIO generic keycode builder -------------------- */
405 583
406static int build_key(struct saa7134_dev *dev) 584static int build_key(struct saa7134_dev *dev)
407{ 585{
@@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev)
413 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); 591 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414 592
415 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); 593 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
416 if (ir->polling) { 594 if (ir->polling) {
417 if (ir->last_gpio == gpio) 595 if (ir->last_gpio == gpio)
418 return 0; 596 return 0;
419 ir->last_gpio = gpio; 597 ir->last_gpio = gpio;
420 } 598 }
421 599
422 data = ir_extract_bits(gpio, ir->mask_keycode); 600 data = ir_extract_bits(gpio, ir->mask_keycode);
423 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 601 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
424 gpio, ir->mask_keycode, data); 602 gpio, ir->mask_keycode, data);
425 603
@@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev)
432 return 0; 610 return 0;
433} 611}
434 612
435/* ---------------------------------------------------------------------- */ 613/* --------------------- Chip specific I2C key builders ----------------- */
614
615static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
616{
617 unsigned char b;
618
619 /* poll IR chip */
620 if (1 != i2c_master_recv(&ir->c,&b,1)) {
621 i2cdprintk("read error\n");
622 return -EIO;
623 }
624
625 /* no button press */
626 if (b==0)
627 return 0;
628
629 /* repeating */
630 if (b & 0x80)
631 return 1;
632
633 *ir_key = b;
634 *ir_raw = b;
635 return 1;
636}
637
638/* The new pinnacle PCTV remote (with the colored buttons)
639 *
640 * Ricardo Cerqueira <v4l@cerqueira.org>
641 */
642
643static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
644{
645 unsigned char b[4];
646 unsigned int start = 0,parity = 0,code = 0;
647
648 /* poll IR chip */
649 if (4 != i2c_master_recv(&ir->c,b,4)) {
650 i2cdprintk("read error\n");
651 return -EIO;
652 }
653
654 for (start = 0; start<4; start++) {
655 if (b[start] == 0x80) {
656 code=b[(start+3)%4];
657 parity=b[(start+2)%4];
658 }
659 }
660
661 /* Empty Request */
662 if (parity==0)
663 return 0;
664
665 /* Repeating... */
666 if (ir->old == parity)
667 return 0;
668
669
670 ir->old = parity;
671
672 /* Reduce code value to fit inside IR_KEYTAB_SIZE
673 *
674 * this is the only value that results in 42 unique
675 * codes < 128
676 */
677
678 code %= 0x88;
679
680 *ir_raw = code;
681 *ir_key = code;
682
683 i2cdprintk("Pinnacle PCTV key %02x\n", code);
684
685 return 1;
686}
687
436 688
437void saa7134_input_irq(struct saa7134_dev *dev) 689void saa7134_input_irq(struct saa7134_dev *dev)
438{ 690{
439 struct saa7134_ir *ir = dev->remote; 691 struct saa7134_ir *ir = dev->remote;
440 692
441 if (!ir->polling) 693 if (!ir->polling)
442 build_key(dev); 694 build_key(dev);
443} 695}
444 696
@@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
464 int polling = 0; 716 int polling = 0;
465 int ir_type = IR_TYPE_OTHER; 717 int ir_type = IR_TYPE_OTHER;
466 718
467 if (!dev->has_remote) 719 if (dev->has_remote != SAA7134_REMOTE_GPIO)
468 return -ENODEV; 720 return -ENODEV;
469 if (disable_ir) 721 if (disable_ir)
470 return -ENODEV; 722 return -ENODEV;
@@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
473 switch (dev->board) { 725 switch (dev->board) {
474 case SAA7134_BOARD_FLYVIDEO2000: 726 case SAA7134_BOARD_FLYVIDEO2000:
475 case SAA7134_BOARD_FLYVIDEO3000: 727 case SAA7134_BOARD_FLYVIDEO3000:
476 case SAA7134_BOARD_FLYTVPLATINUM_FM: 728 case SAA7134_BOARD_FLYTVPLATINUM_FM:
729 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
477 ir_codes = flyvideo_codes; 730 ir_codes = flyvideo_codes;
478 mask_keycode = 0xEC00000; 731 mask_keycode = 0xEC00000;
479 mask_keydown = 0x0040000; 732 mask_keydown = 0x0040000;
@@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev)
514 saa_setb(SAA7134_GPIO_GPMODE0, 0x4); 767 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 768 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516 break; 769 break;
770 case SAA7134_BOARD_KWORLD_TERMINATOR:
771 ir_codes = avacssmart_codes;
772 mask_keycode = 0x00001f;
773 mask_keyup = 0x000060;
774 polling = 50; // ms
775 break;
517 case SAA7134_BOARD_MANLI_MTV001: 776 case SAA7134_BOARD_MANLI_MTV001:
518 case SAA7134_BOARD_MANLI_MTV002: 777 case SAA7134_BOARD_MANLI_MTV002:
778 case SAA7134_BOARD_BEHOLD_409FM:
519 ir_codes = manli_codes; 779 ir_codes = manli_codes;
520 mask_keycode = 0x001f00; 780 mask_keycode = 0x001f00;
521 mask_keyup = 0x004000; 781 mask_keyup = 0x004000;
522 mask_keydown = 0x002000;
523 polling = 50; // ms 782 polling = 50; // ms
524 break; 783 break;
784 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
785 ir_codes = pctv_sedna_codes;
786 mask_keycode = 0x001f00;
787 mask_keyup = 0x004000;
788 polling = 50; // ms
789 break;
790 case SAA7134_BOARD_GOTVIEW_7135:
791 ir_codes = gotview7135_codes;
792 mask_keycode = 0x0003EC;
793 mask_keyup = 0x008000;
794 mask_keydown = 0x000010;
795 polling = 50; // ms
796 break;
525 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 797 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
526 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 798 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
527 ir_codes = videomate_tv_pvr_codes; 799 ir_codes = videomate_tv_pvr_codes;
@@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
529 mask_keyup = 0x400000; 801 mask_keyup = 0x400000;
530 polling = 50; // ms 802 polling = 50; // ms
531 break; 803 break;
804 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
805 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
806 ir_codes = videomate_tv_pvr_codes;
807 mask_keycode = 0x003F00;
808 mask_keyup = 0x040000;
809 break;
532 } 810 }
533 if (NULL == ir_codes) { 811 if (NULL == ir_codes) {
534 printk("%s: Oops: IR config error [card=%d]\n", 812 printk("%s: Oops: IR config error [card=%d]\n",
@@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 ir->mask_keycode = mask_keycode; 826 ir->mask_keycode = mask_keycode;
549 ir->mask_keydown = mask_keydown; 827 ir->mask_keydown = mask_keydown;
550 ir->mask_keyup = mask_keyup; 828 ir->mask_keyup = mask_keyup;
551 ir->polling = polling; 829 ir->polling = polling;
552 830
553 /* init input device */ 831 /* init input device */
554 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", 832 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev)
596 dev->remote = NULL; 874 dev->remote = NULL;
597} 875}
598 876
877void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
878{
879 if (disable_ir) {
880 dprintk("Found supported i2c remote, but IR has been disabled\n");
881 ir->get_key=NULL;
882 return;
883 }
884
885 switch (dev->board) {
886 case SAA7134_BOARD_PINNACLE_PCTV_110i:
887 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
888 ir->get_key = get_key_pinnacle;
889 ir->ir_codes = ir_codes_pinnacle;
890 break;
891 case SAA7134_BOARD_UPMOST_PURPLE_TV:
892 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
893 ir->get_key = get_key_purpletv;
894 ir->ir_codes = ir_codes_purpletv;
895 break;
896 default:
897 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
898 break;
899 }
900
901}
599/* ---------------------------------------------------------------------- 902/* ----------------------------------------------------------------------
600 * Local variables: 903 * Local variables:
601 * c-basic-offset: 8 904 * c-basic-offset: 8
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..fd53dfcc1644 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44#define dprintk(fmt, arg...) if (oss_debug) \ 44#define dprintk(fmt, arg...) if (oss_debug) \
45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
46 46
47
47/* ------------------------------------------------------------------ */ 48/* ------------------------------------------------------------------ */
48 49
49static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
58 if ((blksize * blocks) > 1024*1024) 59 if ((blksize * blocks) > 1024*1024)
59 blocks = 1024*1024 / blksize; 60 blocks = 1024*1024 / blksize;
60 61
61 dev->oss.blocks = blocks; 62 dev->dmasound.blocks = blocks;
62 dev->oss.blksize = blksize; 63 dev->dmasound.blksize = blksize;
63 dev->oss.bufsize = blksize * blocks; 64 dev->dmasound.bufsize = blksize * blocks;
64 65
65 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", 66 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
66 blocks,blksize,blksize * blocks / 1024); 67 blocks,blksize,blksize * blocks / 1024);
67 return 0; 68 return 0;
68} 69}
69 70
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
71{ 72{
72 int err; 73 int err;
73 74
74 if (!dev->oss.bufsize) 75 if (!dev->dmasound.bufsize)
75 BUG(); 76 BUG();
76 videobuf_dma_init(&dev->oss.dma); 77 videobuf_dma_init(&dev->dmasound.dma);
77 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, 78 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
78 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); 79 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
79 if (0 != err) 80 if (0 != err)
80 return err; 81 return err;
81 return 0; 82 return 0;
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
83 84
84static int dsp_buffer_free(struct saa7134_dev *dev) 85static int dsp_buffer_free(struct saa7134_dev *dev)
85{ 86{
86 if (!dev->oss.blksize) 87 if (!dev->dmasound.blksize)
87 BUG(); 88 BUG();
88 videobuf_dma_free(&dev->oss.dma); 89 videobuf_dma_free(&dev->dmasound.dma);
89 dev->oss.blocks = 0; 90 dev->dmasound.blocks = 0;
90 dev->oss.blksize = 0; 91 dev->dmasound.blksize = 0;
91 dev->oss.bufsize = 0; 92 dev->dmasound.bufsize = 0;
92 return 0; 93 return 0;
93} 94}
94 95
95static void dsp_dma_start(struct saa7134_dev *dev) 96static void dsp_dma_start(struct saa7134_dev *dev)
96{ 97{
97 dev->oss.dma_blk = 0; 98 dev->dmasound.dma_blk = 0;
98 dev->oss.dma_running = 1; 99 dev->dmasound.dma_running = 1;
99 saa7134_set_dmabits(dev); 100 saa7134_set_dmabits(dev);
100} 101}
101 102
102static void dsp_dma_stop(struct saa7134_dev *dev) 103static void dsp_dma_stop(struct saa7134_dev *dev)
103{ 104{
104 dev->oss.dma_blk = -1; 105 dev->dmasound.dma_blk = -1;
105 dev->oss.dma_running = 0; 106 dev->dmasound.dma_running = 0;
106 saa7134_set_dmabits(dev); 107 saa7134_set_dmabits(dev);
107} 108}
108 109
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev)
113 unsigned long flags; 114 unsigned long flags;
114 115
115 /* prepare buffer */ 116 /* prepare buffer */
116 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) 117 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
117 return err; 118 return err;
118 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt))) 119 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
119 goto fail1; 120 goto fail1;
120 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt, 121 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
121 dev->oss.dma.sglist, 122 dev->dmasound.dma.sglist,
122 dev->oss.dma.sglen, 123 dev->dmasound.dma.sglen,
123 0))) 124 0)))
124 goto fail2; 125 goto fail2;
125 126
126 /* sample format */ 127 /* sample format */
127 switch (dev->oss.afmt) { 128 switch (dev->dmasound.afmt) {
128 case AFMT_U8: 129 case AFMT_U8:
129 case AFMT_S8: fmt = 0x00; break; 130 case AFMT_S8: fmt = 0x00; break;
130 case AFMT_U16_LE: 131 case AFMT_U16_LE:
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev)
136 goto fail2; 137 goto fail2;
137 } 138 }
138 139
139 switch (dev->oss.afmt) { 140 switch (dev->dmasound.afmt) {
140 case AFMT_S8: 141 case AFMT_S8:
141 case AFMT_S16_LE: 142 case AFMT_S16_LE:
142 case AFMT_S16_BE: sign = 1; break; 143 case AFMT_S16_BE: sign = 1; break;
143 default: sign = 0; break; 144 default: sign = 0; break;
144 } 145 }
145 146
146 switch (dev->oss.afmt) { 147 switch (dev->dmasound.afmt) {
147 case AFMT_U16_BE: 148 case AFMT_U16_BE:
148 case AFMT_S16_BE: bswap = 1; break; 149 case AFMT_S16_BE: bswap = 1; break;
149 default: bswap = 0; break; 150 default: bswap = 0; break;
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev)
151 152
152 switch (dev->pci->device) { 153 switch (dev->pci->device) {
153 case PCI_DEVICE_ID_PHILIPS_SAA7134: 154 case PCI_DEVICE_ID_PHILIPS_SAA7134:
154 if (1 == dev->oss.channels) 155 if (1 == dev->dmasound.channels)
155 fmt |= (1 << 3); 156 fmt |= (1 << 3);
156 if (2 == dev->oss.channels) 157 if (2 == dev->dmasound.channels)
157 fmt |= (3 << 3); 158 fmt |= (3 << 3);
158 if (sign) 159 if (sign)
159 fmt |= 0x04; 160 fmt |= 0x04;
160 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; 161 fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
161 162
162 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); 163 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
163 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); 164 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
164 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); 165 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
165 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); 166 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
166 167
167 break; 168 break;
168 case PCI_DEVICE_ID_PHILIPS_SAA7133: 169 case PCI_DEVICE_ID_PHILIPS_SAA7133:
169 case PCI_DEVICE_ID_PHILIPS_SAA7135: 170 case PCI_DEVICE_ID_PHILIPS_SAA7135:
170 if (1 == dev->oss.channels) 171 if (1 == dev->dmasound.channels)
171 fmt |= (1 << 4); 172 fmt |= (1 << 4);
172 if (2 == dev->oss.channels) 173 if (2 == dev->dmasound.channels)
173 fmt |= (2 << 4); 174 fmt |= (2 << 4);
174 if (!sign) 175 if (!sign)
175 fmt |= 0x04; 176 fmt |= 0x04;
176 saa_writel(0x588 >> 2, dev->oss.blksize -4); 177 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
177 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); 178 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
178 break; 179 break;
179 } 180 }
180 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", 181 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
181 dev->oss.afmt, dev->oss.channels, fmt, 182 dev->dmasound.afmt, dev->dmasound.channels, fmt,
182 bswap ? 'b' : '-'); 183 bswap ? 'b' : '-');
183 184
184 /* dma: setup channel 6 (= AUDIO) */ 185 /* dma: setup channel 6 (= AUDIO) */
185 control = SAA7134_RS_CONTROL_BURST_16 | 186 control = SAA7134_RS_CONTROL_BURST_16 |
186 SAA7134_RS_CONTROL_ME | 187 SAA7134_RS_CONTROL_ME |
187 (dev->oss.pt.dma >> 12); 188 (dev->dmasound.pt.dma >> 12);
188 if (bswap) 189 if (bswap)
189 control |= SAA7134_RS_CONTROL_BSWAP; 190 control |= SAA7134_RS_CONTROL_BSWAP;
190 saa_writel(SAA7134_RS_BA1(6),0); 191 saa_writel(SAA7134_RS_BA1(6),0);
191 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); 192 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
192 saa_writel(SAA7134_RS_PITCH(6),0); 193 saa_writel(SAA7134_RS_PITCH(6),0);
193 saa_writel(SAA7134_RS_CONTROL(6),control); 194 saa_writel(SAA7134_RS_CONTROL(6),control);
194 195
195 /* start dma */ 196 /* start dma */
196 dev->oss.recording_on = 1; 197 dev->dmasound.recording_on = 1;
197 spin_lock_irqsave(&dev->slock,flags); 198 spin_lock_irqsave(&dev->slock,flags);
198 dsp_dma_start(dev); 199 dsp_dma_start(dev);
199 spin_unlock_irqrestore(&dev->slock,flags); 200 spin_unlock_irqrestore(&dev->slock,flags);
200 return 0; 201 return 0;
201 202
202 fail2: 203 fail2:
203 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 204 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
204 fail1: 205 fail1:
205 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 206 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
206 return err; 207 return err;
207} 208}
208 209
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
210{ 211{
211 unsigned long flags; 212 unsigned long flags;
212 213
213 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk); 214 dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
214 215
215 /* stop dma */ 216 /* stop dma */
216 dev->oss.recording_on = 0; 217 dev->dmasound.recording_on = 0;
217 spin_lock_irqsave(&dev->slock,flags); 218 spin_lock_irqsave(&dev->slock,flags);
218 dsp_dma_stop(dev); 219 dsp_dma_stop(dev);
219 spin_unlock_irqrestore(&dev->slock,flags); 220 spin_unlock_irqrestore(&dev->slock,flags);
220 221
221 /* unlock buffer */ 222 /* unlock buffer */
222 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 223 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
223 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 224 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
224 return 0; 225 return 0;
225} 226}
226 227
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file)
235 236
236 list_for_each(list,&saa7134_devlist) { 237 list_for_each(list,&saa7134_devlist) {
237 h = list_entry(list, struct saa7134_dev, devlist); 238 h = list_entry(list, struct saa7134_dev, devlist);
238 if (h->oss.minor_dsp == minor) 239 if (h->dmasound.minor_dsp == minor)
239 dev = h; 240 dev = h;
240 } 241 }
241 if (NULL == dev) 242 if (NULL == dev)
242 return -ENODEV; 243 return -ENODEV;
243 244
244 down(&dev->oss.lock); 245 down(&dev->dmasound.lock);
245 err = -EBUSY; 246 err = -EBUSY;
246 if (dev->oss.users_dsp) 247 if (dev->dmasound.users_dsp)
247 goto fail1; 248 goto fail1;
248 dev->oss.users_dsp++; 249 dev->dmasound.users_dsp++;
249 file->private_data = dev; 250 file->private_data = dev;
250 251
251 dev->oss.afmt = AFMT_U8; 252 dev->dmasound.afmt = AFMT_U8;
252 dev->oss.channels = 1; 253 dev->dmasound.channels = 1;
253 dev->oss.read_count = 0; 254 dev->dmasound.read_count = 0;
254 dev->oss.read_offset = 0; 255 dev->dmasound.read_offset = 0;
255 dsp_buffer_conf(dev,PAGE_SIZE,64); 256 dsp_buffer_conf(dev,PAGE_SIZE,64);
256 err = dsp_buffer_init(dev); 257 err = dsp_buffer_init(dev);
257 if (0 != err) 258 if (0 != err)
258 goto fail2; 259 goto fail2;
259 260
260 up(&dev->oss.lock); 261 up(&dev->dmasound.lock);
261 return 0; 262 return 0;
262 263
263 fail2: 264 fail2:
264 dev->oss.users_dsp--; 265 dev->dmasound.users_dsp--;
265 fail1: 266 fail1:
266 up(&dev->oss.lock); 267 up(&dev->dmasound.lock);
267 return err; 268 return err;
268} 269}
269 270
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file)
271{ 272{
272 struct saa7134_dev *dev = file->private_data; 273 struct saa7134_dev *dev = file->private_data;
273 274
274 down(&dev->oss.lock); 275 down(&dev->dmasound.lock);
275 if (dev->oss.recording_on) 276 if (dev->dmasound.recording_on)
276 dsp_rec_stop(dev); 277 dsp_rec_stop(dev);
277 dsp_buffer_free(dev); 278 dsp_buffer_free(dev);
278 dev->oss.users_dsp--; 279 dev->dmasound.users_dsp--;
279 file->private_data = NULL; 280 file->private_data = NULL;
280 up(&dev->oss.lock); 281 up(&dev->dmasound.lock);
281 return 0; 282 return 0;
282} 283}
283 284
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
290 unsigned long flags; 291 unsigned long flags;
291 int err,ret = 0; 292 int err,ret = 0;
292 293
293 add_wait_queue(&dev->oss.wq, &wait); 294 add_wait_queue(&dev->dmasound.wq, &wait);
294 down(&dev->oss.lock); 295 down(&dev->dmasound.lock);
295 while (count > 0) { 296 while (count > 0) {
296 /* wait for data if needed */ 297 /* wait for data if needed */
297 if (0 == dev->oss.read_count) { 298 if (0 == dev->dmasound.read_count) {
298 if (!dev->oss.recording_on) { 299 if (!dev->dmasound.recording_on) {
299 err = dsp_rec_start(dev); 300 err = dsp_rec_start(dev);
300 if (err < 0) { 301 if (err < 0) {
301 if (0 == ret) 302 if (0 == ret)
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
303 break; 304 break;
304 } 305 }
305 } 306 }
306 if (dev->oss.recording_on && 307 if (dev->dmasound.recording_on &&
307 !dev->oss.dma_running) { 308 !dev->dmasound.dma_running) {
308 /* recover from overruns */ 309 /* recover from overruns */
309 spin_lock_irqsave(&dev->slock,flags); 310 spin_lock_irqsave(&dev->slock,flags);
310 dsp_dma_start(dev); 311 dsp_dma_start(dev);
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
315 ret = -EAGAIN; 316 ret = -EAGAIN;
316 break; 317 break;
317 } 318 }
318 up(&dev->oss.lock); 319 up(&dev->dmasound.lock);
319 set_current_state(TASK_INTERRUPTIBLE); 320 set_current_state(TASK_INTERRUPTIBLE);
320 if (0 == dev->oss.read_count) 321 if (0 == dev->dmasound.read_count)
321 schedule(); 322 schedule();
322 set_current_state(TASK_RUNNING); 323 set_current_state(TASK_RUNNING);
323 down(&dev->oss.lock); 324 down(&dev->dmasound.lock);
324 if (signal_pending(current)) { 325 if (signal_pending(current)) {
325 if (0 == ret) 326 if (0 == ret)
326 ret = -EINTR; 327 ret = -EINTR;
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
330 331
331 /* copy data to userspace */ 332 /* copy data to userspace */
332 bytes = count; 333 bytes = count;
333 if (bytes > dev->oss.read_count) 334 if (bytes > dev->dmasound.read_count)
334 bytes = dev->oss.read_count; 335 bytes = dev->dmasound.read_count;
335 if (bytes > dev->oss.bufsize - dev->oss.read_offset) 336 if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
336 bytes = dev->oss.bufsize - dev->oss.read_offset; 337 bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
337 if (copy_to_user(buffer + ret, 338 if (copy_to_user(buffer + ret,
338 dev->oss.dma.vmalloc + dev->oss.read_offset, 339 dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
339 bytes)) { 340 bytes)) {
340 if (0 == ret) 341 if (0 == ret)
341 ret = -EFAULT; 342 ret = -EFAULT;
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
344 345
345 ret += bytes; 346 ret += bytes;
346 count -= bytes; 347 count -= bytes;
347 dev->oss.read_count -= bytes; 348 dev->dmasound.read_count -= bytes;
348 dev->oss.read_offset += bytes; 349 dev->dmasound.read_offset += bytes;
349 if (dev->oss.read_offset == dev->oss.bufsize) 350 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
350 dev->oss.read_offset = 0; 351 dev->dmasound.read_offset = 0;
351 } 352 }
352 up(&dev->oss.lock); 353 up(&dev->dmasound.lock);
353 remove_wait_queue(&dev->oss.wq, &wait); 354 remove_wait_queue(&dev->dmasound.wq, &wait);
354 return ret; 355 return ret;
355} 356}
356 357
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
370 371
371 if (oss_debug > 1) 372 if (oss_debug > 1)
372 saa7134_print_ioctl(dev->name,cmd); 373 saa7134_print_ioctl(dev->name,cmd);
373 switch (cmd) { 374 switch (cmd) {
374 case OSS_GETVERSION: 375 case OSS_GETVERSION:
375 return put_user(SOUND_VERSION, p); 376 return put_user(SOUND_VERSION, p);
376 case SNDCTL_DSP_GETCAPS: 377 case SNDCTL_DSP_GETCAPS:
377 return 0; 378 return 0;
378 379
379 case SNDCTL_DSP_SPEED: 380 case SNDCTL_DSP_SPEED:
380 if (get_user(val, p)) 381 if (get_user(val, p))
381 return -EFAULT; 382 return -EFAULT;
382 /* fall through */ 383 /* fall through */
383 case SOUND_PCM_READ_RATE: 384 case SOUND_PCM_READ_RATE:
384 return put_user(dev->oss.rate, p); 385 return put_user(dev->dmasound.rate, p);
385 386
386 case SNDCTL_DSP_STEREO: 387 case SNDCTL_DSP_STEREO:
387 if (get_user(val, p)) 388 if (get_user(val, p))
388 return -EFAULT; 389 return -EFAULT;
389 down(&dev->oss.lock); 390 down(&dev->dmasound.lock);
390 dev->oss.channels = val ? 2 : 1; 391 dev->dmasound.channels = val ? 2 : 1;
391 if (dev->oss.recording_on) { 392 if (dev->dmasound.recording_on) {
392 dsp_rec_stop(dev); 393 dsp_rec_stop(dev);
393 dsp_rec_start(dev); 394 dsp_rec_start(dev);
394 } 395 }
395 up(&dev->oss.lock); 396 up(&dev->dmasound.lock);
396 return put_user(dev->oss.channels-1, p); 397 return put_user(dev->dmasound.channels-1, p);
397 398
398 case SNDCTL_DSP_CHANNELS: 399 case SNDCTL_DSP_CHANNELS:
399 if (get_user(val, p)) 400 if (get_user(val, p))
400 return -EFAULT; 401 return -EFAULT;
401 if (val != 1 && val != 2) 402 if (val != 1 && val != 2)
402 return -EINVAL; 403 return -EINVAL;
403 down(&dev->oss.lock); 404 down(&dev->dmasound.lock);
404 dev->oss.channels = val; 405 dev->dmasound.channels = val;
405 if (dev->oss.recording_on) { 406 if (dev->dmasound.recording_on) {
406 dsp_rec_stop(dev); 407 dsp_rec_stop(dev);
407 dsp_rec_start(dev); 408 dsp_rec_start(dev);
408 } 409 }
409 up(&dev->oss.lock); 410 up(&dev->dmasound.lock);
410 /* fall through */ 411 /* fall through */
411 case SOUND_PCM_READ_CHANNELS: 412 case SOUND_PCM_READ_CHANNELS:
412 return put_user(dev->oss.channels, p); 413 return put_user(dev->dmasound.channels, p);
413 414
414 case SNDCTL_DSP_GETFMTS: /* Returns a mask */ 415 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
415 return put_user(AFMT_U8 | AFMT_S8 | 416 return put_user(AFMT_U8 | AFMT_S8 |
416 AFMT_U16_LE | AFMT_U16_BE | 417 AFMT_U16_LE | AFMT_U16_BE |
417 AFMT_S16_LE | AFMT_S16_BE, p); 418 AFMT_S16_LE | AFMT_S16_BE, p);
418 419
419 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ 420 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
420 if (get_user(val, p)) 421 if (get_user(val, p))
421 return -EFAULT; 422 return -EFAULT;
422 switch (val) { 423 switch (val) {
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
429 case AFMT_U16_BE: 430 case AFMT_U16_BE:
430 case AFMT_S16_LE: 431 case AFMT_S16_LE:
431 case AFMT_S16_BE: 432 case AFMT_S16_BE:
432 down(&dev->oss.lock); 433 down(&dev->dmasound.lock);
433 dev->oss.afmt = val; 434 dev->dmasound.afmt = val;
434 if (dev->oss.recording_on) { 435 if (dev->dmasound.recording_on) {
435 dsp_rec_stop(dev); 436 dsp_rec_stop(dev);
436 dsp_rec_start(dev); 437 dsp_rec_start(dev);
437 } 438 }
438 up(&dev->oss.lock); 439 up(&dev->dmasound.lock);
439 return put_user(dev->oss.afmt, p); 440 return put_user(dev->dmasound.afmt, p);
440 default: 441 default:
441 return -EINVAL; 442 return -EINVAL;
442 } 443 }
443 444
444 case SOUND_PCM_READ_BITS: 445 case SOUND_PCM_READ_BITS:
445 switch (dev->oss.afmt) { 446 switch (dev->dmasound.afmt) {
446 case AFMT_U8: 447 case AFMT_U8:
447 case AFMT_S8: 448 case AFMT_S8:
448 return put_user(8, p); 449 return put_user(8, p);
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
457 458
458 case SNDCTL_DSP_NONBLOCK: 459 case SNDCTL_DSP_NONBLOCK:
459 file->f_flags |= O_NONBLOCK; 460 file->f_flags |= O_NONBLOCK;
460 return 0; 461 return 0;
461 462
462 case SNDCTL_DSP_RESET: 463 case SNDCTL_DSP_RESET:
463 down(&dev->oss.lock); 464 down(&dev->dmasound.lock);
464 if (dev->oss.recording_on) 465 if (dev->dmasound.recording_on)
465 dsp_rec_stop(dev); 466 dsp_rec_stop(dev);
466 up(&dev->oss.lock); 467 up(&dev->dmasound.lock);
467 return 0; 468 return 0;
468 case SNDCTL_DSP_GETBLKSIZE: 469 case SNDCTL_DSP_GETBLKSIZE:
469 return put_user(dev->oss.blksize, p); 470 return put_user(dev->dmasound.blksize, p);
470 471
471 case SNDCTL_DSP_SETFRAGMENT: 472 case SNDCTL_DSP_SETFRAGMENT:
472 if (get_user(val, p)) 473 if (get_user(val, p))
473 return -EFAULT; 474 return -EFAULT;
474 if (dev->oss.recording_on) 475 if (dev->dmasound.recording_on)
475 return -EBUSY; 476 return -EBUSY;
476 dsp_buffer_free(dev); 477 dsp_buffer_free(dev);
477 /* used to be arg >> 16 instead of val >> 16; fixed */ 478 /* used to be arg >> 16 instead of val >> 16; fixed */
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
479 dsp_buffer_init(dev); 480 dsp_buffer_init(dev);
480 return 0; 481 return 0;
481 482
482 case SNDCTL_DSP_SYNC: 483 case SNDCTL_DSP_SYNC:
483 /* NOP */ 484 /* NOP */
484 return 0; 485 return 0;
485 486
486 case SNDCTL_DSP_GETISPACE: 487 case SNDCTL_DSP_GETISPACE:
487 { 488 {
488 audio_buf_info info; 489 audio_buf_info info;
489 info.fragsize = dev->oss.blksize; 490 info.fragsize = dev->dmasound.blksize;
490 info.fragstotal = dev->oss.blocks; 491 info.fragstotal = dev->dmasound.blocks;
491 info.bytes = dev->oss.read_count; 492 info.bytes = dev->dmasound.read_count;
492 info.fragments = info.bytes / info.fragsize; 493 info.fragments = info.bytes / info.fragsize;
493 if (copy_to_user(argp, &info, sizeof(info))) 494 if (copy_to_user(argp, &info, sizeof(info)))
494 return -EFAULT; 495 return -EFAULT;
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
504 struct saa7134_dev *dev = file->private_data; 505 struct saa7134_dev *dev = file->private_data;
505 unsigned int mask = 0; 506 unsigned int mask = 0;
506 507
507 poll_wait(file, &dev->oss.wq, wait); 508 poll_wait(file, &dev->dmasound.wq, wait);
508 509
509 if (0 == dev->oss.read_count) { 510 if (0 == dev->dmasound.read_count) {
510 down(&dev->oss.lock); 511 down(&dev->dmasound.lock);
511 if (!dev->oss.recording_on) 512 if (!dev->dmasound.recording_on)
512 dsp_rec_start(dev); 513 dsp_rec_start(dev);
513 up(&dev->oss.lock); 514 up(&dev->dmasound.lock);
514 } else 515 } else
515 mask |= (POLLIN | POLLRDNORM); 516 mask |= (POLLIN | POLLRDNORM);
516 return mask; 517 return mask;
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
534{ 535{
535 int analog_io,rate; 536 int analog_io,rate;
536 537
537 switch (dev->oss.input) { 538 switch (dev->dmasound.input) {
538 case TV: 539 case TV:
539 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); 540 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
540 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); 541 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
542 case LINE1: 543 case LINE1:
543 case LINE2: 544 case LINE2:
544 case LINE2_LEFT: 545 case LINE2_LEFT:
545 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; 546 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
546 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; 547 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
547 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); 548 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
548 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); 549 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
549 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); 550 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
559 560
560 xbarin = 0x03; // adc 561 xbarin = 0x03; // adc
561 anabar = 0; 562 anabar = 0;
562 switch (dev->oss.input) { 563 switch (dev->dmasound.input) {
563 case TV: 564 case TV:
564 xbarin = 0; // Demodulator 565 xbarin = 0; // Demodulator
565 anabar = 2; // DACs 566 anabar = 2; // DACs
566 break; 567 break;
567 case LINE1: 568 case LINE1:
568 anabar = 0; // aux1, aux1 569 anabar = 0; // aux1, aux1
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
585{ 586{
586 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; 587 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
587 588
588 dev->oss.count++; 589 dev->dmasound.count++;
589 dev->oss.input = src; 590 dev->dmasound.input = src;
590 dprintk("mixer input = %s\n",iname[dev->oss.input]); 591 dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
591 592
592 switch (dev->pci->device) { 593 switch (dev->pci->device) {
593 case PCI_DEVICE_ID_PHILIPS_SAA7134: 594 case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file)
639 640
640 list_for_each(list,&saa7134_devlist) { 641 list_for_each(list,&saa7134_devlist) {
641 h = list_entry(list, struct saa7134_dev, devlist); 642 h = list_entry(list, struct saa7134_dev, devlist);
642 if (h->oss.minor_mixer == minor) 643 if (h->dmasound.minor_mixer == minor)
643 dev = h; 644 dev = h;
644 } 645 }
645 if (NULL == dev) 646 if (NULL == dev)
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
666 667
667 if (oss_debug > 1) 668 if (oss_debug > 1)
668 saa7134_print_ioctl(dev->name,cmd); 669 saa7134_print_ioctl(dev->name,cmd);
669 switch (cmd) { 670 switch (cmd) {
670 case OSS_GETVERSION: 671 case OSS_GETVERSION:
671 return put_user(SOUND_VERSION, p); 672 return put_user(SOUND_VERSION, p);
672 case SOUND_MIXER_INFO: 673 case SOUND_MIXER_INFO:
673 { 674 {
674 mixer_info info; 675 mixer_info info;
675 memset(&info,0,sizeof(info)); 676 memset(&info,0,sizeof(info));
676 strlcpy(info.id, "TV audio", sizeof(info.id)); 677 strlcpy(info.id, "TV audio", sizeof(info.id));
677 strlcpy(info.name, dev->name, sizeof(info.name)); 678 strlcpy(info.name, dev->name, sizeof(info.name));
678 info.modify_counter = dev->oss.count; 679 info.modify_counter = dev->dmasound.count;
679 if (copy_to_user(argp, &info, sizeof(info))) 680 if (copy_to_user(argp, &info, sizeof(info)))
680 return -EFAULT; 681 return -EFAULT;
681 return 0; 682 return 0;
682 } 683 }
683 case SOUND_OLD_MIXER_INFO: 684 case SOUND_OLD_MIXER_INFO:
684 { 685 {
685 _old_mixer_info info; 686 _old_mixer_info info;
686 memset(&info,0,sizeof(info)); 687 memset(&info,0,sizeof(info));
687 strlcpy(info.id, "TV audio", sizeof(info.id)); 688 strlcpy(info.id, "TV audio", sizeof(info.id));
688 strlcpy(info.name, dev->name, sizeof(info.name)); 689 strlcpy(info.name, dev->name, sizeof(info.name));
689 if (copy_to_user(argp, &info, sizeof(info))) 690 if (copy_to_user(argp, &info, sizeof(info)))
690 return -EFAULT; 691 return -EFAULT;
691 return 0; 692 return 0;
692 } 693 }
693 case MIXER_READ(SOUND_MIXER_CAPS): 694 case MIXER_READ(SOUND_MIXER_CAPS):
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
697 case MIXER_READ(SOUND_MIXER_RECMASK): 698 case MIXER_READ(SOUND_MIXER_RECMASK):
698 case MIXER_READ(SOUND_MIXER_DEVMASK): 699 case MIXER_READ(SOUND_MIXER_DEVMASK):
699 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; 700 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
700 if (32000 == dev->oss.rate) 701 if (32000 == dev->dmasound.rate)
701 val |= SOUND_MASK_VIDEO; 702 val |= SOUND_MASK_VIDEO;
702 return put_user(val, p); 703 return put_user(val, p);
703 704
704 case MIXER_WRITE(SOUND_MIXER_RECSRC): 705 case MIXER_WRITE(SOUND_MIXER_RECSRC):
705 if (get_user(val, p)) 706 if (get_user(val, p))
706 return -EFAULT; 707 return -EFAULT;
707 input = dev->oss.input; 708 input = dev->dmasound.input;
708 if (32000 == dev->oss.rate && 709 if (32000 == dev->dmasound.rate &&
709 val & SOUND_MASK_VIDEO && dev->oss.input != TV) 710 val & SOUND_MASK_VIDEO && dev->dmasound.input != TV)
710 input = TV; 711 input = TV;
711 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1) 712 if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1)
712 input = LINE1; 713 input = LINE1;
713 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2) 714 if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2)
714 input = LINE2; 715 input = LINE2;
715 if (input != dev->oss.input) 716 if (input != dev->dmasound.input)
716 mixer_recsrc(dev,input); 717 mixer_recsrc(dev,input);
717 /* fall throuth */ 718 /* fall throuth */
718 case MIXER_READ(SOUND_MIXER_RECSRC): 719 case MIXER_READ(SOUND_MIXER_RECSRC):
719 switch (dev->oss.input) { 720 switch (dev->dmasound.input) {
720 case TV: ret = SOUND_MASK_VIDEO; break; 721 case TV: ret = SOUND_MASK_VIDEO; break;
721 case LINE1: ret = SOUND_MASK_LINE1; break; 722 case LINE1: ret = SOUND_MASK_LINE1; break;
722 case LINE2: ret = SOUND_MASK_LINE2; break; 723 case LINE2: ret = SOUND_MASK_LINE2; break;
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
726 727
727 case MIXER_WRITE(SOUND_MIXER_VIDEO): 728 case MIXER_WRITE(SOUND_MIXER_VIDEO):
728 case MIXER_READ(SOUND_MIXER_VIDEO): 729 case MIXER_READ(SOUND_MIXER_VIDEO):
729 if (32000 != dev->oss.rate) 730 if (32000 != dev->dmasound.rate)
730 return -EINVAL; 731 return -EINVAL;
731 return put_user(100 | 100 << 8, p); 732 return put_user(100 | 100 << 8, p);
732 733
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
735 return -EFAULT; 736 return -EFAULT;
736 val &= 0xff; 737 val &= 0xff;
737 val = (val <= 50) ? 50 : 100; 738 val = (val <= 50) ? 50 : 100;
738 dev->oss.line1 = val; 739 dev->dmasound.line1 = val;
739 mixer_level(dev,LINE1,dev->oss.line1); 740 mixer_level(dev,LINE1,dev->dmasound.line1);
740 /* fall throuth */ 741 /* fall throuth */
741 case MIXER_READ(SOUND_MIXER_LINE1): 742 case MIXER_READ(SOUND_MIXER_LINE1):
742 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p); 743 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
743 744
744 case MIXER_WRITE(SOUND_MIXER_LINE2): 745 case MIXER_WRITE(SOUND_MIXER_LINE2):
745 if (get_user(val, p)) 746 if (get_user(val, p))
746 return -EFAULT; 747 return -EFAULT;
747 val &= 0xff; 748 val &= 0xff;
748 val = (val <= 50) ? 50 : 100; 749 val = (val <= 50) ? 50 : 100;
749 dev->oss.line2 = val; 750 dev->dmasound.line2 = val;
750 mixer_level(dev,LINE2,dev->oss.line2); 751 mixer_level(dev,LINE2,dev->dmasound.line2);
751 /* fall throuth */ 752 /* fall throuth */
752 case MIXER_READ(SOUND_MIXER_LINE2): 753 case MIXER_READ(SOUND_MIXER_LINE2):
753 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p); 754 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
754 755
755 default: 756 default:
756 return -EINVAL; 757 return -EINVAL;
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = {
770int saa7134_oss_init1(struct saa7134_dev *dev) 771int saa7134_oss_init1(struct saa7134_dev *dev)
771{ 772{
772 /* general */ 773 /* general */
773 init_MUTEX(&dev->oss.lock); 774 init_MUTEX(&dev->dmasound.lock);
774 init_waitqueue_head(&dev->oss.wq); 775 init_waitqueue_head(&dev->dmasound.wq);
775 776
776 switch (dev->pci->device) { 777 switch (dev->pci->device) {
777 case PCI_DEVICE_ID_PHILIPS_SAA7133: 778 case PCI_DEVICE_ID_PHILIPS_SAA7133:
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
783 } 784 }
784 785
785 /* dsp */ 786 /* dsp */
786 dev->oss.rate = 32000; 787 dev->dmasound.rate = 32000;
787 if (oss_rate) 788 if (oss_rate)
788 dev->oss.rate = oss_rate; 789 dev->dmasound.rate = oss_rate;
789 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; 790 dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
790 791
791 /* mixer */ 792 /* mixer */
792 dev->oss.line1 = 50; 793 dev->dmasound.line1 = 50;
793 dev->oss.line2 = 50; 794 dev->dmasound.line2 = 50;
794 mixer_level(dev,LINE1,dev->oss.line1); 795 mixer_level(dev,LINE1,dev->dmasound.line1);
795 mixer_level(dev,LINE2,dev->oss.line2); 796 mixer_level(dev,LINE2,dev->dmasound.line2);
796 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); 797 mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
797 798
798 return 0; 799 return 0;
799} 800}
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
809 int next_blk, reg = 0; 810 int next_blk, reg = 0;
810 811
811 spin_lock(&dev->slock); 812 spin_lock(&dev->slock);
812 if (UNSET == dev->oss.dma_blk) { 813 if (UNSET == dev->dmasound.dma_blk) {
813 dprintk("irq: recording stopped\n"); 814 dprintk("irq: recording stopped\n");
814 goto done; 815 goto done;
815 } 816 }
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
817 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); 818 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
818 if (0 == (status & 0x10000000)) { 819 if (0 == (status & 0x10000000)) {
819 /* odd */ 820 /* odd */
820 if (0 == (dev->oss.dma_blk & 0x01)) 821 if (0 == (dev->dmasound.dma_blk & 0x01))
821 reg = SAA7134_RS_BA1(6); 822 reg = SAA7134_RS_BA1(6);
822 } else { 823 } else {
823 /* even */ 824 /* even */
824 if (1 == (dev->oss.dma_blk & 0x01)) 825 if (1 == (dev->dmasound.dma_blk & 0x01))
825 reg = SAA7134_RS_BA2(6); 826 reg = SAA7134_RS_BA2(6);
826 } 827 }
827 if (0 == reg) { 828 if (0 == reg) {
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
829 (status & 0x10000000) ? "even" : "odd"); 830 (status & 0x10000000) ? "even" : "odd");
830 goto done; 831 goto done;
831 } 832 }
832 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) { 833 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
833 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count, 834 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
834 dev->oss.bufsize); 835 dev->dmasound.bufsize);
835 dsp_dma_stop(dev); 836 dsp_dma_stop(dev);
836 goto done; 837 goto done;
837 } 838 }
838 839
839 /* next block addr */ 840 /* next block addr */
840 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; 841 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
841 saa_writel(reg,next_blk * dev->oss.blksize); 842 saa_writel(reg,next_blk * dev->dmasound.blksize);
842 if (oss_debug > 2) 843 if (oss_debug > 2)
843 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", 844 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
844 (status & 0x10000000) ? "even" : "odd ", next_blk, 845 (status & 0x10000000) ? "even" : "odd ", next_blk,
845 next_blk * dev->oss.blksize); 846 next_blk * dev->dmasound.blksize);
846 847
847 /* update status & wake waiting readers */ 848 /* update status & wake waiting readers */
848 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; 849 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
849 dev->oss.read_count += dev->oss.blksize; 850 dev->dmasound.read_count += dev->dmasound.blksize;
850 wake_up(&dev->oss.wq); 851 wake_up(&dev->dmasound.wq);
851 852
852 done: 853 done:
853 spin_unlock(&dev->slock); 854 spin_unlock(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index ae0c7a165390..ac6431ba4fc3 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -27,7 +27,7 @@
27 27
28/* DMA channels, n = 0 ... 6 */ 28/* DMA channels, n = 0 ... 6 */
29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) 29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) 30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) 31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) 32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) 33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
@@ -43,16 +43,24 @@
43#define SAA7134_FIFO_SIZE (0x2a0 >> 2) 43#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
44#define SAA7134_THRESHOULD (0x2a4 >> 2) 44#define SAA7134_THRESHOULD (0x2a4 >> 2)
45 45
46#define SAA7133_NUM_SAMPLES (0x588 >> 2)
47#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
48#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
49#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
50#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
51#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
52#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
53
46/* main control */ 54/* main control */
47#define SAA7134_MAIN_CTRL (0x2a8 >> 2) 55#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
48#define SAA7134_MAIN_CTRL_VPLLE (1 << 15) 56#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
49#define SAA7134_MAIN_CTRL_APLLE (1 << 14) 57#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
50#define SAA7134_MAIN_CTRL_EXOSC (1 << 13) 58#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
51#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) 59#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
52#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) 60#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
53#define SAA7134_MAIN_CTRL_ESFE (1 << 10) 61#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
54#define SAA7134_MAIN_CTRL_EBADC (1 << 9) 62#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
55#define SAA7134_MAIN_CTRL_EBDAC (1 << 8) 63#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
56#define SAA7134_MAIN_CTRL_TE6 (1 << 6) 64#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
57#define SAA7134_MAIN_CTRL_TE5 (1 << 5) 65#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
58#define SAA7134_MAIN_CTRL_TE4 (1 << 4) 66#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
@@ -348,6 +356,7 @@
348 356
349/* test modes */ 357/* test modes */
350#define SAA7134_SPECIAL_MODE 0x1d0 358#define SAA7134_SPECIAL_MODE 0x1d0
359#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
351 360
352/* audio -- saa7133 + saa7135 only */ 361/* audio -- saa7133 + saa7135 only */
353#define SAA7135_DSP_RWSTATE 0x580 362#define SAA7135_DSP_RWSTATE 0x580
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 463885601ab4..470903e2f5e5 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev,
46 struct saa7134_buf *buf, 46 struct saa7134_buf *buf,
47 struct saa7134_buf *next) 47 struct saa7134_buf *next)
48{ 48{
49 u32 control;
50 49
51 dprintk("buffer_activate [%p]",buf); 50 dprintk("buffer_activate [%p]",buf);
52 buf->vb.state = STATE_ACTIVE; 51 buf->vb.state = STATE_ACTIVE;
53 buf->top_seen = 0; 52 buf->top_seen = 0;
54 53
55 /* dma: setup channel 5 (= TS) */
56 control = SAA7134_RS_CONTROL_BURST_16 |
57 SAA7134_RS_CONTROL_ME |
58 (buf->pt->dma >> 12);
59
60 if (NULL == next) 54 if (NULL == next)
61 next = buf; 55 next = buf;
62 if (V4L2_FIELD_TOP == buf->vb.field) { 56 if (V4L2_FIELD_TOP == buf->vb.field) {
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev,
68 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); 62 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
69 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); 63 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
70 } 64 }
71 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
72 saa_writel(SAA7134_RS_CONTROL(5),control);
73 65
74 /* start DMA */ 66 /* start DMA */
75 saa7134_set_dmabits(dev); 67 saa7134_set_dmabits(dev);
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
84 struct saa7134_dev *dev = q->priv_data; 76 struct saa7134_dev *dev = q->priv_data;
85 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 77 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
86 unsigned int lines, llength, size; 78 unsigned int lines, llength, size;
79 u32 control;
87 int err; 80 int err;
88 81
89 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); 82 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
115 if (err) 108 if (err)
116 goto oops; 109 goto oops;
117 } 110 }
111
112 /* dma: setup channel 5 (= TS) */
113 control = SAA7134_RS_CONTROL_BURST_16 |
114 SAA7134_RS_CONTROL_ME |
115 (buf->pt->dma >> 12);
116
117 saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff));
118 saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff));
119 saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
120 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
121 saa_writel(SAA7134_RS_CONTROL(5),control);
122
118 buf->vb.state = STATE_PREPARED; 123 buf->vb.state = STATE_PREPARED;
119 buf->activate = buffer_activate; 124 buf->activate = buffer_activate;
120 buf->vb.field = field; 125 buf->vb.field = field;
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164/* ----------------------------------------------------------- */ 169/* ----------------------------------------------------------- */
165/* exported stuff */ 170/* exported stuff */
166 171
167static unsigned int tsbufs = 4; 172static unsigned int tsbufs = 8;
168module_param(tsbufs, int, 0444); 173module_param(tsbufs, int, 0444);
169MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); 174MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
170 175
171static unsigned int ts_nr_packets = 30; 176static unsigned int ts_nr_packets = 64;
172module_param(ts_nr_packets, int, 0444); 177module_param(ts_nr_packets, int, 0444);
173MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); 178MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
174 179
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
220 if (dev->ts_q.curr) { 225 if (dev->ts_q.curr) {
221 field = dev->ts_q.curr->vb.field; 226 field = dev->ts_q.curr->vb.field;
222 if (field == V4L2_FIELD_TOP) { 227 if (field == V4L2_FIELD_TOP) {
223 if ((status & 0x100000) != 0x100000) 228 if ((status & 0x100000) != 0x000000)
224 goto done; 229 goto done;
225 } else { 230 } else {
226 if ((status & 0x100000) != 0x000000) 231 if ((status & 0x100000) != 0x100000)
227 goto done; 232 goto done;
228 } 233 }
229 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); 234 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 61a2d6b50eef..93268427750d 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev,
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); 207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208} 208}
209 209
210#define SAA7134_MUTE_MASK 0xbb
211#define SAA7134_MUTE_ANALOG 0x04
212#define SAA7134_MUTE_I2S 0x40
213
210static void mute_input_7134(struct saa7134_dev *dev) 214static void mute_input_7134(struct saa7134_dev *dev)
211{ 215{
212 unsigned int mute; 216 unsigned int mute;
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
241 245
242 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) 246 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
243 /* 7134 mute */ 247 /* 7134 mute */
244 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); 248 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
249 SAA7134_MUTE_MASK |
250 SAA7134_MUTE_ANALOG |
251 SAA7134_MUTE_I2S :
252 SAA7134_MUTE_MASK);
245 253
246 /* switch internal audio mux */ 254 /* switch internal audio mux */
247 switch (in->amux) { 255 switch (in->amux) {
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev)
753 761
754 762
755 /* switch gpio-connected external audio mux */ 763 /* switch gpio-connected external audio mux */
756 if (0 != card(dev).gpiomask) { 764 if (0 != card(dev).gpiomask) {
757 mask = card(dev).gpiomask; 765 mask = card(dev).gpiomask;
758 766
759 if (card(dev).mute.name && dev->ctl_mute) 767 if (card(dev).mute.name && dev->ctl_mute)
760 in = &card(dev).mute; 768 in = &card(dev).mute;
761 else 769 else
762 in = dev->input; 770 in = dev->input;
763 771
764 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); 772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
765 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); 773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
766 saa7134_track_gpio(dev,in->name); 774 saa7134_track_gpio(dev,in->name);
767 } 775 }
768 776
769 return 0; 777 return 0;
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1016 return 0; 1024 return 0;
1017} 1025}
1018 1026
1027EXPORT_SYMBOL(saa_dsp_writel);
1028
1019/* ----------------------------------------------------------- */ 1029/* ----------------------------------------------------------- */
1020/* 1030/*
1021 * Local variables: 1031 * Local variables:
1022 * c-basic-offset: 8 1032 * c-basic-offset: 8
1023 * End: 1033 * End:
1024 */ 1034 */
1035
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 35e5e85f669a..45c852df13ed 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,9 @@
30#include "saa7134-reg.h" 30#include "saa7134-reg.h"
31#include "saa7134.h" 31#include "saa7134.h"
32 32
33/* Include V4L1 specific functions. Should be removed soon */
34#include <linux/videodev.h>
35
33/* ------------------------------------------------------------------ */ 36/* ------------------------------------------------------------------ */
34 37
35static unsigned int video_debug = 0; 38static unsigned int video_debug = 0;
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
48 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) 51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
49 52
50/* ------------------------------------------------------------------ */ 53/* ------------------------------------------------------------------ */
54/* Defines for Video Output Port Register at address 0x191 */
55
56/* Bit 0: VIP code T bit polarity */
57
58#define VP_T_CODE_P_NON_INVERTED 0x00
59#define VP_T_CODE_P_INVERTED 0x01
60
61/* ------------------------------------------------------------------ */
62/* Defines for Video Output Port Register at address 0x195 */
63
64/* Bit 2: Video output clock delay control */
65
66#define VP_CLK_CTRL2_NOT_DELAYED 0x00
67#define VP_CLK_CTRL2_DELAYED 0x04
68
69/* Bit 1: Video output clock invert control */
70
71#define VP_CLK_CTRL1_NON_INVERTED 0x00
72#define VP_CLK_CTRL1_INVERTED 0x02
73
74/* ------------------------------------------------------------------ */
75/* Defines for Video Output Port Register at address 0x196 */
76
77/* Bits 2 to 0: VSYNC pin video vertical sync type */
78
79#define VP_VS_TYPE_MASK 0x07
80
81#define VP_VS_TYPE_OFF 0x00
82#define VP_VS_TYPE_V123 0x01
83#define VP_VS_TYPE_V_ITU 0x02
84#define VP_VS_TYPE_VGATE_L 0x03
85#define VP_VS_TYPE_RESERVED1 0x04
86#define VP_VS_TYPE_RESERVED2 0x05
87#define VP_VS_TYPE_F_ITU 0x06
88#define VP_VS_TYPE_SC_FID 0x07
89
90/* ------------------------------------------------------------------ */
51/* data structs for video */ 91/* data structs for video */
52 92
53static int video_out[][9] = { 93static int video_out[][9] = {
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = {
273 313
274 .h_start = 0, 314 .h_start = 0,
275 .h_stop = 719, 315 .h_stop = 719,
276 .video_v_start = 23, 316 .video_v_start = 23,
277 .video_v_stop = 262, 317 .video_v_stop = 262,
278 .vbi_v_start_0 = 10, 318 .vbi_v_start_0 = 10,
279 .vbi_v_stop_0 = 21, 319 .vbi_v_stop_0 = 21,
280 .vbi_v_start_1 = 273, 320 .vbi_v_start_1 = 273,
281 .src_timing = 7, 321 .src_timing = 7,
282 322
283 .sync_control = 0x18, 323 .sync_control = 0x18,
284 .luma_control = 0x40, 324 .luma_control = 0x40,
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task,
622 prescale = 1; 662 prescale = 1;
623 xscale = 1024 * dev->crop_current.width / prescale / width; 663 xscale = 1024 * dev->crop_current.width / prescale / width;
624 yscale = 512 * div * dev->crop_current.height / height; 664 yscale = 512 * div * dev->crop_current.height / height;
625 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); 665 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
626 set_h_prescale(dev,task,prescale); 666 set_h_prescale(dev,task,prescale);
627 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); 667 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
628 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); 668 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752 maxh = dev->crop_current.height; 792 maxh = dev->crop_current.height;
753 793
754 if (V4L2_FIELD_ANY == field) { 794 if (V4L2_FIELD_ANY == field) {
755 field = (win->w.height > maxh/2) 795 field = (win->w.height > maxh/2)
756 ? V4L2_FIELD_INTERLACED 796 ? V4L2_FIELD_INTERLACED
757 : V4L2_FIELD_TOP; 797 : V4L2_FIELD_TOP;
758 } 798 }
759 switch (field) { 799 switch (field) {
760 case V4L2_FIELD_TOP: 800 case V4L2_FIELD_TOP:
761 case V4L2_FIELD_BOTTOM: 801 case V4L2_FIELD_BOTTOM:
762 maxh = maxh / 2; 802 maxh = maxh / 2;
763 break; 803 break;
764 case V4L2_FIELD_INTERLACED: 804 case V4L2_FIELD_INTERLACED:
765 break; 805 break;
766 default: 806 default:
767 return -EINVAL; 807 return -EINVAL;
768 } 808 }
769 809
770 win->field = field; 810 win->field = field;
771 if (win->w.width > maxw) 811 if (win->w.width > maxw)
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1306 if (res_locked(fh->dev,RESOURCE_VIDEO)) { 1346 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1307 up(&fh->cap.lock); 1347 up(&fh->cap.lock);
1308 return POLLERR; 1348 return POLLERR;
1309 } 1349 }
1310 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { 1350 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1311 up(&fh->cap.lock); 1351 up(&fh->cap.lock);
1312 return POLLERR; 1352 return POLLERR;
1313 } 1353 }
1314 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1354 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1315 fh->cap.read_off = 0; 1355 fh->cap.read_off = 0;
1316 } 1356 }
1317 up(&fh->cap.lock); 1357 up(&fh->cap.lock);
1318 buf = fh->cap.read_buf; 1358 buf = fh->cap.read_buf;
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1666 case VIDIOC_QUERYCAP: 1706 case VIDIOC_QUERYCAP:
1667 { 1707 {
1668 struct v4l2_capability *cap = arg; 1708 struct v4l2_capability *cap = arg;
1709 unsigned int tuner_type = dev->tuner_type;
1669 1710
1670 memset(cap,0,sizeof(*cap)); 1711 memset(cap,0,sizeof(*cap));
1671 strcpy(cap->driver, "saa7134"); 1712 strcpy(cap->driver, "saa7134");
1672 strlcpy(cap->card, saa7134_boards[dev->board].name, 1713 strlcpy(cap->card, saa7134_boards[dev->board].name,
1673 sizeof(cap->card)); 1714 sizeof(cap->card));
1674 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1715 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1677 V4L2_CAP_VIDEO_CAPTURE | 1718 V4L2_CAP_VIDEO_CAPTURE |
1678 V4L2_CAP_VIDEO_OVERLAY | 1719 V4L2_CAP_VIDEO_OVERLAY |
1679 V4L2_CAP_VBI_CAPTURE | 1720 V4L2_CAP_VBI_CAPTURE |
1680 V4L2_CAP_TUNER |
1681 V4L2_CAP_READWRITE | 1721 V4L2_CAP_READWRITE |
1682 V4L2_CAP_STREAMING; 1722 V4L2_CAP_STREAMING |
1723 V4L2_CAP_TUNER;
1724
1725 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1726 cap->capabilities &= ~V4L2_CAP_TUNER;
1727
1683 return 0; 1728 return 0;
1684 } 1729 }
1685 1730
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1793 crop->c.height = b->top - crop->c.top + b->height; 1838 crop->c.height = b->top - crop->c.top + b->height;
1794 1839
1795 if (crop->c.left < b->left) 1840 if (crop->c.left < b->left)
1796 crop->c.top = b->left; 1841 crop->c.left = b->left;
1797 if (crop->c.left > b->left + b->width) 1842 if (crop->c.left > b->left + b->width)
1798 crop->c.top = b->left + b->width; 1843 crop->c.left = b->left + b->width;
1799 if (crop->c.width > b->left - crop->c.left + b->width) 1844 if (crop->c.width > b->left - crop->c.left + b->width)
1800 crop->c.width = b->left - crop->c.left + b->width; 1845 crop->c.width = b->left - crop->c.left + b->width;
1801 1846
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1817 break; 1862 break;
1818 if (NULL != card_in(dev,n).name) { 1863 if (NULL != card_in(dev,n).name) {
1819 strcpy(t->name, "Television"); 1864 strcpy(t->name, "Television");
1865 t->type = V4L2_TUNER_ANALOG_TV;
1820 t->capability = V4L2_TUNER_CAP_NORM | 1866 t->capability = V4L2_TUNER_CAP_NORM |
1821 V4L2_TUNER_CAP_STEREO | 1867 V4L2_TUNER_CAP_STEREO |
1822 V4L2_TUNER_CAP_LANG1 | 1868 V4L2_TUNER_CAP_LANG1 |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1892 } 1938 }
1893 case VIDIOC_S_AUDIO: 1939 case VIDIOC_S_AUDIO:
1894 return 0; 1940 return 0;
1895 case VIDIOC_G_PARM: 1941 case VIDIOC_G_PARM:
1896 { 1942 {
1897 struct v4l2_captureparm *parm = arg; 1943 struct v4l2_captureparm *parm = arg;
1898 memset(parm,0,sizeof(*parm)); 1944 memset(parm,0,sizeof(*parm));
1899 return 0; 1945 return 0;
1900 } 1946 }
1901 1947
1902 case VIDIOC_G_PRIORITY: 1948 case VIDIOC_G_PRIORITY:
1903 { 1949 {
1904 enum v4l2_priority *p = arg; 1950 enum v4l2_priority *p = arg;
1905 1951
1906 *p = v4l2_prio_max(&dev->prio); 1952 *p = v4l2_prio_max(&dev->prio);
1907 return 0; 1953 return 0;
1908 } 1954 }
1909 case VIDIOC_S_PRIORITY: 1955 case VIDIOC_S_PRIORITY:
1910 { 1956 {
1911 enum v4l2_priority *prio = arg; 1957 enum v4l2_priority *prio = arg;
1912 1958
1913 return v4l2_prio_change(&dev->prio, &fh->prio, *prio); 1959 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1914 } 1960 }
1915 1961
1916 /* --- preview ioctls ---------------------------------------- */ 1962 /* --- preview ioctls ---------------------------------------- */
1917 case VIDIOC_ENUM_FMT: 1963 case VIDIOC_ENUM_FMT:
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2018 struct v4l2_format *f = arg; 2064 struct v4l2_format *f = arg;
2019 return saa7134_try_fmt(dev,fh,f); 2065 return saa7134_try_fmt(dev,fh,f);
2020 } 2066 }
2021 2067#ifdef HAVE_V4L1
2022 case VIDIOCGMBUF: 2068 case VIDIOCGMBUF:
2023 { 2069 {
2024 struct video_mbuf *mbuf = arg; 2070 struct video_mbuf *mbuf = arg;
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2043 } 2089 }
2044 return 0; 2090 return 0;
2045 } 2091 }
2092#endif
2046 case VIDIOC_REQBUFS: 2093 case VIDIOC_REQBUFS:
2047 return videobuf_reqbufs(saa7134_queue(fh),arg); 2094 return videobuf_reqbufs(saa7134_queue(fh),arg);
2048 2095
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2060 { 2107 {
2061 int res = saa7134_resource(fh); 2108 int res = saa7134_resource(fh);
2062 2109
2063 if (!res_get(dev,fh,res)) 2110 if (!res_get(dev,fh,res))
2064 return -EBUSY; 2111 return -EBUSY;
2065 return videobuf_streamon(saa7134_queue(fh)); 2112 return videobuf_streamon(saa7134_queue(fh));
2066 } 2113 }
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2102 struct v4l2_capability *cap = arg; 2149 struct v4l2_capability *cap = arg;
2103 2150
2104 memset(cap,0,sizeof(*cap)); 2151 memset(cap,0,sizeof(*cap));
2105 strcpy(cap->driver, "saa7134"); 2152 strcpy(cap->driver, "saa7134");
2106 strlcpy(cap->card, saa7134_boards[dev->board].name, 2153 strlcpy(cap->card, saa7134_boards[dev->board].name,
2107 sizeof(cap->card)); 2154 sizeof(cap->card));
2108 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 2155 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2119 2166
2120 memset(t,0,sizeof(*t)); 2167 memset(t,0,sizeof(*t));
2121 strcpy(t->name, "Radio"); 2168 strcpy(t->name, "Radio");
2169 t->type = V4L2_TUNER_RADIO;
2122 2170
2123 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 2171 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2124 2172
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template =
2233{ 2281{
2234 .name = "saa7134-video", 2282 .name = "saa7134-video",
2235 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| 2283 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2236 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 2284 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2237 .hardware = 0, 2285 .hardware = 0,
2238 .fops = &video_fops, 2286 .fops = &video_fops,
2239 .minor = -1, 2287 .minor = -1,
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2280 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2328 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2281 dev->automute = 0; 2329 dev->automute = 0;
2282 2330
2283 INIT_LIST_HEAD(&dev->video_q.queue); 2331 INIT_LIST_HEAD(&dev->video_q.queue);
2284 init_timer(&dev->video_q.timeout); 2332 init_timer(&dev->video_q.timeout);
2285 dev->video_q.timeout.function = saa7134_buffer_timeout; 2333 dev->video_q.timeout.function = saa7134_buffer_timeout;
2286 dev->video_q.timeout.data = (unsigned long)(&dev->video_q); 2334 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2289 if (saa7134_boards[dev->board].video_out) { 2337 if (saa7134_boards[dev->board].video_out) {
2290 /* enable video output */ 2338 /* enable video output */
2291 int vo = saa7134_boards[dev->board].video_out; 2339 int vo = saa7134_boards[dev->board].video_out;
2340 int video_reg;
2341 unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
2292 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); 2342 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2293 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]); 2343 video_reg = video_out[vo][1];
2344 if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
2345 video_reg &= ~VP_T_CODE_P_INVERTED;
2346 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
2294 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); 2347 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2295 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); 2348 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2296 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); 2349 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2297 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]); 2350 video_reg = video_out[vo][5];
2298 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]); 2351 if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
2352 video_reg &= ~VP_CLK_CTRL2_DELAYED;
2353 if (vid_port_opts & SET_CLOCK_INVERTED)
2354 video_reg |= VP_CLK_CTRL1_INVERTED;
2355 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
2356 video_reg = video_out[vo][6];
2357 if (vid_port_opts & SET_VSYNC_OFF) {
2358 video_reg &= ~VP_VS_TYPE_MASK;
2359 video_reg |= VP_VS_TYPE_OFF;
2360 }
2361 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
2299 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); 2362 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2300 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); 2363 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2301 } 2364 }
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 860b89530e2a..fb9727471661 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -24,16 +24,18 @@
24 24
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev.h> 27#include <linux/videodev2.h>
28#include <linux/kdev_t.h> 28#include <linux/kdev_t.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/notifier.h>
31#include <linux/delay.h>
30 32
31#include <asm/io.h> 33#include <asm/io.h>
32 34
33#include <media/tuner.h> 35#include <media/tuner.h>
34#include <media/audiochip.h> 36#include <media/audiochip.h>
35#include <media/id.h>
36#include <media/ir-common.h> 37#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h>
37#include <media/video-buf.h> 39#include <media/video-buf.h>
38#include <media/video-buf-dvb.h> 40#include <media/video-buf-dvb.h>
39 41
@@ -45,6 +47,10 @@
45#endif 47#endif
46#define UNSET (-1U) 48#define UNSET (-1U)
47 49
50#include <sound/driver.h>
51#include <sound/core.h>
52#include <sound/pcm.h>
53
48/* ----------------------------------------------------------- */ 54/* ----------------------------------------------------------- */
49/* enums */ 55/* enums */
50 56
@@ -187,10 +193,39 @@ struct saa7134_format {
187#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 193#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
188#define SAA7134_BOARD_KWORLD_TERMINATOR 65 194#define SAA7134_BOARD_KWORLD_TERMINATOR 65
189#define SAA7134_BOARD_YUAN_TUN900 66 195#define SAA7134_BOARD_YUAN_TUN900 66
196#define SAA7134_BOARD_BEHOLD_409FM 67
197#define SAA7134_BOARD_GOTVIEW_7135 68
198#define SAA7134_BOARD_PHILIPS_EUROPA 69
199#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
200#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
201#define SAA7134_BOARD_RTD_VFG7350 72
202#define SAA7134_BOARD_RTD_VFG7330 73
203#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
204#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
205#define SAA7134_BOARD_MONSTERTV_MOBILE 76
206#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
207#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
208#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
209#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
210#define SAA7134_BOARD_PHILIPS_TIGER 81
190 211
191#define SAA7134_MAXBOARDS 8 212#define SAA7134_MAXBOARDS 8
192#define SAA7134_INPUT_MAX 8 213#define SAA7134_INPUT_MAX 8
193 214
215/* ----------------------------------------------------------- */
216/* Since we support 2 remote types, lets tell them apart */
217
218#define SAA7134_REMOTE_GPIO 1
219#define SAA7134_REMOTE_I2C 2
220
221/* ----------------------------------------------------------- */
222/* Video Output Port Register Initialization Options */
223
224#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
225#define SET_CLOCK_NOT_DELAYED (1 << 1)
226#define SET_CLOCK_INVERTED (1 << 2)
227#define SET_VSYNC_OFF (1 << 3)
228
194struct saa7134_input { 229struct saa7134_input {
195 char *name; 230 char *name;
196 unsigned int vmux; 231 unsigned int vmux;
@@ -226,6 +261,7 @@ struct saa7134_board {
226 /* peripheral I/O */ 261 /* peripheral I/O */
227 enum saa7134_video_out video_out; 262 enum saa7134_video_out video_out;
228 enum saa7134_mpeg_type mpeg; 263 enum saa7134_mpeg_type mpeg;
264 unsigned int vid_port_opts;
229}; 265};
230 266
231#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) 267#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
@@ -319,9 +355,9 @@ struct saa7134_fh {
319 struct saa7134_pgtable pt_vbi; 355 struct saa7134_pgtable pt_vbi;
320}; 356};
321 357
322/* oss dsp status */ 358/* dmasound dsp status */
323struct saa7134_oss { 359struct saa7134_dmasound {
324 struct semaphore lock; 360 struct semaphore lock;
325 int minor_mixer; 361 int minor_mixer;
326 int minor_dsp; 362 int minor_dsp;
327 unsigned int users_dsp; 363 unsigned int users_dsp;
@@ -347,6 +383,7 @@ struct saa7134_oss {
347 unsigned int dma_blk; 383 unsigned int dma_blk;
348 unsigned int read_offset; 384 unsigned int read_offset;
349 unsigned int read_count; 385 unsigned int read_count;
386 snd_pcm_substream_t *substream;
350}; 387};
351 388
352/* IR input */ 389/* IR input */
@@ -358,9 +395,9 @@ struct saa7134_ir {
358 u32 mask_keycode; 395 u32 mask_keycode;
359 u32 mask_keydown; 396 u32 mask_keydown;
360 u32 mask_keyup; 397 u32 mask_keyup;
361 int polling; 398 int polling;
362 u32 last_gpio; 399 u32 last_gpio;
363 struct timer_list timer; 400 struct timer_list timer;
364}; 401};
365 402
366/* ts/mpeg status */ 403/* ts/mpeg status */
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops {
383/* global device status */ 420/* global device status */
384struct saa7134_dev { 421struct saa7134_dev {
385 struct list_head devlist; 422 struct list_head devlist;
386 struct semaphore lock; 423 struct semaphore lock;
387 spinlock_t slock; 424 spinlock_t slock;
388#ifdef VIDIOC_G_PRIORITY 425#ifdef VIDIOC_G_PRIORITY
389 struct v4l2_prio_state prio; 426 struct v4l2_prio_state prio;
390#endif 427#endif
@@ -394,7 +431,7 @@ struct saa7134_dev {
394 struct video_device *video_dev; 431 struct video_device *video_dev;
395 struct video_device *radio_dev; 432 struct video_device *radio_dev;
396 struct video_device *vbi_dev; 433 struct video_device *vbi_dev;
397 struct saa7134_oss oss; 434 struct saa7134_dmasound dmasound;
398 435
399 /* infrared remote */ 436 /* infrared remote */
400 int has_remote; 437 int has_remote;
@@ -421,7 +458,7 @@ struct saa7134_dev {
421 /* i2c i/o */ 458 /* i2c i/o */
422 struct i2c_adapter i2c_adap; 459 struct i2c_adapter i2c_adap;
423 struct i2c_client i2c_client; 460 struct i2c_client i2c_client;
424 unsigned char eedata[64]; 461 unsigned char eedata[128];
425 462
426 /* video overlay */ 463 /* video overlay */
427 struct v4l2_framebuffer ovbuf; 464 struct v4l2_framebuffer ovbuf;
@@ -626,6 +663,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
626int saa7134_input_init1(struct saa7134_dev *dev); 663int saa7134_input_init1(struct saa7134_dev *dev);
627void saa7134_input_fini(struct saa7134_dev *dev); 664void saa7134_input_fini(struct saa7134_dev *dev);
628void saa7134_input_irq(struct saa7134_dev *dev); 665void saa7134_input_irq(struct saa7134_dev *dev);
666void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
629 667
630/* 668/*
631 * Local variables: 669 * Local variables:
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 255b6088ebf9..d32737dd2142 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,6 @@
50 50
51#include "bttv.h" 51#include "bttv.h"
52#include <media/audiochip.h> 52#include <media/audiochip.h>
53#include <media/id.h>
54 53
55#ifndef VIDEO_AUDIO_BALANCE 54#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32 55# define VIDEO_AUDIO_BALANCE 32
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
310 memset(t,0,sizeof *t); 309 memset(t,0,sizeof *t);
311 310
312 client = &t->c; 311 client = &t->c;
313 memcpy(client,&client_template,sizeof(struct i2c_client)); 312 memcpy(client,&client_template,sizeof(struct i2c_client));
314 client->adapter = adap; 313 client->adapter = adap;
315 client->addr = addr; 314 client->addr = addr;
316 i2c_set_clientdata(client, t); 315 i2c_set_clientdata(client, t);
317 316
318 do_tda7432_init(client); 317 do_tda7432_init(client);
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client,
472 } 471 }
473 } 472 }
474 473
475 t->muted=(va->flags & VIDEO_AUDIO_MUTE); 474 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
476 if (t->muted) 475 if (t->muted)
477 { 476 {
478 /* Mute & update balance*/ 477 /* Mute & update balance*/
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client,
503 502
504static struct i2c_driver driver = { 503static struct i2c_driver driver = {
505 .owner = THIS_MODULE, 504 .owner = THIS_MODULE,
506 .name = "i2c tda7432 driver", 505 .name = "i2c tda7432 driver",
507 .id = I2C_DRIVERID_TDA7432, 506 .id = I2C_DRIVERID_TDA7432,
508 .flags = I2C_DF_NOTIFY, 507 .flags = I2C_DF_NOTIFY,
509 .attach_adapter = tda7432_probe, 508 .attach_adapter = tda7432_probe,
510 .detach_client = tda7432_detach, 509 .detach_client = tda7432_detach,
511 .command = tda7432_command, 510 .command = tda7432_command,
512}; 511};
513 512
514static struct i2c_client client_template = 513static struct i2c_client client_template =
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index c65f0c7680a2..b2dfe07e9f9d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,172 +1,406 @@
1/* 1/*
2 * 2
3 * i2c tv tuner chip device driver 3 i2c tv tuner chip device driver
4 * controls the philips tda8290+75 tuner chip combo. 4 controls the philips tda8290+75 tuner chip combo.
5 */ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
6#include <linux/i2c.h> 21#include <linux/i2c.h>
7#include <linux/videodev.h> 22#include <linux/videodev.h>
8#include <linux/delay.h> 23#include <linux/delay.h>
9#include <media/tuner.h> 24#include <media/tuner.h>
10 25
11#define I2C_ADDR_TDA8290 0x4b
12#define I2C_ADDR_TDA8275 0x61
13
14/* ---------------------------------------------------------------------- */ 26/* ---------------------------------------------------------------------- */
15 27
16struct freq_entry { 28struct tda827x_data {
17 u16 freq; 29 u32 lomax;
18 u8 value; 30 u8 spd;
31 u8 bs;
32 u8 bp;
33 u8 cp;
34 u8 gc3;
35 u8 div1p5;
19}; 36};
20 37
21static struct freq_entry band_table[] = { 38 /* Note lomax entry is lo / 62500 */
22 { 0x2DF4, 0x1C }, 39
23 { 0x2574, 0x14 }, 40static struct tda827x_data tda827x_analog[] = {
24 { 0x22B4, 0x0C }, 41 { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
25 { 0x20D4, 0x0B }, 42 { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
26 { 0x1E74, 0x3B }, 43 { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
27 { 0x1C34, 0x33 }, 44 { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
28 { 0x16F4, 0x5B }, 45 { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
29 { 0x1454, 0x53 }, 46 { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
30 { 0x12D4, 0x52 }, 47 { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
31 { 0x1034, 0x4A }, 48 { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
32 { 0x0EE4, 0x7A }, 49 { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
33 { 0x0D34, 0x72 }, 50 { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
34 { 0x0B54, 0x9A }, 51 { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
35 { 0x0914, 0x91 }, 52 { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
36 { 0x07F4, 0x89 }, 53 { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
37 { 0x0774, 0xB9 }, 54 { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
38 { 0x067B, 0xB1 }, 55 { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
39 { 0x0634, 0xD9 }, 56 { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
40 { 0x05A4, 0xD8 }, // FM radio 57 { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
41 { 0x0494, 0xD0 }, 58 { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
42 { 0x03BC, 0xC8 }, 59 { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
43 { 0x0394, 0xF8 }, // 57250000 Hz 60 { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
44 { 0x0000, 0xF0 }, // 0 61 { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
62 { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
63 { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
64 { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
65 { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
66 { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
67 { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
68 { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
69 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
45}; 70};
46 71
47static struct freq_entry div_table[] = { 72static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
48 { 0x1C34, 3 }, 73{
49 { 0x0D34, 2 }, 74 unsigned char tuner_reg[8];
50 { 0x067B, 1 }, 75 unsigned char reg2[2];
51 { 0x0000, 0 }, 76 u32 N;
52}; 77 int i;
78 struct tuner *t = i2c_get_clientdata(c);
79 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
53 80
54static struct freq_entry agc_table[] = { 81 if (t->mode == V4L2_TUNER_RADIO)
55 { 0x22B4, 0x8F }, 82 freq = freq / 1000;
56 { 0x0B54, 0x9F },
57 { 0x09A4, 0x8F },
58 { 0x0554, 0x9F },
59 { 0x0000, 0xBF },
60};
61 83
62static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) 84 N = freq + ifc;
63{ 85 i = 0;
64 while(table->freq && table->freq > freq) 86 while (tda827x_analog[i].lomax < N) {
65 table++; 87 if(tda827x_analog[i + 1].lomax == 0)
66 return table->value; 88 break;
67} 89 i++;
90 }
91
92 N = N << tda827x_analog[i].spd;
93
94 tuner_reg[0] = 0;
95 tuner_reg[1] = (unsigned char)(N>>8);
96 tuner_reg[2] = (unsigned char) N;
97 tuner_reg[3] = 0x40;
98 tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);
99 tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
100 (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
101 tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
102 tuner_reg[7] = 0x8f;
103
104 msg.buf = tuner_reg;
105 msg.len = 8;
106 i2c_transfer(c->adapter, &msg, 1);
107
108 msg.buf= reg2;
109 msg.len = 2;
110 reg2[0] = 0x80;
111 reg2[1] = 0;
112 i2c_transfer(c->adapter, &msg, 1);
113
114 reg2[0] = 0x60;
115 reg2[1] = 0xbf;
116 i2c_transfer(c->adapter, &msg, 1);
117
118 reg2[0] = 0x30;
119 reg2[1] = tuner_reg[4] + 0x80;
120 i2c_transfer(c->adapter, &msg, 1);
121
122 msleep(1);
123 reg2[0] = 0x30;
124 reg2[1] = tuner_reg[4] + 4;
125 i2c_transfer(c->adapter, &msg, 1);
126
127 msleep(1);
128 reg2[0] = 0x30;
129 reg2[1] = tuner_reg[4];
130 i2c_transfer(c->adapter, &msg, 1);
68 131
69/* ---------------------------------------------------------------------- */ 132 msleep(550);
133 reg2[0] = 0x30;
134 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
135 i2c_transfer(c->adapter, &msg, 1);
70 136
71static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; 137 reg2[0] = 0x60;
72static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; 138 reg2[1] = 0x3f;
73static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, 139 i2c_transfer(c->adapter, &msg, 1);
74 0xfC, 0x04, 0xA3, 0x3F,
75 0x2A, 0x04, 0xFF, 0x00,
76 0x00, 0x40 };
77static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
78static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
79static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
80static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
81static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
82static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
83static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
84static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
85static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
86static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
87static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
88static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
89static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
90static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
91static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
92
93static struct i2c_msg i2c_msg_init[] = {
94 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
95 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
96 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
97 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
98};
99 140
100static struct i2c_msg i2c_msg_prolog[] = { 141 reg2[0] = 0x80;
101// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, 142 reg2[1] = 0x08; // Vsync en
102 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, 143 i2c_transfer(c->adapter, &msg, 1);
103 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, 144}
104 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
105};
106 145
107static struct i2c_msg i2c_msg_config[] = { 146static void tda827x_agcf(struct i2c_client *c)
108// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, 147{
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, 148 struct tuner *t = i2c_get_clientdata(c);
110 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, 149 unsigned char data[] = {0x80, 0x0c};
111 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, 150 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
112 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, 151 .flags = 0, .len = 2};
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, 152 i2c_transfer(c->adapter, &msg, 1);
114}; 153}
115 154
116static struct i2c_msg i2c_msg_epilog[] = { 155/* ---------------------------------------------------------------------- */
117 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, 156
118 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, 157struct tda827xa_data {
119 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, 158 u32 lomax;
120 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 159 u8 svco;
121 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, 160 u8 spd;
161 u8 scr;
162 u8 sbs;
163 u8 gc3;
122}; 164};
123 165
124static struct i2c_msg i2c_msg_standby[] = { 166static struct tda827xa_data tda827xa_analog[] = {
125 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, 167 { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
126 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 }, 168 { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
127 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 169 { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
128 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby }, 170 { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
171 { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
172 { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
173 { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
174 { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
175 { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
176 { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
177 { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
178 { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
179 { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
180 { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
181 { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
182 { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
183 { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
184 { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
185 { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
186 { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
187 { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
188 { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
189 { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
190 { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
191 { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
129}; 193};
130 194
131static int tda8290_tune(struct i2c_client *c) 195static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
132{ 196{
197 unsigned char tuner_reg[14];
198 unsigned char reg2[2];
199 u32 N;
200 int i;
133 struct tuner *t = i2c_get_clientdata(c); 201 struct tuner *t = i2c_get_clientdata(c);
134 struct i2c_msg easy_mode = 202 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
135 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
136 struct i2c_msg set_freq =
137 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
138 203
139 i2c_transfer(c->adapter, &easy_mode, 1); 204 if (t->mode == V4L2_TUNER_RADIO)
140 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); 205 freq = freq / 1000;
141 206
142 i2c_transfer(c->adapter, &set_freq, 1); 207 N = freq + ifc;
143 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); 208 i = 0;
209 while (tda827xa_analog[i].lomax < N) {
210 if(tda827xa_analog[i + 1].lomax == 0)
211 break;
212 i++;
213 }
214
215 N = N << tda827xa_analog[i].spd;
216
217 tuner_reg[0] = 0;
218 tuner_reg[1] = (unsigned char)(N>>8);
219 tuner_reg[2] = (unsigned char) N;
220 tuner_reg[3] = 0;
221 tuner_reg[4] = 0x16;
222 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
223 tda827xa_analog[i].sbs;
224 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
225 tuner_reg[7] = 0x0c;
226 tuner_reg[8] = 4;
227 tuner_reg[9] = 0x20;
228 tuner_reg[10] = 0xff;
229 tuner_reg[11] = 0xe0;
230 tuner_reg[12] = 0;
231 tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
232
233 msg.buf = tuner_reg;
234 msg.len = 14;
235 i2c_transfer(c->adapter, &msg, 1);
236
237 msg.buf= reg2;
238 msg.len = 2;
239 reg2[0] = 0x60;
240 reg2[1] = 0x3c;
241 i2c_transfer(c->adapter, &msg, 1);
242
243 reg2[0] = 0xa0;
244 reg2[1] = 0xc0;
245 i2c_transfer(c->adapter, &msg, 1);
246
247 msleep(2);
248 reg2[0] = 0x30;
249 reg2[1] = 0x10 + tda827xa_analog[i].scr;
250 i2c_transfer(c->adapter, &msg, 1);
144 251
145 msleep(550); 252 msleep(550);
146 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); 253 reg2[0] = 0x50;
147 return 0; 254 reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
255 i2c_transfer(c->adapter, &msg, 1);
256
257 reg2[0] = 0x80;
258 reg2[1] = 0x28;
259 i2c_transfer(c->adapter, &msg, 1);
260
261 reg2[0] = 0xb0;
262 reg2[1] = 0x01;
263 i2c_transfer(c->adapter, &msg, 1);
264
265 reg2[0] = 0xc0;
266 reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
267 i2c_transfer(c->adapter, &msg, 1);
148} 268}
149 269
150static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) 270static void tda827xa_agcf(struct i2c_client *c)
151{ 271{
152 u32 N; 272 struct tuner *t = i2c_get_clientdata(c);
273 unsigned char data[] = {0x80, 0x2c};
274 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
275 .flags = 0, .len = 2};
276 i2c_transfer(c->adapter, &msg, 1);
277}
153 278
154 if (t->mode == V4L2_TUNER_RADIO) 279/*---------------------------------------------------------------------*/
155 freq = freq / 1000;
156 280
157 N = (((freq<<3)+ifc)&0x3fffc); 281static void tda8290_i2c_bridge(struct i2c_client *c, int close)
158 282{
159 N = N >> get_freq_entry(div_table, freq); 283 unsigned char enable[2] = { 0x21, 0xC0 };
160 t->i2c_set_freq[0] = 0; 284 unsigned char disable[2] = { 0x21, 0x80 };
161 t->i2c_set_freq[1] = (unsigned char)(N>>8); 285 unsigned char *msg;
162 t->i2c_set_freq[2] = (unsigned char) N; 286 if(close) {
163 t->i2c_set_freq[3] = 0x40; 287 msg = enable;
164 t->i2c_set_freq[4] = 0x52; 288 i2c_master_send(c, msg, 2);
165 t->i2c_set_freq[5] = get_freq_entry(band_table, freq); 289 /* let the bridge stabilize */
166 t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); 290 msleep(20);
167 t->i2c_set_freq[7] = 0x8f; 291 } else {
292 msg = disable;
293 i2c_master_send(c, msg, 2);
294 }
168} 295}
169 296
297/*---------------------------------------------------------------------*/
298
299static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
300{
301 struct tuner *t = i2c_get_clientdata(c);
302 unsigned char soft_reset[] = { 0x00, 0x00 };
303 unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
304 unsigned char expert_mode[] = { 0x01, 0x80 };
305 unsigned char gainset_off[] = { 0x28, 0x14 };
306 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
307 unsigned char adc_head_6[] = { 0x05, 0x04 };
308 unsigned char adc_head_9[] = { 0x05, 0x02 };
309 unsigned char adc_head_12[] = { 0x05, 0x01 };
310 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
311 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
312 unsigned char gainset_2[] = { 0x28, 0x64 };
313 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
314 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
315 unsigned char if_agc_set[] = { 0x0f, 0x81 };
316 unsigned char addr_adc_sat = 0x1a;
317 unsigned char addr_agc_stat = 0x1d;
318 unsigned char addr_pll_stat = 0x1b;
319 unsigned char adc_sat, agc_stat,
320 pll_stat;
321
322 i2c_master_send(c, easy_mode, 2);
323 i2c_master_send(c, soft_reset, 2);
324 msleep(1);
325
326 expert_mode[1] = t->tda8290_easy_mode + 0x80;
327 i2c_master_send(c, expert_mode, 2);
328 i2c_master_send(c, gainset_off, 2);
329 i2c_master_send(c, if_agc_spd, 2);
330 if (t->tda8290_easy_mode & 0x60)
331 i2c_master_send(c, adc_head_9, 2);
332 else
333 i2c_master_send(c, adc_head_6, 2);
334 i2c_master_send(c, pll_bw_nom, 2);
335
336 tda8290_i2c_bridge(c, 1);
337 if (t->tda827x_ver != 0)
338 tda827xa_tune(c, ifc, freq);
339 else
340 tda827x_tune(c, ifc, freq);
341 /* adjust headroom resp. gain */
342 i2c_master_send(c, &addr_adc_sat, 1);
343 i2c_master_recv(c, &adc_sat, 1);
344 i2c_master_send(c, &addr_agc_stat, 1);
345 i2c_master_recv(c, &agc_stat, 1);
346 i2c_master_send(c, &addr_pll_stat, 1);
347 i2c_master_recv(c, &pll_stat, 1);
348 if (pll_stat & 0x80)
349 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
350 else
351 tuner_dbg("tda8290 not locked, no signal?\n");
352 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
353 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
354 agc_stat, adc_sat, pll_stat & 0x80);
355 i2c_master_send(c, gainset_2, 2);
356 msleep(100);
357 i2c_master_send(c, &addr_agc_stat, 1);
358 i2c_master_recv(c, &agc_stat, 1);
359 i2c_master_send(c, &addr_pll_stat, 1);
360 i2c_master_recv(c, &pll_stat, 1);
361 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
362 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
363 agc_stat, pll_stat & 0x80);
364 if (t->tda827x_ver != 0)
365 tda827xa_agcf(c);
366 else
367 tda827x_agcf(c);
368 msleep(100);
369 i2c_master_send(c, &addr_agc_stat, 1);
370 i2c_master_recv(c, &agc_stat, 1);
371 i2c_master_send(c, &addr_pll_stat, 1);
372 i2c_master_recv(c, &pll_stat, 1);
373 if((agc_stat > 115) || !(pll_stat & 0x80)) {
374 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
375 i2c_master_send(c, adc_head_12, 2);
376 i2c_master_send(c, pll_bw_low, 2);
377 msleep(100);
378 }
379 }
380 }
381
382 /* l/ l' deadlock? */
383 if(t->tda8290_easy_mode & 0x60) {
384 i2c_master_send(c, &addr_adc_sat, 1);
385 i2c_master_recv(c, &adc_sat, 1);
386 i2c_master_send(c, &addr_pll_stat, 1);
387 i2c_master_recv(c, &pll_stat, 1);
388 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
389 tuner_dbg("trying to resolve SECAM L deadlock\n");
390 i2c_master_send(c, agc_rst_on, 2);
391 msleep(40);
392 i2c_master_send(c, agc_rst_off, 2);
393 }
394 }
395
396 tda8290_i2c_bridge(c, 0);
397 i2c_master_send(c, if_agc_set, 2);
398 return 0;
399}
400
401
402/*---------------------------------------------------------------------*/
403
170#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) 404#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
171#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) 405#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
172#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) 406#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
174 408
175static void set_audio(struct tuner *t) 409static void set_audio(struct tuner *t)
176{ 410{
177 t->i2c_easy_mode[0] = 0x01; 411 char* mode;
178 412
179 if (t->std & V4L2_STD_MN) 413 t->tda827x_lpsel = 0;
180 t->i2c_easy_mode[1] = 0x01; 414 mode = "xx";
181 else if (t->std & V4L2_STD_B) 415 if (t->std & V4L2_STD_MN) {
182 t->i2c_easy_mode[1] = 0x02; 416 t->sgIF = 92;
183 else if (t->std & V4L2_STD_GH) 417 t->tda8290_easy_mode = 0x01;
184 t->i2c_easy_mode[1] = 0x04; 418 t->tda827x_lpsel = 1;
185 else if (t->std & V4L2_STD_PAL_I) 419 mode = "MN";
186 t->i2c_easy_mode[1] = 0x08; 420 } else if (t->std & V4L2_STD_B) {
187 else if (t->std & V4L2_STD_DK) 421 t->sgIF = 108;
188 t->i2c_easy_mode[1] = 0x10; 422 t->tda8290_easy_mode = 0x02;
189 else if (t->std & V4L2_STD_SECAM_L) 423 mode = "B";
190 t->i2c_easy_mode[1] = 0x20; 424 } else if (t->std & V4L2_STD_GH) {
425 t->sgIF = 124;
426 t->tda8290_easy_mode = 0x04;
427 mode = "GH";
428 } else if (t->std & V4L2_STD_PAL_I) {
429 t->sgIF = 124;
430 t->tda8290_easy_mode = 0x08;
431 mode = "I";
432 } else if (t->std & V4L2_STD_DK) {
433 t->sgIF = 124;
434 t->tda8290_easy_mode = 0x10;
435 mode = "DK";
436 } else if (t->std & V4L2_STD_SECAM_L) {
437 t->sgIF = 124;
438 t->tda8290_easy_mode = 0x20;
439 mode = "L";
440 }
441 tuner_dbg("setting tda8290 to system %s\n", mode);
191} 442}
192 443
193static void set_tv_freq(struct i2c_client *c, unsigned int freq) 444static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
195 struct tuner *t = i2c_get_clientdata(c); 446 struct tuner *t = i2c_get_clientdata(c);
196 447
197 set_audio(t); 448 set_audio(t);
198 set_frequency(t, 864, freq); 449 tda8290_tune(c, t->sgIF, freq);
199 tda8290_tune(c);
200} 450}
201 451
202static void set_radio_freq(struct i2c_client *c, unsigned int freq) 452static void set_radio_freq(struct i2c_client *c, unsigned int freq)
203{ 453{
204 struct tuner *t = i2c_get_clientdata(c); 454 /* if frequency is 5.5 MHz */
205 set_frequency(t, 704, freq); 455 tda8290_tune(c, 88, freq);
206 tda8290_tune(c);
207} 456}
208 457
209static int has_signal(struct i2c_client *c) 458static int has_signal(struct i2c_client *c)
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c)
216 return (afc & 0x80)? 65535:0; 465 return (afc & 0x80)? 65535:0;
217} 466}
218 467
468/*---------------------------------------------------------------------*/
469
219static void standby(struct i2c_client *c) 470static void standby(struct i2c_client *c)
220{ 471{
221 i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby)); 472 struct tuner *t = i2c_get_clientdata(c);
473 unsigned char cb1[] = { 0x30, 0xD0 };
474 unsigned char tda8290_standby[] = { 0x00, 0x02 };
475 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
476
477 tda8290_i2c_bridge(c, 1);
478 if (t->tda827x_ver != 0)
479 cb1[1] = 0x90;
480 i2c_transfer(c->adapter, &msg, 1);
481 tda8290_i2c_bridge(c, 0);
482 i2c_master_send(c, tda8290_standby, 2);
222} 483}
223 484
224int tda8290_init(struct i2c_client *c) 485
486static void tda8290_init_if(struct i2c_client *c)
487{
488 unsigned char set_VS[] = { 0x30, 0x6F };
489 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
490
491 i2c_master_send(c, set_VS, 2);
492 i2c_master_send(c, set_GP01_CF, 2);
493}
494
495static void tda8290_init_tuner(struct i2c_client *c)
225{ 496{
226 struct tuner *t = i2c_get_clientdata(c); 497 struct tuner *t = i2c_get_clientdata(c);
498 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
499 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
500 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
501 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
502 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0,
503 .buf=tda8275_init, .len = 14};
504 if (t->tda827x_ver != 0)
505 msg.buf = tda8275a_init;
506
507 tda8290_i2c_bridge(c, 1);
508 i2c_transfer(c->adapter, &msg, 1);
509 tda8290_i2c_bridge(c, 0);
510}
227 511
228 strlcpy(c->name, "tda8290+75", sizeof(c->name)); 512/*---------------------------------------------------------------------*/
513
514int tda8290_init(struct i2c_client *c)
515{
516 struct tuner *t = i2c_get_clientdata(c);
517 u8 data;
518 int i, ret, tuners_found;
519 u32 tuner_addrs;
520 struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
521
522 tda8290_i2c_bridge(c, 1);
523 /* probe for tuner chip */
524 tuners_found = 0;
525 tuner_addrs = 0;
526 for (i=0x60; i<= 0x63; i++) {
527 msg.addr = i;
528 ret = i2c_transfer(c->adapter, &msg, 1);
529 if (ret == 1) {
530 tuners_found++;
531 tuner_addrs = (tuner_addrs << 8) + i;
532 }
533 }
534 /* if there is more than one tuner, we expect the right one is
535 behind the bridge and we choose the highest address that doesn't
536 give a response now
537 */
538 tda8290_i2c_bridge(c, 0);
539 if(tuners_found > 1)
540 for (i = 0; i < tuners_found; i++) {
541 msg.addr = tuner_addrs & 0xff;
542 ret = i2c_transfer(c->adapter, &msg, 1);
543 if(ret == 1)
544 tuner_addrs = tuner_addrs >> 8;
545 else
546 break;
547 }
548 if (tuner_addrs == 0) {
549 tuner_addrs = 0x61;
550 tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
551 tuner_addrs);
552 } else {
553 tuner_addrs = tuner_addrs & 0xff;
554 tuner_info ("setting tuner address to %x\n", tuner_addrs);
555 }
556 t->tda827x_addr = tuner_addrs;
557 msg.addr = tuner_addrs;
558
559 tda8290_i2c_bridge(c, 1);
560 ret = i2c_transfer(c->adapter, &msg, 1);
561 if( ret != 1)
562 tuner_warn ("TDA827x access failed!\n");
563 if ((data & 0x3c) == 0) {
564 strlcpy(c->name, "tda8290+75", sizeof(c->name));
565 t->tda827x_ver = 0;
566 } else {
567 strlcpy(c->name, "tda8290+75a", sizeof(c->name));
568 t->tda827x_ver = 2;
569 }
229 tuner_info("tuner: type set to %s\n", c->name); 570 tuner_info("tuner: type set to %s\n", c->name);
571
230 t->tv_freq = set_tv_freq; 572 t->tv_freq = set_tv_freq;
231 t->radio_freq = set_radio_freq; 573 t->radio_freq = set_radio_freq;
232 t->has_signal = has_signal; 574 t->has_signal = has_signal;
233 t->standby = standby; 575 t->standby = standby;
576 t->tda827x_lpsel = 0;
234 577
235 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); 578 tda8290_init_tuner(c);
236 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); 579 tda8290_init_if(c);
237 return 0; 580 return 0;
238} 581}
239 582
583int tda8290_probe(struct i2c_client *c)
584{
585 unsigned char soft_reset[] = { 0x00, 0x00 };
586 unsigned char easy_mode_b[] = { 0x01, 0x02 };
587 unsigned char easy_mode_g[] = { 0x01, 0x04 };
588 unsigned char addr_dto_lsb = 0x07;
589 unsigned char data;
590
591 i2c_master_send(c, easy_mode_b, 2);
592 i2c_master_send(c, soft_reset, 2);
593 i2c_master_send(c, &addr_dto_lsb, 1);
594 i2c_master_recv(c, &data, 1);
595 if (data == 0) {
596 i2c_master_send(c, easy_mode_g, 2);
597 i2c_master_send(c, soft_reset, 2);
598 i2c_master_send(c, &addr_dto_lsb, 1);
599 i2c_master_recv(c, &data, 1);
600 if (data == 0x7b) {
601 return 0;
602 }
603 }
604 return -1;
605}
606
240/* 607/*
241 * Overrides for Emacs so that we follow Linus's tabbing style. 608 * Overrides for Emacs so that we follow Linus's tabbing style.
242 * --------------------------------------------------------------------------- 609 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7e3dcdb262b0..a5e37dc91f39 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -32,7 +32,6 @@
32 32
33#include "bttv.h" 33#include "bttv.h"
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36 35
37static int debug; /* insmod parameter */ 36static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR); 37module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
126 125
127static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 126static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
128{ 127{
129 unsigned char write[1]; 128 unsigned char write[1];
130 unsigned char read[1]; 129 unsigned char read[1];
131 struct i2c_msg msgs[2] = { 130 struct i2c_msg msgs[2] = {
132 { addr, 0, 1, write }, 131 { addr, 0, 1, write },
133 { addr, I2C_M_RD, 1, read } 132 { addr, I2C_M_RD, 1, read }
134 }; 133 };
135 write[0] = reg; 134 write[0] = reg;
136 135
137 if (2 != i2c_transfer(adap,msgs,2)) { 136 if (2 != i2c_transfer(adap,msgs,2)) {
138 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 137 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
139 return -1; 138 return -1;
140 } 139 }
141 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 140 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
142 return read[0]; 141 return read[0];
143} 142}
144 143
145static void tda9875_set(struct i2c_client *client) 144static void tda9875_set(struct i2c_client *client)
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client)
184 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 183 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
185 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 184 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
186 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 185 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
187 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 186 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
188 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 187 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
189 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 188 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
190 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 189 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client)
200 199
201 t->mode=AUDIO_UNMUTE; 200 t->mode=AUDIO_UNMUTE;
202 t->lvol=t->rvol =0; /* 0dB */ 201 t->lvol=t->rvol =0; /* 0dB */
203 t->bass=0; /* 0dB */ 202 t->bass=0; /* 0dB */
204 t->treble=0; /* 0dB */ 203 t->treble=0; /* 0dB */
205 tda9875_set(client); 204 tda9875_set(client);
206 205
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
239 memset(t,0,sizeof *t); 238 memset(t,0,sizeof *t);
240 239
241 client = &t->c; 240 client = &t->c;
242 memcpy(client,&client_template,sizeof(struct i2c_client)); 241 memcpy(client,&client_template,sizeof(struct i2c_client));
243 client->adapter = adap; 242 client->adapter = adap;
244 client->addr = addr; 243 client->addr = addr;
245 i2c_set_clientdata(client, t); 244 i2c_set_clientdata(client, t);
246 245
247 if(!tda9875_checkit(adap,addr)) { 246 if(!tda9875_checkit(adap,addr)) {
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client,
287 dprintk("In tda9875_command...\n"); 286 dprintk("In tda9875_command...\n");
288 287
289 switch (cmd) { 288 switch (cmd) {
290 /* --- v4l ioctls --- */ 289 /* --- v4l ioctls --- */
291 /* take care: bttv does userspace copying, we'll get a 290 /* take care: bttv does userspace copying, we'll get a
292 kernel pointer here... */ 291 kernel pointer here... */
293 case VIDIOCGAUDIO: 292 case VIDIOCGAUDIO:
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client,
355//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 354//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
356 355
357 356
358 tda9875_set(client); 357 tda9875_set(client);
359 358
360 break; 359 break;
361 360
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client,
374 373
375static struct i2c_driver driver = { 374static struct i2c_driver driver = {
376 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
377 .name = "i2c tda9875 driver", 376 .name = "i2c tda9875 driver",
378 .id = I2C_DRIVERID_TDA9875, 377 .id = I2C_DRIVERID_TDA9875,
379 .flags = I2C_DF_NOTIFY, 378 .flags = I2C_DF_NOTIFY,
380 .attach_adapter = tda9875_probe, 379 .attach_adapter = tda9875_probe,
381 .detach_client = tda9875_detach, 380 .detach_client = tda9875_detach,
382 .command = tda9875_command, 381 .command = tda9875_command,
383}; 382};
384 383
385static struct i2c_client client_template = 384static struct i2c_client client_template =
386{ 385{
387 .name = "tda9875", 386 .name = "tda9875",
388 .driver = &driver, 387 .driver = &driver,
389}; 388};
390 389
391static int __init tda9875_init(void) 390static int __init tda9875_init(void)
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 94053f149ddf..4249127c0a1d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -11,7 +11,6 @@
11 11
12#include <media/audiochip.h> 12#include <media/audiochip.h>
13#include <media/tuner.h> 13#include <media/tuner.h>
14#include <media/id.h>
15 14
16/* Chips: 15/* Chips:
17 TDA9885 (PAL, NTSC) 16 TDA9885 (PAL, NTSC)
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL");
44/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
45 44
46#define UNSET (-1U) 45#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: " 46#define tda9887_info(fmt, arg...) do {\
48#define dprintk if (debug) printk 47 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
48 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49#define tda9887_dbg(fmt, arg...) do {\
50 if (debug) \
51 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
52 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49 53
50struct tda9887 { 54struct tda9887 {
51 struct i2c_client client; 55 struct i2c_client client;
@@ -55,6 +59,7 @@ struct tda9887 {
55 unsigned int pinnacle_id; 59 unsigned int pinnacle_id;
56 unsigned int using_v4l2; 60 unsigned int using_v4l2;
57 unsigned int radio_mode; 61 unsigned int radio_mode;
62 unsigned char data[4];
58}; 63};
59 64
60struct tvnorm { 65struct tvnorm {
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = {
180 .name = "SECAM-L", 185 .name = "SECAM-L",
181 .b = ( cPositiveAmTV | 186 .b = ( cPositiveAmTV |
182 cQSS ), 187 cQSS ),
183 .e = ( cAudioIF_6_5 | 188 .e = ( cGating_36 |
189 cAudioIF_6_5 |
184 cVideoIF_38_90 ), 190 cVideoIF_38_90 ),
185 },{ 191 },{
186 .std = V4L2_STD_SECAM_DK, 192 .std = V4L2_STD_SECAM_DK,
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = {
236 242
237/* ---------------------------------------------------------------------- */ 243/* ---------------------------------------------------------------------- */
238 244
239static void dump_read_message(unsigned char *buf) 245static void dump_read_message(struct tda9887 *t, unsigned char *buf)
240{ 246{
241 static char *afc[16] = { 247 static char *afc[16] = {
242 "- 12.5 kHz", 248 "- 12.5 kHz",
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf)
256 "+ 37.5 kHz", 262 "+ 37.5 kHz",
257 "+ 12.5 kHz", 263 "+ 12.5 kHz",
258 }; 264 };
259 printk(PREFIX "read: 0x%2x\n", buf[0]); 265 tda9887_info("read: 0x%2x\n", buf[0]);
260 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); 266 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
261 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); 267 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
262 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); 268 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
263 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); 269 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
264 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 270 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
265} 271}
266 272
267static void dump_write_message(unsigned char *buf) 273static void dump_write_message(struct tda9887 *t, unsigned char *buf)
268{ 274{
269 static char *sound[4] = { 275 static char *sound[4] = {
270 "AM/TV", 276 "AM/TV",
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf)
304 "44 MHz", 310 "44 MHz",
305 }; 311 };
306 312
307 printk(PREFIX "write: byte B 0x%02x\n",buf[1]); 313 tda9887_info("write: byte B 0x%02x\n",buf[1]);
308 printk(" B0 video mode : %s\n", 314 tda9887_info(" B0 video mode : %s\n",
309 (buf[1] & 0x01) ? "video trap" : "sound trap"); 315 (buf[1] & 0x01) ? "video trap" : "sound trap");
310 printk(" B1 auto mute fm : %s\n", 316 tda9887_info(" B1 auto mute fm : %s\n",
311 (buf[1] & 0x02) ? "yes" : "no"); 317 (buf[1] & 0x02) ? "yes" : "no");
312 printk(" B2 carrier mode : %s\n", 318 tda9887_info(" B2 carrier mode : %s\n",
313 (buf[1] & 0x04) ? "QSS" : "Intercarrier"); 319 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
314 printk(" B3-4 tv sound/radio : %s\n", 320 tda9887_info(" B3-4 tv sound/radio : %s\n",
315 sound[(buf[1] & 0x18) >> 3]); 321 sound[(buf[1] & 0x18) >> 3]);
316 printk(" B5 force mute audio: %s\n", 322 tda9887_info(" B5 force mute audio: %s\n",
317 (buf[1] & 0x20) ? "yes" : "no"); 323 (buf[1] & 0x20) ? "yes" : "no");
318 printk(" B6 output port 1 : %s\n", 324 tda9887_info(" B6 output port 1 : %s\n",
319 (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); 325 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
320 printk(" B7 output port 2 : %s\n", 326 tda9887_info(" B7 output port 2 : %s\n",
321 (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); 327 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
322 328
323 printk(PREFIX "write: byte C 0x%02x\n",buf[2]); 329 tda9887_info("write: byte C 0x%02x\n",buf[2]);
324 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); 330 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
325 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); 331 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
326 printk(" C7 audio gain : %s\n", 332 tda9887_info(" C7 audio gain : %s\n",
327 (buf[2] & 0x80) ? "-6" : "0"); 333 (buf[2] & 0x80) ? "-6" : "0");
328 334
329 printk(PREFIX "write: byte E 0x%02x\n",buf[3]); 335 tda9887_info("write: byte E 0x%02x\n",buf[3]);
330 printk(" E0-1 sound carrier : %s\n", 336 tda9887_info(" E0-1 sound carrier : %s\n",
331 carrier[(buf[3] & 0x03)]); 337 carrier[(buf[3] & 0x03)]);
332 printk(" E6 l pll ganting : %s\n", 338 tda9887_info(" E6 l pll gating : %s\n",
333 (buf[3] & 0x40) ? "36" : "13"); 339 (buf[3] & 0x40) ? "36" : "13");
334 340
335 if (buf[1] & 0x08) { 341 if (buf[1] & 0x08) {
336 /* radio */ 342 /* radio */
337 printk(" E2-4 video if : %s\n", 343 tda9887_info(" E2-4 video if : %s\n",
338 rif[(buf[3] & 0x0c) >> 2]); 344 rif[(buf[3] & 0x0c) >> 2]);
339 printk(" E7 vif agc output : %s\n", 345 tda9887_info(" E7 vif agc output : %s\n",
340 (buf[3] & 0x80) 346 (buf[3] & 0x80)
341 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") 347 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
342 : "fm radio carrier afc"); 348 : "fm radio carrier afc");
343 } else { 349 } else {
344 /* video */ 350 /* video */
345 printk(" E2-4 video if : %s\n", 351 tda9887_info(" E2-4 video if : %s\n",
346 vif[(buf[3] & 0x1c) >> 2]); 352 vif[(buf[3] & 0x1c) >> 2]);
347 printk(" E5 tuner gain : %s\n", 353 tda9887_info(" E5 tuner gain : %s\n",
348 (buf[3] & 0x80) 354 (buf[3] & 0x80)
349 ? ((buf[3] & 0x20) ? "external" : "normal") 355 ? ((buf[3] & 0x20) ? "external" : "normal")
350 : ((buf[3] & 0x20) ? "minimum" : "normal")); 356 : ((buf[3] & 0x20) ? "minimum" : "normal"));
351 printk(" E7 vif agc output : %s\n", 357 tda9887_info(" E7 vif agc output : %s\n",
352 (buf[3] & 0x80) 358 (buf[3] & 0x80)
353 ? ((buf[3] & 0x20) 359 ? ((buf[3] & 0x20)
354 ? "pin3 port, pin22 vif agc out" 360 ? "pin3 port, pin22 vif agc out"
355 : "pin22 port, pin3 vif acg ext in") 361 : "pin22 port, pin3 vif acg ext in")
356 : "pin3+pin22 port"); 362 : "pin3+pin22 port");
357 } 363 }
358 printk("--\n"); 364 tda9887_info("--\n");
359} 365}
360 366
361/* ---------------------------------------------------------------------- */ 367/* ---------------------------------------------------------------------- */
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
379 } 385 }
380 } 386 }
381 if (NULL == norm) { 387 if (NULL == norm) {
382 dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n"); 388 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
383 return -1; 389 return -1;
384 } 390 }
385 391
386 dprintk(PREFIX "configure for: %s\n",norm->name); 392 tda9887_dbg("configure for: %s\n",norm->name);
387 buf[1] = norm->b; 393 buf[1] = norm->b;
388 buf[2] = norm->c; 394 buf[2] = norm->c;
389 buf[3] = norm->e; 395 buf[3] = norm->e;
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
458 break; 464 break;
459 } 465 }
460 } 466 }
467 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
468 buf[1] &= ~cQSS;
461 return 0; 469 return 0;
462} 470}
463 471
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
475 } 483 }
476 } 484 }
477 if (t->std & V4L2_STD_525_60) { 485 if (t->std & V4L2_STD_525_60) {
478 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { 486 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
479 bCarrierMode = cIntercarrier; 487 bCarrierMode = cIntercarrier;
480 } else { 488 } else {
481 bCarrierMode = cQSS; 489 bCarrierMode = cQSS;
482 } 490 }
483 } 491 }
484 492
485 if (bCarrierMode != UNSET) { 493 if (bCarrierMode != UNSET) {
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
505 case 'B': 513 case 'B':
506 case 'g': 514 case 'g':
507 case 'G': 515 case 'G':
508 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); 516 tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
509 t->std = V4L2_STD_PAL_BG; 517 t->std = V4L2_STD_PAL_BG;
510 break; 518 break;
511 case 'i': 519 case 'i':
512 case 'I': 520 case 'I':
513 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); 521 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
514 t->std = V4L2_STD_PAL_I; 522 t->std = V4L2_STD_PAL_I;
515 break; 523 break;
516 case 'd': 524 case 'd':
517 case 'D': 525 case 'D':
518 case 'k': 526 case 'k':
519 case 'K': 527 case 'K':
520 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); 528 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
521 t->std = V4L2_STD_PAL_DK; 529 t->std = V4L2_STD_PAL_DK;
522 break; 530 break;
523 case '-': 531 case '-':
524 /* default parameter, do nothing */ 532 /* default parameter, do nothing */
525 break; 533 break;
526 default: 534 default:
527 printk(PREFIX "pal= argument not recognised\n"); 535 tda9887_info("pal= argument not recognised\n");
528 break; 536 break;
529 } 537 }
530 } 538 }
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t)
534 case 'D': 542 case 'D':
535 case 'k': 543 case 'k':
536 case 'K': 544 case 'K':
537 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); 545 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
538 t->std = V4L2_STD_SECAM_DK; 546 t->std = V4L2_STD_SECAM_DK;
539 break; 547 break;
540 case 'l': 548 case 'l':
541 case 'L': 549 case 'L':
542 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); 550 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
543 t->std = V4L2_STD_SECAM_L; 551 t->std = V4L2_STD_SECAM_L;
544 break; 552 break;
545 case '-': 553 case '-':
546 /* default parameter, do nothing */ 554 /* default parameter, do nothing */
547 break; 555 break;
548 default: 556 default:
549 printk(PREFIX "secam= argument not recognised\n"); 557 tda9887_info("secam= argument not recognised\n");
550 break; 558 break;
551 } 559 }
552 } 560 }
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t)
559 int rc; 567 int rc;
560 568
561 memset(buf,0,sizeof(buf)); 569 memset(buf,0,sizeof(buf));
562 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 570 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
563 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); 571 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
564 dump_read_message(buf); 572 dump_read_message(t, buf);
565 return 0; 573 return 0;
566} 574}
567 575
568static int tda9887_configure(struct tda9887 *t) 576static int tda9887_configure(struct tda9887 *t)
569{ 577{
570 unsigned char buf[4];
571 int rc; 578 int rc;
572 579
573 memset(buf,0,sizeof(buf)); 580 memset(t->data,0,sizeof(t->data));
574 tda9887_set_tvnorm(t,buf); 581 tda9887_set_tvnorm(t,t->data);
575 582
576 buf[1] |= cOutputPort1Inactive; 583 t->data[1] |= cOutputPort1Inactive;
577 buf[1] |= cOutputPort2Inactive; 584 t->data[1] |= cOutputPort2Inactive;
578 585
579 if (UNSET != t->pinnacle_id) { 586 if (UNSET != t->pinnacle_id) {
580 tda9887_set_pinnacle(t,buf); 587 tda9887_set_pinnacle(t,t->data);
581 } 588 }
582 tda9887_set_config(t,buf); 589 tda9887_set_config(t,t->data);
583 tda9887_set_insmod(t,buf); 590 tda9887_set_insmod(t,t->data);
584 591
585 if (t->mode == T_STANDBY) { 592 if (t->mode == T_STANDBY) {
586 buf[1] |= cForcedMuteAudioON; 593 t->data[1] |= cForcedMuteAudioON;
587 } 594 }
588 595
589 596
590 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 597 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
591 buf[1],buf[2],buf[3]); 598 t->data[1],t->data[2],t->data[3]);
592 if (debug > 1) 599 if (debug > 1)
593 dump_write_message(buf); 600 dump_write_message(t, t->data);
594 601
595 if (4 != (rc = i2c_master_send(&t->client,buf,4))) 602 if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
596 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); 603 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
597 604
598 if (debug > 2) { 605 if (debug > 2) {
599 msleep_interruptible(1000); 606 msleep_interruptible(1000);
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
608{ 615{
609 struct tda9887 *t; 616 struct tda9887 *t;
610 617
611 client_template.adapter = adap; 618 client_template.adapter = adap;
612 client_template.addr = addr; 619 client_template.addr = addr;
613
614 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
615 620
616 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 621 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
617 return -ENOMEM; 622 return -ENOMEM;
618 memset(t,0,sizeof(*t)); 623 memset(t,0,sizeof(*t));
619 624
620 t->client = client_template; 625 t->client = client_template;
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
622 t->pinnacle_id = UNSET; 627 t->pinnacle_id = UNSET;
623 t->radio_mode = V4L2_TUNER_MODE_STEREO; 628 t->radio_mode = V4L2_TUNER_MODE_STEREO;
624 629
630 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
631
625 i2c_set_clientdata(&t->client, t); 632 i2c_set_clientdata(&t->client, t);
626 i2c_attach_client(&t->client); 633 i2c_attach_client(&t->client);
627 634
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client)
655} 662}
656 663
657#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 664#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
658 printk(PREFIX "switching to v4l2\n"); \ 665 tda9887_info("switching to v4l2\n"); \
659 t->using_v4l2 = 1; 666 t->using_v4l2 = 1;
660#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ 667#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
661 printk(PREFIX "ignore v4l1 call\n"); \ 668 tda9887_info("ignore v4l1 call\n"); \
662 return 0; } 669 return 0; }
663 670
664static int 671static int
665tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) 672tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
666{ 673{
667 struct tda9887 *t = i2c_get_clientdata(client); 674 struct tda9887 *t = i2c_get_clientdata(client);
668 675
669 switch (cmd) { 676 switch (cmd) {
670 677
671 /* --- configuration --- */ 678 /* --- configuration --- */
672 case AUDC_SET_RADIO: 679 case AUDC_SET_RADIO:
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
777 } 784 }
778 break; 785 break;
779 } 786 }
787 case VIDIOC_LOG_STATUS:
788 {
789 tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
790 break;
791 }
780 default: 792 default:
781 /* nothing */ 793 /* nothing */
782 break; 794 break;
@@ -786,7 +798,10 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
786 798
787static int tda9887_suspend(struct device * dev, pm_message_t state) 799static int tda9887_suspend(struct device * dev, pm_message_t state)
788{ 800{
789 dprintk("tda9887: suspend\n"); 801 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
802 struct tda9887 *t = i2c_get_clientdata(c);
803
804 tda9887_dbg("suspend\n");
790 return 0; 805 return 0;
791} 806}
792 807
@@ -795,7 +810,7 @@ static int tda9887_resume(struct device * dev)
795 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 810 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
796 struct tda9887 *t = i2c_get_clientdata(c); 811 struct tda9887 *t = i2c_get_clientdata(c);
797 812
798 dprintk("tda9887: resume\n"); 813 tda9887_dbg("resume\n");
799 tda9887_configure(t); 814 tda9887_configure(t);
800 return 0; 815 return 0;
801} 816}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index 38bf50943798..a9375ef05de1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -117,10 +117,10 @@
117#define TEA5767_RESERVED_MASK 0xff 117#define TEA5767_RESERVED_MASK 0xff
118 118
119enum tea5767_xtal_freq { 119enum tea5767_xtal_freq {
120 TEA5767_LOW_LO_32768 = 0, 120 TEA5767_LOW_LO_32768 = 0,
121 TEA5767_HIGH_LO_32768 = 1, 121 TEA5767_HIGH_LO_32768 = 1,
122 TEA5767_LOW_LO_13MHz = 2, 122 TEA5767_LOW_LO_13MHz = 2,
123 TEA5767_HIGH_LO_13MHz = 3, 123 TEA5767_HIGH_LO_13MHz = 3,
124}; 124};
125 125
126 126
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index ad85bef1c3d5..73c4041c35d7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -28,7 +28,7 @@
28 28
29/* standard i2c insmod options */ 29/* standard i2c insmod options */
30static unsigned short normal_i2c[] = { 30static unsigned short normal_i2c[] = {
31 0x4b, /* tda8290 */ 31 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
34 I2C_CLIENT_END 34 I2C_CLIENT_END
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
189 i2c_master_send(c, buffer, 4); 189 i2c_master_send(c, buffer, 4);
190 default_tuner_init(c); 190 default_tuner_init(c);
191 break; 191 break;
192 case TUNER_PHILIPS_TD1316:
193 buffer[0] = 0x0b;
194 buffer[1] = 0xdc;
195 buffer[2] = 0x86;
196 buffer[3] = 0xa4;
197 i2c_master_send(c,buffer,4);
198 default_tuner_init(c);
192 default: 199 default:
193 default_tuner_init(c); 200 default_tuner_init(c);
194 break; 201 break;
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
215{ 222{
216 struct tuner *t = i2c_get_clientdata(c); 223 struct tuner *t = i2c_get_clientdata(c);
217 224
218 if ((tun_setup->addr == ADDR_UNSET && 225 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
219 (t->mode_mask & tun_setup->mode_mask)) || 226 (t->mode_mask & tun_setup->mode_mask)) ||
220 tun_setup->addr == c->addr) { 227 tun_setup->addr == c->addr)) {
221 set_type(c, tun_setup->type, tun_setup->mode_mask); 228 set_type(c, tun_setup->type, tun_setup->mode_mask);
222 } 229 }
223} 230}
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
341 t->audmode = V4L2_TUNER_MODE_STEREO; 348 t->audmode = V4L2_TUNER_MODE_STEREO;
342 t->mode_mask = T_UNINITIALIZED; 349 t->mode_mask = T_UNINITIALIZED;
343 350
344
345 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
346
347 if (show_i2c) { 351 if (show_i2c) {
348 unsigned char buffer[16]; 352 unsigned char buffer[16];
349 int i,rc; 353 int i,rc;
350 354
351 memset(buffer, 0, sizeof(buffer)); 355 memset(buffer, 0, sizeof(buffer));
352 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); 356 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
353 printk("tuner-%04x I2C RECV = ",addr); 357 tuner_info("I2C RECV = ");
354 for (i=0;i<rc;i++) 358 for (i=0;i<rc;i++)
355 printk("%02x ",buffer[i]); 359 printk("%02x ",buffer[i]);
356 printk("\n"); 360 printk("\n");
357 } 361 }
358 /* TEA5767 autodetection code - only for addr = 0xc0 */ 362 /* TEA5767 autodetection code - only for addr = 0xc0 */
359 if (!no_autodetect) { 363 if (!no_autodetect) {
360 if (addr == 0x60) { 364 switch (addr) {
365 case 0x42:
366 case 0x43:
367 case 0x4a:
368 case 0x4b:
369 /* If chip is not tda8290, don't register.
370 since it can be tda9887*/
371 if (tda8290_probe(&t->i2c) != 0) {
372 tuner_dbg("chip at addr %x is not a tda8290\n", addr);
373 kfree(t);
374 return 0;
375 }
376 break;
377 case 0x60:
361 if (tea5767_autodetection(&t->i2c) != EINVAL) { 378 if (tea5767_autodetection(&t->i2c) != EINVAL) {
362 t->type = TUNER_TEA5767; 379 t->type = TUNER_TEA5767;
363 t->mode_mask = T_RADIO; 380 t->mode_mask = T_RADIO;
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
365 t->freq = 87.5 * 16; /* Sets freq to FM range */ 382 t->freq = 87.5 * 16; /* Sets freq to FM range */
366 default_mode_mask &= ~T_RADIO; 383 default_mode_mask &= ~T_RADIO;
367 384
368 i2c_attach_client (&t->i2c); 385 goto register_client;
369 set_type(&t->i2c,t->type, t->mode_mask);
370 return 0;
371 } 386 }
387 break;
372 } 388 }
373 } 389 }
374 390
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
381 } 397 }
382 398
383 /* Should be just before return */ 399 /* Should be just before return */
400register_client:
401 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
384 i2c_attach_client (&t->i2c); 402 i2c_attach_client (&t->i2c);
385 set_type (&t->i2c,t->type, t->mode_mask); 403 set_type (&t->i2c,t->type, t->mode_mask);
386 return 0; 404 return 0;
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client)
425 443
426static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) 444static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
427{ 445{
428 if (mode == t->mode) 446 if (mode == t->mode)
429 return 0; 447 return 0;
430 448
431 t->mode = mode; 449 t->mode = mode;
432 450
433 if (check_mode(t, cmd) == EINVAL) { 451 if (check_mode(t, cmd) == EINVAL) {
434 t->mode = T_STANDBY; 452 t->mode = T_STANDBY;
435 if (t->standby) 453 if (t->standby)
436 t->standby (client); 454 t->standby (client);
437 return EINVAL; 455 return EINVAL;
438 } 456 }
439 return 0; 457 return 0;
440} 458}
441 459
442#define switch_v4l2() if (!t->using_v4l2) \ 460#define switch_v4l2() if (!t->using_v4l2) \
443 tuner_dbg("switching to v4l2\n"); \ 461 tuner_dbg("switching to v4l2\n"); \
444 t->using_v4l2 = 1; 462 t->using_v4l2 = 1;
445 463
446static inline int check_v4l2(struct tuner *t) 464static inline int check_v4l2(struct tuner *t)
447{ 465{
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
479 break; 497 break;
480 } 498 }
481 case AUDC_CONFIG_PINNACLE: 499 case AUDC_CONFIG_PINNACLE:
482 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
483 return 0;
484 switch (*iarg) { 500 switch (*iarg) {
485 case 2: 501 case 2:
486 tuner_dbg("pinnacle pal\n"); 502 tuner_dbg("pinnacle pal\n");
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
616 switch_v4l2(); 632 switch_v4l2();
617 if (V4L2_TUNER_RADIO == f->type && 633 if (V4L2_TUNER_RADIO == f->type &&
618 V4L2_TUNER_RADIO != t->mode) { 634 V4L2_TUNER_RADIO != t->mode) {
619 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") 635 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
620 == EINVAL) 636 == EINVAL)
621 return 0; 637 return 0;
622 } 638 }
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
688 break; 704 break;
689 } 705 }
690 default: 706 default:
691 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", 707 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
692 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), 708 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
693 _IOC_NR(cmd), _IOC_SIZE(cmd)); 709 _IOC_NR(cmd), _IOC_SIZE(cmd));
694 break; 710 break;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 8edd73abe1d8..d832205818f2 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -102,7 +102,7 @@ struct tunertype
102 */ 102 */
103static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
104 /* 0-9 */ 104 /* 0-9 */
105 { "Temic PAL (4002 FH5)", TEMIC, PAL, 105 { "Temic PAL (4002 FH5)", TEMIC, PAL,
106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, 106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, 107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = {
118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
123 { "Alps HSBH1", TEMIC, NTSC, 123 { "Alps HSBH1", TEMIC, NTSC,
124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
125 125
126 /* 10-19 */ 126 /* 10-19 */
127 { "Alps TSBE1", TEMIC, PAL, 127 { "Alps TSBE1", TEMIC, PAL,
128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ 129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, 130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137 { "Alps TSCH6", Alps, NTSC, 137 { "Alps TSCH6", Alps, NTSC,
138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, 139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
141 { "Philips NTSC_M (MK2)", Philips, NTSC, 141 { "Philips NTSC_M (MK2)", Philips, NTSC,
142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
147 147
148 /* 20-29 */ 148 /* 20-29 */
149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, 149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, 153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = {
173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ 173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ 175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
176 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 176 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
177 { "MT20xx universal", Microtune, PAL|NTSC, 177 { "MT20xx universal", Microtune, PAL|NTSC,
178 /* see mt20xx.c for details */ }, 178 /* see mt20xx.c for details */ },
179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, 186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, 187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
188 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 188 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
191 191
192 /* 40-49 */ 192 /* 40-49 */
193 { "HITACHI V7-J180AT", HITACHI, NTSC, 193 { "HITACHI V7-J180AT", HITACHI, NTSC,
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = {
196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, 197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
203 { "Microtune 4049 FM5", Microtune, PAL, 203 { "Microtune 4049 FM5", Microtune, PAL,
204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
209 { "Tenna TNF 8831 BGFF)", Philips, PAL, 209 { "Tenna TNF 8831 BGFF)", Philips, PAL,
210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
213 213
214 /* 50-59 */ 214 /* 50-59 */
215 { "TCL 2002N", TCL, NTSC, 215 { "TCL 2002N", TCL, NTSC,
216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = {
222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ 222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
223 { "tda8290+75", Philips, PAL|NTSC, 223 { "tda8290+75", Philips, PAL|NTSC,
224 /* see tda8290.c for details */ }, 224 /* see tda8290.c for details */ },
225 { "LG PAL (TAPE series)", LGINNOTEK, PAL, 225 { "TCL 2002MB", TCL, PAL,
226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
229 { "Philips FQ1236A MK4", Philips, NTSC, 229 { "Philips FQ1236A MK4", Philips, NTSC,
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = {
233 { "Ymec TVision TVF-5533MF", Philips, NTSC, 233 { "Ymec TVision TVF-5533MF", Philips, NTSC,
234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
235 235
236 /* 60-66 */ 236 /* 60-68 */
237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
241 { "Philips TEA5767HN FM Radio", Philips, RADIO, 241 { "Philips TEA5767HN FM Radio", Philips, RADIO,
242 /* see tea5767.c for details */}, 242 /* see tea5767.c for details */},
243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, 245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
247 { "Ymec TVF66T5-B/DFF", Philips, PAL, 247 { "Ymec TVF66T5-B/DFF", Philips, PAL,
248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, 248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, 249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, 250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
251 { "Philips TD1316 Hybrid Tuner", Philips, PAL,
252 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
253 { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
254 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
251}; 255};
252 256
253unsigned const int tuner_count = ARRAY_SIZE(tuners); 257unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c)
277 status = tuner_getstatus (c); 281 status = tuner_getstatus (c);
278 282
279 switch (t->type) { 283 switch (t->type) {
280 case TUNER_PHILIPS_FM1216ME_MK3: 284 case TUNER_PHILIPS_FM1216ME_MK3:
281 case TUNER_PHILIPS_FM1236_MK3: 285 case TUNER_PHILIPS_FM1236_MK3:
282 case TUNER_PHILIPS_FM1256_IH3: 286 case TUNER_PHILIPS_FM1256_IH3:
283 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 287 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c)
295static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) 299static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
296{ 300{
297 struct tuner *t = i2c_get_clientdata(c); 301 struct tuner *t = i2c_get_clientdata(c);
298 u8 config; 302 u8 config, tuneraddr;
299 u16 div; 303 u16 div;
300 struct tunertype *tun; 304 struct tunertype *tun;
301 unsigned char buffer[4]; 305 unsigned char buffer[4];
302 int rc; 306 int rc;
303 307
304 tun = &tuners[t->type]; 308 tun = &tuners[t->type];
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
373 /* Set the charge pump for fast tuning */ 377 /* Set the charge pump for fast tuning */
374 tun->config |= TUNER_CHARGE_PUMP; 378 tun->config |= TUNER_CHARGE_PUMP;
375 break; 379 break;
380
381 case TUNER_PHILIPS_TUV1236D:
382 /* 0x40 -> ATSC antenna input 1 */
383 /* 0x48 -> ATSC antenna input 2 */
384 /* 0x00 -> NTSC antenna input 1 */
385 /* 0x08 -> NTSC antenna input 2 */
386 buffer[0] = 0x14;
387 buffer[1] = 0x00;
388 buffer[2] = 0x17;
389 buffer[3] = 0x00;
390 config &= ~0x40;
391 if (t->std & V4L2_STD_ATSC) {
392 config |= 0x40;
393 buffer[1] = 0x04;
394 }
395 /* set to the correct mode (analog or digital) */
396 tuneraddr = c->addr;
397 c->addr = 0x0a;
398 if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
399 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
400 if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
401 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
402 c->addr = tuneraddr;
403 /* FIXME: input */
404 break;
376 } 405 }
377 406
378 /* 407 /*
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
404 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 433 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
405 buffer[0],buffer[1],buffer[2],buffer[3]); 434 buffer[0],buffer[1],buffer[2],buffer[3]);
406 435
407 if (4 != (rc = i2c_master_send(c,buffer,4))) 436 if (4 != (rc = i2c_master_send(c,buffer,4)))
408 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 437 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
409 438
410 if (t->type == TUNER_MICROTUNE_4042FI5) { 439 if (t->type == TUNER_MICROTUNE_4042FI5) {
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
443{ 472{
444 struct tunertype *tun; 473 struct tunertype *tun;
445 struct tuner *t = i2c_get_clientdata(c); 474 struct tuner *t = i2c_get_clientdata(c);
446 unsigned char buffer[4]; 475 unsigned char buffer[4];
447 unsigned div; 476 unsigned div;
448 int rc; 477 int rc;
449 478
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
476 buffer[3] = 0xa4; 505 buffer[3] = 0xa4;
477 break; 506 break;
478 } 507 }
479 buffer[0] = (div>>8) & 0x7f; 508 buffer[0] = (div>>8) & 0x7f;
480 buffer[1] = div & 0xff; 509 buffer[1] = div & 0xff;
481 510
482 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 511 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
483 buffer[0],buffer[1],buffer[2],buffer[3]); 512 buffer[0],buffer[1],buffer[2],buffer[3]);
484 513
485 if (4 != (rc = i2c_master_send(c,buffer,4))) 514 if (4 != (rc = i2c_master_send(c,buffer,4)))
486 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 515 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
487} 516}
488 517
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1c31ef52f863..c31bf28b73fe 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,7 +31,6 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/id.h>
35 34
36#include "tvaudio.h" 35#include "tvaudio.h"
37 36
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
458#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ 457#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
459#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ 458#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
460 /* Bits 0 to 3 select various combinations 459 /* Bits 0 to 3 select various combinations
461 * of line in and line out, only the 460 * of line in and line out, only the
462 * interesting ones are defined */ 461 * interesting ones are defined */
463#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ 462#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
464#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ 463#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
465 464
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1028#define TEA6300_TR 0x03 /* treble */ 1027#define TEA6300_TR 0x03 /* treble */
1029#define TEA6300_FA 0x04 /* fader control */ 1028#define TEA6300_FA 0x04 /* fader control */
1030#define TEA6300_S 0x05 /* switch register */ 1029#define TEA6300_S 0x05 /* switch register */
1031 /* values for those registers: */ 1030 /* values for those registers: */
1032#define TEA6300_S_SA 0x01 /* stereo A input */ 1031#define TEA6300_S_SA 0x01 /* stereo A input */
1033#define TEA6300_S_SB 0x02 /* stereo B */ 1032#define TEA6300_S_SB 0x02 /* stereo B */
1034#define TEA6300_S_SC 0x04 /* stereo C */ 1033#define TEA6300_S_SC 0x04 /* stereo C */
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1042#define TEA6320_BA 0x05 /* bass (0-4) */ 1041#define TEA6320_BA 0x05 /* bass (0-4) */
1043#define TEA6320_TR 0x06 /* treble (0-4) */ 1042#define TEA6320_TR 0x06 /* treble (0-4) */
1044#define TEA6320_S 0x07 /* switch register */ 1043#define TEA6320_S 0x07 /* switch register */
1045 /* values for those registers: */ 1044 /* values for those registers: */
1046#define TEA6320_S_SA 0x07 /* stereo A input */ 1045#define TEA6320_S_SA 0x07 /* stereo A input */
1047#define TEA6320_S_SB 0x06 /* stereo B */ 1046#define TEA6320_S_SB 0x06 /* stereo B */
1048#define TEA6320_S_SC 0x05 /* stereo C */ 1047#define TEA6320_S_SC 0x05 /* stereo C */
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip)
1082#define TDA8425_BA 0x02 /* bass */ 1081#define TDA8425_BA 0x02 /* bass */
1083#define TDA8425_TR 0x03 /* treble */ 1082#define TDA8425_TR 0x03 /* treble */
1084#define TDA8425_S1 0x08 /* switch functions */ 1083#define TDA8425_S1 0x08 /* switch functions */
1085 /* values for those registers: */ 1084 /* values for those registers: */
1086#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ 1085#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1087#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ 1086#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1088#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ 1087#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1148 1147
1149/* bit definition of the RESET register, I2C data. */ 1148/* bit definition of the RESET register, I2C data. */
1150#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ 1149#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1151 /* code of remote controller */ 1150 /* code of remote controller */
1152#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ 1151#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1153#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ 1152#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1154#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ 1153#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = {
1281 .setmode = tda9840_setmode, 1280 .setmode = tda9840_setmode,
1282 .checkmode = generic_checkmode, 1281 .checkmode = generic_checkmode,
1283 1282
1284 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN 1283 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1285 /* ,TDA9840_SW, TDA9840_MONO */} } 1284 /* ,TDA9840_SW, TDA9840_MONO */} }
1286 }, 1285 },
1287 { 1286 {
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = {
1438 }, 1437 },
1439 { 1438 {
1440 .name = "pic16c54 (PV951)", 1439 .name = "pic16c54 (PV951)",
1441 .id = I2C_DRIVERID_PIC16C54_PV951, 1440 .id = I2C_DRIVERID_PIC16C54_PV9,
1442 .insmodopt = &pic16c54, 1441 .insmodopt = &pic16c54,
1443 .addr_lo = I2C_PIC16C54 >> 1, 1442 .addr_lo = I2C_PIC16C54 >> 1,
1444 .addr_hi = I2C_PIC16C54>> 1, 1443 .addr_hi = I2C_PIC16C54>> 1,
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = {
1467 .setmode = ta8874z_setmode, 1466 .setmode = ta8874z_setmode,
1468 .checkmode = generic_checkmode, 1467 .checkmode = generic_checkmode,
1469 1468
1470 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, 1469 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1471 }, 1470 },
1472 { .name = NULL } /* EOF */ 1471 { .name = NULL } /* EOF */
1473}; 1472};
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1486 return -ENOMEM; 1485 return -ENOMEM;
1487 memset(chip,0,sizeof(*chip)); 1486 memset(chip,0,sizeof(*chip));
1488 memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); 1487 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1489 chip->c.adapter = adap; 1488 chip->c.adapter = adap;
1490 chip->c.addr = addr; 1489 chip->c.addr = addr;
1491 i2c_set_clientdata(&chip->c, chip); 1490 i2c_set_clientdata(&chip->c, chip);
1492 1491
1493 /* find description for the chip */ 1492 /* find description for the chip */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 5344d5592199..72e8741e8b59 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -6,12 +6,12 @@
6 * which are: 6 * which are:
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 * Adjustments to fit a more general model and all bugs: 12 * Adjustments to fit a more general model and all bugs:
13 13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com> 14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15 15
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40 40
41#include <media/tuner.h> 41#include <media/tuner.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/audiochip.h>
43 44
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar"); 46MODULE_AUTHOR("John Klar");
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54#define tveeprom_info(fmt, arg...) do {\ 55#define tveeprom_info(fmt, arg...) do {\
55 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
56 c->adapter->nr, c->addr , ##arg); } while (0) 57 c->adapter->nr, c->addr , ##arg); } while (0)
57#define tveeprom_warn(fmt, arg...) do {\ 58#define tveeprom_warn(fmt, arg...) do {\
58 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ 59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
59 c->adapter->nr, c->addr , ##arg); } while (0) 60 c->adapter->nr, c->addr , ##arg); } while (0)
60#define tveeprom_dbg(fmt, arg...) do {\ 61#define tveeprom_dbg(fmt, arg...) do {\
61 if (debug) \ 62 if (debug) \
62 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
63 c->adapter->nr, c->addr , ##arg); } while (0) 64 c->adapter->nr, c->addr , ##arg); } while (0)
64 65
65 66
66/* ----------------------------------------------------------------------- */ 67/* ----------------------------------------------------------------------- */
@@ -134,8 +135,8 @@ hauppauge_tuner[] =
134 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, 135 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
135 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, 136 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
136 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, 137 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
137 { TUNER_PHILIPS_NTSC, "Philips TD1536" }, 138 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
138 { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, 139 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
139 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ 140 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
140 { TUNER_ABSENT, "Philips FI1256MP" }, 141 { TUNER_ABSENT, "Philips FI1256MP" },
141 /* 40-49 */ 142 /* 40-49 */
@@ -189,7 +190,7 @@ hauppauge_tuner[] =
189 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, 191 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
191 { TUNER_TCL_2002N, "TCL 2002N 6A"}, 192 { TUNER_TCL_2002N, "TCL 2002N 6A"},
192 { TUNER_ABSENT, "Philips FQ1236 MK3"}, 193 { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
193 { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, 194 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
194 { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, 195 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
195 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, 196 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
@@ -200,95 +201,137 @@ hauppauge_tuner[] =
200 { TUNER_ABSENT, "Philips FQ1286A MK4"}, 201 { TUNER_ABSENT, "Philips FQ1286A MK4"},
201 { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 202 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
202 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 203 { TUNER_ABSENT, "Philips FQ1236 MK5"},
203 { TUNER_ABSENT, "Unspecified"}, 204 { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
204 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, 205 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
205 { TUNER_ABSENT, "Unspecified"}, 206 { TUNER_ABSENT, "TCL 2002MI_3H"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"}, 207 { TUNER_TCL_2002N, "TCL 2002N 5H"},
207 /* 100-103 */ 208 /* 100-109 */
208 { TUNER_ABSENT, "Unspecified"}, 209 { TUNER_ABSENT, "Philips FMD1216ME"},
209 { TUNER_TEA5767, "Philips TEA5767HN FM Radio"}, 210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
210 { TUNER_ABSENT, "Unspecified"}, 211 { TUNER_ABSENT, "Panasonic ENV57H12D5"},
211 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"}, 212 { TUNER_ABSENT, "TCL MFNM05-4"},
213 { TUNER_ABSENT, "TCL MNM05-4"},
214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
215 { TUNER_ABSENT, "TCL MQNM05-4"},
216 { TUNER_ABSENT, "LG TAPC-W701D"},
217 { TUNER_ABSENT, "TCL 9886P-WM"},
218 { TUNER_ABSENT, "TCL 1676NM-WM"},
212}; 219};
213 220
214/* This list is supplied by Hauppauge. Thanks! */ 221static struct HAUPPAUGE_AUDIOIC
215static const char *audioIC[] = { 222{
216 /* 0-4 */ 223 enum audiochip id;
217 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", 224 char *name;
218 /* 5-9 */ 225}
219 "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331", 226audioIC[] =
220 /* 10-14 */ 227{
221 "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416", 228 /* 0-4 */
222 /* 15-19 */ 229 {AUDIO_CHIP_NONE, "None"},
223 "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716", 230 {AUDIO_CHIP_TEA6300, "TEA6300"},
224 /* 20-24 */ 231 {AUDIO_CHIP_TEA6300, "TEA6320"},
225 "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408", 232 {AUDIO_CHIP_TDA985X, "TDA9850"},
226 /* 25-29 */ 233 {AUDIO_CHIP_MSP34XX, "MSP3400C"},
227 "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d", 234 /* 5-9 */
228 /* 30-34 */ 235 {AUDIO_CHIP_MSP34XX, "MSP3410D"},
229 "CX880", "CX881", "CX883", "CX882", "CX25840", 236 {AUDIO_CHIP_MSP34XX, "MSP3415"},
230 /* 35-38 */ 237 {AUDIO_CHIP_MSP34XX, "MSP3430"},
231 "CX25841", "CX25842", "CX25843", "CX23418", 238 {AUDIO_CHIP_UNKNOWN, "MSP3438"},
239 {AUDIO_CHIP_UNKNOWN, "CS5331"},
240 /* 10-14 */
241 {AUDIO_CHIP_MSP34XX, "MSP3435"},
242 {AUDIO_CHIP_MSP34XX, "MSP3440"},
243 {AUDIO_CHIP_MSP34XX, "MSP3445"},
244 {AUDIO_CHIP_UNKNOWN, "MSP3411"},
245 {AUDIO_CHIP_UNKNOWN, "MSP3416"},
246 /* 15-19 */
247 {AUDIO_CHIP_MSP34XX, "MSP3425"},
248 {AUDIO_CHIP_UNKNOWN, "MSP3451"},
249 {AUDIO_CHIP_UNKNOWN, "MSP3418"},
250 {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
251 {AUDIO_CHIP_UNKNOWN, "OKI7716"},
252 /* 20-24 */
253 {AUDIO_CHIP_UNKNOWN, "MSP4410"},
254 {AUDIO_CHIP_UNKNOWN, "MSP4420"},
255 {AUDIO_CHIP_UNKNOWN, "MSP4440"},
256 {AUDIO_CHIP_UNKNOWN, "MSP4450"},
257 {AUDIO_CHIP_UNKNOWN, "MSP4408"},
258 /* 25-29 */
259 {AUDIO_CHIP_UNKNOWN, "MSP4418"},
260 {AUDIO_CHIP_UNKNOWN, "MSP4428"},
261 {AUDIO_CHIP_UNKNOWN, "MSP4448"},
262 {AUDIO_CHIP_UNKNOWN, "MSP4458"},
263 {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
264 /* 30-34 */
265 {AUDIO_CHIP_INTERNAL, "CX880"},
266 {AUDIO_CHIP_INTERNAL, "CX881"},
267 {AUDIO_CHIP_INTERNAL, "CX883"},
268 {AUDIO_CHIP_INTERNAL, "CX882"},
269 {AUDIO_CHIP_INTERNAL, "CX25840"},
270 /* 35-38 */
271 {AUDIO_CHIP_INTERNAL, "CX25841"},
272 {AUDIO_CHIP_INTERNAL, "CX25842"},
273 {AUDIO_CHIP_INTERNAL, "CX25843"},
274 {AUDIO_CHIP_INTERNAL, "CX23418"},
232}; 275};
233 276
234/* This list is supplied by Hauppauge. Thanks! */ 277/* This list is supplied by Hauppauge. Thanks! */
235static const char *decoderIC[] = { 278static const char *decoderIC[] = {
236 /* 0-4 */ 279 /* 0-4 */
237 "None", "BT815", "BT817", "BT819", "BT815A", 280 "None", "BT815", "BT817", "BT819", "BT815A",
238 /* 5-9 */ 281 /* 5-9 */
239 "BT817A", "BT819A", "BT827", "BT829", "BT848", 282 "BT817A", "BT819A", "BT827", "BT829", "BT848",
240 /* 10-14 */ 283 /* 10-14 */
241 "BT848A", "BT849A", "BT829A", "BT827A", "BT878", 284 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
242 /* 15-19 */ 285 /* 15-19 */
243 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", 286 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
244 /* 20-24 */ 287 /* 20-24 */
245 "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 288 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
246 /* 25-29 */ 289 /* 25-29 */
247 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 290 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
248 /* 30-31 */ 291 /* 30-31 */
249 "CX25843", "CX23418", 292 "CX25843", "CX23418",
250}; 293};
251 294
252static int hasRadioTuner(int tunerType) 295static int hasRadioTuner(int tunerType)
253{ 296{
254 switch (tunerType) { 297 switch (tunerType) {
255 case 18: //PNPEnv_TUNER_FR1236_MK2: 298 case 18: //PNPEnv_TUNER_FR1236_MK2:
256 case 23: //PNPEnv_TUNER_FM1236: 299 case 23: //PNPEnv_TUNER_FM1236:
257 case 38: //PNPEnv_TUNER_FMR1236: 300 case 38: //PNPEnv_TUNER_FMR1236:
258 case 16: //PNPEnv_TUNER_FR1216_MK2: 301 case 16: //PNPEnv_TUNER_FR1216_MK2:
259 case 19: //PNPEnv_TUNER_FR1246_MK2: 302 case 19: //PNPEnv_TUNER_FR1246_MK2:
260 case 21: //PNPEnv_TUNER_FM1216: 303 case 21: //PNPEnv_TUNER_FM1216:
261 case 24: //PNPEnv_TUNER_FM1246: 304 case 24: //PNPEnv_TUNER_FM1246:
262 case 17: //PNPEnv_TUNER_FR1216MF_MK2: 305 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
263 case 22: //PNPEnv_TUNER_FM1216MF: 306 case 22: //PNPEnv_TUNER_FM1216MF:
264 case 20: //PNPEnv_TUNER_FR1256_MK2: 307 case 20: //PNPEnv_TUNER_FR1256_MK2:
265 case 25: //PNPEnv_TUNER_FM1256: 308 case 25: //PNPEnv_TUNER_FM1256:
266 case 33: //PNPEnv_TUNER_4039FR5: 309 case 33: //PNPEnv_TUNER_4039FR5:
267 case 42: //PNPEnv_TUNER_4009FR5: 310 case 42: //PNPEnv_TUNER_4009FR5:
268 case 52: //PNPEnv_TUNER_4049FM5: 311 case 52: //PNPEnv_TUNER_4049FM5:
269 case 54: //PNPEnv_TUNER_4049FM5_AltI2C: 312 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
270 case 44: //PNPEnv_TUNER_4009FN5: 313 case 44: //PNPEnv_TUNER_4009FN5:
271 case 31: //PNPEnv_TUNER_TCPB9085P: 314 case 31: //PNPEnv_TUNER_TCPB9085P:
272 case 30: //PNPEnv_TUNER_TCPN9085D: 315 case 30: //PNPEnv_TUNER_TCPN9085D:
273 case 46: //PNPEnv_TUNER_TP18NSR01F: 316 case 46: //PNPEnv_TUNER_TP18NSR01F:
274 case 47: //PNPEnv_TUNER_TP18PSB01D: 317 case 47: //PNPEnv_TUNER_TP18PSB01D:
275 case 49: //PNPEnv_TUNER_TAPC_I001D: 318 case 49: //PNPEnv_TUNER_TAPC_I001D:
276 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: 319 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
277 case 57: //PNPEnv_TUNER_FM1216ME_MK3: 320 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
278 case 59: //PNPEnv_TUNER_FM1216MP_MK3: 321 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
279 case 58: //PNPEnv_TUNER_FM1236_MK3: 322 case 58: //PNPEnv_TUNER_FM1236_MK3:
280 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: 323 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
281 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: 324 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
282 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: 325 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
283 case 89: //PNPEnv_TUNER_TCL_MFPE05_2: 326 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
284 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: 327 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
285 return 1; 328 return 1;
286 } 329 }
287 return 0; 330 return 0;
288} 331}
289 332
290void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, 333void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
291 unsigned char *eeprom_data) 334 unsigned char *eeprom_data)
292{ 335{
293 /* ---------------------------------------------- 336 /* ----------------------------------------------
294 ** The hauppauge eeprom format is tagged 337 ** The hauppauge eeprom format is tagged
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
312 ** # of inputs/outputs ??? 355 ** # of inputs/outputs ???
313 */ 356 */
314 357
315 int i, j, len, done, beenhere, tag; 358 int i, j, len, done, beenhere, tag,start;
316 359
317 int tuner1 = 0, t_format1 = 0; 360 int tuner1 = 0, t_format1 = 0, audioic=-1;
318 char *t_name1 = NULL; 361 char *t_name1 = NULL;
319 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; 362 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
320 363
321 int tuner2 = 0, t_format2 = 0; 364 int tuner2 = 0, t_format2 = 0;
322 char *t_name2 = NULL; 365 char *t_name2 = NULL;
323 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; 366 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
324 367
325 memset(tvee, 0, sizeof(*tvee)); 368 memset(tvee, 0, sizeof(*tvee));
326 done = len = beenhere = 0; 369 done = len = beenhere = 0;
327 for (i = 0; !done && i < 256; i += len) { 370
371 /* Hack for processing eeprom for em28xx */
372 if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
373 (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
374 start=0xa0;
375 else
376 start=0;
377
378 for (i = start; !done && i < 256; i += len) {
328 if (eeprom_data[i] == 0x84) { 379 if (eeprom_data[i] == 0x84) {
329 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 380 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
330 i += 3; 381 i += 3;
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
338 ++i; 389 ++i;
339 } else { 390 } else {
340 tveeprom_warn("Encountered bad packet header [%02x]. " 391 tveeprom_warn("Encountered bad packet header [%02x]. "
341 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); 392 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
342 return; 393 return;
343 } 394 }
344 395
345 if (debug) { 396 if (debug) {
346 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); 397 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
347 for(j = 1; j < len; j++) { 398 for(j = 1; j < len; j++) {
348 printk(" %02x", eeprom_data[i + j]); 399 printk(" %02x", eeprom_data[i + j]);
349 } 400 }
350 printk("\n"); 401 printk("\n");
351 } 402 }
352 403
353 /* process by tag */ 404 /* process by tag */
354 tag = eeprom_data[i]; 405 tag = eeprom_data[i];
355 switch (tag) { 406 switch (tag) {
356 case 0x00: 407 case 0x00:
357 /* tag: 'Comprehensive' */ 408 /* tag: 'Comprehensive' */
358 tuner1 = eeprom_data[i+6]; 409 tuner1 = eeprom_data[i+6];
359 t_format1 = eeprom_data[i+5]; 410 t_format1 = eeprom_data[i+5];
360 tvee->has_radio = eeprom_data[i+len-1]; 411 tvee->has_radio = eeprom_data[i+len-1];
361 /* old style tag, don't know how to detect 412 /* old style tag, don't know how to detect
362 IR presence, mark as unknown. */ 413 IR presence, mark as unknown. */
363 tvee->has_ir = 2; 414 tvee->has_ir = 2;
364 tvee->model = 415 tvee->model =
365 eeprom_data[i+8] + 416 eeprom_data[i+8] +
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
370 break; 421 break;
371 422
372 case 0x01: 423 case 0x01:
373 /* tag: 'SerialID' */ 424 /* tag: 'SerialID' */
374 tvee->serial_number = 425 tvee->serial_number =
375 eeprom_data[i+6] + 426 eeprom_data[i+6] +
376 (eeprom_data[i+7] << 8) + 427 (eeprom_data[i+7] << 8) +
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
378 break; 429 break;
379 430
380 case 0x02: 431 case 0x02:
381 /* tag 'AudioInfo' 432 /* tag 'AudioInfo'
382 Note mask with 0x7F, high bit used on some older models 433 Note mask with 0x7F, high bit used on some older models
383 to indicate 4052 mux was removed in favor of using MSP 434 to indicate 4052 mux was removed in favor of using MSP
384 inputs directly. */ 435 inputs directly. */
385 tvee->audio_processor = eeprom_data[i+2] & 0x7f; 436 audioic = eeprom_data[i+2] & 0x7f;
437 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
438 tvee->audio_processor = audioIC[audioic].id;
439 else
440 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
386 break; 441 break;
387 442
388 /* case 0x03: tag 'EEInfo' */ 443 /* case 0x03: tag 'EEInfo' */
389 444
390 case 0x04: 445 case 0x04:
391 /* tag 'SerialID2' */ 446 /* tag 'SerialID2' */
392 tvee->serial_number = 447 tvee->serial_number =
393 eeprom_data[i+5] + 448 eeprom_data[i+5] +
394 (eeprom_data[i+6] << 8) + 449 (eeprom_data[i+6] << 8) +
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
396 break; 451 break;
397 452
398 case 0x05: 453 case 0x05:
399 /* tag 'Audio2' 454 /* tag 'Audio2'
400 Note mask with 0x7F, high bit used on some older models 455 Note mask with 0x7F, high bit used on some older models
401 to indicate 4052 mux was removed in favor of using MSP 456 to indicate 4052 mux was removed in favor of using MSP
402 inputs directly. */ 457 inputs directly. */
403 tvee->audio_processor = eeprom_data[i+1] & 0x7f; 458 audioic = eeprom_data[i+1] & 0x7f;
459 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
460 tvee->audio_processor = audioIC[audioic].id;
461 else
462 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
463
404 break; 464 break;
405 465
406 case 0x06: 466 case 0x06:
407 /* tag 'ModelRev' */ 467 /* tag 'ModelRev' */
408 tvee->model = 468 tvee->model =
409 eeprom_data[i+1] + 469 eeprom_data[i+1] +
410 (eeprom_data[i+2] << 8); 470 (eeprom_data[i+2] << 8);
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
414 break; 474 break;
415 475
416 case 0x07: 476 case 0x07:
417 /* tag 'Details': according to Hauppauge not interesting 477 /* tag 'Details': according to Hauppauge not interesting
418 on any PCI-era or later boards. */ 478 on any PCI-era or later boards. */
419 break; 479 break;
420 480
421 /* there is no tag 0x08 defined */ 481 /* there is no tag 0x08 defined */
422 482
423 case 0x09: 483 case 0x09:
424 /* tag 'Video' */ 484 /* tag 'Video' */
425 tvee->decoder_processor = eeprom_data[i + 1]; 485 tvee->decoder_processor = eeprom_data[i + 1];
426 break; 486 break;
427 487
428 case 0x0a: 488 case 0x0a:
429 /* tag 'Tuner' */ 489 /* tag 'Tuner' */
430 if (beenhere == 0) { 490 if (beenhere == 0) {
431 tuner1 = eeprom_data[i+2]; 491 tuner1 = eeprom_data[i+2];
432 t_format1 = eeprom_data[i+1]; 492 t_format1 = eeprom_data[i+1];
433 beenhere = 1; 493 beenhere = 1;
434 } else { 494 } else {
435 /* a second (radio) tuner may be present */ 495 /* a second (radio) tuner may be present */
436 tuner2 = eeprom_data[i+2]; 496 tuner2 = eeprom_data[i+2];
437 t_format2 = eeprom_data[i+1]; 497 t_format2 = eeprom_data[i+1];
438 if (t_format2 == 0) { /* not a TV tuner? */ 498 if (t_format2 == 0) { /* not a TV tuner? */
439 tvee->has_radio = 1; /* must be radio */ 499 tvee->has_radio = 1; /* must be radio */
440 } 500 }
441 } 501 }
442 break; 502 break;
443 503
444 case 0x0b: 504 case 0x0b:
445 /* tag 'Inputs': according to Hauppauge this is specific 505 /* tag 'Inputs': according to Hauppauge this is specific
446 to each driver family, so no good assumptions can be 506 to each driver family, so no good assumptions can be
447 made. */ 507 made. */
448 break; 508 break;
449 509
450 /* case 0x0c: tag 'Balun' */ 510 /* case 0x0c: tag 'Balun' */
451 /* case 0x0d: tag 'Teletext' */ 511 /* case 0x0d: tag 'Teletext' */
452 512
453 case 0x0e: 513 case 0x0e:
454 /* tag: 'Radio' */ 514 /* tag: 'Radio' */
455 tvee->has_radio = eeprom_data[i+1]; 515 tvee->has_radio = eeprom_data[i+1];
456 break; 516 break;
457 517
458 case 0x0f: 518 case 0x0f:
459 /* tag 'IRInfo' */ 519 /* tag 'IRInfo' */
460 tvee->has_ir = eeprom_data[i+1]; 520 tvee->has_ir = eeprom_data[i+1];
461 break; 521 break;
462 522
463 /* case 0x10: tag 'VBIInfo' */ 523 /* case 0x10: tag 'VBIInfo' */
464 /* case 0x11: tag 'QCInfo' */ 524 /* case 0x11: tag 'QCInfo' */
465 /* case 0x12: tag 'InfoBits' */ 525 /* case 0x12: tag 'InfoBits' */
466 526
467 default: 527 default:
468 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); 528 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
483 tvee->rev_str[4] = 0; 543 tvee->rev_str[4] = 0;
484 } 544 }
485 545
486 if (hasRadioTuner(tuner1) && !tvee->has_radio) { 546 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
487 tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); 547 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
488 tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); 548 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
489 tvee->has_radio = 1; 549 tvee->has_radio = 1;
490 } 550 }
491 551
492 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 552 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
493 tvee->tuner_type = hauppauge_tuner[tuner1].id; 553 tvee->tuner_type = hauppauge_tuner[tuner1].id;
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
510 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 570 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
511 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; 571 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
512 } 572 }
513 if (t_format2 & (1 << i)) { 573 if (t_format2 & (1 << i)) {
514 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; 574 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
515 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; 575 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
516 } 576 }
517 } 577 }
518 578
519 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 579 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
520 tvee->model, tvee->rev_str, tvee->serial_number); 580 tvee->model, tvee->rev_str, tvee->serial_number);
521 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 581 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
522 t_name1, tuner1, tvee->tuner_type); 582 t_name1, tuner1, tvee->tuner_type);
523 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 583 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
524 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], 584 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
525 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], 585 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
526 t_format1); 586 t_format1);
527 if (tuner2) { 587 if (tuner2) {
528 tveeprom_info("second tuner model is %s (idx %d, type %d)\n", 588 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
529 t_name2, tuner2, tvee->tuner2_type); 589 t_name2, tuner2, tvee->tuner2_type);
530 } 590 }
531 if (t_format2) { 591 if (t_format2) {
532 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 592 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
533 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], 593 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
534 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], 594 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
535 t_format2); 595 t_format2);
536 } 596 }
537 tveeprom_info("audio processor is %s (idx %d)\n", 597 if (audioic<0) {
538 STRM(audioIC, tvee->audio_processor), 598 tveeprom_info("audio processor is unknown (no idx)\n");
539 tvee->audio_processor); 599 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
540 if (tvee->decoder_processor) { 600 } else {
541 tveeprom_info("decoder processor is %s (idx %d)\n", 601 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
542 STRM(decoderIC, tvee->decoder_processor), 602 tveeprom_info("audio processor is %s (idx %d)\n",
543 tvee->decoder_processor); 603 audioIC[audioic].name,audioic);
544 } 604 else
545 if (tvee->has_ir == 2) 605 tveeprom_info("audio processor is unknown (idx %d)\n",
546 tveeprom_info("has %sradio\n", 606 audioic);
547 tvee->has_radio ? "" : "no "); 607 }
548 else 608 if (tvee->decoder_processor) {
549 tveeprom_info("has %sradio, has %sIR remote\n", 609 tveeprom_info("decoder processor is %s (idx %d)\n",
550 tvee->has_radio ? "" : "no ", 610 STRM(decoderIC, tvee->decoder_processor),
551 tvee->has_ir ? "" : "no "); 611 tvee->decoder_processor);
612 }
613 if (tvee->has_ir == 2)
614 tveeprom_info("has %sradio\n",
615 tvee->has_radio ? "" : "no ");
616 else
617 tveeprom_info("has %sradio, has %sIR remote\n",
618 tvee->has_radio ? "" : "no ",
619 tvee->has_ir ? "" : "no ");
552} 620}
553EXPORT_SYMBOL(tveeprom_hauppauge_analog); 621EXPORT_SYMBOL(tveeprom_hauppauge_analog);
554 622
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
569 tveeprom_warn("i2c eeprom read error (err=%d)\n", err); 637 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
570 return -1; 638 return -1;
571 } 639 }
572 if (debug) { 640 if (debug) {
573 int i; 641 int i;
574 642
575 tveeprom_info("full 256-byte eeprom dump:\n"); 643 tveeprom_info("full 256-byte eeprom dump:\n");
576 for (i = 0; i < len; i++) { 644 for (i = 0; i < len; i++) {
577 if (0 == (i % 16)) 645 if (0 == (i % 16))
578 tveeprom_info("%02x:", i); 646 tveeprom_info("%02x:", i);
579 printk(" %02x", eedata[i]); 647 printk(" %02x", eedata[i]);
580 if (15 == (i % 16)) 648 if (15 == (i % 16))
581 printk("\n"); 649 printk("\n");
582 } 650 }
583 } 651 }
584 return 0; 652 return 0;
585} 653}
586EXPORT_SYMBOL(tveeprom_read); 654EXPORT_SYMBOL(tveeprom_read);
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read);
590/* run, just call the exported tveeprom_* directly, there is no point in */ 658/* run, just call the exported tveeprom_* directly, there is no point in */
591/* using the indirect way via i2c_driver->command() */ 659/* using the indirect way via i2c_driver->command() */
592 660
593#ifndef I2C_DRIVERID_TVEEPROM
594# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
595#endif
596
597static unsigned short normal_i2c[] = { 661static unsigned short normal_i2c[] = {
598 0xa0 >> 1, 662 0xa0 >> 1,
599 I2C_CLIENT_END, 663 I2C_CLIENT_END,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index d86e08ebddfc..8318bd1aad00 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
79{ 79{
80 struct video_audio va; 80 struct video_audio va;
81 int left,right,ret,val = 0; 81 int left,right,ret,val = 0;
82 struct TVMIXER *mix = file->private_data; 82 struct TVMIXER *mix = file->private_data;
83 struct i2c_client *client = mix->dev; 83 struct i2c_client *client = mix->dev;
84 void __user *argp = (void __user *)arg; 84 void __user *argp = (void __user *)arg;
85 int __user *p = argp; 85 int __user *p = argp;
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
87 if (NULL == client) 87 if (NULL == client)
88 return -ENODEV; 88 return -ENODEV;
89 89
90 if (cmd == SOUND_MIXER_INFO) { 90 if (cmd == SOUND_MIXER_INFO) {
91 mixer_info info; 91 mixer_info info;
92 strlcpy(info.id, "tv card", sizeof(info.id)); 92 strlcpy(info.id, "tv card", sizeof(info.id));
93 strlcpy(info.name, client->name, sizeof(info.name)); 93 strlcpy(info.name, client->name, sizeof(info.name));
94 info.modify_counter = 42 /* FIXME */; 94 info.modify_counter = 42 /* FIXME */;
95 if (copy_to_user(argp, &info, sizeof(info))) 95 if (copy_to_user(argp, &info, sizeof(info)))
96 return -EFAULT; 96 return -EFAULT;
97 return 0; 97 return 0;
98 } 98 }
99 if (cmd == SOUND_OLD_MIXER_INFO) { 99 if (cmd == SOUND_OLD_MIXER_INFO) {
100 _old_mixer_info info; 100 _old_mixer_info info;
101 strlcpy(info.id, "tv card", sizeof(info.id)); 101 strlcpy(info.id, "tv card", sizeof(info.id));
102 strlcpy(info.name, client->name, sizeof(info.name)); 102 strlcpy(info.name, client->name, sizeof(info.name));
103 if (copy_to_user(argp, &info, sizeof(info))) 103 if (copy_to_user(argp, &info, sizeof(info)))
104 return -EFAULT; 104 return -EFAULT;
105 return 0; 105 return 0;
106 } 106 }
107 if (cmd == OSS_GETVERSION) 107 if (cmd == OSS_GETVERSION)
108 return put_user(SOUND_VERSION, p); 108 return put_user(SOUND_VERSION, p);
109 109
110 if (_SIOC_DIR(cmd) & _SIOC_WRITE) 110 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
111 if (get_user(val, p)) 111 if (get_user(val, p))
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
181 181
182static int tvmixer_open(struct inode *inode, struct file *file) 182static int tvmixer_open(struct inode *inode, struct file *file)
183{ 183{
184 int i, minor = iminor(inode); 184 int i, minor = iminor(inode);
185 struct TVMIXER *mix = NULL; 185 struct TVMIXER *mix = NULL;
186 struct i2c_client *client = NULL; 186 struct i2c_client *client = NULL;
187 187
188 for (i = 0; i < DEV_MAX; i++) { 188 for (i = 0; i < DEV_MAX; i++) {
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file)
204#endif 204#endif
205 if (client->adapter->owner) 205 if (client->adapter->owner)
206 try_module_get(client->adapter->owner); 206 try_module_get(client->adapter->owner);
207 return 0; 207 return 0;
208} 208}
209 209
210static int tvmixer_release(struct inode *inode, struct file *file) 210static int tvmixer_release(struct inode *inode, struct file *file)
@@ -231,15 +231,15 @@ static struct i2c_driver driver = {
231 .owner = THIS_MODULE, 231 .owner = THIS_MODULE,
232#endif 232#endif
233 .name = "tv card mixer driver", 233 .name = "tv card mixer driver",
234 .id = I2C_DRIVERID_TVMIXER, 234 .id = I2C_DRIVERID_TVMIXER,
235#ifdef I2C_DF_DUMMY 235#ifdef I2C_DF_DUMMY
236 .flags = I2C_DF_DUMMY, 236 .flags = I2C_DF_DUMMY,
237#else 237#else
238 .flags = I2C_DF_NOTIFY, 238 .flags = I2C_DF_NOTIFY,
239 .detach_adapter = tvmixer_adapters, 239 .detach_adapter = tvmixer_adapters,
240#endif 240#endif
241 .attach_adapter = tvmixer_adapters, 241 .attach_adapter = tvmixer_adapters,
242 .detach_client = tvmixer_clients, 242 .detach_client = tvmixer_clients,
243}; 243};
244 244
245static struct file_operations tvmixer_fops = { 245static struct file_operations tvmixer_fops = {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
new file mode 100644
index 000000000000..81e6d4494e7d
--- /dev/null
+++ b/drivers/media/video/tvp5150.c
@@ -0,0 +1,829 @@
1/*
2 * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
3 *
4 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
5 * This code is placed under the terms of the GNU General Public License
6 */
7
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/delay.h>
11#include <linux/video_decoder.h>
12
13#include "tvp5150_reg.h"
14
15MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
16MODULE_AUTHOR("Mauro Carvalho Chehab");
17MODULE_LICENSE("GPL");
18
19static unsigned short normal_i2c[] = {
20 0xb8 >> 1,
21 0xba >> 1,
22 I2C_CLIENT_END
23};
24
25I2C_CLIENT_INSMOD;
26
27static int debug = 0;
28module_param(debug, int, 0);
29MODULE_PARM_DESC(debug, "Debug level (0-1)");
30
31#define dprintk(num, format, args...) \
32 do { \
33 if (debug >= num) \
34 printk(format , ##args); \
35 } while (0)
36
37/* supported controls */
38static struct v4l2_queryctrl tvp5150_qctrl[] = {
39 {
40 .id = V4L2_CID_BRIGHTNESS,
41 .type = V4L2_CTRL_TYPE_INTEGER,
42 .name = "Brightness",
43 .minimum = 0,
44 .maximum = 255,
45 .step = 1,
46 .default_value = 0,
47 .flags = 0,
48 }, {
49 .id = V4L2_CID_CONTRAST,
50 .type = V4L2_CTRL_TYPE_INTEGER,
51 .name = "Contrast",
52 .minimum = 0,
53 .maximum = 255,
54 .step = 0x1,
55 .default_value = 0x10,
56 .flags = 0,
57 }, {
58 .id = V4L2_CID_SATURATION,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Saturation",
61 .minimum = 0,
62 .maximum = 255,
63 .step = 0x1,
64 .default_value = 0x10,
65 .flags = 0,
66 }, {
67 .id = V4L2_CID_HUE,
68 .type = V4L2_CTRL_TYPE_INTEGER,
69 .name = "Hue",
70 .minimum = -128,
71 .maximum = 127,
72 .step = 0x1,
73 .default_value = 0x10,
74 .flags = 0,
75 }
76};
77
78struct tvp5150 {
79 struct i2c_client *client;
80
81 int norm;
82 int input;
83 int enable;
84 int bright;
85 int contrast;
86 int hue;
87 int sat;
88};
89
90static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
91{
92 unsigned char buffer[1];
93 int rc;
94
95 buffer[0] = addr;
96 if (1 != (rc = i2c_master_send(c, buffer, 1)))
97 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
98
99 msleep(10);
100
101 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
102 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
103
104 return (buffer[0]);
105}
106
107static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
108 unsigned char value)
109{
110 unsigned char buffer[2];
111 int rc;
112/* struct tvp5150 *core = i2c_get_clientdata(c); */
113
114 buffer[0] = addr;
115 buffer[1] = value;
116 dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
117 if (2 != (rc = i2c_master_send(c, buffer, 2)))
118 dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
119}
120
121static void dump_reg(struct i2c_client *c)
122{
123 printk("tvp5150: Video input source selection #1 = 0x%02x\n",
124 tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
125 printk("tvp5150: Analog channel controls = 0x%02x\n",
126 tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
127 printk("tvp5150: Operation mode controls = 0x%02x\n",
128 tvp5150_read(c, TVP5150_OP_MODE_CTL));
129 printk("tvp5150: Miscellaneous controls = 0x%02x\n",
130 tvp5150_read(c, TVP5150_MISC_CTL));
131 printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
132 tvp5150_read(c, TVP5150_AUTOSW_MSK));
133 printk("tvp5150: Color killer threshold control = 0x%02x\n",
134 tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
135 printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
136 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
137 printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
138 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
139 printk("tvp5150: Brightness control = 0x%02x\n",
140 tvp5150_read(c, TVP5150_BRIGHT_CTL));
141 printk("tvp5150: Color saturation control = 0x%02x\n",
142 tvp5150_read(c, TVP5150_SATURATION_CTL));
143 printk("tvp5150: Hue control = 0x%02x\n",
144 tvp5150_read(c, TVP5150_HUE_CTL));
145 printk("tvp5150: Contrast control = 0x%02x\n",
146 tvp5150_read(c, TVP5150_CONTRAST_CTL));
147 printk("tvp5150: Outputs and data rates select = 0x%02x\n",
148 tvp5150_read(c, TVP5150_DATA_RATE_SEL));
149 printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
150 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
151 printk("tvp5150: Configuration shared pins = 0x%02x\n",
152 tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
153 printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
154 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
155 printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
156 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
157 printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
158 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
159 printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
160 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
161 printk("tvp5150: Genlock/RTC = 0x%02x\n",
162 tvp5150_read(c, TVP5150_GENLOCK));
163 printk("tvp5150: Horizontal sync start = 0x%02x\n",
164 tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
165 printk("tvp5150: Vertical blanking start = 0x%02x\n",
166 tvp5150_read(c, TVP5150_VERT_BLANKING_START));
167 printk("tvp5150: Vertical blanking stop = 0x%02x\n",
168 tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
169 printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
170 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
171 printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
172 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
173 printk("tvp5150: Interrupt reset register B = 0x%02x\n",
174 tvp5150_read(c, TVP5150_INT_RESET_REG_B));
175 printk("tvp5150: Interrupt enable register B = 0x%02x\n",
176 tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
177 printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
178 tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
179 printk("tvp5150: Video standard = 0x%02x\n",
180 tvp5150_read(c, TVP5150_VIDEO_STD));
181 printk("tvp5150: Cb gain factor = 0x%02x\n",
182 tvp5150_read(c, TVP5150_CB_GAIN_FACT));
183 printk("tvp5150: Cr gain factor = 0x%02x\n",
184 tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
185 printk("tvp5150: Macrovision on counter = 0x%02x\n",
186 tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
187 printk("tvp5150: Macrovision off counter = 0x%02x\n",
188 tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
189 printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
190 tvp5150_read(c, TVP5150_REV_SELECT));
191 printk("tvp5150: MSB of device ID = 0x%02x\n",
192 tvp5150_read(c, TVP5150_MSB_DEV_ID));
193 printk("tvp5150: LSB of device ID = 0x%02x\n",
194 tvp5150_read(c, TVP5150_LSB_DEV_ID));
195 printk("tvp5150: ROM major version = 0x%02x\n",
196 tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
197 printk("tvp5150: ROM minor version = 0x%02x\n",
198 tvp5150_read(c, TVP5150_ROM_MINOR_VER));
199 printk("tvp5150: Vertical line count MSB = 0x%02x\n",
200 tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
201 printk("tvp5150: Vertical line count LSB = 0x%02x\n",
202 tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
203 printk("tvp5150: Interrupt status register B = 0x%02x\n",
204 tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
205 printk("tvp5150: Interrupt active register B = 0x%02x\n",
206 tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
207 printk("tvp5150: Status register #1 = 0x%02x\n",
208 tvp5150_read(c, TVP5150_STATUS_REG_1));
209 printk("tvp5150: Status register #2 = 0x%02x\n",
210 tvp5150_read(c, TVP5150_STATUS_REG_2));
211 printk("tvp5150: Status register #3 = 0x%02x\n",
212 tvp5150_read(c, TVP5150_STATUS_REG_3));
213 printk("tvp5150: Status register #4 = 0x%02x\n",
214 tvp5150_read(c, TVP5150_STATUS_REG_4));
215 printk("tvp5150: Status register #5 = 0x%02x\n",
216 tvp5150_read(c, TVP5150_STATUS_REG_5));
217 printk("tvp5150: Closed caption data registers = 0x%02x\n",
218 tvp5150_read(c, TVP5150_CC_DATA_REG1));
219 printk("tvp5150: Closed caption data registers = 0x%02x\n",
220 tvp5150_read(c, TVP5150_CC_DATA_REG2));
221 printk("tvp5150: Closed caption data registers = 0x%02x\n",
222 tvp5150_read(c, TVP5150_CC_DATA_REG3));
223 printk("tvp5150: Closed caption data registers = 0x%02x\n",
224 tvp5150_read(c, TVP5150_CC_DATA_REG4));
225 printk("tvp5150: WSS data registers = 0x%02x\n",
226 tvp5150_read(c, TVP5150_WSS_DATA_REG1));
227 printk("tvp5150: WSS data registers = 0x%02x\n",
228 tvp5150_read(c, TVP5150_WSS_DATA_REG2));
229 printk("tvp5150: WSS data registers = 0x%02x\n",
230 tvp5150_read(c, TVP5150_WSS_DATA_REG3));
231 printk("tvp5150: WSS data registers = 0x%02x\n",
232 tvp5150_read(c, TVP5150_WSS_DATA_REG4));
233 printk("tvp5150: WSS data registers = 0x%02x\n",
234 tvp5150_read(c, TVP5150_WSS_DATA_REG5));
235 printk("tvp5150: WSS data registers = 0x%02x\n",
236 tvp5150_read(c, TVP5150_WSS_DATA_REG6));
237 printk("tvp5150: VPS data registers = 0x%02x\n",
238 tvp5150_read(c, TVP5150_VPS_DATA_REG1));
239 printk("tvp5150: VPS data registers = 0x%02x\n",
240 tvp5150_read(c, TVP5150_VPS_DATA_REG2));
241 printk("tvp5150: VPS data registers = 0x%02x\n",
242 tvp5150_read(c, TVP5150_VPS_DATA_REG3));
243 printk("tvp5150: VPS data registers = 0x%02x\n",
244 tvp5150_read(c, TVP5150_VPS_DATA_REG4));
245 printk("tvp5150: VPS data registers = 0x%02x\n",
246 tvp5150_read(c, TVP5150_VPS_DATA_REG5));
247 printk("tvp5150: VPS data registers = 0x%02x\n",
248 tvp5150_read(c, TVP5150_VPS_DATA_REG6));
249 printk("tvp5150: VPS data registers = 0x%02x\n",
250 tvp5150_read(c, TVP5150_VPS_DATA_REG7));
251 printk("tvp5150: VPS data registers = 0x%02x\n",
252 tvp5150_read(c, TVP5150_VPS_DATA_REG8));
253 printk("tvp5150: VPS data registers = 0x%02x\n",
254 tvp5150_read(c, TVP5150_VPS_DATA_REG9));
255 printk("tvp5150: VPS data registers = 0x%02x\n",
256 tvp5150_read(c, TVP5150_VPS_DATA_REG10));
257 printk("tvp5150: VPS data registers = 0x%02x\n",
258 tvp5150_read(c, TVP5150_VPS_DATA_REG11));
259 printk("tvp5150: VPS data registers = 0x%02x\n",
260 tvp5150_read(c, TVP5150_VPS_DATA_REG12));
261 printk("tvp5150: VPS data registers = 0x%02x\n",
262 tvp5150_read(c, TVP5150_VPS_DATA_REG13));
263 printk("tvp5150: VITC data registers = 0x%02x\n",
264 tvp5150_read(c, TVP5150_VITC_DATA_REG1));
265 printk("tvp5150: VITC data registers = 0x%02x\n",
266 tvp5150_read(c, TVP5150_VITC_DATA_REG2));
267 printk("tvp5150: VITC data registers = 0x%02x\n",
268 tvp5150_read(c, TVP5150_VITC_DATA_REG3));
269 printk("tvp5150: VITC data registers = 0x%02x\n",
270 tvp5150_read(c, TVP5150_VITC_DATA_REG4));
271 printk("tvp5150: VITC data registers = 0x%02x\n",
272 tvp5150_read(c, TVP5150_VITC_DATA_REG5));
273 printk("tvp5150: VITC data registers = 0x%02x\n",
274 tvp5150_read(c, TVP5150_VITC_DATA_REG6));
275 printk("tvp5150: VITC data registers = 0x%02x\n",
276 tvp5150_read(c, TVP5150_VITC_DATA_REG7));
277 printk("tvp5150: VITC data registers = 0x%02x\n",
278 tvp5150_read(c, TVP5150_VITC_DATA_REG8));
279 printk("tvp5150: VITC data registers = 0x%02x\n",
280 tvp5150_read(c, TVP5150_VITC_DATA_REG9));
281 printk("tvp5150: VBI FIFO read data = 0x%02x\n",
282 tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
283 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
284 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
285 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
286 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
287 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
288 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
289 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
290 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
291 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
292 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
293 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
294 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
295 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
296 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
297 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
298 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
299 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
300 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
301 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
302 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
303 printk("tvp5150: Teletext filter enable = 0x%02x\n",
304 tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
305 printk("tvp5150: Interrupt status register A = 0x%02x\n",
306 tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
307 printk("tvp5150: Interrupt enable register A = 0x%02x\n",
308 tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
309 printk("tvp5150: Interrupt configuration = 0x%02x\n",
310 tvp5150_read(c, TVP5150_INT_CONF));
311 printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
312 tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
313 printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
314 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
315 printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
316 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
317 printk("tvp5150: VDP status register = 0x%02x\n",
318 tvp5150_read(c, TVP5150_VDP_STATUS_REG));
319 printk("tvp5150: FIFO word count = 0x%02x\n",
320 tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
321 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
322 tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
323 printk("tvp5150: FIFO reset = 0x%02x\n",
324 tvp5150_read(c, TVP5150_FIFO_RESET));
325 printk("tvp5150: Line number interrupt = 0x%02x\n",
326 tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
327 printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
328 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
329 printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
330 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
331 printk("tvp5150: FIFO output control = 0x%02x\n",
332 tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
333 printk("tvp5150: Full field enable 1 = 0x%02x\n",
334 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
335 printk("tvp5150: Full field enable 2 = 0x%02x\n",
336 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
337 printk("tvp5150: Line mode registers = 0x%02x\n",
338 tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
339 printk("tvp5150: Line mode registers = 0x%02x\n",
340 tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
341 printk("tvp5150: Line mode registers = 0x%02x\n",
342 tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
343 printk("tvp5150: Line mode registers = 0x%02x\n",
344 tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
345 printk("tvp5150: Line mode registers = 0x%02x\n",
346 tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
347 printk("tvp5150: Line mode registers = 0x%02x\n",
348 tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
349 printk("tvp5150: Line mode registers = 0x%02x\n",
350 tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
351 printk("tvp5150: Line mode registers = 0x%02x\n",
352 tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
353 printk("tvp5150: Line mode registers = 0x%02x\n",
354 tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
355 printk("tvp5150: Line mode registers = 0x%02x\n",
356 tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
357 printk("tvp5150: Line mode registers = 0x%02x\n",
358 tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
359 printk("tvp5150: Line mode registers = 0x%02x\n",
360 tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
361 printk("tvp5150: Line mode registers = 0x%02x\n",
362 tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
363 printk("tvp5150: Line mode registers = 0x%02x\n",
364 tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
365 printk("tvp5150: Line mode registers = 0x%02x\n",
366 tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
367 printk("tvp5150: Line mode registers = 0x%02x\n",
368 tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
369 printk("tvp5150: Line mode registers = 0x%02x\n",
370 tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
371 printk("tvp5150: Line mode registers = 0x%02x\n",
372 tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
373 printk("tvp5150: Line mode registers = 0x%02x\n",
374 tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
375 printk("tvp5150: Line mode registers = 0x%02x\n",
376 tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
377 printk("tvp5150: Line mode registers = 0x%02x\n",
378 tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
379 printk("tvp5150: Line mode registers = 0x%02x\n",
380 tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
381 printk("tvp5150: Line mode registers = 0x%02x\n",
382 tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
383 printk("tvp5150: Line mode registers = 0x%02x\n",
384 tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
385 printk("tvp5150: Line mode registers = 0x%02x\n",
386 tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
387 printk("tvp5150: Line mode registers = 0x%02x\n",
388 tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
389 printk("tvp5150: Line mode registers = 0x%02x\n",
390 tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
391 printk("tvp5150: Line mode registers = 0x%02x\n",
392 tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
393 printk("tvp5150: Line mode registers = 0x%02x\n",
394 tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
395 printk("tvp5150: Line mode registers = 0x%02x\n",
396 tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
397 printk("tvp5150: Line mode registers = 0x%02x\n",
398 tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
399 printk("tvp5150: Line mode registers = 0x%02x\n",
400 tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
401 printk("tvp5150: Line mode registers = 0x%02x\n",
402 tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
403 printk("tvp5150: Line mode registers = 0x%02x\n",
404 tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
405 printk("tvp5150: Line mode registers = 0x%02x\n",
406 tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
407 printk("tvp5150: Line mode registers = 0x%02x\n",
408 tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
409 printk("tvp5150: Line mode registers = 0x%02x\n",
410 tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
411 printk("tvp5150: Line mode registers = 0x%02x\n",
412 tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
413 printk("tvp5150: Line mode registers = 0x%02x\n",
414 tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
415 printk("tvp5150: Line mode registers = 0x%02x\n",
416 tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
417 printk("tvp5150: Line mode registers = 0x%02x\n",
418 tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
419 printk("tvp5150: Line mode registers = 0x%02x\n",
420 tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
421 printk("tvp5150: Line mode registers = 0x%02x\n",
422 tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
423 printk("tvp5150: Full field mode register = 0x%02x\n",
424 tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
425}
426
427/****************************************************************************
428 Basic functions
429 ****************************************************************************/
430enum tvp5150_input {
431 TVP5150_ANALOG_CH0 = 0,
432 TVP5150_SVIDEO = 1,
433 TVP5150_ANALOG_CH1 = 2,
434 TVP5150_BLACK_SCREEN = 8
435};
436
437static inline void tvp5150_selmux(struct i2c_client *c,
438 enum tvp5150_input input)
439{
440 struct tvp5150 *decoder = i2c_get_clientdata(c);
441
442 if (!decoder->enable)
443 input |= TVP5150_BLACK_SCREEN;
444
445 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
446};
447
448static inline void tvp5150_reset(struct i2c_client *c)
449{
450 struct tvp5150 *decoder = i2c_get_clientdata(c);
451
452 tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
453
454 /* Automatic offset and AGC enabled */
455 tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
456
457 /* Normal Operation */
458// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
459
460 /* Activate YCrCb output 0x9 or 0xd ? */
461 tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
462
463 /* Activates video std autodetection for all standards */
464 tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
465
466 /* Default format: 0x47, 4:2:2: 0x40 */
467 tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
468
469 tvp5150_selmux(c, decoder->input);
470
471 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
472 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
473
474 tvp5150_write(c, 0x27, 0x20); /* ?????????? */
475
476 tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */
477
478 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
479 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
480 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
481 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
482};
483
484static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
485{
486/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
487
488 switch (ctrl->id) {
489 case V4L2_CID_BRIGHTNESS:
490 ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL);
491 return 0;
492 case V4L2_CID_CONTRAST:
493 ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL);
494 return 0;
495 case V4L2_CID_SATURATION:
496 ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL);
497 return 0;
498 case V4L2_CID_HUE:
499 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
500 return 0;
501 default:
502 return -EINVAL;
503 }
504}
505
506static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
507{
508/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
509
510 switch (ctrl->id) {
511 case V4L2_CID_BRIGHTNESS:
512 tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
513 return 0;
514 case V4L2_CID_CONTRAST:
515 tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
516 return 0;
517 case V4L2_CID_SATURATION:
518 tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
519 return 0;
520 case V4L2_CID_HUE:
521 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
522 return 0;
523 default:
524 return -EINVAL;
525 }
526}
527
528/****************************************************************************
529 I2C Command
530 ****************************************************************************/
531static int tvp5150_command(struct i2c_client *client,
532 unsigned int cmd, void *arg)
533{
534 struct tvp5150 *decoder = i2c_get_clientdata(client);
535
536 switch (cmd) {
537
538 case 0:
539 case DECODER_INIT:
540 tvp5150_reset(client);
541 break;
542
543 case DECODER_DUMP:
544 dump_reg(client);
545 break;
546
547 case DECODER_GET_CAPABILITIES:
548 {
549 struct video_decoder_capability *cap = arg;
550
551 cap->flags = VIDEO_DECODER_PAL |
552 VIDEO_DECODER_NTSC |
553 VIDEO_DECODER_SECAM |
554 VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
555 cap->inputs = 3;
556 cap->outputs = 1;
557 break;
558 }
559 case DECODER_GET_STATUS:
560 {
561 break;
562 }
563
564 case DECODER_SET_GPIO:
565 break;
566
567 case DECODER_SET_VBI_BYPASS:
568 break;
569
570 case DECODER_SET_NORM:
571 {
572 int *iarg = arg;
573
574 switch (*iarg) {
575
576 case VIDEO_MODE_NTSC:
577 break;
578
579 case VIDEO_MODE_PAL:
580 break;
581
582 case VIDEO_MODE_SECAM:
583 break;
584
585 case VIDEO_MODE_AUTO:
586 break;
587
588 default:
589 return -EINVAL;
590
591 }
592 decoder->norm = *iarg;
593 break;
594 }
595 case DECODER_SET_INPUT:
596 {
597 int *iarg = arg;
598 if (*iarg < 0 || *iarg > 3) {
599 return -EINVAL;
600 }
601
602 decoder->input = *iarg;
603 tvp5150_selmux(client, decoder->input);
604
605 break;
606 }
607 case DECODER_SET_OUTPUT:
608 {
609 int *iarg = arg;
610
611 /* not much choice of outputs */
612 if (*iarg != 0) {
613 return -EINVAL;
614 }
615 break;
616 }
617 case DECODER_ENABLE_OUTPUT:
618 {
619 int *iarg = arg;
620
621 decoder->enable = (*iarg != 0);
622
623 tvp5150_selmux(client, decoder->input);
624
625 break;
626 }
627 case VIDIOC_QUERYCTRL:
628 {
629 struct v4l2_queryctrl *qc = arg;
630 u8 i, n;
631
632 dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
633
634 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
635 for (i = 0; i < n; i++)
636 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
637 memcpy(qc, &(tvp5150_qctrl[i]),
638 sizeof(*qc));
639 return 0;
640 }
641
642 return -EINVAL;
643 }
644 case VIDIOC_G_CTRL:
645 {
646 struct v4l2_control *ctrl = arg;
647 dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
648
649 return tvp5150_get_ctrl(client, ctrl);
650 }
651 case VIDIOC_S_CTRL_OLD: /* ??? */
652 case VIDIOC_S_CTRL:
653 {
654 struct v4l2_control *ctrl = arg;
655 u8 i, n;
656 dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
657 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
658 for (i = 0; i < n; i++)
659 if (ctrl->id == tvp5150_qctrl[i].id) {
660 if (ctrl->value <
661 tvp5150_qctrl[i].minimum
662 || ctrl->value >
663 tvp5150_qctrl[i].maximum)
664 return -ERANGE;
665 dprintk(1,
666 KERN_DEBUG
667 "VIDIOC_S_CTRL: id=%d, value=%d",
668 ctrl->id, ctrl->value);
669 return tvp5150_set_ctrl(client, ctrl);
670 }
671 return -EINVAL;
672 }
673
674 case DECODER_SET_PICTURE:
675 {
676 struct video_picture *pic = arg;
677 if (decoder->bright != pic->brightness) {
678 /* We want 0 to 255 we get 0-65535 */
679 decoder->bright = pic->brightness;
680 tvp5150_write(client, TVP5150_BRIGHT_CTL,
681 decoder->bright >> 8);
682 }
683 if (decoder->contrast != pic->contrast) {
684 /* We want 0 to 255 we get 0-65535 */
685 decoder->contrast = pic->contrast;
686 tvp5150_write(client, TVP5150_CONTRAST_CTL,
687 decoder->contrast >> 8);
688 }
689 if (decoder->sat != pic->colour) {
690 /* We want 0 to 255 we get 0-65535 */
691 decoder->sat = pic->colour;
692 tvp5150_write(client, TVP5150_SATURATION_CTL,
693 decoder->contrast >> 8);
694 }
695 if (decoder->hue != pic->hue) {
696 /* We want -128 to 127 we get 0-65535 */
697 decoder->hue = pic->hue;
698 tvp5150_write(client, TVP5150_HUE_CTL,
699 (decoder->hue - 32768) >> 8);
700 }
701 break;
702 }
703 default:
704 return -EINVAL;
705 }
706
707 return 0;
708}
709
710/****************************************************************************
711 I2C Client & Driver
712 ****************************************************************************/
713static struct i2c_driver driver;
714
715static struct i2c_client client_template = {
716 .name = "(unset)",
717 .flags = I2C_CLIENT_ALLOW_USE,
718 .driver = &driver,
719};
720
721static int tvp5150_detect_client(struct i2c_adapter *adapter,
722 int address, int kind)
723{
724 struct i2c_client *client;
725 struct tvp5150 *core;
726 int rv;
727
728 dprintk(1,
729 KERN_INFO
730 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
731 address << 1);
732
733 client_template.adapter = adapter;
734 client_template.addr = address;
735
736 /* Check if the adapter supports the needed features */
737 if (!i2c_check_functionality
738 (adapter,
739 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
740 return 0;
741
742 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
743 if (client == 0)
744 return -ENOMEM;
745 memcpy(client, &client_template, sizeof(struct i2c_client));
746
747 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
748 if (core == 0) {
749 kfree(client);
750 return -ENOMEM;
751 }
752 memset(core, 0, sizeof(struct tvp5150));
753 i2c_set_clientdata(client, core);
754
755 rv = i2c_attach_client(client);
756
757 core->norm = VIDEO_MODE_AUTO;
758 core->input = 2;
759 core->enable = 1;
760 core->bright = 32768;
761 core->contrast = 32768;
762 core->hue = 32768;
763 core->sat = 32768;
764
765 if (rv) {
766 kfree(client);
767 kfree(core);
768 return rv;
769 }
770
771 if (debug > 1)
772 dump_reg(client);
773
774 return 0;
775}
776
777static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
778{
779 dprintk(1,
780 KERN_INFO
781 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
782 adapter->name, adapter->id);
783 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
784}
785
786static int tvp5150_detach_client(struct i2c_client *client)
787{
788 struct tvp5150 *decoder = i2c_get_clientdata(client);
789 int err;
790
791 err = i2c_detach_client(client);
792 if (err) {
793 return err;
794 }
795
796 kfree(decoder);
797 kfree(client);
798
799 return 0;
800}
801
802/* ----------------------------------------------------------------------- */
803
804static struct i2c_driver driver = {
805 .owner = THIS_MODULE,
806 .name = "tvp5150",
807
808 /* FIXME */
809 .id = I2C_DRIVERID_SAA7110,
810 .flags = I2C_DF_NOTIFY,
811
812 .attach_adapter = tvp5150_attach_adapter,
813 .detach_client = tvp5150_detach_client,
814
815 .command = tvp5150_command,
816};
817
818static int __init tvp5150_init(void)
819{
820 return i2c_add_driver(&driver);
821}
822
823static void __exit tvp5150_exit(void)
824{
825 i2c_del_driver(&driver);
826}
827
828module_init(tvp5150_init);
829module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
new file mode 100644
index 000000000000..cd45c1ded786
--- /dev/null
+++ b/drivers/media/video/tvp5150_reg.h
@@ -0,0 +1,173 @@
1#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
2#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
3#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
4#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
5#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
6
7/* Reserved 05h */
8
9#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
10#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
11#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
12#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
13#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
14#define TVP5150_HUE_CTL 0x0b /* Hue control */
15#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
16#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
17#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
18#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
19
20/* Reserved 10h */
21
22#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
23#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
24#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
25#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
26#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
27#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
28
29/* Reserved 17h */
30
31#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
32#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
33#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
34#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
35#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
36#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
37#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
38
39/* Reserved 1Fh-27h */
40
41#define TVP5150_VIDEO_STD 0x28 /* Video standard */
42
43/* Reserved 29h-2bh */
44
45#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
46#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
47#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
48#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
49#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
50
51/* Reserved 31h-7Fh */
52
53#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
54#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
55#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
56#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
57#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
58#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
59#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
60#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
61#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
62#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
63#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
64#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
65#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
66/* Reserved 8Dh-8Fh */
67#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */
68#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */
69#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */
70#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */
71#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */
72#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */
73#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */
74#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */
75#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */
76#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */
77#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */
78#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */
79#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */
80#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */
81#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */
82#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */
83#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */
84#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */
85#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */
86#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */
87#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */
88#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */
89#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */
90#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */
91#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */
92#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */
93#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */
94#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */
95#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */
96#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */
97#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */
98#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */
99#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
100#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */
101#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */
102#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */
103#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */
104#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */
105#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */
106#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */
107#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */
108#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */
109#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */
110#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
111/* Reserved BCh-BFh */
112#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
113#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
114#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
115#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
116#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
117#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
118#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
119#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
120#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
121#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
122#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
123#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
124#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
125#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
126/* Reserved CEh */
127#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */
128#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */
129#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */
130#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */
131#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */
132#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */
133#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */
134#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */
135#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */
136#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */
137#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */
138#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */
139#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */
140#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */
141#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */
142#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */
143#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */
144#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */
145#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */
146#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */
147#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */
148#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */
149#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */
150#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */
151#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */
152#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */
153#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */
154#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */
155#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */
156#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */
157#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */
158#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */
159#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */
160#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */
161#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */
162#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */
163#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */
164#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */
165#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */
166#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */
167#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */
168#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */
169#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */
170#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */
171#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */
172#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
173/* Reserved FDh-FFh */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d679ca23ded7..4134549d11a8 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
708 } 708 }
709 case VIDIOCGFREQ: /* get frequency */ 709 case VIDIOCGFREQ: /* get frequency */
710 { 710 {
711 int *freq = arg; 711 unsigned long *freq = arg;
712 712
713 freq2.tuner = 0; 713 freq2.tuner = 0;
714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
720 } 720 }
721 case VIDIOCSFREQ: /* set frequency */ 721 case VIDIOCSFREQ: /* set frequency */
722 { 722 {
723 int *freq = arg; 723 unsigned long *freq = arg;
724 724
725 freq2.tuner = 0; 725 freq2.tuner = 0;
726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
960 fmt->start[1] = fmt2->fmt.vbi.start[1]; 960 fmt->start[1] = fmt2->fmt.vbi.start[1];
961 fmt->count[1] = fmt2->fmt.vbi.count[1]; 961 fmt->count[1] = fmt2->fmt.vbi.count[1];
962 fmt->flags = fmt2->fmt.vbi.flags & 0x03; 962 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
963 break; 963 break;
964 } 964 }
965 case VIDIOCSVBIFMT: 965 case VIDIOCSVBIFMT:
966 { 966 {
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 574b8e36f3c6..acfd3a103f35 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
147 data,size,dma->nr_pages); 147 data,size,dma->nr_pages);
148 148
149 down_read(&current->mm->mmap_sem); 149 down_read(&current->mm->mmap_sem);
150 err = get_user_pages(current,current->mm, 150 err = get_user_pages(current,current->mm,
151 data & PAGE_MASK, dma->nr_pages, 151 data & PAGE_MASK, dma->nr_pages,
152 rw == READ, 1, /* force */ 152 rw == READ, 1, /* force */
153 dma->pages, NULL); 153 dma->pages, NULL);
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750{ 750{
751 enum v4l2_field field; 751 enum v4l2_field field;
752 unsigned long flags; 752 unsigned long flags;
753 int retval; 753 int retval;
754 754
755 /* setup stuff */ 755 /* setup stuff */
756 retval = -ENOMEM; 756 retval = -ENOMEM;
757 q->read_buf = videobuf_alloc(q->msize); 757 q->read_buf = videobuf_alloc(q->msize);
758 if (NULL == q->read_buf) 758 if (NULL == q->read_buf)
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
760 760
761 q->read_buf->memory = V4L2_MEMORY_USERPTR; 761 q->read_buf->memory = V4L2_MEMORY_USERPTR;
762 q->read_buf->baddr = (unsigned long)data; 762 q->read_buf->baddr = (unsigned long)data;
763 q->read_buf->bsize = count; 763 q->read_buf->bsize = count;
764 field = videobuf_next_field(q); 764 field = videobuf_next_field(q);
765 retval = q->ops->buf_prepare(q,q->read_buf,field); 765 retval = q->ops->buf_prepare(q,q->read_buf,field);
766 if (0 != retval) 766 if (0 != retval)
767 goto done; 767 goto done;
768 768
769 /* start capture & wait */ 769 /* start capture & wait */
770 spin_lock_irqsave(q->irqlock,flags); 770 spin_lock_irqsave(q->irqlock,flags);
771 q->ops->buf_queue(q,q->read_buf); 771 q->ops->buf_queue(q,q->read_buf);
772 spin_unlock_irqrestore(q->irqlock,flags); 772 spin_unlock_irqrestore(q->irqlock,flags);
773 retval = videobuf_waiton(q->read_buf,0,0); 773 retval = videobuf_waiton(q->read_buf,0,0);
774 if (0 == retval) { 774 if (0 == retval) {
775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
776 if (STATE_ERROR == q->read_buf->state) 776 if (STATE_ERROR == q->read_buf->state)
777 retval = -EIO; 777 retval = -EIO;
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
828 } 828 }
829 829
830 /* wait until capture is done */ 830 /* wait until capture is done */
831 retval = videobuf_waiton(q->read_buf, nonblocking, 1); 831 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
832 if (0 != retval) 832 if (0 != retval)
833 goto done; 833 goto done;
834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1096 1096
1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", 1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1098 vaddr,vma->vm_start,vma->vm_end); 1098 vaddr,vma->vm_start,vma->vm_end);
1099 if (vaddr > vma->vm_end) 1099 if (vaddr > vma->vm_end)
1100 return NOPAGE_SIGBUS; 1100 return NOPAGE_SIGBUS;
1101 page = alloc_page(GFP_USER); 1101 page = alloc_page(GFP_USER);
1102 if (!page) 1102 if (!page)
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
new file mode 100644
index 000000000000..22f286222004
--- /dev/null
+++ b/drivers/media/video/wm8775.c
@@ -0,0 +1,254 @@
1/*
2 * wm8775 - driver version 0.0.1
3 *
4 * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
5 *
6 * Based on saa7115 driver
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/ioctl.h>
27#include <asm/uaccess.h>
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/videodev.h>
31#include <media/audiochip.h>
32
33MODULE_DESCRIPTION("wm8775 driver");
34MODULE_AUTHOR("Ulf Eklund");
35MODULE_LICENSE("GPL");
36
37#define wm8775_err(fmt, arg...) do { \
38 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
39 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
40#define wm8775_info(fmt, arg...) do { \
41 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
42 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
43
44
45static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
46
47
48I2C_CLIENT_INSMOD;
49
50/* ----------------------------------------------------------------------- */
51
52enum {
53 R7 = 7, R11 = 11,
54 R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
55 TOT_REGS
56};
57
58struct wm8775_state {
59 u8 input; /* Last selected input (0-0xf) */
60 u8 muted;
61};
62
63static int wm8775_write(struct i2c_client *client, int reg, u16 val)
64{
65 int i;
66
67 if (reg < 0 || reg >= TOT_REGS) {
68 wm8775_err("Invalid register R%d\n", reg);
69 return -1;
70 }
71
72 for (i = 0; i < 3; i++) {
73 if (i2c_smbus_write_byte_data(client, (reg << 1) |
74 (val >> 8), val & 0xff) == 0) {
75 return 0;
76 }
77 }
78 wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
79 return -1;
80}
81
82static int wm8775_command(struct i2c_client *client, unsigned int cmd,
83 void *arg)
84{
85 struct wm8775_state *state = i2c_get_clientdata(client);
86 int *input = arg;
87
88 switch (cmd) {
89 case AUDC_SET_INPUT:
90 wm8775_write(client, R21, 0x0c0);
91 wm8775_write(client, R14, 0x1d4);
92 wm8775_write(client, R15, 0x1d4);
93
94 if (*input == AUDIO_RADIO) {
95 wm8775_write(client, R21, 0x108);
96 state->input = 8;
97 state->muted = 0;
98 break;
99 }
100 if (*input == AUDIO_MUTE) {
101 state->muted = 1;
102 break;
103 }
104 if (*input == AUDIO_UNMUTE) {
105 wm8775_write(client, R21, 0x100 + state->input);
106 state->muted = 0;
107 break;
108 }
109 /* All other inputs... */
110 wm8775_write(client, R21, 0x102);
111 state->input = 2;
112 state->muted = 0;
113 break;
114
115 case VIDIOC_LOG_STATUS:
116 wm8775_info("Input: %s%s\n",
117 state->input == 8 ? "radio" : "default",
118 state->muted ? " (muted)" : "");
119 break;
120
121 case VIDIOC_S_FREQUENCY:
122 /* If I remove this, then it can happen that I have no
123 sound the first time I tune from static to a valid channel.
124 It's difficult to reproduce and is almost certainly related
125 to the zero cross detect circuit. */
126 wm8775_write(client, R21, 0x0c0);
127 wm8775_write(client, R14, 0x1d4);
128 wm8775_write(client, R15, 0x1d4);
129 wm8775_write(client, R21, 0x100 + state->input);
130 break;
131
132 default:
133 return -EINVAL;
134 }
135 return 0;
136}
137
138/* ----------------------------------------------------------------------- */
139
140/* i2c implementation */
141
142/*
143 * Generic i2c probe
144 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
145 */
146
147static struct i2c_driver i2c_driver;
148
149static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
150{
151 struct i2c_client *client;
152 struct wm8775_state *state;
153
154 /* Check if the adapter supports the needed features */
155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
156 return 0;
157
158 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
159 if (client == 0)
160 return -ENOMEM;
161
162 memset(client, 0, sizeof(struct i2c_client));
163 client->addr = address;
164 client->adapter = adapter;
165 client->driver = &i2c_driver;
166 client->flags = I2C_CLIENT_ALLOW_USE;
167 snprintf(client->name, sizeof(client->name) - 1, "wm8775");
168
169 wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
170
171 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
172 if (state == NULL) {
173 kfree(client);
174 return -ENOMEM;
175 }
176 state->input = 2;
177 state->muted = 0;
178 i2c_set_clientdata(client, state);
179
180 /* initialize wm8775 */
181 wm8775_write(client, R23, 0x000); /* RESET */
182 wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */
183 wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */
184 wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */
185 wm8775_write(client, R13, 0x000); /* Powered up */
186 wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
187 wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
188 wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */
189 /* max gain +8dB */
190 wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */
191 /* detection, ALC hold time 42.6 ms */
192 wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */
193 /* ALC gain ramp down delay 33 ms */
194 wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */
195 wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */
196 /* limit -1dB */
197 wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */
198 i2c_attach_client(client);
199
200 return 0;
201}
202
203static int wm8775_probe(struct i2c_adapter *adapter)
204{
205#ifdef I2C_CLASS_TV_ANALOG
206 if (adapter->class & I2C_CLASS_TV_ANALOG)
207#else
208 if (adapter->id == I2C_HW_B_BT848)
209#endif
210 return i2c_probe(adapter, &addr_data, wm8775_attach);
211 return 0;
212}
213
214static int wm8775_detach(struct i2c_client *client)
215{
216 int err;
217
218 err = i2c_detach_client(client);
219 if (err) {
220 return err;
221 }
222 kfree(client);
223
224 return 0;
225}
226
227/* ----------------------------------------------------------------------- */
228
229/* i2c implementation */
230static struct i2c_driver i2c_driver = {
231 .name = "wm8775",
232
233 .id = I2C_DRIVERID_WM8775,
234 .flags = I2C_DF_NOTIFY,
235
236 .attach_adapter = wm8775_probe,
237 .detach_client = wm8775_detach,
238 .command = wm8775_command,
239 .owner = THIS_MODULE,
240};
241
242
243static int __init wm8775_init_module(void)
244{
245 return i2c_add_driver(&i2c_driver);
246}
247
248static void __exit wm8775_cleanup_module(void)
249{
250 i2c_del_driver(&i2c_driver);
251}
252
253module_init(wm8775_init_module);
254module_exit(wm8775_cleanup_module);
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
index d4740a89cea1..4ed898585c70 100644
--- a/drivers/media/video/zr36016.c
+++ b/drivers/media/video/zr36016.c
@@ -26,7 +26,6 @@
26 26
27#define ZR016_VERSION "v0.7" 27#define ZR016_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 13b1e7b6fd6e..0144576a6123 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -26,7 +26,6 @@
26 26
27#define ZR050_VERSION "v0.7.1" 27#define ZR050_VERSION "v0.7.1"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index b50dc403e6db..129744a07abd 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -26,7 +26,6 @@
26 26
27#define ZR060_VERSION "v0.7" 27#define ZR060_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 790a2932ded9..74022316fc63 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -47,7 +47,6 @@
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49#include <linux/config.h> 49#include <linux/config.h>
50#include <linux/version.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
@@ -92,9 +91,9 @@ static int mfcounter = 0;
92 * Public data... 91 * Public data...
93 */ 92 */
94int mpt_lan_index = -1; 93int mpt_lan_index = -1;
95int mpt_stm_index = -1; 94static int mpt_stm_index = -1;
96 95
97struct proc_dir_entry *mpt_proc_root_dir; 96static struct proc_dir_entry *mpt_proc_root_dir;
98 97
99#define WHOINIT_UNKNOWN 0xAA 98#define WHOINIT_UNKNOWN 0xAA
100 99
@@ -6272,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume);
6272EXPORT_SYMBOL(mpt_suspend); 6271EXPORT_SYMBOL(mpt_suspend);
6273#endif 6272#endif
6274EXPORT_SYMBOL(ioc_list); 6273EXPORT_SYMBOL(ioc_list);
6275EXPORT_SYMBOL(mpt_proc_root_dir);
6276EXPORT_SYMBOL(mpt_register); 6274EXPORT_SYMBOL(mpt_register);
6277EXPORT_SYMBOL(mpt_deregister); 6275EXPORT_SYMBOL(mpt_deregister);
6278EXPORT_SYMBOL(mpt_event_register); 6276EXPORT_SYMBOL(mpt_event_register);
@@ -6290,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter);
6290EXPORT_SYMBOL(mpt_GetIocState); 6288EXPORT_SYMBOL(mpt_GetIocState);
6291EXPORT_SYMBOL(mpt_print_ioc_summary); 6289EXPORT_SYMBOL(mpt_print_ioc_summary);
6292EXPORT_SYMBOL(mpt_lan_index); 6290EXPORT_SYMBOL(mpt_lan_index);
6293EXPORT_SYMBOL(mpt_stm_index);
6294EXPORT_SYMBOL(mpt_HardResetHandler); 6291EXPORT_SYMBOL(mpt_HardResetHandler);
6295EXPORT_SYMBOL(mpt_config); 6292EXPORT_SYMBOL(mpt_config);
6296EXPORT_SYMBOL(mpt_toolbox); 6293EXPORT_SYMBOL(mpt_toolbox);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e7efeb7740b9..8ad277a9afa1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -49,7 +49,6 @@
49#define MPTBASE_H_INCLUDED 49#define MPTBASE_H_INCLUDED
50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include <linux/version.h>
53#include <linux/config.h> 52#include <linux/config.h>
54#include <linux/kernel.h> 53#include <linux/kernel.h>
55#include <linux/pci.h> 54#include <linux/pci.h>
@@ -1007,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1007 * Public data decl's... 1006 * Public data decl's...
1008 */ 1007 */
1009extern struct list_head ioc_list; 1008extern struct list_head ioc_list;
1010extern struct proc_dir_entry *mpt_proc_root_dir;
1011 1009
1012extern int mpt_lan_index; /* needed by mptlan.c */ 1010extern int mpt_lan_index; /* needed by mptlan.c */
1013extern int mpt_stm_index; /* needed by mptstm.c */
1014 1011
1015/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1012/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016#endif /* } __KERNEL__ */ 1013#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..602138f8544d 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -45,7 +45,6 @@
45*/ 45*/
46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 47
48#include <linux/version.h>
49#include <linux/kernel.h> 48#include <linux/kernel.h>
50#include <linux/module.h> 49#include <linux/module.h>
51#include <linux/errno.h> 50#include <linux/errno.h>
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 28754a9cb803..518996e03481 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -49,7 +49,6 @@
49#define MPTCTL_H_INCLUDED 49#define MPTCTL_H_INCLUDED
50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include "linux/version.h"
53 52
54 53
55/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 54/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 750e343eb981..3726ecba5707 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -66,7 +66,6 @@
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/miscdevice.h> 67#include <linux/miscdevice.h>
68#include <linux/spinlock.h> 68#include <linux/spinlock.h>
69#include <linux/version.h>
70#include <linux/workqueue.h> 69#include <linux/workqueue.h>
71#include <linux/delay.h> 70#include <linux/delay.h>
72// #include <linux/trdevice.h> 71// #include <linux/trdevice.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 9c4dd682ac74..bc2b72b32905 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/spinlock.h> 19#include <linux/spinlock.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index 165f3405df27..4bb461793851 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index ecce4ffd3e23..d7e20a34f88d 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/config.h> 32#include <linux/config.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/version.h>
35#include <linux/interrupt.h> 34#include <linux/interrupt.h>
36#include <linux/device.h> 35#include <linux/device.h>
37#include <linux/input.h> 36#include <linux/input.h>
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c4a19d2dc67f..0807c1c91e55 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -20,7 +20,6 @@
20 * - Plugged memory leak in cfi_staa_writev(). 20 * - Plugged memory leak in cfi_staa_writev().
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/types.h> 24#include <linux/types.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index de48b35f5609..666cce1bf60c 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -82,7 +82,6 @@
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/version.h>
86#include <linux/config.h> 85#include <linux/config.h>
87#include <linux/kernel.h> 86#include <linux/kernel.h>
88#include <linux/module.h> 87#include <linux/module.h>
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index c0daf58357ca..60a6e51d662f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm44x.h> 25#include <asm/ibm44x.h>
27#include <platforms/4xx/ebony.h> 26#include <platforms/4xx/ebony.h>
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 6e559bc14636..c223514ca2eb 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -19,7 +19,6 @@
19#include <linux/mtd/map.h> 19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/ibm44x.h> 23#include <asm/ibm44x.h>
25#include <platforms/4xx/ocotea.h> 24#include <platforms/4xx/ocotea.h>
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index 5c17bca3a37e..f46bec66150f 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm4xx.h> 25#include <asm/ibm4xx.h>
27#include <platforms/4xx/walnut.h> 26#include <platforms/4xx/walnut.h>
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 3cafcdf28aed..9c5945d6df88 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -17,6 +17,7 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20#include <linux/version.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22/* fixme: this is ugly */ 23/* fixme: this is ugly */
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 056dfc17a075..a3c7fea404d0 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -27,7 +27,6 @@
27 * 10-06-2002 TG 128K card support added 27 * 10-06-2002 TG 128K card support added
28 */ 28 */
29 29
30#include <linux/version.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/module.h> 32#include <linux/module.h>
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index cc38fa0d45c6..f67d5d6eb9a6 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -12,6 +12,8 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/jiffies.h>
15#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h> 18#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 041ee59ea77d..0ab8d29caeea 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -18,6 +18,7 @@
18#include <linux/mtd/blktrans.h> 18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/jiffies.h>
21 22
22#include <asm/types.h> 23#include <asm/types.h>
23 24
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1958d9e16a3a..5c69d57f8548 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
447 447
448config SGI_IOC3_ETH 448config SGI_IOC3_ETH
449 bool "SGI IOC3 Ethernet" 449 bool "SGI IOC3 Ethernet"
450 depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN 450 depends on NET_ETHERNET && PCI && SGI_IP27
451 select CRC32 451 select CRC32
452 select MII 452 select MII
453 help 453 help
@@ -2523,6 +2523,19 @@ config PPP_BSDCOMP
2523 module; it is called bsd_comp and will show up in the directory 2523 module; it is called bsd_comp and will show up in the directory
2524 modules once you have said "make modules". If unsure, say N. 2524 modules once you have said "make modules". If unsure, say N.
2525 2525
2526config PPP_MPPE
2527 tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
2528 depends on PPP && EXPERIMENTAL
2529 select CRYPTO
2530 select CRYPTO_SHA1
2531 select CRYPTO_ARC4
2532 ---help---
2533 Support for the MPPE Encryption protocol, as employed by the
2534 Microsoft Point-to-Point Tunneling Protocol.
2535
2536 See http://pptpclient.sourceforge.net/ for information on
2537 configuring PPTP clients and servers to utilize this method.
2538
2526config PPPOE 2539config PPPOE
2527 tristate "PPP over Ethernet (EXPERIMENTAL)" 2540 tristate "PPP over Ethernet (EXPERIMENTAL)"
2528 depends on EXPERIMENTAL && PPP 2541 depends on EXPERIMENTAL && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7c313cb341b8..4cffd34442aa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
112obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o 112obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
113obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o 113obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
114obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o 114obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
115obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
115obj-$(CONFIG_PPPOE) += pppox.o pppoe.o 116obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
116 117
117obj-$(CONFIG_SLIP) += slip.o 118obj-$(CONFIG_SLIP) += slip.o
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 0ee3e27969c6..c53848f787eb 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -18,7 +18,6 @@
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/version.h>
22#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
23 22
24#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -29,8 +28,8 @@
29 28
30#define DRV_MODULE_NAME "b44" 29#define DRV_MODULE_NAME "b44"
31#define PFX DRV_MODULE_NAME ": " 30#define PFX DRV_MODULE_NAME ": "
32#define DRV_MODULE_VERSION "0.95" 31#define DRV_MODULE_VERSION "0.96"
33#define DRV_MODULE_RELDATE "Aug 3, 2004" 32#define DRV_MODULE_RELDATE "Nov 8, 2005"
34 33
35#define B44_DEF_MSG_ENABLE \ 34#define B44_DEF_MSG_ENABLE \
36 (NETIF_MSG_DRV | \ 35 (NETIF_MSG_DRV | \
@@ -102,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
102static void b44_halt(struct b44 *); 101static void b44_halt(struct b44 *);
103static void b44_init_rings(struct b44 *); 102static void b44_init_rings(struct b44 *);
104static void b44_init_hw(struct b44 *); 103static void b44_init_hw(struct b44 *);
105static int b44_poll(struct net_device *dev, int *budget);
106#ifdef CONFIG_NET_POLL_CONTROLLER
107static void b44_poll_controller(struct net_device *dev);
108#endif
109 104
110static int dma_desc_align_mask; 105static int dma_desc_align_mask;
111static int dma_desc_sync_size; 106static int dma_desc_sync_size;
112 107
108static const char b44_gstrings[][ETH_GSTRING_LEN] = {
109#define _B44(x...) # x,
110B44_STAT_REG_DECLARE
111#undef _B44
112};
113
113static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, 114static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
114 dma_addr_t dma_base, 115 dma_addr_t dma_base,
115 unsigned long offset, 116 unsigned long offset,
@@ -502,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
502 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 503 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
503 *val++ += br32(bp, reg); 504 *val++ += br32(bp, reg);
504 } 505 }
505 val = &bp->hw_stats.rx_good_octets; 506
507 /* Pad */
508 reg += 8*4UL;
509
506 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 510 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
507 *val++ += br32(bp, reg); 511 *val++ += br32(bp, reg);
508 } 512 }
@@ -653,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
653 657
654 /* Hardware bug work-around, the chip is unable to do PCI DMA 658 /* Hardware bug work-around, the chip is unable to do PCI DMA
655 to/from anything above 1GB :-( */ 659 to/from anything above 1GB :-( */
656 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 660 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
657 /* Sigh... */ 661 /* Sigh... */
658 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 662 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
659 dev_kfree_skb_any(skb); 663 dev_kfree_skb_any(skb);
@@ -663,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
663 mapping = pci_map_single(bp->pdev, skb->data, 667 mapping = pci_map_single(bp->pdev, skb->data,
664 RX_PKT_BUF_SZ, 668 RX_PKT_BUF_SZ,
665 PCI_DMA_FROMDEVICE); 669 PCI_DMA_FROMDEVICE);
666 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 670 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
667 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 671 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
668 dev_kfree_skb_any(skb); 672 dev_kfree_skb_any(skb);
669 return -ENOMEM; 673 return -ENOMEM;
@@ -890,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
890{ 894{
891 struct net_device *dev = dev_id; 895 struct net_device *dev = dev_id;
892 struct b44 *bp = netdev_priv(dev); 896 struct b44 *bp = netdev_priv(dev);
893 unsigned long flags;
894 u32 istat, imask; 897 u32 istat, imask;
895 int handled = 0; 898 int handled = 0;
896 899
897 spin_lock_irqsave(&bp->lock, flags); 900 spin_lock(&bp->lock);
898 901
899 istat = br32(bp, B44_ISTAT); 902 istat = br32(bp, B44_ISTAT);
900 imask = br32(bp, B44_IMASK); 903 imask = br32(bp, B44_IMASK);
@@ -905,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
905 istat &= imask; 908 istat &= imask;
906 if (istat) { 909 if (istat) {
907 handled = 1; 910 handled = 1;
911
912 if (unlikely(!netif_running(dev))) {
913 printk(KERN_INFO "%s: late interrupt.\n", dev->name);
914 goto irq_ack;
915 }
916
908 if (netif_rx_schedule_prep(dev)) { 917 if (netif_rx_schedule_prep(dev)) {
909 /* NOTE: These writes are posted by the readback of 918 /* NOTE: These writes are posted by the readback of
910 * the ISTAT register below. 919 * the ISTAT register below.
@@ -917,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
917 dev->name); 926 dev->name);
918 } 927 }
919 928
929irq_ack:
920 bw32(bp, B44_ISTAT, istat); 930 bw32(bp, B44_ISTAT, istat);
921 br32(bp, B44_ISTAT); 931 br32(bp, B44_ISTAT);
922 } 932 }
923 spin_unlock_irqrestore(&bp->lock, flags); 933 spin_unlock(&bp->lock);
924 return IRQ_RETVAL(handled); 934 return IRQ_RETVAL(handled);
925} 935}
926 936
@@ -948,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
948{ 958{
949 struct b44 *bp = netdev_priv(dev); 959 struct b44 *bp = netdev_priv(dev);
950 struct sk_buff *bounce_skb; 960 struct sk_buff *bounce_skb;
961 int rc = NETDEV_TX_OK;
951 dma_addr_t mapping; 962 dma_addr_t mapping;
952 u32 len, entry, ctrl; 963 u32 len, entry, ctrl;
953 964
@@ -957,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
957 /* This is a hard error, log it. */ 968 /* This is a hard error, log it. */
958 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { 969 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
959 netif_stop_queue(dev); 970 netif_stop_queue(dev);
960 spin_unlock_irq(&bp->lock);
961 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", 971 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
962 dev->name); 972 dev->name);
963 return 1; 973 goto err_out;
964 } 974 }
965 975
966 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); 976 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
967 if(mapping+len > B44_DMA_MASK) { 977 if (mapping + len > B44_DMA_MASK) {
968 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 978 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
969 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); 979 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
970 980
971 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, 981 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
972 GFP_ATOMIC|GFP_DMA); 982 GFP_ATOMIC|GFP_DMA);
973 if (!bounce_skb) 983 if (!bounce_skb)
974 return NETDEV_TX_BUSY; 984 goto err_out;
975 985
976 mapping = pci_map_single(bp->pdev, bounce_skb->data, 986 mapping = pci_map_single(bp->pdev, bounce_skb->data,
977 len, PCI_DMA_TODEVICE); 987 len, PCI_DMA_TODEVICE);
978 if(mapping+len > B44_DMA_MASK) { 988 if (mapping + len > B44_DMA_MASK) {
979 pci_unmap_single(bp->pdev, mapping, 989 pci_unmap_single(bp->pdev, mapping,
980 len, PCI_DMA_TODEVICE); 990 len, PCI_DMA_TODEVICE);
981 dev_kfree_skb_any(bounce_skb); 991 dev_kfree_skb_any(bounce_skb);
982 return NETDEV_TX_BUSY; 992 goto err_out;
983 } 993 }
984 994
985 memcpy(skb_put(bounce_skb, len), skb->data, skb->len); 995 memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -1019,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
1019 if (TX_BUFFS_AVAIL(bp) < 1) 1029 if (TX_BUFFS_AVAIL(bp) < 1)
1020 netif_stop_queue(dev); 1030 netif_stop_queue(dev);
1021 1031
1032 dev->trans_start = jiffies;
1033
1034out_unlock:
1022 spin_unlock_irq(&bp->lock); 1035 spin_unlock_irq(&bp->lock);
1023 1036
1024 dev->trans_start = jiffies; 1037 return rc;
1025 1038
1026 return 0; 1039err_out:
1040 rc = NETDEV_TX_BUSY;
1041 goto out_unlock;
1027} 1042}
1028 1043
1029static int b44_change_mtu(struct net_device *dev, int new_mtu) 1044static int b44_change_mtu(struct net_device *dev, int new_mtu)
@@ -1097,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
1097 * 1112 *
1098 * The chip has been shut down and the driver detached from 1113 * The chip has been shut down and the driver detached from
1099 * the networking, so no interrupts or new tx packets will 1114 * the networking, so no interrupts or new tx packets will
1100 * end up in the driver. bp->lock is not held and we are not 1115 * end up in the driver.
1101 * in an interrupt context and thus may sleep.
1102 */ 1116 */
1103static void b44_init_rings(struct b44 *bp) 1117static void b44_init_rings(struct b44 *bp)
1104{ 1118{
@@ -1170,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
1170 int size; 1184 int size;
1171 1185
1172 size = B44_RX_RING_SIZE * sizeof(struct ring_info); 1186 size = B44_RX_RING_SIZE * sizeof(struct ring_info);
1173 bp->rx_buffers = kmalloc(size, GFP_KERNEL); 1187 bp->rx_buffers = kzalloc(size, GFP_KERNEL);
1174 if (!bp->rx_buffers) 1188 if (!bp->rx_buffers)
1175 goto out_err; 1189 goto out_err;
1176 memset(bp->rx_buffers, 0, size);
1177 1190
1178 size = B44_TX_RING_SIZE * sizeof(struct ring_info); 1191 size = B44_TX_RING_SIZE * sizeof(struct ring_info);
1179 bp->tx_buffers = kmalloc(size, GFP_KERNEL); 1192 bp->tx_buffers = kzalloc(size, GFP_KERNEL);
1180 if (!bp->tx_buffers) 1193 if (!bp->tx_buffers)
1181 goto out_err; 1194 goto out_err;
1182 memset(bp->tx_buffers, 0, size);
1183 1195
1184 size = DMA_TABLE_BYTES; 1196 size = DMA_TABLE_BYTES;
1185 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); 1197 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
@@ -1190,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1190 struct dma_desc *rx_ring; 1202 struct dma_desc *rx_ring;
1191 dma_addr_t rx_ring_dma; 1203 dma_addr_t rx_ring_dma;
1192 1204
1193 if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1205 rx_ring = kzalloc(size, GFP_KERNEL);
1206 if (!rx_ring)
1194 goto out_err; 1207 goto out_err;
1195 1208
1196 memset(rx_ring, 0, size);
1197 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, 1209 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
1198 DMA_TABLE_BYTES, 1210 DMA_TABLE_BYTES,
1199 DMA_BIDIRECTIONAL); 1211 DMA_BIDIRECTIONAL);
@@ -1216,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1216 struct dma_desc *tx_ring; 1228 struct dma_desc *tx_ring;
1217 dma_addr_t tx_ring_dma; 1229 dma_addr_t tx_ring_dma;
1218 1230
1219 if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1231 tx_ring = kzalloc(size, GFP_KERNEL);
1232 if (!tx_ring)
1220 goto out_err; 1233 goto out_err;
1221 1234
1222 memset(tx_ring, 0, size);
1223 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, 1235 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
1224 DMA_TABLE_BYTES, 1236 DMA_TABLE_BYTES,
1225 DMA_TO_DEVICE); 1237 DMA_TO_DEVICE);
@@ -1382,22 +1394,21 @@ static int b44_open(struct net_device *dev)
1382 1394
1383 err = b44_alloc_consistent(bp); 1395 err = b44_alloc_consistent(bp);
1384 if (err) 1396 if (err)
1385 return err; 1397 goto out;
1386
1387 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1388 if (err)
1389 goto err_out_free;
1390
1391 spin_lock_irq(&bp->lock);
1392 1398
1393 b44_init_rings(bp); 1399 b44_init_rings(bp);
1394 b44_init_hw(bp); 1400 b44_init_hw(bp);
1395 bp->flags |= B44_FLAG_INIT_COMPLETE;
1396 1401
1397 netif_carrier_off(dev); 1402 netif_carrier_off(dev);
1398 b44_check_phy(bp); 1403 b44_check_phy(bp);
1399 1404
1400 spin_unlock_irq(&bp->lock); 1405 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1406 if (unlikely(err < 0)) {
1407 b44_chip_reset(bp);
1408 b44_free_rings(bp);
1409 b44_free_consistent(bp);
1410 goto out;
1411 }
1401 1412
1402 init_timer(&bp->timer); 1413 init_timer(&bp->timer);
1403 bp->timer.expires = jiffies + HZ; 1414 bp->timer.expires = jiffies + HZ;
@@ -1406,11 +1417,7 @@ static int b44_open(struct net_device *dev)
1406 add_timer(&bp->timer); 1417 add_timer(&bp->timer);
1407 1418
1408 b44_enable_ints(bp); 1419 b44_enable_ints(bp);
1409 1420out:
1410 return 0;
1411
1412err_out_free:
1413 b44_free_consistent(bp);
1414 return err; 1421 return err;
1415} 1422}
1416 1423
@@ -1445,6 +1452,8 @@ static int b44_close(struct net_device *dev)
1445 1452
1446 netif_stop_queue(dev); 1453 netif_stop_queue(dev);
1447 1454
1455 netif_poll_disable(dev);
1456
1448 del_timer_sync(&bp->timer); 1457 del_timer_sync(&bp->timer);
1449 1458
1450 spin_lock_irq(&bp->lock); 1459 spin_lock_irq(&bp->lock);
@@ -1454,13 +1463,14 @@ static int b44_close(struct net_device *dev)
1454#endif 1463#endif
1455 b44_halt(bp); 1464 b44_halt(bp);
1456 b44_free_rings(bp); 1465 b44_free_rings(bp);
1457 bp->flags &= ~B44_FLAG_INIT_COMPLETE;
1458 netif_carrier_off(bp->dev); 1466 netif_carrier_off(bp->dev);
1459 1467
1460 spin_unlock_irq(&bp->lock); 1468 spin_unlock_irq(&bp->lock);
1461 1469
1462 free_irq(dev->irq, dev); 1470 free_irq(dev->irq, dev);
1463 1471
1472 netif_poll_enable(dev);
1473
1464 b44_free_consistent(bp); 1474 b44_free_consistent(bp);
1465 1475
1466 return 0; 1476 return 0;
@@ -1525,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
1525{ 1535{
1526 struct b44 *bp = netdev_priv(dev); 1536 struct b44 *bp = netdev_priv(dev);
1527 u32 val; 1537 u32 val;
1528 int i=0;
1529 unsigned char zero[6] = {0,0,0,0,0,0};
1530 1538
1531 val = br32(bp, B44_RXCONFIG); 1539 val = br32(bp, B44_RXCONFIG);
1532 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); 1540 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1534,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
1534 val |= RXCONFIG_PROMISC; 1542 val |= RXCONFIG_PROMISC;
1535 bw32(bp, B44_RXCONFIG, val); 1543 bw32(bp, B44_RXCONFIG, val);
1536 } else { 1544 } else {
1545 unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
1546 int i = 0;
1547
1537 __b44_set_mac_addr(bp); 1548 __b44_set_mac_addr(bp);
1538 1549
1539 if (dev->flags & IFF_ALLMULTI) 1550 if (dev->flags & IFF_ALLMULTI)
1540 val |= RXCONFIG_ALLMULTI; 1551 val |= RXCONFIG_ALLMULTI;
1541 else 1552 else
1542 i=__b44_load_mcast(bp, dev); 1553 i = __b44_load_mcast(bp, dev);
1543 1554
1544 for(;i<64;i++) { 1555 for (; i < 64; i++) {
1545 __b44_cam_write(bp, zero, i); 1556 __b44_cam_write(bp, zero, i);
1546 } 1557 }
1547 bw32(bp, B44_RXCONFIG, val); 1558 bw32(bp, B44_RXCONFIG, val);
@@ -1605,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1605{ 1616{
1606 struct b44 *bp = netdev_priv(dev); 1617 struct b44 *bp = netdev_priv(dev);
1607 1618
1608 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1619 if (!netif_running(dev))
1609 return -EAGAIN; 1620 return -EAGAIN;
1610 cmd->supported = (SUPPORTED_Autoneg); 1621 cmd->supported = (SUPPORTED_Autoneg);
1611 cmd->supported |= (SUPPORTED_100baseT_Half | 1622 cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1643,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1643{ 1654{
1644 struct b44 *bp = netdev_priv(dev); 1655 struct b44 *bp = netdev_priv(dev);
1645 1656
1646 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1657 if (!netif_running(dev))
1647 return -EAGAIN; 1658 return -EAGAIN;
1648 1659
1649 /* We do not support gigabit. */ 1660 /* We do not support gigabit. */
@@ -1773,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
1773 return 0; 1784 return 0;
1774} 1785}
1775 1786
1787static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1788{
1789 switch(stringset) {
1790 case ETH_SS_STATS:
1791 memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
1792 break;
1793 }
1794}
1795
1796static int b44_get_stats_count(struct net_device *dev)
1797{
1798 return ARRAY_SIZE(b44_gstrings);
1799}
1800
1801static void b44_get_ethtool_stats(struct net_device *dev,
1802 struct ethtool_stats *stats, u64 *data)
1803{
1804 struct b44 *bp = netdev_priv(dev);
1805 u32 *val = &bp->hw_stats.tx_good_octets;
1806 u32 i;
1807
1808 spin_lock_irq(&bp->lock);
1809
1810 b44_stats_update(bp);
1811
1812 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
1813 *data++ = *val++;
1814
1815 spin_unlock_irq(&bp->lock);
1816}
1817
1776static struct ethtool_ops b44_ethtool_ops = { 1818static struct ethtool_ops b44_ethtool_ops = {
1777 .get_drvinfo = b44_get_drvinfo, 1819 .get_drvinfo = b44_get_drvinfo,
1778 .get_settings = b44_get_settings, 1820 .get_settings = b44_get_settings,
@@ -1785,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
1785 .set_pauseparam = b44_set_pauseparam, 1827 .set_pauseparam = b44_set_pauseparam,
1786 .get_msglevel = b44_get_msglevel, 1828 .get_msglevel = b44_get_msglevel,
1787 .set_msglevel = b44_set_msglevel, 1829 .set_msglevel = b44_set_msglevel,
1830 .get_strings = b44_get_strings,
1831 .get_stats_count = b44_get_stats_count,
1832 .get_ethtool_stats = b44_get_ethtool_stats,
1788 .get_perm_addr = ethtool_op_get_perm_addr, 1833 .get_perm_addr = ethtool_op_get_perm_addr,
1789}; 1834};
1790 1835
@@ -1893,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1893 1938
1894 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); 1939 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
1895 if (err) { 1940 if (err) {
1896 printk(KERN_ERR PFX "No usable DMA configuration, " 1941 printk(KERN_ERR PFX "No usable DMA configuration, "
1897 "aborting.\n"); 1942 "aborting.\n");
1898 goto err_out_free_res; 1943 goto err_out_free_res;
1899 } 1944 }
1900 1945
1901 b44reg_base = pci_resource_start(pdev, 0); 1946 b44reg_base = pci_resource_start(pdev, 0);
@@ -1917,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1917 bp = netdev_priv(dev); 1962 bp = netdev_priv(dev);
1918 bp->pdev = pdev; 1963 bp->pdev = pdev;
1919 bp->dev = dev; 1964 bp->dev = dev;
1920 if (b44_debug >= 0) 1965
1921 bp->msg_enable = (1 << b44_debug) - 1; 1966 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
1922 else
1923 bp->msg_enable = B44_DEF_MSG_ENABLE;
1924 1967
1925 spin_lock_init(&bp->lock); 1968 spin_lock_init(&bp->lock);
1926 1969
@@ -2010,17 +2053,14 @@ err_out_disable_pdev:
2010static void __devexit b44_remove_one(struct pci_dev *pdev) 2053static void __devexit b44_remove_one(struct pci_dev *pdev)
2011{ 2054{
2012 struct net_device *dev = pci_get_drvdata(pdev); 2055 struct net_device *dev = pci_get_drvdata(pdev);
2056 struct b44 *bp = netdev_priv(dev);
2013 2057
2014 if (dev) { 2058 unregister_netdev(dev);
2015 struct b44 *bp = netdev_priv(dev); 2059 iounmap(bp->regs);
2016 2060 free_netdev(dev);
2017 unregister_netdev(dev); 2061 pci_release_regions(pdev);
2018 iounmap(bp->regs); 2062 pci_disable_device(pdev);
2019 free_netdev(dev); 2063 pci_set_drvdata(pdev, NULL);
2020 pci_release_regions(pdev);
2021 pci_disable_device(pdev);
2022 pci_set_drvdata(pdev, NULL);
2023 }
2024} 2064}
2025 2065
2026static int b44_suspend(struct pci_dev *pdev, pm_message_t state) 2066static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 593cb0ad4100..b178662978f3 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -346,29 +346,63 @@ struct ring_info {
346 346
347#define B44_MCAST_TABLE_SIZE 32 347#define B44_MCAST_TABLE_SIZE 32
348 348
349#define B44_STAT_REG_DECLARE \
350 _B44(tx_good_octets) \
351 _B44(tx_good_pkts) \
352 _B44(tx_octets) \
353 _B44(tx_pkts) \
354 _B44(tx_broadcast_pkts) \
355 _B44(tx_multicast_pkts) \
356 _B44(tx_len_64) \
357 _B44(tx_len_65_to_127) \
358 _B44(tx_len_128_to_255) \
359 _B44(tx_len_256_to_511) \
360 _B44(tx_len_512_to_1023) \
361 _B44(tx_len_1024_to_max) \
362 _B44(tx_jabber_pkts) \
363 _B44(tx_oversize_pkts) \
364 _B44(tx_fragment_pkts) \
365 _B44(tx_underruns) \
366 _B44(tx_total_cols) \
367 _B44(tx_single_cols) \
368 _B44(tx_multiple_cols) \
369 _B44(tx_excessive_cols) \
370 _B44(tx_late_cols) \
371 _B44(tx_defered) \
372 _B44(tx_carrier_lost) \
373 _B44(tx_pause_pkts) \
374 _B44(rx_good_octets) \
375 _B44(rx_good_pkts) \
376 _B44(rx_octets) \
377 _B44(rx_pkts) \
378 _B44(rx_broadcast_pkts) \
379 _B44(rx_multicast_pkts) \
380 _B44(rx_len_64) \
381 _B44(rx_len_65_to_127) \
382 _B44(rx_len_128_to_255) \
383 _B44(rx_len_256_to_511) \
384 _B44(rx_len_512_to_1023) \
385 _B44(rx_len_1024_to_max) \
386 _B44(rx_jabber_pkts) \
387 _B44(rx_oversize_pkts) \
388 _B44(rx_fragment_pkts) \
389 _B44(rx_missed_pkts) \
390 _B44(rx_crc_align_errs) \
391 _B44(rx_undersize) \
392 _B44(rx_crc_errs) \
393 _B44(rx_align_errs) \
394 _B44(rx_symbol_errs) \
395 _B44(rx_pause_pkts) \
396 _B44(rx_nonpause_pkts)
397
349/* SW copy of device statistics, kept up to date by periodic timer 398/* SW copy of device statistics, kept up to date by periodic timer
350 * which probes HW values. Must have same relative layout as HW 399 * which probes HW values. Check b44_stats_update if you mess with
351 * register above, because b44_stats_update depends upon this. 400 * the layout
352 */ 401 */
353struct b44_hw_stats { 402struct b44_hw_stats {
354 u32 tx_good_octets, tx_good_pkts, tx_octets; 403#define _B44(x) u32 x;
355 u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; 404B44_STAT_REG_DECLARE
356 u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; 405#undef _B44
357 u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
358 u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
359 u32 tx_underruns, tx_total_cols, tx_single_cols;
360 u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
361 u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
362 u32 __pad1[8];
363
364 u32 rx_good_octets, rx_good_pkts, rx_octets;
365 u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
366 u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
367 u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
368 u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
369 u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
370 u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
371 u32 rx_pause_pkts, rx_nonpause_pkts;
372}; 406};
373 407
374struct b44 { 408struct b44 {
@@ -386,7 +420,6 @@ struct b44 {
386 420
387 u32 dma_offset; 421 u32 dma_offset;
388 u32 flags; 422 u32 flags;
389#define B44_FLAG_INIT_COMPLETE 0x00000001
390#define B44_FLAG_BUGGY_TXPTR 0x00000002 423#define B44_FLAG_BUGGY_TXPTR 0x00000002
391#define B44_FLAG_REORDER_BUG 0x00000004 424#define B44_FLAG_REORDER_BUG 0x00000004
392#define B44_FLAG_PAUSE_AUTO 0x00008000 425#define B44_FLAG_PAUSE_AUTO 0x00008000
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8032126fd589..94cec3cf2a13 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) 1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
1605 1605
1606/* 1606/*
1607 * Compute the features available to the bonding device by 1607 * Compute the common dev->feature set available to all slaves. Some
1608 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. 1608 * feature bits are managed elsewhere, so preserve feature bits set on
1609 * Call this after attaching or detaching a slave to update the 1609 * master device that are not part of the examined set.
1610 * bond's features.
1611 */ 1610 */
1612static int bond_compute_features(struct bonding *bond) 1611static int bond_compute_features(struct bonding *bond)
1613{ 1612{
1614 int i; 1613 unsigned long features = BOND_INTERSECT_FEATURES;
1615 struct slave *slave; 1614 struct slave *slave;
1616 struct net_device *bond_dev = bond->dev; 1615 struct net_device *bond_dev = bond->dev;
1617 int features = bond->bond_features; 1616 int i;
1618 1617
1619 bond_for_each_slave(bond, slave, i) { 1618 bond_for_each_slave(bond, slave, i)
1620 struct net_device * slave_dev = slave->dev; 1619 features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
1621 if (i == 0) {
1622 features |= BOND_INTERSECT_FEATURES;
1623 }
1624 features &=
1625 ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
1626 }
1627 1620
1628 /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
1629 if ((features & NETIF_F_SG) && 1621 if ((features & NETIF_F_SG) &&
1630 !(features & (NETIF_F_IP_CSUM | 1622 !(features & (NETIF_F_IP_CSUM |
1631 NETIF_F_NO_CSUM | 1623 NETIF_F_NO_CSUM |
1632 NETIF_F_HW_CSUM))) { 1624 NETIF_F_HW_CSUM)))
1633 features &= ~NETIF_F_SG; 1625 features &= ~NETIF_F_SG;
1634 }
1635 1626
1627 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
1636 bond_dev->features = features; 1628 bond_dev->features = features;
1637 1629
1638 return 0; 1630 return 0;
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4561 NETIF_F_HW_VLAN_RX | 4553 NETIF_F_HW_VLAN_RX |
4562 NETIF_F_HW_VLAN_FILTER); 4554 NETIF_F_HW_VLAN_FILTER);
4563 4555
4564 bond->bond_features = bond_dev->features;
4565
4566#ifdef CONFIG_PROC_FS 4556#ifdef CONFIG_PROC_FS
4567 bond_create_proc_entry(bond); 4557 bond_create_proc_entry(bond);
4568#endif 4558#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8af624..1433e91db0f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
40#include "bond_3ad.h" 40#include "bond_3ad.h"
41#include "bond_alb.h" 41#include "bond_alb.h"
42 42
43#define DRV_VERSION "2.6.4" 43#define DRV_VERSION "2.6.5"
44#define DRV_RELDATE "September 26, 2005" 44#define DRV_RELDATE "November 4, 2005"
45#define DRV_NAME "bonding" 45#define DRV_NAME "bonding"
46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
47 47
@@ -211,9 +211,6 @@ struct bonding {
211 struct bond_params params; 211 struct bond_params params;
212 struct list_head vlan_list; 212 struct list_head vlan_list;
213 struct vlan_group *vlgrp; 213 struct vlan_group *vlgrp;
214 /* the features the bonding device supports, independently
215 * of any slaves */
216 int bond_features;
217}; 214};
218 215
219/** 216/**
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 50f43dbf31ae..1f7ca453bb4a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -67,7 +67,6 @@
67 */ 67 */
68 68
69#include <linux/config.h> 69#include <linux/config.h>
70#include <linux/version.h>
71 70
72#include <linux/module.h> 71#include <linux/module.h>
73#include <linux/kernel.h> 72#include <linux/kernel.h>
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409static void e100_rx(struct net_device *dev); 409static void e100_rx(struct net_device *dev);
410static int e100_close(struct net_device *dev); 410static int e100_close(struct net_device *dev);
411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
412static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
413static int e100_set_config(struct net_device* dev, struct ifmap* map); 412static int e100_set_config(struct net_device* dev, struct ifmap* map);
414static void e100_tx_timeout(struct net_device *dev); 413static void e100_tx_timeout(struct net_device *dev);
415static struct net_device_stats *e100_get_stats(struct net_device *dev); 414static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
436static void e100_clear_network_leds(unsigned long dummy); 435static void e100_clear_network_leds(unsigned long dummy);
437static void e100_set_network_leds(int active); 436static void e100_set_network_leds(int active);
438 437
438static struct ethtool_ops e100_ethtool_ops;
439
439static void broadcom_check_speed(struct net_device* dev); 440static void broadcom_check_speed(struct net_device* dev);
440static void broadcom_check_duplex(struct net_device* dev); 441static void broadcom_check_duplex(struct net_device* dev);
441static void tdk_check_speed(struct net_device* dev); 442static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
495 dev->get_stats = e100_get_stats; 496 dev->get_stats = e100_get_stats;
496 dev->set_multicast_list = set_multicast_list; 497 dev->set_multicast_list = set_multicast_list;
497 dev->set_mac_address = e100_set_mac_address; 498 dev->set_mac_address = e100_set_mac_address;
499 dev->ethtool_ops = &e100_ethtool_ops;
498 dev->do_ioctl = e100_ioctl; 500 dev->do_ioctl = e100_ioctl;
499 dev->set_config = e100_set_config; 501 dev->set_config = e100_set_config;
500 dev->tx_timeout = e100_tx_timeout; 502 dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448 1450
1449 spin_lock(&np->lock); /* Preempt protection */ 1451 spin_lock(&np->lock); /* Preempt protection */
1450 switch (cmd) { 1452 switch (cmd) {
1451 case SIOCETHTOOL:
1452 return e100_ethtool_ioctl(dev,ifr);
1453 case SIOCGMIIPHY: /* Get PHY address */ 1453 case SIOCGMIIPHY: /* Get PHY address */
1454 data->phy_id = mdio_phy_addr; 1454 data->phy_id = mdio_phy_addr;
1455 break; 1455 break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1486 return 0; 1486 return 0;
1487} 1487}
1488 1488
1489static int 1489static int e100_set_settings(struct net_device *dev,
1490e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) 1490 struct ethtool_cmd *ecmd)
1491{ 1491{
1492 struct ethtool_cmd ecmd; 1492 ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1493
1494 if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
1495 return -EFAULT;
1496
1497 switch (ecmd.cmd) {
1498 case ETHTOOL_GSET:
1499 {
1500 memset((void *) &ecmd, 0, sizeof (ecmd));
1501 ecmd.supported =
1502 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1503 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | 1493 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1504 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; 1494 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
1505 ecmd.port = PORT_TP; 1495 ecmd->port = PORT_TP;
1506 ecmd.transceiver = XCVR_EXTERNAL; 1496 ecmd->transceiver = XCVR_EXTERNAL;
1507 ecmd.phy_address = mdio_phy_addr; 1497 ecmd->phy_address = mdio_phy_addr;
1508 ecmd.speed = current_speed; 1498 ecmd->speed = current_speed;
1509 ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1499 ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1510 ecmd.advertising = ADVERTISED_TP; 1500 ecmd->advertising = ADVERTISED_TP;
1511 if (current_duplex == autoneg && current_speed_selection == 0) 1501
1512 ecmd.advertising |= ADVERTISED_Autoneg; 1502 if (current_duplex == autoneg && current_speed_selection == 0)
1513 else { 1503 ecmd->advertising |= ADVERTISED_Autoneg;
1514 ecmd.advertising |= 1504 else {
1515 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | 1505 ecmd->advertising |=
1516 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; 1506 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
1517 if (current_speed_selection == 10) 1507 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
1518 ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); 1508 if (current_speed_selection == 10)
1519 else if (current_speed_selection == 100) 1509 ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
1520 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); 1510 ADVERTISED_100baseT_Full);
1521 if (current_duplex == half) 1511 else if (current_speed_selection == 100)
1522 ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); 1512 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1523 else if (current_duplex == full) 1513 ADVERTISED_10baseT_Full);
1524 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); 1514 if (current_duplex == half)
1525 } 1515 ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
1526 ecmd.autoneg = AUTONEG_ENABLE; 1516 ADVERTISED_100baseT_Full);
1527 if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) 1517 else if (current_duplex == full)
1528 return -EFAULT; 1518 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1529 } 1519 ADVERTISED_100baseT_Half);
1530 break; 1520 }
1531 case ETHTOOL_SSET: 1521
1532 { 1522 ecmd->autoneg = AUTONEG_ENABLE;
1533 if (!capable(CAP_NET_ADMIN)) { 1523 return 0;
1534 return -EPERM; 1524}
1535 } 1525
1536 if (ecmd.autoneg == AUTONEG_ENABLE) { 1526static int e100_set_settings(struct net_device *dev,
1537 e100_set_duplex(dev, autoneg); 1527 struct ethtool_cmd *ecmd)
1538 e100_set_speed(dev, 0); 1528{
1539 } else { 1529 if (ecmd->autoneg == AUTONEG_ENABLE) {
1540 e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); 1530 e100_set_duplex(dev, autoneg);
1541 e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); 1531 e100_set_speed(dev, 0);
1542 } 1532 } else {
1543 } 1533 e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
1544 break; 1534 e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
1545 case ETHTOOL_GDRVINFO:
1546 {
1547 struct ethtool_drvinfo info;
1548 memset((void *) &info, 0, sizeof (info));
1549 strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
1550 strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
1551 strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
1552 strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
1553 info.regdump_len = 0;
1554 info.eedump_len = 0;
1555 info.testinfo_len = 0;
1556 if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
1557 return -EFAULT;
1558 }
1559 break;
1560 case ETHTOOL_NWAY_RST:
1561 if (current_duplex == autoneg && current_speed_selection == 0)
1562 e100_negotiate(dev);
1563 break;
1564 default:
1565 return -EOPNOTSUPP;
1566 break;
1567 } 1535 }
1536
1537 return 0;
1538}
1539
1540static void e100_get_drvinfo(struct net_device *dev,
1541 struct ethtool_drvinfo *info)
1542{
1543 strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
1544 strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
1545 strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
1546 strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
1547}
1548
1549static int e100_nway_reset(struct net_device *dev)
1550{
1551 if (current_duplex == autoneg && current_speed_selection == 0)
1552 e100_negotiate(dev);
1568 return 0; 1553 return 0;
1569} 1554}
1570 1555
1556static struct ethtool_ops e100_ethtool_ops = {
1557 .get_settings = e100_get_settings,
1558 .set_settings = e100_set_settings,
1559 .get_drvinfo = e100_get_drvinfo,
1560 .nway_reset = e100_nway_reset,
1561 .get_link = ethtool_op_get_link,
1562};
1563
1571static int 1564static int
1572e100_set_config(struct net_device *dev, struct ifmap *map) 1565e100_set_config(struct net_device *dev, struct ifmap *map)
1573{ 1566{
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838e6c4c..2a290cc397ad 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
1549static int __init dgrs_init_module (void) 1549static int __init dgrs_init_module (void)
1550{ 1550{
1551 int i; 1551 int i;
1552 int eisacount = 0, pcicount = 0; 1552 int cardcount = 0;
1553 1553
1554 /* 1554 /*
1555 * Command line variable overrides 1555 * Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
1591 * Find and configure all the cards 1591 * Find and configure all the cards
1592 */ 1592 */
1593#ifdef CONFIG_EISA 1593#ifdef CONFIG_EISA
1594 eisacount = eisa_driver_register(&dgrs_eisa_driver); 1594 cardcount = eisa_driver_register(&dgrs_eisa_driver);
1595 if (eisacount < 0) 1595 if (cardcount < 0)
1596 return eisacount; 1596 return cardcount;
1597#endif
1598#ifdef CONFIG_PCI
1599 pcicount = pci_register_driver(&dgrs_pci_driver);
1600 if (pcicount)
1601 return pcicount;
1602#endif 1597#endif
1598 cardcount = pci_register_driver(&dgrs_pci_driver);
1599 if (cardcount)
1600 return cardcount;
1603 return 0; 1601 return 0;
1604} 1602}
1605 1603
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index c0af6fb1fbba..f8c9bcdab68b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -60,7 +60,6 @@
60#include <linux/etherdevice.h> 60#include <linux/etherdevice.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/skbuff.h> 62#include <linux/skbuff.h>
63#include <linux/version.h>
64#include <linux/spinlock.h> 63#include <linux/spinlock.h>
65#include <linux/crc32.h> 64#include <linux/crc32.h>
66#include <linux/mii.h> 65#include <linux/mii.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index eb169a8e8773..7a6aeae2c9fa 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1478 1478
1479 if(pci_dma_mapping_error(rx->dma_addr)) { 1479 if(pci_dma_mapping_error(rx->dma_addr)) {
1480 dev_kfree_skb_any(rx->skb); 1480 dev_kfree_skb_any(rx->skb);
1481 rx->skb = 0; 1481 rx->skb = NULL;
1482 rx->dma_addr = 0; 1482 rx->dma_addr = 0;
1483 return -ENOMEM; 1483 return -ENOMEM;
1484 } 1484 }
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
1764 if((err = e100_hw_init(nic))) 1764 if((err = e100_hw_init(nic)))
1765 goto err_clean_cbs; 1765 goto err_clean_cbs;
1766 e100_set_multicast_list(nic->netdev); 1766 e100_set_multicast_list(nic->netdev);
1767 e100_start_receiver(nic, 0); 1767 e100_start_receiver(nic, NULL);
1768 mod_timer(&nic->watchdog, jiffies); 1768 mod_timer(&nic->watchdog, jiffies);
1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, 1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
1770 nic->netdev->name, nic->netdev))) 1770 nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
1845 BMCR_LOOPBACK); 1845 BMCR_LOOPBACK);
1846 1846
1847 e100_start_receiver(nic, 0); 1847 e100_start_receiver(nic, NULL);
1848 1848
1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { 1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
1850 err = -ENOMEM; 1850 err = -ENOMEM;
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 1105543b9d88..e7ec96c964a9 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -4,7 +4,6 @@
4#include <linux/mii.h> 4#include <linux/mii.h>
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/version.h>
8#include <linux/list.h> 7#include <linux/list.h>
9 8
10#include <linux/fs_enet_pd.h> 9#include <linux/fs_enet_pd.h>
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 962580f2c4ab..54d294ad6df5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -90,7 +90,6 @@
90#include <asm/irq.h> 90#include <asm/irq.h>
91#include <asm/uaccess.h> 91#include <asm/uaccess.h>
92#include <linux/module.h> 92#include <linux/module.h>
93#include <linux/version.h>
94#include <linux/dma-mapping.h> 93#include <linux/dma-mapping.h>
95#include <linux/crc32.h> 94#include <linux/crc32.h>
96#include <linux/mii.h> 95#include <linux/mii.h>
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c77ca6c0d04a..220084e53341 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -43,7 +43,6 @@
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/version.h>
47#include <linux/crc32.h> 46#include <linux/crc32.h>
48#include <linux/workqueue.h> 47#include <linux/workqueue.h>
49#include <linux/ethtool.h> 48#include <linux/ethtool.h>
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 68e3578e7613..5a2d810ce575 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -34,7 +34,6 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/version.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
39#include <asm/types.h> 38#include <asm/types.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5a74d3d3dbe1..7263395d78bb 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -32,7 +32,6 @@
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/version.h>
36#include <linux/platform_device.h> 35#include <linux/platform_device.h>
37#include <asm/ocp.h> 36#include <asm/ocp.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index b71fab6e34f4..e92c17f6931c 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -96,7 +96,6 @@
96 96
97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ 97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */
98 98
99#include <linux/version.h>
100#include <linux/module.h> 99#include <linux/module.h>
101#include <linux/kernel.h> 100#include <linux/kernel.h>
102#include <linux/string.h> 101#include <linux/string.h>
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 94239f67f3a3..be191d80ef9c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -35,7 +35,6 @@
35 35
36#include <linux/config.h> 36#include <linux/config.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/errno.h> 39#include <linux/errno.h>
41#include <linux/ioport.h> 40#include <linux/ioport.h>
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 49e5467bdd73..6a3129bc15a6 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -46,10 +46,8 @@
46#include <linux/udp.h> 46#include <linux/udp.h>
47 47
48#ifdef CONFIG_SERIAL_8250 48#ifdef CONFIG_SERIAL_8250
49#include <linux/serial.h> 49#include <linux/serial_core.h>
50#include <asm/serial.h> 50#include <linux/serial_8250.h>
51#define IOC3_BAUD (22000000 / (3*16))
52#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
53#endif 51#endif
54 52
55#include <linux/netdevice.h> 53#include <linux/netdevice.h>
@@ -1146,12 +1144,11 @@ static inline int ioc3_is_menet(struct pci_dev *pdev)
1146 * around ioc3 oddities in this respect. 1144 * around ioc3 oddities in this respect.
1147 * 1145 *
1148 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. 1146 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
1149 * (IOC3_BAUD = (22000000 / (3*16)))
1150 */ 1147 */
1151 1148
1152static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) 1149static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1153{ 1150{
1154 struct serial_struct req; 1151 struct uart_port port;
1155 1152
1156 /* 1153 /*
1157 * We need to recognice and treat the fourth MENET serial as it 1154 * We need to recognice and treat the fourth MENET serial as it
@@ -1165,20 +1162,25 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1165 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3) 1162 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
1166 return; 1163 return;
1167 1164
1168 /* Register to interrupt zero because we share the interrupt with 1165 /*
1169 the serial driver which we don't properly support yet. */ 1166 * Register to interrupt zero because we share the interrupt with
1170 memset(&req, 0, sizeof(req)); 1167 * the serial driver which we don't properly support yet.
1171 req.irq = 0; 1168 *
1172 req.flags = IOC3_COM_FLAGS; 1169 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
1173 req.io_type = SERIAL_IO_MEM; 1170 * been registered.
1174 req.iomem_reg_shift = 0; 1171 */
1175 req.baud_base = IOC3_BAUD; 1172 memset(&port, 0, sizeof(port));
1176 1173 port.irq = 0;
1177 req.iomem_base = (unsigned char *) &ioc3->sregs.uarta; 1174 port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
1178 register_serial(&req); 1175 port.iotype = UPIO_MEM;
1179 1176 port.regshift = 0;
1180 req.iomem_base = (unsigned char *) &ioc3->sregs.uartb; 1177 port.uartclk = 22000000 / 3;
1181 register_serial(&req); 1178
1179 port.membase = (unsigned char *) &ioc3->sregs.uarta;
1180 serial8250_register_port(&port);
1181
1182 port.membase = (unsigned char *) &ioc3->sregs.uartb;
1183 serial8250_register_port(&port);
1182} 1184}
1183#endif 1185#endif
1184 1186
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0282771b1cbb..3137592d60c0 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1459,8 +1459,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1459 */ 1459 */
1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ 1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); 1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) 1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1463 return -EPERM; 1463 ret = -EPERM;
1464 goto out;
1465 }
1464 1466
1465 /* self->speed=irq->ifr_baudrate; */ 1467 /* self->speed=irq->ifr_baudrate; */
1466 /* toshoboe_setbaud(self); */ 1468 /* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1470 case SIOCSMEDIABUSY: /* Set media busy */ 1472 case SIOCSMEDIABUSY: /* Set media busy */
1471 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ 1473 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1472 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); 1474 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1473 if (!capable (CAP_NET_ADMIN)) 1475 if (!capable (CAP_NET_ADMIN)) {
1474 return -EPERM; 1476 ret = -EPERM;
1477 goto out;
1478 }
1475 irda_device_set_media_busy (self->netdev, TRUE); 1479 irda_device_set_media_busy (self->netdev, TRUE);
1476 break; 1480 break;
1477 case SIOCGRECEIVING: /* Check if we are receiving right now */ 1481 case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1483,7 +1487,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1483 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); 1487 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1484 ret = -EOPNOTSUPP; 1488 ret = -EOPNOTSUPP;
1485 } 1489 }
1486 1490out:
1487 spin_unlock_irqrestore(&self->spinlock, flags); 1491 spin_unlock_irqrestore(&self->spinlock, flags);
1488 return ret; 1492 return ret;
1489 1493
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index d86d8f055a6c..77eadf84cb2c 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -58,7 +58,6 @@
58 58
59#include <linux/config.h> 59#include <linux/config.h>
60#include <linux/module.h> 60#include <linux/module.h>
61#include <linux/version.h>
62#include <linux/types.h> 61#include <linux/types.h>
63#include <linux/errno.h> 62#include <linux/errno.h>
64#include <linux/ioport.h> 63#include <linux/ioport.h>
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index ce5761816a64..d8c99f038fa0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -15,7 +15,6 @@
15 * and fixed access to Sonic Sys card which masquerades as a Farallon 15 * and fixed access to Sonic Sys card which masquerades as a Farallon
16 * by rayk@knightsmanor.org */ 16 * by rayk@knightsmanor.org */
17 17
18#include <linux/version.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/types.h> 20#include <linux/types.h>
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index bcfda5192da0..f769f9b626ea 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -1,7 +1,6 @@
1#ifndef __MV643XX_ETH_H__ 1#ifndef __MV643XX_ETH_H__
2#define __MV643XX_ETH_H__ 2#define __MV643XX_ETH_H__
3 3
4#include <linux/version.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index a3c3fc9c0d8a..f857ae94d261 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -110,7 +110,6 @@
110#include <linux/init.h> 110#include <linux/init.h>
111#include <linux/ip.h> /* for iph */ 111#include <linux/ip.h> /* for iph */
112#include <linux/in.h> /* for IPPROTO_... */ 112#include <linux/in.h> /* for IPPROTO_... */
113#include <linux/eeprom.h>
114#include <linux/compiler.h> 113#include <linux/compiler.h>
115#include <linux/prefetch.h> 114#include <linux/prefetch.h>
116#include <linux/ethtool.h> 115#include <linux/ethtool.h>
@@ -445,7 +444,6 @@ struct ns83820 {
445 444
446 u32 MEAR_cache; 445 u32 MEAR_cache;
447 u32 IMR_cache; 446 u32 IMR_cache;
448 struct eeprom ee;
449 447
450 unsigned linkstate; 448 unsigned linkstate;
451 449
@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
1558 unsigned i; 1556 unsigned i;
1559 for (i=0; i<3; i++) { 1557 for (i=0; i<3; i++) {
1560 u32 data; 1558 u32 data;
1561#if 0 /* I've left this in as an example of how to use eeprom.h */ 1559
1562 data = eeprom_readw(&dev->ee, 0xa + 2 - i);
1563#else
1564 /* Read from the perfect match memory: this is loaded by 1560 /* Read from the perfect match memory: this is loaded by
1565 * the chip from the EEPROM via the EELOAD self test. 1561 * the chip from the EEPROM via the EELOAD self test.
1566 */ 1562 */
1567 writel(i*2, dev->base + RFCR); 1563 writel(i*2, dev->base + RFCR);
1568 data = readl(dev->base + RFDR); 1564 data = readl(dev->base + RFDR);
1569#endif 1565
1570 *mac++ = data; 1566 *mac++ = data;
1571 *mac++ = data >> 8; 1567 *mac++ = data >> 8;
1572 } 1568 }
@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1851 spin_lock_init(&dev->misc_lock); 1847 spin_lock_init(&dev->misc_lock);
1852 dev->pci_dev = pci_dev; 1848 dev->pci_dev = pci_dev;
1853 1849
1854 dev->ee.cache = &dev->MEAR_cache;
1855 dev->ee.lock = &dev->misc_lock;
1856 SET_MODULE_OWNER(ndev); 1850 SET_MODULE_OWNER(ndev);
1857 SET_NETDEV_DEV(ndev, &pci_dev->dev); 1851 SET_NETDEV_DEV(ndev, &pci_dev->dev);
1858 1852
@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1887 1881
1888 dev->IMR_cache = 0; 1882 dev->IMR_cache = 0;
1889 1883
1890 setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
1891 0);
1892
1893 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, 1884 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
1894 DRV_NAME, ndev); 1885 DRV_NAME, ndev);
1895 if (err) { 1886 if (err) {
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 59e8183c639e..400f652282d7 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <asm/string.h>
34 35
35#define PPP_VERSION "2.4.2" 36#define PPP_VERSION "2.4.2"
36 37
@@ -835,8 +836,11 @@ process_input_packet(struct asyncppp *ap)
835 err: 836 err:
836 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */ 837 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
837 ap->state = SC_PREV_ERROR; 838 ap->state = SC_PREV_ERROR;
838 if (skb) 839 if (skb) {
840 /* make skb appear as freshly allocated */
839 skb_trim(skb, 0); 841 skb_trim(skb, 0);
842 skb_reserve(skb, - skb_headroom(skb));
843 }
840} 844}
841 845
842/* Called when the tty driver has data for us. Runs parallel with the 846/* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
889 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); 893 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
890 if (skb == 0) 894 if (skb == 0)
891 goto nomem; 895 goto nomem;
892 /* Try to get the payload 4-byte aligned */ 896 ap->rpkt = skb;
897 }
898 if (skb->len == 0) {
899 /* Try to get the payload 4-byte aligned.
900 * This should match the
901 * PPP_ALLSTATIONS/PPP_UI/compressed tests in
902 * process_input_packet, but we do not have
903 * enough chars here to test buf[1] and buf[2].
904 */
893 if (buf[0] != PPP_ALLSTATIONS) 905 if (buf[0] != PPP_ALLSTATIONS)
894 skb_reserve(skb, 2 + (buf[0] & 1)); 906 skb_reserve(skb, 2 + (buf[0] & 1));
895 ap->rpkt = skb;
896 } 907 }
897 if (n > skb_tailroom(skb)) { 908 if (n > skb_tailroom(skb)) {
898 /* packet overflowed MRU */ 909 /* packet overflowed MRU */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index d3c9958b00d0..50430f79f8cf 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -137,13 +137,14 @@ struct ppp {
137 137
138/* 138/*
139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC, 139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP. 140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
141 * SC_MUST_COMP
141 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR. 142 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
142 * Bits in xstate: SC_COMP_RUN 143 * Bits in xstate: SC_COMP_RUN
143 */ 144 */
144#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \ 145#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
145 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \ 146 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
146 |SC_COMP_TCP|SC_REJ_COMP_TCP) 147 |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
147 148
148/* 149/*
149 * Private data structure for each channel. 150 * Private data structure for each channel.
@@ -1027,6 +1028,56 @@ ppp_xmit_process(struct ppp *ppp)
1027 ppp_xmit_unlock(ppp); 1028 ppp_xmit_unlock(ppp);
1028} 1029}
1029 1030
1031static inline struct sk_buff *
1032pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
1033{
1034 struct sk_buff *new_skb;
1035 int len;
1036 int new_skb_size = ppp->dev->mtu +
1037 ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
1038 int compressor_skb_size = ppp->dev->mtu +
1039 ppp->xcomp->comp_extra + PPP_HDRLEN;
1040 new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
1041 if (!new_skb) {
1042 if (net_ratelimit())
1043 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1044 return NULL;
1045 }
1046 if (ppp->dev->hard_header_len > PPP_HDRLEN)
1047 skb_reserve(new_skb,
1048 ppp->dev->hard_header_len - PPP_HDRLEN);
1049
1050 /* compressor still expects A/C bytes in hdr */
1051 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1052 new_skb->data, skb->len + 2,
1053 compressor_skb_size);
1054 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1055 kfree_skb(skb);
1056 skb = new_skb;
1057 skb_put(skb, len);
1058 skb_pull(skb, 2); /* pull off A/C bytes */
1059 } else if (len == 0) {
1060 /* didn't compress, or CCP not up yet */
1061 kfree_skb(new_skb);
1062 new_skb = skb;
1063 } else {
1064 /*
1065 * (len < 0)
1066 * MPPE requires that we do not send unencrypted
1067 * frames. The compressor will return -1 if we
1068 * should drop the frame. We cannot simply test
1069 * the compress_proto because MPPE and MPPC share
1070 * the same number.
1071 */
1072 if (net_ratelimit())
1073 printk(KERN_ERR "ppp: compressor dropped pkt\n");
1074 kfree_skb(skb);
1075 kfree_skb(new_skb);
1076 new_skb = NULL;
1077 }
1078 return new_skb;
1079}
1080
1030/* 1081/*
1031 * Compress and send a frame. 1082 * Compress and send a frame.
1032 * The caller should have locked the xmit path, 1083 * The caller should have locked the xmit path,
@@ -1113,29 +1164,14 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1113 /* try to do packet compression */ 1164 /* try to do packet compression */
1114 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 1165 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
1115 && proto != PPP_LCP && proto != PPP_CCP) { 1166 && proto != PPP_LCP && proto != PPP_CCP) {
1116 new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, 1167 if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
1117 GFP_ATOMIC); 1168 if (net_ratelimit())
1118 if (new_skb == 0) { 1169 printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
1119 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1120 goto drop; 1170 goto drop;
1121 } 1171 }
1122 if (ppp->dev->hard_header_len > PPP_HDRLEN) 1172 skb = pad_compress_skb(ppp, skb);
1123 skb_reserve(new_skb, 1173 if (!skb)
1124 ppp->dev->hard_header_len - PPP_HDRLEN); 1174 goto drop;
1125
1126 /* compressor still expects A/C bytes in hdr */
1127 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1128 new_skb->data, skb->len + 2,
1129 ppp->dev->mtu + PPP_HDRLEN);
1130 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1131 kfree_skb(skb);
1132 skb = new_skb;
1133 skb_put(skb, len);
1134 skb_pull(skb, 2); /* pull off A/C bytes */
1135 } else {
1136 /* didn't compress, or CCP not up yet */
1137 kfree_skb(new_skb);
1138 }
1139 } 1175 }
1140 1176
1141 /* 1177 /*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1155 return; 1191 return;
1156 1192
1157 drop: 1193 drop:
1158 kfree_skb(skb); 1194 if (skb)
1195 kfree_skb(skb);
1159 ++ppp->stats.tx_errors; 1196 ++ppp->stats.tx_errors;
1160} 1197}
1161 1198
@@ -1552,6 +1589,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1552 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) 1589 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
1553 skb = ppp_decompress_frame(ppp, skb); 1590 skb = ppp_decompress_frame(ppp, skb);
1554 1591
1592 if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
1593 goto err;
1594
1555 proto = PPP_PROTO(skb); 1595 proto = PPP_PROTO(skb);
1556 switch (proto) { 1596 switch (proto) {
1557 case PPP_VJC_COMP: 1597 case PPP_VJC_COMP:
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
new file mode 100644
index 000000000000..1985d1b57c45
--- /dev/null
+++ b/drivers/net/ppp_mppe.c
@@ -0,0 +1,724 @@
1/*
2 * ppp_mppe.c - interface MPPE to the PPP code.
3 * This version is for use with Linux kernel 2.6.14+
4 *
5 * By Frank Cusack <fcusack@fcusack.com>.
6 * Copyright (c) 2002,2003,2004 Google, Inc.
7 * All rights reserved.
8 *
9 * License:
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation is hereby granted, provided that the above copyright
12 * notice appears in all copies. This software is provided without any
13 * warranty, express or implied.
14 *
15 * ALTERNATIVELY, provided that this notice is retained in full, this product
16 * may be distributed under the terms of the GNU General Public License (GPL),
17 * in which case the provisions of the GPL apply INSTEAD OF those given above.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 *
34 * Changelog:
35 * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
36 * Only need extra skb padding on transmit, not receive.
37 * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
38 * Use Linux kernel 2.6 arc4 and sha1 routines rather than
39 * providing our own.
40 * 2/15/04 - TS: added #include <version.h> and testing for Kernel
41 * version before using
42 * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
43 * deprecated in 2.6
44 */
45
46#include <linux/config.h>
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/version.h>
50#include <linux/init.h>
51#include <linux/types.h>
52#include <linux/slab.h>
53#include <linux/string.h>
54#include <linux/crypto.h>
55#include <linux/mm.h>
56#include <linux/ppp_defs.h>
57#include <linux/ppp-comp.h>
58#include <asm/scatterlist.h>
59
60#include "ppp_mppe.h"
61
62MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
63MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
64MODULE_LICENSE("Dual BSD/GPL");
65MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
66MODULE_VERSION("1.0.2");
67
68static void
69setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
70{
71 sg[0].page = virt_to_page(address);
72 sg[0].offset = offset_in_page(address);
73 sg[0].length = length;
74}
75
76#define SHA1_PAD_SIZE 40
77
78/*
79 * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
80 * static data area. That means sha_pad needs to be kmalloc'd.
81 */
82
83struct sha_pad {
84 unsigned char sha_pad1[SHA1_PAD_SIZE];
85 unsigned char sha_pad2[SHA1_PAD_SIZE];
86};
87static struct sha_pad *sha_pad;
88
89static inline void sha_pad_init(struct sha_pad *shapad)
90{
91 memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
92 memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
93}
94
95/*
96 * State for an MPPE (de)compressor.
97 */
98struct ppp_mppe_state {
99 struct crypto_tfm *arc4;
100 struct crypto_tfm *sha1;
101 unsigned char *sha1_digest;
102 unsigned char master_key[MPPE_MAX_KEY_LEN];
103 unsigned char session_key[MPPE_MAX_KEY_LEN];
104 unsigned keylen; /* key length in bytes */
105 /* NB: 128-bit == 16, 40-bit == 8! */
106 /* If we want to support 56-bit, */
107 /* the unit has to change to bits */
108 unsigned char bits; /* MPPE control bits */
109 unsigned ccount; /* 12-bit coherency count (seqno) */
110 unsigned stateful; /* stateful mode flag */
111 int discard; /* stateful mode packet loss flag */
112 int sanity_errors; /* take down LCP if too many */
113 int unit;
114 int debug;
115 struct compstat stats;
116};
117
118/* struct ppp_mppe_state.bits definitions */
119#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
120#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
121#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
122#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
123
124#define MPPE_BIT_FLUSHED MPPE_BIT_A
125#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
126
127#define MPPE_BITS(p) ((p)[4] & 0xf0)
128#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
129#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
130
131#define MPPE_OVHD 2 /* MPPE overhead/packet */
132#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
133
134/*
135 * Key Derivation, from RFC 3078, RFC 3079.
136 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
137 */
138static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
139{
140 struct scatterlist sg[4];
141
142 setup_sg(&sg[0], state->master_key, state->keylen);
143 setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
144 setup_sg(&sg[2], state->session_key, state->keylen);
145 setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
146
147 crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
148
149 memcpy(InterimKey, state->sha1_digest, state->keylen);
150}
151
152/*
153 * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
154 * Well, not what's written there, but rather what they meant.
155 */
156static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
157{
158 unsigned char InterimKey[MPPE_MAX_KEY_LEN];
159 struct scatterlist sg_in[1], sg_out[1];
160
161 get_new_key_from_sha(state, InterimKey);
162 if (!initial_key) {
163 crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
164 setup_sg(sg_in, InterimKey, state->keylen);
165 setup_sg(sg_out, state->session_key, state->keylen);
166 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
167 state->keylen) != 0) {
168 printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
169 }
170 } else {
171 memcpy(state->session_key, InterimKey, state->keylen);
172 }
173 if (state->keylen == 8) {
174 /* See RFC 3078 */
175 state->session_key[0] = 0xd1;
176 state->session_key[1] = 0x26;
177 state->session_key[2] = 0x9e;
178 }
179 crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
180}
181
182/*
183 * Allocate space for a (de)compressor.
184 */
185static void *mppe_alloc(unsigned char *options, int optlen)
186{
187 struct ppp_mppe_state *state;
188 unsigned int digestsize;
189
190 if (optlen != CILEN_MPPE + sizeof(state->master_key)
191 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
192 goto out;
193
194 state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
195 if (state == NULL)
196 goto out;
197
198 memset(state, 0, sizeof(*state));
199
200 state->arc4 = crypto_alloc_tfm("arc4", 0);
201 if (!state->arc4)
202 goto out_free;
203
204 state->sha1 = crypto_alloc_tfm("sha1", 0);
205 if (!state->sha1)
206 goto out_free;
207
208 digestsize = crypto_tfm_alg_digestsize(state->sha1);
209 if (digestsize < MPPE_MAX_KEY_LEN)
210 goto out_free;
211
212 state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
213 if (!state->sha1_digest)
214 goto out_free;
215
216 /* Save keys. */
217 memcpy(state->master_key, &options[CILEN_MPPE],
218 sizeof(state->master_key));
219 memcpy(state->session_key, state->master_key,
220 sizeof(state->master_key));
221
222 /*
223 * We defer initial key generation until mppe_init(), as mppe_alloc()
224 * is called frequently during negotiation.
225 */
226
227 return (void *)state;
228
229 out_free:
230 if (state->sha1_digest)
231 kfree(state->sha1_digest);
232 if (state->sha1)
233 crypto_free_tfm(state->sha1);
234 if (state->arc4)
235 crypto_free_tfm(state->arc4);
236 kfree(state);
237 out:
238 return NULL;
239}
240
241/*
242 * Deallocate space for a (de)compressor.
243 */
244static void mppe_free(void *arg)
245{
246 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
247 if (state) {
248 if (state->sha1_digest)
249 kfree(state->sha1_digest);
250 if (state->sha1)
251 crypto_free_tfm(state->sha1);
252 if (state->arc4)
253 crypto_free_tfm(state->arc4);
254 kfree(state);
255 }
256}
257
258/*
259 * Initialize (de)compressor state.
260 */
261static int
262mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
263 const char *debugstr)
264{
265 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
266 unsigned char mppe_opts;
267
268 if (optlen != CILEN_MPPE
269 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
270 return 0;
271
272 MPPE_CI_TO_OPTS(&options[2], mppe_opts);
273 if (mppe_opts & MPPE_OPT_128)
274 state->keylen = 16;
275 else if (mppe_opts & MPPE_OPT_40)
276 state->keylen = 8;
277 else {
278 printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
279 unit);
280 return 0;
281 }
282 if (mppe_opts & MPPE_OPT_STATEFUL)
283 state->stateful = 1;
284
285 /* Generate the initial session key. */
286 mppe_rekey(state, 1);
287
288 if (debug) {
289 int i;
290 char mkey[sizeof(state->master_key) * 2 + 1];
291 char skey[sizeof(state->session_key) * 2 + 1];
292
293 printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
294 debugstr, unit, (state->keylen == 16) ? 128 : 40,
295 (state->stateful) ? "stateful" : "stateless");
296
297 for (i = 0; i < sizeof(state->master_key); i++)
298 sprintf(mkey + i * 2, "%02x", state->master_key[i]);
299 for (i = 0; i < sizeof(state->session_key); i++)
300 sprintf(skey + i * 2, "%02x", state->session_key[i]);
301 printk(KERN_DEBUG
302 "%s[%d]: keys: master: %s initial session: %s\n",
303 debugstr, unit, mkey, skey);
304 }
305
306 /*
307 * Initialize the coherency count. The initial value is not specified
308 * in RFC 3078, but we can make a reasonable assumption that it will
309 * start at 0. Setting it to the max here makes the comp/decomp code
310 * do the right thing (determined through experiment).
311 */
312 state->ccount = MPPE_CCOUNT_SPACE - 1;
313
314 /*
315 * Note that even though we have initialized the key table, we don't
316 * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
317 */
318 state->bits = MPPE_BIT_ENCRYPTED;
319
320 state->unit = unit;
321 state->debug = debug;
322
323 return 1;
324}
325
326static int
327mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
328 int hdrlen, int debug)
329{
330 /* ARGSUSED */
331 return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
332}
333
334/*
335 * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
336 * tell the compressor to rekey. Note that we MUST NOT rekey for
337 * every CCP Reset-Request; we only rekey on the next xmit packet.
338 * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
339 * So, rekeying for every CCP Reset-Request is broken as the peer will not
340 * know how many times we've rekeyed. (If we rekey and THEN get another
341 * CCP Reset-Request, we must rekey again.)
342 */
343static void mppe_comp_reset(void *arg)
344{
345 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
346
347 state->bits |= MPPE_BIT_FLUSHED;
348}
349
350/*
351 * Compress (encrypt) a packet.
352 * It's strange to call this a compressor, since the output is always
353 * MPPE_OVHD + 2 bytes larger than the input.
354 */
355static int
356mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
357 int isize, int osize)
358{
359 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
360 int proto;
361 struct scatterlist sg_in[1], sg_out[1];
362
363 /*
364 * Check that the protocol is in the range we handle.
365 */
366 proto = PPP_PROTOCOL(ibuf);
367 if (proto < 0x0021 || proto > 0x00fa)
368 return 0;
369
370 /* Make sure we have enough room to generate an encrypted packet. */
371 if (osize < isize + MPPE_OVHD + 2) {
372 /* Drop the packet if we should encrypt it, but can't. */
373 printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
374 "(have: %d need: %d)\n", state->unit,
375 osize, osize + MPPE_OVHD + 2);
376 return -1;
377 }
378
379 osize = isize + MPPE_OVHD + 2;
380
381 /*
382 * Copy over the PPP header and set control bits.
383 */
384 obuf[0] = PPP_ADDRESS(ibuf);
385 obuf[1] = PPP_CONTROL(ibuf);
386 obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
387 obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
388 obuf += PPP_HDRLEN;
389
390 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
391 if (state->debug >= 7)
392 printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
393 state->ccount);
394 obuf[0] = state->ccount >> 8;
395 obuf[1] = state->ccount & 0xff;
396
397 if (!state->stateful || /* stateless mode */
398 ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
399 (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
400 /* We must rekey */
401 if (state->debug && state->stateful)
402 printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
403 state->unit);
404 mppe_rekey(state, 0);
405 state->bits |= MPPE_BIT_FLUSHED;
406 }
407 obuf[0] |= state->bits;
408 state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
409
410 obuf += MPPE_OVHD;
411 ibuf += 2; /* skip to proto field */
412 isize -= 2;
413
414 /* Encrypt packet */
415 setup_sg(sg_in, ibuf, isize);
416 setup_sg(sg_out, obuf, osize);
417 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
418 printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
419 return -1;
420 }
421
422 state->stats.unc_bytes += isize;
423 state->stats.unc_packets++;
424 state->stats.comp_bytes += osize;
425 state->stats.comp_packets++;
426
427 return osize;
428}
429
430/*
431 * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
432 * to look bad ... and the longer the link is up the worse it will get.
433 */
434static void mppe_comp_stats(void *arg, struct compstat *stats)
435{
436 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
437
438 *stats = state->stats;
439}
440
441static int
442mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
443 int hdrlen, int mru, int debug)
444{
445 /* ARGSUSED */
446 return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
447}
448
449/*
450 * We received a CCP Reset-Ack. Just ignore it.
451 */
452static void mppe_decomp_reset(void *arg)
453{
454 /* ARGSUSED */
455 return;
456}
457
458/*
459 * Decompress (decrypt) an MPPE packet.
460 */
461static int
462mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
463 int osize)
464{
465 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
466 unsigned ccount;
467 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
468 int sanity = 0;
469 struct scatterlist sg_in[1], sg_out[1];
470
471 if (isize <= PPP_HDRLEN + MPPE_OVHD) {
472 if (state->debug)
473 printk(KERN_DEBUG
474 "mppe_decompress[%d]: short pkt (%d)\n",
475 state->unit, isize);
476 return DECOMP_ERROR;
477 }
478
479 /*
480 * Make sure we have enough room to decrypt the packet.
481 * Note that for our test we only subtract 1 byte whereas in
482 * mppe_compress() we added 2 bytes (+MPPE_OVHD);
483 * this is to account for possible PFC.
484 */
485 if (osize < isize - MPPE_OVHD - 1) {
486 printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
487 "(have: %d need: %d)\n", state->unit,
488 osize, isize - MPPE_OVHD - 1);
489 return DECOMP_ERROR;
490 }
491 osize = isize - MPPE_OVHD - 2; /* assume no PFC */
492
493 ccount = MPPE_CCOUNT(ibuf);
494 if (state->debug >= 7)
495 printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
496 state->unit, ccount);
497
498 /* sanity checks -- terminate with extreme prejudice */
499 if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
500 printk(KERN_DEBUG
501 "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
502 state->unit);
503 state->sanity_errors += 100;
504 sanity = 1;
505 }
506 if (!state->stateful && !flushed) {
507 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
508 "stateless mode!\n", state->unit);
509 state->sanity_errors += 100;
510 sanity = 1;
511 }
512 if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
513 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
514 "flag packet!\n", state->unit);
515 state->sanity_errors += 100;
516 sanity = 1;
517 }
518
519 if (sanity) {
520 if (state->sanity_errors < SANITY_MAX)
521 return DECOMP_ERROR;
522 else
523 /*
524 * Take LCP down if the peer is sending too many bogons.
525 * We don't want to do this for a single or just a few
526 * instances since it could just be due to packet corruption.
527 */
528 return DECOMP_FATALERROR;
529 }
530
531 /*
532 * Check the coherency count.
533 */
534
535 if (!state->stateful) {
536 /* RFC 3078, sec 8.1. Rekey for every packet. */
537 while (state->ccount != ccount) {
538 mppe_rekey(state, 0);
539 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
540 }
541 } else {
542 /* RFC 3078, sec 8.2. */
543 if (!state->discard) {
544 /* normal state */
545 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
546 if (ccount != state->ccount) {
547 /*
548 * (ccount > state->ccount)
549 * Packet loss detected, enter the discard state.
550 * Signal the peer to rekey (by sending a CCP Reset-Request).
551 */
552 state->discard = 1;
553 return DECOMP_ERROR;
554 }
555 } else {
556 /* discard state */
557 if (!flushed) {
558 /* ccp.c will be silent (no additional CCP Reset-Requests). */
559 return DECOMP_ERROR;
560 } else {
561 /* Rekey for every missed "flag" packet. */
562 while ((ccount & ~0xff) !=
563 (state->ccount & ~0xff)) {
564 mppe_rekey(state, 0);
565 state->ccount =
566 (state->ccount +
567 256) % MPPE_CCOUNT_SPACE;
568 }
569
570 /* reset */
571 state->discard = 0;
572 state->ccount = ccount;
573 /*
574 * Another problem with RFC 3078 here. It implies that the
575 * peer need not send a Reset-Ack packet. But RFC 1962
576 * requires it. Hopefully, M$ does send a Reset-Ack; even
577 * though it isn't required for MPPE synchronization, it is
578 * required to reset CCP state.
579 */
580 }
581 }
582 if (flushed)
583 mppe_rekey(state, 0);
584 }
585
586 /*
587 * Fill in the first part of the PPP header. The protocol field
588 * comes from the decrypted data.
589 */
590 obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
591 obuf[1] = PPP_CONTROL(ibuf); /* +1 */
592 obuf += 2;
593 ibuf += PPP_HDRLEN + MPPE_OVHD;
594 isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
595 /* net osize: isize-4 */
596
597 /*
598 * Decrypt the first byte in order to check if it is
599 * a compressed or uncompressed protocol field.
600 */
601 setup_sg(sg_in, ibuf, 1);
602 setup_sg(sg_out, obuf, 1);
603 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
604 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
605 return DECOMP_ERROR;
606 }
607
608 /*
609 * Do PFC decompression.
610 * This would be nicer if we were given the actual sk_buff
611 * instead of a char *.
612 */
613 if ((obuf[0] & 0x01) != 0) {
614 obuf[1] = obuf[0];
615 obuf[0] = 0;
616 obuf++;
617 osize++;
618 }
619
620 /* And finally, decrypt the rest of the packet. */
621 setup_sg(sg_in, ibuf + 1, isize - 1);
622 setup_sg(sg_out, obuf + 1, osize - 1);
623 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
624 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
625 return DECOMP_ERROR;
626 }
627
628 state->stats.unc_bytes += osize;
629 state->stats.unc_packets++;
630 state->stats.comp_bytes += isize;
631 state->stats.comp_packets++;
632
633 /* good packet credit */
634 state->sanity_errors >>= 1;
635
636 return osize;
637}
638
639/*
640 * Incompressible data has arrived (this should never happen!).
641 * We should probably drop the link if the protocol is in the range
642 * of what should be encrypted. At the least, we should drop this
643 * packet. (How to do this?)
644 */
645static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
646{
647 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
648
649 if (state->debug &&
650 (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
651 printk(KERN_DEBUG
652 "mppe_incomp[%d]: incompressible (unencrypted) data! "
653 "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
654
655 state->stats.inc_bytes += icnt;
656 state->stats.inc_packets++;
657 state->stats.unc_bytes += icnt;
658 state->stats.unc_packets++;
659}
660
661/*************************************************************
662 * Module interface table
663 *************************************************************/
664
665/*
666 * Procedures exported to if_ppp.c.
667 */
668static struct compressor ppp_mppe = {
669 .compress_proto = CI_MPPE,
670 .comp_alloc = mppe_alloc,
671 .comp_free = mppe_free,
672 .comp_init = mppe_comp_init,
673 .comp_reset = mppe_comp_reset,
674 .compress = mppe_compress,
675 .comp_stat = mppe_comp_stats,
676 .decomp_alloc = mppe_alloc,
677 .decomp_free = mppe_free,
678 .decomp_init = mppe_decomp_init,
679 .decomp_reset = mppe_decomp_reset,
680 .decompress = mppe_decompress,
681 .incomp = mppe_incomp,
682 .decomp_stat = mppe_comp_stats,
683 .owner = THIS_MODULE,
684 .comp_extra = MPPE_PAD,
685};
686
687/*
688 * ppp_mppe_init()
689 *
690 * Prior to allowing load, try to load the arc4 and sha1 crypto
691 * libraries. The actual use will be allocated later, but
692 * this way the module will fail to insmod if they aren't available.
693 */
694
695static int __init ppp_mppe_init(void)
696{
697 int answer;
698 if (!(crypto_alg_available("arc4", 0) &&
699 crypto_alg_available("sha1", 0)))
700 return -ENODEV;
701
702 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
703 if (!sha_pad)
704 return -ENOMEM;
705 sha_pad_init(sha_pad);
706
707 answer = ppp_register_compressor(&ppp_mppe);
708
709 if (answer == 0)
710 printk(KERN_INFO "PPP MPPE Compression module registered\n");
711 else
712 kfree(sha_pad);
713
714 return answer;
715}
716
717static void __exit ppp_mppe_cleanup(void)
718{
719 ppp_unregister_compressor(&ppp_mppe);
720 kfree(sha_pad);
721}
722
723module_init(ppp_mppe_init);
724module_exit(ppp_mppe_cleanup);
diff --git a/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
new file mode 100644
index 000000000000..7a14e058c668
--- /dev/null
+++ b/drivers/net/ppp_mppe.h
@@ -0,0 +1,86 @@
1#define MPPE_PAD 4 /* MPPE growth per frame */
2#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
3
4/* option bits for ccp_options.mppe */
5#define MPPE_OPT_40 0x01 /* 40 bit */
6#define MPPE_OPT_128 0x02 /* 128 bit */
7#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
8/* unsupported opts */
9#define MPPE_OPT_56 0x08 /* 56 bit */
10#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
11#define MPPE_OPT_D 0x20 /* Unknown */
12#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
13#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
14
15/*
16 * This is not nice ... the alternative is a bitfield struct though.
17 * And unfortunately, we cannot share the same bits for the option
18 * names above since C and H are the same bit. We could do a u_int32
19 * but then we have to do a htonl() all the time and/or we still need
20 * to know which octet is which.
21 */
22#define MPPE_C_BIT 0x01 /* MPPC */
23#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
24#define MPPE_L_BIT 0x20 /* 40-bit */
25#define MPPE_S_BIT 0x40 /* 128-bit */
26#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
27#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
28
29/* Does not include H bit; used for least significant octet only. */
30#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
31
32/* Build a CI from mppe opts (see RFC 3078) */
33#define MPPE_OPTS_TO_CI(opts, ci) \
34 do { \
35 u_char *ptr = ci; /* u_char[4] */ \
36 \
37 /* H bit */ \
38 if (opts & MPPE_OPT_STATEFUL) \
39 *ptr++ = 0x0; \
40 else \
41 *ptr++ = MPPE_H_BIT; \
42 *ptr++ = 0; \
43 *ptr++ = 0; \
44 \
45 /* S,L bits */ \
46 *ptr = 0; \
47 if (opts & MPPE_OPT_128) \
48 *ptr |= MPPE_S_BIT; \
49 if (opts & MPPE_OPT_40) \
50 *ptr |= MPPE_L_BIT; \
51 /* M,D,C bits not supported */ \
52 } while (/* CONSTCOND */ 0)
53
54/* The reverse of the above */
55#define MPPE_CI_TO_OPTS(ci, opts) \
56 do { \
57 u_char *ptr = ci; /* u_char[4] */ \
58 \
59 opts = 0; \
60 \
61 /* H bit */ \
62 if (!(ptr[0] & MPPE_H_BIT)) \
63 opts |= MPPE_OPT_STATEFUL; \
64 \
65 /* S,L bits */ \
66 if (ptr[3] & MPPE_S_BIT) \
67 opts |= MPPE_OPT_128; \
68 if (ptr[3] & MPPE_L_BIT) \
69 opts |= MPPE_OPT_40; \
70 \
71 /* M,D,C bits */ \
72 if (ptr[3] & MPPE_M_BIT) \
73 opts |= MPPE_OPT_56; \
74 if (ptr[3] & MPPE_D_BIT) \
75 opts |= MPPE_OPT_D; \
76 if (ptr[3] & MPPE_C_BIT) \
77 opts |= MPPE_OPT_MPPC; \
78 \
79 /* Other bits */ \
80 if (ptr[0] & ~MPPE_H_BIT) \
81 opts |= MPPE_OPT_UNKNOWN; \
82 if (ptr[1] || ptr[2]) \
83 opts |= MPPE_OPT_UNKNOWN; \
84 if (ptr[3] & ~MPPE_ALL_BITS) \
85 opts |= MPPE_OPT_UNKNOWN; \
86 } while (/* CONSTCOND */ 0)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 0745dd9d01f3..e57df8dfe6b4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -55,7 +55,6 @@
55#include <linux/timex.h> 55#include <linux/timex.h>
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/ethtool.h> 57#include <linux/ethtool.h>
58#include <linux/version.h>
59#include <linux/workqueue.h> 58#include <linux/workqueue.h>
60#include <linux/if_vlan.h> 59#include <linux/if_vlan.h>
61 60
@@ -1532,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
1532#define LINK_UP_DOWN_INTERRUPT 1 1531#define LINK_UP_DOWN_INTERRUPT 1
1533#define MAC_RMAC_ERR_TIMER 2 1532#define MAC_RMAC_ERR_TIMER 2
1534 1533
1535int s2io_link_fault_indication(nic_t *nic) 1534static int s2io_link_fault_indication(nic_t *nic)
1536{ 1535{
1537 if (nic->intr_type != INTA) 1536 if (nic->intr_type != INTA)
1538 return MAC_RMAC_ERR_TIMER; 1537 return MAC_RMAC_ERR_TIMER;
@@ -1864,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
1864 * 1863 *
1865 */ 1864 */
1866 1865
1867void fix_mac_address(nic_t * sp) 1866static void fix_mac_address(nic_t * sp)
1868{ 1867{
1869 XENA_dev_config_t __iomem *bar0 = sp->bar0; 1868 XENA_dev_config_t __iomem *bar0 = sp->bar0;
1870 u64 val64; 1869 u64 val64;
@@ -2160,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2160 * SUCCESS on success or an appropriate -ve value on failure. 2159 * SUCCESS on success or an appropriate -ve value on failure.
2161 */ 2160 */
2162 2161
2163int fill_rx_buffers(struct s2io_nic *nic, int ring_no) 2162static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2164{ 2163{
2165 struct net_device *dev = nic->dev; 2164 struct net_device *dev = nic->dev;
2166 struct sk_buff *skb; 2165 struct sk_buff *skb;
@@ -2831,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
2831 * SUCCESS on success and FAILURE on failure. 2830 * SUCCESS on success and FAILURE on failure.
2832 */ 2831 */
2833 2832
2834int wait_for_cmd_complete(nic_t * sp) 2833static int wait_for_cmd_complete(nic_t * sp)
2835{ 2834{
2836 XENA_dev_config_t __iomem *bar0 = sp->bar0; 2835 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2837 int ret = FAILURE, cnt = 0; 2836 int ret = FAILURE, cnt = 0;
@@ -3077,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
3077 return SUCCESS; 3076 return SUCCESS;
3078} 3077}
3079 3078
3080int wait_for_msix_trans(nic_t *nic, int i) 3079static int wait_for_msix_trans(nic_t *nic, int i)
3081{ 3080{
3082 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3081 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3083 u64 val64; 3082 u64 val64;
@@ -3116,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic)
3116 } 3115 }
3117} 3116}
3118 3117
3119void store_xmsi_data(nic_t *nic) 3118static void store_xmsi_data(nic_t *nic)
3120{ 3119{
3121 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3120 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3122 u64 val64, addr, data; 3121 u64 val64, addr, data;
@@ -3288,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
3288 * file on failure. 3287 * file on failure.
3289 */ 3288 */
3290 3289
3291int s2io_open(struct net_device *dev) 3290static int s2io_open(struct net_device *dev)
3292{ 3291{
3293 nic_t *sp = dev->priv; 3292 nic_t *sp = dev->priv;
3294 int err = 0; 3293 int err = 0;
@@ -3418,7 +3417,7 @@ hw_init_failed:
3418 * file on failure. 3417 * file on failure.
3419 */ 3418 */
3420 3419
3421int s2io_close(struct net_device *dev) 3420static int s2io_close(struct net_device *dev)
3422{ 3421{
3423 nic_t *sp = dev->priv; 3422 nic_t *sp = dev->priv;
3424 int i; 3423 int i;
@@ -3467,7 +3466,7 @@ int s2io_close(struct net_device *dev)
3467 * 0 on success & 1 on failure. 3466 * 0 on success & 1 on failure.
3468 */ 3467 */
3469 3468
3470int s2io_xmit(struct sk_buff *skb, struct net_device *dev) 3469static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
3471{ 3470{
3472 nic_t *sp = dev->priv; 3471 nic_t *sp = dev->priv;
3473 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; 3472 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3913,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
3913 * pointer to the updated net_device_stats structure. 3912 * pointer to the updated net_device_stats structure.
3914 */ 3913 */
3915 3914
3916struct net_device_stats *s2io_get_stats(struct net_device *dev) 3915static struct net_device_stats *s2io_get_stats(struct net_device *dev)
3917{ 3916{
3918 nic_t *sp = dev->priv; 3917 nic_t *sp = dev->priv;
3919 mac_info_t *mac_control; 3918 mac_info_t *mac_control;
@@ -5106,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
5106 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; 5105 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
5107} 5106}
5108 5107
5109int s2io_ethtool_get_regs_len(struct net_device *dev) 5108static int s2io_ethtool_get_regs_len(struct net_device *dev)
5110{ 5109{
5111 return (XENA_REG_SPACE); 5110 return (XENA_REG_SPACE);
5112} 5111}
5113 5112
5114 5113
5115u32 s2io_ethtool_get_rx_csum(struct net_device * dev) 5114static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
5116{ 5115{
5117 nic_t *sp = dev->priv; 5116 nic_t *sp = dev->priv;
5118 5117
5119 return (sp->rx_csum); 5118 return (sp->rx_csum);
5120} 5119}
5121int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) 5120
5121static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5122{ 5122{
5123 nic_t *sp = dev->priv; 5123 nic_t *sp = dev->priv;
5124 5124
@@ -5129,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5129 5129
5130 return 0; 5130 return 0;
5131} 5131}
5132int s2io_get_eeprom_len(struct net_device *dev) 5132
5133static int s2io_get_eeprom_len(struct net_device *dev)
5133{ 5134{
5134 return (XENA_EEPROM_SPACE); 5135 return (XENA_EEPROM_SPACE);
5135} 5136}
5136 5137
5137int s2io_ethtool_self_test_count(struct net_device *dev) 5138static int s2io_ethtool_self_test_count(struct net_device *dev)
5138{ 5139{
5139 return (S2IO_TEST_LEN); 5140 return (S2IO_TEST_LEN);
5140} 5141}
5141void s2io_ethtool_get_strings(struct net_device *dev, 5142
5142 u32 stringset, u8 * data) 5143static void s2io_ethtool_get_strings(struct net_device *dev,
5144 u32 stringset, u8 * data)
5143{ 5145{
5144 switch (stringset) { 5146 switch (stringset) {
5145 case ETH_SS_TEST: 5147 case ETH_SS_TEST:
@@ -5155,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
5155 return (S2IO_STAT_LEN); 5157 return (S2IO_STAT_LEN);
5156} 5158}
5157 5159
5158int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 5160static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
5159{ 5161{
5160 if (data) 5162 if (data)
5161 dev->features |= NETIF_F_IP_CSUM; 5163 dev->features |= NETIF_F_IP_CSUM;
@@ -5208,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
5208 * function always return EOPNOTSUPPORTED 5210 * function always return EOPNOTSUPPORTED
5209 */ 5211 */
5210 5212
5211int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 5213static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5212{ 5214{
5213 return -EOPNOTSUPP; 5215 return -EOPNOTSUPP;
5214} 5216}
@@ -5224,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5224 * file on failure. 5226 * file on failure.
5225 */ 5227 */
5226 5228
5227int s2io_change_mtu(struct net_device *dev, int new_mtu) 5229static int s2io_change_mtu(struct net_device *dev, int new_mtu)
5228{ 5230{
5229 nic_t *sp = dev->priv; 5231 nic_t *sp = dev->priv;
5230 5232
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
index 308440bd0e12..91b8d4f45904 100644
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -39,9 +39,6 @@
39#ifndef __INC_SKDRV1ST_H 39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H 40#define __INC_SKDRV1ST_H
41 41
42/* Check kernel version */
43#include <linux/version.h>
44
45typedef struct s_AC SK_AC; 42typedef struct s_AC SK_AC;
46 43
47/* Set card versions */ 44/* Set card versions */
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4c56b8d8221b..e5d6d95960c7 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -93,7 +93,6 @@ History:
93#include <linux/mca-legacy.h> 93#include <linux/mca-legacy.h>
94#include <linux/init.h> 94#include <linux/init.h>
95#include <linux/module.h> 95#include <linux/module.h>
96#include <linux/version.h>
97#include <linux/netdevice.h> 96#include <linux/netdevice.h>
98#include <linux/etherdevice.h> 97#include <linux/etherdevice.h>
99#include <linux/skbuff.h> 98#include <linux/skbuff.h>
diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
index 7e7c99582746..d6fa1823dfa6 100644
--- a/drivers/net/sk_mca.h
+++ b/drivers/net/sk_mca.h
@@ -1,5 +1,3 @@
1#include <linux/version.h>
2
3#ifndef _SK_MCA_INCLUDE_ 1#ifndef _SK_MCA_INCLUDE_
4#define _SK_MCA_INCLUDE_ 2#define _SK_MCA_INCLUDE_
5 3
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 572f121b1f4e..596c93b12daa 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,12 +37,13 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/crc32.h> 38#include <linux/crc32.h>
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/mii.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41 42
42#include "skge.h" 43#include "skge.h"
43 44
44#define DRV_NAME "skge" 45#define DRV_NAME "skge"
45#define DRV_VERSION "1.1" 46#define DRV_VERSION "1.2"
46#define PFX DRV_NAME " " 47#define PFX DRV_NAME " "
47 48
48#define DEFAULT_TX_RING_SIZE 128 49#define DEFAULT_TX_RING_SIZE 128
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
88static int skge_up(struct net_device *dev); 89static int skge_up(struct net_device *dev);
89static int skge_down(struct net_device *dev); 90static int skge_down(struct net_device *dev);
90static void skge_tx_clean(struct skge_port *skge); 91static void skge_tx_clean(struct skge_port *skge);
91static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 92static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
92static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 93static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
93static void genesis_get_stats(struct skge_port *skge, u64 *data); 94static void genesis_get_stats(struct skge_port *skge, u64 *data);
94static void yukon_get_stats(struct skge_port *skge, u64 *data); 95static void yukon_get_stats(struct skge_port *skge, u64 *data);
95static void yukon_init(struct skge_hw *hw, int port); 96static void yukon_init(struct skge_hw *hw, int port);
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
129 regs->len - B3_RI_WTO_R1); 130 regs->len - B3_RI_WTO_R1);
130} 131}
131 132
132/* Wake on Lan only supported on Yukon chps with rev 1 or above */ 133/* Wake on Lan only supported on Yukon chips with rev 1 or above */
133static int wol_supported(const struct skge_hw *hw) 134static int wol_supported(const struct skge_hw *hw)
134{ 135{
135 return !((hw->chip_id == CHIP_ID_GENESIS || 136 return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
169 return 0; 170 return 0;
170} 171}
171 172
172/* Determine supported/adverised modes based on hardware. 173/* Determine supported/advertised modes based on hardware.
173 * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx 174 * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
174 */ 175 */
175static u32 skge_supported_modes(const struct skge_hw *hw) 176static u32 skge_supported_modes(const struct skge_hw *hw)
176{ 177{
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
531 return 78215; /* or: 78.125 MHz */ 532 return 78215; /* or: 78.125 MHz */
532} 533}
533 534
534/* Chip hz to microseconds */ 535/* Chip HZ to microseconds */
535static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) 536static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
536{ 537{
537 return (ticks * 1000) / hwkhz(hw); 538 return (ticks * 1000) / hwkhz(hw);
538} 539}
539 540
540/* Microseconds to chip hz */ 541/* Microseconds to chip HZ */
541static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) 542static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
542{ 543{
543 return hwkhz(hw) * usec / 1000; 544 return hwkhz(hw) * usec / 1000;
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
883 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); 884 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
884} 885}
885 886
886static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) 887static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
887{ 888{
888 int i; 889 int i;
889 u16 v;
890 890
891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
892 v = xm_read16(hw, port, XM_PHY_DATA); 892 xm_read16(hw, port, XM_PHY_DATA);
893 893
894 /* Need to wait for external PHY */ 894 /* Need to wait for external PHY */
895 for (i = 0; i < PHY_RETRIES; i++) { 895 for (i = 0; i < PHY_RETRIES; i++) {
896 udelay(1); 896 udelay(1);
897 if (xm_read16(hw, port, XM_MMU_CMD) 897 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
898 & XM_MMU_PHY_RDY)
899 goto ready; 898 goto ready;
900 } 899 }
901 900
902 printk(KERN_WARNING PFX "%s: phy read timed out\n", 901 return -ETIMEDOUT;
903 hw->dev[port]->name);
904 return 0;
905 ready: 902 ready:
906 v = xm_read16(hw, port, XM_PHY_DATA); 903 *val = xm_read16(hw, port, XM_PHY_DATA);
907 904
905 return 0;
906}
907
908static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
909{
910 u16 v = 0;
911 if (__xm_phy_read(hw, port, reg, &v))
912 printk(KERN_WARNING PFX "%s: phy read timed out\n",
913 hw->dev[port]->name);
908 return v; 914 return v;
909} 915}
910 916
911static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) 917static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
912{ 918{
913 int i; 919 int i;
914 920
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
918 goto ready; 924 goto ready;
919 udelay(1); 925 udelay(1);
920 } 926 }
921 printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", 927 return -EIO;
922 hw->dev[port]->name);
923
924 928
925 ready: 929 ready:
926 xm_write16(hw, port, XM_PHY_DATA, val); 930 xm_write16(hw, port, XM_PHY_DATA, val);
927 for (i = 0; i < PHY_RETRIES; i++) { 931 return 0;
928 udelay(1);
929 if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
930 return;
931 }
932 printk(KERN_WARNING PFX "%s: phy write timed out\n",
933 hw->dev[port]->name);
934} 932}
935 933
936static void genesis_init(struct skge_hw *hw) 934static void genesis_init(struct skge_hw *hw)
@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1165 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); 1163 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
1166 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); 1164 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
1167 1165
1168 /* Use link status change interrrupt */ 1166 /* Use link status change interrupt */
1169 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1167 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1170 1168
1171 bcom_check_link(hw, port); 1169 bcom_check_link(hw, port);
@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1205 skge_write32(hw, B2_GP_IO, r); 1203 skge_write32(hw, B2_GP_IO, r);
1206 skge_read32(hw, B2_GP_IO); 1204 skge_read32(hw, B2_GP_IO);
1207 1205
1208 /* Enable GMII interfac */ 1206 /* Enable GMII interface */
1209 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1207 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1210 1208
1211 bcom_phy_init(skge, jumbo); 1209 bcom_phy_init(skge, jumbo);
@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1256 * that jumbo frames larger than 8192 bytes will be 1254 * that jumbo frames larger than 8192 bytes will be
1257 * truncated. Disabling all bad frame filtering causes 1255 * truncated. Disabling all bad frame filtering causes
1258 * the RX FIFO to operate in streaming mode, in which 1256 * the RX FIFO to operate in streaming mode, in which
1259 * case the XMAC will start transfering frames out of the 1257 * case the XMAC will start transferring frames out of the
1260 * RX FIFO as soon as the FIFO threshold is reached. 1258 * RX FIFO as soon as the FIFO threshold is reached.
1261 */ 1259 */
1262 xm_write32(hw, port, XM_MODE, XM_DEF_MODE); 1260 xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
1323 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); 1321 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
1324 1322
1325 /* 1323 /*
1326 * If the transfer stucks at the MAC the STOP command will not 1324 * If the transfer sticks at the MAC the STOP command will not
1327 * terminate if we don't flush the XMAC's transmit FIFO ! 1325 * terminate if we don't flush the XMAC's transmit FIFO !
1328 */ 1326 */
1329 xm_write32(hw, port, XM_MODE, 1327 xm_write32(hw, port, XM_MODE,
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
1400 } 1398 }
1401} 1399}
1402 1400
1403static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1404{
1405 int i;
1406
1407 gma_write16(hw, port, GM_SMI_DATA, val);
1408 gma_write16(hw, port, GM_SMI_CTRL,
1409 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1410 for (i = 0; i < PHY_RETRIES; i++) {
1411 udelay(1);
1412
1413 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1414 break;
1415 }
1416}
1417
1418static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1419{
1420 int i;
1421
1422 gma_write16(hw, port, GM_SMI_CTRL,
1423 GM_SMI_CT_PHY_AD(hw->phy_addr)
1424 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1425
1426 for (i = 0; i < PHY_RETRIES; i++) {
1427 udelay(1);
1428 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1429 goto ready;
1430 }
1431
1432 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1433 hw->dev[port]->name);
1434 return 0;
1435 ready:
1436 return gma_read16(hw, port, GM_SMI_DATA);
1437}
1438
1439static void genesis_link_up(struct skge_port *skge) 1401static void genesis_link_up(struct skge_port *skge)
1440{ 1402{
1441 struct skge_hw *hw = skge->hw; 1403 struct skge_hw *hw = skge->hw;
@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
1549 1511
1550} 1512}
1551 1513
1552/* Marvell Phy Initailization */ 1514static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1515{
1516 int i;
1517
1518 gma_write16(hw, port, GM_SMI_DATA, val);
1519 gma_write16(hw, port, GM_SMI_CTRL,
1520 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1521 for (i = 0; i < PHY_RETRIES; i++) {
1522 udelay(1);
1523
1524 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1525 return 0;
1526 }
1527
1528 printk(KERN_WARNING PFX "%s: phy write timeout\n",
1529 hw->dev[port]->name);
1530 return -EIO;
1531}
1532
1533static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
1534{
1535 int i;
1536
1537 gma_write16(hw, port, GM_SMI_CTRL,
1538 GM_SMI_CT_PHY_AD(hw->phy_addr)
1539 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1540
1541 for (i = 0; i < PHY_RETRIES; i++) {
1542 udelay(1);
1543 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1544 goto ready;
1545 }
1546
1547 return -ETIMEDOUT;
1548 ready:
1549 *val = gma_read16(hw, port, GM_SMI_DATA);
1550 return 0;
1551}
1552
1553static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1554{
1555 u16 v = 0;
1556 if (__gm_phy_read(hw, port, reg, &v))
1557 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1558 hw->dev[port]->name);
1559 return v;
1560}
1561
1562/* Marvell Phy Initialization */
1553static void yukon_init(struct skge_hw *hw, int port) 1563static void yukon_init(struct skge_hw *hw, int port)
1554{ 1564{
1555 struct skge_port *skge = netdev_priv(hw->dev[port]); 1565 struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
1794 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 1804 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
1795} 1805}
1796 1806
1807/* Go into power down mode */
1808static void yukon_suspend(struct skge_hw *hw, int port)
1809{
1810 u16 ctrl;
1811
1812 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
1813 ctrl |= PHY_M_PC_POL_R_DIS;
1814 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
1815
1816 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1817 ctrl |= PHY_CT_RESET;
1818 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1819
1820 /* switch IEEE compatible power down mode on */
1821 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1822 ctrl |= PHY_CT_PDOWN;
1823 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1824}
1825
1797static void yukon_stop(struct skge_port *skge) 1826static void yukon_stop(struct skge_port *skge)
1798{ 1827{
1799 struct skge_hw *hw = skge->hw; 1828 struct skge_hw *hw = skge->hw;
@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
1807 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); 1836 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
1808 gma_read16(hw, port, GM_GP_CTRL); 1837 gma_read16(hw, port, GM_GP_CTRL);
1809 1838
1810 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1839 yukon_suspend(hw, port);
1811 hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
1812 u32 io = skge_read32(hw, B2_GP_IO);
1813
1814 io |= GP_DIR_9 | GP_IO_9;
1815 skge_write32(hw, B2_GP_IO, io);
1816 skge_read32(hw, B2_GP_IO);
1817 }
1818 1840
1819 /* set GPHY Control reset */ 1841 /* set GPHY Control reset */
1820 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1842 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
1997 /* XXX restart autonegotiation? */ 2019 /* XXX restart autonegotiation? */
1998} 2020}
1999 2021
2022/* Basic MII support */
2023static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2024{
2025 struct mii_ioctl_data *data = if_mii(ifr);
2026 struct skge_port *skge = netdev_priv(dev);
2027 struct skge_hw *hw = skge->hw;
2028 int err = -EOPNOTSUPP;
2029
2030 if (!netif_running(dev))
2031 return -ENODEV; /* Phy still in reset */
2032
2033 switch(cmd) {
2034 case SIOCGMIIPHY:
2035 data->phy_id = hw->phy_addr;
2036
2037 /* fallthru */
2038 case SIOCGMIIREG: {
2039 u16 val = 0;
2040 spin_lock_bh(&hw->phy_lock);
2041 if (hw->chip_id == CHIP_ID_GENESIS)
2042 err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2043 else
2044 err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2045 spin_unlock_bh(&hw->phy_lock);
2046 data->val_out = val;
2047 break;
2048 }
2049
2050 case SIOCSMIIREG:
2051 if (!capable(CAP_NET_ADMIN))
2052 return -EPERM;
2053
2054 spin_lock_bh(&hw->phy_lock);
2055 if (hw->chip_id == CHIP_ID_GENESIS)
2056 err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2057 data->val_in);
2058 else
2059 err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2060 data->val_in);
2061 spin_unlock_bh(&hw->phy_lock);
2062 break;
2063 }
2064 return err;
2065}
2066
2000static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) 2067static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
2001{ 2068{
2002 u32 end; 2069 u32 end;
@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
2089 hw->intr_mask |= portirqmask[port]; 2156 hw->intr_mask |= portirqmask[port];
2090 skge_write32(hw, B0_IMSK, hw->intr_mask); 2157 skge_write32(hw, B0_IMSK, hw->intr_mask);
2091 2158
2092 /* Initialze MAC */ 2159 /* Initialize MAC */
2093 spin_lock_bh(&hw->phy_lock); 2160 spin_lock_bh(&hw->phy_lock);
2094 if (hw->chip_id == CHIP_ID_GENESIS) 2161 if (hw->chip_id == CHIP_ID_GENESIS)
2095 genesis_mac_init(hw, port); 2162 genesis_mac_init(hw, port);
@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
2409 reg = gma_read16(hw, port, GM_RX_CTRL); 2476 reg = gma_read16(hw, port, GM_RX_CTRL);
2410 reg |= GM_RXCR_UCF_ENA; 2477 reg |= GM_RXCR_UCF_ENA;
2411 2478
2412 if (dev->flags & IFF_PROMISC) /* promiscious */ 2479 if (dev->flags & IFF_PROMISC) /* promiscuous */
2413 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); 2480 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
2414 else if (dev->flags & IFF_ALLMULTI) /* all multicast */ 2481 else if (dev->flags & IFF_ALLMULTI) /* all multicast */
2415 memset(filter, 0xff, sizeof(filter)); 2482 memset(filter, 0xff, sizeof(filter));
@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
2560 unsigned int to_do = min(dev->quota, *budget); 2627 unsigned int to_do = min(dev->quota, *budget);
2561 unsigned int work_done = 0; 2628 unsigned int work_done = 0;
2562 2629
2563 for (e = ring->to_clean; work_done < to_do; e = e->next) { 2630 for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
2564 struct skge_rx_desc *rd = e->desc; 2631 struct skge_rx_desc *rd = e->desc;
2565 struct sk_buff *skb; 2632 struct sk_buff *skb;
2566 u32 control; 2633 u32 control;
@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
2593 if (work_done >= to_do) 2660 if (work_done >= to_do)
2594 return 1; /* not done */ 2661 return 1; /* not done */
2595 2662
2596 local_irq_disable(); 2663 netif_rx_complete(dev);
2597 __netif_rx_complete(dev);
2598 hw->intr_mask |= portirqmask[skge->port]; 2664 hw->intr_mask |= portirqmask[skge->port];
2599 skge_write32(hw, B0_IMSK, hw->intr_mask); 2665 skge_write32(hw, B0_IMSK, hw->intr_mask);
2600 local_irq_enable(); 2666 skge_read32(hw, B0_IMSK);
2667
2601 return 0; 2668 return 0;
2602} 2669}
2603 2670
@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
2609 struct skge_element *e; 2676 struct skge_element *e;
2610 2677
2611 spin_lock(&skge->tx_lock); 2678 spin_lock(&skge->tx_lock);
2612 for (e = ring->to_clean; e != ring->to_use; e = e->next) { 2679 for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
2613 struct skge_tx_desc *td = e->desc; 2680 struct skge_tx_desc *td = e->desc;
2614 u32 control; 2681 u32 control;
2615 2682
@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
2732} 2799}
2733 2800
2734/* 2801/*
2735 * Interrrupt from PHY are handled in tasklet (soft irq) 2802 * Interrupt from PHY are handled in tasklet (soft irq)
2736 * because accessing phy registers requires spin wait which might 2803 * because accessing phy registers requires spin wait which might
2737 * cause excess interrupt latency. 2804 * cause excess interrupt latency.
2738 */ 2805 */
@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
2762 local_irq_enable(); 2829 local_irq_enable();
2763} 2830}
2764 2831
2832static inline void skge_wakeup(struct net_device *dev)
2833{
2834 struct skge_port *skge = netdev_priv(dev);
2835
2836 prefetch(skge->rx_ring.to_clean);
2837 netif_rx_schedule(dev);
2838}
2839
2765static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) 2840static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2766{ 2841{
2767 struct skge_hw *hw = dev_id; 2842 struct skge_hw *hw = dev_id;
@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2773 status &= hw->intr_mask; 2848 status &= hw->intr_mask;
2774 if (status & IS_R1_F) { 2849 if (status & IS_R1_F) {
2775 hw->intr_mask &= ~IS_R1_F; 2850 hw->intr_mask &= ~IS_R1_F;
2776 netif_rx_schedule(hw->dev[0]); 2851 skge_wakeup(hw->dev[0]);
2777 } 2852 }
2778 2853
2779 if (status & IS_R2_F) { 2854 if (status & IS_R2_F) {
2780 hw->intr_mask &= ~IS_R2_F; 2855 hw->intr_mask &= ~IS_R2_F;
2781 netif_rx_schedule(hw->dev[1]); 2856 skge_wakeup(hw->dev[1]);
2782 } 2857 }
2783 2858
2784 if (status & IS_XA1_F) 2859 if (status & IS_XA1_F)
@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
2893 */ 2968 */
2894static int skge_reset(struct skge_hw *hw) 2969static int skge_reset(struct skge_hw *hw)
2895{ 2970{
2971 u32 reg;
2896 u16 ctst; 2972 u16 ctst;
2897 u8 t8, mac_cfg, pmd_type, phy_type; 2973 u8 t8, mac_cfg, pmd_type, phy_type;
2898 int i; 2974 int i;
@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
2971 /* switch power to VCC (WA for VAUX problem) */ 3047 /* switch power to VCC (WA for VAUX problem) */
2972 skge_write8(hw, B0_POWER_CTRL, 3048 skge_write8(hw, B0_POWER_CTRL,
2973 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); 3049 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
3050
2974 /* avoid boards with stuck Hardware error bits */ 3051 /* avoid boards with stuck Hardware error bits */
2975 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && 3052 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
2976 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { 3053 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
2978 hw->intr_mask &= ~IS_HW_ERR; 3055 hw->intr_mask &= ~IS_HW_ERR;
2979 } 3056 }
2980 3057
3058 /* Clear PHY COMA */
3059 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3060 pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
3061 reg &= ~PCI_PHY_COMA;
3062 pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
3063 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3064
3065
2981 for (i = 0; i < hw->ports; i++) { 3066 for (i = 0; i < hw->ports; i++) {
2982 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 3067 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2983 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 3068 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3048 SET_NETDEV_DEV(dev, &hw->pdev->dev); 3133 SET_NETDEV_DEV(dev, &hw->pdev->dev);
3049 dev->open = skge_up; 3134 dev->open = skge_up;
3050 dev->stop = skge_down; 3135 dev->stop = skge_down;
3136 dev->do_ioctl = skge_ioctl;
3051 dev->hard_start_xmit = skge_xmit_frame; 3137 dev->hard_start_xmit = skge_xmit_frame;
3052 dev->get_stats = skge_get_stats; 3138 dev->get_stats = skge_get_stats;
3053 if (hw->chip_id == CHIP_ID_GENESIS) 3139 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3147 } 3233 }
3148 3234
3149#ifdef __BIG_ENDIAN 3235#ifdef __BIG_ENDIAN
3150 /* byte swap decriptors in hardware */ 3236 /* byte swap descriptors in hardware */
3151 { 3237 {
3152 u32 reg; 3238 u32 reg;
3153 3239
@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3158#endif 3244#endif
3159 3245
3160 err = -ENOMEM; 3246 err = -ENOMEM;
3161 hw = kmalloc(sizeof(*hw), GFP_KERNEL); 3247 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3162 if (!hw) { 3248 if (!hw) {
3163 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", 3249 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
3164 pci_name(pdev)); 3250 pci_name(pdev));
3165 goto err_out_free_regions; 3251 goto err_out_free_regions;
3166 } 3252 }
3167 3253
3168 memset(hw, 0, sizeof(*hw));
3169 hw->pdev = pdev; 3254 hw->pdev = pdev;
3170 spin_lock_init(&hw->phy_lock); 3255 spin_lock_init(&hw->phy_lock);
3171 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); 3256 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3188 if (err) 3273 if (err)
3189 goto err_out_free_irq; 3274 goto err_out_free_irq;
3190 3275
3191 printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", 3276 printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
3192 pci_resource_start(pdev, 0), pdev->irq, 3277 pci_resource_start(pdev, 0), pdev->irq,
3193 skge_board_name(hw), hw->chip_rev); 3278 skge_board_name(hw), hw->chip_rev);
3194 3279
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b87a5a..ee123c15f545 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
6 6
7/* PCI config registers */ 7/* PCI config registers */
8#define PCI_DEV_REG1 0x40 8#define PCI_DEV_REG1 0x40
9#define PCI_PHY_COMA 0x8000000
10#define PCI_VIO 0x2000000
9#define PCI_DEV_REG2 0x44 11#define PCI_DEV_REG2 0x44
10#define PCI_REV_DESC 0x4 12#define PCI_REV_DESC 0x4
11 13
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 38b2b0a3ce96..d167deda9a53 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -147,7 +147,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
147#define DRV_RELDATE "October 3, 2005" 147#define DRV_RELDATE "October 3, 2005"
148 148
149#include <linux/config.h> 149#include <linux/config.h>
150#include <linux/version.h>
151#include <linux/module.h> 150#include <linux/module.h>
152#include <linux/kernel.h> 151#include <linux/kernel.h>
153#include <linux/pci.h> 152#include <linux/pci.h>
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a368d08e7d19..82c6b757d306 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,7 +61,6 @@
61#include <linux/timer.h> 61#include <linux/timer.h>
62#include <linux/slab.h> 62#include <linux/slab.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/version.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/wait.h> 65#include <linux/wait.h>
67#include <asm/io.h> 66#include <asm/io.h>
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 6afc6e5dee9b..340ab4ee4b67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4535 StatusRid status_rid; 4535 StatusRid status_rid;
4536 int i; 4536 int i;
4537 4537
4538 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4538 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4539 return -ENOMEM; 4539 return -ENOMEM;
4540 memset(file->private_data, 0, sizeof(struct proc_data));
4541 data = (struct proc_data *)file->private_data; 4540 data = (struct proc_data *)file->private_data;
4542 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4541 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4543 kfree (file->private_data); 4542 kfree (file->private_data);
@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
4615 int i, j; 4614 int i, j;
4616 u32 *vals = stats.vals; 4615 u32 *vals = stats.vals;
4617 4616
4618 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4617 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4619 return -ENOMEM; 4618 return -ENOMEM;
4620 memset(file->private_data, 0, sizeof(struct proc_data));
4621 data = (struct proc_data *)file->private_data; 4619 data = (struct proc_data *)file->private_data;
4622 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { 4620 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4623 kfree (file->private_data); 4621 kfree (file->private_data);
@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
4881 struct airo_info *ai = dev->priv; 4879 struct airo_info *ai = dev->priv;
4882 int i; 4880 int i;
4883 4881
4884 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4882 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4885 return -ENOMEM; 4883 return -ENOMEM;
4886 memset(file->private_data, 0, sizeof(struct proc_data));
4887 data = (struct proc_data *)file->private_data; 4884 data = (struct proc_data *)file->private_data;
4888 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4885 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4889 kfree (file->private_data); 4886 kfree (file->private_data);
4890 return -ENOMEM; 4887 return -ENOMEM;
4891 } 4888 }
4892 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4889 if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
4893 kfree (data->rbuffer); 4890 kfree (data->rbuffer);
4894 kfree (file->private_data); 4891 kfree (file->private_data);
4895 return -ENOMEM; 4892 return -ENOMEM;
4896 } 4893 }
4897 memset( data->wbuffer, 0, 2048 );
4898 data->maxwritelen = 2048; 4894 data->maxwritelen = 2048;
4899 data->on_close = proc_config_on_close; 4895 data->on_close = proc_config_on_close;
4900 4896
@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5155 int j=0; 5151 int j=0;
5156 int rc; 5152 int rc;
5157 5153
5158 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5154 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5159 return -ENOMEM; 5155 return -ENOMEM;
5160 memset(file->private_data, 0, sizeof(struct proc_data));
5161 memset(&wkr, 0, sizeof(wkr)); 5156 memset(&wkr, 0, sizeof(wkr));
5162 data = (struct proc_data *)file->private_data; 5157 data = (struct proc_data *)file->private_data;
5163 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) { 5158 if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5164 kfree (file->private_data); 5159 kfree (file->private_data);
5165 return -ENOMEM; 5160 return -ENOMEM;
5166 } 5161 }
5167 memset(data->rbuffer, 0, 180);
5168 data->writelen = 0; 5162 data->writelen = 0;
5169 data->maxwritelen = 80; 5163 data->maxwritelen = 80;
5170 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) { 5164 if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5171 kfree (data->rbuffer); 5165 kfree (data->rbuffer);
5172 kfree (file->private_data); 5166 kfree (file->private_data);
5173 return -ENOMEM; 5167 return -ENOMEM;
5174 } 5168 }
5175 memset( data->wbuffer, 0, 80 );
5176 data->on_close = proc_wepkey_on_close; 5169 data->on_close = proc_wepkey_on_close;
5177 5170
5178 ptr = data->rbuffer; 5171 ptr = data->rbuffer;
@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5203 char *ptr; 5196 char *ptr;
5204 SsidRid SSID_rid; 5197 SsidRid SSID_rid;
5205 5198
5206 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5199 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5207 return -ENOMEM; 5200 return -ENOMEM;
5208 memset(file->private_data, 0, sizeof(struct proc_data));
5209 data = (struct proc_data *)file->private_data; 5201 data = (struct proc_data *)file->private_data;
5210 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5202 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5211 kfree (file->private_data); 5203 kfree (file->private_data);
@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5213 } 5205 }
5214 data->writelen = 0; 5206 data->writelen = 0;
5215 data->maxwritelen = 33*3; 5207 data->maxwritelen = 33*3;
5216 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) { 5208 if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
5217 kfree (data->rbuffer); 5209 kfree (data->rbuffer);
5218 kfree (file->private_data); 5210 kfree (file->private_data);
5219 return -ENOMEM; 5211 return -ENOMEM;
5220 } 5212 }
5221 memset( data->wbuffer, 0, 33*3 );
5222 data->on_close = proc_SSID_on_close; 5213 data->on_close = proc_SSID_on_close;
5223 5214
5224 readSsidRid(ai, &SSID_rid); 5215 readSsidRid(ai, &SSID_rid);
@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5247 char *ptr; 5238 char *ptr;
5248 APListRid APList_rid; 5239 APListRid APList_rid;
5249 5240
5250 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5241 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5251 return -ENOMEM; 5242 return -ENOMEM;
5252 memset(file->private_data, 0, sizeof(struct proc_data));
5253 data = (struct proc_data *)file->private_data; 5243 data = (struct proc_data *)file->private_data;
5254 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5244 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5255 kfree (file->private_data); 5245 kfree (file->private_data);
@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5257 } 5247 }
5258 data->writelen = 0; 5248 data->writelen = 0;
5259 data->maxwritelen = 4*6*3; 5249 data->maxwritelen = 4*6*3;
5260 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) { 5250 if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5261 kfree (data->rbuffer); 5251 kfree (data->rbuffer);
5262 kfree (file->private_data); 5252 kfree (file->private_data);
5263 return -ENOMEM; 5253 return -ENOMEM;
5264 } 5254 }
5265 memset( data->wbuffer, 0, data->maxwritelen );
5266 data->on_close = proc_APList_on_close; 5255 data->on_close = proc_APList_on_close;
5267 5256
5268 readAPListRid(ai, &APList_rid); 5257 readAPListRid(ai, &APList_rid);
@@ -5297,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5297 /* If doLoseSync is not 1, we won't do a Lose Sync */ 5286 /* If doLoseSync is not 1, we won't do a Lose Sync */
5298 int doLoseSync = -1; 5287 int doLoseSync = -1;
5299 5288
5300 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5289 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5301 return -ENOMEM; 5290 return -ENOMEM;
5302 memset(file->private_data, 0, sizeof(struct proc_data));
5303 data = (struct proc_data *)file->private_data; 5291 data = (struct proc_data *)file->private_data;
5304 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { 5292 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5305 kfree (file->private_data); 5293 kfree (file->private_data);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 96ed8da8661d..e328547599dc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void)
170 DEBUG(0, "airo_attach()\n"); 170 DEBUG(0, "airo_attach()\n");
171 171
172 /* Initialize the dev_link_t structure */ 172 /* Initialize the dev_link_t structure */
173 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
174 if (!link) { 174 if (!link) {
175 printk(KERN_ERR "airo_cs: no memory for new device\n"); 175 printk(KERN_ERR "airo_cs: no memory for new device\n");
176 return NULL; 176 return NULL;
177 } 177 }
178 memset(link, 0, sizeof(struct dev_link_t));
179 178
180 /* Interrupt setup */ 179 /* Interrupt setup */
181 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 180 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void)
194 link->conf.IntType = INT_MEMORY_AND_IO; 193 link->conf.IntType = INT_MEMORY_AND_IO;
195 194
196 /* Allocate space for private device-specific data */ 195 /* Allocate space for private device-specific data */
197 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 196 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
198 if (!local) { 197 if (!local) {
199 printk(KERN_ERR "airo_cs: no memory for new device\n"); 198 printk(KERN_ERR "airo_cs: no memory for new device\n");
200 kfree (link); 199 kfree (link);
201 return NULL; 200 return NULL;
202 } 201 }
203 memset(local, 0, sizeof(local_info_t));
204 link->priv = local; 202 link->priv = local;
205 203
206 /* Register with Card Services */ 204 /* Register with Card Services */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 1fbe027d26b6..a3e23527fe7f 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
2217 int k,i,j; 2217 int k,i,j;
2218 2218
2219 dwrq->length = sizeof(struct iw_range); 2219 dwrq->length = sizeof(struct iw_range);
2220 memset(range, 0, sizeof(range)); 2220 memset(range, 0, sizeof(struct iw_range));
2221 range->min_nwid = 0x0000; 2221 range->min_nwid = 0x0000;
2222 range->max_nwid = 0x0000; 2222 range->max_nwid = 0x0000;
2223 range->num_channels = 0; 2223 range->num_channels = 0;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 195cb36619e8..1bd13146c644 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
180 DEBUG(0, "atmel_attach()\n"); 180 DEBUG(0, "atmel_attach()\n");
181 181
182 /* Initialize the dev_link_t structure */ 182 /* Initialize the dev_link_t structure */
183 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 183 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
184 if (!link) { 184 if (!link) {
185 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 185 printk(KERN_ERR "atmel_cs: no memory for new device\n");
186 return NULL; 186 return NULL;
187 } 187 }
188 memset(link, 0, sizeof(struct dev_link_t));
189 188
190 /* Interrupt setup */ 189 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 190 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
204 link->conf.IntType = INT_MEMORY_AND_IO; 203 link->conf.IntType = INT_MEMORY_AND_IO;
205 204
206 /* Allocate space for private device-specific data */ 205 /* Allocate space for private device-specific data */
207 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 206 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 207 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 208 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 209 kfree (link);
211 return NULL; 210 return NULL;
212 } 211 }
213 memset(local, 0, sizeof(local_info_t));
214 link->priv = local; 212 link->priv = local;
215 213
216 /* Register with Card Services */ 214 /* Register with Card Services */
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index 6a96cd9f2685..3d2ea61033be 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 59fc15572395..abfae7fedebc 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -31,7 +31,6 @@
31 31
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34#include <linux/version.h>
35 34
36#include <asm/delay.h> 35#include <asm/delay.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index da0c80fb941c..2e85bdced2dd 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
5 * Andy Warner <andyw@pobox.com> */ 5 * Andy Warner <andyw@pobox.com> */
6 6
7#include <linux/config.h> 7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/if.h> 10#include <linux/if.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 78d67b408b2f..94fe2449f099 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
8 8
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/if.h> 13#include <linux/if.h>
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ad7f8cd76db9..a2e6214169e9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,17 +167,16 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "1.1.0" 170#define IPW2100_VERSION "1.1.3"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
176
177 176
178/* Debugging stuff */ 177/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG 178#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */ 179#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif 180#endif
182 181
183MODULE_DESCRIPTION(DRV_DESCRIPTION); 182MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
220} while (0) 219} while (0)
221#else 220#else
222#define IPW_DEBUG(level, message...) do {} while (0) 221#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */ 222#endif /* CONFIG_IPW_DEBUG */
224 223
225#ifdef CONFIG_IPW_DEBUG 224#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = { 225static const char *command_types[] = {
227 "undefined", 226 "undefined",
228 "unused", /* HOST_ATTENTION */ 227 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE", 228 "HOST_COMPLETE",
230 "unused", /* SLEEP */ 229 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */ 230 "unused", /* HOST_POWER_DOWN */
232 "unused", 231 "unused",
233 "SYSTEM_CONFIG", 232 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */ 233 "unused", /* SET_IMR */
235 "SSID", 234 "SSID",
236 "MANDATORY_BSSID", 235 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE", 236 "AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
277 "GROUP_ORDINALS", 276 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT", 277 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT", 278 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */ 279 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */ 280 "unused", /* RESTORE_CALIBRATION */
282 "undefined", 281 "undefined",
283 "undefined", 282 "undefined",
284 "undefined", 283 "undefined",
285 "HOST_PRE_POWER_DOWN", 284 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */ 285 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined", 286 "undefined",
288 "CARD_DISABLE_PHY_OFF", 287 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES" 288 "MSDU_TX_RATES" "undefined",
290 "undefined",
291 "undefined", 289 "undefined",
292 "SET_STATION_STAT_BITS", 290 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS", 291 "CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
298}; 296};
299#endif 297#endif
300 298
301
302/* Pre-decl until we get the code solid and then we can clean it up */ 299/* Pre-decl until we get the code solid and then we can clean it up */
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); 300static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv); 301static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
321static int ipw2100_ucode_download(struct ipw2100_priv *priv, 318static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw); 319 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv); 320static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev); 321static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
325static struct iw_handler_def ipw2100_wx_handler_def; 322static struct iw_handler_def ipw2100_wx_handler_def;
326 323
327 324static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{ 325{
330 *val = readl((void __iomem *)(dev->base_addr + reg)); 326 *val = readl((void __iomem *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val); 327 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct net_device *dev, u32 reg, u32 val)
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val); 333 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338} 334}
339 335
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val) 336static inline void read_register_word(struct net_device *dev, u32 reg,
337 u16 * val)
341{ 338{
342 *val = readw((void __iomem *)(dev->base_addr + reg)); 339 *val = readw((void __iomem *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val); 340 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344} 341}
345 342
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val) 343static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
347{ 344{
348 *val = readb((void __iomem *)(dev->base_addr + reg)); 345 *val = readb((void __iomem *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val); 346 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val); 352 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356} 353}
357 354
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val) 355static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{ 356{
361 writeb(val, (void __iomem *)(dev->base_addr + reg)); 357 writeb(val, (void __iomem *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val); 358 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363} 359}
364 360
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val) 361static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
366{ 362{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 363 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK); 364 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 372 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377} 373}
378 374
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val) 375static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
380{ 376{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 377 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK); 378 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 386 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391} 387}
392 388
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val) 389static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
394{ 390{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 391 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK); 392 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
416} 412}
417 413
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, 414static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf) 415 const u8 * buf)
420{ 416{
421 u32 aligned_addr; 417 u32 aligned_addr;
422 u32 aligned_len; 418 u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 427 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr); 428 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++) 429 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte( 430 write_register_byte(dev,
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, 431 IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf); 432 *buf);
437 433
438 len -= dif_len; 434 len -= dif_len;
439 aligned_addr += 4; 435 aligned_addr += 4;
440 } 436 }
441 437
442 /* read DWs through autoincrement registers */ 438 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 439 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
444 aligned_addr);
445 aligned_len = len & (~0x3); 440 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 441 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register( 442 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449 443
450 /* copy the last nibble */ 444 /* copy the last nibble */
451 dif_len = len - aligned_len; 445 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr); 446 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++) 447 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte( 448 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf); 449 *buf);
456} 450}
457 451
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len, 452static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf) 453 u8 * buf)
460{ 454{
461 u32 aligned_addr; 455 u32 aligned_addr;
462 u32 aligned_len; 456 u32 aligned_len;
@@ -471,39 +465,38 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 465 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr); 466 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++) 467 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte( 468 read_register_byte(dev,
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf); 469 IPW_REG_INDIRECT_ACCESS_DATA + i,
470 buf);
476 471
477 len -= dif_len; 472 len -= dif_len;
478 aligned_addr += 4; 473 aligned_addr += 4;
479 } 474 }
480 475
481 /* read DWs through autoincrement registers */ 476 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 477 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
483 aligned_addr);
484 aligned_len = len & (~0x3); 478 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 479 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, 480 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, (u32 *) buf);
487 (u32 *)buf);
488 481
489 /* copy the last nibble */ 482 /* copy the last nibble */
490 dif_len = len - aligned_len; 483 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 484 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++) 485 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + 486 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
495 i, buf);
496} 487}
497 488
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev) 489static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{ 490{
500 return (dev->base_addr && 491 return (dev->base_addr &&
501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START)) 492 (readl
493 ((void __iomem *)(dev->base_addr +
494 IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE)); 495 == IPW_DATA_DOA_DEBUG_VALUE));
503} 496}
504 497
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, 498static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len) 499 void *val, u32 * len)
507{ 500{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals; 501 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr; 502 u32 addr;
@@ -529,8 +522,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
529 return -EINVAL; 522 return -EINVAL;
530 } 523 }
531 524
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 525 read_nic_dword(priv->net_dev,
533 &addr); 526 ordinals->table1_addr + (ord << 2), &addr);
534 read_nic_dword(priv->net_dev, addr, val); 527 read_nic_dword(priv->net_dev, addr, val);
535 528
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE; 529 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
@@ -543,8 +536,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
543 ord -= IPW_START_ORD_TAB_2; 536 ord -= IPW_START_ORD_TAB_2;
544 537
545 /* get the address of statistic */ 538 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3), 539 read_nic_dword(priv->net_dev,
547 &addr); 540 ordinals->table2_addr + (ord << 3), &addr);
548 541
549 /* get the second DW of statistics ; 542 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */ 543 * two 16-bit words - first is length, second is count */
@@ -553,10 +546,10 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
553 &field_info); 546 &field_info);
554 547
555 /* get each entry length */ 548 /* get each entry length */
556 field_len = *((u16 *)&field_info); 549 field_len = *((u16 *) & field_info);
557 550
558 /* get number of entries */ 551 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1); 552 field_count = *(((u16 *) & field_info) + 1);
560 553
561 /* abort if no enought memory */ 554 /* abort if no enought memory */
562 total_length = field_len * field_count; 555 total_length = field_len * field_count;
@@ -581,8 +574,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
581 return -EINVAL; 574 return -EINVAL;
582} 575}
583 576
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val, 577static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
585 u32 *len) 578 u32 * len)
586{ 579{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals; 580 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr; 581 u32 addr;
@@ -594,8 +587,8 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
594 return -EINVAL; 587 return -EINVAL;
595 } 588 }
596 589
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 590 read_nic_dword(priv->net_dev,
598 &addr); 591 ordinals->table1_addr + (ord << 2), &addr);
599 592
600 write_nic_dword(priv->net_dev, addr, *val); 593 write_nic_dword(priv->net_dev, addr, *val);
601 594
@@ -612,7 +605,7 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
612} 605}
613 606
614static char *snprint_line(char *buf, size_t count, 607static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs) 608 const u8 * data, u32 len, u32 ofs)
616{ 609{
617 int out, i, j, l; 610 int out, i, j, l;
618 char c; 611 char c;
@@ -646,7 +639,7 @@ static char *snprint_line(char *buf, size_t count,
646 return buf; 639 return buf;
647} 640}
648 641
649static void printk_buf(int level, const u8 *data, u32 len) 642static void printk_buf(int level, const u8 * data, u32 len)
650{ 643{
651 char line[81]; 644 char line[81];
652 u32 ofs = 0; 645 u32 ofs = 0;
@@ -662,8 +655,6 @@ static void printk_buf(int level, const u8 *data, u32 len)
662 } 655 }
663} 656}
664 657
665
666
667#define MAX_RESET_BACKOFF 10 658#define MAX_RESET_BACKOFF 10
668 659
669static inline void schedule_reset(struct ipw2100_priv *priv) 660static inline void schedule_reset(struct ipw2100_priv *priv)
@@ -703,7 +694,7 @@ static inline void schedule_reset(struct ipw2100_priv *priv)
703 694
704#define HOST_COMPLETE_TIMEOUT (2 * HZ) 695#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv, 696static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd) 697 struct host_command *cmd)
707{ 698{
708 struct list_head *element; 699 struct list_head *element;
709 struct ipw2100_tx_packet *packet; 700 struct ipw2100_tx_packet *packet;
@@ -713,25 +704,28 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 704 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command, 705 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length); 706 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters, 707 printk_buf(IPW_DL_HC, (u8 *) cmd->host_command_parameters,
717 cmd->host_command_length); 708 cmd->host_command_length);
718 709
719 spin_lock_irqsave(&priv->low_lock, flags); 710 spin_lock_irqsave(&priv->low_lock, flags);
720 711
721 if (priv->fatal_error) { 712 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n"); 713 IPW_DEBUG_INFO
714 ("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO; 715 err = -EIO;
724 goto fail_unlock; 716 goto fail_unlock;
725 } 717 }
726 718
727 if (!(priv->status & STATUS_RUNNING)) { 719 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n"); 720 IPW_DEBUG_INFO
721 ("Attempt to send command while hardware is not running.\n");
729 err = -EIO; 722 err = -EIO;
730 goto fail_unlock; 723 goto fail_unlock;
731 } 724 }
732 725
733 if (priv->status & STATUS_CMD_ACTIVE) { 726 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n"); 727 IPW_DEBUG_INFO
728 ("Attempt to send command while another command is pending.\n");
735 err = -EBUSY; 729 err = -EBUSY;
736 goto fail_unlock; 730 goto fail_unlock;
737 } 731 }
@@ -752,7 +746,8 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
752 /* initialize the firmware command packet */ 746 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command; 747 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1; 748 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length; 749 packet->info.c_struct.cmd->host_command_len_reg =
750 cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence; 751 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757 752
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg, 753 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
@@ -776,13 +771,15 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
776 * then there is a problem. 771 * then there is a problem.
777 */ 772 */
778 773
779 err = wait_event_interruptible_timeout( 774 err =
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE), 775 wait_event_interruptible_timeout(priv->wait_command_queue,
781 HOST_COMPLETE_TIMEOUT); 776 !(priv->
777 status & STATUS_CMD_ACTIVE),
778 HOST_COMPLETE_TIMEOUT);
782 779
783 if (err == 0) { 780 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100)); 782 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT; 783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE; 784 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv); 785 schedule_reset(priv);
@@ -804,13 +801,12 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
804 801
805 return 0; 802 return 0;
806 803
807 fail_unlock: 804 fail_unlock:
808 spin_unlock_irqrestore(&priv->low_lock, flags); 805 spin_unlock_irqrestore(&priv->low_lock, flags);
809 806
810 return err; 807 return err;
811} 808}
812 809
813
814/* 810/*
815 * Verify the values and data access of the hardware 811 * Verify the values and data access of the hardware
816 * No locks needed or used. No functions called. 812 * No locks needed or used. No functions called.
@@ -825,8 +821,7 @@ static int ipw2100_verify(struct ipw2100_priv *priv)
825 821
826 /* Domain 0 check - all values should be DOA_DEBUG */ 822 /* Domain 0 check - all values should be DOA_DEBUG */
827 for (address = IPW_REG_DOA_DEBUG_AREA_START; 823 for (address = IPW_REG_DOA_DEBUG_AREA_START;
828 address < IPW_REG_DOA_DEBUG_AREA_END; 824 address < IPW_REG_DOA_DEBUG_AREA_END; address += sizeof(u32)) {
829 address += sizeof(u32)) {
830 read_register(priv->net_dev, address, &data1); 825 read_register(priv->net_dev, address, &data1);
831 if (data1 != IPW_DATA_DOA_DEBUG_VALUE) 826 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
832 return -EIO; 827 return -EIO;
@@ -898,7 +893,6 @@ static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
898 return -EIO; 893 return -EIO;
899} 894}
900 895
901
902/********************************************************************* 896/*********************************************************************
903 Procedure : sw_reset_and_clock 897 Procedure : sw_reset_and_clock
904 Purpose : Asserts s/w reset, asserts clock initialization 898 Purpose : Asserts s/w reset, asserts clock initialization
@@ -975,17 +969,16 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
975 969
976 if (priv->fatal_error) { 970 if (priv->fatal_error) {
977 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after " 971 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
978 "fatal error %d. Interface must be brought down.\n", 972 "fatal error %d. Interface must be brought down.\n",
979 priv->net_dev->name, priv->fatal_error); 973 priv->net_dev->name, priv->fatal_error);
980 return -EINVAL; 974 return -EINVAL;
981 } 975 }
982
983#ifdef CONFIG_PM 976#ifdef CONFIG_PM
984 if (!ipw2100_firmware.version) { 977 if (!ipw2100_firmware.version) {
985 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 978 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
986 if (err) { 979 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 980 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
988 priv->net_dev->name, err); 981 priv->net_dev->name, err);
989 priv->fatal_error = IPW2100_ERR_FW_LOAD; 982 priv->fatal_error = IPW2100_ERR_FW_LOAD;
990 goto fail; 983 goto fail;
991 } 984 }
@@ -994,7 +987,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
994 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 987 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
995 if (err) { 988 if (err) {
996 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 989 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
997 priv->net_dev->name, err); 990 priv->net_dev->name, err);
998 priv->fatal_error = IPW2100_ERR_FW_LOAD; 991 priv->fatal_error = IPW2100_ERR_FW_LOAD;
999 goto fail; 992 goto fail;
1000 } 993 }
@@ -1005,21 +998,20 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1005 err = sw_reset_and_clock(priv); 998 err = sw_reset_and_clock(priv);
1006 if (err) { 999 if (err) {
1007 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n", 1000 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1008 priv->net_dev->name, err); 1001 priv->net_dev->name, err);
1009 goto fail; 1002 goto fail;
1010 } 1003 }
1011 1004
1012 err = ipw2100_verify(priv); 1005 err = ipw2100_verify(priv);
1013 if (err) { 1006 if (err) {
1014 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n", 1007 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1015 priv->net_dev->name, err); 1008 priv->net_dev->name, err);
1016 goto fail; 1009 goto fail;
1017 } 1010 }
1018 1011
1019 /* Hold ARC */ 1012 /* Hold ARC */
1020 write_nic_dword(priv->net_dev, 1013 write_nic_dword(priv->net_dev,
1021 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1014 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x80000000);
1022 0x80000000);
1023 1015
1024 /* allow ARC to run */ 1016 /* allow ARC to run */
1025 write_register(priv->net_dev, IPW_REG_RESET_REG, 0); 1017 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
@@ -1034,13 +1026,13 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1034 1026
1035 /* release ARC */ 1027 /* release ARC */
1036 write_nic_dword(priv->net_dev, 1028 write_nic_dword(priv->net_dev,
1037 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1029 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x00000000);
1038 0x00000000);
1039 1030
1040 /* s/w reset and clock stabilization (again!!!) */ 1031 /* s/w reset and clock stabilization (again!!!) */
1041 err = sw_reset_and_clock(priv); 1032 err = sw_reset_and_clock(priv);
1042 if (err) { 1033 if (err) {
1043 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n", 1034 printk(KERN_ERR DRV_NAME
1035 ": %s: sw_reset_and_clock failed: %d\n",
1044 priv->net_dev->name, err); 1036 priv->net_dev->name, err);
1045 goto fail; 1037 goto fail;
1046 } 1038 }
@@ -1049,10 +1041,9 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1049 err = ipw2100_fw_download(priv, &ipw2100_firmware); 1041 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1050 if (err) { 1042 if (err) {
1051 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n", 1043 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1052 priv->net_dev->name, err); 1044 priv->net_dev->name, err);
1053 goto fail; 1045 goto fail;
1054 } 1046 }
1055
1056#ifndef CONFIG_PM 1047#ifndef CONFIG_PM
1057 /* 1048 /*
1058 * When the .resume method of the driver is called, the other 1049 * When the .resume method of the driver is called, the other
@@ -1084,7 +1075,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1084 1075
1085 return 0; 1076 return 0;
1086 1077
1087 fail: 1078 fail:
1088 ipw2100_release_firmware(priv, &ipw2100_firmware); 1079 ipw2100_release_firmware(priv, &ipw2100_firmware);
1089 return err; 1080 return err;
1090} 1081}
@@ -1105,7 +1096,6 @@ static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1105 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0); 1096 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1106} 1097}
1107 1098
1108
1109static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv) 1099static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1110{ 1100{
1111 struct ipw2100_ordinals *ord = &priv->ordinals; 1101 struct ipw2100_ordinals *ord = &priv->ordinals;
@@ -1177,11 +1167,10 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1177 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1 1167 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1178 */ 1168 */
1179 len = sizeof(addr); 1169 len = sizeof(addr);
1180 if (ipw2100_get_ordinal( 1170 if (ipw2100_get_ordinal
1181 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, 1171 (priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, &addr, &len)) {
1182 &addr, &len)) {
1183 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1172 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1184 __LINE__); 1173 __LINE__);
1185 return -EIO; 1174 return -EIO;
1186 } 1175 }
1187 1176
@@ -1194,7 +1183,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1194 priv->eeprom_version = (val >> 24) & 0xFF; 1183 priv->eeprom_version = (val >> 24) & 0xFF;
1195 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version); 1184 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1196 1185
1197 /* 1186 /*
1198 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware 1187 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1199 * 1188 *
1200 * notice that the EEPROM bit is reverse polarity, i.e. 1189 * notice that the EEPROM bit is reverse polarity, i.e.
@@ -1206,8 +1195,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1206 priv->hw_features |= HW_FEATURE_RFKILL; 1195 priv->hw_features |= HW_FEATURE_RFKILL;
1207 1196
1208 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n", 1197 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1209 (priv->hw_features & HW_FEATURE_RFKILL) ? 1198 (priv->hw_features & HW_FEATURE_RFKILL) ? "" : "not ");
1210 "" : "not ");
1211 1199
1212 return 0; 1200 return 0;
1213} 1201}
@@ -1234,7 +1222,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1234 * fw & dino ucode 1222 * fw & dino ucode
1235 */ 1223 */
1236 if (ipw2100_download_firmware(priv)) { 1224 if (ipw2100_download_firmware(priv)) {
1237 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n", 1225 printk(KERN_ERR DRV_NAME
1226 ": %s: Failed to power on the adapter.\n",
1238 priv->net_dev->name); 1227 priv->net_dev->name);
1239 return -EIO; 1228 return -EIO;
1240 } 1229 }
@@ -1293,7 +1282,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1293 i ? "SUCCESS" : "FAILED"); 1282 i ? "SUCCESS" : "FAILED");
1294 1283
1295 if (!i) { 1284 if (!i) {
1296 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n", 1285 printk(KERN_WARNING DRV_NAME
1286 ": %s: Firmware did not initialize.\n",
1297 priv->net_dev->name); 1287 priv->net_dev->name);
1298 return -EIO; 1288 return -EIO;
1299 } 1289 }
@@ -1326,7 +1316,6 @@ static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1326 priv->fatal_error = 0; 1316 priv->fatal_error = 0;
1327} 1317}
1328 1318
1329
1330/* NOTE: Our interrupt is disabled when this method is called */ 1319/* NOTE: Our interrupt is disabled when this method is called */
1331static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) 1320static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1332{ 1321{
@@ -1350,19 +1339,19 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1350 1339
1351 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 1340 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1352 break; 1341 break;
1353 } while(i--); 1342 } while (i--);
1354 1343
1355 priv->status &= ~STATUS_RESET_PENDING; 1344 priv->status &= ~STATUS_RESET_PENDING;
1356 1345
1357 if (!i) { 1346 if (!i) {
1358 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n"); 1347 IPW_DEBUG_INFO
1348 ("exit - waited too long for master assert stop\n");
1359 return -EIO; 1349 return -EIO;
1360 } 1350 }
1361 1351
1362 write_register(priv->net_dev, IPW_REG_RESET_REG, 1352 write_register(priv->net_dev, IPW_REG_RESET_REG,
1363 IPW_AUX_HOST_RESET_REG_SW_RESET); 1353 IPW_AUX_HOST_RESET_REG_SW_RESET);
1364 1354
1365
1366 /* Reset any fatal_error conditions */ 1355 /* Reset any fatal_error conditions */
1367 ipw2100_reset_fatalerror(priv); 1356 ipw2100_reset_fatalerror(priv);
1368 1357
@@ -1415,7 +1404,6 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1415 return -EIO; 1404 return -EIO;
1416} 1405}
1417 1406
1418
1419static int ipw2100_enable_adapter(struct ipw2100_priv *priv) 1407static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1420{ 1408{
1421 struct host_command cmd = { 1409 struct host_command cmd = {
@@ -1445,9 +1433,8 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1445 1433
1446 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED); 1434 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1447 if (err) { 1435 if (err) {
1448 IPW_DEBUG_INFO( 1436 IPW_DEBUG_INFO("%s: card not responding to init command.\n",
1449 "%s: card not responding to init command.\n", 1437 priv->net_dev->name);
1450 priv->net_dev->name);
1451 goto fail_up; 1438 goto fail_up;
1452 } 1439 }
1453 1440
@@ -1456,7 +1443,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1456 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); 1443 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1457 } 1444 }
1458 1445
1459fail_up: 1446 fail_up:
1460 up(&priv->adapter_sem); 1447 up(&priv->adapter_sem);
1461 return err; 1448 return err;
1462} 1449}
@@ -1488,7 +1475,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1488 1475
1489 err = ipw2100_hw_phy_off(priv); 1476 err = ipw2100_hw_phy_off(priv);
1490 if (err) 1477 if (err)
1491 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err); 1478 printk(KERN_WARNING DRV_NAME
1479 ": Error disabling radio %d\n", err);
1492 1480
1493 /* 1481 /*
1494 * If in D0-standby mode going directly to D3 may cause a 1482 * If in D0-standby mode going directly to D3 may cause a
@@ -1566,7 +1554,6 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1566 return 0; 1554 return 0;
1567} 1555}
1568 1556
1569
1570static int ipw2100_disable_adapter(struct ipw2100_priv *priv) 1557static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1571{ 1558{
1572 struct host_command cmd = { 1559 struct host_command cmd = {
@@ -1593,19 +1580,21 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1593 1580
1594 err = ipw2100_hw_send_command(priv, &cmd); 1581 err = ipw2100_hw_send_command(priv, &cmd);
1595 if (err) { 1582 if (err) {
1596 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n"); 1583 printk(KERN_WARNING DRV_NAME
1584 ": exit - failed to send CARD_DISABLE command\n");
1597 goto fail_up; 1585 goto fail_up;
1598 } 1586 }
1599 1587
1600 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED); 1588 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1601 if (err) { 1589 if (err) {
1602 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n"); 1590 printk(KERN_WARNING DRV_NAME
1591 ": exit - card failed to change to DISABLED\n");
1603 goto fail_up; 1592 goto fail_up;
1604 } 1593 }
1605 1594
1606 IPW_DEBUG_INFO("TODO: implement scan state machine\n"); 1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1607 1596
1608fail_up: 1597 fail_up:
1609 up(&priv->adapter_sem); 1598 up(&priv->adapter_sem);
1610 return err; 1599 return err;
1611} 1600}
@@ -1627,7 +1616,7 @@ static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1627 1616
1628 if (!(priv->config & CFG_ASSOCIATE)) 1617 if (!(priv->config & CFG_ASSOCIATE))
1629 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE; 1618 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1630 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled) 1619 if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
1631 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL; 1620 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1632 if (priv->config & CFG_PASSIVE_SCAN) 1621 if (priv->config & CFG_PASSIVE_SCAN)
1633 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE; 1622 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -1709,8 +1698,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1709 (priv->status & STATUS_RESET_PENDING)) { 1698 (priv->status & STATUS_RESET_PENDING)) {
1710 /* Power cycle the card ... */ 1699 /* Power cycle the card ... */
1711 if (ipw2100_power_cycle_adapter(priv)) { 1700 if (ipw2100_power_cycle_adapter(priv)) {
1712 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n", 1701 printk(KERN_WARNING DRV_NAME
1713 priv->net_dev->name); 1702 ": %s: Could not cycle adapter.\n",
1703 priv->net_dev->name);
1714 rc = 1; 1704 rc = 1;
1715 goto exit; 1705 goto exit;
1716 } 1706 }
@@ -1719,8 +1709,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1719 1709
1720 /* Load the firmware, start the clocks, etc. */ 1710 /* Load the firmware, start the clocks, etc. */
1721 if (ipw2100_start_adapter(priv)) { 1711 if (ipw2100_start_adapter(priv)) {
1722 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n", 1712 printk(KERN_ERR DRV_NAME
1723 priv->net_dev->name); 1713 ": %s: Failed to start the firmware.\n",
1714 priv->net_dev->name);
1724 rc = 1; 1715 rc = 1;
1725 goto exit; 1716 goto exit;
1726 } 1717 }
@@ -1729,16 +1720,18 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1729 1720
1730 /* Determine capabilities of this particular HW configuration */ 1721 /* Determine capabilities of this particular HW configuration */
1731 if (ipw2100_get_hw_features(priv)) { 1722 if (ipw2100_get_hw_features(priv)) {
1732 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n", 1723 printk(KERN_ERR DRV_NAME
1733 priv->net_dev->name); 1724 ": %s: Failed to determine HW features.\n",
1725 priv->net_dev->name);
1734 rc = 1; 1726 rc = 1;
1735 goto exit; 1727 goto exit;
1736 } 1728 }
1737 1729
1738 lock = LOCK_NONE; 1730 lock = LOCK_NONE;
1739 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { 1731 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1740 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n", 1732 printk(KERN_ERR DRV_NAME
1741 priv->net_dev->name); 1733 ": %s: Failed to clear ordinal lock.\n",
1734 priv->net_dev->name);
1742 rc = 1; 1735 rc = 1;
1743 goto exit; 1736 goto exit;
1744 } 1737 }
@@ -1764,7 +1757,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1764 * HOST_COMPLETE */ 1757 * HOST_COMPLETE */
1765 if (ipw2100_adapter_setup(priv)) { 1758 if (ipw2100_adapter_setup(priv)) {
1766 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n", 1759 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
1767 priv->net_dev->name); 1760 priv->net_dev->name);
1768 rc = 1; 1761 rc = 1;
1769 goto exit; 1762 goto exit;
1770 } 1763 }
@@ -1773,20 +1766,19 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1773 /* Enable the adapter - sends HOST_COMPLETE */ 1766 /* Enable the adapter - sends HOST_COMPLETE */
1774 if (ipw2100_enable_adapter(priv)) { 1767 if (ipw2100_enable_adapter(priv)) {
1775 printk(KERN_ERR DRV_NAME ": " 1768 printk(KERN_ERR DRV_NAME ": "
1776 "%s: failed in call to enable adapter.\n", 1769 "%s: failed in call to enable adapter.\n",
1777 priv->net_dev->name); 1770 priv->net_dev->name);
1778 ipw2100_hw_stop_adapter(priv); 1771 ipw2100_hw_stop_adapter(priv);
1779 rc = 1; 1772 rc = 1;
1780 goto exit; 1773 goto exit;
1781 } 1774 }
1782 1775
1783
1784 /* Start a scan . . . */ 1776 /* Start a scan . . . */
1785 ipw2100_set_scan_options(priv); 1777 ipw2100_set_scan_options(priv);
1786 ipw2100_start_scan(priv); 1778 ipw2100_start_scan(priv);
1787 } 1779 }
1788 1780
1789 exit: 1781 exit:
1790 return rc; 1782 return rc;
1791} 1783}
1792 1784
@@ -1802,8 +1794,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1802 unsigned long flags; 1794 unsigned long flags;
1803 union iwreq_data wrqu = { 1795 union iwreq_data wrqu = {
1804 .ap_addr = { 1796 .ap_addr = {
1805 .sa_family = ARPHRD_ETHER 1797 .sa_family = ARPHRD_ETHER}
1806 }
1807 }; 1798 };
1808 int associated = priv->status & STATUS_ASSOCIATED; 1799 int associated = priv->status & STATUS_ASSOCIATED;
1809 1800
@@ -1842,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1842 1833
1843#ifdef ACPI_CSTATE_LIMIT_DEFINED 1834#ifdef ACPI_CSTATE_LIMIT_DEFINED
1844 if (priv->config & CFG_C3_DISABLED) { 1835 if (priv->config & CFG_C3_DISABLED) {
1845 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 1836 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
1846 acpi_set_cstate_limit(priv->cstate_limit); 1837 acpi_set_cstate_limit(priv->cstate_limit);
1847 priv->config &= ~CFG_C3_DISABLED; 1838 priv->config &= ~CFG_C3_DISABLED;
1848 } 1839 }
@@ -1862,14 +1853,12 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1862 unsigned long flags; 1853 unsigned long flags;
1863 union iwreq_data wrqu = { 1854 union iwreq_data wrqu = {
1864 .ap_addr = { 1855 .ap_addr = {
1865 .sa_family = ARPHRD_ETHER 1856 .sa_family = ARPHRD_ETHER}
1866 }
1867 }; 1857 };
1868 int associated = priv->status & STATUS_ASSOCIATED; 1858 int associated = priv->status & STATUS_ASSOCIATED;
1869 1859
1870 spin_lock_irqsave(&priv->low_lock, flags); 1860 spin_lock_irqsave(&priv->low_lock, flags);
1871 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n", 1861 IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
1872 priv->net_dev->name);
1873 priv->resets++; 1862 priv->resets++;
1874 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 1863 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1875 priv->status |= STATUS_SECURITY_UPDATED; 1864 priv->status |= STATUS_SECURITY_UPDATED;
@@ -1894,7 +1883,6 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1894 1883
1895} 1884}
1896 1885
1897
1898static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) 1886static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1899{ 1887{
1900 1888
@@ -1904,7 +1892,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1904 u32 txrate; 1892 u32 txrate;
1905 u32 chan; 1893 u32 chan;
1906 char *txratename; 1894 char *txratename;
1907 u8 bssid[ETH_ALEN]; 1895 u8 bssid[ETH_ALEN];
1908 1896
1909 /* 1897 /*
1910 * TBD: BSSID is usually 00:00:00:00:00:00 here and not 1898 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1918,16 +1906,15 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1918 essid, &essid_len); 1906 essid, &essid_len);
1919 if (ret) { 1907 if (ret) {
1920 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1908 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1921 __LINE__); 1909 __LINE__);
1922 return; 1910 return;
1923 } 1911 }
1924 1912
1925 len = sizeof(u32); 1913 len = sizeof(u32);
1926 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, 1914 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &txrate, &len);
1927 &txrate, &len);
1928 if (ret) { 1915 if (ret) {
1929 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1916 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1930 __LINE__); 1917 __LINE__);
1931 return; 1918 return;
1932 } 1919 }
1933 1920
@@ -1935,19 +1922,18 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1935 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len); 1922 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1936 if (ret) { 1923 if (ret) {
1937 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1924 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1938 __LINE__); 1925 __LINE__);
1939 return; 1926 return;
1940 } 1927 }
1941 len = ETH_ALEN; 1928 len = ETH_ALEN;
1942 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); 1929 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1943 if (ret) { 1930 if (ret) {
1944 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1931 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1945 __LINE__); 1932 __LINE__);
1946 return; 1933 return;
1947 } 1934 }
1948 memcpy(priv->ieee->bssid, bssid, ETH_ALEN); 1935 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1949 1936
1950
1951 switch (txrate) { 1937 switch (txrate) {
1952 case TX_RATE_1_MBIT: 1938 case TX_RATE_1_MBIT:
1953 txratename = "1Mbps"; 1939 txratename = "1Mbps";
@@ -1974,7 +1960,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1974 1960
1975 /* now we copy read ssid into dev */ 1961 /* now we copy read ssid into dev */
1976 if (!(priv->config & CFG_STATIC_ESSID)) { 1962 if (!(priv->config & CFG_STATIC_ESSID)) {
1977 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE); 1963 priv->essid_len = min((u8) essid_len, (u8) IW_ESSID_MAX_SIZE);
1978 memcpy(priv->essid, essid, priv->essid_len); 1964 memcpy(priv->essid, essid, priv->essid_len);
1979 } 1965 }
1980 priv->channel = chan; 1966 priv->channel = chan;
@@ -1986,7 +1972,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1986 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); 1972 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1987} 1973}
1988 1974
1989
1990static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, 1975static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1991 int length, int batch_mode) 1976 int length, int batch_mode)
1992{ 1977{
@@ -2001,8 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2001 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len)); 1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2002 1987
2003 if (ssid_len) 1988 if (ssid_len)
2004 memcpy((char*)cmd.host_command_parameters, 1989 memcpy(cmd.host_command_parameters, essid, ssid_len);
2005 essid, ssid_len);
2006 1990
2007 if (!batch_mode) { 1991 if (!batch_mode) {
2008 err = ipw2100_disable_adapter(priv); 1992 err = ipw2100_disable_adapter(priv);
@@ -2014,7 +1998,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2014 * disable auto association -- so we cheat by setting a bogus SSID */ 1998 * disable auto association -- so we cheat by setting a bogus SSID */
2015 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) { 1999 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2016 int i; 2000 int i;
2017 u8 *bogus = (u8*)cmd.host_command_parameters; 2001 u8 *bogus = (u8 *) cmd.host_command_parameters;
2018 for (i = 0; i < IW_ESSID_MAX_SIZE; i++) 2002 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2019 bogus[i] = 0x18 + i; 2003 bogus[i] = 0x18 + i;
2020 cmd.host_command_length = IW_ESSID_MAX_SIZE; 2004 cmd.host_command_length = IW_ESSID_MAX_SIZE;
@@ -2025,8 +2009,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2025 2009
2026 err = ipw2100_hw_send_command(priv, &cmd); 2010 err = ipw2100_hw_send_command(priv, &cmd);
2027 if (!err) { 2011 if (!err) {
2028 memset(priv->essid + ssid_len, 0, 2012 memset(priv->essid + ssid_len, 0, IW_ESSID_MAX_SIZE - ssid_len);
2029 IW_ESSID_MAX_SIZE - ssid_len);
2030 memcpy(priv->essid, essid, ssid_len); 2013 memcpy(priv->essid, essid, ssid_len);
2031 priv->essid_len = ssid_len; 2014 priv->essid_len = ssid_len;
2032 } 2015 }
@@ -2071,14 +2054,14 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2071static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) 2054static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2072{ 2055{
2073 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n", 2056 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2074 priv->net_dev->name); 2057 priv->net_dev->name);
2075 2058
2076 /* RF_KILL is now enabled (else we wouldn't be here) */ 2059 /* RF_KILL is now enabled (else we wouldn't be here) */
2077 priv->status |= STATUS_RF_KILL_HW; 2060 priv->status |= STATUS_RF_KILL_HW;
2078 2061
2079#ifdef ACPI_CSTATE_LIMIT_DEFINED 2062#ifdef ACPI_CSTATE_LIMIT_DEFINED
2080 if (priv->config & CFG_C3_DISABLED) { 2063 if (priv->config & CFG_C3_DISABLED) {
2081 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 2064 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
2082 acpi_set_cstate_limit(priv->cstate_limit); 2065 acpi_set_cstate_limit(priv->cstate_limit);
2083 priv->config &= ~CFG_C3_DISABLED; 2066 priv->config &= ~CFG_C3_DISABLED;
2084 } 2067 }
@@ -2102,16 +2085,16 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2102#define IPW2100_HANDLER(v, f) { v, f, # v } 2085#define IPW2100_HANDLER(v, f) { v, f, # v }
2103struct ipw2100_status_indicator { 2086struct ipw2100_status_indicator {
2104 int status; 2087 int status;
2105 void (*cb)(struct ipw2100_priv *priv, u32 status); 2088 void (*cb) (struct ipw2100_priv * priv, u32 status);
2106 char *name; 2089 char *name;
2107}; 2090};
2108#else 2091#else
2109#define IPW2100_HANDLER(v, f) { v, f } 2092#define IPW2100_HANDLER(v, f) { v, f }
2110struct ipw2100_status_indicator { 2093struct ipw2100_status_indicator {
2111 int status; 2094 int status;
2112 void (*cb)(struct ipw2100_priv *priv, u32 status); 2095 void (*cb) (struct ipw2100_priv * priv, u32 status);
2113}; 2096};
2114#endif /* CONFIG_IPW_DEBUG */ 2097#endif /* CONFIG_IPW_DEBUG */
2115 2098
2116static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status) 2099static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2117{ 2100{
@@ -2135,7 +2118,6 @@ static const struct ipw2100_status_indicator status_handlers[] = {
2135 IPW2100_HANDLER(-1, NULL) 2118 IPW2100_HANDLER(-1, NULL)
2136}; 2119};
2137 2120
2138
2139static void isr_status_change(struct ipw2100_priv *priv, int status) 2121static void isr_status_change(struct ipw2100_priv *priv, int status)
2140{ 2122{
2141 int i; 2123 int i;
@@ -2153,7 +2135,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2153 for (i = 0; status_handlers[i].status != -1; i++) { 2135 for (i = 0; status_handlers[i].status != -1; i++) {
2154 if (status == status_handlers[i].status) { 2136 if (status == status_handlers[i].status) {
2155 IPW_DEBUG_NOTIF("Status change: %s\n", 2137 IPW_DEBUG_NOTIF("Status change: %s\n",
2156 status_handlers[i].name); 2138 status_handlers[i].name);
2157 if (status_handlers[i].cb) 2139 if (status_handlers[i].cb)
2158 status_handlers[i].cb(priv, status); 2140 status_handlers[i].cb(priv, status);
2159 priv->wstats.status = status; 2141 priv->wstats.status = status;
@@ -2164,9 +2146,8 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2164 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status); 2146 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2165} 2147}
2166 2148
2167static void isr_rx_complete_command( 2149static void isr_rx_complete_command(struct ipw2100_priv *priv,
2168 struct ipw2100_priv *priv, 2150 struct ipw2100_cmd_header *cmd)
2169 struct ipw2100_cmd_header *cmd)
2170{ 2151{
2171#ifdef CONFIG_IPW_DEBUG 2152#ifdef CONFIG_IPW_DEBUG
2172 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) { 2153 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
@@ -2196,10 +2177,8 @@ static const char *frame_types[] = {
2196}; 2177};
2197#endif 2178#endif
2198 2179
2199 2180static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
2200static inline int ipw2100_alloc_skb( 2181 struct ipw2100_rx_packet *packet)
2201 struct ipw2100_priv *priv,
2202 struct ipw2100_rx_packet *packet)
2203{ 2182{
2204 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx)); 2183 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2205 if (!packet->skb) 2184 if (!packet->skb)
@@ -2215,7 +2194,6 @@ static inline int ipw2100_alloc_skb(
2215 return 0; 2194 return 0;
2216} 2195}
2217 2196
2218
2219#define SEARCH_ERROR 0xffffffff 2197#define SEARCH_ERROR 0xffffffff
2220#define SEARCH_FAIL 0xfffffffe 2198#define SEARCH_FAIL 0xfffffffe
2221#define SEARCH_SUCCESS 0xfffffff0 2199#define SEARCH_SUCCESS 0xfffffff0
@@ -2229,10 +2207,10 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2229 if (priv->snapshot[0]) 2207 if (priv->snapshot[0])
2230 return 1; 2208 return 1;
2231 for (i = 0; i < 0x30; i++) { 2209 for (i = 0; i < 0x30; i++) {
2232 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC); 2210 priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
2233 if (!priv->snapshot[i]) { 2211 if (!priv->snapshot[i]) {
2234 IPW_DEBUG_INFO("%s: Error allocating snapshot " 2212 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2235 "buffer %d\n", priv->net_dev->name, i); 2213 "buffer %d\n", priv->net_dev->name, i);
2236 while (i > 0) 2214 while (i > 0)
2237 kfree(priv->snapshot[--i]); 2215 kfree(priv->snapshot[--i]);
2238 priv->snapshot[0] = NULL; 2216 priv->snapshot[0] = NULL;
@@ -2253,7 +2231,7 @@ static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2253 priv->snapshot[0] = NULL; 2231 priv->snapshot[0] = NULL;
2254} 2232}
2255 2233
2256static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf, 2234static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
2257 size_t len, int mode) 2235 size_t len, int mode)
2258{ 2236{
2259 u32 i, j; 2237 u32 i, j;
@@ -2270,9 +2248,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2270 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) { 2248 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2271 read_nic_dword(priv->net_dev, i, &tmp); 2249 read_nic_dword(priv->net_dev, i, &tmp);
2272 if (mode == SEARCH_SNAPSHOT) 2250 if (mode == SEARCH_SNAPSHOT)
2273 *(u32 *)SNAPSHOT_ADDR(i) = tmp; 2251 *(u32 *) SNAPSHOT_ADDR(i) = tmp;
2274 if (ret == SEARCH_FAIL) { 2252 if (ret == SEARCH_FAIL) {
2275 d = (u8*)&tmp; 2253 d = (u8 *) & tmp;
2276 for (j = 0; j < 4; j++) { 2254 for (j = 0; j < 4; j++) {
2277 if (*s != *d) { 2255 if (*s != *d) {
2278 s = in_buf; 2256 s = in_buf;
@@ -2310,8 +2288,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2310static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH]; 2288static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2311#endif 2289#endif
2312 2290
2313static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, 2291static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
2314 int i)
2315{ 2292{
2316#ifdef CONFIG_IPW_DEBUG_C3 2293#ifdef CONFIG_IPW_DEBUG_C3
2317 struct ipw2100_status *status = &priv->status_queue.drv[i]; 2294 struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2322,11 +2299,11 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2322 int limit; 2299 int limit;
2323#endif 2300#endif
2324 2301
2325 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at " 2302 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
2326 "0x%04zX.\n", i * sizeof(struct ipw2100_status)); 2303 i * sizeof(struct ipw2100_status));
2327 2304
2328#ifdef ACPI_CSTATE_LIMIT_DEFINED 2305#ifdef ACPI_CSTATE_LIMIT_DEFINED
2329 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n"); 2306 IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
2330 limit = acpi_get_cstate_limit(); 2307 limit = acpi_get_cstate_limit();
2331 if (limit > 2) { 2308 if (limit > 2) {
2332 priv->cstate_limit = limit; 2309 priv->cstate_limit = limit;
@@ -2346,9 +2323,9 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2346 2323
2347 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 2324 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2348 break; 2325 break;
2349 } while (j--); 2326 } while (j--);
2350 2327
2351 match = ipw2100_match_buf(priv, (u8*)status, 2328 match = ipw2100_match_buf(priv, (u8 *) status,
2352 sizeof(struct ipw2100_status), 2329 sizeof(struct ipw2100_status),
2353 SEARCH_SNAPSHOT); 2330 SEARCH_SNAPSHOT);
2354 if (match < SEARCH_SUCCESS) 2331 if (match < SEARCH_SUCCESS)
@@ -2360,7 +2337,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2360 IPW_DEBUG_INFO("%s: No DMA status match in " 2337 IPW_DEBUG_INFO("%s: No DMA status match in "
2361 "Firmware.\n", priv->net_dev->name); 2338 "Firmware.\n", priv->net_dev->name);
2362 2339
2363 printk_buf((u8*)priv->status_queue.drv, 2340 printk_buf((u8 *) priv->status_queue.drv,
2364 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH); 2341 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2365#endif 2342#endif
2366 2343
@@ -2392,26 +2369,26 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2392 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2393 return; 2370 return;
2394 } 2371 }
2395 2372#ifdef CONFIG_IPW2100_MONITOR
2396 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && 2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2374 priv->config & CFG_CRC_CHECK &&
2397 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { 2375 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2398 IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); 2376 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2399 priv->ieee->stats.rx_errors++; 2377 priv->ieee->stats.rx_errors++;
2400 return; 2378 return;
2401 } 2379 }
2380#endif
2402 2381
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) { 2383 !(priv->status & STATUS_ASSOCIATED))) {
2405 IPW_DEBUG_DROP("Dropping packet while not associated.\n"); 2384 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2406 priv->wstats.discard.misc++; 2385 priv->wstats.discard.misc++;
2407 return; 2386 return;
2408 } 2387 }
2409 2388
2410
2411 pci_unmap_single(priv->pci_dev, 2389 pci_unmap_single(priv->pci_dev,
2412 packet->dma_addr, 2390 packet->dma_addr,
2413 sizeof(struct ipw2100_rx), 2391 sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
2414 PCI_DMA_FROMDEVICE);
2415 2392
2416 skb_put(packet->skb, status->frame_size); 2393 skb_put(packet->skb, status->frame_size);
2417 2394
@@ -2438,8 +2415,8 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2438 /* We need to allocate a new SKB and attach it to the RDB. */ 2415 /* We need to allocate a new SKB and attach it to the RDB. */
2439 if (unlikely(ipw2100_alloc_skb(priv, packet))) { 2416 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2440 printk(KERN_WARNING DRV_NAME ": " 2417 printk(KERN_WARNING DRV_NAME ": "
2441 "%s: Unable to allocate SKB onto RBD ring - disabling " 2418 "%s: Unable to allocate SKB onto RBD ring - disabling "
2442 "adapter.\n", priv->net_dev->name); 2419 "adapter.\n", priv->net_dev->name);
2443 /* TODO: schedule adapter shutdown */ 2420 /* TODO: schedule adapter shutdown */
2444 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); 2421 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2445 } 2422 }
@@ -2534,11 +2511,11 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2534 2511
2535 /* Sync the DMA for the STATUS buffer so CPU is sure to get 2512 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2536 * the correct values */ 2513 * the correct values */
2537 pci_dma_sync_single_for_cpu( 2514 pci_dma_sync_single_for_cpu(priv->pci_dev,
2538 priv->pci_dev, 2515 sq->nic +
2539 sq->nic + sizeof(struct ipw2100_status) * i, 2516 sizeof(struct ipw2100_status) * i,
2540 sizeof(struct ipw2100_status), 2517 sizeof(struct ipw2100_status),
2541 PCI_DMA_FROMDEVICE); 2518 PCI_DMA_FROMDEVICE);
2542 2519
2543 /* Sync the DMA for the RX buffer so CPU is sure to get 2520 /* Sync the DMA for the RX buffer so CPU is sure to get
2544 * the correct values */ 2521 * the correct values */
@@ -2552,8 +2529,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2552 } 2529 }
2553 2530
2554 u = packet->rxp; 2531 u = packet->rxp;
2555 frame_type = sq->drv[i].status_fields & 2532 frame_type = sq->drv[i].status_fields & STATUS_TYPE_MASK;
2556 STATUS_TYPE_MASK;
2557 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM; 2533 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2558 stats.len = sq->drv[i].frame_size; 2534 stats.len = sq->drv[i].frame_size;
2559 2535
@@ -2562,16 +2538,14 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2562 stats.mask |= IEEE80211_STATMASK_RSSI; 2538 stats.mask |= IEEE80211_STATMASK_RSSI;
2563 stats.freq = IEEE80211_24GHZ_BAND; 2539 stats.freq = IEEE80211_24GHZ_BAND;
2564 2540
2565 IPW_DEBUG_RX( 2541 IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
2566 "%s: '%s' frame type received (%d).\n", 2542 priv->net_dev->name, frame_types[frame_type],
2567 priv->net_dev->name, frame_types[frame_type], 2543 stats.len);
2568 stats.len);
2569 2544
2570 switch (frame_type) { 2545 switch (frame_type) {
2571 case COMMAND_STATUS_VAL: 2546 case COMMAND_STATUS_VAL:
2572 /* Reset Rx watchdog */ 2547 /* Reset Rx watchdog */
2573 isr_rx_complete_command( 2548 isr_rx_complete_command(priv, &u->rx_data.command);
2574 priv, &u->rx_data.command);
2575 break; 2549 break;
2576 2550
2577 case STATUS_CHANGE_VAL: 2551 case STATUS_CHANGE_VAL:
@@ -2588,12 +2562,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2588#endif 2562#endif
2589 if (stats.len < sizeof(u->rx_data.header)) 2563 if (stats.len < sizeof(u->rx_data.header))
2590 break; 2564 break;
2591 switch (WLAN_FC_GET_TYPE(u->rx_data.header. 2565 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2592 frame_ctl)) {
2593 case IEEE80211_FTYPE_MGMT: 2566 case IEEE80211_FTYPE_MGMT:
2594 ieee80211_rx_mgt(priv->ieee, 2567 ieee80211_rx_mgt(priv->ieee,
2595 &u->rx_data.header, 2568 &u->rx_data.header, &stats);
2596 &stats);
2597 break; 2569 break;
2598 2570
2599 case IEEE80211_FTYPE_CTL: 2571 case IEEE80211_FTYPE_CTL:
@@ -2607,7 +2579,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2607 break; 2579 break;
2608 } 2580 }
2609 2581
2610 increment: 2582 increment:
2611 /* clear status field associated with this RBD */ 2583 /* clear status field associated with this RBD */
2612 rxq->drv[i].status.info.field = 0; 2584 rxq->drv[i].status.info.field = 0;
2613 2585
@@ -2619,12 +2591,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2619 rxq->next = (i ? i : rxq->entries) - 1; 2591 rxq->next = (i ? i : rxq->entries) - 1;
2620 2592
2621 write_register(priv->net_dev, 2593 write_register(priv->net_dev,
2622 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, 2594 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, rxq->next);
2623 rxq->next);
2624 } 2595 }
2625} 2596}
2626 2597
2627
2628/* 2598/*
2629 * __ipw2100_tx_process 2599 * __ipw2100_tx_process
2630 * 2600 *
@@ -2667,7 +2637,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2667static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) 2637static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2668{ 2638{
2669 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2639 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2670 struct ipw2100_bd *tbd; 2640 struct ipw2100_bd *tbd;
2671 struct list_head *element; 2641 struct list_head *element;
2672 struct ipw2100_tx_packet *packet; 2642 struct ipw2100_tx_packet *packet;
2673 int descriptors_used; 2643 int descriptors_used;
@@ -2680,7 +2650,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2680 element = priv->fw_pend_list.next; 2650 element = priv->fw_pend_list.next;
2681 2651
2682 packet = list_entry(element, struct ipw2100_tx_packet, list); 2652 packet = list_entry(element, struct ipw2100_tx_packet, list);
2683 tbd = &txq->drv[packet->index]; 2653 tbd = &txq->drv[packet->index];
2684 2654
2685 /* Determine how many TBD entries must be finished... */ 2655 /* Determine how many TBD entries must be finished... */
2686 switch (packet->type) { 2656 switch (packet->type) {
@@ -2693,14 +2663,14 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2693 case DATA: 2663 case DATA:
2694 /* DATA uses two slots; advance and loop position. */ 2664 /* DATA uses two slots; advance and loop position. */
2695 descriptors_used = tbd->num_fragments; 2665 descriptors_used = tbd->num_fragments;
2696 frag_num = tbd->num_fragments - 1; 2666 frag_num = tbd->num_fragments - 1;
2697 e = txq->oldest + frag_num; 2667 e = txq->oldest + frag_num;
2698 e %= txq->entries; 2668 e %= txq->entries;
2699 break; 2669 break;
2700 2670
2701 default: 2671 default:
2702 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n", 2672 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2703 priv->net_dev->name); 2673 priv->net_dev->name);
2704 return 0; 2674 return 0;
2705 } 2675 }
2706 2676
@@ -2716,13 +2686,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2716 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n", 2686 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2717 priv->net_dev->name); 2687 priv->net_dev->name);
2718 2688
2719 /* 2689 /*
2720 * txq->next is the index of the last packet written txq->oldest is 2690 * txq->next is the index of the last packet written txq->oldest is
2721 * the index of the r is the index of the next packet to be read by 2691 * the index of the r is the index of the next packet to be read by
2722 * firmware 2692 * firmware
2723 */ 2693 */
2724 2694
2725
2726 /* 2695 /*
2727 * Quick graphic to help you visualize the following 2696 * Quick graphic to help you visualize the following
2728 * if / else statement 2697 * if / else statement
@@ -2750,23 +2719,20 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2750#ifdef CONFIG_IPW_DEBUG 2719#ifdef CONFIG_IPW_DEBUG
2751 { 2720 {
2752 int i = txq->oldest; 2721 int i = txq->oldest;
2753 IPW_DEBUG_TX( 2722 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2754 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2723 &txq->drv[i],
2755 &txq->drv[i], 2724 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
2756 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)), 2725 txq->drv[i].host_addr, txq->drv[i].buf_length);
2757 txq->drv[i].host_addr,
2758 txq->drv[i].buf_length);
2759 2726
2760 if (packet->type == DATA) { 2727 if (packet->type == DATA) {
2761 i = (i + 1) % txq->entries; 2728 i = (i + 1) % txq->entries;
2762 2729
2763 IPW_DEBUG_TX( 2730 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2764 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2731 &txq->drv[i],
2765 &txq->drv[i], 2732 (u32) (txq->nic + i *
2766 (u32)(txq->nic + i * 2733 sizeof(struct ipw2100_bd)),
2767 sizeof(struct ipw2100_bd)), 2734 (u32) txq->drv[i].host_addr,
2768 (u32)txq->drv[i].host_addr, 2735 txq->drv[i].buf_length);
2769 txq->drv[i].buf_length);
2770 } 2736 }
2771 } 2737 }
2772#endif 2738#endif
@@ -2780,23 +2746,18 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2780 priv->net_dev->name, txq->oldest, packet->index); 2746 priv->net_dev->name, txq->oldest, packet->index);
2781 2747
2782 /* DATA packet; we have to unmap and free the SKB */ 2748 /* DATA packet; we have to unmap and free the SKB */
2783 priv->ieee->stats.tx_packets++;
2784 for (i = 0; i < frag_num; i++) { 2749 for (i = 0; i < frag_num; i++) {
2785 tbd = &txq->drv[(packet->index + 1 + i) % 2750 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
2786 txq->entries];
2787 2751
2788 IPW_DEBUG_TX( 2752 IPW_DEBUG_TX("TX%d P=%08x L=%d\n",
2789 "TX%d P=%08x L=%d\n", 2753 (packet->index + 1 + i) % txq->entries,
2790 (packet->index + 1 + i) % txq->entries, 2754 tbd->host_addr, tbd->buf_length);
2791 tbd->host_addr, tbd->buf_length);
2792 2755
2793 pci_unmap_single(priv->pci_dev, 2756 pci_unmap_single(priv->pci_dev,
2794 tbd->host_addr, 2757 tbd->host_addr,
2795 tbd->buf_length, 2758 tbd->buf_length, PCI_DMA_TODEVICE);
2796 PCI_DMA_TODEVICE);
2797 } 2759 }
2798 2760
2799 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2800 ieee80211_txb_free(packet->info.d_struct.txb); 2761 ieee80211_txb_free(packet->info.d_struct.txb);
2801 packet->info.d_struct.txb = NULL; 2762 packet->info.d_struct.txb = NULL;
2802 2763
@@ -2805,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2805 2766
2806 /* We have a free slot in the Tx queue, so wake up the 2767 /* We have a free slot in the Tx queue, so wake up the
2807 * transmit layer if it is stopped. */ 2768 * transmit layer if it is stopped. */
2808 if (priv->status & STATUS_ASSOCIATED && 2769 if (priv->status & STATUS_ASSOCIATED)
2809 netif_queue_stopped(priv->net_dev)) {
2810 IPW_DEBUG_INFO(KERN_INFO
2811 "%s: Waking net queue.\n",
2812 priv->net_dev->name);
2813 netif_wake_queue(priv->net_dev); 2770 netif_wake_queue(priv->net_dev);
2814 }
2815 2771
2816 /* A packet was processed by the hardware, so update the 2772 /* A packet was processed by the hardware, so update the
2817 * watchdog */ 2773 * watchdog */
@@ -2829,11 +2785,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2829#ifdef CONFIG_IPW_DEBUG 2785#ifdef CONFIG_IPW_DEBUG
2830 if (packet->info.c_struct.cmd->host_command_reg < 2786 if (packet->info.c_struct.cmd->host_command_reg <
2831 sizeof(command_types) / sizeof(*command_types)) 2787 sizeof(command_types) / sizeof(*command_types))
2832 IPW_DEBUG_TX( 2788 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
2833 "Command '%s (%d)' processed: %d.\n", 2789 command_types[packet->info.c_struct.cmd->
2834 command_types[packet->info.c_struct.cmd->host_command_reg], 2790 host_command_reg],
2835 packet->info.c_struct.cmd->host_command_reg, 2791 packet->info.c_struct.cmd->
2836 packet->info.c_struct.cmd->cmd_status_reg); 2792 host_command_reg,
2793 packet->info.c_struct.cmd->cmd_status_reg);
2837#endif 2794#endif
2838 2795
2839 list_add_tail(element, &priv->msg_free_list); 2796 list_add_tail(element, &priv->msg_free_list);
@@ -2848,17 +2805,17 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2848 SET_STAT(&priv->txq_stat, txq->available); 2805 SET_STAT(&priv->txq_stat, txq->available);
2849 2806
2850 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n", 2807 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2851 jiffies - packet->jiffy_start); 2808 jiffies - packet->jiffy_start);
2852 2809
2853 return (!list_empty(&priv->fw_pend_list)); 2810 return (!list_empty(&priv->fw_pend_list));
2854} 2811}
2855 2812
2856
2857static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv) 2813static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2858{ 2814{
2859 int i = 0; 2815 int i = 0;
2860 2816
2861 while (__ipw2100_tx_process(priv) && i < 200) i++; 2817 while (__ipw2100_tx_process(priv) && i < 200)
2818 i++;
2862 2819
2863 if (i == 200) { 2820 if (i == 200) {
2864 printk(KERN_WARNING DRV_NAME ": " 2821 printk(KERN_WARNING DRV_NAME ": "
@@ -2867,7 +2824,6 @@ static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2867 } 2824 }
2868} 2825}
2869 2826
2870
2871static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) 2827static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2872{ 2828{
2873 struct list_head *element; 2829 struct list_head *element;
@@ -2892,13 +2848,12 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2892 list_del(element); 2848 list_del(element);
2893 DEC_STAT(&priv->msg_pend_stat); 2849 DEC_STAT(&priv->msg_pend_stat);
2894 2850
2895 packet = list_entry(element, 2851 packet = list_entry(element, struct ipw2100_tx_packet, list);
2896 struct ipw2100_tx_packet, list);
2897 2852
2898 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", 2853 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2899 &txq->drv[txq->next], 2854 &txq->drv[txq->next],
2900 (void*)(txq->nic + txq->next * 2855 (void *)(txq->nic + txq->next *
2901 sizeof(struct ipw2100_bd))); 2856 sizeof(struct ipw2100_bd)));
2902 2857
2903 packet->index = txq->next; 2858 packet->index = txq->next;
2904 2859
@@ -2911,8 +2866,8 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2911 * with f/w debug version */ 2866 * with f/w debug version */
2912 tbd->num_fragments = 1; 2867 tbd->num_fragments = 1;
2913 tbd->status.info.field = 2868 tbd->status.info.field =
2914 IPW_BD_STATUS_TX_FRAME_COMMAND | 2869 IPW_BD_STATUS_TX_FRAME_COMMAND |
2915 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2870 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2916 2871
2917 /* update TBD queue counters */ 2872 /* update TBD queue counters */
2918 txq->next++; 2873 txq->next++;
@@ -2934,7 +2889,6 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2934 } 2889 }
2935} 2890}
2936 2891
2937
2938/* 2892/*
2939 * ipw2100_tx_send_data 2893 * ipw2100_tx_send_data
2940 * 2894 *
@@ -2946,7 +2900,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2946 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2900 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2947 struct ipw2100_bd *tbd; 2901 struct ipw2100_bd *tbd;
2948 int next = txq->next; 2902 int next = txq->next;
2949 int i = 0; 2903 int i = 0;
2950 struct ipw2100_data_header *ipw_hdr; 2904 struct ipw2100_data_header *ipw_hdr;
2951 struct ieee80211_hdr_3addr *hdr; 2905 struct ieee80211_hdr_3addr *hdr;
2952 2906
@@ -2958,20 +2912,18 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2958 * maintained between the r and w indexes 2912 * maintained between the r and w indexes
2959 */ 2913 */
2960 element = priv->tx_pend_list.next; 2914 element = priv->tx_pend_list.next;
2961 packet = list_entry(element, struct ipw2100_tx_packet, list); 2915 packet = list_entry(element, struct ipw2100_tx_packet, list);
2962 2916
2963 if (unlikely(1 + packet->info.d_struct.txb->nr_frags > 2917 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2964 IPW_MAX_BDS)) { 2918 IPW_MAX_BDS)) {
2965 /* TODO: Support merging buffers if more than 2919 /* TODO: Support merging buffers if more than
2966 * IPW_MAX_BDS are used */ 2920 * IPW_MAX_BDS are used */
2967 IPW_DEBUG_INFO( 2921 IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. "
2968 "%s: Maximum BD theshold exceeded. " 2922 "Increase fragmentation level.\n",
2969 "Increase fragmentation level.\n", 2923 priv->net_dev->name);
2970 priv->net_dev->name);
2971 } 2924 }
2972 2925
2973 if (txq->available <= 3 + 2926 if (txq->available <= 3 + packet->info.d_struct.txb->nr_frags) {
2974 packet->info.d_struct.txb->nr_frags) {
2975 IPW_DEBUG_TX("no room in tx_queue\n"); 2927 IPW_DEBUG_TX("no room in tx_queue\n");
2976 break; 2928 break;
2977 } 2929 }
@@ -2985,7 +2937,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2985 2937
2986 ipw_hdr = packet->info.d_struct.data; 2938 ipw_hdr = packet->info.d_struct.data;
2987 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb-> 2939 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
2988 fragments[0]->data; 2940 fragments[0]->data;
2989 2941
2990 if (priv->ieee->iw_mode == IW_MODE_INFRA) { 2942 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2991 /* To DS: Addr1 = BSSID, Addr2 = SA, 2943 /* To DS: Addr1 = BSSID, Addr2 = SA,
@@ -3007,7 +2959,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3007 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted; 2959 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3008 if (packet->info.d_struct.txb->nr_frags > 1) 2960 if (packet->info.d_struct.txb->nr_frags > 1)
3009 ipw_hdr->fragment_size = 2961 ipw_hdr->fragment_size =
3010 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN; 2962 packet->info.d_struct.txb->frag_size -
2963 IEEE80211_3ADDR_LEN;
3011 else 2964 else
3012 ipw_hdr->fragment_size = 0; 2965 ipw_hdr->fragment_size = 0;
3013 2966
@@ -3015,54 +2968,53 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3015 tbd->buf_length = sizeof(struct ipw2100_data_header); 2968 tbd->buf_length = sizeof(struct ipw2100_data_header);
3016 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags; 2969 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3017 tbd->status.info.field = 2970 tbd->status.info.field =
3018 IPW_BD_STATUS_TX_FRAME_802_3 | 2971 IPW_BD_STATUS_TX_FRAME_802_3 |
3019 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2972 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3020 txq->next++; 2973 txq->next++;
3021 txq->next %= txq->entries; 2974 txq->next %= txq->entries;
3022 2975
3023 IPW_DEBUG_TX( 2976 IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
3024 "data header tbd TX%d P=%08x L=%d\n", 2977 packet->index, tbd->host_addr, tbd->buf_length);
3025 packet->index, tbd->host_addr,
3026 tbd->buf_length);
3027#ifdef CONFIG_IPW_DEBUG 2978#ifdef CONFIG_IPW_DEBUG
3028 if (packet->info.d_struct.txb->nr_frags > 1) 2979 if (packet->info.d_struct.txb->nr_frags > 1)
3029 IPW_DEBUG_FRAG("fragment Tx: %d frames\n", 2980 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3030 packet->info.d_struct.txb->nr_frags); 2981 packet->info.d_struct.txb->nr_frags);
3031#endif 2982#endif
3032 2983
3033 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) { 2984 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3034 tbd = &txq->drv[txq->next]; 2985 tbd = &txq->drv[txq->next];
3035 if (i == packet->info.d_struct.txb->nr_frags - 1) 2986 if (i == packet->info.d_struct.txb->nr_frags - 1)
3036 tbd->status.info.field = 2987 tbd->status.info.field =
3037 IPW_BD_STATUS_TX_FRAME_802_3 | 2988 IPW_BD_STATUS_TX_FRAME_802_3 |
3038 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2989 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3039 else 2990 else
3040 tbd->status.info.field = 2991 tbd->status.info.field =
3041 IPW_BD_STATUS_TX_FRAME_802_3 | 2992 IPW_BD_STATUS_TX_FRAME_802_3 |
3042 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2993 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3043 2994
3044 tbd->buf_length = packet->info.d_struct.txb-> 2995 tbd->buf_length = packet->info.d_struct.txb->
3045 fragments[i]->len - IEEE80211_3ADDR_LEN; 2996 fragments[i]->len - IEEE80211_3ADDR_LEN;
3046 2997
3047 tbd->host_addr = pci_map_single( 2998 tbd->host_addr = pci_map_single(priv->pci_dev,
3048 priv->pci_dev, 2999 packet->info.d_struct.
3049 packet->info.d_struct.txb->fragments[i]->data + 3000 txb->fragments[i]->
3050 IEEE80211_3ADDR_LEN, 3001 data +
3051 tbd->buf_length, 3002 IEEE80211_3ADDR_LEN,
3052 PCI_DMA_TODEVICE); 3003 tbd->buf_length,
3004 PCI_DMA_TODEVICE);
3053 3005
3054 IPW_DEBUG_TX( 3006 IPW_DEBUG_TX("data frag tbd TX%d P=%08x L=%d\n",
3055 "data frag tbd TX%d P=%08x L=%d\n", 3007 txq->next, tbd->host_addr,
3056 txq->next, tbd->host_addr, tbd->buf_length); 3008 tbd->buf_length);
3057 3009
3058 pci_dma_sync_single_for_device( 3010 pci_dma_sync_single_for_device(priv->pci_dev,
3059 priv->pci_dev, tbd->host_addr, 3011 tbd->host_addr,
3060 tbd->buf_length, 3012 tbd->buf_length,
3061 PCI_DMA_TODEVICE); 3013 PCI_DMA_TODEVICE);
3062 3014
3063 txq->next++; 3015 txq->next++;
3064 txq->next %= txq->entries; 3016 txq->next %= txq->entries;
3065 } 3017 }
3066 3018
3067 txq->available -= 1 + packet->info.d_struct.txb->nr_frags; 3019 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3068 SET_STAT(&priv->txq_stat, txq->available); 3020 SET_STAT(&priv->txq_stat, txq->available);
@@ -3078,7 +3030,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3078 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX, 3030 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3079 txq->next); 3031 txq->next);
3080 } 3032 }
3081 return; 3033 return;
3082} 3034}
3083 3035
3084static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) 3036static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3106,11 +3058,9 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3106 3058
3107 if (inta & IPW2100_INTA_FATAL_ERROR) { 3059 if (inta & IPW2100_INTA_FATAL_ERROR) {
3108 printk(KERN_WARNING DRV_NAME 3060 printk(KERN_WARNING DRV_NAME
3109 ": Fatal interrupt. Scheduling firmware restart.\n"); 3061 ": Fatal interrupt. Scheduling firmware restart.\n");
3110 priv->inta_other++; 3062 priv->inta_other++;
3111 write_register( 3063 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FATAL_ERROR);
3112 dev, IPW_REG_INTA,
3113 IPW2100_INTA_FATAL_ERROR);
3114 3064
3115 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error); 3065 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3116 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n", 3066 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
@@ -3125,11 +3075,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3125 } 3075 }
3126 3076
3127 if (inta & IPW2100_INTA_PARITY_ERROR) { 3077 if (inta & IPW2100_INTA_PARITY_ERROR) {
3128 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3078 printk(KERN_ERR DRV_NAME
3079 ": ***** PARITY ERROR INTERRUPT !!!! \n");
3129 priv->inta_other++; 3080 priv->inta_other++;
3130 write_register( 3081 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3131 dev, IPW_REG_INTA,
3132 IPW2100_INTA_PARITY_ERROR);
3133 } 3082 }
3134 3083
3135 if (inta & IPW2100_INTA_RX_TRANSFER) { 3084 if (inta & IPW2100_INTA_RX_TRANSFER) {
@@ -3137,9 +3086,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3137 3086
3138 priv->rx_interrupts++; 3087 priv->rx_interrupts++;
3139 3088
3140 write_register( 3089 write_register(dev, IPW_REG_INTA, IPW2100_INTA_RX_TRANSFER);
3141 dev, IPW_REG_INTA,
3142 IPW2100_INTA_RX_TRANSFER);
3143 3090
3144 __ipw2100_rx_process(priv); 3091 __ipw2100_rx_process(priv);
3145 __ipw2100_tx_complete(priv); 3092 __ipw2100_tx_complete(priv);
@@ -3150,8 +3097,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3150 3097
3151 priv->tx_interrupts++; 3098 priv->tx_interrupts++;
3152 3099
3153 write_register(dev, IPW_REG_INTA, 3100 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_TRANSFER);
3154 IPW2100_INTA_TX_TRANSFER);
3155 3101
3156 __ipw2100_tx_complete(priv); 3102 __ipw2100_tx_complete(priv);
3157 ipw2100_tx_send_commands(priv); 3103 ipw2100_tx_send_commands(priv);
@@ -3161,9 +3107,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3161 if (inta & IPW2100_INTA_TX_COMPLETE) { 3107 if (inta & IPW2100_INTA_TX_COMPLETE) {
3162 IPW_DEBUG_ISR("TX complete\n"); 3108 IPW_DEBUG_ISR("TX complete\n");
3163 priv->inta_other++; 3109 priv->inta_other++;
3164 write_register( 3110 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_COMPLETE);
3165 dev, IPW_REG_INTA,
3166 IPW2100_INTA_TX_COMPLETE);
3167 3111
3168 __ipw2100_tx_complete(priv); 3112 __ipw2100_tx_complete(priv);
3169 } 3113 }
@@ -3171,9 +3115,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3171 if (inta & IPW2100_INTA_EVENT_INTERRUPT) { 3115 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3172 /* ipw2100_handle_event(dev); */ 3116 /* ipw2100_handle_event(dev); */
3173 priv->inta_other++; 3117 priv->inta_other++;
3174 write_register( 3118 write_register(dev, IPW_REG_INTA, IPW2100_INTA_EVENT_INTERRUPT);
3175 dev, IPW_REG_INTA,
3176 IPW2100_INTA_EVENT_INTERRUPT);
3177 } 3119 }
3178 3120
3179 if (inta & IPW2100_INTA_FW_INIT_DONE) { 3121 if (inta & IPW2100_INTA_FW_INIT_DONE) {
@@ -3183,30 +3125,25 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3183 read_register(dev, IPW_REG_INTA, &tmp); 3125 read_register(dev, IPW_REG_INTA, &tmp);
3184 if (tmp & (IPW2100_INTA_FATAL_ERROR | 3126 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3185 IPW2100_INTA_PARITY_ERROR)) { 3127 IPW2100_INTA_PARITY_ERROR)) {
3186 write_register( 3128 write_register(dev, IPW_REG_INTA,
3187 dev, IPW_REG_INTA, 3129 IPW2100_INTA_FATAL_ERROR |
3188 IPW2100_INTA_FATAL_ERROR | 3130 IPW2100_INTA_PARITY_ERROR);
3189 IPW2100_INTA_PARITY_ERROR);
3190 } 3131 }
3191 3132
3192 write_register(dev, IPW_REG_INTA, 3133 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FW_INIT_DONE);
3193 IPW2100_INTA_FW_INIT_DONE);
3194 } 3134 }
3195 3135
3196 if (inta & IPW2100_INTA_STATUS_CHANGE) { 3136 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3197 IPW_DEBUG_ISR("Status change interrupt\n"); 3137 IPW_DEBUG_ISR("Status change interrupt\n");
3198 priv->inta_other++; 3138 priv->inta_other++;
3199 write_register( 3139 write_register(dev, IPW_REG_INTA, IPW2100_INTA_STATUS_CHANGE);
3200 dev, IPW_REG_INTA,
3201 IPW2100_INTA_STATUS_CHANGE);
3202 } 3140 }
3203 3141
3204 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) { 3142 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3205 IPW_DEBUG_ISR("slave host mode interrupt\n"); 3143 IPW_DEBUG_ISR("slave host mode interrupt\n");
3206 priv->inta_other++; 3144 priv->inta_other++;
3207 write_register( 3145 write_register(dev, IPW_REG_INTA,
3208 dev, IPW_REG_INTA, 3146 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3209 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3210 } 3147 }
3211 3148
3212 priv->in_isr--; 3149 priv->in_isr--;
@@ -3217,9 +3154,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3217 IPW_DEBUG_ISR("exit\n"); 3154 IPW_DEBUG_ISR("exit\n");
3218} 3155}
3219 3156
3220 3157static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
3221static irqreturn_t ipw2100_interrupt(int irq, void *data,
3222 struct pt_regs *regs)
3223{ 3158{
3224 struct ipw2100_priv *priv = data; 3159 struct ipw2100_priv *priv = data;
3225 u32 inta, inta_mask; 3160 u32 inta, inta_mask;
@@ -3227,7 +3162,7 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3227 if (!data) 3162 if (!data)
3228 return IRQ_NONE; 3163 return IRQ_NONE;
3229 3164
3230 spin_lock(&priv->low_lock); 3165 spin_lock(&priv->low_lock);
3231 3166
3232 /* We check to see if we should be ignoring interrupts before 3167 /* We check to see if we should be ignoring interrupts before
3233 * we touch the hardware. During ucode load if we try and handle 3168 * we touch the hardware. During ucode load if we try and handle
@@ -3261,10 +3196,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3261 ipw2100_disable_interrupts(priv); 3196 ipw2100_disable_interrupts(priv);
3262 3197
3263 tasklet_schedule(&priv->irq_tasklet); 3198 tasklet_schedule(&priv->irq_tasklet);
3264 spin_unlock(&priv->low_lock); 3199 spin_unlock(&priv->low_lock);
3265 3200
3266 return IRQ_HANDLED; 3201 return IRQ_HANDLED;
3267 none: 3202 none:
3268 spin_unlock(&priv->low_lock); 3203 spin_unlock(&priv->low_lock);
3269 return IRQ_NONE; 3204 return IRQ_NONE;
3270} 3205}
@@ -3294,10 +3229,8 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3294 3229
3295 packet->info.d_struct.txb = txb; 3230 packet->info.d_struct.txb = txb;
3296 3231
3297 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", 3232 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", txb->fragments[0]->len);
3298 txb->fragments[0]->len); 3233 printk_buf(IPW_DL_TX, txb->fragments[0]->data, txb->fragments[0]->len);
3299 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3300 txb->fragments[0]->len);
3301 3234
3302 packet->jiffy_start = jiffies; 3235 packet->jiffy_start = jiffies;
3303 3236
@@ -3312,22 +3245,23 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3312 spin_unlock_irqrestore(&priv->low_lock, flags); 3245 spin_unlock_irqrestore(&priv->low_lock, flags);
3313 return 0; 3246 return 0;
3314 3247
3315 fail_unlock: 3248 fail_unlock:
3316 netif_stop_queue(dev); 3249 netif_stop_queue(dev);
3317 spin_unlock_irqrestore(&priv->low_lock, flags); 3250 spin_unlock_irqrestore(&priv->low_lock, flags);
3318 return 1; 3251 return 1;
3319} 3252}
3320 3253
3321
3322static int ipw2100_msg_allocate(struct ipw2100_priv *priv) 3254static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3323{ 3255{
3324 int i, j, err = -EINVAL; 3256 int i, j, err = -EINVAL;
3325 void *v; 3257 void *v;
3326 dma_addr_t p; 3258 dma_addr_t p;
3327 3259
3328 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc( 3260 priv->msg_buffers =
3329 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), 3261 (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
3330 GFP_KERNEL); 3262 sizeof(struct
3263 ipw2100_tx_packet),
3264 GFP_KERNEL);
3331 if (!priv->msg_buffers) { 3265 if (!priv->msg_buffers) {
3332 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " 3266 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3333 "buffers.\n", priv->net_dev->name); 3267 "buffers.\n", priv->net_dev->name);
@@ -3335,15 +3269,12 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3335 } 3269 }
3336 3270
3337 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { 3271 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3338 v = pci_alloc_consistent( 3272 v = pci_alloc_consistent(priv->pci_dev,
3339 priv->pci_dev, 3273 sizeof(struct ipw2100_cmd_header), &p);
3340 sizeof(struct ipw2100_cmd_header),
3341 &p);
3342 if (!v) { 3274 if (!v) {
3343 printk(KERN_ERR DRV_NAME ": " 3275 printk(KERN_ERR DRV_NAME ": "
3344 "%s: PCI alloc failed for msg " 3276 "%s: PCI alloc failed for msg "
3345 "buffers.\n", 3277 "buffers.\n", priv->net_dev->name);
3346 priv->net_dev->name);
3347 err = -ENOMEM; 3278 err = -ENOMEM;
3348 break; 3279 break;
3349 } 3280 }
@@ -3352,7 +3283,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3352 3283
3353 priv->msg_buffers[i].type = COMMAND; 3284 priv->msg_buffers[i].type = COMMAND;
3354 priv->msg_buffers[i].info.c_struct.cmd = 3285 priv->msg_buffers[i].info.c_struct.cmd =
3355 (struct ipw2100_cmd_header*)v; 3286 (struct ipw2100_cmd_header *)v;
3356 priv->msg_buffers[i].info.c_struct.cmd_phys = p; 3287 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3357 } 3288 }
3358 3289
@@ -3360,11 +3291,11 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3360 return 0; 3291 return 0;
3361 3292
3362 for (j = 0; j < i; j++) { 3293 for (j = 0; j < i; j++) {
3363 pci_free_consistent( 3294 pci_free_consistent(priv->pci_dev,
3364 priv->pci_dev, 3295 sizeof(struct ipw2100_cmd_header),
3365 sizeof(struct ipw2100_cmd_header), 3296 priv->msg_buffers[j].info.c_struct.cmd,
3366 priv->msg_buffers[j].info.c_struct.cmd, 3297 priv->msg_buffers[j].info.c_struct.
3367 priv->msg_buffers[j].info.c_struct.cmd_phys); 3298 cmd_phys);
3368 } 3299 }
3369 3300
3370 kfree(priv->msg_buffers); 3301 kfree(priv->msg_buffers);
@@ -3398,7 +3329,8 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
3398 pci_free_consistent(priv->pci_dev, 3329 pci_free_consistent(priv->pci_dev,
3399 sizeof(struct ipw2100_cmd_header), 3330 sizeof(struct ipw2100_cmd_header),
3400 priv->msg_buffers[i].info.c_struct.cmd, 3331 priv->msg_buffers[i].info.c_struct.cmd,
3401 priv->msg_buffers[i].info.c_struct.cmd_phys); 3332 priv->msg_buffers[i].info.c_struct.
3333 cmd_phys);
3402 } 3334 }
3403 3335
3404 kfree(priv->msg_buffers); 3336 kfree(priv->msg_buffers);
@@ -3424,6 +3356,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3424 3356
3425 return out - buf; 3357 return out - buf;
3426} 3358}
3359
3427static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); 3360static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3428 3361
3429static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 3362static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
@@ -3432,209 +3365,269 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3432 struct ipw2100_priv *p = d->driver_data; 3365 struct ipw2100_priv *p = d->driver_data;
3433 return sprintf(buf, "0x%08x\n", (int)p->config); 3366 return sprintf(buf, "0x%08x\n", (int)p->config);
3434} 3367}
3368
3435static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 3369static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3436 3370
3437static ssize_t show_status(struct device *d, struct device_attribute *attr, 3371static ssize_t show_status(struct device *d, struct device_attribute *attr,
3438 char *buf) 3372 char *buf)
3439{ 3373{
3440 struct ipw2100_priv *p = d->driver_data; 3374 struct ipw2100_priv *p = d->driver_data;
3441 return sprintf(buf, "0x%08x\n", (int)p->status); 3375 return sprintf(buf, "0x%08x\n", (int)p->status);
3442} 3376}
3377
3443static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 3378static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3444 3379
3445static ssize_t show_capability(struct device *d, struct device_attribute *attr, 3380static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3446 char *buf) 3381 char *buf)
3447{ 3382{
3448 struct ipw2100_priv *p = d->driver_data; 3383 struct ipw2100_priv *p = d->driver_data;
3449 return sprintf(buf, "0x%08x\n", (int)p->capability); 3384 return sprintf(buf, "0x%08x\n", (int)p->capability);
3450} 3385}
3451static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3452 3386
3387static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3453 3388
3454#define IPW2100_REG(x) { IPW_ ##x, #x } 3389#define IPW2100_REG(x) { IPW_ ##x, #x }
3455static const struct { 3390static const struct {
3456 u32 addr; 3391 u32 addr;
3457 const char *name; 3392 const char *name;
3458} hw_data[] = { 3393} hw_data[] = {
3459 IPW2100_REG(REG_GP_CNTRL), 3394IPW2100_REG(REG_GP_CNTRL),
3460 IPW2100_REG(REG_GPIO), 3395 IPW2100_REG(REG_GPIO),
3461 IPW2100_REG(REG_INTA), 3396 IPW2100_REG(REG_INTA),
3462 IPW2100_REG(REG_INTA_MASK), 3397 IPW2100_REG(REG_INTA_MASK), IPW2100_REG(REG_RESET_REG),};
3463 IPW2100_REG(REG_RESET_REG),
3464};
3465#define IPW2100_NIC(x, s) { x, #x, s } 3398#define IPW2100_NIC(x, s) { x, #x, s }
3466static const struct { 3399static const struct {
3467 u32 addr; 3400 u32 addr;
3468 const char *name; 3401 const char *name;
3469 size_t size; 3402 size_t size;
3470} nic_data[] = { 3403} nic_data[] = {
3471 IPW2100_NIC(IPW2100_CONTROL_REG, 2), 3404IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3472 IPW2100_NIC(0x210014, 1), 3405 IPW2100_NIC(0x210014, 1), IPW2100_NIC(0x210000, 1),};
3473 IPW2100_NIC(0x210000, 1),
3474};
3475#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d } 3406#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3476static const struct { 3407static const struct {
3477 u8 index; 3408 u8 index;
3478 const char *name; 3409 const char *name;
3479 const char *desc; 3410 const char *desc;
3480} ord_data[] = { 3411} ord_data[] = {
3481 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"), 3412IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3482 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"), 3413 IPW2100_ORD(STAT_TX_HOST_COMPLETE,
3483 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"), 3414 "successful Host Tx's (MSDU)"),
3484 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"), 3415 IPW2100_ORD(STAT_TX_DIR_DATA,
3485 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"), 3416 "successful Directed Tx's (MSDU)"),
3486 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"), 3417 IPW2100_ORD(STAT_TX_DIR_DATA1,
3487 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"), 3418 "successful Directed Tx's (MSDU) @ 1MB"),
3488 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"), 3419 IPW2100_ORD(STAT_TX_DIR_DATA2,
3489 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"), 3420 "successful Directed Tx's (MSDU) @ 2MB"),
3490 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"), 3421 IPW2100_ORD(STAT_TX_DIR_DATA5_5,
3491 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"), 3422 "successful Directed Tx's (MSDU) @ 5_5MB"),
3492 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"), 3423 IPW2100_ORD(STAT_TX_DIR_DATA11,
3493 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"), 3424 "successful Directed Tx's (MSDU) @ 11MB"),
3494 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"), 3425 IPW2100_ORD(STAT_TX_NODIR_DATA1,
3495 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"), 3426 "successful Non_Directed Tx's (MSDU) @ 1MB"),
3496 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"), 3427 IPW2100_ORD(STAT_TX_NODIR_DATA2,
3497 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"), 3428 "successful Non_Directed Tx's (MSDU) @ 2MB"),
3498 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"), 3429 IPW2100_ORD(STAT_TX_NODIR_DATA5_5,
3499 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"), 3430 "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3500 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"), 3431 IPW2100_ORD(STAT_TX_NODIR_DATA11,
3501 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"), 3432 "successful Non_Directed Tx's (MSDU) @ 11MB"),
3502 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"), 3433 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3503 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"), 3434 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3504 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"), 3435 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3505 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"), 3436 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3506 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"), 3437 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3507 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"), 3438 IPW2100_ORD(STAT_TX_ASSN_RESP,
3508 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"), 3439 "successful Association response Tx's"),
3509 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"), 3440 IPW2100_ORD(STAT_TX_REASSN,
3510 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"), 3441 "successful Reassociation Tx's"),
3511 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"), 3442 IPW2100_ORD(STAT_TX_REASSN_RESP,
3512 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"), 3443 "successful Reassociation response Tx's"),
3513 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"), 3444 IPW2100_ORD(STAT_TX_PROBE,
3514 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"), 3445 "probes successfully transmitted"),
3515 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"), 3446 IPW2100_ORD(STAT_TX_PROBE_RESP,
3516 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"), 3447 "probe responses successfully transmitted"),
3517 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"), 3448 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3518 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"), 3449 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3519 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"), 3450 IPW2100_ORD(STAT_TX_DISASSN,
3520 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"), 3451 "successful Disassociation TX"),
3521 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"), 3452 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3522 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"), 3453 IPW2100_ORD(STAT_TX_DEAUTH,
3523 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"), 3454 "successful Deauthentication TX"),
3524 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"), 3455 IPW2100_ORD(STAT_TX_TOTAL_BYTES,
3525 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"), 3456 "Total successful Tx data bytes"),
3526 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"), 3457 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3527 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"), 3458 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3528 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"), 3459 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3529 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"), 3460 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3530 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), 3461 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3531 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"), 3462 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3532 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"), 3463 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,
3533 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"), 3464 "times max tries in a hop failed"),
3534 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"), 3465 IPW2100_ORD(STAT_TX_DISASSN_FAIL,
3535 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"), 3466 "times disassociation failed"),
3536 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"), 3467 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3537 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"), 3468 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3538 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"), 3469 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3539 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"), 3470 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3540 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"), 3471 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3541 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"), 3472 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3542 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"), 3473 IPW2100_ORD(STAT_RX_DIR_DATA5_5,
3543 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"), 3474 "directed packets at 5.5MB"),
3544 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"), 3475 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3545 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"), 3476 IPW2100_ORD(STAT_RX_NODIR_DATA, "nondirected packets"),
3546 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"), 3477 IPW2100_ORD(STAT_RX_NODIR_DATA1,
3547 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"), 3478 "nondirected packets at 1MB"),
3548 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"), 3479 IPW2100_ORD(STAT_RX_NODIR_DATA2,
3549 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"), 3480 "nondirected packets at 2MB"),
3550 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"), 3481 IPW2100_ORD(STAT_RX_NODIR_DATA5_5,
3551 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"), 3482 "nondirected packets at 5.5MB"),
3552 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"), 3483 IPW2100_ORD(STAT_RX_NODIR_DATA11,
3553 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"), 3484 "nondirected packets at 11MB"),
3554 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"), 3485 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3555 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"), 3486 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), IPW2100_ORD(STAT_RX_CTS,
3556 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"), 3487 "Rx CTS"),
3557 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"), 3488 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3558 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"), 3489 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3559 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"), 3490 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3560 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"), 3491 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3561 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"), 3492 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3562 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"), 3493 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3563 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"), 3494 IPW2100_ORD(STAT_RX_REASSN_RESP,
3564 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"), 3495 "Reassociation response Rx's"),
3565 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"), 3496 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3566 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"), 3497 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3567 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"), 3498 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3568 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"), 3499 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3569 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"), 3500 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3570 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"), 3501 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3571 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"), 3502 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3572 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"), 3503 IPW2100_ORD(STAT_RX_TOTAL_BYTES,
3573 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"), 3504 "Total rx data bytes received"),
3574 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"), 3505 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3575 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"), 3506 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3576 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"), 3507 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3577 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"), 3508 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3578 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"), 3509 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3579 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"), 3510 IPW2100_ORD(STAT_RX_DUPLICATE1,
3580 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"), 3511 "duplicate rx packets at 1MB"),
3581 IPW2100_ORD(STAT_AP_ASSNS, "associations"), 3512 IPW2100_ORD(STAT_RX_DUPLICATE2,
3582 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"), 3513 "duplicate rx packets at 2MB"),
3583 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"), 3514 IPW2100_ORD(STAT_RX_DUPLICATE5_5,
3584 IPW2100_ORD(STAT_FULL_SCANS, "full scans"), 3515 "duplicate rx packets at 5.5MB"),
3585 IPW2100_ORD(CARD_DISABLED, "Card Disabled"), 3516 IPW2100_ORD(STAT_RX_DUPLICATE11,
3586 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"), 3517 "duplicate rx packets at 11MB"),
3587 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"), 3518 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3588 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"), 3519 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3589 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"), 3520 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3590 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"), 3521 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3591 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"), 3522 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL,
3592 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"), 3523 "rx frames with invalid protocol"),
3593 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"), 3524 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3594 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"), 3525 IPW2100_ORD(STAT_RX_NO_BUFFER,
3595 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"), 3526 "rx frames rejected due to no buffer"),
3596 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"), 3527 IPW2100_ORD(STAT_RX_MISSING_FRAG,
3597 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"), 3528 "rx frames dropped due to missing fragment"),
3598 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"), 3529 IPW2100_ORD(STAT_RX_ORPHAN_FRAG,
3599 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"), 3530 "rx frames dropped due to non-sequential fragment"),
3600 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"), 3531 IPW2100_ORD(STAT_RX_ORPHAN_FRAME,
3601 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"), 3532 "rx frames dropped due to unmatched 1st frame"),
3602 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"), 3533 IPW2100_ORD(STAT_RX_FRAG_AGEOUT,
3603 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"), 3534 "rx frames dropped due to uncompleted frame"),
3604 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"), 3535 IPW2100_ORD(STAT_RX_ICV_ERRORS,
3605 IPW2100_ORD(RTC_TIME, "current RTC time"), 3536 "ICV errors during decryption"),
3606 IPW2100_ORD(PORT_TYPE, "operating mode"), 3537 IPW2100_ORD(STAT_PSP_SUSPENSION, "times adapter suspended"),
3607 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"), 3538 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3608 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"), 3539 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT,
3609 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"), 3540 "poll response timeouts"),
3610 IPW2100_ORD(BASIC_RATES, "basic tx rates"), 3541 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT,
3611 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"), 3542 "timeouts waiting for last {broad,multi}cast pkt"),
3612 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"), 3543 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3613 IPW2100_ORD(CAPABILITIES, "Management frame capability field"), 3544 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3614 IPW2100_ORD(AUTH_TYPE, "Type of authentication"), 3545 IPW2100_ORD(STAT_PSP_STATION_ID, "PSP Station ID"),
3615 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"), 3546 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3616 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"), 3547 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,
3617 IPW2100_ORD(INT_MODE, "International mode"), 3548 "current calculation of % missed beacons"),
3618 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"), 3549 IPW2100_ORD(STAT_PERCENT_RETRIES,
3619 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"), 3550 "current calculation of % missed tx retries"),
3620 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"), 3551 IPW2100_ORD(ASSOCIATED_AP_PTR,
3621 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"), 3552 "0 if not associated, else pointer to AP table entry"),
3622 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"), 3553 IPW2100_ORD(AVAILABLE_AP_CNT,
3623 IPW2100_ORD(MAC_VERSION, "MAC Version"), 3554 "AP's decsribed in the AP table"),
3624 IPW2100_ORD(MAC_REVISION, "MAC Revision"), 3555 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3625 IPW2100_ORD(RADIO_VERSION, "Radio Version"), 3556 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3626 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"), 3557 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3627 IPW2100_ORD(UCODE_VERSION, "Ucode Version"), 3558 IPW2100_ORD(STAT_ASSN_RESP_FAIL,
3628}; 3559 "failures due to response fail"),
3629 3560 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3561 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3562 IPW2100_ORD(STAT_ROAM_INHIBIT,
3563 "times roaming was inhibited due to activity"),
3564 IPW2100_ORD(RSSI_AT_ASSN,
3565 "RSSI of associated AP at time of association"),
3566 IPW2100_ORD(STAT_ASSN_CAUSE1,
3567 "reassociation: no probe response or TX on hop"),
3568 IPW2100_ORD(STAT_ASSN_CAUSE2,
3569 "reassociation: poor tx/rx quality"),
3570 IPW2100_ORD(STAT_ASSN_CAUSE3,
3571 "reassociation: tx/rx quality (excessive AP load"),
3572 IPW2100_ORD(STAT_ASSN_CAUSE4,
3573 "reassociation: AP RSSI level"),
3574 IPW2100_ORD(STAT_ASSN_CAUSE5,
3575 "reassociations due to load leveling"),
3576 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3577 IPW2100_ORD(STAT_AUTH_RESP_FAIL,
3578 "times authentication response failed"),
3579 IPW2100_ORD(STATION_TABLE_CNT,
3580 "entries in association table"),
3581 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3582 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3583 IPW2100_ORD(COUNTRY_CODE,
3584 "IEEE country code as recv'd from beacon"),
3585 IPW2100_ORD(COUNTRY_CHANNELS,
3586 "channels suported by country"),
3587 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3588 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3589 IPW2100_ORD(ANTENNA_DIVERSITY,
3590 "TRUE if antenna diversity is disabled"),
3591 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3592 IPW2100_ORD(OUR_FREQ,
3593 "current radio freq lower digits - channel ID"),
3594 IPW2100_ORD(RTC_TIME, "current RTC time"),
3595 IPW2100_ORD(PORT_TYPE, "operating mode"),
3596 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3597 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3598 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3599 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3600 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3601 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3602 IPW2100_ORD(CAPABILITIES,
3603 "Management frame capability field"),
3604 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3605 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3606 IPW2100_ORD(RTS_THRESHOLD,
3607 "Min packet length for RTS handshaking"),
3608 IPW2100_ORD(INT_MODE, "International mode"),
3609 IPW2100_ORD(FRAGMENTATION_THRESHOLD,
3610 "protocol frag threshold"),
3611 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
3612 "EEPROM offset in SRAM"),
3613 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE,
3614 "EEPROM size in SRAM"),
3615 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3616 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS,
3617 "EEPROM IBSS 11b channel set"),
3618 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3619 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3620 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3621 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3622 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),};
3630 3623
3631static ssize_t show_registers(struct device *d, struct device_attribute *attr, 3624static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3632 char *buf) 3625 char *buf)
3633{ 3626{
3634 int i; 3627 int i;
3635 struct ipw2100_priv *priv = dev_get_drvdata(d); 3628 struct ipw2100_priv *priv = dev_get_drvdata(d);
3636 struct net_device *dev = priv->net_dev; 3629 struct net_device *dev = priv->net_dev;
3637 char * out = buf; 3630 char *out = buf;
3638 u32 val = 0; 3631 u32 val = 0;
3639 3632
3640 out += sprintf(out, "%30s [Address ] : Hex\n", "Register"); 3633 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
@@ -3647,15 +3640,15 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3647 3640
3648 return out - buf; 3641 return out - buf;
3649} 3642}
3650static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3651 3643
3644static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3652 3645
3653static ssize_t show_hardware(struct device *d, struct device_attribute *attr, 3646static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3654 char *buf) 3647 char *buf)
3655{ 3648{
3656 struct ipw2100_priv *priv = dev_get_drvdata(d); 3649 struct ipw2100_priv *priv = dev_get_drvdata(d);
3657 struct net_device *dev = priv->net_dev; 3650 struct net_device *dev = priv->net_dev;
3658 char * out = buf; 3651 char *out = buf;
3659 int i; 3652 int i;
3660 3653
3661 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry"); 3654 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
@@ -3688,11 +3681,11 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3688 } 3681 }
3689 return out - buf; 3682 return out - buf;
3690} 3683}
3691static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3692 3684
3685static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3693 3686
3694static ssize_t show_memory(struct device *d, struct device_attribute *attr, 3687static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3695 char *buf) 3688 char *buf)
3696{ 3689{
3697 struct ipw2100_priv *priv = dev_get_drvdata(d); 3690 struct ipw2100_priv *priv = dev_get_drvdata(d);
3698 struct net_device *dev = priv->net_dev; 3691 struct net_device *dev = priv->net_dev;
@@ -3708,10 +3701,13 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3708 /* sysfs provides us PAGE_SIZE buffer */ 3701 /* sysfs provides us PAGE_SIZE buffer */
3709 while (len < PAGE_SIZE - 128 && loop < 0x30000) { 3702 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3710 3703
3711 if (priv->snapshot[0]) for (i = 0; i < 4; i++) 3704 if (priv->snapshot[0])
3712 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4); 3705 for (i = 0; i < 4; i++)
3713 else for (i = 0; i < 4; i++) 3706 buffer[i] =
3714 read_nic_dword(dev, loop + i * 4, &buffer[i]); 3707 *(u32 *) SNAPSHOT_ADDR(loop + i * 4);
3708 else
3709 for (i = 0; i < 4; i++)
3710 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3715 3711
3716 if (priv->dump_raw) 3712 if (priv->dump_raw)
3717 len += sprintf(buf + len, 3713 len += sprintf(buf + len,
@@ -3719,26 +3715,26 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3719 "%c%c%c%c" 3715 "%c%c%c%c"
3720 "%c%c%c%c" 3716 "%c%c%c%c"
3721 "%c%c%c%c", 3717 "%c%c%c%c",
3722 ((u8*)buffer)[0x0], 3718 ((u8 *) buffer)[0x0],
3723 ((u8*)buffer)[0x1], 3719 ((u8 *) buffer)[0x1],
3724 ((u8*)buffer)[0x2], 3720 ((u8 *) buffer)[0x2],
3725 ((u8*)buffer)[0x3], 3721 ((u8 *) buffer)[0x3],
3726 ((u8*)buffer)[0x4], 3722 ((u8 *) buffer)[0x4],
3727 ((u8*)buffer)[0x5], 3723 ((u8 *) buffer)[0x5],
3728 ((u8*)buffer)[0x6], 3724 ((u8 *) buffer)[0x6],
3729 ((u8*)buffer)[0x7], 3725 ((u8 *) buffer)[0x7],
3730 ((u8*)buffer)[0x8], 3726 ((u8 *) buffer)[0x8],
3731 ((u8*)buffer)[0x9], 3727 ((u8 *) buffer)[0x9],
3732 ((u8*)buffer)[0xa], 3728 ((u8 *) buffer)[0xa],
3733 ((u8*)buffer)[0xb], 3729 ((u8 *) buffer)[0xb],
3734 ((u8*)buffer)[0xc], 3730 ((u8 *) buffer)[0xc],
3735 ((u8*)buffer)[0xd], 3731 ((u8 *) buffer)[0xd],
3736 ((u8*)buffer)[0xe], 3732 ((u8 *) buffer)[0xe],
3737 ((u8*)buffer)[0xf]); 3733 ((u8 *) buffer)[0xf]);
3738 else 3734 else
3739 len += sprintf(buf + len, "%s\n", 3735 len += sprintf(buf + len, "%s\n",
3740 snprint_line(line, sizeof(line), 3736 snprint_line(line, sizeof(line),
3741 (u8*)buffer, 16, loop)); 3737 (u8 *) buffer, 16, loop));
3742 loop += 16; 3738 loop += 16;
3743 } 3739 }
3744 3740
@@ -3746,44 +3742,44 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3746} 3742}
3747 3743
3748static ssize_t store_memory(struct device *d, struct device_attribute *attr, 3744static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3749 const char *buf, size_t count) 3745 const char *buf, size_t count)
3750{ 3746{
3751 struct ipw2100_priv *priv = dev_get_drvdata(d); 3747 struct ipw2100_priv *priv = dev_get_drvdata(d);
3752 struct net_device *dev = priv->net_dev; 3748 struct net_device *dev = priv->net_dev;
3753 const char *p = buf; 3749 const char *p = buf;
3754 3750
3751 (void) dev; /* kill unused-var warning for debug-only code */
3752
3755 if (count < 1) 3753 if (count < 1)
3756 return count; 3754 return count;
3757 3755
3758 if (p[0] == '1' || 3756 if (p[0] == '1' ||
3759 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) { 3757 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3760 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n", 3758 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3761 dev->name); 3759 dev->name);
3762 priv->dump_raw = 1; 3760 priv->dump_raw = 1;
3763 3761
3764 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' && 3762 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3765 tolower(p[1]) == 'f')) { 3763 tolower(p[1]) == 'f')) {
3766 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n", 3764 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3767 dev->name); 3765 dev->name);
3768 priv->dump_raw = 0; 3766 priv->dump_raw = 0;
3769 3767
3770 } else if (tolower(p[0]) == 'r') { 3768 } else if (tolower(p[0]) == 'r') {
3771 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", 3769 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", dev->name);
3772 dev->name);
3773 ipw2100_snapshot_free(priv); 3770 ipw2100_snapshot_free(priv);
3774 3771
3775 } else 3772 } else
3776 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, " 3773 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3777 "reset = clear memory snapshot\n", 3774 "reset = clear memory snapshot\n", dev->name);
3778 dev->name);
3779 3775
3780 return count; 3776 return count;
3781} 3777}
3782static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3783 3778
3779static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory);
3784 3780
3785static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, 3781static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3786 char *buf) 3782 char *buf)
3787{ 3783{
3788 struct ipw2100_priv *priv = dev_get_drvdata(d); 3784 struct ipw2100_priv *priv = dev_get_drvdata(d);
3789 u32 val = 0; 3785 u32 val = 0;
@@ -3791,6 +3787,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3791 u32 val_len; 3787 u32 val_len;
3792 static int loop = 0; 3788 static int loop = 0;
3793 3789
3790 if (priv->status & STATUS_RF_KILL_MASK)
3791 return 0;
3792
3794 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3793 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3795 loop = 0; 3794 loop = 0;
3796 3795
@@ -3814,14 +3813,14 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3814 3813
3815 return len; 3814 return len;
3816} 3815}
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3818 3816
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3819 3818
3820static ssize_t show_stats(struct device *d, struct device_attribute *attr, 3819static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3821 char *buf) 3820 char *buf)
3822{ 3821{
3823 struct ipw2100_priv *priv = dev_get_drvdata(d); 3822 struct ipw2100_priv *priv = dev_get_drvdata(d);
3824 char * out = buf; 3823 char *out = buf;
3825 3824
3826 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n", 3825 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3827 priv->interrupts, priv->tx_interrupts, 3826 priv->interrupts, priv->tx_interrupts,
@@ -3835,8 +3834,8 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3835 3834
3836 return out - buf; 3835 return out - buf;
3837} 3836}
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3839 3837
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3840 3839
3841static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) 3840static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3842{ 3841{
@@ -3864,19 +3863,18 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3864 priv->last_mode = priv->ieee->iw_mode; 3863 priv->last_mode = priv->ieee->iw_mode;
3865 priv->net_dev->type = ARPHRD_IEEE80211; 3864 priv->net_dev->type = ARPHRD_IEEE80211;
3866 break; 3865 break;
3867#endif /* CONFIG_IPW2100_MONITOR */ 3866#endif /* CONFIG_IPW2100_MONITOR */
3868 } 3867 }
3869 3868
3870 priv->ieee->iw_mode = mode; 3869 priv->ieee->iw_mode = mode;
3871 3870
3872#ifdef CONFIG_PM 3871#ifdef CONFIG_PM
3873 /* Indicate ipw2100_download_firmware download firmware 3872 /* Indicate ipw2100_download_firmware download firmware
3874 * from disk instead of memory. */ 3873 * from disk instead of memory. */
3875 ipw2100_firmware.version = 0; 3874 ipw2100_firmware.version = 0;
3876#endif 3875#endif
3877 3876
3878 printk(KERN_INFO "%s: Reseting on mode change.\n", 3877 printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
3879 priv->net_dev->name);
3880 priv->reset_backoff = 0; 3878 priv->reset_backoff = 0;
3881 schedule_reset(priv); 3879 schedule_reset(priv);
3882 3880
@@ -3884,12 +3882,12 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3884} 3882}
3885 3883
3886static ssize_t show_internals(struct device *d, struct device_attribute *attr, 3884static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3887 char *buf) 3885 char *buf)
3888{ 3886{
3889 struct ipw2100_priv *priv = dev_get_drvdata(d); 3887 struct ipw2100_priv *priv = dev_get_drvdata(d);
3890 int len = 0; 3888 int len = 0;
3891 3889
3892#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x) 3890#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" y "\n", priv-> x)
3893 3891
3894 if (priv->status & STATUS_ASSOCIATED) 3892 if (priv->status & STATUS_ASSOCIATED)
3895 len += sprintf(buf + len, "connected: %lu\n", 3893 len += sprintf(buf + len, "connected: %lu\n",
@@ -3897,55 +3895,60 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3897 else 3895 else
3898 len += sprintf(buf + len, "not connected\n"); 3896 len += sprintf(buf + len, "not connected\n");
3899 3897
3900 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p); 3898 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
3901 DUMP_VAR(status, 08lx); 3899 DUMP_VAR(status, "08lx");
3902 DUMP_VAR(config, 08lx); 3900 DUMP_VAR(config, "08lx");
3903 DUMP_VAR(capability, 08lx); 3901 DUMP_VAR(capability, "08lx");
3904 3902
3905 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc); 3903 len +=
3904 sprintf(buf + len, "last_rtc: %lu\n",
3905 (unsigned long)priv->last_rtc);
3906 3906
3907 DUMP_VAR(fatal_error, d); 3907 DUMP_VAR(fatal_error, "d");
3908 DUMP_VAR(stop_hang_check, d); 3908 DUMP_VAR(stop_hang_check, "d");
3909 DUMP_VAR(stop_rf_kill, d); 3909 DUMP_VAR(stop_rf_kill, "d");
3910 DUMP_VAR(messages_sent, d); 3910 DUMP_VAR(messages_sent, "d");
3911 3911
3912 DUMP_VAR(tx_pend_stat.value, d); 3912 DUMP_VAR(tx_pend_stat.value, "d");
3913 DUMP_VAR(tx_pend_stat.hi, d); 3913 DUMP_VAR(tx_pend_stat.hi, "d");
3914 3914
3915 DUMP_VAR(tx_free_stat.value, d); 3915 DUMP_VAR(tx_free_stat.value, "d");
3916 DUMP_VAR(tx_free_stat.lo, d); 3916 DUMP_VAR(tx_free_stat.lo, "d");
3917 3917
3918 DUMP_VAR(msg_free_stat.value, d); 3918 DUMP_VAR(msg_free_stat.value, "d");
3919 DUMP_VAR(msg_free_stat.lo, d); 3919 DUMP_VAR(msg_free_stat.lo, "d");
3920 3920
3921 DUMP_VAR(msg_pend_stat.value, d); 3921 DUMP_VAR(msg_pend_stat.value, "d");
3922 DUMP_VAR(msg_pend_stat.hi, d); 3922 DUMP_VAR(msg_pend_stat.hi, "d");
3923 3923
3924 DUMP_VAR(fw_pend_stat.value, d); 3924 DUMP_VAR(fw_pend_stat.value, "d");
3925 DUMP_VAR(fw_pend_stat.hi, d); 3925 DUMP_VAR(fw_pend_stat.hi, "d");
3926 3926
3927 DUMP_VAR(txq_stat.value, d); 3927 DUMP_VAR(txq_stat.value, "d");
3928 DUMP_VAR(txq_stat.lo, d); 3928 DUMP_VAR(txq_stat.lo, "d");
3929 3929
3930 DUMP_VAR(ieee->scans, d); 3930 DUMP_VAR(ieee->scans, "d");
3931 DUMP_VAR(reset_backoff, d); 3931 DUMP_VAR(reset_backoff, "d");
3932 3932
3933 return len; 3933 return len;
3934} 3934}
3935static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3936 3935
3936static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3937 3937
3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, 3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3939 char *buf) 3939 char *buf)
3940{ 3940{
3941 struct ipw2100_priv *priv = dev_get_drvdata(d); 3941 struct ipw2100_priv *priv = dev_get_drvdata(d);
3942 char essid[IW_ESSID_MAX_SIZE + 1]; 3942 char essid[IW_ESSID_MAX_SIZE + 1];
3943 u8 bssid[ETH_ALEN]; 3943 u8 bssid[ETH_ALEN];
3944 u32 chan = 0; 3944 u32 chan = 0;
3945 char * out = buf; 3945 char *out = buf;
3946 int length; 3946 int length;
3947 int ret; 3947 int ret;
3948 3948
3949 if (priv->status & STATUS_RF_KILL_MASK)
3950 return 0;
3951
3949 memset(essid, 0, sizeof(essid)); 3952 memset(essid, 0, sizeof(essid));
3950 memset(bssid, 0, sizeof(bssid)); 3953 memset(bssid, 0, sizeof(bssid));
3951 3954
@@ -3976,8 +3979,8 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3976 3979
3977 return out - buf; 3980 return out - buf;
3978} 3981}
3979static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3980 3982
3983static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3981 3984
3982#ifdef CONFIG_IPW_DEBUG 3985#ifdef CONFIG_IPW_DEBUG
3983static ssize_t show_debug_level(struct device_driver *d, char *buf) 3986static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -3985,8 +3988,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
3985 return sprintf(buf, "0x%08X\n", ipw2100_debug_level); 3988 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3986} 3989}
3987 3990
3988static ssize_t store_debug_level(struct device_driver *d, const char *buf, 3991static ssize_t store_debug_level(struct device_driver *d,
3989 size_t count) 3992 const char *buf, size_t count)
3990{ 3993{
3991 char *p = (char *)buf; 3994 char *p = (char *)buf;
3992 u32 val; 3995 u32 val;
@@ -3999,28 +4002,26 @@ static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3999 } else 4002 } else
4000 val = simple_strtoul(p, &p, 10); 4003 val = simple_strtoul(p, &p, 10);
4001 if (p == buf) 4004 if (p == buf)
4002 IPW_DEBUG_INFO(DRV_NAME 4005 IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
4003 ": %s is not in hex or decimal form.\n", buf);
4004 else 4006 else
4005 ipw2100_debug_level = val; 4007 ipw2100_debug_level = val;
4006 4008
4007 return strnlen(buf, count); 4009 return strnlen(buf, count);
4008} 4010}
4011
4009static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, 4012static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4010 store_debug_level); 4013 store_debug_level);
4011#endif /* CONFIG_IPW_DEBUG */ 4014#endif /* CONFIG_IPW_DEBUG */
4012
4013 4015
4014static ssize_t show_fatal_error(struct device *d, 4016static ssize_t show_fatal_error(struct device *d,
4015 struct device_attribute *attr, char *buf) 4017 struct device_attribute *attr, char *buf)
4016{ 4018{
4017 struct ipw2100_priv *priv = dev_get_drvdata(d); 4019 struct ipw2100_priv *priv = dev_get_drvdata(d);
4018 char *out = buf; 4020 char *out = buf;
4019 int i; 4021 int i;
4020 4022
4021 if (priv->fatal_error) 4023 if (priv->fatal_error)
4022 out += sprintf(out, "0x%08X\n", 4024 out += sprintf(out, "0x%08X\n", priv->fatal_error);
4023 priv->fatal_error);
4024 else 4025 else
4025 out += sprintf(out, "0\n"); 4026 out += sprintf(out, "0\n");
4026 4027
@@ -4038,24 +4039,26 @@ static ssize_t show_fatal_error(struct device *d,
4038} 4039}
4039 4040
4040static ssize_t store_fatal_error(struct device *d, 4041static ssize_t store_fatal_error(struct device *d,
4041 struct device_attribute *attr, const char *buf, size_t count) 4042 struct device_attribute *attr, const char *buf,
4043 size_t count)
4042{ 4044{
4043 struct ipw2100_priv *priv = dev_get_drvdata(d); 4045 struct ipw2100_priv *priv = dev_get_drvdata(d);
4044 schedule_reset(priv); 4046 schedule_reset(priv);
4045 return count; 4047 return count;
4046} 4048}
4047static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4048 4049
4050static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error,
4051 store_fatal_error);
4049 4052
4050static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 4053static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4051 char *buf) 4054 char *buf)
4052{ 4055{
4053 struct ipw2100_priv *priv = dev_get_drvdata(d); 4056 struct ipw2100_priv *priv = dev_get_drvdata(d);
4054 return sprintf(buf, "%d\n", priv->ieee->scan_age); 4057 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4055} 4058}
4056 4059
4057static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, 4060static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4058 const char *buf, size_t count) 4061 const char *buf, size_t count)
4059{ 4062{
4060 struct ipw2100_priv *priv = dev_get_drvdata(d); 4063 struct ipw2100_priv *priv = dev_get_drvdata(d);
4061 struct net_device *dev = priv->net_dev; 4064 struct net_device *dev = priv->net_dev;
@@ -4065,6 +4068,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4065 unsigned long val; 4068 unsigned long val;
4066 char *p = buffer; 4069 char *p = buffer;
4067 4070
4071 (void) dev; /* kill unused-var warning for debug-only code */
4072
4068 IPW_DEBUG_INFO("enter\n"); 4073 IPW_DEBUG_INFO("enter\n");
4069 4074
4070 strncpy(buffer, buf, len); 4075 strncpy(buffer, buf, len);
@@ -4078,8 +4083,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4078 } else 4083 } else
4079 val = simple_strtoul(p, &p, 10); 4084 val = simple_strtoul(p, &p, 10);
4080 if (p == buffer) { 4085 if (p == buffer) {
4081 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", 4086 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
4082 dev->name);
4083 } else { 4087 } else {
4084 priv->ieee->scan_age = val; 4088 priv->ieee->scan_age = val;
4085 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age); 4089 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
@@ -4088,11 +4092,11 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4088 IPW_DEBUG_INFO("exit\n"); 4092 IPW_DEBUG_INFO("exit\n");
4089 return len; 4093 return len;
4090} 4094}
4091static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4092 4095
4096static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4093 4097
4094static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, 4098static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4095 char *buf) 4099 char *buf)
4096{ 4100{
4097 /* 0 - RF kill not enabled 4101 /* 0 - RF kill not enabled
4098 1 - SW based RF kill active (sysfs) 4102 1 - SW based RF kill active (sysfs)
@@ -4100,7 +4104,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4100 3 - Both HW and SW baed RF kill active */ 4104 3 - Both HW and SW baed RF kill active */
4101 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data; 4105 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4102 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | 4106 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4103 (rf_kill_active(priv) ? 0x2 : 0x0); 4107 (rf_kill_active(priv) ? 0x2 : 0x0);
4104 return sprintf(buf, "%i\n", val); 4108 return sprintf(buf, "%i\n", val);
4105} 4109}
4106 4110
@@ -4108,7 +4112,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4108{ 4112{
4109 if ((disable_radio ? 1 : 0) == 4113 if ((disable_radio ? 1 : 0) ==
4110 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 4114 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4111 return 0 ; 4115 return 0;
4112 4116
4113 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 4117 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4114 disable_radio ? "OFF" : "ON"); 4118 disable_radio ? "OFF" : "ON");
@@ -4126,8 +4130,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4126 /* Make sure the RF_KILL check timer is running */ 4130 /* Make sure the RF_KILL check timer is running */
4127 priv->stop_rf_kill = 0; 4131 priv->stop_rf_kill = 0;
4128 cancel_delayed_work(&priv->rf_kill); 4132 cancel_delayed_work(&priv->rf_kill);
4129 queue_delayed_work(priv->workqueue, &priv->rf_kill, 4133 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
4130 HZ);
4131 } else 4134 } else
4132 schedule_reset(priv); 4135 schedule_reset(priv);
4133 } 4136 }
@@ -4137,14 +4140,14 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4137} 4140}
4138 4141
4139static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, 4142static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4140 const char *buf, size_t count) 4143 const char *buf, size_t count)
4141{ 4144{
4142 struct ipw2100_priv *priv = dev_get_drvdata(d); 4145 struct ipw2100_priv *priv = dev_get_drvdata(d);
4143 ipw_radio_kill_sw(priv, buf[0] == '1'); 4146 ipw_radio_kill_sw(priv, buf[0] == '1');
4144 return count; 4147 return count;
4145} 4148}
4146static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4147 4149
4150static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
4148 4151
4149static struct attribute *ipw2100_sysfs_entries[] = { 4152static struct attribute *ipw2100_sysfs_entries[] = {
4150 &dev_attr_hardware.attr, 4153 &dev_attr_hardware.attr,
@@ -4168,7 +4171,6 @@ static struct attribute_group ipw2100_attribute_group = {
4168 .attrs = ipw2100_sysfs_entries, 4171 .attrs = ipw2100_sysfs_entries,
4169}; 4172};
4170 4173
4171
4172static int status_queue_allocate(struct ipw2100_priv *priv, int entries) 4174static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4173{ 4175{
4174 struct ipw2100_status_queue *q = &priv->status_queue; 4176 struct ipw2100_status_queue *q = &priv->status_queue;
@@ -4176,11 +4178,11 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4176 IPW_DEBUG_INFO("enter\n"); 4178 IPW_DEBUG_INFO("enter\n");
4177 4179
4178 q->size = entries * sizeof(struct ipw2100_status); 4180 q->size = entries * sizeof(struct ipw2100_status);
4179 q->drv = (struct ipw2100_status *)pci_alloc_consistent( 4181 q->drv =
4180 priv->pci_dev, q->size, &q->nic); 4182 (struct ipw2100_status *)pci_alloc_consistent(priv->pci_dev,
4183 q->size, &q->nic);
4181 if (!q->drv) { 4184 if (!q->drv) {
4182 IPW_DEBUG_WARNING( 4185 IPW_DEBUG_WARNING("Can not allocate status queue.\n");
4183 "Can not allocate status queue.\n");
4184 return -ENOMEM; 4186 return -ENOMEM;
4185 } 4187 }
4186 4188
@@ -4196,9 +4198,9 @@ static void status_queue_free(struct ipw2100_priv *priv)
4196 IPW_DEBUG_INFO("enter\n"); 4198 IPW_DEBUG_INFO("enter\n");
4197 4199
4198 if (priv->status_queue.drv) { 4200 if (priv->status_queue.drv) {
4199 pci_free_consistent( 4201 pci_free_consistent(priv->pci_dev, priv->status_queue.size,
4200 priv->pci_dev, priv->status_queue.size, 4202 priv->status_queue.drv,
4201 priv->status_queue.drv, priv->status_queue.nic); 4203 priv->status_queue.nic);
4202 priv->status_queue.drv = NULL; 4204 priv->status_queue.drv = NULL;
4203 } 4205 }
4204 4206
@@ -4216,7 +4218,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4216 q->size = entries * sizeof(struct ipw2100_bd); 4218 q->size = entries * sizeof(struct ipw2100_bd);
4217 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic); 4219 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4218 if (!q->drv) { 4220 if (!q->drv) {
4219 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n"); 4221 IPW_DEBUG_INFO
4222 ("can't allocate shared memory for buffer descriptors\n");
4220 return -ENOMEM; 4223 return -ENOMEM;
4221 } 4224 }
4222 memset(q->drv, 0, q->size); 4225 memset(q->drv, 0, q->size);
@@ -4226,8 +4229,7 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4226 return 0; 4229 return 0;
4227} 4230}
4228 4231
4229static void bd_queue_free(struct ipw2100_priv *priv, 4232static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
4230 struct ipw2100_bd_queue *q)
4231{ 4233{
4232 IPW_DEBUG_INFO("enter\n"); 4234 IPW_DEBUG_INFO("enter\n");
4233 4235
@@ -4235,21 +4237,21 @@ static void bd_queue_free(struct ipw2100_priv *priv,
4235 return; 4237 return;
4236 4238
4237 if (q->drv) { 4239 if (q->drv) {
4238 pci_free_consistent(priv->pci_dev, 4240 pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
4239 q->size, q->drv, q->nic);
4240 q->drv = NULL; 4241 q->drv = NULL;
4241 } 4242 }
4242 4243
4243 IPW_DEBUG_INFO("exit\n"); 4244 IPW_DEBUG_INFO("exit\n");
4244} 4245}
4245 4246
4246static void bd_queue_initialize( 4247static void bd_queue_initialize(struct ipw2100_priv *priv,
4247 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q, 4248 struct ipw2100_bd_queue *q, u32 base, u32 size,
4248 u32 base, u32 size, u32 r, u32 w) 4249 u32 r, u32 w)
4249{ 4250{
4250 IPW_DEBUG_INFO("enter\n"); 4251 IPW_DEBUG_INFO("enter\n");
4251 4252
4252 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic); 4253 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv,
4254 (u32) q->nic);
4253 4255
4254 write_register(priv->net_dev, base, q->nic); 4256 write_register(priv->net_dev, base, q->nic);
4255 write_register(priv->net_dev, size, q->entries); 4257 write_register(priv->net_dev, size, q->entries);
@@ -4285,32 +4287,38 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4285 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH); 4287 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4286 if (err) { 4288 if (err) {
4287 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n", 4289 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4288 priv->net_dev->name); 4290 priv->net_dev->name);
4289 return err; 4291 return err;
4290 } 4292 }
4291 4293
4292 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc( 4294 priv->tx_buffers =
4293 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet), 4295 (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
4294 GFP_ATOMIC); 4296 sizeof(struct
4297 ipw2100_tx_packet),
4298 GFP_ATOMIC);
4295 if (!priv->tx_buffers) { 4299 if (!priv->tx_buffers) {
4296 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n", 4300 printk(KERN_ERR DRV_NAME
4301 ": %s: alloc failed form tx buffers.\n",
4297 priv->net_dev->name); 4302 priv->net_dev->name);
4298 bd_queue_free(priv, &priv->tx_queue); 4303 bd_queue_free(priv, &priv->tx_queue);
4299 return -ENOMEM; 4304 return -ENOMEM;
4300 } 4305 }
4301 4306
4302 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4307 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4303 v = pci_alloc_consistent( 4308 v = pci_alloc_consistent(priv->pci_dev,
4304 priv->pci_dev, sizeof(struct ipw2100_data_header), &p); 4309 sizeof(struct ipw2100_data_header),
4310 &p);
4305 if (!v) { 4311 if (!v) {
4306 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx " 4312 printk(KERN_ERR DRV_NAME
4307 "buffers.\n", priv->net_dev->name); 4313 ": %s: PCI alloc failed for tx " "buffers.\n",
4314 priv->net_dev->name);
4308 err = -ENOMEM; 4315 err = -ENOMEM;
4309 break; 4316 break;
4310 } 4317 }
4311 4318
4312 priv->tx_buffers[i].type = DATA; 4319 priv->tx_buffers[i].type = DATA;
4313 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v; 4320 priv->tx_buffers[i].info.d_struct.data =
4321 (struct ipw2100_data_header *)v;
4314 priv->tx_buffers[i].info.d_struct.data_phys = p; 4322 priv->tx_buffers[i].info.d_struct.data_phys = p;
4315 priv->tx_buffers[i].info.d_struct.txb = NULL; 4323 priv->tx_buffers[i].info.d_struct.txb = NULL;
4316 } 4324 }
@@ -4319,11 +4327,11 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4319 return 0; 4327 return 0;
4320 4328
4321 for (j = 0; j < i; j++) { 4329 for (j = 0; j < i; j++) {
4322 pci_free_consistent( 4330 pci_free_consistent(priv->pci_dev,
4323 priv->pci_dev, 4331 sizeof(struct ipw2100_data_header),
4324 sizeof(struct ipw2100_data_header), 4332 priv->tx_buffers[j].info.d_struct.data,
4325 priv->tx_buffers[j].info.d_struct.data, 4333 priv->tx_buffers[j].info.d_struct.
4326 priv->tx_buffers[j].info.d_struct.data_phys); 4334 data_phys);
4327 } 4335 }
4328 4336
4329 kfree(priv->tx_buffers); 4337 kfree(priv->tx_buffers);
@@ -4356,7 +4364,8 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4356 /* We simply drop any SKBs that have been queued for 4364 /* We simply drop any SKBs that have been queued for
4357 * transmit */ 4365 * transmit */
4358 if (priv->tx_buffers[i].info.d_struct.txb) { 4366 if (priv->tx_buffers[i].info.d_struct.txb) {
4359 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4367 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4368 txb);
4360 priv->tx_buffers[i].info.d_struct.txb = NULL; 4369 priv->tx_buffers[i].info.d_struct.txb = NULL;
4361 } 4370 }
4362 4371
@@ -4394,15 +4403,17 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4394 4403
4395 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4404 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4396 if (priv->tx_buffers[i].info.d_struct.txb) { 4405 if (priv->tx_buffers[i].info.d_struct.txb) {
4397 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4406 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4407 txb);
4398 priv->tx_buffers[i].info.d_struct.txb = NULL; 4408 priv->tx_buffers[i].info.d_struct.txb = NULL;
4399 } 4409 }
4400 if (priv->tx_buffers[i].info.d_struct.data) 4410 if (priv->tx_buffers[i].info.d_struct.data)
4401 pci_free_consistent( 4411 pci_free_consistent(priv->pci_dev,
4402 priv->pci_dev, 4412 sizeof(struct ipw2100_data_header),
4403 sizeof(struct ipw2100_data_header), 4413 priv->tx_buffers[i].info.d_struct.
4404 priv->tx_buffers[i].info.d_struct.data, 4414 data,
4405 priv->tx_buffers[i].info.d_struct.data_phys); 4415 priv->tx_buffers[i].info.d_struct.
4416 data_phys);
4406 } 4417 }
4407 4418
4408 kfree(priv->tx_buffers); 4419 kfree(priv->tx_buffers);
@@ -4411,8 +4422,6 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4411 IPW_DEBUG_INFO("exit\n"); 4422 IPW_DEBUG_INFO("exit\n");
4412} 4423}
4413 4424
4414
4415
4416static int ipw2100_rx_allocate(struct ipw2100_priv *priv) 4425static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4417{ 4426{
4418 int i, j, err = -EINVAL; 4427 int i, j, err = -EINVAL;
@@ -4542,14 +4551,13 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4542 4551
4543 int err; 4552 int err;
4544 4553
4545 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, 4554 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length);
4546 mac, &length);
4547 if (err) { 4555 if (err) {
4548 IPW_DEBUG_INFO("MAC address read failed\n"); 4556 IPW_DEBUG_INFO("MAC address read failed\n");
4549 return -EIO; 4557 return -EIO;
4550 } 4558 }
4551 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n", 4559 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4552 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4560 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4553 4561
4554 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN); 4562 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4555 4563
@@ -4576,8 +4584,7 @@ static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4576 IPW_DEBUG_INFO("enter\n"); 4584 IPW_DEBUG_INFO("enter\n");
4577 4585
4578 if (priv->config & CFG_CUSTOM_MAC) { 4586 if (priv->config & CFG_CUSTOM_MAC) {
4579 memcpy(cmd.host_command_parameters, priv->mac_addr, 4587 memcpy(cmd.host_command_parameters, priv->mac_addr, ETH_ALEN);
4580 ETH_ALEN);
4581 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 4588 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4582 } else 4589 } else
4583 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr, 4590 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
@@ -4614,7 +4621,8 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4614 if (!batch_mode) { 4621 if (!batch_mode) {
4615 err = ipw2100_disable_adapter(priv); 4622 err = ipw2100_disable_adapter(priv);
4616 if (err) { 4623 if (err) {
4617 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 4624 printk(KERN_ERR DRV_NAME
4625 ": %s: Could not disable adapter %d\n",
4618 priv->net_dev->name, err); 4626 priv->net_dev->name, err);
4619 return err; 4627 return err;
4620 } 4628 }
@@ -4629,7 +4637,6 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4629 return err; 4637 return err;
4630} 4638}
4631 4639
4632
4633static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel, 4640static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4634 int batch_mode) 4641 int batch_mode)
4635{ 4642{
@@ -4660,8 +4667,7 @@ static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4660 4667
4661 err = ipw2100_hw_send_command(priv, &cmd); 4668 err = ipw2100_hw_send_command(priv, &cmd);
4662 if (err) { 4669 if (err) {
4663 IPW_DEBUG_INFO("Failed to set channel to %d", 4670 IPW_DEBUG_INFO("Failed to set channel to %d", channel);
4664 channel);
4665 return err; 4671 return err;
4666 } 4672 }
4667 4673
@@ -4703,15 +4709,14 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4703 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START; 4709 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4704 4710
4705 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK | 4711 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4706 IPW_CFG_BSS_MASK | 4712 IPW_CFG_BSS_MASK | IPW_CFG_802_1x_ENABLE;
4707 IPW_CFG_802_1x_ENABLE;
4708 4713
4709 if (!(priv->config & CFG_LONG_PREAMBLE)) 4714 if (!(priv->config & CFG_LONG_PREAMBLE))
4710 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO; 4715 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4711 4716
4712 err = ipw2100_get_ordinal(priv, 4717 err = ipw2100_get_ordinal(priv,
4713 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, 4718 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4714 &ibss_mask, &len); 4719 &ibss_mask, &len);
4715 if (err) 4720 if (err)
4716 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK; 4721 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4717 4722
@@ -4719,7 +4724,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4719 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask; 4724 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4720 4725
4721 /* 11b only */ 4726 /* 11b only */
4722 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/ 4727 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A; */
4723 4728
4724 err = ipw2100_hw_send_command(priv, &cmd); 4729 err = ipw2100_hw_send_command(priv, &cmd);
4725 if (err) 4730 if (err)
@@ -4783,8 +4788,7 @@ static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4783 return 0; 4788 return 0;
4784} 4789}
4785 4790
4786static int ipw2100_set_power_mode(struct ipw2100_priv *priv, 4791static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
4787 int power_level)
4788{ 4792{
4789 struct host_command cmd = { 4793 struct host_command cmd = {
4790 .host_command = POWER_MODE, 4794 .host_command = POWER_MODE,
@@ -4805,11 +4809,10 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4805 priv->power_mode = IPW_POWER_ENABLED | power_level; 4809 priv->power_mode = IPW_POWER_ENABLED | power_level;
4806 4810
4807#ifdef CONFIG_IPW2100_TX_POWER 4811#ifdef CONFIG_IPW2100_TX_POWER
4808 if (priv->port_type == IBSS && 4812 if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4809 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4810 /* Set beacon interval */ 4813 /* Set beacon interval */
4811 cmd.host_command = TX_POWER_INDEX; 4814 cmd.host_command = TX_POWER_INDEX;
4812 cmd.host_command_parameters[0] = (u32)priv->adhoc_power; 4815 cmd.host_command_parameters[0] = (u32) priv->adhoc_power;
4813 4816
4814 err = ipw2100_hw_send_command(priv, &cmd); 4817 err = ipw2100_hw_send_command(priv, &cmd);
4815 if (err) 4818 if (err)
@@ -4820,7 +4823,6 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4820 return 0; 4823 return 0;
4821} 4824}
4822 4825
4823
4824static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold) 4826static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4825{ 4827{
4826 struct host_command cmd = { 4828 struct host_command cmd = {
@@ -4925,8 +4927,7 @@ static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4925 return 0; 4927 return 0;
4926} 4928}
4927 4929
4928 4930static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4929static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4930 int batch_mode) 4931 int batch_mode)
4931{ 4932{
4932 struct host_command cmd = { 4933 struct host_command cmd = {
@@ -4938,16 +4939,15 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4938 4939
4939#ifdef CONFIG_IPW_DEBUG 4940#ifdef CONFIG_IPW_DEBUG
4940 if (bssid != NULL) 4941 if (bssid != NULL)
4941 IPW_DEBUG_HC( 4942 IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4942 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", 4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], 4944 bssid[5]);
4944 bssid[5]);
4945 else 4945 else
4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n"); 4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4947#endif 4947#endif
4948 /* if BSSID is empty then we disable mandatory bssid mode */ 4948 /* if BSSID is empty then we disable mandatory bssid mode */
4949 if (bssid != NULL) 4949 if (bssid != NULL)
4950 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN); 4950 memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
4951 4951
4952 if (!batch_mode) { 4952 if (!batch_mode) {
4953 err = ipw2100_disable_adapter(priv); 4953 err = ipw2100_disable_adapter(priv);
@@ -4963,7 +4963,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4963 return err; 4963 return err;
4964} 4964}
4965 4965
4966#ifdef CONFIG_IEEE80211_WPA
4967static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv) 4966static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4968{ 4967{
4969 struct host_command cmd = { 4968 struct host_command cmd = {
@@ -4987,42 +4986,10 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4987 4986
4988 return err; 4987 return err;
4989} 4988}
4990#endif
4991
4992/*
4993 * Pseudo code for setting up wpa_frame:
4994 */
4995#if 0
4996void x(struct ieee80211_assoc_frame *wpa_assoc)
4997{
4998 struct ipw2100_wpa_assoc_frame frame;
4999 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
5000 IPW_WPA_LISTENINTERVAL |
5001 IPW_WPA_AP_ADDRESS;
5002 frame->capab_info = wpa_assoc->capab_info;
5003 frame->lisen_interval = wpa_assoc->listent_interval;
5004 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5005
5006 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5007 * setup here to test it with.
5008 *
5009 * Walk the IEs in the wpa_assoc and figure out the total size of all
5010 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5011 * the IEs from wpa_frame into frame.
5012 */
5013 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5014 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5015
5016 ipw2100_set_wpa_ie(priv, &frame, 0);
5017}
5018#endif
5019
5020
5021
5022 4989
5023static int ipw2100_set_wpa_ie(struct ipw2100_priv *, 4990static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5024 struct ipw2100_wpa_assoc_frame *, int) 4991 struct ipw2100_wpa_assoc_frame *, int)
5025__attribute__ ((unused)); 4992 __attribute__ ((unused));
5026 4993
5027static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv, 4994static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5028 struct ipw2100_wpa_assoc_frame *wpa_frame, 4995 struct ipw2100_wpa_assoc_frame *wpa_frame,
@@ -5076,7 +5043,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5076 .host_command_length = sizeof(struct security_info_params) 5043 .host_command_length = sizeof(struct security_info_params)
5077 }; 5044 };
5078 struct security_info_params *security = 5045 struct security_info_params *security =
5079 (struct security_info_params *)&cmd.host_command_parameters; 5046 (struct security_info_params *)&cmd.host_command_parameters;
5080 int err; 5047 int err;
5081 memset(security, 0, sizeof(*security)); 5048 memset(security, 0, sizeof(*security));
5082 5049
@@ -5094,25 +5061,25 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5094 break; 5061 break;
5095 case SEC_LEVEL_1: 5062 case SEC_LEVEL_1:
5096 security->allowed_ciphers = IPW_WEP40_CIPHER | 5063 security->allowed_ciphers = IPW_WEP40_CIPHER |
5097 IPW_WEP104_CIPHER; 5064 IPW_WEP104_CIPHER;
5098 break; 5065 break;
5099 case SEC_LEVEL_2: 5066 case SEC_LEVEL_2:
5100 security->allowed_ciphers = IPW_WEP40_CIPHER | 5067 security->allowed_ciphers = IPW_WEP40_CIPHER |
5101 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER; 5068 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5102 break; 5069 break;
5103 case SEC_LEVEL_2_CKIP: 5070 case SEC_LEVEL_2_CKIP:
5104 security->allowed_ciphers = IPW_WEP40_CIPHER | 5071 security->allowed_ciphers = IPW_WEP40_CIPHER |
5105 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER; 5072 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5106 break; 5073 break;
5107 case SEC_LEVEL_3: 5074 case SEC_LEVEL_3:
5108 security->allowed_ciphers = IPW_WEP40_CIPHER | 5075 security->allowed_ciphers = IPW_WEP40_CIPHER |
5109 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER; 5076 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5110 break; 5077 break;
5111 } 5078 }
5112 5079
5113 IPW_DEBUG_HC( 5080 IPW_DEBUG_HC
5114 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n", 5081 ("SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5115 security->auth_mode, security->allowed_ciphers, security_level); 5082 security->auth_mode, security->allowed_ciphers, security_level);
5116 5083
5117 security->replay_counters_number = 0; 5084 security->replay_counters_number = 0;
5118 5085
@@ -5130,8 +5097,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5130 return err; 5097 return err;
5131} 5098}
5132 5099
5133static int ipw2100_set_tx_power(struct ipw2100_priv *priv, 5100static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
5134 u32 tx_power)
5135{ 5101{
5136 struct host_command cmd = { 5102 struct host_command cmd = {
5137 .host_command = TX_POWER_INDEX, 5103 .host_command = TX_POWER_INDEX,
@@ -5140,6 +5106,10 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5140 }; 5106 };
5141 int err = 0; 5107 int err = 0;
5142 5108
5109 if (tx_power != IPW_TX_POWER_DEFAULT)
5110 tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
5111 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
5112
5143 cmd.host_command_parameters[0] = tx_power; 5113 cmd.host_command_parameters[0] = tx_power;
5144 5114
5145 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 5115 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -5185,7 +5155,6 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5185 return 0; 5155 return 0;
5186} 5156}
5187 5157
5188
5189void ipw2100_queues_initialize(struct ipw2100_priv *priv) 5158void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5190{ 5159{
5191 ipw2100_tx_initialize(priv); 5160 ipw2100_tx_initialize(priv);
@@ -5203,13 +5172,12 @@ void ipw2100_queues_free(struct ipw2100_priv *priv)
5203int ipw2100_queues_allocate(struct ipw2100_priv *priv) 5172int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5204{ 5173{
5205 if (ipw2100_tx_allocate(priv) || 5174 if (ipw2100_tx_allocate(priv) ||
5206 ipw2100_rx_allocate(priv) || 5175 ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
5207 ipw2100_msg_allocate(priv))
5208 goto fail; 5176 goto fail;
5209 5177
5210 return 0; 5178 return 0;
5211 5179
5212 fail: 5180 fail:
5213 ipw2100_tx_free(priv); 5181 ipw2100_tx_free(priv);
5214 ipw2100_rx_free(priv); 5182 ipw2100_rx_free(priv);
5215 ipw2100_msg_free(priv); 5183 ipw2100_msg_free(priv);
@@ -5235,7 +5203,8 @@ static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5235 if (!batch_mode) { 5203 if (!batch_mode) {
5236 err = ipw2100_disable_adapter(priv); 5204 err = ipw2100_disable_adapter(priv);
5237 if (err) { 5205 if (err) {
5238 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5206 printk(KERN_ERR DRV_NAME
5207 ": %s: Could not disable adapter %d\n",
5239 priv->net_dev->name, err); 5208 priv->net_dev->name, err);
5240 return err; 5209 return err;
5241 } 5210 }
@@ -5262,7 +5231,6 @@ struct ipw2100_wep_key {
5262#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4] 5231#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5263#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10] 5232#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5264 5233
5265
5266/** 5234/**
5267 * Set a the wep key 5235 * Set a the wep key
5268 * 5236 *
@@ -5287,11 +5255,11 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5287 .host_command_sequence = 0, 5255 .host_command_sequence = 0,
5288 .host_command_length = sizeof(struct ipw2100_wep_key), 5256 .host_command_length = sizeof(struct ipw2100_wep_key),
5289 }; 5257 };
5290 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters; 5258 struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
5291 int err; 5259 int err;
5292 5260
5293 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n", 5261 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5294 idx, keylen, len); 5262 idx, keylen, len);
5295 5263
5296 /* NOTE: We don't check cached values in case the firmware was reset 5264 /* NOTE: We don't check cached values in case the firmware was reset
5297 * or some other problem is occuring. If the user is setting the key, 5265 * or some other problem is occuring. If the user is setting the key,
@@ -5308,22 +5276,23 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5308 /* Will be optimized out on debug not being configured in */ 5276 /* Will be optimized out on debug not being configured in */
5309 if (keylen == 0) 5277 if (keylen == 0)
5310 IPW_DEBUG_WEP("%s: Clearing key %d\n", 5278 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5311 priv->net_dev->name, wep_key->idx); 5279 priv->net_dev->name, wep_key->idx);
5312 else if (keylen == 5) 5280 else if (keylen == 5)
5313 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n", 5281 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5314 priv->net_dev->name, wep_key->idx, wep_key->len, 5282 priv->net_dev->name, wep_key->idx, wep_key->len,
5315 WEP_STR_64(wep_key->key)); 5283 WEP_STR_64(wep_key->key));
5316 else 5284 else
5317 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128 5285 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5318 "\n", 5286 "\n",
5319 priv->net_dev->name, wep_key->idx, wep_key->len, 5287 priv->net_dev->name, wep_key->idx, wep_key->len,
5320 WEP_STR_128(wep_key->key)); 5288 WEP_STR_128(wep_key->key));
5321 5289
5322 if (!batch_mode) { 5290 if (!batch_mode) {
5323 err = ipw2100_disable_adapter(priv); 5291 err = ipw2100_disable_adapter(priv);
5324 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */ 5292 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5325 if (err) { 5293 if (err) {
5326 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5294 printk(KERN_ERR DRV_NAME
5295 ": %s: Could not disable adapter %d\n",
5327 priv->net_dev->name, err); 5296 priv->net_dev->name, err);
5328 return err; 5297 return err;
5329 } 5298 }
@@ -5347,7 +5316,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5347 .host_command = WEP_KEY_INDEX, 5316 .host_command = WEP_KEY_INDEX,
5348 .host_command_sequence = 0, 5317 .host_command_sequence = 0,
5349 .host_command_length = 4, 5318 .host_command_length = 4,
5350 .host_command_parameters = { idx }, 5319 .host_command_parameters = {idx},
5351 }; 5320 };
5352 int err; 5321 int err;
5353 5322
@@ -5359,7 +5328,8 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5359 if (!batch_mode) { 5328 if (!batch_mode) {
5360 err = ipw2100_disable_adapter(priv); 5329 err = ipw2100_disable_adapter(priv);
5361 if (err) { 5330 if (err) {
5362 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5331 printk(KERN_ERR DRV_NAME
5332 ": %s: Could not disable adapter %d\n",
5363 priv->net_dev->name, err); 5333 priv->net_dev->name, err);
5364 return err; 5334 return err;
5365 } 5335 }
@@ -5374,9 +5344,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5374 return err; 5344 return err;
5375} 5345}
5376 5346
5377 5347static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
5378static int ipw2100_configure_security(struct ipw2100_priv *priv,
5379 int batch_mode)
5380{ 5348{
5381 int i, err, auth_mode, sec_level, use_group; 5349 int i, err, auth_mode, sec_level, use_group;
5382 5350
@@ -5389,40 +5357,42 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5389 return err; 5357 return err;
5390 } 5358 }
5391 5359
5392 if (!priv->sec.enabled) { 5360 if (!priv->ieee->sec.enabled) {
5393 err = ipw2100_set_security_information( 5361 err =
5394 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1); 5362 ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
5363 SEC_LEVEL_0, 0, 1);
5395 } else { 5364 } else {
5396 auth_mode = IPW_AUTH_OPEN; 5365 auth_mode = IPW_AUTH_OPEN;
5397 if ((priv->sec.flags & SEC_AUTH_MODE) && 5366 if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
5398 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) 5367 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5399 auth_mode = IPW_AUTH_SHARED; 5368 auth_mode = IPW_AUTH_SHARED;
5400 5369
5401 sec_level = SEC_LEVEL_0; 5370 sec_level = SEC_LEVEL_0;
5402 if (priv->sec.flags & SEC_LEVEL) 5371 if (priv->ieee->sec.flags & SEC_LEVEL)
5403 sec_level = priv->sec.level; 5372 sec_level = priv->ieee->sec.level;
5404 5373
5405 use_group = 0; 5374 use_group = 0;
5406 if (priv->sec.flags & SEC_UNICAST_GROUP) 5375 if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
5407 use_group = priv->sec.unicast_uses_group; 5376 use_group = priv->ieee->sec.unicast_uses_group;
5408 5377
5409 err = ipw2100_set_security_information( 5378 err =
5410 priv, auth_mode, sec_level, use_group, 1); 5379 ipw2100_set_security_information(priv, auth_mode, sec_level,
5380 use_group, 1);
5411 } 5381 }
5412 5382
5413 if (err) 5383 if (err)
5414 goto exit; 5384 goto exit;
5415 5385
5416 if (priv->sec.enabled) { 5386 if (priv->ieee->sec.enabled) {
5417 for (i = 0; i < 4; i++) { 5387 for (i = 0; i < 4; i++) {
5418 if (!(priv->sec.flags & (1 << i))) { 5388 if (!(priv->ieee->sec.flags & (1 << i))) {
5419 memset(priv->sec.keys[i], 0, WEP_KEY_LEN); 5389 memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
5420 priv->sec.key_sizes[i] = 0; 5390 priv->ieee->sec.key_sizes[i] = 0;
5421 } else { 5391 } else {
5422 err = ipw2100_set_key(priv, i, 5392 err = ipw2100_set_key(priv, i,
5423 priv->sec.keys[i], 5393 priv->ieee->sec.keys[i],
5424 priv->sec.key_sizes[i], 5394 priv->ieee->sec.
5425 1); 5395 key_sizes[i], 1);
5426 if (err) 5396 if (err)
5427 goto exit; 5397 goto exit;
5428 } 5398 }
@@ -5433,14 +5403,16 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5433 5403
5434 /* Always enable privacy so the Host can filter WEP packets if 5404 /* Always enable privacy so the Host can filter WEP packets if
5435 * encrypted data is sent up */ 5405 * encrypted data is sent up */
5436 err = ipw2100_set_wep_flags( 5406 err =
5437 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1); 5407 ipw2100_set_wep_flags(priv,
5408 priv->ieee->sec.
5409 enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5438 if (err) 5410 if (err)
5439 goto exit; 5411 goto exit;
5440 5412
5441 priv->status &= ~STATUS_SECURITY_UPDATED; 5413 priv->status &= ~STATUS_SECURITY_UPDATED;
5442 5414
5443 exit: 5415 exit:
5444 if (!batch_mode) 5416 if (!batch_mode)
5445 ipw2100_enable_adapter(priv); 5417 ipw2100_enable_adapter(priv);
5446 5418
@@ -5469,60 +5441,64 @@ static void shim__set_security(struct net_device *dev,
5469 5441
5470 for (i = 0; i < 4; i++) { 5442 for (i = 0; i < 4; i++) {
5471 if (sec->flags & (1 << i)) { 5443 if (sec->flags & (1 << i)) {
5472 priv->sec.key_sizes[i] = sec->key_sizes[i]; 5444 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
5473 if (sec->key_sizes[i] == 0) 5445 if (sec->key_sizes[i] == 0)
5474 priv->sec.flags &= ~(1 << i); 5446 priv->ieee->sec.flags &= ~(1 << i);
5475 else 5447 else
5476 memcpy(priv->sec.keys[i], sec->keys[i], 5448 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
5477 sec->key_sizes[i]); 5449 sec->key_sizes[i]);
5478 priv->sec.flags |= (1 << i); 5450 if (sec->level == SEC_LEVEL_1) {
5479 priv->status |= STATUS_SECURITY_UPDATED; 5451 priv->ieee->sec.flags |= (1 << i);
5452 priv->status |= STATUS_SECURITY_UPDATED;
5453 } else
5454 priv->ieee->sec.flags &= ~(1 << i);
5480 } 5455 }
5481 } 5456 }
5482 5457
5483 if ((sec->flags & SEC_ACTIVE_KEY) && 5458 if ((sec->flags & SEC_ACTIVE_KEY) &&
5484 priv->sec.active_key != sec->active_key) { 5459 priv->ieee->sec.active_key != sec->active_key) {
5485 if (sec->active_key <= 3) { 5460 if (sec->active_key <= 3) {
5486 priv->sec.active_key = sec->active_key; 5461 priv->ieee->sec.active_key = sec->active_key;
5487 priv->sec.flags |= SEC_ACTIVE_KEY; 5462 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
5488 } else 5463 } else
5489 priv->sec.flags &= ~SEC_ACTIVE_KEY; 5464 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
5490 5465
5491 priv->status |= STATUS_SECURITY_UPDATED; 5466 priv->status |= STATUS_SECURITY_UPDATED;
5492 } 5467 }
5493 5468
5494 if ((sec->flags & SEC_AUTH_MODE) && 5469 if ((sec->flags & SEC_AUTH_MODE) &&
5495 (priv->sec.auth_mode != sec->auth_mode)) { 5470 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
5496 priv->sec.auth_mode = sec->auth_mode; 5471 priv->ieee->sec.auth_mode = sec->auth_mode;
5497 priv->sec.flags |= SEC_AUTH_MODE; 5472 priv->ieee->sec.flags |= SEC_AUTH_MODE;
5498 priv->status |= STATUS_SECURITY_UPDATED; 5473 priv->status |= STATUS_SECURITY_UPDATED;
5499 } 5474 }
5500 5475
5501 if (sec->flags & SEC_ENABLED && 5476 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
5502 priv->sec.enabled != sec->enabled) { 5477 priv->ieee->sec.flags |= SEC_ENABLED;
5503 priv->sec.flags |= SEC_ENABLED; 5478 priv->ieee->sec.enabled = sec->enabled;
5504 priv->sec.enabled = sec->enabled;
5505 priv->status |= STATUS_SECURITY_UPDATED; 5479 priv->status |= STATUS_SECURITY_UPDATED;
5506 force_update = 1; 5480 force_update = 1;
5507 } 5481 }
5508 5482
5509 if (sec->flags & SEC_LEVEL && 5483 if (sec->flags & SEC_ENCRYPT)
5510 priv->sec.level != sec->level) { 5484 priv->ieee->sec.encrypt = sec->encrypt;
5511 priv->sec.level = sec->level; 5485
5512 priv->sec.flags |= SEC_LEVEL; 5486 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
5487 priv->ieee->sec.level = sec->level;
5488 priv->ieee->sec.flags |= SEC_LEVEL;
5513 priv->status |= STATUS_SECURITY_UPDATED; 5489 priv->status |= STATUS_SECURITY_UPDATED;
5514 } 5490 }
5515 5491
5516 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n", 5492 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5517 priv->sec.flags & (1<<8) ? '1' : '0', 5493 priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
5518 priv->sec.flags & (1<<7) ? '1' : '0', 5494 priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
5519 priv->sec.flags & (1<<6) ? '1' : '0', 5495 priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
5520 priv->sec.flags & (1<<5) ? '1' : '0', 5496 priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
5521 priv->sec.flags & (1<<4) ? '1' : '0', 5497 priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
5522 priv->sec.flags & (1<<3) ? '1' : '0', 5498 priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
5523 priv->sec.flags & (1<<2) ? '1' : '0', 5499 priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
5524 priv->sec.flags & (1<<1) ? '1' : '0', 5500 priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
5525 priv->sec.flags & (1<<0) ? '1' : '0'); 5501 priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
5526 5502
5527/* As a temporary work around to enable WPA until we figure out why 5503/* As a temporary work around to enable WPA until we figure out why
5528 * wpa_supplicant toggles the security capability of the driver, which 5504 * wpa_supplicant toggles the security capability of the driver, which
@@ -5531,7 +5507,7 @@ static void shim__set_security(struct net_device *dev,
5531 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/ 5507 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5532 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) 5508 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5533 ipw2100_configure_security(priv, 0); 5509 ipw2100_configure_security(priv, 0);
5534done: 5510 done:
5535 up(&priv->action_sem); 5511 up(&priv->action_sem);
5536} 5512}
5537 5513
@@ -5556,7 +5532,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5556 5532
5557 return 0; 5533 return 0;
5558 } 5534 }
5559#endif /* CONFIG_IPW2100_MONITOR */ 5535#endif /* CONFIG_IPW2100_MONITOR */
5560 5536
5561 err = ipw2100_read_mac_address(priv); 5537 err = ipw2100_read_mac_address(priv);
5562 if (err) 5538 if (err)
@@ -5576,7 +5552,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5576 return err; 5552 return err;
5577 } 5553 }
5578 5554
5579 err = ipw2100_system_config(priv, batch_mode); 5555 err = ipw2100_system_config(priv, batch_mode);
5580 if (err) 5556 if (err)
5581 return err; 5557 return err;
5582 5558
@@ -5614,8 +5590,10 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5614 return err; 5590 return err;
5615 5591
5616 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 5592 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5617 err = ipw2100_set_ibss_beacon_interval( 5593 err =
5618 priv, priv->beacon_interval, batch_mode); 5594 ipw2100_set_ibss_beacon_interval(priv,
5595 priv->beacon_interval,
5596 batch_mode);
5619 if (err) 5597 if (err)
5620 return err; 5598 return err;
5621 5599
@@ -5625,18 +5603,17 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5625 } 5603 }
5626 5604
5627 /* 5605 /*
5628 err = ipw2100_set_fragmentation_threshold( 5606 err = ipw2100_set_fragmentation_threshold(
5629 priv, priv->frag_threshold, batch_mode); 5607 priv, priv->frag_threshold, batch_mode);
5630 if (err) 5608 if (err)
5631 return err; 5609 return err;
5632 */ 5610 */
5633 5611
5634 IPW_DEBUG_INFO("exit\n"); 5612 IPW_DEBUG_INFO("exit\n");
5635 5613
5636 return 0; 5614 return 0;
5637} 5615}
5638 5616
5639
5640/************************************************************************* 5617/*************************************************************************
5641 * 5618 *
5642 * EXTERNALLY CALLED METHODS 5619 * EXTERNALLY CALLED METHODS
@@ -5669,7 +5646,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5669 ipw2100_reset_adapter(priv); 5646 ipw2100_reset_adapter(priv);
5670 return 0; 5647 return 0;
5671 5648
5672 done: 5649 done:
5673 up(&priv->action_sem); 5650 up(&priv->action_sem);
5674 return err; 5651 return err;
5675} 5652}
@@ -5708,7 +5685,7 @@ static int ipw2100_close(struct net_device *dev)
5708 /* Flush the TX queue ... */ 5685 /* Flush the TX queue ... */
5709 while (!list_empty(&priv->tx_pend_list)) { 5686 while (!list_empty(&priv->tx_pend_list)) {
5710 element = priv->tx_pend_list.next; 5687 element = priv->tx_pend_list.next;
5711 packet = list_entry(element, struct ipw2100_tx_packet, list); 5688 packet = list_entry(element, struct ipw2100_tx_packet, list);
5712 5689
5713 list_del(element); 5690 list_del(element);
5714 DEC_STAT(&priv->tx_pend_stat); 5691 DEC_STAT(&priv->tx_pend_stat);
@@ -5726,8 +5703,6 @@ static int ipw2100_close(struct net_device *dev)
5726 return 0; 5703 return 0;
5727} 5704}
5728 5705
5729
5730
5731/* 5706/*
5732 * TODO: Fix this function... its just wrong 5707 * TODO: Fix this function... its just wrong
5733 */ 5708 */
@@ -5747,7 +5722,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
5747 schedule_reset(priv); 5722 schedule_reset(priv);
5748} 5723}
5749 5724
5750
5751/* 5725/*
5752 * TODO: reimplement it so that it reads statistics 5726 * TODO: reimplement it so that it reads statistics
5753 * from the adapter using ordinal tables 5727 * from the adapter using ordinal tables
@@ -5761,11 +5735,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5761 return &priv->ieee->stats; 5735 return &priv->ieee->stats;
5762} 5736}
5763 5737
5764/* Support for wpa_supplicant. Will be replaced with WEXT once 5738#if WIRELESS_EXT < 18
5765 * they get WPA support. */ 5739/* Support for wpa_supplicant before WE-18, deprecated. */
5766#ifdef CONFIG_IEEE80211_WPA
5767 5740
5768/* following definitions must match definitions in driver_ipw2100.c */ 5741/* following definitions must match definitions in driver_ipw.c */
5769 5742
5770#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 5743#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5771 5744
@@ -5796,25 +5769,26 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5796struct ipw2100_param { 5769struct ipw2100_param {
5797 u32 cmd; 5770 u32 cmd;
5798 u8 sta_addr[ETH_ALEN]; 5771 u8 sta_addr[ETH_ALEN];
5799 union { 5772 union {
5800 struct { 5773 struct {
5801 u8 name; 5774 u8 name;
5802 u32 value; 5775 u32 value;
5803 } wpa_param; 5776 } wpa_param;
5804 struct { 5777 struct {
5805 u32 len; 5778 u32 len;
5806 u8 *data; 5779 u8 reserved[32];
5780 u8 data[0];
5807 } wpa_ie; 5781 } wpa_ie;
5808 struct{ 5782 struct {
5809 int command; 5783 u32 command;
5810 int reason_code; 5784 u32 reason_code;
5811 } mlme; 5785 } mlme;
5812 struct { 5786 struct {
5813 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; 5787 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5814 u8 set_tx; 5788 u8 set_tx;
5815 u32 err; 5789 u32 err;
5816 u8 idx; 5790 u8 idx;
5817 u8 seq[8]; /* sequence counter (set: RX, get: TX) */ 5791 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5818 u16 key_len; 5792 u16 key_len;
5819 u8 key[0]; 5793 u8 key[0];
5820 } crypt; 5794 } crypt;
@@ -5822,38 +5796,24 @@ struct ipw2100_param {
5822 } u; 5796 } u;
5823}; 5797};
5824 5798
5825/* end of driver_ipw2100.c code */ 5799/* end of driver_ipw.c code */
5826 5800#endif /* WIRELESS_EXT < 18 */
5827static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5828 5801
5829 struct ieee80211_device *ieee = priv->ieee; 5802static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5830 struct ieee80211_security sec = { 5803{
5831 .flags = SEC_LEVEL | SEC_ENABLED, 5804 /* This is called when wpa_supplicant loads and closes the driver
5832 }; 5805 * interface. */
5833 int ret = 0; 5806 priv->ieee->wpa_enabled = value;
5834 5807 return 0;
5835 ieee->wpa_enabled = value;
5836
5837 if (value){
5838 sec.level = SEC_LEVEL_3;
5839 sec.enabled = 1;
5840 } else {
5841 sec.level = SEC_LEVEL_0;
5842 sec.enabled = 0;
5843 }
5844
5845 if (ieee->set_security)
5846 ieee->set_security(ieee->dev, &sec);
5847 else
5848 ret = -EOPNOTSUPP;
5849
5850 return ret;
5851} 5808}
5852 5809
5853#define AUTH_ALG_OPEN_SYSTEM 0x1 5810#if WIRELESS_EXT < 18
5854#define AUTH_ALG_SHARED_KEY 0x2 5811#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5812#define IW_AUTH_ALG_SHARED_KEY 0x2
5813#endif
5855 5814
5856static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){ 5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5816{
5857 5817
5858 struct ieee80211_device *ieee = priv->ieee; 5818 struct ieee80211_device *ieee = priv->ieee;
5859 struct ieee80211_security sec = { 5819 struct ieee80211_security sec = {
@@ -5861,13 +5821,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5861 }; 5821 };
5862 int ret = 0; 5822 int ret = 0;
5863 5823
5864 if (value & AUTH_ALG_SHARED_KEY){ 5824 if (value & IW_AUTH_ALG_SHARED_KEY) {
5865 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 5825 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5866 ieee->open_wep = 0; 5826 ieee->open_wep = 0;
5867 } else { 5827 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
5868 sec.auth_mode = WLAN_AUTH_OPEN; 5828 sec.auth_mode = WLAN_AUTH_OPEN;
5869 ieee->open_wep = 1; 5829 ieee->open_wep = 1;
5870 } 5830 } else
5831 return -EINVAL;
5871 5832
5872 if (ieee->set_security) 5833 if (ieee->set_security)
5873 ieee->set_security(ieee->dev, &sec); 5834 ieee->set_security(ieee->dev, &sec);
@@ -5877,103 +5838,135 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5877 return ret; 5838 return ret;
5878} 5839}
5879 5840
5841void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5842 char *wpa_ie, int wpa_ie_len)
5843{
5880 5844
5881static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){ 5845 struct ipw2100_wpa_assoc_frame frame;
5882
5883 struct ipw2100_priv *priv = ieee80211_priv(dev);
5884 int ret=0;
5885 5846
5886 switch(name){ 5847 frame.fixed_ie_mask = 0;
5887 case IPW2100_PARAM_WPA_ENABLED:
5888 ret = ipw2100_wpa_enable(priv, value);
5889 break;
5890 5848
5891 case IPW2100_PARAM_TKIP_COUNTERMEASURES: 5849 /* copy WPA IE */
5892 priv->ieee->tkip_countermeasures=value; 5850 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5893 break; 5851 frame.var_ie_len = wpa_ie_len;
5894 5852
5895 case IPW2100_PARAM_DROP_UNENCRYPTED: 5853 /* make sure WPA is enabled */
5896 priv->ieee->drop_unencrypted=value; 5854 ipw2100_wpa_enable(priv, 1);
5897 break; 5855 ipw2100_set_wpa_ie(priv, &frame, 0);
5856}
5898 5857
5899 case IPW2100_PARAM_PRIVACY_INVOKED: 5858#if WIRELESS_EXT < 18
5900 priv->ieee->privacy_invoked=value; 5859static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5901 break; 5860{
5861 struct ipw2100_priv *priv = ieee80211_priv(dev);
5862 struct ieee80211_crypt_data *crypt;
5863 unsigned long flags;
5864 int ret = 0;
5902 5865
5903 case IPW2100_PARAM_AUTH_ALGS: 5866 switch (name) {
5904 ret = ipw2100_wpa_set_auth_algs(priv, value); 5867 case IPW2100_PARAM_WPA_ENABLED:
5905 break; 5868 ret = ipw2100_wpa_enable(priv, value);
5869 break;
5906 5870
5907 case IPW2100_PARAM_IEEE_802_1X: 5871 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5908 priv->ieee->ieee802_1x=value; 5872 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5873 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
5909 break; 5874 break;
5910 5875
5911 default: 5876 flags = crypt->ops->get_flags(crypt->priv);
5912 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5913 dev->name, name);
5914 ret = -EOPNOTSUPP;
5915 }
5916 5877
5917 return ret; 5878 if (value)
5918} 5879 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5880 else
5881 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5919 5882
5920static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){ 5883 crypt->ops->set_flags(flags, crypt->priv);
5921 5884
5922 struct ipw2100_priv *priv = ieee80211_priv(dev); 5885 break;
5923 int ret=0;
5924 5886
5925 switch(command){ 5887 case IPW2100_PARAM_DROP_UNENCRYPTED:{
5926 case IPW2100_MLME_STA_DEAUTH: 5888 /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
5927 // silently ignore 5889 struct ieee80211_security sec = {
5890 .flags = SEC_ENABLED,
5891 .enabled = value,
5892 };
5893 priv->ieee->drop_unencrypted = value;
5894 /* We only change SEC_LEVEL for open mode. Others
5895 * are set by ipw_wpa_set_encryption.
5896 */
5897 if (!value) {
5898 sec.flags |= SEC_LEVEL;
5899 sec.level = SEC_LEVEL_0;
5900 } else {
5901 sec.flags |= SEC_LEVEL;
5902 sec.level = SEC_LEVEL_1;
5903 }
5904 if (priv->ieee->set_security)
5905 priv->ieee->set_security(priv->ieee->dev, &sec);
5928 break; 5906 break;
5907 }
5929 5908
5930 case IPW2100_MLME_STA_DISASSOC: 5909 case IPW2100_PARAM_PRIVACY_INVOKED:
5931 ipw2100_disassociate_bssid(priv); 5910 priv->ieee->privacy_invoked = value;
5932 break; 5911 break;
5933 5912
5934 default: 5913 case IPW2100_PARAM_AUTH_ALGS:
5935 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", 5914 ret = ipw2100_wpa_set_auth_algs(priv, value);
5936 dev->name, command); 5915 break;
5937 ret = -EOPNOTSUPP; 5916
5917 case IPW2100_PARAM_IEEE_802_1X:
5918 priv->ieee->ieee802_1x = value;
5919 break;
5920
5921 default:
5922 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5923 dev->name, name);
5924 ret = -EOPNOTSUPP;
5938 } 5925 }
5939 5926
5940 return ret; 5927 return ret;
5941} 5928}
5942 5929
5930static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5931{
5943 5932
5944void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, 5933 struct ipw2100_priv *priv = ieee80211_priv(dev);
5945 char *wpa_ie, int wpa_ie_len){ 5934 int ret = 0;
5946 5935
5947 struct ipw2100_wpa_assoc_frame frame; 5936 switch (command) {
5937 case IPW2100_MLME_STA_DEAUTH:
5938 // silently ignore
5939 break;
5948 5940
5949 frame.fixed_ie_mask = 0; 5941 case IPW2100_MLME_STA_DISASSOC:
5942 ipw2100_disassociate_bssid(priv);
5943 break;
5950 5944
5951 /* copy WPA IE */ 5945 default:
5952 memcpy(frame.var_ie, wpa_ie, wpa_ie_len); 5946 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5953 frame.var_ie_len = wpa_ie_len; 5947 dev->name, command);
5948 ret = -EOPNOTSUPP;
5949 }
5954 5950
5955 /* make sure WPA is enabled */ 5951 return ret;
5956 ipw2100_wpa_enable(priv, 1);
5957 ipw2100_set_wpa_ie(priv, &frame, 0);
5958} 5952}
5959 5953
5960
5961static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, 5954static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5962 struct ipw2100_param *param, int plen){ 5955 struct ipw2100_param *param, int plen)
5956{
5963 5957
5964 struct ipw2100_priv *priv = ieee80211_priv(dev); 5958 struct ipw2100_priv *priv = ieee80211_priv(dev);
5965 struct ieee80211_device *ieee = priv->ieee; 5959 struct ieee80211_device *ieee = priv->ieee;
5966 u8 *buf; 5960 u8 *buf;
5967 5961
5968 if (! ieee->wpa_enabled) 5962 if (!ieee->wpa_enabled)
5969 return -EOPNOTSUPP; 5963 return -EOPNOTSUPP;
5970 5964
5971 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || 5965 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5972 (param->u.wpa_ie.len && 5966 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5973 param->u.wpa_ie.data==NULL))
5974 return -EINVAL; 5967 return -EINVAL;
5975 5968
5976 if (param->u.wpa_ie.len){ 5969 if (param->u.wpa_ie.len) {
5977 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); 5970 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5978 if (buf == NULL) 5971 if (buf == NULL)
5979 return -ENOMEM; 5972 return -ENOMEM;
@@ -5998,8 +5991,9 @@ static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5998/* implementation borrowed from hostap driver */ 5991/* implementation borrowed from hostap driver */
5999 5992
6000static int ipw2100_wpa_set_encryption(struct net_device *dev, 5993static int ipw2100_wpa_set_encryption(struct net_device *dev,
6001 struct ipw2100_param *param, int param_len){ 5994 struct ipw2100_param *param,
6002 5995 int param_len)
5996{
6003 int ret = 0; 5997 int ret = 0;
6004 struct ipw2100_priv *priv = ieee80211_priv(dev); 5998 struct ipw2100_priv *priv = ieee80211_priv(dev);
6005 struct ieee80211_device *ieee = priv->ieee; 5999 struct ieee80211_device *ieee = priv->ieee;
@@ -6014,9 +6008,10 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6014 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0'; 6008 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6015 6009
6016 if (param_len != 6010 if (param_len !=
6017 (int) ((char *) param->u.crypt.key - (char *) param) + 6011 (int)((char *)param->u.crypt.key - (char *)param) +
6018 param->u.crypt.key_len){ 6012 param->u.crypt.key_len) {
6019 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); 6013 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6014 param->u.crypt.key_len);
6020 return -EINVAL; 6015 return -EINVAL;
6021 } 6016 }
6022 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 6017 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -6029,17 +6024,19 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6029 return -EINVAL; 6024 return -EINVAL;
6030 } 6025 }
6031 6026
6027 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6032 if (strcmp(param->u.crypt.alg, "none") == 0) { 6028 if (strcmp(param->u.crypt.alg, "none") == 0) {
6033 if (crypt){ 6029 if (crypt) {
6034 sec.enabled = 0; 6030 sec.enabled = 0;
6031 sec.encrypt = 0;
6035 sec.level = SEC_LEVEL_0; 6032 sec.level = SEC_LEVEL_0;
6036 sec.flags |= SEC_ENABLED | SEC_LEVEL; 6033 sec.flags |= SEC_LEVEL;
6037 ieee80211_crypt_delayed_deinit(ieee, crypt); 6034 ieee80211_crypt_delayed_deinit(ieee, crypt);
6038 } 6035 }
6039 goto done; 6036 goto done;
6040 } 6037 }
6041 sec.enabled = 1; 6038 sec.enabled = 1;
6042 sec.flags |= SEC_ENABLED; 6039 sec.encrypt = 1;
6043 6040
6044 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 6041 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6045 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 6042 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -6054,7 +6051,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6054 } 6051 }
6055 if (ops == NULL) { 6052 if (ops == NULL) {
6056 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", 6053 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6057 dev->name, param->u.crypt.alg); 6054 dev->name, param->u.crypt.alg);
6058 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG; 6055 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6059 ret = -EINVAL; 6056 ret = -EINVAL;
6060 goto done; 6057 goto done;
@@ -6065,21 +6062,20 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6065 6062
6066 ieee80211_crypt_delayed_deinit(ieee, crypt); 6063 ieee80211_crypt_delayed_deinit(ieee, crypt);
6067 6064
6068 new_crypt = (struct ieee80211_crypt_data *) 6065 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6069 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6070 if (new_crypt == NULL) { 6066 if (new_crypt == NULL) {
6071 ret = -ENOMEM; 6067 ret = -ENOMEM;
6072 goto done; 6068 goto done;
6073 } 6069 }
6074 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6075 new_crypt->ops = ops; 6070 new_crypt->ops = ops;
6076 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 6071 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6077 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); 6072 new_crypt->priv =
6073 new_crypt->ops->init(param->u.crypt.idx);
6078 6074
6079 if (new_crypt->priv == NULL) { 6075 if (new_crypt->priv == NULL) {
6080 kfree(new_crypt); 6076 kfree(new_crypt);
6081 param->u.crypt.err = 6077 param->u.crypt.err =
6082 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED; 6078 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6083 ret = -EINVAL; 6079 ret = -EINVAL;
6084 goto done; 6080 goto done;
6085 } 6081 }
@@ -6091,24 +6087,25 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6091 (*crypt)->ops->set_key(param->u.crypt.key, 6087 (*crypt)->ops->set_key(param->u.crypt.key,
6092 param->u.crypt.key_len, param->u.crypt.seq, 6088 param->u.crypt.key_len, param->u.crypt.seq,
6093 (*crypt)->priv) < 0) { 6089 (*crypt)->priv) < 0) {
6094 IPW_DEBUG_INFO("%s: key setting failed\n", 6090 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6095 dev->name);
6096 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED; 6091 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6097 ret = -EINVAL; 6092 ret = -EINVAL;
6098 goto done; 6093 goto done;
6099 } 6094 }
6100 6095
6101 if (param->u.crypt.set_tx){ 6096 if (param->u.crypt.set_tx) {
6102 ieee->tx_keyidx = param->u.crypt.idx; 6097 ieee->tx_keyidx = param->u.crypt.idx;
6103 sec.active_key = param->u.crypt.idx; 6098 sec.active_key = param->u.crypt.idx;
6104 sec.flags |= SEC_ACTIVE_KEY; 6099 sec.flags |= SEC_ACTIVE_KEY;
6105 } 6100 }
6106 6101
6107 if (ops->name != NULL){ 6102 if (ops->name != NULL) {
6108 6103
6109 if (strcmp(ops->name, "WEP") == 0) { 6104 if (strcmp(ops->name, "WEP") == 0) {
6110 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); 6105 memcpy(sec.keys[param->u.crypt.idx],
6111 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; 6106 param->u.crypt.key, param->u.crypt.key_len);
6107 sec.key_sizes[param->u.crypt.idx] =
6108 param->u.crypt.key_len;
6112 sec.flags |= (1 << param->u.crypt.idx); 6109 sec.flags |= (1 << param->u.crypt.idx);
6113 sec.flags |= SEC_LEVEL; 6110 sec.flags |= SEC_LEVEL;
6114 sec.level = SEC_LEVEL_1; 6111 sec.level = SEC_LEVEL_1;
@@ -6120,7 +6117,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6120 sec.level = SEC_LEVEL_3; 6117 sec.level = SEC_LEVEL_3;
6121 } 6118 }
6122 } 6119 }
6123 done: 6120 done:
6124 if (ieee->set_security) 6121 if (ieee->set_security)
6125 ieee->set_security(ieee->dev, &sec); 6122 ieee->set_security(ieee->dev, &sec);
6126 6123
@@ -6131,8 +6128,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6131 * the callbacks structures used to initialize the 802.11 stack. */ 6128 * the callbacks structures used to initialize the 802.11 stack. */
6132 if (ieee->reset_on_keychange && 6129 if (ieee->reset_on_keychange &&
6133 ieee->iw_mode != IW_MODE_INFRA && 6130 ieee->iw_mode != IW_MODE_INFRA &&
6134 ieee->reset_port && 6131 ieee->reset_port && ieee->reset_port(dev)) {
6135 ieee->reset_port(dev)) {
6136 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); 6132 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6137 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; 6133 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6138 return -EINVAL; 6134 return -EINVAL;
@@ -6141,11 +6137,11 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6141 return ret; 6137 return ret;
6142} 6138}
6143 6139
6144 6140static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6145static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){ 6141{
6146 6142
6147 struct ipw2100_param *param; 6143 struct ipw2100_param *param;
6148 int ret=0; 6144 int ret = 0;
6149 6145
6150 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); 6146 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6151 6147
@@ -6156,12 +6152,12 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6156 if (param == NULL) 6152 if (param == NULL)
6157 return -ENOMEM; 6153 return -ENOMEM;
6158 6154
6159 if (copy_from_user(param, p->pointer, p->length)){ 6155 if (copy_from_user(param, p->pointer, p->length)) {
6160 kfree(param); 6156 kfree(param);
6161 return -EFAULT; 6157 return -EFAULT;
6162 } 6158 }
6163 6159
6164 switch (param->cmd){ 6160 switch (param->cmd) {
6165 6161
6166 case IPW2100_CMD_SET_WPA_PARAM: 6162 case IPW2100_CMD_SET_WPA_PARAM:
6167 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, 6163 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
@@ -6182,8 +6178,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6182 break; 6178 break;
6183 6179
6184 default: 6180 default:
6185 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n", 6181 printk(KERN_ERR DRV_NAME
6186 dev->name, param->cmd); 6182 ": %s: Unknown WPA supplicant request: %d\n", dev->name,
6183 param->cmd);
6187 ret = -EOPNOTSUPP; 6184 ret = -EOPNOTSUPP;
6188 6185
6189 } 6186 }
@@ -6194,27 +6191,23 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6194 kfree(param); 6191 kfree(param);
6195 return ret; 6192 return ret;
6196} 6193}
6197#endif /* CONFIG_IEEE80211_WPA */
6198 6194
6199static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6200{ 6196{
6201#ifdef CONFIG_IEEE80211_WPA 6197 struct iwreq *wrq = (struct iwreq *)rq;
6202 struct iwreq *wrq = (struct iwreq *) rq; 6198 int ret = -1;
6203 int ret=-1; 6199 switch (cmd) {
6204 switch (cmd){ 6200 case IPW2100_IOCTL_WPA_SUPPLICANT:
6205 case IPW2100_IOCTL_WPA_SUPPLICANT:
6206 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); 6201 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6207 return ret; 6202 return ret;
6208 6203
6209 default: 6204 default:
6210 return -EOPNOTSUPP; 6205 return -EOPNOTSUPP;
6211 } 6206 }
6212 6207
6213#endif /* CONFIG_IEEE80211_WPA */
6214
6215 return -EOPNOTSUPP; 6208 return -EOPNOTSUPP;
6216} 6209}
6217 6210#endif /* WIRELESS_EXT < 18 */
6218 6211
6219static void ipw_ethtool_get_drvinfo(struct net_device *dev, 6212static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6220 struct ethtool_drvinfo *info) 6213 struct ethtool_drvinfo *info)
@@ -6236,14 +6229,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6236 6229
6237static u32 ipw2100_ethtool_get_link(struct net_device *dev) 6230static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6238{ 6231{
6239 struct ipw2100_priv *priv = ieee80211_priv(dev); 6232 struct ipw2100_priv *priv = ieee80211_priv(dev);
6240 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0; 6233 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6241} 6234}
6242 6235
6243
6244static struct ethtool_ops ipw2100_ethtool_ops = { 6236static struct ethtool_ops ipw2100_ethtool_ops = {
6245 .get_link = ipw2100_ethtool_get_link, 6237 .get_link = ipw2100_ethtool_get_link,
6246 .get_drvinfo = ipw_ethtool_get_drvinfo, 6238 .get_drvinfo = ipw_ethtool_get_drvinfo,
6247}; 6239};
6248 6240
6249static void ipw2100_hang_check(void *adapter) 6241static void ipw2100_hang_check(void *adapter)
@@ -6288,7 +6280,6 @@ static void ipw2100_hang_check(void *adapter)
6288 spin_unlock_irqrestore(&priv->low_lock, flags); 6280 spin_unlock_irqrestore(&priv->low_lock, flags);
6289} 6281}
6290 6282
6291
6292static void ipw2100_rf_kill(void *adapter) 6283static void ipw2100_rf_kill(void *adapter)
6293{ 6284{
6294 struct ipw2100_priv *priv = adapter; 6285 struct ipw2100_priv *priv = adapter;
@@ -6313,7 +6304,7 @@ static void ipw2100_rf_kill(void *adapter)
6313 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " 6304 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6314 "enabled\n"); 6305 "enabled\n");
6315 6306
6316 exit_unlock: 6307 exit_unlock:
6317 spin_unlock_irqrestore(&priv->low_lock, flags); 6308 spin_unlock_irqrestore(&priv->low_lock, flags);
6318} 6309}
6319 6310
@@ -6321,11 +6312,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6321 6312
6322/* Look into using netdev destructor to shutdown ieee80211? */ 6313/* Look into using netdev destructor to shutdown ieee80211? */
6323 6314
6324static struct net_device *ipw2100_alloc_device( 6315static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6325 struct pci_dev *pci_dev, 6316 void __iomem * base_addr,
6326 void __iomem *base_addr, 6317 unsigned long mem_start,
6327 unsigned long mem_start, 6318 unsigned long mem_len)
6328 unsigned long mem_len)
6329{ 6319{
6330 struct ipw2100_priv *priv; 6320 struct ipw2100_priv *priv;
6331 struct net_device *dev; 6321 struct net_device *dev;
@@ -6341,17 +6331,22 @@ static struct net_device *ipw2100_alloc_device(
6341 priv->ieee->hard_start_xmit = ipw2100_tx; 6331 priv->ieee->hard_start_xmit = ipw2100_tx;
6342 priv->ieee->set_security = shim__set_security; 6332 priv->ieee->set_security = shim__set_security;
6343 6333
6334 priv->ieee->perfect_rssi = -20;
6335 priv->ieee->worst_rssi = -85;
6336
6344 dev->open = ipw2100_open; 6337 dev->open = ipw2100_open;
6345 dev->stop = ipw2100_close; 6338 dev->stop = ipw2100_close;
6346 dev->init = ipw2100_net_init; 6339 dev->init = ipw2100_net_init;
6340#if WIRELESS_EXT < 18
6347 dev->do_ioctl = ipw2100_ioctl; 6341 dev->do_ioctl = ipw2100_ioctl;
6342#endif
6348 dev->get_stats = ipw2100_stats; 6343 dev->get_stats = ipw2100_stats;
6349 dev->ethtool_ops = &ipw2100_ethtool_ops; 6344 dev->ethtool_ops = &ipw2100_ethtool_ops;
6350 dev->tx_timeout = ipw2100_tx_timeout; 6345 dev->tx_timeout = ipw2100_tx_timeout;
6351 dev->wireless_handlers = &ipw2100_wx_handler_def; 6346 dev->wireless_handlers = &ipw2100_wx_handler_def;
6352 dev->get_wireless_stats = ipw2100_wx_wireless_stats; 6347 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6353 dev->set_mac_address = ipw2100_set_address; 6348 dev->set_mac_address = ipw2100_set_address;
6354 dev->watchdog_timeo = 3*HZ; 6349 dev->watchdog_timeo = 3 * HZ;
6355 dev->irq = 0; 6350 dev->irq = 0;
6356 6351
6357 dev->base_addr = (unsigned long)base_addr; 6352 dev->base_addr = (unsigned long)base_addr;
@@ -6364,22 +6359,19 @@ static struct net_device *ipw2100_alloc_device(
6364 * ends up causing problems. So, we just handle 6359 * ends up causing problems. So, we just handle
6365 * the WX extensions through the ipw2100_ioctl interface */ 6360 * the WX extensions through the ipw2100_ioctl interface */
6366 6361
6367
6368 /* memset() puts everything to 0, so we only have explicitely set 6362 /* memset() puts everything to 0, so we only have explicitely set
6369 * those values that need to be something else */ 6363 * those values that need to be something else */
6370 6364
6371 /* If power management is turned on, default to AUTO mode */ 6365 /* If power management is turned on, default to AUTO mode */
6372 priv->power_mode = IPW_POWER_AUTO; 6366 priv->power_mode = IPW_POWER_AUTO;
6373 6367
6374 6368#ifdef CONFIG_IPW2100_MONITOR
6375 6369 priv->config |= CFG_CRC_CHECK;
6376#ifdef CONFIG_IEEE80211_WPA 6370#endif
6377 priv->ieee->wpa_enabled = 0; 6371 priv->ieee->wpa_enabled = 0;
6378 priv->ieee->tkip_countermeasures = 0;
6379 priv->ieee->drop_unencrypted = 0; 6372 priv->ieee->drop_unencrypted = 0;
6380 priv->ieee->privacy_invoked = 0; 6373 priv->ieee->privacy_invoked = 0;
6381 priv->ieee->ieee802_1x = 1; 6374 priv->ieee->ieee802_1x = 1;
6382#endif /* CONFIG_IEEE80211_WPA */
6383 6375
6384 /* Set module parameters */ 6376 /* Set module parameters */
6385 switch (mode) { 6377 switch (mode) {
@@ -6401,8 +6393,7 @@ static struct net_device *ipw2100_alloc_device(
6401 priv->status |= STATUS_RF_KILL_SW; 6393 priv->status |= STATUS_RF_KILL_SW;
6402 6394
6403 if (channel != 0 && 6395 if (channel != 0 &&
6404 ((channel >= REG_MIN_CHANNEL) && 6396 ((channel >= REG_MIN_CHANNEL) && (channel <= REG_MAX_CHANNEL))) {
6405 (channel <= REG_MAX_CHANNEL))) {
6406 priv->config |= CFG_STATIC_CHANNEL; 6397 priv->config |= CFG_STATIC_CHANNEL;
6407 priv->channel = channel; 6398 priv->channel = channel;
6408 } 6399 }
@@ -6441,12 +6432,8 @@ static struct net_device *ipw2100_alloc_device(
6441 INIT_LIST_HEAD(&priv->fw_pend_list); 6432 INIT_LIST_HEAD(&priv->fw_pend_list);
6442 INIT_STAT(&priv->fw_pend_stat); 6433 INIT_STAT(&priv->fw_pend_stat);
6443 6434
6444
6445#ifdef CONFIG_SOFTWARE_SUSPEND2
6446 priv->workqueue = create_workqueue(DRV_NAME, 0);
6447#else
6448 priv->workqueue = create_workqueue(DRV_NAME); 6435 priv->workqueue = create_workqueue(DRV_NAME);
6449#endif 6436
6450 INIT_WORK(&priv->reset_work, 6437 INIT_WORK(&priv->reset_work,
6451 (void (*)(void *))ipw2100_reset_adapter, priv); 6438 (void (*)(void *))ipw2100_reset_adapter, priv);
6452 INIT_WORK(&priv->security_work, 6439 INIT_WORK(&priv->security_work,
@@ -6535,7 +6522,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6535 return err; 6522 return err;
6536 } 6523 }
6537 6524
6538 /* We disable the RETRY_TIMEOUT register (0x41) to keep 6525 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6539 * PCI Tx retries from interfering with C3 CPU state */ 6526 * PCI Tx retries from interfering with C3 CPU state */
6540 pci_read_config_dword(pci_dev, 0x40, &val); 6527 pci_read_config_dword(pci_dev, 0x40, &val);
6541 if ((val & 0x0000ff00) != 0) 6528 if ((val & 0x0000ff00) != 0)
@@ -6566,12 +6553,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6566 ipw2100_queues_initialize(priv); 6553 ipw2100_queues_initialize(priv);
6567 6554
6568 err = request_irq(pci_dev->irq, 6555 err = request_irq(pci_dev->irq,
6569 ipw2100_interrupt, SA_SHIRQ, 6556 ipw2100_interrupt, SA_SHIRQ, dev->name, priv);
6570 dev->name, priv);
6571 if (err) { 6557 if (err) {
6572 printk(KERN_WARNING DRV_NAME 6558 printk(KERN_WARNING DRV_NAME
6573 "Error calling request_irq: %d.\n", 6559 "Error calling request_irq: %d.\n", pci_dev->irq);
6574 pci_dev->irq);
6575 goto fail; 6560 goto fail;
6576 } 6561 }
6577 dev->irq = pci_dev->irq; 6562 dev->irq = pci_dev->irq;
@@ -6606,7 +6591,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6606 6591
6607 /* perform this after register_netdev so that dev->name is set */ 6592 /* perform this after register_netdev so that dev->name is set */
6608 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6593 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6609 netif_carrier_off(dev);
6610 6594
6611 /* If the RF Kill switch is disabled, go ahead and complete the 6595 /* If the RF Kill switch is disabled, go ahead and complete the
6612 * startup sequence */ 6596 * startup sequence */
@@ -6634,10 +6618,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6634 6618
6635 return 0; 6619 return 0;
6636 6620
6637 fail_unlock: 6621 fail_unlock:
6638 up(&priv->action_sem); 6622 up(&priv->action_sem);
6639 6623
6640 fail: 6624 fail:
6641 if (dev) { 6625 if (dev) {
6642 if (registered) 6626 if (registered)
6643 unregister_netdev(dev); 6627 unregister_netdev(dev);
@@ -6653,7 +6637,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6653 6637
6654 /* These are safe to call even if they weren't allocated */ 6638 /* These are safe to call even if they weren't allocated */
6655 ipw2100_queues_free(priv); 6639 ipw2100_queues_free(priv);
6656 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6640 sysfs_remove_group(&pci_dev->dev.kobj,
6641 &ipw2100_attribute_group);
6657 6642
6658 free_ieee80211(dev); 6643 free_ieee80211(dev);
6659 pci_set_drvdata(pci_dev, NULL); 6644 pci_set_drvdata(pci_dev, NULL);
@@ -6679,7 +6664,8 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6679 priv->status &= ~STATUS_INITIALIZED; 6664 priv->status &= ~STATUS_INITIALIZED;
6680 6665
6681 dev = priv->net_dev; 6666 dev = priv->net_dev;
6682 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6667 sysfs_remove_group(&pci_dev->dev.kobj,
6668 &ipw2100_attribute_group);
6683 6669
6684#ifdef CONFIG_PM 6670#ifdef CONFIG_PM
6685 if (ipw2100_firmware.version) 6671 if (ipw2100_firmware.version)
@@ -6721,19 +6707,13 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6721 IPW_DEBUG_INFO("exit\n"); 6707 IPW_DEBUG_INFO("exit\n");
6722} 6708}
6723 6709
6724
6725#ifdef CONFIG_PM 6710#ifdef CONFIG_PM
6726#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6727static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6728#else
6729static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) 6711static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6730#endif
6731{ 6712{
6732 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6713 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6733 struct net_device *dev = priv->net_dev; 6714 struct net_device *dev = priv->net_dev;
6734 6715
6735 IPW_DEBUG_INFO("%s: Going into suspend...\n", 6716 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
6736 dev->name);
6737 6717
6738 down(&priv->action_sem); 6718 down(&priv->action_sem);
6739 if (priv->status & STATUS_INITIALIZED) { 6719 if (priv->status & STATUS_INITIALIZED) {
@@ -6745,7 +6725,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6745 netif_device_detach(dev); 6725 netif_device_detach(dev);
6746 6726
6747 pci_save_state(pci_dev); 6727 pci_save_state(pci_dev);
6748 pci_disable_device (pci_dev); 6728 pci_disable_device(pci_dev);
6749 pci_set_power_state(pci_dev, PCI_D3hot); 6729 pci_set_power_state(pci_dev, PCI_D3hot);
6750 6730
6751 up(&priv->action_sem); 6731 up(&priv->action_sem);
@@ -6764,8 +6744,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6764 6744
6765 down(&priv->action_sem); 6745 down(&priv->action_sem);
6766 6746
6767 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", 6747 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6768 dev->name);
6769 6748
6770 pci_set_power_state(pci_dev, PCI_D0); 6749 pci_set_power_state(pci_dev, PCI_D0);
6771 pci_enable_device(pci_dev); 6750 pci_enable_device(pci_dev);
@@ -6785,9 +6764,9 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6785 * the queue of needed */ 6764 * the queue of needed */
6786 netif_device_attach(dev); 6765 netif_device_attach(dev);
6787 6766
6788 /* Bring the device back up */ 6767 /* Bring the device back up */
6789 if (!(priv->status & STATUS_RF_KILL_SW)) 6768 if (!(priv->status & STATUS_RF_KILL_SW))
6790 ipw2100_up(priv, 0); 6769 ipw2100_up(priv, 0);
6791 6770
6792 up(&priv->action_sem); 6771 up(&priv->action_sem);
6793 6772
@@ -6795,56 +6774,55 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6795} 6774}
6796#endif 6775#endif
6797 6776
6798
6799#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } 6777#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6800 6778
6801static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { 6779static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6802 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ 6780 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6803 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ 6781 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6804 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ 6782 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6805 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */ 6783 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6806 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */ 6784 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6807 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */ 6785 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6808 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */ 6786 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6809 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */ 6787 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6810 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */ 6788 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6811 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */ 6789 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6812 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */ 6790 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */ 6791 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6814 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */ 6792 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6815 6793
6816 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */ 6794 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6817 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */ 6795 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6818 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */ 6796 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6819 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */ 6797 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6820 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */ 6798 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6821 6799
6822 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */ 6800 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6823 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */ 6801 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6824 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */ 6802 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6825 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */ 6803 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6826 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */ 6804 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6827 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */ 6805 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6828 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */ 6806 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6829 6807
6830 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */ 6808 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6831 6809
6832 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */ 6810 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6833 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */ 6811 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6834 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */ 6812 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6835 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */ 6813 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6836 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */ 6814 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6837 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */ 6815 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6838 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */ 6816 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6839 6817
6840 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */ 6818 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6841 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */ 6819 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6842 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */ 6820 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6843 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */ 6821 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6844 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */ 6822 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6845 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */ 6823 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6846 6824
6847 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */ 6825 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6848 {0,}, 6826 {0,},
6849}; 6827};
6850 6828
@@ -6861,7 +6839,6 @@ static struct pci_driver ipw2100_pci_driver = {
6861#endif 6839#endif
6862}; 6840};
6863 6841
6864
6865/** 6842/**
6866 * Initialize the ipw2100 driver/module 6843 * Initialize the ipw2100 driver/module
6867 * 6844 *
@@ -6878,10 +6855,6 @@ static int __init ipw2100_init(void)
6878 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6855 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6879 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6856 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6880 6857
6881#ifdef CONFIG_IEEE80211_NOWEP
6882 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6883#endif
6884
6885 ret = pci_module_init(&ipw2100_pci_driver); 6858 ret = pci_module_init(&ipw2100_pci_driver);
6886 6859
6887#ifdef CONFIG_IPW_DEBUG 6860#ifdef CONFIG_IPW_DEBUG
@@ -6893,7 +6866,6 @@ static int __init ipw2100_init(void)
6893 return ret; 6866 return ret;
6894} 6867}
6895 6868
6896
6897/** 6869/**
6898 * Cleanup ipw2100 driver registration 6870 * Cleanup ipw2100 driver registration
6899 */ 6871 */
@@ -6949,7 +6921,6 @@ static int ipw2100_wx_get_name(struct net_device *dev,
6949 return 0; 6921 return 0;
6950} 6922}
6951 6923
6952
6953static int ipw2100_wx_set_freq(struct net_device *dev, 6924static int ipw2100_wx_set_freq(struct net_device *dev,
6954 struct iw_request_info *info, 6925 struct iw_request_info *info,
6955 union iwreq_data *wrqu, char *extra) 6926 union iwreq_data *wrqu, char *extra)
@@ -6969,8 +6940,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6969 6940
6970 /* if setting by freq convert to channel */ 6941 /* if setting by freq convert to channel */
6971 if (fwrq->e == 1) { 6942 if (fwrq->e == 1) {
6972 if ((fwrq->m >= (int) 2.412e8 && 6943 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
6973 fwrq->m <= (int) 2.487e8)) {
6974 int f = fwrq->m / 100000; 6944 int f = fwrq->m / 100000;
6975 int c = 0; 6945 int c = 0;
6976 6946
@@ -6984,19 +6954,19 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6984 } 6954 }
6985 } 6955 }
6986 6956
6987 if (fwrq->e > 0 || fwrq->m > 1000) 6957 if (fwrq->e > 0 || fwrq->m > 1000) {
6988 return -EOPNOTSUPP; 6958 err = -EOPNOTSUPP;
6989 else { /* Set the channel */ 6959 goto done;
6960 } else { /* Set the channel */
6990 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6961 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6991 err = ipw2100_set_channel(priv, fwrq->m, 0); 6962 err = ipw2100_set_channel(priv, fwrq->m, 0);
6992 } 6963 }
6993 6964
6994 done: 6965 done:
6995 up(&priv->action_sem); 6966 up(&priv->action_sem);
6996 return err; 6967 return err;
6997} 6968}
6998 6969
6999
7000static int ipw2100_wx_get_freq(struct net_device *dev, 6970static int ipw2100_wx_get_freq(struct net_device *dev,
7001 struct iw_request_info *info, 6971 struct iw_request_info *info,
7002 union iwreq_data *wrqu, char *extra) 6972 union iwreq_data *wrqu, char *extra)
@@ -7045,7 +7015,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7045 case IW_MODE_MONITOR: 7015 case IW_MODE_MONITOR:
7046 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR); 7016 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7047 break; 7017 break;
7048#endif /* CONFIG_IPW2100_MONITOR */ 7018#endif /* CONFIG_IPW2100_MONITOR */
7049 case IW_MODE_ADHOC: 7019 case IW_MODE_ADHOC:
7050 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC); 7020 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7051 break; 7021 break;
@@ -7056,9 +7026,9 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7056 break; 7026 break;
7057 } 7027 }
7058 7028
7059done: 7029 done:
7060 up(&priv->action_sem); 7030 up(&priv->action_sem);
7061 return err; 7031 return err;
7062} 7032}
7063 7033
7064static int ipw2100_wx_get_mode(struct net_device *dev, 7034static int ipw2100_wx_get_mode(struct net_device *dev,
@@ -7077,7 +7047,6 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
7077 return 0; 7047 return 0;
7078} 7048}
7079 7049
7080
7081#define POWER_MODES 5 7050#define POWER_MODES 5
7082 7051
7083/* Values are in microsecond */ 7052/* Values are in microsecond */
@@ -7124,19 +7093,19 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7124 /* ~5 Mb/s real (802.11b) */ 7093 /* ~5 Mb/s real (802.11b) */
7125 range->throughput = 5 * 1000 * 1000; 7094 range->throughput = 5 * 1000 * 1000;
7126 7095
7127// range->sensitivity; /* signal level threshold range */ 7096// range->sensitivity; /* signal level threshold range */
7128 7097
7129 range->max_qual.qual = 100; 7098 range->max_qual.qual = 100;
7130 /* TODO: Find real max RSSI and stick here */ 7099 /* TODO: Find real max RSSI and stick here */
7131 range->max_qual.level = 0; 7100 range->max_qual.level = 0;
7132 range->max_qual.noise = 0; 7101 range->max_qual.noise = 0;
7133 range->max_qual.updated = 7; /* Updated all three */ 7102 range->max_qual.updated = 7; /* Updated all three */
7134 7103
7135 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ 7104 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7136 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 7105 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7137 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; 7106 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7138 range->avg_qual.noise = 0; 7107 range->avg_qual.noise = 0;
7139 range->avg_qual.updated = 7; /* Updated all three */ 7108 range->avg_qual.updated = 7; /* Updated all three */
7140 7109
7141 range->num_bitrates = RATE_COUNT; 7110 range->num_bitrates = RATE_COUNT;
7142 7111
@@ -7150,61 +7119,62 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7150 range->max_frag = MAX_FRAG_THRESHOLD; 7119 range->max_frag = MAX_FRAG_THRESHOLD;
7151 7120
7152 range->min_pmp = period_duration[0]; /* Minimal PM period */ 7121 range->min_pmp = period_duration[0]; /* Minimal PM period */
7153 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */ 7122 range->max_pmp = period_duration[POWER_MODES - 1]; /* Maximal PM period */
7154 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */ 7123 range->min_pmt = timeout_duration[POWER_MODES - 1]; /* Minimal PM timeout */
7155 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */ 7124 range->max_pmt = timeout_duration[0]; /* Maximal PM timeout */
7156 7125
7157 /* How to decode max/min PM period */ 7126 /* How to decode max/min PM period */
7158 range->pmp_flags = IW_POWER_PERIOD; 7127 range->pmp_flags = IW_POWER_PERIOD;
7159 /* How to decode max/min PM period */ 7128 /* How to decode max/min PM period */
7160 range->pmt_flags = IW_POWER_TIMEOUT; 7129 range->pmt_flags = IW_POWER_TIMEOUT;
7161 /* What PM options are supported */ 7130 /* What PM options are supported */
7162 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD; 7131 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7163 7132
7164 range->encoding_size[0] = 5; 7133 range->encoding_size[0] = 5;
7165 range->encoding_size[1] = 13; /* Different token sizes */ 7134 range->encoding_size[1] = 13; /* Different token sizes */
7166 range->num_encoding_sizes = 2; /* Number of entry in the list */ 7135 range->num_encoding_sizes = 2; /* Number of entry in the list */
7167 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */ 7136 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7168// range->encoding_login_index; /* token index for login token */ 7137// range->encoding_login_index; /* token index for login token */
7169 7138
7170 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7139 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7171 range->txpower_capa = IW_TXPOW_DBM; 7140 range->txpower_capa = IW_TXPOW_DBM;
7172 range->num_txpower = IW_MAX_TXPOWER; 7141 range->num_txpower = IW_MAX_TXPOWER;
7173 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER; 7142 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16);
7174 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) / 7143 i < IW_MAX_TXPOWER;
7175 (IW_MAX_TXPOWER - 1)) 7144 i++, level -=
7145 ((IPW_TX_POWER_MAX_DBM -
7146 IPW_TX_POWER_MIN_DBM) * 16) / (IW_MAX_TXPOWER - 1))
7176 range->txpower[i] = level / 16; 7147 range->txpower[i] = level / 16;
7177 } else { 7148 } else {
7178 range->txpower_capa = 0; 7149 range->txpower_capa = 0;
7179 range->num_txpower = 0; 7150 range->num_txpower = 0;
7180 } 7151 }
7181 7152
7182
7183 /* Set the Wireless Extension versions */ 7153 /* Set the Wireless Extension versions */
7184 range->we_version_compiled = WIRELESS_EXT; 7154 range->we_version_compiled = WIRELESS_EXT;
7185 range->we_version_source = 16; 7155 range->we_version_source = 16;
7186 7156
7187// range->retry_capa; /* What retry options are supported */ 7157// range->retry_capa; /* What retry options are supported */
7188// range->retry_flags; /* How to decode max/min retry limit */ 7158// range->retry_flags; /* How to decode max/min retry limit */
7189// range->r_time_flags; /* How to decode max/min retry life */ 7159// range->r_time_flags; /* How to decode max/min retry life */
7190// range->min_retry; /* Minimal number of retries */ 7160// range->min_retry; /* Minimal number of retries */
7191// range->max_retry; /* Maximal number of retries */ 7161// range->max_retry; /* Maximal number of retries */
7192// range->min_r_time; /* Minimal retry lifetime */ 7162// range->min_r_time; /* Minimal retry lifetime */
7193// range->max_r_time; /* Maximal retry lifetime */ 7163// range->max_r_time; /* Maximal retry lifetime */
7194 7164
7195 range->num_channels = FREQ_COUNT; 7165 range->num_channels = FREQ_COUNT;
7196 7166
7197 val = 0; 7167 val = 0;
7198 for (i = 0; i < FREQ_COUNT; i++) { 7168 for (i = 0; i < FREQ_COUNT; i++) {
7199 // TODO: Include only legal frequencies for some countries 7169 // TODO: Include only legal frequencies for some countries
7200// if (local->channel_mask & (1 << i)) { 7170// if (local->channel_mask & (1 << i)) {
7201 range->freq[val].i = i + 1; 7171 range->freq[val].i = i + 1;
7202 range->freq[val].m = ipw2100_frequencies[i] * 100000; 7172 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7203 range->freq[val].e = 1; 7173 range->freq[val].e = 1;
7204 val++; 7174 val++;
7205// } 7175// }
7206 if (val == IW_MAX_FREQUENCIES) 7176 if (val == IW_MAX_FREQUENCIES)
7207 break; 7177 break;
7208 } 7178 }
7209 range->num_frequency = val; 7179 range->num_frequency = val;
7210 7180
@@ -7259,7 +7229,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
7259 wrqu->ap_addr.sa_data[4] & 0xff, 7229 wrqu->ap_addr.sa_data[4] & 0xff,
7260 wrqu->ap_addr.sa_data[5] & 0xff); 7230 wrqu->ap_addr.sa_data[5] & 0xff);
7261 7231
7262 done: 7232 done:
7263 up(&priv->action_sem); 7233 up(&priv->action_sem);
7264 return err; 7234 return err;
7265} 7235}
@@ -7276,10 +7246,9 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
7276 7246
7277 /* If we are associated, trying to associate, or have a statically 7247 /* If we are associated, trying to associate, or have a statically
7278 * configured BSSID then return that; otherwise return ANY */ 7248 * configured BSSID then return that; otherwise return ANY */
7279 if (priv->config & CFG_STATIC_BSSID || 7249 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
7280 priv->status & STATUS_ASSOCIATED) {
7281 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 7250 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7282 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 7251 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
7283 } else 7252 } else
7284 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 7253 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7285 7254
@@ -7293,7 +7262,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7293 union iwreq_data *wrqu, char *extra) 7262 union iwreq_data *wrqu, char *extra)
7294{ 7263{
7295 struct ipw2100_priv *priv = ieee80211_priv(dev); 7264 struct ipw2100_priv *priv = ieee80211_priv(dev);
7296 char *essid = ""; /* ANY */ 7265 char *essid = ""; /* ANY */
7297 int length = 0; 7266 int length = 0;
7298 int err = 0; 7267 int err = 0;
7299 7268
@@ -7333,7 +7302,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7333 7302
7334 err = ipw2100_set_essid(priv, essid, length, 0); 7303 err = ipw2100_set_essid(priv, essid, length, 0);
7335 7304
7336 done: 7305 done:
7337 up(&priv->action_sem); 7306 up(&priv->action_sem);
7338 return err; 7307 return err;
7339} 7308}
@@ -7350,17 +7319,16 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
7350 7319
7351 /* If we are associated, trying to associate, or have a statically 7320 /* If we are associated, trying to associate, or have a statically
7352 * configured ESSID then return that; otherwise return ANY */ 7321 * configured ESSID then return that; otherwise return ANY */
7353 if (priv->config & CFG_STATIC_ESSID || 7322 if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
7354 priv->status & STATUS_ASSOCIATED) {
7355 IPW_DEBUG_WX("Getting essid: '%s'\n", 7323 IPW_DEBUG_WX("Getting essid: '%s'\n",
7356 escape_essid(priv->essid, priv->essid_len)); 7324 escape_essid(priv->essid, priv->essid_len));
7357 memcpy(extra, priv->essid, priv->essid_len); 7325 memcpy(extra, priv->essid, priv->essid_len);
7358 wrqu->essid.length = priv->essid_len; 7326 wrqu->essid.length = priv->essid_len;
7359 wrqu->essid.flags = 1; /* active */ 7327 wrqu->essid.flags = 1; /* active */
7360 } else { 7328 } else {
7361 IPW_DEBUG_WX("Getting essid: ANY\n"); 7329 IPW_DEBUG_WX("Getting essid: ANY\n");
7362 wrqu->essid.length = 0; 7330 wrqu->essid.length = 0;
7363 wrqu->essid.flags = 0; /* active */ 7331 wrqu->essid.flags = 0; /* active */
7364 } 7332 }
7365 7333
7366 return 0; 7334 return 0;
@@ -7379,9 +7347,9 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7379 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 7347 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7380 return -E2BIG; 7348 return -E2BIG;
7381 7349
7382 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick)); 7350 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
7383 memset(priv->nick, 0, sizeof(priv->nick)); 7351 memset(priv->nick, 0, sizeof(priv->nick));
7384 memcpy(priv->nick, extra, wrqu->data.length); 7352 memcpy(priv->nick, extra, wrqu->data.length);
7385 7353
7386 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7354 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7387 7355
@@ -7400,7 +7368,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7400 7368
7401 wrqu->data.length = strlen(priv->nick) + 1; 7369 wrqu->data.length = strlen(priv->nick) + 1;
7402 memcpy(extra, priv->nick, wrqu->data.length); 7370 memcpy(extra, priv->nick, wrqu->data.length);
7403 wrqu->data.flags = 1; /* active */ 7371 wrqu->data.flags = 1; /* active */
7404 7372
7405 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7373 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7406 7374
@@ -7442,12 +7410,11 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7442 err = ipw2100_set_tx_rates(priv, rate, 0); 7410 err = ipw2100_set_tx_rates(priv, rate, 0);
7443 7411
7444 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7412 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7445 done: 7413 done:
7446 up(&priv->action_sem); 7414 up(&priv->action_sem);
7447 return err; 7415 return err;
7448} 7416}
7449 7417
7450
7451static int ipw2100_wx_get_rate(struct net_device *dev, 7418static int ipw2100_wx_get_rate(struct net_device *dev,
7452 struct iw_request_info *info, 7419 struct iw_request_info *info,
7453 union iwreq_data *wrqu, char *extra) 7420 union iwreq_data *wrqu, char *extra)
@@ -7495,7 +7462,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7495 7462
7496 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7463 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7497 7464
7498 done: 7465 done:
7499 up(&priv->action_sem); 7466 up(&priv->action_sem);
7500 return err; 7467 return err;
7501} 7468}
@@ -7520,8 +7487,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7520 if (wrqu->rts.disabled) 7487 if (wrqu->rts.disabled)
7521 value = priv->rts_threshold | RTS_DISABLED; 7488 value = priv->rts_threshold | RTS_DISABLED;
7522 else { 7489 else {
7523 if (wrqu->rts.value < 1 || 7490 if (wrqu->rts.value < 1 || wrqu->rts.value > 2304) {
7524 wrqu->rts.value > 2304) {
7525 err = -EINVAL; 7491 err = -EINVAL;
7526 goto done; 7492 goto done;
7527 } 7493 }
@@ -7531,7 +7497,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7531 err = ipw2100_set_rts_threshold(priv, value); 7497 err = ipw2100_set_rts_threshold(priv, value);
7532 7498
7533 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7499 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7534 done: 7500 done:
7535 up(&priv->action_sem); 7501 up(&priv->action_sem);
7536 return err; 7502 return err;
7537} 7503}
@@ -7547,7 +7513,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7547 struct ipw2100_priv *priv = ieee80211_priv(dev); 7513 struct ipw2100_priv *priv = ieee80211_priv(dev);
7548 7514
7549 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED; 7515 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7550 wrqu->rts.fixed = 1; /* no auto select */ 7516 wrqu->rts.fixed = 1; /* no auto select */
7551 7517
7552 /* If RTS is set to the default value, then it is disabled */ 7518 /* If RTS is set to the default value, then it is disabled */
7553 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7519 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
@@ -7574,8 +7540,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7574 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM) 7540 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7575 return -EINVAL; 7541 return -EINVAL;
7576 7542
7577 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 / 7543 value = wrqu->txpower.value;
7578 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7579 } 7544 }
7580 7545
7581 down(&priv->action_sem); 7546 down(&priv->action_sem);
@@ -7588,7 +7553,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7588 7553
7589 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7554 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7590 7555
7591 done: 7556 done:
7592 up(&priv->action_sem); 7557 up(&priv->action_sem);
7593 return err; 7558 return err;
7594} 7559}
@@ -7615,11 +7580,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7615 } else { 7580 } else {
7616 wrqu->power.disabled = 0; 7581 wrqu->power.disabled = 0;
7617 wrqu->power.fixed = 1; 7582 wrqu->power.fixed = 1;
7618 wrqu->power.value = 7583 wrqu->power.value = priv->tx_power;
7619 (priv->tx_power *
7620 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7621 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7622 IPW_TX_POWER_MIN_DBM;
7623 } 7584 }
7624 7585
7625 wrqu->power.flags = IW_TXPOW_DBM; 7586 wrqu->power.flags = IW_TXPOW_DBM;
@@ -7684,8 +7645,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7684 struct ipw2100_priv *priv = ieee80211_priv(dev); 7645 struct ipw2100_priv *priv = ieee80211_priv(dev);
7685 int err = 0; 7646 int err = 0;
7686 7647
7687 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 7648 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
7688 wrqu->retry.disabled)
7689 return -EINVAL; 7649 return -EINVAL;
7690 7650
7691 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 7651 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
@@ -7700,14 +7660,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7700 if (wrqu->retry.flags & IW_RETRY_MIN) { 7660 if (wrqu->retry.flags & IW_RETRY_MIN) {
7701 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7661 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7702 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7662 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7703 wrqu->retry.value); 7663 wrqu->retry.value);
7704 goto done; 7664 goto done;
7705 } 7665 }
7706 7666
7707 if (wrqu->retry.flags & IW_RETRY_MAX) { 7667 if (wrqu->retry.flags & IW_RETRY_MAX) {
7708 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7668 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7709 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7669 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7710 wrqu->retry.value); 7670 wrqu->retry.value);
7711 goto done; 7671 goto done;
7712 } 7672 }
7713 7673
@@ -7717,7 +7677,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7717 7677
7718 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7678 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7719 7679
7720 done: 7680 done:
7721 up(&priv->action_sem); 7681 up(&priv->action_sem);
7722 return err; 7682 return err;
7723} 7683}
@@ -7732,20 +7692,19 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7732 7692
7733 struct ipw2100_priv *priv = ieee80211_priv(dev); 7693 struct ipw2100_priv *priv = ieee80211_priv(dev);
7734 7694
7735 wrqu->retry.disabled = 0; /* can't be disabled */ 7695 wrqu->retry.disabled = 0; /* can't be disabled */
7736 7696
7737 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 7697 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
7738 IW_RETRY_LIFETIME)
7739 return -EINVAL; 7698 return -EINVAL;
7740 7699
7741 if (wrqu->retry.flags & IW_RETRY_MAX) { 7700 if (wrqu->retry.flags & IW_RETRY_MAX) {
7742 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 7701 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
7743 wrqu->retry.value = priv->long_retry_limit; 7702 wrqu->retry.value = priv->long_retry_limit;
7744 } else { 7703 } else {
7745 wrqu->retry.flags = 7704 wrqu->retry.flags =
7746 (priv->short_retry_limit != 7705 (priv->short_retry_limit !=
7747 priv->long_retry_limit) ? 7706 priv->long_retry_limit) ?
7748 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT; 7707 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
7749 7708
7750 wrqu->retry.value = priv->short_retry_limit; 7709 wrqu->retry.value = priv->short_retry_limit;
7751 } 7710 }
@@ -7769,15 +7728,14 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7769 } 7728 }
7770 7729
7771 IPW_DEBUG_WX("Initiating scan...\n"); 7730 IPW_DEBUG_WX("Initiating scan...\n");
7772 if (ipw2100_set_scan_options(priv) || 7731 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7773 ipw2100_start_scan(priv)) {
7774 IPW_DEBUG_WX("Start scan failed.\n"); 7732 IPW_DEBUG_WX("Start scan failed.\n");
7775 7733
7776 /* TODO: Mark a scan as pending so when hardware initialized 7734 /* TODO: Mark a scan as pending so when hardware initialized
7777 * a scan starts */ 7735 * a scan starts */
7778 } 7736 }
7779 7737
7780 done: 7738 done:
7781 up(&priv->action_sem); 7739 up(&priv->action_sem);
7782 return err; 7740 return err;
7783} 7741}
@@ -7794,7 +7752,6 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
7794 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra); 7752 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7795} 7753}
7796 7754
7797
7798/* 7755/*
7799 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c 7756 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7800 */ 7757 */
@@ -7823,8 +7780,8 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
7823} 7780}
7824 7781
7825static int ipw2100_wx_set_power(struct net_device *dev, 7782static int ipw2100_wx_set_power(struct net_device *dev,
7826 struct iw_request_info *info, 7783 struct iw_request_info *info,
7827 union iwreq_data *wrqu, char *extra) 7784 union iwreq_data *wrqu, char *extra)
7828{ 7785{
7829 struct ipw2100_priv *priv = ieee80211_priv(dev); 7786 struct ipw2100_priv *priv = ieee80211_priv(dev);
7830 int err = 0; 7787 int err = 0;
@@ -7843,11 +7800,11 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7843 } 7800 }
7844 7801
7845 switch (wrqu->power.flags & IW_POWER_MODE) { 7802 switch (wrqu->power.flags & IW_POWER_MODE) {
7846 case IW_POWER_ON: /* If not specified */ 7803 case IW_POWER_ON: /* If not specified */
7847 case IW_POWER_MODE: /* If set all mask */ 7804 case IW_POWER_MODE: /* If set all mask */
7848 case IW_POWER_ALL_R: /* If explicitely state all */ 7805 case IW_POWER_ALL_R: /* If explicitely state all */
7849 break; 7806 break;
7850 default: /* Otherwise we don't support it */ 7807 default: /* Otherwise we don't support it */
7851 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 7808 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7852 wrqu->power.flags); 7809 wrqu->power.flags);
7853 err = -EOPNOTSUPP; 7810 err = -EOPNOTSUPP;
@@ -7859,18 +7816,17 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7859 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; 7816 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7860 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 7817 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7861 7818
7862 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", 7819 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
7863 priv->power_mode);
7864 7820
7865 done: 7821 done:
7866 up(&priv->action_sem); 7822 up(&priv->action_sem);
7867 return err; 7823 return err;
7868 7824
7869} 7825}
7870 7826
7871static int ipw2100_wx_get_power(struct net_device *dev, 7827static int ipw2100_wx_get_power(struct net_device *dev,
7872 struct iw_request_info *info, 7828 struct iw_request_info *info,
7873 union iwreq_data *wrqu, char *extra) 7829 union iwreq_data *wrqu, char *extra)
7874{ 7830{
7875 /* 7831 /*
7876 * This can be called at any time. No action lock required 7832 * This can be called at any time. No action lock required
@@ -7878,9 +7834,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7878 7834
7879 struct ipw2100_priv *priv = ieee80211_priv(dev); 7835 struct ipw2100_priv *priv = ieee80211_priv(dev);
7880 7836
7881 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7837 if (!(priv->power_mode & IPW_POWER_ENABLED))
7882 wrqu->power.disabled = 1; 7838 wrqu->power.disabled = 1;
7883 } else { 7839 else {
7884 wrqu->power.disabled = 0; 7840 wrqu->power.disabled = 0;
7885 wrqu->power.flags = 0; 7841 wrqu->power.flags = 0;
7886 } 7842 }
@@ -7890,6 +7846,269 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7890 return 0; 7846 return 0;
7891} 7847}
7892 7848
7849#if WIRELESS_EXT > 17
7850/*
7851 * WE-18 WPA support
7852 */
7853
7854/* SIOCSIWGENIE */
7855static int ipw2100_wx_set_genie(struct net_device *dev,
7856 struct iw_request_info *info,
7857 union iwreq_data *wrqu, char *extra)
7858{
7859
7860 struct ipw2100_priv *priv = ieee80211_priv(dev);
7861 struct ieee80211_device *ieee = priv->ieee;
7862 u8 *buf;
7863
7864 if (!ieee->wpa_enabled)
7865 return -EOPNOTSUPP;
7866
7867 if (wrqu->data.length > MAX_WPA_IE_LEN ||
7868 (wrqu->data.length && extra == NULL))
7869 return -EINVAL;
7870
7871 if (wrqu->data.length) {
7872 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
7873 if (buf == NULL)
7874 return -ENOMEM;
7875
7876 memcpy(buf, extra, wrqu->data.length);
7877 kfree(ieee->wpa_ie);
7878 ieee->wpa_ie = buf;
7879 ieee->wpa_ie_len = wrqu->data.length;
7880 } else {
7881 kfree(ieee->wpa_ie);
7882 ieee->wpa_ie = NULL;
7883 ieee->wpa_ie_len = 0;
7884 }
7885
7886 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
7887
7888 return 0;
7889}
7890
7891/* SIOCGIWGENIE */
7892static int ipw2100_wx_get_genie(struct net_device *dev,
7893 struct iw_request_info *info,
7894 union iwreq_data *wrqu, char *extra)
7895{
7896 struct ipw2100_priv *priv = ieee80211_priv(dev);
7897 struct ieee80211_device *ieee = priv->ieee;
7898
7899 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
7900 wrqu->data.length = 0;
7901 return 0;
7902 }
7903
7904 if (wrqu->data.length < ieee->wpa_ie_len)
7905 return -E2BIG;
7906
7907 wrqu->data.length = ieee->wpa_ie_len;
7908 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
7909
7910 return 0;
7911}
7912
7913/* SIOCSIWAUTH */
7914static int ipw2100_wx_set_auth(struct net_device *dev,
7915 struct iw_request_info *info,
7916 union iwreq_data *wrqu, char *extra)
7917{
7918 struct ipw2100_priv *priv = ieee80211_priv(dev);
7919 struct ieee80211_device *ieee = priv->ieee;
7920 struct iw_param *param = &wrqu->param;
7921 struct ieee80211_crypt_data *crypt;
7922 unsigned long flags;
7923 int ret = 0;
7924
7925 switch (param->flags & IW_AUTH_INDEX) {
7926 case IW_AUTH_WPA_VERSION:
7927 case IW_AUTH_CIPHER_PAIRWISE:
7928 case IW_AUTH_CIPHER_GROUP:
7929 case IW_AUTH_KEY_MGMT:
7930 /*
7931 * ipw2200 does not use these parameters
7932 */
7933 break;
7934
7935 case IW_AUTH_TKIP_COUNTERMEASURES:
7936 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
7937 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
7938 break;
7939
7940 flags = crypt->ops->get_flags(crypt->priv);
7941
7942 if (param->value)
7943 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7944 else
7945 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7946
7947 crypt->ops->set_flags(flags, crypt->priv);
7948
7949 break;
7950
7951 case IW_AUTH_DROP_UNENCRYPTED:{
7952 /* HACK:
7953 *
7954 * wpa_supplicant calls set_wpa_enabled when the driver
7955 * is loaded and unloaded, regardless of if WPA is being
7956 * used. No other calls are made which can be used to
7957 * determine if encryption will be used or not prior to
7958 * association being expected. If encryption is not being
7959 * used, drop_unencrypted is set to false, else true -- we
7960 * can use this to determine if the CAP_PRIVACY_ON bit should
7961 * be set.
7962 */
7963 struct ieee80211_security sec = {
7964 .flags = SEC_ENABLED,
7965 .enabled = param->value,
7966 };
7967 priv->ieee->drop_unencrypted = param->value;
7968 /* We only change SEC_LEVEL for open mode. Others
7969 * are set by ipw_wpa_set_encryption.
7970 */
7971 if (!param->value) {
7972 sec.flags |= SEC_LEVEL;
7973 sec.level = SEC_LEVEL_0;
7974 } else {
7975 sec.flags |= SEC_LEVEL;
7976 sec.level = SEC_LEVEL_1;
7977 }
7978 if (priv->ieee->set_security)
7979 priv->ieee->set_security(priv->ieee->dev, &sec);
7980 break;
7981 }
7982
7983 case IW_AUTH_80211_AUTH_ALG:
7984 ret = ipw2100_wpa_set_auth_algs(priv, param->value);
7985 break;
7986
7987 case IW_AUTH_WPA_ENABLED:
7988 ret = ipw2100_wpa_enable(priv, param->value);
7989 break;
7990
7991 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
7992 ieee->ieee802_1x = param->value;
7993 break;
7994
7995 //case IW_AUTH_ROAMING_CONTROL:
7996 case IW_AUTH_PRIVACY_INVOKED:
7997 ieee->privacy_invoked = param->value;
7998 break;
7999
8000 default:
8001 return -EOPNOTSUPP;
8002 }
8003 return ret;
8004}
8005
8006/* SIOCGIWAUTH */
8007static int ipw2100_wx_get_auth(struct net_device *dev,
8008 struct iw_request_info *info,
8009 union iwreq_data *wrqu, char *extra)
8010{
8011 struct ipw2100_priv *priv = ieee80211_priv(dev);
8012 struct ieee80211_device *ieee = priv->ieee;
8013 struct ieee80211_crypt_data *crypt;
8014 struct iw_param *param = &wrqu->param;
8015 int ret = 0;
8016
8017 switch (param->flags & IW_AUTH_INDEX) {
8018 case IW_AUTH_WPA_VERSION:
8019 case IW_AUTH_CIPHER_PAIRWISE:
8020 case IW_AUTH_CIPHER_GROUP:
8021 case IW_AUTH_KEY_MGMT:
8022 /*
8023 * wpa_supplicant will control these internally
8024 */
8025 ret = -EOPNOTSUPP;
8026 break;
8027
8028 case IW_AUTH_TKIP_COUNTERMEASURES:
8029 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
8030 if (!crypt || !crypt->ops->get_flags) {
8031 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
8032 "crypt not set!\n");
8033 break;
8034 }
8035
8036 param->value = (crypt->ops->get_flags(crypt->priv) &
8037 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
8038
8039 break;
8040
8041 case IW_AUTH_DROP_UNENCRYPTED:
8042 param->value = ieee->drop_unencrypted;
8043 break;
8044
8045 case IW_AUTH_80211_AUTH_ALG:
8046 param->value = priv->ieee->sec.auth_mode;
8047 break;
8048
8049 case IW_AUTH_WPA_ENABLED:
8050 param->value = ieee->wpa_enabled;
8051 break;
8052
8053 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
8054 param->value = ieee->ieee802_1x;
8055 break;
8056
8057 case IW_AUTH_ROAMING_CONTROL:
8058 case IW_AUTH_PRIVACY_INVOKED:
8059 param->value = ieee->privacy_invoked;
8060 break;
8061
8062 default:
8063 return -EOPNOTSUPP;
8064 }
8065 return 0;
8066}
8067
8068/* SIOCSIWENCODEEXT */
8069static int ipw2100_wx_set_encodeext(struct net_device *dev,
8070 struct iw_request_info *info,
8071 union iwreq_data *wrqu, char *extra)
8072{
8073 struct ipw2100_priv *priv = ieee80211_priv(dev);
8074 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
8075}
8076
8077/* SIOCGIWENCODEEXT */
8078static int ipw2100_wx_get_encodeext(struct net_device *dev,
8079 struct iw_request_info *info,
8080 union iwreq_data *wrqu, char *extra)
8081{
8082 struct ipw2100_priv *priv = ieee80211_priv(dev);
8083 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
8084}
8085
8086/* SIOCSIWMLME */
8087static int ipw2100_wx_set_mlme(struct net_device *dev,
8088 struct iw_request_info *info,
8089 union iwreq_data *wrqu, char *extra)
8090{
8091 struct ipw2100_priv *priv = ieee80211_priv(dev);
8092 struct iw_mlme *mlme = (struct iw_mlme *)extra;
8093 u16 reason;
8094
8095 reason = cpu_to_le16(mlme->reason_code);
8096
8097 switch (mlme->cmd) {
8098 case IW_MLME_DEAUTH:
8099 // silently ignore
8100 break;
8101
8102 case IW_MLME_DISASSOC:
8103 ipw2100_disassociate_bssid(priv);
8104 break;
8105
8106 default:
8107 return -EOPNOTSUPP;
8108 }
8109 return 0;
8110}
8111#endif /* WIRELESS_EXT > 17 */
7893 8112
7894/* 8113/*
7895 * 8114 *
@@ -7923,7 +8142,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7923 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8142 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7924 err = ipw2100_switch_mode(priv, priv->last_mode); 8143 err = ipw2100_switch_mode(priv, priv->last_mode);
7925 } 8144 }
7926 done: 8145 done:
7927 up(&priv->action_sem); 8146 up(&priv->action_sem);
7928 return err; 8147 return err;
7929} 8148}
@@ -7958,7 +8177,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7958 8177
7959 if (priv->power_mode != mode) 8178 if (priv->power_mode != mode)
7960 err = ipw2100_set_power_mode(priv, mode); 8179 err = ipw2100_set_power_mode(priv, mode);
7961 done: 8180 done:
7962 up(&priv->action_sem); 8181 up(&priv->action_sem);
7963 return err; 8182 return err;
7964} 8183}
@@ -7986,8 +8205,8 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
7986 "Power save level: %d (None)", level); 8205 "Power save level: %d (None)", level);
7987 break; 8206 break;
7988 case IPW_POWER_AUTO: 8207 case IPW_POWER_AUTO:
7989 snprintf(extra, MAX_POWER_STRING, 8208 snprintf(extra, MAX_POWER_STRING,
7990 "Power save level: %d (Auto)", 0); 8209 "Power save level: %d (Auto)", 0);
7991 break; 8210 break;
7992 default: 8211 default:
7993 timeout = timeout_duration[level - 1] / 1000; 8212 timeout = timeout_duration[level - 1] / 1000;
@@ -8004,7 +8223,6 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
8004 return 0; 8223 return 0;
8005} 8224}
8006 8225
8007
8008static int ipw2100_wx_set_preamble(struct net_device *dev, 8226static int ipw2100_wx_set_preamble(struct net_device *dev,
8009 struct iw_request_info *info, 8227 struct iw_request_info *info,
8010 union iwreq_data *wrqu, char *extra) 8228 union iwreq_data *wrqu, char *extra)
@@ -8029,14 +8247,14 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
8029 8247
8030 err = ipw2100_system_config(priv, 0); 8248 err = ipw2100_system_config(priv, 0);
8031 8249
8032done: 8250 done:
8033 up(&priv->action_sem); 8251 up(&priv->action_sem);
8034 return err; 8252 return err;
8035} 8253}
8036 8254
8037static int ipw2100_wx_get_preamble(struct net_device *dev, 8255static int ipw2100_wx_get_preamble(struct net_device *dev,
8038 struct iw_request_info *info, 8256 struct iw_request_info *info,
8039 union iwreq_data *wrqu, char *extra) 8257 union iwreq_data *wrqu, char *extra)
8040{ 8258{
8041 /* 8259 /*
8042 * This can be called at any time. No action lock required 8260 * This can be called at any time. No action lock required
@@ -8052,54 +8270,116 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
8052 return 0; 8270 return 0;
8053} 8271}
8054 8272
8055static iw_handler ipw2100_wx_handlers[] = 8273#ifdef CONFIG_IPW2100_MONITOR
8056{ 8274static int ipw2100_wx_set_crc_check(struct net_device *dev,
8057 NULL, /* SIOCSIWCOMMIT */ 8275 struct iw_request_info *info,
8058 ipw2100_wx_get_name, /* SIOCGIWNAME */ 8276 union iwreq_data *wrqu, char *extra)
8059 NULL, /* SIOCSIWNWID */ 8277{
8060 NULL, /* SIOCGIWNWID */ 8278 struct ipw2100_priv *priv = ieee80211_priv(dev);
8061 ipw2100_wx_set_freq, /* SIOCSIWFREQ */ 8279 int err, mode = *(int *)extra;
8062 ipw2100_wx_get_freq, /* SIOCGIWFREQ */ 8280
8063 ipw2100_wx_set_mode, /* SIOCSIWMODE */ 8281 down(&priv->action_sem);
8064 ipw2100_wx_get_mode, /* SIOCGIWMODE */ 8282 if (!(priv->status & STATUS_INITIALIZED)) {
8065 NULL, /* SIOCSIWSENS */ 8283 err = -EIO;
8066 NULL, /* SIOCGIWSENS */ 8284 goto done;
8067 NULL, /* SIOCSIWRANGE */ 8285 }
8068 ipw2100_wx_get_range, /* SIOCGIWRANGE */ 8286
8069 NULL, /* SIOCSIWPRIV */ 8287 if (mode == 1)
8070 NULL, /* SIOCGIWPRIV */ 8288 priv->config |= CFG_CRC_CHECK;
8071 NULL, /* SIOCSIWSTATS */ 8289 else if (mode == 0)
8072 NULL, /* SIOCGIWSTATS */ 8290 priv->config &= ~CFG_CRC_CHECK;
8073 NULL, /* SIOCSIWSPY */ 8291 else {
8074 NULL, /* SIOCGIWSPY */ 8292 err = -EINVAL;
8075 NULL, /* SIOCGIWTHRSPY */ 8293 goto done;
8076 NULL, /* SIOCWIWTHRSPY */ 8294 }
8077 ipw2100_wx_set_wap, /* SIOCSIWAP */ 8295 err = 0;
8078 ipw2100_wx_get_wap, /* SIOCGIWAP */ 8296
8079 NULL, /* -- hole -- */ 8297 done:
8080 NULL, /* SIOCGIWAPLIST -- deprecated */ 8298 up(&priv->action_sem);
8081 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 8299 return err;
8082 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 8300}
8083 ipw2100_wx_set_essid, /* SIOCSIWESSID */ 8301
8084 ipw2100_wx_get_essid, /* SIOCGIWESSID */ 8302static int ipw2100_wx_get_crc_check(struct net_device *dev,
8085 ipw2100_wx_set_nick, /* SIOCSIWNICKN */ 8303 struct iw_request_info *info,
8086 ipw2100_wx_get_nick, /* SIOCGIWNICKN */ 8304 union iwreq_data *wrqu, char *extra)
8087 NULL, /* -- hole -- */ 8305{
8088 NULL, /* -- hole -- */ 8306 /*
8089 ipw2100_wx_set_rate, /* SIOCSIWRATE */ 8307 * This can be called at any time. No action lock required
8090 ipw2100_wx_get_rate, /* SIOCGIWRATE */ 8308 */
8091 ipw2100_wx_set_rts, /* SIOCSIWRTS */ 8309
8092 ipw2100_wx_get_rts, /* SIOCGIWRTS */ 8310 struct ipw2100_priv *priv = ieee80211_priv(dev);
8093 ipw2100_wx_set_frag, /* SIOCSIWFRAG */ 8311
8094 ipw2100_wx_get_frag, /* SIOCGIWFRAG */ 8312 if (priv->config & CFG_CRC_CHECK)
8095 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */ 8313 snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
8096 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */ 8314 else
8097 ipw2100_wx_set_retry, /* SIOCSIWRETRY */ 8315 snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
8098 ipw2100_wx_get_retry, /* SIOCGIWRETRY */ 8316
8099 ipw2100_wx_set_encode, /* SIOCSIWENCODE */ 8317 return 0;
8100 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 8318}
8101 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 8319#endif /* CONFIG_IPW2100_MONITOR */
8102 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 8320
8321static iw_handler ipw2100_wx_handlers[] = {
8322 NULL, /* SIOCSIWCOMMIT */
8323 ipw2100_wx_get_name, /* SIOCGIWNAME */
8324 NULL, /* SIOCSIWNWID */
8325 NULL, /* SIOCGIWNWID */
8326 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8327 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8328 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8329 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8330 NULL, /* SIOCSIWSENS */
8331 NULL, /* SIOCGIWSENS */
8332 NULL, /* SIOCSIWRANGE */
8333 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8334 NULL, /* SIOCSIWPRIV */
8335 NULL, /* SIOCGIWPRIV */
8336 NULL, /* SIOCSIWSTATS */
8337 NULL, /* SIOCGIWSTATS */
8338 NULL, /* SIOCSIWSPY */
8339 NULL, /* SIOCGIWSPY */
8340 NULL, /* SIOCGIWTHRSPY */
8341 NULL, /* SIOCWIWTHRSPY */
8342 ipw2100_wx_set_wap, /* SIOCSIWAP */
8343 ipw2100_wx_get_wap, /* SIOCGIWAP */
8344#if WIRELESS_EXT > 17
8345 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8346#else
8347 NULL, /* -- hole -- */
8348#endif
8349 NULL, /* SIOCGIWAPLIST -- deprecated */
8350 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8351 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8352 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8353 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8354 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8355 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8356 NULL, /* -- hole -- */
8357 NULL, /* -- hole -- */
8358 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8359 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8360 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8361 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8362 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8363 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8364 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8365 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8366 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8367 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8368 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8369 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8370 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8371 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8372#if WIRELESS_EXT > 17
8373 NULL, /* -- hole -- */
8374 NULL, /* -- hole -- */
8375 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
8376 ipw2100_wx_get_genie, /* SIOCGIWGENIE */
8377 ipw2100_wx_set_auth, /* SIOCSIWAUTH */
8378 ipw2100_wx_get_auth, /* SIOCGIWAUTH */
8379 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8380 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8381 NULL, /* SIOCSIWPMKSA */
8382#endif
8103}; 8383};
8104 8384
8105#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 8385#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8108,60 +8388,71 @@ static iw_handler ipw2100_wx_handlers[] =
8108#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3 8388#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8109#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4 8389#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8110#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5 8390#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8391#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
8392#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
8111 8393
8112static const struct iw_priv_args ipw2100_private_args[] = { 8394static const struct iw_priv_args ipw2100_private_args[] = {
8113 8395
8114#ifdef CONFIG_IPW2100_MONITOR 8396#ifdef CONFIG_IPW2100_MONITOR
8115 { 8397 {
8116 IPW2100_PRIV_SET_MONITOR, 8398 IPW2100_PRIV_SET_MONITOR,
8117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" 8399 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
8118 },
8119 { 8400 {
8120 IPW2100_PRIV_RESET, 8401 IPW2100_PRIV_RESET,
8121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" 8402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
8122 }, 8403#endif /* CONFIG_IPW2100_MONITOR */
8123#endif /* CONFIG_IPW2100_MONITOR */
8124 8404
8125 { 8405 {
8126 IPW2100_PRIV_SET_POWER, 8406 IPW2100_PRIV_SET_POWER,
8127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power" 8407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"},
8128 },
8129 { 8408 {
8130 IPW2100_PRIV_GET_POWER, 8409 IPW2100_PRIV_GET_POWER,
8131 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power" 8410 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING,
8132 }, 8411 "get_power"},
8133 { 8412 {
8134 IPW2100_PRIV_SET_LONGPREAMBLE, 8413 IPW2100_PRIV_SET_LONGPREAMBLE,
8135 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble" 8414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
8136 },
8137 { 8415 {
8138 IPW2100_PRIV_GET_LONGPREAMBLE, 8416 IPW2100_PRIV_GET_LONGPREAMBLE,
8139 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble" 8417 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
8140 }, 8418#ifdef CONFIG_IPW2100_MONITOR
8419 {
8420 IPW2100_PRIV_SET_CRC_CHECK,
8421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
8422 {
8423 IPW2100_PRIV_GET_CRC_CHECK,
8424 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
8425#endif /* CONFIG_IPW2100_MONITOR */
8141}; 8426};
8142 8427
8143static iw_handler ipw2100_private_handler[] = { 8428static iw_handler ipw2100_private_handler[] = {
8144#ifdef CONFIG_IPW2100_MONITOR 8429#ifdef CONFIG_IPW2100_MONITOR
8145 ipw2100_wx_set_promisc, 8430 ipw2100_wx_set_promisc,
8146 ipw2100_wx_reset, 8431 ipw2100_wx_reset,
8147#else /* CONFIG_IPW2100_MONITOR */ 8432#else /* CONFIG_IPW2100_MONITOR */
8148 NULL, 8433 NULL,
8149 NULL, 8434 NULL,
8150#endif /* CONFIG_IPW2100_MONITOR */ 8435#endif /* CONFIG_IPW2100_MONITOR */
8151 ipw2100_wx_set_powermode, 8436 ipw2100_wx_set_powermode,
8152 ipw2100_wx_get_powermode, 8437 ipw2100_wx_get_powermode,
8153 ipw2100_wx_set_preamble, 8438 ipw2100_wx_set_preamble,
8154 ipw2100_wx_get_preamble, 8439 ipw2100_wx_get_preamble,
8440#ifdef CONFIG_IPW2100_MONITOR
8441 ipw2100_wx_set_crc_check,
8442 ipw2100_wx_get_crc_check,
8443#else /* CONFIG_IPW2100_MONITOR */
8444 NULL,
8445 NULL,
8446#endif /* CONFIG_IPW2100_MONITOR */
8155}; 8447};
8156 8448
8157static struct iw_handler_def ipw2100_wx_handler_def = 8449static struct iw_handler_def ipw2100_wx_handler_def = {
8158{
8159 .standard = ipw2100_wx_handlers, 8450 .standard = ipw2100_wx_handlers,
8160 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), 8451 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8161 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), 8452 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8162 .num_private_args = sizeof(ipw2100_private_args) / 8453 .num_private_args = sizeof(ipw2100_private_args) /
8163 sizeof(struct iw_priv_args), 8454 sizeof(struct iw_priv_args),
8164 .private = (iw_handler *)ipw2100_private_handler, 8455 .private = (iw_handler *) ipw2100_private_handler,
8165 .private_args = (struct iw_priv_args *)ipw2100_private_args, 8456 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8166}; 8457};
8167 8458
@@ -8170,7 +8461,7 @@ static struct iw_handler_def ipw2100_wx_handler_def =
8170 * Called by /proc/net/wireless 8461 * Called by /proc/net/wireless
8171 * Also called by SIOCGIWSTATS 8462 * Also called by SIOCGIWSTATS
8172 */ 8463 */
8173static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev) 8464static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8174{ 8465{
8175 enum { 8466 enum {
8176 POOR = 30, 8467 POOR = 30,
@@ -8190,7 +8481,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8190 u32 ord_len = sizeof(u32); 8481 u32 ord_len = sizeof(u32);
8191 8482
8192 if (!priv) 8483 if (!priv)
8193 return (struct iw_statistics *) NULL; 8484 return (struct iw_statistics *)NULL;
8194 8485
8195 wstats = &priv->wstats; 8486 wstats = &priv->wstats;
8196 8487
@@ -8207,7 +8498,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8207 wstats->qual.noise = 0; 8498 wstats->qual.noise = 0;
8208 wstats->qual.updated = 7; 8499 wstats->qual.updated = 7;
8209 wstats->qual.updated |= IW_QUAL_NOISE_INVALID | 8500 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8210 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 8501 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8211 return wstats; 8502 return wstats;
8212 } 8503 }
8213 8504
@@ -8215,7 +8506,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8215 &missed_beacons, &ord_len)) 8506 &missed_beacons, &ord_len))
8216 goto fail_get_ordinal; 8507 goto fail_get_ordinal;
8217 8508
8218 /* If we don't have a connection the quality and level is 0*/ 8509 /* If we don't have a connection the quality and level is 0 */
8219 if (!(priv->status & STATUS_ASSOCIATED)) { 8510 if (!(priv->status & STATUS_ASSOCIATED)) {
8220 wstats->qual.qual = 0; 8511 wstats->qual.qual = 0;
8221 wstats->qual.level = 0; 8512 wstats->qual.level = 0;
@@ -8232,10 +8523,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8232 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR; 8523 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8233 else if (rssi < 30) 8524 else if (rssi < 30)
8234 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) / 8525 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8235 10 + GOOD; 8526 10 + GOOD;
8236 else 8527 else
8237 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) / 8528 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8238 10 + VERY_GOOD; 8529 10 + VERY_GOOD;
8239 8530
8240 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES, 8531 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8241 &tx_retries, &ord_len)) 8532 &tx_retries, &ord_len))
@@ -8249,25 +8540,25 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8249 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; 8540 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8250 else if (tx_retries > 50) 8541 else if (tx_retries > 50)
8251 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / 8542 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8252 15 + GOOD; 8543 15 + GOOD;
8253 else 8544 else
8254 tx_qual = (50 - tx_retries) * 8545 tx_qual = (50 - tx_retries) *
8255 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; 8546 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8256 8547
8257 if (missed_beacons > 50) 8548 if (missed_beacons > 50)
8258 beacon_qual = (60 - missed_beacons) * POOR / 10; 8549 beacon_qual = (60 - missed_beacons) * POOR / 10;
8259 else if (missed_beacons > 40) 8550 else if (missed_beacons > 40)
8260 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) / 8551 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8261 10 + POOR; 8552 10 + POOR;
8262 else if (missed_beacons > 32) 8553 else if (missed_beacons > 32)
8263 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) / 8554 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8264 18 + FAIR; 8555 18 + FAIR;
8265 else if (missed_beacons > 20) 8556 else if (missed_beacons > 20)
8266 beacon_qual = (32 - missed_beacons) * 8557 beacon_qual = (32 - missed_beacons) *
8267 (VERY_GOOD - GOOD) / 20 + GOOD; 8558 (VERY_GOOD - GOOD) / 20 + GOOD;
8268 else 8559 else
8269 beacon_qual = (20 - missed_beacons) * 8560 beacon_qual = (20 - missed_beacons) *
8270 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD; 8561 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8271 8562
8272 quality = min(beacon_qual, min(tx_qual, rssi_qual)); 8563 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8273 8564
@@ -8290,7 +8581,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8290 wstats->qual.updated = 7; 8581 wstats->qual.updated = 7;
8291 wstats->qual.updated |= IW_QUAL_NOISE_INVALID; 8582 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8292 8583
8293 /* FIXME: this is percent and not a # */ 8584 /* FIXME: this is percent and not a # */
8294 wstats->miss.beacon = missed_beacons; 8585 wstats->miss.beacon = missed_beacons;
8295 8586
8296 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES, 8587 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
@@ -8300,10 +8591,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8300 8591
8301 return wstats; 8592 return wstats;
8302 8593
8303 fail_get_ordinal: 8594 fail_get_ordinal:
8304 IPW_DEBUG_WX("failed querying ordinals.\n"); 8595 IPW_DEBUG_WX("failed querying ordinals.\n");
8305 8596
8306 return (struct iw_statistics *) NULL; 8597 return (struct iw_statistics *)NULL;
8307} 8598}
8308 8599
8309static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 8600static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
@@ -8326,23 +8617,17 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8326 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) || 8617 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8327 priv->status & STATUS_RF_KILL_MASK || 8618 priv->status & STATUS_RF_KILL_MASK ||
8328 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, 8619 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8329 &priv->bssid, &len)) { 8620 &priv->bssid, &len)) {
8330 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 8621 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8331 } else { 8622 } else {
8332 /* We now have the BSSID, so can finish setting to the full 8623 /* We now have the BSSID, so can finish setting to the full
8333 * associated state */ 8624 * associated state */
8334 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 8625 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8335 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN); 8626 memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
8336 priv->status &= ~STATUS_ASSOCIATING; 8627 priv->status &= ~STATUS_ASSOCIATING;
8337 priv->status |= STATUS_ASSOCIATED; 8628 priv->status |= STATUS_ASSOCIATED;
8338 netif_carrier_on(priv->net_dev); 8629 netif_carrier_on(priv->net_dev);
8339 if (netif_queue_stopped(priv->net_dev)) { 8630 netif_wake_queue(priv->net_dev);
8340 IPW_DEBUG_INFO("Waking net queue.\n");
8341 netif_wake_queue(priv->net_dev);
8342 } else {
8343 IPW_DEBUG_INFO("Starting net queue.\n");
8344 netif_start_queue(priv->net_dev);
8345 }
8346 } 8631 }
8347 8632
8348 if (!(priv->status & STATUS_ASSOCIATED)) { 8633 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -8351,7 +8636,8 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8351 /* This is a disassociation event, so kick the firmware to 8636 /* This is a disassociation event, so kick the firmware to
8352 * look for another AP */ 8637 * look for another AP */
8353 if (priv->config & CFG_STATIC_ESSID) 8638 if (priv->config & CFG_STATIC_ESSID)
8354 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0); 8639 ipw2100_set_essid(priv, priv->essid, priv->essid_len,
8640 0);
8355 else 8641 else
8356 ipw2100_set_essid(priv, NULL, 0, 0); 8642 ipw2100_set_essid(priv, NULL, 0, 0);
8357 up(&priv->action_sem); 8643 up(&priv->action_sem);
@@ -8374,7 +8660,6 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8374 8660
8375#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw" 8661#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8376 8662
8377
8378/* 8663/*
8379 8664
8380BINARY FIRMWARE HEADER FORMAT 8665BINARY FIRMWARE HEADER FORMAT
@@ -8396,12 +8681,10 @@ struct ipw2100_fw_header {
8396 unsigned int uc_size; 8681 unsigned int uc_size;
8397} __attribute__ ((packed)); 8682} __attribute__ ((packed));
8398 8683
8399
8400
8401static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw) 8684static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8402{ 8685{
8403 struct ipw2100_fw_header *h = 8686 struct ipw2100_fw_header *h =
8404 (struct ipw2100_fw_header *)fw->fw_entry->data; 8687 (struct ipw2100_fw_header *)fw->fw_entry->data;
8405 8688
8406 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) { 8689 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8407 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible " 8690 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
@@ -8420,7 +8703,6 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8420 return 0; 8703 return 0;
8421} 8704}
8422 8705
8423
8424static int ipw2100_get_firmware(struct ipw2100_priv *priv, 8706static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8425 struct ipw2100_fw *fw) 8707 struct ipw2100_fw *fw)
8426{ 8708{
@@ -8428,7 +8710,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8428 int rc; 8710 int rc;
8429 8711
8430 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n", 8712 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8431 priv->net_dev->name); 8713 priv->net_dev->name);
8432 8714
8433 switch (priv->ieee->iw_mode) { 8715 switch (priv->ieee->iw_mode) {
8434 case IW_MODE_ADHOC: 8716 case IW_MODE_ADHOC:
@@ -8454,7 +8736,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8454 return rc; 8736 return rc;
8455 } 8737 }
8456 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, 8738 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
8457 fw->fw_entry->size); 8739 fw->fw_entry->size);
8458 8740
8459 ipw2100_mod_firmware_load(fw); 8741 ipw2100_mod_firmware_load(fw);
8460 8742
@@ -8470,7 +8752,6 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8470 fw->fw_entry = NULL; 8752 fw->fw_entry = NULL;
8471} 8753}
8472 8754
8473
8474static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, 8755static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8475 size_t max) 8756 size_t max)
8476{ 8757{
@@ -8479,8 +8760,7 @@ static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8479 u32 tmp; 8760 u32 tmp;
8480 int i; 8761 int i;
8481 /* firmware version is an ascii string (max len of 14) */ 8762 /* firmware version is an ascii string (max len of 14) */
8482 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, 8763 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, ver, &len))
8483 ver, &len))
8484 return -EIO; 8764 return -EIO;
8485 tmp = max; 8765 tmp = max;
8486 if (len >= max) 8766 if (len >= max)
@@ -8497,8 +8777,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8497 u32 ver; 8777 u32 ver;
8498 u32 len = sizeof(ver); 8778 u32 len = sizeof(ver);
8499 /* microcode version is a 32 bit integer */ 8779 /* microcode version is a 32 bit integer */
8500 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, 8780 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, &ver, &len))
8501 &ver, &len))
8502 return -EIO; 8781 return -EIO;
8503 return snprintf(buf, max, "%08X", ver); 8782 return snprintf(buf, max, "%08X", ver);
8504} 8783}
@@ -8506,8 +8785,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8506/* 8785/*
8507 * On exit, the firmware will have been freed from the fw list 8786 * On exit, the firmware will have been freed from the fw list
8508 */ 8787 */
8509static int ipw2100_fw_download(struct ipw2100_priv *priv, 8788static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8510 struct ipw2100_fw *fw)
8511{ 8789{
8512 /* firmware is constructed of N contiguous entries, each entry is 8790 /* firmware is constructed of N contiguous entries, each entry is
8513 * structured as: 8791 * structured as:
@@ -8515,7 +8793,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8515 * offset sie desc 8793 * offset sie desc
8516 * 0 4 address to write to 8794 * 0 4 address to write to
8517 * 4 2 length of data run 8795 * 4 2 length of data run
8518 * 6 length data 8796 * 6 length data
8519 */ 8797 */
8520 unsigned int addr; 8798 unsigned int addr;
8521 unsigned short len; 8799 unsigned short len;
@@ -8524,12 +8802,12 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8524 unsigned int firmware_data_left = fw->fw.size; 8802 unsigned int firmware_data_left = fw->fw.size;
8525 8803
8526 while (firmware_data_left > 0) { 8804 while (firmware_data_left > 0) {
8527 addr = *(u32 *)(firmware_data); 8805 addr = *(u32 *) (firmware_data);
8528 firmware_data += 4; 8806 firmware_data += 4;
8529 firmware_data_left -= 4; 8807 firmware_data_left -= 4;
8530 8808
8531 len = *(u16 *)(firmware_data); 8809 len = *(u16 *) (firmware_data);
8532 firmware_data += 2; 8810 firmware_data += 2;
8533 firmware_data_left -= 2; 8811 firmware_data_left -= 2;
8534 8812
8535 if (len > 32) { 8813 if (len > 32) {
@@ -8540,7 +8818,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8540 } 8818 }
8541 8819
8542 write_nic_memory(priv->net_dev, addr, len, firmware_data); 8820 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8543 firmware_data += len; 8821 firmware_data += len;
8544 firmware_data_left -= len; 8822 firmware_data_left -= len;
8545 } 8823 }
8546 8824
@@ -8654,21 +8932,19 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8654 for (i = 0; i < 30; i++) { 8932 for (i = 0; i < 30; i++) {
8655 /* Read alive response structure */ 8933 /* Read alive response structure */
8656 for (j = 0; 8934 for (j = 0;
8657 j < (sizeof(struct symbol_alive_response) >> 1); 8935 j < (sizeof(struct symbol_alive_response) >> 1); j++)
8658 j++) 8936 read_nic_word(dev, 0x210004, ((u16 *) & response) + j);
8659 read_nic_word(dev, 0x210004,
8660 ((u16 *)&response) + j);
8661 8937
8662 if ((response.cmd_id == 1) && 8938 if ((response.cmd_id == 1) && (response.ucode_valid == 0x1))
8663 (response.ucode_valid == 0x1))
8664 break; 8939 break;
8665 udelay(10); 8940 udelay(10);
8666 } 8941 }
8667 8942
8668 if (i == 30) { 8943 if (i == 30) {
8669 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n", 8944 printk(KERN_ERR DRV_NAME
8945 ": %s: No response from Symbol - hw not alive\n",
8670 dev->name); 8946 dev->name);
8671 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response)); 8947 printk_buf(IPW_DL_ERROR, (u8 *) & response, sizeof(response));
8672 return -EIO; 8948 return -EIO;
8673 } 8949 }
8674 8950
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index c9e99ce15d66..140fdf2a0a09 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,6 @@
37#include <linux/socket.h> 37#include <linux/socket.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/wireless.h> 39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API 40#include <net/iw_handler.h> // new driver API
42 41
43#include <net/ieee80211.h> 42#include <net/ieee80211.h>
@@ -93,7 +92,6 @@ struct ipw2100_rx_packet;
93#define IPW_DL_IOCTL (1<<14) 92#define IPW_DL_IOCTL (1<<14)
94#define IPW_DL_RF_KILL (1<<17) 93#define IPW_DL_RF_KILL (1<<17)
95 94
96
97#define IPW_DL_MANAGE (1<<15) 95#define IPW_DL_MANAGE (1<<15)
98#define IPW_DL_FW (1<<16) 96#define IPW_DL_FW (1<<16)
99 97
@@ -156,7 +154,9 @@ extern const char *band_str[];
156 154
157struct bd_status { 155struct bd_status {
158 union { 156 union {
159 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields; 157 struct {
158 u8 nlf:1, txType:2, intEnabled:1, reserved:4;
159 } fields;
160 u8 field; 160 u8 field;
161 } info; 161 } info;
162} __attribute__ ((packed)); 162} __attribute__ ((packed));
@@ -165,7 +165,7 @@ struct ipw2100_bd {
165 u32 host_addr; 165 u32 host_addr;
166 u32 buf_length; 166 u32 buf_length;
167 struct bd_status status; 167 struct bd_status status;
168 /* number of fragments for frame (should be set only for 168 /* number of fragments for frame (should be set only for
169 * 1st TBD) */ 169 * 1st TBD) */
170 u8 num_fragments; 170 u8 num_fragments;
171 u8 reserved[6]; 171 u8 reserved[6];
@@ -293,10 +293,10 @@ struct ipw2100_cmd_header {
293struct ipw2100_data_header { 293struct ipw2100_data_header {
294 u32 host_command_reg; 294 u32 host_command_reg;
295 u32 host_command_reg1; 295 u32 host_command_reg1;
296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver 296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC 297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key 298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV 299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
300 u8 key[16]; 300 u8 key[16];
301 u8 reserved[10]; // f/w reserved 301 u8 reserved[10]; // f/w reserved
302 u8 src_addr[ETH_ALEN]; 302 u8 src_addr[ETH_ALEN];
@@ -306,14 +306,13 @@ struct ipw2100_data_header {
306 306
307/* Host command data structure */ 307/* Host command data structure */
308struct host_command { 308struct host_command {
309 u32 host_command; // COMMAND ID 309 u32 host_command; // COMMAND ID
310 u32 host_command1; // COMMAND ID 310 u32 host_command1; // COMMAND ID
311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) 311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
312 u32 host_command_length; // LENGTH 312 u32 host_command_length; // LENGTH
313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS 313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
314} __attribute__ ((packed)); 314} __attribute__ ((packed));
315 315
316
317typedef enum { 316typedef enum {
318 POWER_ON_RESET, 317 POWER_ON_RESET,
319 EXIT_POWER_DOWN_RESET, 318 EXIT_POWER_DOWN_RESET,
@@ -328,17 +327,16 @@ enum {
328 RX 327 RX
329}; 328};
330 329
331
332struct ipw2100_tx_packet { 330struct ipw2100_tx_packet {
333 int type; 331 int type;
334 int index; 332 int index;
335 union { 333 union {
336 struct { /* COMMAND */ 334 struct { /* COMMAND */
337 struct ipw2100_cmd_header* cmd; 335 struct ipw2100_cmd_header *cmd;
338 dma_addr_t cmd_phys; 336 dma_addr_t cmd_phys;
339 } c_struct; 337 } c_struct;
340 struct { /* DATA */ 338 struct { /* DATA */
341 struct ipw2100_data_header* data; 339 struct ipw2100_data_header *data;
342 dma_addr_t data_phys; 340 dma_addr_t data_phys;
343 struct ieee80211_txb *txb; 341 struct ieee80211_txb *txb;
344 } d_struct; 342 } d_struct;
@@ -348,7 +346,6 @@ struct ipw2100_tx_packet {
348 struct list_head list; 346 struct list_head list;
349}; 347};
350 348
351
352struct ipw2100_rx_packet { 349struct ipw2100_rx_packet {
353 struct ipw2100_rx *rxp; 350 struct ipw2100_rx *rxp;
354 dma_addr_t dma_addr; 351 dma_addr_t dma_addr;
@@ -432,13 +429,13 @@ enum {
432}; 429};
433 430
434#define STATUS_POWERED (1<<0) 431#define STATUS_POWERED (1<<0)
435#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */ 432#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
436#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */ 433#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
437#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */ 434#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
438#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */ 435#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
439#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */ 436#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
440#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */ 437#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
441#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */ 438#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
442#define STATUS_INT_ENABLED (1<<11) 439#define STATUS_INT_ENABLED (1<<11)
443#define STATUS_RF_KILL_HW (1<<12) 440#define STATUS_RF_KILL_HW (1<<12)
444#define STATUS_RF_KILL_SW (1<<13) 441#define STATUS_RF_KILL_SW (1<<13)
@@ -451,9 +448,7 @@ enum {
451#define STATUS_SCAN_COMPLETE (1<<26) 448#define STATUS_SCAN_COMPLETE (1<<26)
452#define STATUS_WX_EVENT_PENDING (1<<27) 449#define STATUS_WX_EVENT_PENDING (1<<27)
453#define STATUS_RESET_PENDING (1<<29) 450#define STATUS_RESET_PENDING (1<<29)
454#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */ 451#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
455
456
457 452
458/* Internal NIC states */ 453/* Internal NIC states */
459#define IPW_STATE_INITIALIZED (1<<0) 454#define IPW_STATE_INITIALIZED (1<<0)
@@ -469,11 +464,9 @@ enum {
469#define IPW_STATE_POWER_DOWN (1<<10) 464#define IPW_STATE_POWER_DOWN (1<<10)
470#define IPW_STATE_SCANNING (1<<11) 465#define IPW_STATE_SCANNING (1<<11)
471 466
472 467#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
473 468#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
474#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ 469#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
475#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
476#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
477#define CFG_CUSTOM_MAC (1<<3) 470#define CFG_CUSTOM_MAC (1<<3)
478#define CFG_LONG_PREAMBLE (1<<4) 471#define CFG_LONG_PREAMBLE (1<<4)
479#define CFG_ASSOCIATE (1<<6) 472#define CFG_ASSOCIATE (1<<6)
@@ -481,14 +474,17 @@ enum {
481#define CFG_ADHOC_CREATE (1<<8) 474#define CFG_ADHOC_CREATE (1<<8)
482#define CFG_C3_DISABLED (1<<9) 475#define CFG_C3_DISABLED (1<<9)
483#define CFG_PASSIVE_SCAN (1<<10) 476#define CFG_PASSIVE_SCAN (1<<10)
477#ifdef CONFIG_IPW2100_MONITOR
478#define CFG_CRC_CHECK (1<<11)
479#endif
484 480
485#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 481#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
486#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 482#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
487 483
488struct ipw2100_priv { 484struct ipw2100_priv {
489 485
490 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */ 486 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
491 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */ 487 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
492 488
493 struct ieee80211_device *ieee; 489 struct ieee80211_device *ieee;
494 unsigned long status; 490 unsigned long status;
@@ -519,19 +515,16 @@ struct ipw2100_priv {
519 unsigned long hw_features; 515 unsigned long hw_features;
520 int hangs; 516 int hangs;
521 u32 last_rtc; 517 u32 last_rtc;
522 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */ 518 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
523 u8* snapshot[0x30]; 519 u8 *snapshot[0x30];
524 520
525 u8 mandatory_bssid_mac[ETH_ALEN]; 521 u8 mandatory_bssid_mac[ETH_ALEN];
526 u8 mac_addr[ETH_ALEN]; 522 u8 mac_addr[ETH_ALEN];
527 523
528 int power_mode; 524 int power_mode;
529 525
530 /* WEP data */
531 struct ieee80211_security sec;
532 int messages_sent; 526 int messages_sent;
533 527
534
535 int short_retry_limit; 528 int short_retry_limit;
536 int long_retry_limit; 529 int long_retry_limit;
537 530
@@ -599,7 +592,6 @@ struct ipw2100_priv {
599 wait_queue_head_t wait_command_queue; 592 wait_queue_head_t wait_command_queue;
600}; 593};
601 594
602
603/********************************************************* 595/*********************************************************
604 * Host Command -> From Driver to FW 596 * Host Command -> From Driver to FW
605 *********************************************************/ 597 *********************************************************/
@@ -646,7 +638,6 @@ struct ipw2100_priv {
646#define CARD_DISABLE_PHY_OFF 61 638#define CARD_DISABLE_PHY_OFF 61
647#define MSDU_TX_RATES 62 639#define MSDU_TX_RATES 62
648 640
649
650/* Rogue AP Detection */ 641/* Rogue AP Detection */
651#define SET_STATION_STAT_BITS 64 642#define SET_STATION_STAT_BITS 64
652#define CLEAR_STATIONS_STAT_BITS 65 643#define CLEAR_STATIONS_STAT_BITS 65
@@ -655,8 +646,6 @@ struct ipw2100_priv {
655#define DISASSOCIATION_BSSID 68 646#define DISASSOCIATION_BSSID 68
656#define SET_WPA_IE 69 647#define SET_WPA_IE 69
657 648
658
659
660/* system configuration bit mask: */ 649/* system configuration bit mask: */
661#define IPW_CFG_MONITOR 0x00004 650#define IPW_CFG_MONITOR 0x00004
662#define IPW_CFG_PREAMBLE_AUTO 0x00010 651#define IPW_CFG_PREAMBLE_AUTO 0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
704#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB) 693#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
705#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1 694#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
706#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2 695#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
707#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3 696#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
708#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4 697#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
709#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5 698#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
710#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16 699#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
784#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli 773#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
785#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli 774#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
786 775
787
788
789
790#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr) 776#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
791#define IPW_MAX_80211_PAYLOAD_SIZE 2304U 777#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
792#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312 778#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
@@ -843,8 +829,8 @@ struct ipw2100_rx {
843#define IPW_TX_POWER_MIN_DBM (-12) 829#define IPW_TX_POWER_MIN_DBM (-12)
844#define IPW_TX_POWER_MAX_DBM 16 830#define IPW_TX_POWER_MAX_DBM 16
845 831
846#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan 832#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
847#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan 833#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
848 834
849#define REG_MIN_CHANNEL 0 835#define REG_MIN_CHANNEL 0
850#define REG_MAX_CHANNEL 14 836#define REG_MAX_CHANNEL 14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
856#define DIVERSITY_ANTENNA_A 1 // Use antenna A 842#define DIVERSITY_ANTENNA_A 1 // Use antenna A
857#define DIVERSITY_ANTENNA_B 2 // Use antenna B 843#define DIVERSITY_ANTENNA_B 2 // Use antenna B
858 844
859
860#define HOST_COMMAND_WAIT 0 845#define HOST_COMMAND_WAIT 0
861#define HOST_COMMAND_NO_WAIT 1 846#define HOST_COMMAND_NO_WAIT 1
862 847
@@ -873,10 +858,9 @@ struct ipw2100_rx {
873#define TYPE_ASSOCIATION_REQUEST 0x0013 858#define TYPE_ASSOCIATION_REQUEST 0x0013
874#define TYPE_REASSOCIATION_REQUEST 0x0014 859#define TYPE_REASSOCIATION_REQUEST 0x0014
875 860
876 861#define HW_FEATURE_RFKILL 0x0001
877#define HW_FEATURE_RFKILL (0x0001) 862#define RF_KILLSWITCH_OFF 1
878#define RF_KILLSWITCH_OFF (1) 863#define RF_KILLSWITCH_ON 0
879#define RF_KILLSWITCH_ON (0)
880 864
881#define IPW_COMMAND_POOL_SIZE 40 865#define IPW_COMMAND_POOL_SIZE 40
882 866
@@ -895,7 +879,7 @@ struct ipw2100_rx {
895// Fixed size data: Ordinal Table 1 879// Fixed size data: Ordinal Table 1
896typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW 880typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
897// Transmit statistics 881// Transmit statistics
898 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU) 882 IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
899 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU) 883 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
900 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU) 884 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
901 885
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
905 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB 889 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
906 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB 890 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
907 891
908 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB 892 IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
909 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB 893 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
910 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB 894 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
911 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB 895 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
912 896
913 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's 897 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
914 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS 898 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
915 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS 899 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
916 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK 900 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
917 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's 901 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
918 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's 902 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
919 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's 903 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
920 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's 904 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
921 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted 905 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
922 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted 906 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
923 IPW_ORD_STAT_TX_BEACON, // # of tx beacon 907 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
924 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM 908 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
925 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX 909 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
926 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx 910 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
927 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX 911 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
928 912
929 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes 913 IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
930 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries 914 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
931 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS 915 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
932 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS 916 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
933 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS 917 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
934 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS 918 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
935 919
936 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures 920 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
937 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time 921 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
938 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed 922 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
939 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup 923 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
940 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted 924 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
941 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed 925 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
942 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames 926 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
943 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent 927 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
944 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks 928 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
945 929
946 // Receive statistics 930 // Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
952 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB 936 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
953 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB 937 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
954 938
955 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets 939 IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
956 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB 940 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
957 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB 941 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
958 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB 942 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
977 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx 961 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
978 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx 962 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
979 963
980 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received 964 IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
981 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error 965 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
982 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB 966 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
983 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB 967 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
984 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB 968 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
985 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB 969 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
986 970
987 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB 971 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
988 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB 972 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
989 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB 973 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
990 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB 974 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
991 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets 975 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
992 976
993 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db 977 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
994 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db 978 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
1006 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption 990 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1007 991
1008// PSP Statistics 992// PSP Statistics
1009 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended 993 IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
1010 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout 994 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1011 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts 995 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1012 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt 996 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
1013 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received 997 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1014 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received 998 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1015 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID 999 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1016 1000
1017// Association and roaming 1001// Association and roaming
1018 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association 1002 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1019 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons 1003 IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
1020 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries 1004 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1021 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated 1005 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1022 // AP table entry. set to 0 if not associated 1006 // AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
1151}; 1135};
1152 1136
1153struct ipw2100_fw_chunk_set { 1137struct ipw2100_fw_chunk_set {
1154 const void *data; 1138 const void *data;
1155 unsigned long size; 1139 unsigned long size;
1156}; 1140};
1157 1141
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
1164 1148
1165#define MAX_FW_VERSION_LEN 14 1149#define MAX_FW_VERSION_LEN 14
1166 1150
1167#endif /* _IPW2100_H */ 1151#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32afe82..b0d195d1721a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 802.11 status code portion of this file from ethereal-0.10.6: 5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB 6 Copyright 2000, Axis Communications AB
@@ -31,30 +31,103 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h>
34 35
35#define IPW2200_VERSION "1.0.0" 36#define IPW2200_VERSION "git-1.0.8"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 38#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 39#define DRV_VERSION IPW2200_VERSION
39 40
41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
42
40MODULE_DESCRIPTION(DRV_DESCRIPTION); 43MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION); 44MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT); 45MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
44 47
48static int cmdlog = 0;
45static int debug = 0; 49static int debug = 0;
46static int channel = 0; 50static int channel = 0;
47static char *ifname;
48static int mode = 0; 51static int mode = 0;
49 52
50static u32 ipw_debug_level; 53static u32 ipw_debug_level;
51static int associate = 1; 54static int associate = 1;
52static int auto_create = 1; 55static int auto_create = 1;
56static int led = 0;
53static int disable = 0; 57static int disable = 0;
58static int hwcrypto = 1;
54static const char ipw_modes[] = { 59static const char ipw_modes[] = {
55 'a', 'b', 'g', '?' 60 'a', 'b', 'g', '?'
56}; 61};
57 62
63#ifdef CONFIG_IPW_QOS
64static int qos_enable = 0;
65static int qos_burst_enable = 0;
66static int qos_no_ack_mask = 0;
67static int burst_duration_CCK = 0;
68static int burst_duration_OFDM = 0;
69
70static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
71 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
72 QOS_TX3_CW_MIN_OFDM},
73 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
74 QOS_TX3_CW_MAX_OFDM},
75 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
76 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
77 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
78 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
79};
80
81static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
82 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
83 QOS_TX3_CW_MIN_CCK},
84 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
85 QOS_TX3_CW_MAX_CCK},
86 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
87 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
88 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
89 QOS_TX3_TXOP_LIMIT_CCK}
90};
91
92static struct ieee80211_qos_parameters def_parameters_OFDM = {
93 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
94 DEF_TX3_CW_MIN_OFDM},
95 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
96 DEF_TX3_CW_MAX_OFDM},
97 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
98 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
99 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
100 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
101};
102
103static struct ieee80211_qos_parameters def_parameters_CCK = {
104 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
105 DEF_TX3_CW_MIN_CCK},
106 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
107 DEF_TX3_CW_MAX_CCK},
108 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
109 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
110 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
111 DEF_TX3_TXOP_LIMIT_CCK}
112};
113
114static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
115
116static int from_priority_to_tx_queue[] = {
117 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
118 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
119};
120
121static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
122
123static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
124 *qos_param);
125static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
126 *qos_param);
127#endif /* CONFIG_IPW_QOS */
128
129static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
130static void ipw_remove_current_network(struct ipw_priv *priv);
58static void ipw_rx(struct ipw_priv *priv); 131static void ipw_rx(struct ipw_priv *priv);
59static int ipw_queue_tx_reclaim(struct ipw_priv *priv, 132static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
60 struct clx2_tx_queue *txq, int qindex); 133 struct clx2_tx_queue *txq, int qindex);
@@ -68,42 +141,24 @@ static void ipw_tx_queue_free(struct ipw_priv *);
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); 141static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); 142static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *); 143static void ipw_rx_queue_replenish(void *);
71
72static int ipw_up(struct ipw_priv *); 144static int ipw_up(struct ipw_priv *);
145static void ipw_bg_up(void *);
73static void ipw_down(struct ipw_priv *); 146static void ipw_down(struct ipw_priv *);
147static void ipw_bg_down(void *);
74static int ipw_config(struct ipw_priv *); 148static int ipw_config(struct ipw_priv *);
75static int init_supported_rates(struct ipw_priv *priv, 149static int init_supported_rates(struct ipw_priv *priv,
76 struct ipw_supported_rates *prates); 150 struct ipw_supported_rates *prates);
151static void ipw_set_hwcrypto_keys(struct ipw_priv *);
152static void ipw_send_wep_keys(struct ipw_priv *, int);
77 153
78static u8 band_b_active_channel[MAX_B_CHANNELS] = { 154static int ipw_is_valid_channel(struct ieee80211_device *, u8);
79 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 155static int ipw_channel_to_index(struct ieee80211_device *, u8);
80}; 156static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
81static u8 band_a_active_channel[MAX_A_CHANNELS] = { 157static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
82 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0 158static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
83};
84 159
85static int is_valid_channel(int mode_mask, int channel) 160static int snprint_line(char *buf, size_t count,
86{ 161 const u8 * data, u32 len, u32 ofs)
87 int i;
88
89 if (!channel)
90 return 0;
91
92 if (mode_mask & IEEE_A)
93 for (i = 0; i < MAX_A_CHANNELS; i++)
94 if (band_a_active_channel[i] == channel)
95 return IEEE_A;
96
97 if (mode_mask & (IEEE_B | IEEE_G))
98 for (i = 0; i < MAX_B_CHANNELS; i++)
99 if (band_b_active_channel[i] == channel)
100 return mode_mask & (IEEE_B | IEEE_G);
101
102 return 0;
103}
104
105static char *snprint_line(char *buf, size_t count,
106 const u8 * data, u32 len, u32 ofs)
107{ 162{
108 int out, i, j, l; 163 int out, i, j, l;
109 char c; 164 char c;
@@ -134,7 +189,7 @@ static char *snprint_line(char *buf, size_t count,
134 out += snprintf(buf + out, count - out, " "); 189 out += snprintf(buf + out, count - out, " ");
135 } 190 }
136 191
137 return buf; 192 return out;
138} 193}
139 194
140static void printk_buf(int level, const u8 * data, u32 len) 195static void printk_buf(int level, const u8 * data, u32 len)
@@ -145,14 +200,33 @@ static void printk_buf(int level, const u8 * data, u32 len)
145 return; 200 return;
146 201
147 while (len) { 202 while (len) {
148 printk(KERN_DEBUG "%s\n", 203 snprint_line(line, sizeof(line), &data[ofs],
149 snprint_line(line, sizeof(line), &data[ofs], 204 min(len, 16U), ofs);
150 min(len, 16U), ofs)); 205 printk(KERN_DEBUG "%s\n", line);
151 ofs += 16; 206 ofs += 16;
152 len -= min(len, 16U); 207 len -= min(len, 16U);
153 } 208 }
154} 209}
155 210
211static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
212{
213 size_t out = size;
214 u32 ofs = 0;
215 int total = 0;
216
217 while (size && len) {
218 out = snprint_line(output, size, &data[ofs],
219 min_t(size_t, len, 16U), ofs);
220
221 ofs += 16;
222 output += out;
223 size -= out;
224 len -= min_t(size_t, len, 16U);
225 total += out;
226 }
227 return total;
228}
229
156static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); 230static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
157#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) 231#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
158 232
@@ -226,38 +300,42 @@ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
226#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) 300#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
227 301
228static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); 302static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
229#define ipw_read_indirect(a, b, c, d) \ 303static inline void __ipw_read_indirect(const char *f, int l,
230 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 304 struct ipw_priv *a, u32 b, u8 * c, int d)
231 _ipw_read_indirect(a, b, c, d) 305{
306 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
307 d);
308 _ipw_read_indirect(a, b, c, d);
309}
310
311#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
232 312
233static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, 313static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
234 int num); 314 int num);
235#define ipw_write_indirect(a, b, c, d) \ 315#define ipw_write_indirect(a, b, c, d) \
236 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 316 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
237 _ipw_write_indirect(a, b, c, d) 317 _ipw_write_indirect(a, b, c, d)
238 318
239/* indirect write s */ 319/* indirect write s */
240static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) 320static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
241{ 321{
242 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); 322 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
243 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 323 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
244 _ipw_write32(priv, CX2_INDIRECT_DATA, value); 324 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
245} 325}
246 326
247static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) 327static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
248{ 328{
249 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 329 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
250 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 330 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
251 _ipw_write8(priv, CX2_INDIRECT_DATA, value); 331 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
252 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
253 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
254} 332}
255 333
256static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) 334static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
257{ 335{
258 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 336 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
259 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 337 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
260 _ipw_write16(priv, CX2_INDIRECT_DATA, value); 338 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
261} 339}
262 340
263/* indirect read s */ 341/* indirect read s */
@@ -265,9 +343,9 @@ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
265static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) 343static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
266{ 344{
267 u32 word; 345 u32 word;
268 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 346 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
269 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 347 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
270 word = _ipw_read32(priv, CX2_INDIRECT_DATA); 348 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
271 return (word >> ((reg & 0x3) * 8)) & 0xff; 349 return (word >> ((reg & 0x3) * 8)) & 0xff;
272} 350}
273 351
@@ -277,8 +355,8 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
277 355
278 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg); 356 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
279 357
280 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 358 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
281 value = _ipw_read32(priv, CX2_INDIRECT_DATA); 359 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
282 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 360 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
283 return value; 361 return value;
284} 362}
@@ -287,67 +365,69 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
287static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 365static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
288 int num) 366 int num)
289{ 367{
290 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 368 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
291 u32 dif_len = addr - aligned_addr; 369 u32 dif_len = addr - aligned_addr;
292 u32 aligned_len;
293 u32 i; 370 u32 i;
294 371
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 372 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296 373
374 if (num <= 0) {
375 return;
376 }
377
297 /* Read the first nibble byte by byte */ 378 /* Read the first nibble byte by byte */
298 if (unlikely(dif_len)) { 379 if (unlikely(dif_len)) {
380 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
299 /* Start reading at aligned_addr + dif_len */ 381 /* Start reading at aligned_addr + dif_len */
300 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 382 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
301 for (i = dif_len; i < 4; i++, buf++) 383 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
302 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
303 num -= dif_len;
304 aligned_addr += 4; 384 aligned_addr += 4;
305 } 385 }
306 386
307 /* Read DWs through autoinc register */ 387 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 388 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
309 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 389 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
310 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
311 *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
312 390
313 /* Copy the last nibble */ 391 /* Copy the last nibble */
314 dif_len = num - aligned_len; 392 if (unlikely(num)) {
315 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 393 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
316 for (i = 0; i < dif_len; i++, buf++) 394 for (i = 0; num > 0; i++, num--)
317 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); 395 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
396 }
318} 397}
319 398
320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 399static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
321 int num) 400 int num)
322{ 401{
323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
324 u32 dif_len = addr - aligned_addr; 403 u32 dif_len = addr - aligned_addr;
325 u32 aligned_len;
326 u32 i; 404 u32 i;
327 405
328 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 406 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
329 407
408 if (num <= 0) {
409 return;
410 }
411
330 /* Write the first nibble byte by byte */ 412 /* Write the first nibble byte by byte */
331 if (unlikely(dif_len)) { 413 if (unlikely(dif_len)) {
332 /* Start writing at aligned_addr + dif_len */ 414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
333 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 415 /* Start reading at aligned_addr + dif_len */
334 for (i = dif_len; i < 4; i++, buf++) 416 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
335 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 417 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
336 num -= dif_len;
337 aligned_addr += 4; 418 aligned_addr += 4;
338 } 419 }
339 420
340 /* Write DWs through autoinc register */ 421 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
341 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 422 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
342 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 423 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
343 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
345 424
346 /* Copy the last nibble */ 425 /* Copy the last nibble */
347 dif_len = num - aligned_len; 426 if (unlikely(num)) {
348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 427 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
349 for (i = 0; i < dif_len; i++, buf++) 428 for (i = 0; num > 0; i++, num--, buf++)
350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 429 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
430 }
351} 431}
352 432
353static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 433static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -371,7 +451,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
371 if (priv->status & STATUS_INT_ENABLED) 451 if (priv->status & STATUS_INT_ENABLED)
372 return; 452 return;
373 priv->status |= STATUS_INT_ENABLED; 453 priv->status |= STATUS_INT_ENABLED;
374 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL); 454 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
375} 455}
376 456
377static inline void ipw_disable_interrupts(struct ipw_priv *priv) 457static inline void ipw_disable_interrupts(struct ipw_priv *priv)
@@ -379,9 +459,10 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
379 if (!(priv->status & STATUS_INT_ENABLED)) 459 if (!(priv->status & STATUS_INT_ENABLED))
380 return; 460 return;
381 priv->status &= ~STATUS_INT_ENABLED; 461 priv->status &= ~STATUS_INT_ENABLED;
382 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 462 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
383} 463}
384 464
465#ifdef CONFIG_IPW_DEBUG
385static char *ipw_error_desc(u32 val) 466static char *ipw_error_desc(u32 val)
386{ 467{
387 switch (val) { 468 switch (val) {
@@ -394,81 +475,65 @@ static char *ipw_error_desc(u32 val)
394 case IPW_FW_ERROR_MEMORY_OVERFLOW: 475 case IPW_FW_ERROR_MEMORY_OVERFLOW:
395 return "MEMORY_OVERFLOW"; 476 return "MEMORY_OVERFLOW";
396 case IPW_FW_ERROR_BAD_PARAM: 477 case IPW_FW_ERROR_BAD_PARAM:
397 return "ERROR_BAD_PARAM"; 478 return "BAD_PARAM";
398 case IPW_FW_ERROR_BAD_CHECKSUM: 479 case IPW_FW_ERROR_BAD_CHECKSUM:
399 return "ERROR_BAD_CHECKSUM"; 480 return "BAD_CHECKSUM";
400 case IPW_FW_ERROR_NMI_INTERRUPT: 481 case IPW_FW_ERROR_NMI_INTERRUPT:
401 return "ERROR_NMI_INTERRUPT"; 482 return "NMI_INTERRUPT";
402 case IPW_FW_ERROR_BAD_DATABASE: 483 case IPW_FW_ERROR_BAD_DATABASE:
403 return "ERROR_BAD_DATABASE"; 484 return "BAD_DATABASE";
404 case IPW_FW_ERROR_ALLOC_FAIL: 485 case IPW_FW_ERROR_ALLOC_FAIL:
405 return "ERROR_ALLOC_FAIL"; 486 return "ALLOC_FAIL";
406 case IPW_FW_ERROR_DMA_UNDERRUN: 487 case IPW_FW_ERROR_DMA_UNDERRUN:
407 return "ERROR_DMA_UNDERRUN"; 488 return "DMA_UNDERRUN";
408 case IPW_FW_ERROR_DMA_STATUS: 489 case IPW_FW_ERROR_DMA_STATUS:
409 return "ERROR_DMA_STATUS"; 490 return "DMA_STATUS";
410 case IPW_FW_ERROR_DINOSTATUS_ERROR: 491 case IPW_FW_ERROR_DINO_ERROR:
411 return "ERROR_DINOSTATUS_ERROR"; 492 return "DINO_ERROR";
412 case IPW_FW_ERROR_EEPROMSTATUS_ERROR: 493 case IPW_FW_ERROR_EEPROM_ERROR:
413 return "ERROR_EEPROMSTATUS_ERROR"; 494 return "EEPROM_ERROR";
414 case IPW_FW_ERROR_SYSASSERT: 495 case IPW_FW_ERROR_SYSASSERT:
415 return "ERROR_SYSASSERT"; 496 return "SYSASSERT";
416 case IPW_FW_ERROR_FATAL_ERROR: 497 case IPW_FW_ERROR_FATAL_ERROR:
417 return "ERROR_FATALSTATUS_ERROR"; 498 return "FATAL_ERROR";
418 default: 499 default:
419 return "UNKNOWNSTATUS_ERROR"; 500 return "UNKNOWN_ERROR";
420 } 501 }
421} 502}
422 503
423static void ipw_dump_nic_error_log(struct ipw_priv *priv) 504static void ipw_dump_error_log(struct ipw_priv *priv,
505 struct ipw_fw_error *error)
424{ 506{
425 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base; 507 u32 i;
426
427 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
428 count = ipw_read_reg32(priv, base);
429 508
430 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 509 if (!error) {
431 IPW_ERROR("Start IPW Error Log Dump:\n"); 510 IPW_ERROR("Error allocating and capturing error log. "
432 IPW_ERROR("Status: 0x%08X, Config: %08X\n", 511 "Nothing to dump.\n");
433 priv->status, priv->config); 512 return;
434 } 513 }
435 514
436 for (i = ERROR_START_OFFSET; 515 IPW_ERROR("Start IPW Error Log Dump:\n");
437 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { 516 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
438 desc = ipw_read_reg32(priv, base + i); 517 error->status, error->config);
439 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
440 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
441 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
442 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
443 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
444 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
445 518
519 for (i = 0; i < error->elem_len; i++)
446 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 520 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
447 ipw_error_desc(desc), time, blink1, blink2, 521 ipw_error_desc(error->elem[i].desc),
448 ilink1, ilink2, idata); 522 error->elem[i].time,
449 } 523 error->elem[i].blink1,
524 error->elem[i].blink2,
525 error->elem[i].link1,
526 error->elem[i].link2, error->elem[i].data);
527 for (i = 0; i < error->log_len; i++)
528 IPW_ERROR("%i\t0x%08x\t%i\n",
529 error->log[i].time,
530 error->log[i].data, error->log[i].event);
450} 531}
532#endif
451 533
452static void ipw_dump_nic_event_log(struct ipw_priv *priv) 534static inline int ipw_is_init(struct ipw_priv *priv)
453{ 535{
454 u32 ev, time, data, i, count, base; 536 return (priv->status & STATUS_INIT) ? 1 : 0;
455
456 base = ipw_read32(priv, IPW_EVENT_LOG);
457 count = ipw_read_reg32(priv, base);
458
459 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
460 IPW_ERROR("Start IPW Event Log Dump:\n");
461
462 for (i = EVENT_START_OFFSET;
463 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
464 ev = ipw_read_reg32(priv, base + i);
465 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
466 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
467
468#ifdef CONFIG_IPW_DEBUG
469 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
470#endif
471 }
472} 537}
473 538
474static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) 539static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
@@ -636,6 +701,340 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
636 701
637} 702}
638 703
704u32 ipw_register_toggle(u32 reg)
705{
706 reg &= ~IPW_START_STANDBY;
707 if (reg & IPW_GATE_ODMA)
708 reg &= ~IPW_GATE_ODMA;
709 if (reg & IPW_GATE_IDMA)
710 reg &= ~IPW_GATE_IDMA;
711 if (reg & IPW_GATE_ADMA)
712 reg &= ~IPW_GATE_ADMA;
713 return reg;
714}
715
716/*
717 * LED behavior:
718 * - On radio ON, turn on any LEDs that require to be on during start
719 * - On initialization, start unassociated blink
720 * - On association, disable unassociated blink
721 * - On disassociation, start unassociated blink
722 * - On radio OFF, turn off any LEDs started during radio on
723 *
724 */
725#define LD_TIME_LINK_ON 300
726#define LD_TIME_LINK_OFF 2700
727#define LD_TIME_ACT_ON 250
728
729void ipw_led_link_on(struct ipw_priv *priv)
730{
731 unsigned long flags;
732 u32 led;
733
734 /* If configured to not use LEDs, or nic_type is 1,
735 * then we don't toggle a LINK led */
736 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
737 return;
738
739 spin_lock_irqsave(&priv->lock, flags);
740
741 if (!(priv->status & STATUS_RF_KILL_MASK) &&
742 !(priv->status & STATUS_LED_LINK_ON)) {
743 IPW_DEBUG_LED("Link LED On\n");
744 led = ipw_read_reg32(priv, IPW_EVENT_REG);
745 led |= priv->led_association_on;
746
747 led = ipw_register_toggle(led);
748
749 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
750 ipw_write_reg32(priv, IPW_EVENT_REG, led);
751
752 priv->status |= STATUS_LED_LINK_ON;
753
754 /* If we aren't associated, schedule turning the LED off */
755 if (!(priv->status & STATUS_ASSOCIATED))
756 queue_delayed_work(priv->workqueue,
757 &priv->led_link_off,
758 LD_TIME_LINK_ON);
759 }
760
761 spin_unlock_irqrestore(&priv->lock, flags);
762}
763
764static void ipw_bg_led_link_on(void *data)
765{
766 struct ipw_priv *priv = data;
767 down(&priv->sem);
768 ipw_led_link_on(data);
769 up(&priv->sem);
770}
771
772void ipw_led_link_off(struct ipw_priv *priv)
773{
774 unsigned long flags;
775 u32 led;
776
777 /* If configured not to use LEDs, or nic type is 1,
778 * then we don't goggle the LINK led. */
779 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
780 return;
781
782 spin_lock_irqsave(&priv->lock, flags);
783
784 if (priv->status & STATUS_LED_LINK_ON) {
785 led = ipw_read_reg32(priv, IPW_EVENT_REG);
786 led &= priv->led_association_off;
787 led = ipw_register_toggle(led);
788
789 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
790 ipw_write_reg32(priv, IPW_EVENT_REG, led);
791
792 IPW_DEBUG_LED("Link LED Off\n");
793
794 priv->status &= ~STATUS_LED_LINK_ON;
795
796 /* If we aren't associated and the radio is on, schedule
797 * turning the LED on (blink while unassociated) */
798 if (!(priv->status & STATUS_RF_KILL_MASK) &&
799 !(priv->status & STATUS_ASSOCIATED))
800 queue_delayed_work(priv->workqueue, &priv->led_link_on,
801 LD_TIME_LINK_OFF);
802
803 }
804
805 spin_unlock_irqrestore(&priv->lock, flags);
806}
807
808static void ipw_bg_led_link_off(void *data)
809{
810 struct ipw_priv *priv = data;
811 down(&priv->sem);
812 ipw_led_link_off(data);
813 up(&priv->sem);
814}
815
816static inline void __ipw_led_activity_on(struct ipw_priv *priv)
817{
818 u32 led;
819
820 if (priv->config & CFG_NO_LED)
821 return;
822
823 if (priv->status & STATUS_RF_KILL_MASK)
824 return;
825
826 if (!(priv->status & STATUS_LED_ACT_ON)) {
827 led = ipw_read_reg32(priv, IPW_EVENT_REG);
828 led |= priv->led_activity_on;
829
830 led = ipw_register_toggle(led);
831
832 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
833 ipw_write_reg32(priv, IPW_EVENT_REG, led);
834
835 IPW_DEBUG_LED("Activity LED On\n");
836
837 priv->status |= STATUS_LED_ACT_ON;
838
839 cancel_delayed_work(&priv->led_act_off);
840 queue_delayed_work(priv->workqueue, &priv->led_act_off,
841 LD_TIME_ACT_ON);
842 } else {
843 /* Reschedule LED off for full time period */
844 cancel_delayed_work(&priv->led_act_off);
845 queue_delayed_work(priv->workqueue, &priv->led_act_off,
846 LD_TIME_ACT_ON);
847 }
848}
849
850void ipw_led_activity_on(struct ipw_priv *priv)
851{
852 unsigned long flags;
853 spin_lock_irqsave(&priv->lock, flags);
854 __ipw_led_activity_on(priv);
855 spin_unlock_irqrestore(&priv->lock, flags);
856}
857
858void ipw_led_activity_off(struct ipw_priv *priv)
859{
860 unsigned long flags;
861 u32 led;
862
863 if (priv->config & CFG_NO_LED)
864 return;
865
866 spin_lock_irqsave(&priv->lock, flags);
867
868 if (priv->status & STATUS_LED_ACT_ON) {
869 led = ipw_read_reg32(priv, IPW_EVENT_REG);
870 led &= priv->led_activity_off;
871
872 led = ipw_register_toggle(led);
873
874 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
875 ipw_write_reg32(priv, IPW_EVENT_REG, led);
876
877 IPW_DEBUG_LED("Activity LED Off\n");
878
879 priv->status &= ~STATUS_LED_ACT_ON;
880 }
881
882 spin_unlock_irqrestore(&priv->lock, flags);
883}
884
885static void ipw_bg_led_activity_off(void *data)
886{
887 struct ipw_priv *priv = data;
888 down(&priv->sem);
889 ipw_led_activity_off(data);
890 up(&priv->sem);
891}
892
893void ipw_led_band_on(struct ipw_priv *priv)
894{
895 unsigned long flags;
896 u32 led;
897
898 /* Only nic type 1 supports mode LEDs */
899 if (priv->config & CFG_NO_LED ||
900 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
901 return;
902
903 spin_lock_irqsave(&priv->lock, flags);
904
905 led = ipw_read_reg32(priv, IPW_EVENT_REG);
906 if (priv->assoc_network->mode == IEEE_A) {
907 led |= priv->led_ofdm_on;
908 led &= priv->led_association_off;
909 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
910 } else if (priv->assoc_network->mode == IEEE_G) {
911 led |= priv->led_ofdm_on;
912 led |= priv->led_association_on;
913 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
914 } else {
915 led &= priv->led_ofdm_off;
916 led |= priv->led_association_on;
917 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
918 }
919
920 led = ipw_register_toggle(led);
921
922 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
923 ipw_write_reg32(priv, IPW_EVENT_REG, led);
924
925 spin_unlock_irqrestore(&priv->lock, flags);
926}
927
928void ipw_led_band_off(struct ipw_priv *priv)
929{
930 unsigned long flags;
931 u32 led;
932
933 /* Only nic type 1 supports mode LEDs */
934 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
935 return;
936
937 spin_lock_irqsave(&priv->lock, flags);
938
939 led = ipw_read_reg32(priv, IPW_EVENT_REG);
940 led &= priv->led_ofdm_off;
941 led &= priv->led_association_off;
942
943 led = ipw_register_toggle(led);
944
945 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
946 ipw_write_reg32(priv, IPW_EVENT_REG, led);
947
948 spin_unlock_irqrestore(&priv->lock, flags);
949}
950
951void ipw_led_radio_on(struct ipw_priv *priv)
952{
953 ipw_led_link_on(priv);
954}
955
956void ipw_led_radio_off(struct ipw_priv *priv)
957{
958 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv);
960}
961
962void ipw_led_link_up(struct ipw_priv *priv)
963{
964 /* Set the Link Led on for all nic types */
965 ipw_led_link_on(priv);
966}
967
968void ipw_led_link_down(struct ipw_priv *priv)
969{
970 ipw_led_activity_off(priv);
971 ipw_led_link_off(priv);
972
973 if (priv->status & STATUS_RF_KILL_MASK)
974 ipw_led_radio_off(priv);
975}
976
977void ipw_led_init(struct ipw_priv *priv)
978{
979 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
980
981 /* Set the default PINs for the link and activity leds */
982 priv->led_activity_on = IPW_ACTIVITY_LED;
983 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
984
985 priv->led_association_on = IPW_ASSOCIATED_LED;
986 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
987
988 /* Set the default PINs for the OFDM leds */
989 priv->led_ofdm_on = IPW_OFDM_LED;
990 priv->led_ofdm_off = ~(IPW_OFDM_LED);
991
992 switch (priv->nic_type) {
993 case EEPROM_NIC_TYPE_1:
994 /* In this NIC type, the LEDs are reversed.... */
995 priv->led_activity_on = IPW_ASSOCIATED_LED;
996 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
997 priv->led_association_on = IPW_ACTIVITY_LED;
998 priv->led_association_off = ~(IPW_ACTIVITY_LED);
999
1000 if (!(priv->config & CFG_NO_LED))
1001 ipw_led_band_on(priv);
1002
1003 /* And we don't blink link LEDs for this nic, so
1004 * just return here */
1005 return;
1006
1007 case EEPROM_NIC_TYPE_3:
1008 case EEPROM_NIC_TYPE_2:
1009 case EEPROM_NIC_TYPE_4:
1010 case EEPROM_NIC_TYPE_0:
1011 break;
1012
1013 default:
1014 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1015 priv->nic_type);
1016 priv->nic_type = EEPROM_NIC_TYPE_0;
1017 break;
1018 }
1019
1020 if (!(priv->config & CFG_NO_LED)) {
1021 if (priv->status & STATUS_ASSOCIATED)
1022 ipw_led_link_on(priv);
1023 else
1024 ipw_led_link_off(priv);
1025 }
1026}
1027
1028void ipw_led_shutdown(struct ipw_priv *priv)
1029{
1030 ipw_led_activity_off(priv);
1031 ipw_led_link_off(priv);
1032 ipw_led_band_off(priv);
1033 cancel_delayed_work(&priv->led_link_on);
1034 cancel_delayed_work(&priv->led_link_off);
1035 cancel_delayed_work(&priv->led_act_off);
1036}
1037
639/* 1038/*
640 * The following adds a new attribute to the sysfs representation 1039 * The following adds a new attribute to the sysfs representation
641 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) 1040 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -647,8 +1046,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
647{ 1046{
648 return sprintf(buf, "0x%08X\n", ipw_debug_level); 1047 return sprintf(buf, "0x%08X\n", ipw_debug_level);
649} 1048}
650static ssize_t store_debug_level(struct device_driver *d, 1049
651 const char *buf, size_t count) 1050static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1051 size_t count)
652{ 1052{
653 char *p = (char *)buf; 1053 char *p = (char *)buf;
654 u32 val; 1054 u32 val;
@@ -672,75 +1072,263 @@ static ssize_t store_debug_level(struct device_driver *d,
672static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 1072static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
673 show_debug_level, store_debug_level); 1073 show_debug_level, store_debug_level);
674 1074
675static ssize_t show_status(struct device *d, 1075static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
676 struct device_attribute *attr, char *buf)
677{ 1076{
678 struct ipw_priv *p = d->driver_data; 1077 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
679 return sprintf(buf, "0x%08x\n", (int)p->status);
680} 1078}
681 1079
682static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 1080static void ipw_capture_event_log(struct ipw_priv *priv,
1081 u32 log_len, struct ipw_event *log)
1082{
1083 u32 base;
683 1084
684static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 1085 if (log_len) {
685 char *buf) 1086 base = ipw_read32(priv, IPW_EVENT_LOG);
1087 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1088 (u8 *) log, sizeof(*log) * log_len);
1089 }
1090}
1091
1092static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
686{ 1093{
687 struct ipw_priv *p = d->driver_data; 1094 struct ipw_fw_error *error;
688 return sprintf(buf, "0x%08x\n", (int)p->config); 1095 u32 log_len = ipw_get_event_log_len(priv);
1096 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1097 u32 elem_len = ipw_read_reg32(priv, base);
1098
1099 error = kmalloc(sizeof(*error) +
1100 sizeof(*error->elem) * elem_len +
1101 sizeof(*error->log) * log_len, GFP_ATOMIC);
1102 if (!error) {
1103 IPW_ERROR("Memory allocation for firmware error log "
1104 "failed.\n");
1105 return NULL;
1106 }
1107 error->jiffies = jiffies;
1108 error->status = priv->status;
1109 error->config = priv->config;
1110 error->elem_len = elem_len;
1111 error->log_len = log_len;
1112 error->elem = (struct ipw_error_elem *)error->payload;
1113 error->log = (struct ipw_event *)(error->elem +
1114 (sizeof(*error->elem) * elem_len));
1115
1116 ipw_capture_event_log(priv, log_len, error->log);
1117
1118 if (elem_len)
1119 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1120 sizeof(*error->elem) * elem_len);
1121
1122 return error;
689} 1123}
690 1124
691static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 1125static void ipw_free_error_log(struct ipw_fw_error *error)
1126{
1127 if (error)
1128 kfree(error);
1129}
692 1130
693static ssize_t show_nic_type(struct device *d, 1131static ssize_t show_event_log(struct device *d,
694 struct device_attribute *attr, char *buf) 1132 struct device_attribute *attr, char *buf)
695{ 1133{
696 struct ipw_priv *p = d->driver_data; 1134 struct ipw_priv *priv = dev_get_drvdata(d);
697 u8 type = p->eeprom[EEPROM_NIC_TYPE]; 1135 u32 log_len = ipw_get_event_log_len(priv);
1136 struct ipw_event log[log_len];
1137 u32 len = 0, i;
1138
1139 ipw_capture_event_log(priv, log_len, log);
1140
1141 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1142 for (i = 0; i < log_len; i++)
1143 len += snprintf(buf + len, PAGE_SIZE - len,
1144 "\n%08X%08X%08X",
1145 log[i].time, log[i].event, log[i].data);
1146 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1147 return len;
1148}
698 1149
699 switch (type) { 1150static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
700 case EEPROM_NIC_TYPE_STANDARD: 1151
701 return sprintf(buf, "STANDARD\n"); 1152static ssize_t show_error(struct device *d,
702 case EEPROM_NIC_TYPE_DELL: 1153 struct device_attribute *attr, char *buf)
703 return sprintf(buf, "DELL\n"); 1154{
704 case EEPROM_NIC_TYPE_FUJITSU: 1155 struct ipw_priv *priv = dev_get_drvdata(d);
705 return sprintf(buf, "FUJITSU\n"); 1156 u32 len = 0, i;
706 case EEPROM_NIC_TYPE_IBM: 1157 if (!priv->error)
707 return sprintf(buf, "IBM\n"); 1158 return 0;
708 case EEPROM_NIC_TYPE_HP: 1159 len += snprintf(buf + len, PAGE_SIZE - len,
709 return sprintf(buf, "HP\n"); 1160 "%08lX%08X%08X%08X",
1161 priv->error->jiffies,
1162 priv->error->status,
1163 priv->error->config, priv->error->elem_len);
1164 for (i = 0; i < priv->error->elem_len; i++)
1165 len += snprintf(buf + len, PAGE_SIZE - len,
1166 "\n%08X%08X%08X%08X%08X%08X%08X",
1167 priv->error->elem[i].time,
1168 priv->error->elem[i].desc,
1169 priv->error->elem[i].blink1,
1170 priv->error->elem[i].blink2,
1171 priv->error->elem[i].link1,
1172 priv->error->elem[i].link2,
1173 priv->error->elem[i].data);
1174
1175 len += snprintf(buf + len, PAGE_SIZE - len,
1176 "\n%08X", priv->error->log_len);
1177 for (i = 0; i < priv->error->log_len; i++)
1178 len += snprintf(buf + len, PAGE_SIZE - len,
1179 "\n%08X%08X%08X",
1180 priv->error->log[i].time,
1181 priv->error->log[i].event,
1182 priv->error->log[i].data);
1183 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1184 return len;
1185}
1186
1187static ssize_t clear_error(struct device *d,
1188 struct device_attribute *attr,
1189 const char *buf, size_t count)
1190{
1191 struct ipw_priv *priv = dev_get_drvdata(d);
1192 if (priv->error) {
1193 ipw_free_error_log(priv->error);
1194 priv->error = NULL;
710 } 1195 }
1196 return count;
1197}
1198
1199static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
711 1200
712 return sprintf(buf, "UNKNOWN\n"); 1201static ssize_t show_cmd_log(struct device *d,
1202 struct device_attribute *attr, char *buf)
1203{
1204 struct ipw_priv *priv = dev_get_drvdata(d);
1205 u32 len = 0, i;
1206 if (!priv->cmdlog)
1207 return 0;
1208 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1209 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1210 i = (i + 1) % priv->cmdlog_len) {
1211 len +=
1212 snprintf(buf + len, PAGE_SIZE - len,
1213 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1214 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1215 priv->cmdlog[i].cmd.len);
1216 len +=
1217 snprintk_buf(buf + len, PAGE_SIZE - len,
1218 (u8 *) priv->cmdlog[i].cmd.param,
1219 priv->cmdlog[i].cmd.len);
1220 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1221 }
1222 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1223 return len;
713} 1224}
714 1225
715static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1226static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
716 1227
717static ssize_t dump_error_log(struct device *d, 1228static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
718 struct device_attribute *attr, const char *buf, 1229 char *buf)
719 size_t count)
720{ 1230{
721 char *p = (char *)buf; 1231 struct ipw_priv *priv = dev_get_drvdata(d);
1232 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1233}
722 1234
723 if (p[0] == '1') 1235static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
724 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data); 1236 const char *buf, size_t count)
1237{
1238 struct ipw_priv *priv = dev_get_drvdata(d);
1239#ifdef CONFIG_IPW_DEBUG
1240 struct net_device *dev = priv->net_dev;
1241#endif
1242 char buffer[] = "00000000";
1243 unsigned long len =
1244 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1245 unsigned long val;
1246 char *p = buffer;
725 1247
726 return strnlen(buf, count); 1248 IPW_DEBUG_INFO("enter\n");
1249
1250 strncpy(buffer, buf, len);
1251 buffer[len] = 0;
1252
1253 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1254 p++;
1255 if (p[0] == 'x' || p[0] == 'X')
1256 p++;
1257 val = simple_strtoul(p, &p, 16);
1258 } else
1259 val = simple_strtoul(p, &p, 10);
1260 if (p == buffer) {
1261 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1262 } else {
1263 priv->ieee->scan_age = val;
1264 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1265 }
1266
1267 IPW_DEBUG_INFO("exit\n");
1268 return len;
727} 1269}
728 1270
729static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); 1271static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
730 1272
731static ssize_t dump_event_log(struct device *d, 1273static ssize_t show_led(struct device *d, struct device_attribute *attr,
732 struct device_attribute *attr, const char *buf, 1274 char *buf)
733 size_t count)
734{ 1275{
735 char *p = (char *)buf; 1276 struct ipw_priv *priv = dev_get_drvdata(d);
1277 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1278}
736 1279
737 if (p[0] == '1') 1280static ssize_t store_led(struct device *d, struct device_attribute *attr,
738 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data); 1281 const char *buf, size_t count)
1282{
1283 struct ipw_priv *priv = dev_get_drvdata(d);
739 1284
740 return strnlen(buf, count); 1285 IPW_DEBUG_INFO("enter\n");
1286
1287 if (count == 0)
1288 return 0;
1289
1290 if (*buf == 0) {
1291 IPW_DEBUG_LED("Disabling LED control.\n");
1292 priv->config |= CFG_NO_LED;
1293 ipw_led_shutdown(priv);
1294 } else {
1295 IPW_DEBUG_LED("Enabling LED control.\n");
1296 priv->config &= ~CFG_NO_LED;
1297 ipw_led_init(priv);
1298 }
1299
1300 IPW_DEBUG_INFO("exit\n");
1301 return count;
1302}
1303
1304static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1305
1306static ssize_t show_status(struct device *d,
1307 struct device_attribute *attr, char *buf)
1308{
1309 struct ipw_priv *p = d->driver_data;
1310 return sprintf(buf, "0x%08x\n", (int)p->status);
741} 1311}
742 1312
743static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); 1313static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1314
1315static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1316 char *buf)
1317{
1318 struct ipw_priv *p = d->driver_data;
1319 return sprintf(buf, "0x%08x\n", (int)p->config);
1320}
1321
1322static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1323
1324static ssize_t show_nic_type(struct device *d,
1325 struct device_attribute *attr, char *buf)
1326{
1327 struct ipw_priv *priv = d->driver_data;
1328 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
1329}
1330
1331static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
744 1332
745static ssize_t show_ucode_version(struct device *d, 1333static ssize_t show_ucode_version(struct device *d,
746 struct device_attribute *attr, char *buf) 1334 struct device_attribute *attr, char *buf)
@@ -798,7 +1386,7 @@ static ssize_t show_command_event_reg(struct device *d,
798 u32 reg = 0; 1386 u32 reg = 0;
799 struct ipw_priv *p = d->driver_data; 1387 struct ipw_priv *p = d->driver_data;
800 1388
801 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT); 1389 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
802 return sprintf(buf, "0x%08x\n", reg); 1390 return sprintf(buf, "0x%08x\n", reg);
803} 1391}
804static ssize_t store_command_event_reg(struct device *d, 1392static ssize_t store_command_event_reg(struct device *d,
@@ -809,7 +1397,7 @@ static ssize_t store_command_event_reg(struct device *d,
809 struct ipw_priv *p = d->driver_data; 1397 struct ipw_priv *p = d->driver_data;
810 1398
811 sscanf(buf, "%x", &reg); 1399 sscanf(buf, "%x", &reg);
812 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); 1400 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
813 return strnlen(buf, count); 1401 return strnlen(buf, count);
814} 1402}
815 1403
@@ -845,6 +1433,7 @@ static ssize_t show_indirect_dword(struct device *d,
845{ 1433{
846 u32 reg = 0; 1434 u32 reg = 0;
847 struct ipw_priv *priv = d->driver_data; 1435 struct ipw_priv *priv = d->driver_data;
1436
848 if (priv->status & STATUS_INDIRECT_DWORD) 1437 if (priv->status & STATUS_INDIRECT_DWORD)
849 reg = ipw_read_reg32(priv, priv->indirect_dword); 1438 reg = ipw_read_reg32(priv, priv->indirect_dword);
850 else 1439 else
@@ -871,6 +1460,7 @@ static ssize_t show_indirect_byte(struct device *d,
871{ 1460{
872 u8 reg = 0; 1461 u8 reg = 0;
873 struct ipw_priv *priv = d->driver_data; 1462 struct ipw_priv *priv = d->driver_data;
1463
874 if (priv->status & STATUS_INDIRECT_BYTE) 1464 if (priv->status & STATUS_INDIRECT_BYTE)
875 reg = ipw_read_reg8(priv, priv->indirect_byte); 1465 reg = ipw_read_reg8(priv, priv->indirect_byte);
876 else 1466 else
@@ -945,7 +1535,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
945static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) 1535static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
946{ 1536{
947 if ((disable_radio ? 1 : 0) == 1537 if ((disable_radio ? 1 : 0) ==
948 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 1538 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
949 return 0; 1539 return 0;
950 1540
951 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 1541 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -954,10 +1544,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
954 if (disable_radio) { 1544 if (disable_radio) {
955 priv->status |= STATUS_RF_KILL_SW; 1545 priv->status |= STATUS_RF_KILL_SW;
956 1546
957 if (priv->workqueue) { 1547 if (priv->workqueue)
958 cancel_delayed_work(&priv->request_scan); 1548 cancel_delayed_work(&priv->request_scan);
959 }
960 wake_up_interruptible(&priv->wait_command_queue);
961 queue_work(priv->workqueue, &priv->down); 1549 queue_work(priv->workqueue, &priv->down);
962 } else { 1550 } else {
963 priv->status &= ~STATUS_RF_KILL_SW; 1551 priv->status &= ~STATUS_RF_KILL_SW;
@@ -987,6 +1575,93 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
987 1575
988static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 1576static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
989 1577
1578static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1579 char *buf)
1580{
1581 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1582 int pos = 0, len = 0;
1583 if (priv->config & CFG_SPEED_SCAN) {
1584 while (priv->speed_scan[pos] != 0)
1585 len += sprintf(&buf[len], "%d ",
1586 priv->speed_scan[pos++]);
1587 return len + sprintf(&buf[len], "\n");
1588 }
1589
1590 return sprintf(buf, "0\n");
1591}
1592
1593static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1594 const char *buf, size_t count)
1595{
1596 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1597 int channel, pos = 0;
1598 const char *p = buf;
1599
1600 /* list of space separated channels to scan, optionally ending with 0 */
1601 while ((channel = simple_strtol(p, NULL, 0))) {
1602 if (pos == MAX_SPEED_SCAN - 1) {
1603 priv->speed_scan[pos] = 0;
1604 break;
1605 }
1606
1607 if (ipw_is_valid_channel(priv->ieee, channel))
1608 priv->speed_scan[pos++] = channel;
1609 else
1610 IPW_WARNING("Skipping invalid channel request: %d\n",
1611 channel);
1612 p = strchr(p, ' ');
1613 if (!p)
1614 break;
1615 while (*p == ' ' || *p == '\t')
1616 p++;
1617 }
1618
1619 if (pos == 0)
1620 priv->config &= ~CFG_SPEED_SCAN;
1621 else {
1622 priv->speed_scan_pos = 0;
1623 priv->config |= CFG_SPEED_SCAN;
1624 }
1625
1626 return count;
1627}
1628
1629static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1630 store_speed_scan);
1631
1632static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1633 char *buf)
1634{
1635 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1636 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1637}
1638
1639static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1640 const char *buf, size_t count)
1641{
1642 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1643 if (buf[0] == '1')
1644 priv->config |= CFG_NET_STATS;
1645 else
1646 priv->config &= ~CFG_NET_STATS;
1647
1648 return count;
1649}
1650
1651static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1652 show_net_stats, store_net_stats);
1653
1654static void notify_wx_assoc_event(struct ipw_priv *priv)
1655{
1656 union iwreq_data wrqu;
1657 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1658 if (priv->status & STATUS_ASSOCIATED)
1659 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1660 else
1661 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1662 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1663}
1664
990static void ipw_irq_tasklet(struct ipw_priv *priv) 1665static void ipw_irq_tasklet(struct ipw_priv *priv)
991{ 1666{
992 u32 inta, inta_mask, handled = 0; 1667 u32 inta, inta_mask, handled = 0;
@@ -995,102 +1670,135 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
995 1670
996 spin_lock_irqsave(&priv->lock, flags); 1671 spin_lock_irqsave(&priv->lock, flags);
997 1672
998 inta = ipw_read32(priv, CX2_INTA_RW); 1673 inta = ipw_read32(priv, IPW_INTA_RW);
999 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 1674 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1000 inta &= (CX2_INTA_MASK_ALL & inta_mask); 1675 inta &= (IPW_INTA_MASK_ALL & inta_mask);
1001 1676
1002 /* Add any cached INTA values that need to be handled */ 1677 /* Add any cached INTA values that need to be handled */
1003 inta |= priv->isr_inta; 1678 inta |= priv->isr_inta;
1004 1679
1005 /* handle all the justifications for the interrupt */ 1680 /* handle all the justifications for the interrupt */
1006 if (inta & CX2_INTA_BIT_RX_TRANSFER) { 1681 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1007 ipw_rx(priv); 1682 ipw_rx(priv);
1008 handled |= CX2_INTA_BIT_RX_TRANSFER; 1683 handled |= IPW_INTA_BIT_RX_TRANSFER;
1009 } 1684 }
1010 1685
1011 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { 1686 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
1012 IPW_DEBUG_HC("Command completed.\n"); 1687 IPW_DEBUG_HC("Command completed.\n");
1013 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1); 1688 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
1014 priv->status &= ~STATUS_HCMD_ACTIVE; 1689 priv->status &= ~STATUS_HCMD_ACTIVE;
1015 wake_up_interruptible(&priv->wait_command_queue); 1690 wake_up_interruptible(&priv->wait_command_queue);
1016 handled |= CX2_INTA_BIT_TX_CMD_QUEUE; 1691 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
1017 } 1692 }
1018 1693
1019 if (inta & CX2_INTA_BIT_TX_QUEUE_1) { 1694 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
1020 IPW_DEBUG_TX("TX_QUEUE_1\n"); 1695 IPW_DEBUG_TX("TX_QUEUE_1\n");
1021 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0); 1696 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
1022 handled |= CX2_INTA_BIT_TX_QUEUE_1; 1697 handled |= IPW_INTA_BIT_TX_QUEUE_1;
1023 } 1698 }
1024 1699
1025 if (inta & CX2_INTA_BIT_TX_QUEUE_2) { 1700 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
1026 IPW_DEBUG_TX("TX_QUEUE_2\n"); 1701 IPW_DEBUG_TX("TX_QUEUE_2\n");
1027 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1); 1702 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
1028 handled |= CX2_INTA_BIT_TX_QUEUE_2; 1703 handled |= IPW_INTA_BIT_TX_QUEUE_2;
1029 } 1704 }
1030 1705
1031 if (inta & CX2_INTA_BIT_TX_QUEUE_3) { 1706 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
1032 IPW_DEBUG_TX("TX_QUEUE_3\n"); 1707 IPW_DEBUG_TX("TX_QUEUE_3\n");
1033 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2); 1708 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
1034 handled |= CX2_INTA_BIT_TX_QUEUE_3; 1709 handled |= IPW_INTA_BIT_TX_QUEUE_3;
1035 } 1710 }
1036 1711
1037 if (inta & CX2_INTA_BIT_TX_QUEUE_4) { 1712 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
1038 IPW_DEBUG_TX("TX_QUEUE_4\n"); 1713 IPW_DEBUG_TX("TX_QUEUE_4\n");
1039 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3); 1714 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
1040 handled |= CX2_INTA_BIT_TX_QUEUE_4; 1715 handled |= IPW_INTA_BIT_TX_QUEUE_4;
1041 } 1716 }
1042 1717
1043 if (inta & CX2_INTA_BIT_STATUS_CHANGE) { 1718 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
1044 IPW_WARNING("STATUS_CHANGE\n"); 1719 IPW_WARNING("STATUS_CHANGE\n");
1045 handled |= CX2_INTA_BIT_STATUS_CHANGE; 1720 handled |= IPW_INTA_BIT_STATUS_CHANGE;
1046 } 1721 }
1047 1722
1048 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) { 1723 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1049 IPW_WARNING("TX_PERIOD_EXPIRED\n"); 1724 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1050 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED; 1725 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
1051 } 1726 }
1052 1727
1053 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) { 1728 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1054 IPW_WARNING("HOST_CMD_DONE\n"); 1729 IPW_WARNING("HOST_CMD_DONE\n");
1055 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE; 1730 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1056 } 1731 }
1057 1732
1058 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) { 1733 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
1059 IPW_WARNING("FW_INITIALIZATION_DONE\n"); 1734 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1060 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE; 1735 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
1061 } 1736 }
1062 1737
1063 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) { 1738 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1064 IPW_WARNING("PHY_OFF_DONE\n"); 1739 IPW_WARNING("PHY_OFF_DONE\n");
1065 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE; 1740 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1066 } 1741 }
1067 1742
1068 if (inta & CX2_INTA_BIT_RF_KILL_DONE) { 1743 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
1069 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 1744 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1070 priv->status |= STATUS_RF_KILL_HW; 1745 priv->status |= STATUS_RF_KILL_HW;
1071 wake_up_interruptible(&priv->wait_command_queue); 1746 wake_up_interruptible(&priv->wait_command_queue);
1072 netif_carrier_off(priv->net_dev); 1747 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1073 netif_stop_queue(priv->net_dev);
1074 cancel_delayed_work(&priv->request_scan); 1748 cancel_delayed_work(&priv->request_scan);
1749 schedule_work(&priv->link_down);
1075 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1750 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1076 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1751 handled |= IPW_INTA_BIT_RF_KILL_DONE;
1077 } 1752 }
1078 1753
1079 if (inta & CX2_INTA_BIT_FATAL_ERROR) { 1754 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1080 IPW_ERROR("Firmware error detected. Restarting.\n"); 1755 IPW_ERROR("Firmware error detected. Restarting.\n");
1756 if (priv->error) {
1757 IPW_ERROR("Sysfs 'error' log already exists.\n");
1081#ifdef CONFIG_IPW_DEBUG 1758#ifdef CONFIG_IPW_DEBUG
1082 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1759 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1083 ipw_dump_nic_error_log(priv); 1760 struct ipw_fw_error *error =
1084 ipw_dump_nic_event_log(priv); 1761 ipw_alloc_error_log(priv);
1085 } 1762 ipw_dump_error_log(priv, error);
1763 if (error)
1764 ipw_free_error_log(error);
1765 }
1086#endif 1766#endif
1767 } else {
1768 priv->error = ipw_alloc_error_log(priv);
1769 if (priv->error)
1770 IPW_ERROR("Sysfs 'error' log captured.\n");
1771 else
1772 IPW_ERROR("Error allocating sysfs 'error' "
1773 "log.\n");
1774#ifdef CONFIG_IPW_DEBUG
1775 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1776 ipw_dump_error_log(priv, priv->error);
1777#endif
1778 }
1779
1780 /* XXX: If hardware encryption is for WPA/WPA2,
1781 * we have to notify the supplicant. */
1782 if (priv->ieee->sec.encrypt) {
1783 priv->status &= ~STATUS_ASSOCIATED;
1784 notify_wx_assoc_event(priv);
1785 }
1786
1787 /* Keep the restart process from trying to send host
1788 * commands by clearing the INIT status bit */
1789 priv->status &= ~STATUS_INIT;
1790
1791 /* Cancel currently queued command. */
1792 priv->status &= ~STATUS_HCMD_ACTIVE;
1793 wake_up_interruptible(&priv->wait_command_queue);
1794
1087 queue_work(priv->workqueue, &priv->adapter_restart); 1795 queue_work(priv->workqueue, &priv->adapter_restart);
1088 handled |= CX2_INTA_BIT_FATAL_ERROR; 1796 handled |= IPW_INTA_BIT_FATAL_ERROR;
1089 } 1797 }
1090 1798
1091 if (inta & CX2_INTA_BIT_PARITY_ERROR) { 1799 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
1092 IPW_ERROR("Parity error\n"); 1800 IPW_ERROR("Parity error\n");
1093 handled |= CX2_INTA_BIT_PARITY_ERROR; 1801 handled |= IPW_INTA_BIT_PARITY_ERROR;
1094 } 1802 }
1095 1803
1096 if (handled != inta) { 1804 if (handled != inta) {
@@ -1103,7 +1811,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1103 spin_unlock_irqrestore(&priv->lock, flags); 1811 spin_unlock_irqrestore(&priv->lock, flags);
1104} 1812}
1105 1813
1106#ifdef CONFIG_IPW_DEBUG
1107#define IPW_CMD(x) case IPW_CMD_ ## x : return #x 1814#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1108static char *get_cmd_string(u8 cmd) 1815static char *get_cmd_string(u8 cmd)
1109{ 1816{
@@ -1162,44 +1869,78 @@ static char *get_cmd_string(u8 cmd)
1162 return "UNKNOWN"; 1869 return "UNKNOWN";
1163 } 1870 }
1164} 1871}
1165#endif /* CONFIG_IPW_DEBUG */
1166 1872
1167#define HOST_COMPLETE_TIMEOUT HZ 1873#define HOST_COMPLETE_TIMEOUT HZ
1168static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1874static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1169{ 1875{
1170 int rc = 0; 1876 int rc = 0;
1877 unsigned long flags;
1171 1878
1879 spin_lock_irqsave(&priv->lock, flags);
1172 if (priv->status & STATUS_HCMD_ACTIVE) { 1880 if (priv->status & STATUS_HCMD_ACTIVE) {
1173 IPW_ERROR("Already sending a command\n"); 1881 IPW_ERROR("Failed to send %s: Already sending a command.\n",
1174 return -1; 1882 get_cmd_string(cmd->cmd));
1883 spin_unlock_irqrestore(&priv->lock, flags);
1884 return -EAGAIN;
1175 } 1885 }
1176 1886
1177 priv->status |= STATUS_HCMD_ACTIVE; 1887 priv->status |= STATUS_HCMD_ACTIVE;
1178 1888
1179 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 1889 if (priv->cmdlog) {
1180 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); 1890 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
1891 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
1892 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
1893 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
1894 cmd->len);
1895 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
1896 }
1897
1898 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1899 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1900 priv->status);
1181 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); 1901 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1182 1902
1183 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1903 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1184 if (rc) 1904 if (rc) {
1185 return rc; 1905 priv->status &= ~STATUS_HCMD_ACTIVE;
1906 IPW_ERROR("Failed to send %s: Reason %d\n",
1907 get_cmd_string(cmd->cmd), rc);
1908 spin_unlock_irqrestore(&priv->lock, flags);
1909 goto exit;
1910 }
1911 spin_unlock_irqrestore(&priv->lock, flags);
1186 1912
1187 rc = wait_event_interruptible_timeout(priv->wait_command_queue, 1913 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1188 !(priv-> 1914 !(priv->
1189 status & STATUS_HCMD_ACTIVE), 1915 status & STATUS_HCMD_ACTIVE),
1190 HOST_COMPLETE_TIMEOUT); 1916 HOST_COMPLETE_TIMEOUT);
1191 if (rc == 0) { 1917 if (rc == 0) {
1192 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 1918 spin_lock_irqsave(&priv->lock, flags);
1193 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1919 if (priv->status & STATUS_HCMD_ACTIVE) {
1194 priv->status &= ~STATUS_HCMD_ACTIVE; 1920 IPW_ERROR("Failed to send %s: Command timed out.\n",
1195 return -EIO; 1921 get_cmd_string(cmd->cmd));
1196 } 1922 priv->status &= ~STATUS_HCMD_ACTIVE;
1197 if (priv->status & STATUS_RF_KILL_MASK) { 1923 spin_unlock_irqrestore(&priv->lock, flags);
1198 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n"); 1924 rc = -EIO;
1199 return -EIO; 1925 goto exit;
1926 }
1927 spin_unlock_irqrestore(&priv->lock, flags);
1928 } else
1929 rc = 0;
1930
1931 if (priv->status & STATUS_RF_KILL_HW) {
1932 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
1933 get_cmd_string(cmd->cmd));
1934 rc = -EIO;
1935 goto exit;
1200 } 1936 }
1201 1937
1202 return 0; 1938 exit:
1939 if (priv->cmdlog) {
1940 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
1941 priv->cmdlog_pos %= priv->cmdlog_len;
1942 }
1943 return rc;
1203} 1944}
1204 1945
1205static int ipw_send_host_complete(struct ipw_priv *priv) 1946static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -1214,12 +1955,7 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
1214 return -1; 1955 return -1;
1215 } 1956 }
1216 1957
1217 if (ipw_send_cmd(priv, &cmd)) { 1958 return ipw_send_cmd(priv, &cmd);
1218 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1219 return -1;
1220 }
1221
1222 return 0;
1223} 1959}
1224 1960
1225static int ipw_send_system_config(struct ipw_priv *priv, 1961static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1235,13 +1971,8 @@ static int ipw_send_system_config(struct ipw_priv *priv,
1235 return -1; 1971 return -1;
1236 } 1972 }
1237 1973
1238 memcpy(&cmd.param, config, sizeof(*config)); 1974 memcpy(cmd.param, config, sizeof(*config));
1239 if (ipw_send_cmd(priv, &cmd)) { 1975 return ipw_send_cmd(priv, &cmd);
1240 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1241 return -1;
1242 }
1243
1244 return 0;
1245} 1976}
1246 1977
1247static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 1978static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1256,13 +1987,8 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
1256 return -1; 1987 return -1;
1257 } 1988 }
1258 1989
1259 memcpy(&cmd.param, ssid, cmd.len); 1990 memcpy(cmd.param, ssid, cmd.len);
1260 if (ipw_send_cmd(priv, &cmd)) { 1991 return ipw_send_cmd(priv, &cmd);
1261 IPW_ERROR("failed to send SSID command\n");
1262 return -1;
1263 }
1264
1265 return 0;
1266} 1992}
1267 1993
1268static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) 1994static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1280,16 +2006,15 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1280 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", 2006 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1281 priv->net_dev->name, MAC_ARG(mac)); 2007 priv->net_dev->name, MAC_ARG(mac));
1282 2008
1283 memcpy(&cmd.param, mac, ETH_ALEN); 2009 memcpy(cmd.param, mac, ETH_ALEN);
1284 2010 return ipw_send_cmd(priv, &cmd);
1285 if (ipw_send_cmd(priv, &cmd)) {
1286 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1287 return -1;
1288 }
1289
1290 return 0;
1291} 2011}
1292 2012
2013/*
2014 * NOTE: This must be executed from our workqueue as it results in udelay
2015 * being called which may corrupt the keyboard if executed on default
2016 * workqueue
2017 */
1293static void ipw_adapter_restart(void *adapter) 2018static void ipw_adapter_restart(void *adapter)
1294{ 2019{
1295 struct ipw_priv *priv = adapter; 2020 struct ipw_priv *priv = adapter;
@@ -1298,12 +2023,25 @@ static void ipw_adapter_restart(void *adapter)
1298 return; 2023 return;
1299 2024
1300 ipw_down(priv); 2025 ipw_down(priv);
2026
2027 if (priv->assoc_network &&
2028 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2029 ipw_remove_current_network(priv);
2030
1301 if (ipw_up(priv)) { 2031 if (ipw_up(priv)) {
1302 IPW_ERROR("Failed to up device\n"); 2032 IPW_ERROR("Failed to up device\n");
1303 return; 2033 return;
1304 } 2034 }
1305} 2035}
1306 2036
2037static void ipw_bg_adapter_restart(void *data)
2038{
2039 struct ipw_priv *priv = data;
2040 down(&priv->sem);
2041 ipw_adapter_restart(data);
2042 up(&priv->sem);
2043}
2044
1307#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2045#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1308 2046
1309static void ipw_scan_check(void *data) 2047static void ipw_scan_check(void *data)
@@ -1313,10 +2051,18 @@ static void ipw_scan_check(void *data)
1313 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2051 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1314 "adapter (%dms).\n", 2052 "adapter (%dms).\n",
1315 IPW_SCAN_CHECK_WATCHDOG / 100); 2053 IPW_SCAN_CHECK_WATCHDOG / 100);
1316 ipw_adapter_restart(priv); 2054 queue_work(priv->workqueue, &priv->adapter_restart);
1317 } 2055 }
1318} 2056}
1319 2057
2058static void ipw_bg_scan_check(void *data)
2059{
2060 struct ipw_priv *priv = data;
2061 down(&priv->sem);
2062 ipw_scan_check(data);
2063 up(&priv->sem);
2064}
2065
1320static int ipw_send_scan_request_ext(struct ipw_priv *priv, 2066static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1321 struct ipw_scan_request_ext *request) 2067 struct ipw_scan_request_ext *request)
1322{ 2068{
@@ -1325,20 +2071,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1325 .len = sizeof(*request) 2071 .len = sizeof(*request)
1326 }; 2072 };
1327 2073
1328 if (!priv || !request) { 2074 memcpy(cmd.param, request, sizeof(*request));
1329 IPW_ERROR("Invalid args\n"); 2075 return ipw_send_cmd(priv, &cmd);
1330 return -1;
1331 }
1332
1333 memcpy(&cmd.param, request, sizeof(*request));
1334 if (ipw_send_cmd(priv, &cmd)) {
1335 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1336 return -1;
1337 }
1338
1339 queue_delayed_work(priv->workqueue, &priv->scan_check,
1340 IPW_SCAN_CHECK_WATCHDOG);
1341 return 0;
1342} 2076}
1343 2077
1344static int ipw_send_scan_abort(struct ipw_priv *priv) 2078static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -1353,12 +2087,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
1353 return -1; 2087 return -1;
1354 } 2088 }
1355 2089
1356 if (ipw_send_cmd(priv, &cmd)) { 2090 return ipw_send_cmd(priv, &cmd);
1357 IPW_ERROR("failed to send SCAN_ABORT command\n");
1358 return -1;
1359 }
1360
1361 return 0;
1362} 2091}
1363 2092
1364static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2093static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -1370,12 +2099,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1370 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) 2099 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
1371 &cmd.param; 2100 &cmd.param;
1372 calib->beacon_rssi_raw = sens; 2101 calib->beacon_rssi_raw = sens;
1373 if (ipw_send_cmd(priv, &cmd)) { 2102 return ipw_send_cmd(priv, &cmd);
1374 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1375 return -1;
1376 }
1377
1378 return 0;
1379} 2103}
1380 2104
1381static int ipw_send_associate(struct ipw_priv *priv, 2105static int ipw_send_associate(struct ipw_priv *priv,
@@ -1386,18 +2110,26 @@ static int ipw_send_associate(struct ipw_priv *priv,
1386 .len = sizeof(*associate) 2110 .len = sizeof(*associate)
1387 }; 2111 };
1388 2112
2113 struct ipw_associate tmp_associate;
2114 memcpy(&tmp_associate, associate, sizeof(*associate));
2115 tmp_associate.policy_support =
2116 cpu_to_le16(tmp_associate.policy_support);
2117 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
2118 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
2119 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
2120 tmp_associate.listen_interval =
2121 cpu_to_le16(tmp_associate.listen_interval);
2122 tmp_associate.beacon_interval =
2123 cpu_to_le16(tmp_associate.beacon_interval);
2124 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2125
1389 if (!priv || !associate) { 2126 if (!priv || !associate) {
1390 IPW_ERROR("Invalid args\n"); 2127 IPW_ERROR("Invalid args\n");
1391 return -1; 2128 return -1;
1392 } 2129 }
1393 2130
1394 memcpy(&cmd.param, associate, sizeof(*associate)); 2131 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
1395 if (ipw_send_cmd(priv, &cmd)) { 2132 return ipw_send_cmd(priv, &cmd);
1396 IPW_ERROR("failed to send ASSOCIATE command\n");
1397 return -1;
1398 }
1399
1400 return 0;
1401} 2133}
1402 2134
1403static int ipw_send_supported_rates(struct ipw_priv *priv, 2135static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -1413,13 +2145,8 @@ static int ipw_send_supported_rates(struct ipw_priv *priv,
1413 return -1; 2145 return -1;
1414 } 2146 }
1415 2147
1416 memcpy(&cmd.param, rates, sizeof(*rates)); 2148 memcpy(cmd.param, rates, sizeof(*rates));
1417 if (ipw_send_cmd(priv, &cmd)) { 2149 return ipw_send_cmd(priv, &cmd);
1418 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1419 return -1;
1420 }
1421
1422 return 0;
1423} 2150}
1424 2151
1425static int ipw_set_random_seed(struct ipw_priv *priv) 2152static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -1436,15 +2163,9 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
1436 2163
1437 get_random_bytes(&cmd.param, sizeof(u32)); 2164 get_random_bytes(&cmd.param, sizeof(u32));
1438 2165
1439 if (ipw_send_cmd(priv, &cmd)) { 2166 return ipw_send_cmd(priv, &cmd);
1440 IPW_ERROR("failed to send SEED_NUMBER command\n");
1441 return -1;
1442 }
1443
1444 return 0;
1445} 2167}
1446 2168
1447#if 0
1448static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) 2169static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1449{ 2170{
1450 struct host_cmd cmd = { 2171 struct host_cmd cmd = {
@@ -1459,14 +2180,8 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1459 2180
1460 *((u32 *) & cmd.param) = phy_off; 2181 *((u32 *) & cmd.param) = phy_off;
1461 2182
1462 if (ipw_send_cmd(priv, &cmd)) { 2183 return ipw_send_cmd(priv, &cmd);
1463 IPW_ERROR("failed to send CARD_DISABLE command\n");
1464 return -1;
1465 }
1466
1467 return 0;
1468} 2184}
1469#endif
1470 2185
1471static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) 2186static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1472{ 2187{
@@ -1480,12 +2195,51 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1480 return -1; 2195 return -1;
1481 } 2196 }
1482 2197
1483 memcpy(&cmd.param, power, sizeof(*power)); 2198 memcpy(cmd.param, power, sizeof(*power));
1484 if (ipw_send_cmd(priv, &cmd)) { 2199 return ipw_send_cmd(priv, &cmd);
1485 IPW_ERROR("failed to send TX_POWER command\n"); 2200}
1486 return -1; 2201
2202static int ipw_set_tx_power(struct ipw_priv *priv)
2203{
2204 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
2205 struct ipw_tx_power tx_power;
2206 s8 max_power;
2207 int i;
2208
2209 memset(&tx_power, 0, sizeof(tx_power));
2210
2211 /* configure device for 'G' band */
2212 tx_power.ieee_mode = IPW_G_MODE;
2213 tx_power.num_channels = geo->bg_channels;
2214 for (i = 0; i < geo->bg_channels; i++) {
2215 max_power = geo->bg[i].max_power;
2216 tx_power.channels_tx_power[i].channel_number =
2217 geo->bg[i].channel;
2218 tx_power.channels_tx_power[i].tx_power = max_power ?
2219 min(max_power, priv->tx_power) : priv->tx_power;
1487 } 2220 }
2221 if (ipw_send_tx_power(priv, &tx_power))
2222 return -EIO;
2223
2224 /* configure device to also handle 'B' band */
2225 tx_power.ieee_mode = IPW_B_MODE;
2226 if (ipw_send_tx_power(priv, &tx_power))
2227 return -EIO;
1488 2228
2229 /* configure device to also handle 'A' band */
2230 if (priv->ieee->abg_true) {
2231 tx_power.ieee_mode = IPW_A_MODE;
2232 tx_power.num_channels = geo->a_channels;
2233 for (i = 0; i < tx_power.num_channels; i++) {
2234 max_power = geo->a[i].max_power;
2235 tx_power.channels_tx_power[i].channel_number =
2236 geo->a[i].channel;
2237 tx_power.channels_tx_power[i].tx_power = max_power ?
2238 min(max_power, priv->tx_power) : priv->tx_power;
2239 }
2240 if (ipw_send_tx_power(priv, &tx_power))
2241 return -EIO;
2242 }
1489 return 0; 2243 return 0;
1490} 2244}
1491 2245
@@ -1504,13 +2258,8 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1504 return -1; 2258 return -1;
1505 } 2259 }
1506 2260
1507 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold)); 2261 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
1508 if (ipw_send_cmd(priv, &cmd)) { 2262 return ipw_send_cmd(priv, &cmd);
1509 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1510 return -1;
1511 }
1512
1513 return 0;
1514} 2263}
1515 2264
1516static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2265static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -1528,13 +2277,8 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1528 return -1; 2277 return -1;
1529 } 2278 }
1530 2279
1531 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold)); 2280 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
1532 if (ipw_send_cmd(priv, &cmd)) { 2281 return ipw_send_cmd(priv, &cmd);
1533 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1534 return -1;
1535 }
1536
1537 return 0;
1538} 2282}
1539 2283
1540static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) 2284static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -1564,12 +2308,27 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
1564 break; 2308 break;
1565 } 2309 }
1566 2310
1567 if (ipw_send_cmd(priv, &cmd)) { 2311 return ipw_send_cmd(priv, &cmd);
1568 IPW_ERROR("failed to send POWER_MODE command\n"); 2312}
2313
2314static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2315{
2316 struct ipw_retry_limit retry_limit = {
2317 .short_retry_limit = slimit,
2318 .long_retry_limit = llimit
2319 };
2320 struct host_cmd cmd = {
2321 .cmd = IPW_CMD_RETRY_LIMIT,
2322 .len = sizeof(retry_limit)
2323 };
2324
2325 if (!priv) {
2326 IPW_ERROR("Invalid args\n");
1569 return -1; 2327 return -1;
1570 } 2328 }
1571 2329
1572 return 0; 2330 memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
2331 return ipw_send_cmd(priv, &cmd);
1573} 2332}
1574 2333
1575/* 2334/*
@@ -1671,8 +2430,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
1671/* data's copy of the eeprom data */ 2430/* data's copy of the eeprom data */
1672static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) 2431static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
1673{ 2432{
1674 u8 *ee = (u8 *) priv->eeprom; 2433 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
1675 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
1676} 2434}
1677 2435
1678/* 2436/*
@@ -1692,7 +2450,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1692 2450
1693 /* read entire contents of eeprom into private buffer */ 2451 /* read entire contents of eeprom into private buffer */
1694 for (i = 0; i < 128; i++) 2452 for (i = 0; i < 128; i++)
1695 eeprom[i] = eeprom_read_u16(priv, (u8) i); 2453 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
1696 2454
1697 /* 2455 /*
1698 If the data looks correct, then copy it to our private 2456 If the data looks correct, then copy it to our private
@@ -1703,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1703 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); 2461 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
1704 2462
1705 /* write the eeprom data to sram */ 2463 /* write the eeprom data to sram */
1706 for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++) 2464 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
1707 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]); 2465 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
1708 2466
1709 /* Do not load eeprom data on fatal error or suspend */ 2467 /* Do not load eeprom data on fatal error or suspend */
@@ -1723,14 +2481,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
1723 count >>= 2; 2481 count >>= 2;
1724 if (!count) 2482 if (!count)
1725 return; 2483 return;
1726 _ipw_write32(priv, CX2_AUTOINC_ADDR, start); 2484 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
1727 while (count--) 2485 while (count--)
1728 _ipw_write32(priv, CX2_AUTOINC_DATA, 0); 2486 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
1729} 2487}
1730 2488
1731static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) 2489static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
1732{ 2490{
1733 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL, 2491 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
1734 CB_NUMBER_OF_ELEMENTS_SMALL * 2492 CB_NUMBER_OF_ELEMENTS_SMALL *
1735 sizeof(struct command_block)); 2493 sizeof(struct command_block));
1736} 2494}
@@ -1744,7 +2502,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
1744 ipw_fw_dma_reset_command_blocks(priv); 2502 ipw_fw_dma_reset_command_blocks(priv);
1745 2503
1746 /* Write CB base address */ 2504 /* Write CB base address */
1747 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL); 2505 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
1748 2506
1749 IPW_DEBUG_FW("<< : \n"); 2507 IPW_DEBUG_FW("<< : \n");
1750 return 0; 2508 return 0;
@@ -1758,7 +2516,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
1758 2516
1759 //set the Stop and Abort bit 2517 //set the Stop and Abort bit
1760 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; 2518 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
1761 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2519 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1762 priv->sram_desc.last_cb_index = 0; 2520 priv->sram_desc.last_cb_index = 0;
1763 2521
1764 IPW_DEBUG_FW("<< \n"); 2522 IPW_DEBUG_FW("<< \n");
@@ -1768,7 +2526,7 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
1768 struct command_block *cb) 2526 struct command_block *cb)
1769{ 2527{
1770 u32 address = 2528 u32 address =
1771 CX2_SHARED_SRAM_DMA_CONTROL + 2529 IPW_SHARED_SRAM_DMA_CONTROL +
1772 (sizeof(struct command_block) * index); 2530 (sizeof(struct command_block) * index);
1773 IPW_DEBUG_FW(">> :\n"); 2531 IPW_DEBUG_FW(">> :\n");
1774 2532
@@ -1792,13 +2550,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv)
1792 &priv->sram_desc.cb_list[index]); 2550 &priv->sram_desc.cb_list[index]);
1793 2551
1794 /* Enable the DMA in the CSR register */ 2552 /* Enable the DMA in the CSR register */
1795 ipw_clear_bit(priv, CX2_RESET_REG, 2553 ipw_clear_bit(priv, IPW_RESET_REG,
1796 CX2_RESET_REG_MASTER_DISABLED | 2554 IPW_RESET_REG_MASTER_DISABLED |
1797 CX2_RESET_REG_STOP_MASTER); 2555 IPW_RESET_REG_STOP_MASTER);
1798 2556
1799 /* Set the Start bit. */ 2557 /* Set the Start bit. */
1800 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; 2558 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
1801 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2559 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1802 2560
1803 IPW_DEBUG_FW("<< :\n"); 2561 IPW_DEBUG_FW("<< :\n");
1804 return 0; 2562 return 0;
@@ -1811,12 +2569,12 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
1811 u32 cb_fields_address = 0; 2569 u32 cb_fields_address = 0;
1812 2570
1813 IPW_DEBUG_FW(">> :\n"); 2571 IPW_DEBUG_FW(">> :\n");
1814 address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2572 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1815 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2573 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
1816 2574
1817 /* Read the DMA Controlor register */ 2575 /* Read the DMA Controlor register */
1818 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); 2576 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
1819 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2577 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
1820 2578
1821 /* Print the CB values */ 2579 /* Print the CB values */
1822 cb_fields_address = address; 2580 cb_fields_address = address;
@@ -1845,9 +2603,9 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
1845 u32 current_cb_index = 0; 2603 u32 current_cb_index = 0;
1846 2604
1847 IPW_DEBUG_FW("<< :\n"); 2605 IPW_DEBUG_FW("<< :\n");
1848 current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2606 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1849 2607
1850 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) / 2608 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
1851 sizeof(struct command_block); 2609 sizeof(struct command_block);
1852 2610
1853 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2611 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
@@ -1976,8 +2734,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
1976 ipw_fw_dma_abort(priv); 2734 ipw_fw_dma_abort(priv);
1977 2735
1978 /*Disable the DMA in the CSR register */ 2736 /*Disable the DMA in the CSR register */
1979 ipw_set_bit(priv, CX2_RESET_REG, 2737 ipw_set_bit(priv, IPW_RESET_REG,
1980 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); 2738 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
1981 2739
1982 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2740 IPW_DEBUG_FW("<< dmaWaitSync \n");
1983 return 0; 2741 return 0;
@@ -1987,6 +2745,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1987{ 2745{
1988 struct list_head *element, *safe; 2746 struct list_head *element, *safe;
1989 struct ieee80211_network *network = NULL; 2747 struct ieee80211_network *network = NULL;
2748 unsigned long flags;
2749
2750 spin_lock_irqsave(&priv->ieee->lock, flags);
1990 list_for_each_safe(element, safe, &priv->ieee->network_list) { 2751 list_for_each_safe(element, safe, &priv->ieee->network_list) {
1991 network = list_entry(element, struct ieee80211_network, list); 2752 network = list_entry(element, struct ieee80211_network, list);
1992 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 2753 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -1995,6 +2756,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1995 &priv->ieee->network_free_list); 2756 &priv->ieee->network_free_list);
1996 } 2757 }
1997 } 2758 }
2759 spin_unlock_irqrestore(&priv->ieee->lock, flags);
1998} 2760}
1999 2761
2000/** 2762/**
@@ -2037,10 +2799,10 @@ static int ipw_stop_master(struct ipw_priv *priv)
2037 2799
2038 IPW_DEBUG_TRACE(">> \n"); 2800 IPW_DEBUG_TRACE(">> \n");
2039 /* stop master. typical delay - 0 */ 2801 /* stop master. typical delay - 0 */
2040 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 2802 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2041 2803
2042 rc = ipw_poll_bit(priv, CX2_RESET_REG, 2804 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2043 CX2_RESET_REG_MASTER_DISABLED, 100); 2805 IPW_RESET_REG_MASTER_DISABLED, 100);
2044 if (rc < 0) { 2806 if (rc < 0) {
2045 IPW_ERROR("stop master failed in 10ms\n"); 2807 IPW_ERROR("stop master failed in 10ms\n");
2046 return -1; 2808 return -1;
@@ -2056,7 +2818,7 @@ static void ipw_arc_release(struct ipw_priv *priv)
2056 IPW_DEBUG_TRACE(">> \n"); 2818 IPW_DEBUG_TRACE(">> \n");
2057 mdelay(5); 2819 mdelay(5);
2058 2820
2059 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 2821 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2060 2822
2061 /* no one knows timing, for safety add some delay */ 2823 /* no one knows timing, for safety add some delay */
2062 mdelay(5); 2824 mdelay(5);
@@ -2073,13 +2835,12 @@ struct fw_chunk {
2073}; 2835};
2074 2836
2075#define IPW_FW_MAJOR_VERSION 2 2837#define IPW_FW_MAJOR_VERSION 2
2076#define IPW_FW_MINOR_VERSION 2 2838#define IPW_FW_MINOR_VERSION 4
2077 2839
2078#define IPW_FW_MINOR(x) ((x & 0xff) >> 8) 2840#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2079#define IPW_FW_MAJOR(x) (x & 0xff) 2841#define IPW_FW_MAJOR(x) (x & 0xff)
2080 2842
2081#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \ 2843#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2082 IPW_FW_MAJOR_VERSION)
2083 2844
2084#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ 2845#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2085"." __stringify(IPW_FW_MINOR_VERSION) "-" 2846"." __stringify(IPW_FW_MINOR_VERSION) "-"
@@ -2107,8 +2868,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2107 2868
2108// spin_lock_irqsave(&priv->lock, flags); 2869// spin_lock_irqsave(&priv->lock, flags);
2109 2870
2110 for (addr = CX2_SHARED_LOWER_BOUND; 2871 for (addr = IPW_SHARED_LOWER_BOUND;
2111 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { 2872 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
2112 ipw_write32(priv, addr, 0); 2873 ipw_write32(priv, addr, 0);
2113 } 2874 }
2114 2875
@@ -2117,16 +2878,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2117 /* destroy DMA queues */ 2878 /* destroy DMA queues */
2118 /* reset sequence */ 2879 /* reset sequence */
2119 2880
2120 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON); 2881 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
2121 ipw_arc_release(priv); 2882 ipw_arc_release(priv);
2122 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); 2883 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
2123 mdelay(1); 2884 mdelay(1);
2124 2885
2125 /* reset PHY */ 2886 /* reset PHY */
2126 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN); 2887 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
2127 mdelay(1); 2888 mdelay(1);
2128 2889
2129 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0); 2890 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
2130 mdelay(1); 2891 mdelay(1);
2131 2892
2132 /* enable ucode store */ 2893 /* enable ucode store */
@@ -2144,18 +2905,19 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2144 */ 2905 */
2145 /* load new ipw uCode */ 2906 /* load new ipw uCode */
2146 for (i = 0; i < len / 2; i++) 2907 for (i = 0; i < len / 2; i++)
2147 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); 2908 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
2909 cpu_to_le16(image[i]));
2148 2910
2149 /* enable DINO */ 2911 /* enable DINO */
2150 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2912 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2151 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM); 2913 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
2152 2914
2153 /* this is where the igx / win driver deveates from the VAP driver. */ 2915 /* this is where the igx / win driver deveates from the VAP driver. */
2154 2916
2155 /* wait for alive response */ 2917 /* wait for alive response */
2156 for (i = 0; i < 100; i++) { 2918 for (i = 0; i < 100; i++) {
2157 /* poll for incoming data */ 2919 /* poll for incoming data */
2158 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS); 2920 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
2159 if (cr & DINO_RXFIFO_DATA) 2921 if (cr & DINO_RXFIFO_DATA)
2160 break; 2922 break;
2161 mdelay(1); 2923 mdelay(1);
@@ -2167,7 +2929,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2167 2929
2168 for (i = 0; i < ARRAY_SIZE(response_buffer); i++) 2930 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2169 response_buffer[i] = 2931 response_buffer[i] =
2170 ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); 2932 le32_to_cpu(ipw_read_reg32(priv,
2933 IPW_BASEBAND_RX_FIFO_READ));
2171 memcpy(&priv->dino_alive, response_buffer, 2934 memcpy(&priv->dino_alive, response_buffer,
2172 sizeof(priv->dino_alive)); 2935 sizeof(priv->dino_alive));
2173 if (priv->dino_alive.alive_command == 1 2936 if (priv->dino_alive.alive_command == 1
@@ -2196,7 +2959,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2196 2959
2197 /* disable DINO, otherwise for some reason 2960 /* disable DINO, otherwise for some reason
2198 firmware have problem getting alive resp. */ 2961 firmware have problem getting alive resp. */
2199 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2962 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2200 2963
2201// spin_unlock_irqrestore(&priv->lock, flags); 2964// spin_unlock_irqrestore(&priv->lock, flags);
2202 2965
@@ -2236,13 +2999,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
2236 * offeset*/ 2999 * offeset*/
2237 /* Dma loading */ 3000 /* Dma loading */
2238 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 3001 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2239 chunk->address, chunk->length); 3002 le32_to_cpu(chunk->address),
3003 le32_to_cpu(chunk->length));
2240 if (rc) { 3004 if (rc) {
2241 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 3005 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2242 goto out; 3006 goto out;
2243 } 3007 }
2244 3008
2245 offset += chunk->length; 3009 offset += le32_to_cpu(chunk->length);
2246 } while (offset < len); 3010 } while (offset < len);
2247 3011
2248 /* Run the DMA and wait for the answer */ 3012 /* Run the DMA and wait for the answer */
@@ -2268,16 +3032,16 @@ static int ipw_stop_nic(struct ipw_priv *priv)
2268 int rc = 0; 3032 int rc = 0;
2269 3033
2270 /* stop */ 3034 /* stop */
2271 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 3035 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2272 3036
2273 rc = ipw_poll_bit(priv, CX2_RESET_REG, 3037 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2274 CX2_RESET_REG_MASTER_DISABLED, 500); 3038 IPW_RESET_REG_MASTER_DISABLED, 500);
2275 if (rc < 0) { 3039 if (rc < 0) {
2276 IPW_ERROR("wait for reg master disabled failed\n"); 3040 IPW_ERROR("wait for reg master disabled failed\n");
2277 return rc; 3041 return rc;
2278 } 3042 }
2279 3043
2280 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3044 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2281 3045
2282 return rc; 3046 return rc;
2283} 3047}
@@ -2287,14 +3051,14 @@ static void ipw_start_nic(struct ipw_priv *priv)
2287 IPW_DEBUG_TRACE(">>\n"); 3051 IPW_DEBUG_TRACE(">>\n");
2288 3052
2289 /* prvHwStartNic release ARC */ 3053 /* prvHwStartNic release ARC */
2290 ipw_clear_bit(priv, CX2_RESET_REG, 3054 ipw_clear_bit(priv, IPW_RESET_REG,
2291 CX2_RESET_REG_MASTER_DISABLED | 3055 IPW_RESET_REG_MASTER_DISABLED |
2292 CX2_RESET_REG_STOP_MASTER | 3056 IPW_RESET_REG_STOP_MASTER |
2293 CBD_RESET_REG_PRINCETON_RESET); 3057 CBD_RESET_REG_PRINCETON_RESET);
2294 3058
2295 /* enable power management */ 3059 /* enable power management */
2296 ipw_set_bit(priv, CX2_GP_CNTRL_RW, 3060 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
2297 CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); 3061 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2298 3062
2299 IPW_DEBUG_TRACE("<<\n"); 3063 IPW_DEBUG_TRACE("<<\n");
2300} 3064}
@@ -2307,25 +3071,25 @@ static int ipw_init_nic(struct ipw_priv *priv)
2307 /* reset */ 3071 /* reset */
2308 /*prvHwInitNic */ 3072 /*prvHwInitNic */
2309 /* set "initialization complete" bit to move adapter to D0 state */ 3073 /* set "initialization complete" bit to move adapter to D0 state */
2310 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3074 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2311 3075
2312 /* low-level PLL activation */ 3076 /* low-level PLL activation */
2313 ipw_write32(priv, CX2_READ_INT_REGISTER, 3077 ipw_write32(priv, IPW_READ_INT_REGISTER,
2314 CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); 3078 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
2315 3079
2316 /* wait for clock stabilization */ 3080 /* wait for clock stabilization */
2317 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, 3081 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
2318 CX2_GP_CNTRL_BIT_CLOCK_READY, 250); 3082 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
2319 if (rc < 0) 3083 if (rc < 0)
2320 IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); 3084 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2321 3085
2322 /* assert SW reset */ 3086 /* assert SW reset */
2323 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET); 3087 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
2324 3088
2325 udelay(10); 3089 udelay(10);
2326 3090
2327 /* set "initialization complete" bit to move adapter to D0 state */ 3091 /* set "initialization complete" bit to move adapter to D0 state */
2328 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3092 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2329 3093
2330 IPW_DEBUG_TRACE(">>\n"); 3094 IPW_DEBUG_TRACE(">>\n");
2331 return 0; 3095 return 0;
@@ -2337,14 +3101,19 @@ static int ipw_init_nic(struct ipw_priv *priv)
2337static int ipw_reset_nic(struct ipw_priv *priv) 3101static int ipw_reset_nic(struct ipw_priv *priv)
2338{ 3102{
2339 int rc = 0; 3103 int rc = 0;
3104 unsigned long flags;
2340 3105
2341 IPW_DEBUG_TRACE(">>\n"); 3106 IPW_DEBUG_TRACE(">>\n");
2342 3107
2343 rc = ipw_init_nic(priv); 3108 rc = ipw_init_nic(priv);
2344 3109
3110 spin_lock_irqsave(&priv->lock, flags);
2345 /* Clear the 'host command active' bit... */ 3111 /* Clear the 'host command active' bit... */
2346 priv->status &= ~STATUS_HCMD_ACTIVE; 3112 priv->status &= ~STATUS_HCMD_ACTIVE;
2347 wake_up_interruptible(&priv->wait_command_queue); 3113 wake_up_interruptible(&priv->wait_command_queue);
3114 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3115 wake_up_interruptible(&priv->wait_state);
3116 spin_unlock_irqrestore(&priv->lock, flags);
2348 3117
2349 IPW_DEBUG_TRACE("<<\n"); 3118 IPW_DEBUG_TRACE("<<\n");
2350 return rc; 3119 return rc;
@@ -2364,22 +3133,23 @@ static int ipw_get_fw(struct ipw_priv *priv,
2364 } 3133 }
2365 3134
2366 header = (struct fw_header *)(*fw)->data; 3135 header = (struct fw_header *)(*fw)->data;
2367 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { 3136 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
2368 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 3137 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2369 name, 3138 name,
2370 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION); 3139 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3140 IPW_FW_MAJOR_VERSION);
2371 return -EINVAL; 3141 return -EINVAL;
2372 } 3142 }
2373 3143
2374 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 3144 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2375 name, 3145 name,
2376 IPW_FW_MAJOR(header->version), 3146 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2377 IPW_FW_MINOR(header->version), 3147 IPW_FW_MINOR(le32_to_cpu(header->version)),
2378 (*fw)->size - sizeof(struct fw_header)); 3148 (*fw)->size - sizeof(struct fw_header));
2379 return 0; 3149 return 0;
2380} 3150}
2381 3151
2382#define CX2_RX_BUF_SIZE (3000) 3152#define IPW_RX_BUF_SIZE (3000)
2383 3153
2384static inline void ipw_rx_queue_reset(struct ipw_priv *priv, 3154static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2385 struct ipw_rx_queue *rxq) 3155 struct ipw_rx_queue *rxq)
@@ -2398,8 +3168,9 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2398 * to an SKB, so we need to unmap and free potential storage */ 3168 * to an SKB, so we need to unmap and free potential storage */
2399 if (rxq->pool[i].skb != NULL) { 3169 if (rxq->pool[i].skb != NULL) {
2400 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 3170 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2401 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 3171 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
2402 dev_kfree_skb(rxq->pool[i].skb); 3172 dev_kfree_skb(rxq->pool[i].skb);
3173 rxq->pool[i].skb = NULL;
2403 } 3174 }
2404 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 3175 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2405 } 3176 }
@@ -2417,6 +3188,19 @@ static int fw_loaded = 0;
2417static const struct firmware *bootfw = NULL; 3188static const struct firmware *bootfw = NULL;
2418static const struct firmware *firmware = NULL; 3189static const struct firmware *firmware = NULL;
2419static const struct firmware *ucode = NULL; 3190static const struct firmware *ucode = NULL;
3191
3192static void free_firmware(void)
3193{
3194 if (fw_loaded) {
3195 release_firmware(bootfw);
3196 release_firmware(ucode);
3197 release_firmware(firmware);
3198 bootfw = ucode = firmware = NULL;
3199 fw_loaded = 0;
3200 }
3201}
3202#else
3203#define free_firmware() do {} while (0)
2420#endif 3204#endif
2421 3205
2422static int ipw_load(struct ipw_priv *priv) 3206static int ipw_load(struct ipw_priv *priv)
@@ -2445,10 +3229,10 @@ static int ipw_load(struct ipw_priv *priv)
2445 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); 3229 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2446 break; 3230 break;
2447 3231
2448#ifdef CONFIG_IPW_PROMISC 3232#ifdef CONFIG_IPW2200_MONITOR
2449 case IW_MODE_MONITOR: 3233 case IW_MODE_MONITOR:
2450 rc = ipw_get_fw(priv, &ucode, 3234 rc = ipw_get_fw(priv, &ucode,
2451 IPW_FW_NAME("ibss_ucode")); 3235 IPW_FW_NAME("sniffer_ucode"));
2452 if (rc) 3236 if (rc)
2453 goto error; 3237 goto error;
2454 3238
@@ -2487,11 +3271,11 @@ static int ipw_load(struct ipw_priv *priv)
2487 3271
2488 retry: 3272 retry:
2489 /* Ensure interrupts are disabled */ 3273 /* Ensure interrupts are disabled */
2490 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3274 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
2491 priv->status &= ~STATUS_INT_ENABLED; 3275 priv->status &= ~STATUS_INT_ENABLED;
2492 3276
2493 /* ack pending interrupts */ 3277 /* ack pending interrupts */
2494 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3278 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2495 3279
2496 ipw_stop_nic(priv); 3280 ipw_stop_nic(priv);
2497 3281
@@ -2501,14 +3285,14 @@ static int ipw_load(struct ipw_priv *priv)
2501 goto error; 3285 goto error;
2502 } 3286 }
2503 3287
2504 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, 3288 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
2505 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND); 3289 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
2506 3290
2507 /* DMA the initial boot firmware into the device */ 3291 /* DMA the initial boot firmware into the device */
2508 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3292 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
2509 bootfw->size - sizeof(struct fw_header)); 3293 bootfw->size - sizeof(struct fw_header));
2510 if (rc < 0) { 3294 if (rc < 0) {
2511 IPW_ERROR("Unable to load boot firmware\n"); 3295 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
2512 goto error; 3296 goto error;
2513 } 3297 }
2514 3298
@@ -2516,8 +3300,8 @@ static int ipw_load(struct ipw_priv *priv)
2516 ipw_start_nic(priv); 3300 ipw_start_nic(priv);
2517 3301
2518 /* wait for the device to finish it's initial startup sequence */ 3302 /* wait for the device to finish it's initial startup sequence */
2519 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3303 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2520 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3304 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2521 if (rc < 0) { 3305 if (rc < 0) {
2522 IPW_ERROR("device failed to boot initial fw image\n"); 3306 IPW_ERROR("device failed to boot initial fw image\n");
2523 goto error; 3307 goto error;
@@ -2525,13 +3309,13 @@ static int ipw_load(struct ipw_priv *priv)
2525 IPW_DEBUG_INFO("initial device response after %dms\n", rc); 3309 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
2526 3310
2527 /* ack fw init done interrupt */ 3311 /* ack fw init done interrupt */
2528 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3312 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2529 3313
2530 /* DMA the ucode into the device */ 3314 /* DMA the ucode into the device */
2531 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3315 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
2532 ucode->size - sizeof(struct fw_header)); 3316 ucode->size - sizeof(struct fw_header));
2533 if (rc < 0) { 3317 if (rc < 0) {
2534 IPW_ERROR("Unable to load ucode\n"); 3318 IPW_ERROR("Unable to load ucode: %d\n", rc);
2535 goto error; 3319 goto error;
2536 } 3320 }
2537 3321
@@ -2543,7 +3327,7 @@ static int ipw_load(struct ipw_priv *priv)
2543 sizeof(struct fw_header), 3327 sizeof(struct fw_header),
2544 firmware->size - sizeof(struct fw_header)); 3328 firmware->size - sizeof(struct fw_header));
2545 if (rc < 0) { 3329 if (rc < 0) {
2546 IPW_ERROR("Unable to load firmware\n"); 3330 IPW_ERROR("Unable to load firmware: %d\n", rc);
2547 goto error; 3331 goto error;
2548 } 3332 }
2549 3333
@@ -2556,12 +3340,14 @@ static int ipw_load(struct ipw_priv *priv)
2556 } 3340 }
2557 3341
2558 /* Ensure interrupts are disabled */ 3342 /* Ensure interrupts are disabled */
2559 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3343 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3344 /* ack pending interrupts */
3345 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2560 3346
2561 /* kick start the device */ 3347 /* kick start the device */
2562 ipw_start_nic(priv); 3348 ipw_start_nic(priv);
2563 3349
2564 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) { 3350 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
2565 if (retries > 0) { 3351 if (retries > 0) {
2566 IPW_WARNING("Parity error. Retrying init.\n"); 3352 IPW_WARNING("Parity error. Retrying init.\n");
2567 retries--; 3353 retries--;
@@ -2574,8 +3360,8 @@ static int ipw_load(struct ipw_priv *priv)
2574 } 3360 }
2575 3361
2576 /* wait for the device */ 3362 /* wait for the device */
2577 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3363 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2578 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3364 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2579 if (rc < 0) { 3365 if (rc < 0) {
2580 IPW_ERROR("device failed to start after 500ms\n"); 3366 IPW_ERROR("device failed to start after 500ms\n");
2581 goto error; 3367 goto error;
@@ -2583,7 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
2583 IPW_DEBUG_INFO("device response after %dms\n", rc); 3369 IPW_DEBUG_INFO("device response after %dms\n", rc);
2584 3370
2585 /* ack fw init done interrupt */ 3371 /* ack fw init done interrupt */
2586 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3372 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2587 3373
2588 /* read eeprom data and initialize the eeprom region of sram */ 3374 /* read eeprom data and initialize the eeprom region of sram */
2589 priv->eeprom_delay = 1; 3375 priv->eeprom_delay = 1;
@@ -2595,10 +3381,10 @@ static int ipw_load(struct ipw_priv *priv)
2595 /* Ensure our queue has valid packets */ 3381 /* Ensure our queue has valid packets */
2596 ipw_rx_queue_replenish(priv); 3382 ipw_rx_queue_replenish(priv);
2597 3383
2598 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read); 3384 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
2599 3385
2600 /* ack pending interrupts */ 3386 /* ack pending interrupts */
2601 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3387 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2602 3388
2603#ifndef CONFIG_PM 3389#ifndef CONFIG_PM
2604 release_firmware(bootfw); 3390 release_firmware(bootfw);
@@ -2755,16 +3541,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2755 return; 3541 return;
2756 3542
2757 /* sanity check */ 3543 /* sanity check */
2758 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) { 3544 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
2759 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks); 3545 IPW_ERROR("Too many chunks: %i\n",
3546 le32_to_cpu(bd->u.data.num_chunks));
2760 /** @todo issue fatal error, it is quite serious situation */ 3547 /** @todo issue fatal error, it is quite serious situation */
2761 return; 3548 return;
2762 } 3549 }
2763 3550
2764 /* unmap chunks if any */ 3551 /* unmap chunks if any */
2765 for (i = 0; i < bd->u.data.num_chunks; i++) { 3552 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
2766 pci_unmap_single(dev, bd->u.data.chunk_ptr[i], 3553 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
2767 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE); 3554 le16_to_cpu(bd->u.data.chunk_len[i]),
3555 PCI_DMA_TODEVICE);
2768 if (txq->txb[txq->q.last_used]) { 3556 if (txq->txb[txq->q.last_used]) {
2769 ieee80211_txb_free(txq->txb[txq->q.last_used]); 3557 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2770 txq->txb[txq->q.last_used] = NULL; 3558 txq->txb[txq->q.last_used] = NULL;
@@ -2821,21 +3609,6 @@ static void ipw_tx_queue_free(struct ipw_priv *priv)
2821 ipw_queue_tx_free(priv, &priv->txq[3]); 3609 ipw_queue_tx_free(priv, &priv->txq[3]);
2822} 3610}
2823 3611
2824static void inline __maybe_wake_tx(struct ipw_priv *priv)
2825{
2826 if (netif_running(priv->net_dev)) {
2827 switch (priv->port_type) {
2828 case DCR_TYPE_MU_BSS:
2829 case DCR_TYPE_MU_IBSS:
2830 if (!(priv->status & STATUS_ASSOCIATED)) {
2831 return;
2832 }
2833 }
2834 netif_wake_queue(priv->net_dev);
2835 }
2836
2837}
2838
2839static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid) 3612static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
2840{ 3613{
2841 /* First 3 bytes are manufacturer */ 3614 /* First 3 bytes are manufacturer */
@@ -2898,7 +3671,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2898{ 3671{
2899 int err; 3672 int err;
2900 3673
2901 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) { 3674 if (priv->status & STATUS_ASSOCIATING) {
3675 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3676 queue_work(priv->workqueue, &priv->disassociate);
3677 return;
3678 }
3679
3680 if (!(priv->status & STATUS_ASSOCIATED)) {
2902 IPW_DEBUG_ASSOC("Disassociating while not associated.\n"); 3681 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
2903 return; 3682 return;
2904 } 3683 }
@@ -2915,6 +3694,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2915 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET; 3694 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
2916 else 3695 else
2917 priv->assoc_request.assoc_type = HC_DISASSOCIATE; 3696 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3697
2918 err = ipw_send_associate(priv, &priv->assoc_request); 3698 err = ipw_send_associate(priv, &priv->assoc_request);
2919 if (err) { 3699 if (err) {
2920 IPW_DEBUG_HC("Attempt to send [dis]associate command " 3700 IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -2924,20 +3704,27 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2924 3704
2925} 3705}
2926 3706
2927static void ipw_disassociate(void *data) 3707static int ipw_disassociate(void *data)
2928{ 3708{
3709 struct ipw_priv *priv = data;
3710 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3711 return 0;
2929 ipw_send_disassociate(data, 0); 3712 ipw_send_disassociate(data, 0);
3713 return 1;
2930} 3714}
2931 3715
2932static void notify_wx_assoc_event(struct ipw_priv *priv) 3716static void ipw_bg_disassociate(void *data)
2933{ 3717{
2934 union iwreq_data wrqu; 3718 struct ipw_priv *priv = data;
2935 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3719 down(&priv->sem);
2936 if (priv->status & STATUS_ASSOCIATED) 3720 ipw_disassociate(data);
2937 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 3721 up(&priv->sem);
2938 else 3722}
2939 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 3723
2940 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 3724static void ipw_system_config(void *data)
3725{
3726 struct ipw_priv *priv = data;
3727 ipw_send_system_config(priv, &priv->sys_config);
2941} 3728}
2942 3729
2943struct ipw_status_code { 3730struct ipw_status_code {
@@ -2997,7 +3784,7 @@ static const char *ipw_get_status_code(u16 status)
2997{ 3784{
2998 int i; 3785 int i;
2999 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) 3786 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
3000 if (ipw_status_codes[i].status == status) 3787 if (ipw_status_codes[i].status == (status & 0xff))
3001 return ipw_status_codes[i].reason; 3788 return ipw_status_codes[i].reason;
3002 return "Unknown status value."; 3789 return "Unknown status value.";
3003} 3790}
@@ -3076,18 +3863,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3076 while (i && !(mask & i)) 3863 while (i && !(mask & i))
3077 i >>= 1; 3864 i >>= 1;
3078 switch (i) { 3865 switch (i) {
3079 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; 3866 case IEEE80211_CCK_RATE_1MB_MASK:
3080 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; 3867 return 1000000;
3081 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; 3868 case IEEE80211_CCK_RATE_2MB_MASK:
3082 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; 3869 return 2000000;
3083 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; 3870 case IEEE80211_CCK_RATE_5MB_MASK:
3084 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; 3871 return 5500000;
3085 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; 3872 case IEEE80211_OFDM_RATE_6MB_MASK:
3086 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; 3873 return 6000000;
3087 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; 3874 case IEEE80211_OFDM_RATE_9MB_MASK:
3088 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; 3875 return 9000000;
3089 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; 3876 case IEEE80211_CCK_RATE_11MB_MASK:
3090 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; 3877 return 11000000;
3878 case IEEE80211_OFDM_RATE_12MB_MASK:
3879 return 12000000;
3880 case IEEE80211_OFDM_RATE_18MB_MASK:
3881 return 18000000;
3882 case IEEE80211_OFDM_RATE_24MB_MASK:
3883 return 24000000;
3884 case IEEE80211_OFDM_RATE_36MB_MASK:
3885 return 36000000;
3886 case IEEE80211_OFDM_RATE_48MB_MASK:
3887 return 48000000;
3888 case IEEE80211_OFDM_RATE_54MB_MASK:
3889 return 54000000;
3091 } 3890 }
3092 3891
3093 if (priv->ieee->mode == IEEE_B) 3892 if (priv->ieee->mode == IEEE_B)
@@ -3115,25 +3914,35 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
3115 return ipw_get_max_rate(priv); 3914 return ipw_get_max_rate(priv);
3116 3915
3117 switch (rate) { 3916 switch (rate) {
3118 case IPW_TX_RATE_1MB: return 1000000; 3917 case IPW_TX_RATE_1MB:
3119 case IPW_TX_RATE_2MB: return 2000000; 3918 return 1000000;
3120 case IPW_TX_RATE_5MB: return 5500000; 3919 case IPW_TX_RATE_2MB:
3121 case IPW_TX_RATE_6MB: return 6000000; 3920 return 2000000;
3122 case IPW_TX_RATE_9MB: return 9000000; 3921 case IPW_TX_RATE_5MB:
3123 case IPW_TX_RATE_11MB: return 11000000; 3922 return 5500000;
3124 case IPW_TX_RATE_12MB: return 12000000; 3923 case IPW_TX_RATE_6MB:
3125 case IPW_TX_RATE_18MB: return 18000000; 3924 return 6000000;
3126 case IPW_TX_RATE_24MB: return 24000000; 3925 case IPW_TX_RATE_9MB:
3127 case IPW_TX_RATE_36MB: return 36000000; 3926 return 9000000;
3128 case IPW_TX_RATE_48MB: return 48000000; 3927 case IPW_TX_RATE_11MB:
3129 case IPW_TX_RATE_54MB: return 54000000; 3928 return 11000000;
3929 case IPW_TX_RATE_12MB:
3930 return 12000000;
3931 case IPW_TX_RATE_18MB:
3932 return 18000000;
3933 case IPW_TX_RATE_24MB:
3934 return 24000000;
3935 case IPW_TX_RATE_36MB:
3936 return 36000000;
3937 case IPW_TX_RATE_48MB:
3938 return 48000000;
3939 case IPW_TX_RATE_54MB:
3940 return 54000000;
3130 } 3941 }
3131 3942
3132 return 0; 3943 return 0;
3133} 3944}
3134 3945
3135#define PERFECT_RSSI (-50)
3136#define WORST_RSSI (-85)
3137#define IPW_STATS_INTERVAL (2 * HZ) 3946#define IPW_STATS_INTERVAL (2 * HZ)
3138static void ipw_gather_stats(struct ipw_priv *priv) 3947static void ipw_gather_stats(struct ipw_priv *priv)
3139{ 3948{
@@ -3145,6 +3954,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3145 s16 rssi; 3954 s16 rssi;
3146 u32 beacon_quality, signal_quality, tx_quality, rx_quality, 3955 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3147 rate_quality; 3956 rate_quality;
3957 u32 max_rate;
3148 3958
3149 if (!(priv->status & STATUS_ASSOCIATED)) { 3959 if (!(priv->status & STATUS_ASSOCIATED)) {
3150 priv->quality = 0; 3960 priv->quality = 0;
@@ -3201,7 +4011,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3201 beacon_quality, missed_beacons_percent); 4011 beacon_quality, missed_beacons_percent);
3202 4012
3203 priv->last_rate = ipw_get_current_rate(priv); 4013 priv->last_rate = ipw_get_current_rate(priv);
3204 rate_quality = priv->last_rate * 40 / priv->last_rate + 60; 4014 max_rate = ipw_get_max_rate(priv);
4015 rate_quality = priv->last_rate * 40 / max_rate + 60;
3205 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", 4016 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3206 rate_quality, priv->last_rate / 1000000); 4017 rate_quality, priv->last_rate / 1000000);
3207 4018
@@ -3222,13 +4033,20 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3222 tx_quality, tx_failures_delta, tx_packets_delta); 4033 tx_quality, tx_failures_delta, tx_packets_delta);
3223 4034
3224 rssi = average_value(&priv->average_rssi); 4035 rssi = average_value(&priv->average_rssi);
3225 if (rssi > PERFECT_RSSI) 4036 signal_quality =
4037 (100 *
4038 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4039 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4040 (priv->ieee->perfect_rssi - rssi) *
4041 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4042 62 * (priv->ieee->perfect_rssi - rssi))) /
4043 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4044 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4045 if (signal_quality > 100)
3226 signal_quality = 100; 4046 signal_quality = 100;
3227 else if (rssi < WORST_RSSI) 4047 else if (signal_quality < 1)
3228 signal_quality = 0; 4048 signal_quality = 0;
3229 else 4049
3230 signal_quality = (rssi - WORST_RSSI) * 100 /
3231 (PERFECT_RSSI - WORST_RSSI);
3232 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 4050 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3233 signal_quality, rssi); 4051 signal_quality, rssi);
3234 4052
@@ -3257,6 +4075,85 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3257 IPW_STATS_INTERVAL); 4075 IPW_STATS_INTERVAL);
3258} 4076}
3259 4077
4078static void ipw_bg_gather_stats(void *data)
4079{
4080 struct ipw_priv *priv = data;
4081 down(&priv->sem);
4082 ipw_gather_stats(data);
4083 up(&priv->sem);
4084}
4085
4086/* Missed beacon behavior:
4087 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4088 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4089 * Above disassociate threshold, give up and stop scanning.
4090 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
4091static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
4092 int missed_count)
4093{
4094 priv->notif_missed_beacons = missed_count;
4095
4096 if (missed_count > priv->disassociate_threshold &&
4097 priv->status & STATUS_ASSOCIATED) {
4098 /* If associated and we've hit the missed
4099 * beacon threshold, disassociate, turn
4100 * off roaming, and abort any active scans */
4101 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4102 IPW_DL_STATE | IPW_DL_ASSOC,
4103 "Missed beacon: %d - disassociate\n", missed_count);
4104 priv->status &= ~STATUS_ROAMING;
4105 if (priv->status & STATUS_SCANNING) {
4106 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4107 IPW_DL_STATE,
4108 "Aborting scan with missed beacon.\n");
4109 queue_work(priv->workqueue, &priv->abort_scan);
4110 }
4111
4112 queue_work(priv->workqueue, &priv->disassociate);
4113 return;
4114 }
4115
4116 if (priv->status & STATUS_ROAMING) {
4117 /* If we are currently roaming, then just
4118 * print a debug statement... */
4119 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4120 "Missed beacon: %d - roam in progress\n",
4121 missed_count);
4122 return;
4123 }
4124
4125 if (missed_count > priv->roaming_threshold &&
4126 missed_count <= priv->disassociate_threshold) {
4127 /* If we are not already roaming, set the ROAM
4128 * bit in the status and kick off a scan.
4129 * This can happen several times before we reach
4130 * disassociate_threshold. */
4131 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4132 "Missed beacon: %d - initiate "
4133 "roaming\n", missed_count);
4134 if (!(priv->status & STATUS_ROAMING)) {
4135 priv->status |= STATUS_ROAMING;
4136 if (!(priv->status & STATUS_SCANNING))
4137 queue_work(priv->workqueue,
4138 &priv->request_scan);
4139 }
4140 return;
4141 }
4142
4143 if (priv->status & STATUS_SCANNING) {
4144 /* Stop scan to keep fw from getting
4145 * stuck (only if we aren't roaming --
4146 * otherwise we'll never scan more than 2 or 3
4147 * channels..) */
4148 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4149 "Aborting scan with missed beacon.\n");
4150 queue_work(priv->workqueue, &priv->abort_scan);
4151 }
4152
4153 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4154
4155}
4156
3260/** 4157/**
3261 * Handle host notification packet. 4158 * Handle host notification packet.
3262 * Called from interrupt routine 4159 * Called from interrupt routine
@@ -3264,6 +4161,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3264static inline void ipw_rx_notification(struct ipw_priv *priv, 4161static inline void ipw_rx_notification(struct ipw_priv *priv,
3265 struct ipw_rx_notification *notif) 4162 struct ipw_rx_notification *notif)
3266{ 4163{
4164 notif->size = le16_to_cpu(notif->size);
4165
3267 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); 4166 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
3268 4167
3269 switch (notif->subtype) { 4168 switch (notif->subtype) {
@@ -3307,30 +4206,44 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3307 4206
3308 priv->status &= ~STATUS_ASSOCIATING; 4207 priv->status &= ~STATUS_ASSOCIATING;
3309 priv->status |= STATUS_ASSOCIATED; 4208 priv->status |= STATUS_ASSOCIATED;
3310 4209 queue_work(priv->workqueue,
3311 netif_carrier_on(priv->net_dev); 4210 &priv->system_config);
3312 if (netif_queue_stopped(priv->net_dev)) { 4211
3313 IPW_DEBUG_NOTIF 4212#ifdef CONFIG_IPW_QOS
3314 ("waking queue\n"); 4213#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
3315 netif_wake_queue(priv->net_dev); 4214 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
3316 } else { 4215 if ((priv->status & STATUS_AUTH) &&
3317 IPW_DEBUG_NOTIF 4216 (IPW_GET_PACKET_STYPE(&notif->u.raw)
3318 ("starting queue\n"); 4217 == IEEE80211_STYPE_ASSOC_RESP)) {
3319 netif_start_queue(priv-> 4218 if ((sizeof
3320 net_dev); 4219 (struct
4220 ieee80211_assoc_response)
4221 <= notif->size)
4222 && (notif->size <= 2314)) {
4223 struct
4224 ieee80211_rx_stats
4225 stats = {
4226 .len =
4227 notif->
4228 size - 1,
4229 };
4230
4231 IPW_DEBUG_QOS
4232 ("QoS Associate "
4233 "size %d\n",
4234 notif->size);
4235 ieee80211_rx_mgt(priv->
4236 ieee,
4237 (struct
4238 ieee80211_hdr_4addr
4239 *)
4240 &notif->u.raw, &stats);
4241 }
3321 } 4242 }
4243#endif
3322 4244
3323 ipw_reset_stats(priv); 4245 schedule_work(&priv->link_up);
3324 /* Ensure the rate is updated immediately */
3325 priv->last_rate =
3326 ipw_get_current_rate(priv);
3327 schedule_work(&priv->gather_stats);
3328 notify_wx_assoc_event(priv);
3329 4246
3330/* queue_delayed_work(priv->workqueue,
3331 &priv->request_scan,
3332 SCAN_ASSOCIATED_INTERVAL);
3333*/
3334 break; 4247 break;
3335 } 4248 }
3336 4249
@@ -3363,12 +4276,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3363 STATUS_AUTH | 4276 STATUS_AUTH |
3364 STATUS_ASSOCIATED); 4277 STATUS_ASSOCIATED);
3365 4278
3366 netif_carrier_off(priv-> 4279 schedule_work(&priv->link_down);
3367 net_dev);
3368 netif_stop_queue(priv->net_dev);
3369 queue_work(priv->workqueue,
3370 &priv->request_scan);
3371 notify_wx_assoc_event(priv);
3372 break; 4280 break;
3373 } 4281 }
3374 4282
@@ -3383,6 +4291,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3383 } 4291 }
3384 4292
3385 case CMAS_INIT:{ 4293 case CMAS_INIT:{
4294 if (priv->status & STATUS_AUTH) {
4295 struct
4296 ieee80211_assoc_response
4297 *resp;
4298 resp =
4299 (struct
4300 ieee80211_assoc_response
4301 *)&notif->u.raw;
4302 IPW_DEBUG(IPW_DL_NOTIF |
4303 IPW_DL_STATE |
4304 IPW_DL_ASSOC,
4305 "association failed (0x%04X): %s\n",
4306 ntohs(resp->status),
4307 ipw_get_status_code
4308 (ntohs
4309 (resp->status)));
4310 }
4311
3386 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4312 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3387 IPW_DL_ASSOC, 4313 IPW_DL_ASSOC,
3388 "disassociated: '%s' " MAC_FMT 4314 "disassociated: '%s' " MAC_FMT
@@ -3395,35 +4321,21 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3395 ~(STATUS_DISASSOCIATING | 4321 ~(STATUS_DISASSOCIATING |
3396 STATUS_ASSOCIATING | 4322 STATUS_ASSOCIATING |
3397 STATUS_ASSOCIATED | STATUS_AUTH); 4323 STATUS_ASSOCIATED | STATUS_AUTH);
4324 if (priv->assoc_network
4325 && (priv->assoc_network->
4326 capability &
4327 WLAN_CAPABILITY_IBSS))
4328 ipw_remove_current_network
4329 (priv);
3398 4330
3399 netif_stop_queue(priv->net_dev); 4331 schedule_work(&priv->link_down);
3400 if (!(priv->status & STATUS_ROAMING)) {
3401 netif_carrier_off(priv->
3402 net_dev);
3403 notify_wx_assoc_event(priv);
3404
3405 /* Cancel any queued work ... */
3406 cancel_delayed_work(&priv->
3407 request_scan);
3408 cancel_delayed_work(&priv->
3409 adhoc_check);
3410
3411 /* Queue up another scan... */
3412 queue_work(priv->workqueue,
3413 &priv->request_scan);
3414
3415 cancel_delayed_work(&priv->
3416 gather_stats);
3417 } else {
3418 priv->status |= STATUS_ROAMING;
3419 queue_work(priv->workqueue,
3420 &priv->request_scan);
3421 }
3422 4332
3423 ipw_reset_stats(priv);
3424 break; 4333 break;
3425 } 4334 }
3426 4335
4336 case CMAS_RX_ASSOC_RESP:
4337 break;
4338
3427 default: 4339 default:
3428 IPW_ERROR("assoc: unknown (%d)\n", 4340 IPW_ERROR("assoc: unknown (%d)\n",
3429 assoc->state); 4341 assoc->state);
@@ -3466,11 +4378,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3466 STATUS_AUTH | 4378 STATUS_AUTH |
3467 STATUS_ASSOCIATED); 4379 STATUS_ASSOCIATED);
3468 4380
3469 netif_carrier_off(priv->net_dev); 4381 schedule_work(&priv->link_down);
3470 netif_stop_queue(priv->net_dev);
3471 queue_work(priv->workqueue,
3472 &priv->request_scan);
3473 notify_wx_assoc_event(priv);
3474 break; 4382 break;
3475 4383
3476 case CMAS_TX_AUTH_SEQ_1: 4384 case CMAS_TX_AUTH_SEQ_1:
@@ -3512,6 +4420,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3512 case CMAS_RX_ASSOC_RESP: 4420 case CMAS_RX_ASSOC_RESP:
3513 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4421 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3514 IPW_DL_ASSOC, "RX_ASSOC_RESP\n"); 4422 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4423
3515 break; 4424 break;
3516 case CMAS_ASSOCIATED: 4425 case CMAS_ASSOCIATED:
3517 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4426 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
@@ -3556,43 +4465,67 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3556 priv->status &= 4465 priv->status &=
3557 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); 4466 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3558 4467
4468 wake_up_interruptible(&priv->wait_state);
3559 cancel_delayed_work(&priv->scan_check); 4469 cancel_delayed_work(&priv->scan_check);
3560 4470
4471 if (priv->status & STATUS_EXIT_PENDING)
4472 break;
4473
4474 priv->ieee->scans++;
4475
4476#ifdef CONFIG_IPW2200_MONITOR
4477 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4478 priv->status |= STATUS_SCAN_FORCED;
4479 queue_work(priv->workqueue,
4480 &priv->request_scan);
4481 break;
4482 }
4483 priv->status &= ~STATUS_SCAN_FORCED;
4484#endif /* CONFIG_IPW2200_MONITOR */
4485
3561 if (!(priv->status & (STATUS_ASSOCIATED | 4486 if (!(priv->status & (STATUS_ASSOCIATED |
3562 STATUS_ASSOCIATING | 4487 STATUS_ASSOCIATING |
3563 STATUS_ROAMING | 4488 STATUS_ROAMING |
3564 STATUS_DISASSOCIATING))) 4489 STATUS_DISASSOCIATING)))
3565 queue_work(priv->workqueue, &priv->associate); 4490 queue_work(priv->workqueue, &priv->associate);
3566 else if (priv->status & STATUS_ROAMING) { 4491 else if (priv->status & STATUS_ROAMING) {
3567 /* If a scan completed and we are in roam mode, then 4492 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
3568 * the scan that completed was the one requested as a 4493 /* If a scan completed and we are in roam mode, then
3569 * result of entering roam... so, schedule the 4494 * the scan that completed was the one requested as a
3570 * roam work */ 4495 * result of entering roam... so, schedule the
3571 queue_work(priv->workqueue, &priv->roam); 4496 * roam work */
4497 queue_work(priv->workqueue,
4498 &priv->roam);
4499 else
4500 /* Don't schedule if we aborted the scan */
4501 priv->status &= ~STATUS_ROAMING;
3572 } else if (priv->status & STATUS_SCAN_PENDING) 4502 } else if (priv->status & STATUS_SCAN_PENDING)
3573 queue_work(priv->workqueue, 4503 queue_work(priv->workqueue,
3574 &priv->request_scan); 4504 &priv->request_scan);
3575 4505 else if (priv->config & CFG_BACKGROUND_SCAN
3576 priv->ieee->scans++; 4506 && priv->status & STATUS_ASSOCIATED)
4507 queue_delayed_work(priv->workqueue,
4508 &priv->request_scan, HZ);
3577 break; 4509 break;
3578 } 4510 }
3579 4511
3580 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ 4512 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
3581 struct notif_frag_length *x = &notif->u.frag_len; 4513 struct notif_frag_length *x = &notif->u.frag_len;
3582 4514
3583 if (notif->size == sizeof(*x)) { 4515 if (notif->size == sizeof(*x))
3584 IPW_ERROR("Frag length: %d\n", x->frag_length); 4516 IPW_ERROR("Frag length: %d\n",
3585 } else { 4517 le16_to_cpu(x->frag_length));
4518 else
3586 IPW_ERROR("Frag length of wrong size %d " 4519 IPW_ERROR("Frag length of wrong size %d "
3587 "(should be %zd)\n", 4520 "(should be %zd)\n",
3588 notif->size, sizeof(*x)); 4521 notif->size, sizeof(*x));
3589 }
3590 break; 4522 break;
3591 } 4523 }
3592 4524
3593 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{ 4525 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
3594 struct notif_link_deterioration *x = 4526 struct notif_link_deterioration *x =
3595 &notif->u.link_deterioration; 4527 &notif->u.link_deterioration;
4528
3596 if (notif->size == sizeof(*x)) { 4529 if (notif->size == sizeof(*x)) {
3597 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4530 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3598 "link deterioration: '%s' " MAC_FMT 4531 "link deterioration: '%s' " MAC_FMT
@@ -3612,11 +4545,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3612 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ 4545 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
3613 IPW_ERROR("Dino config\n"); 4546 IPW_ERROR("Dino config\n");
3614 if (priv->hcmd 4547 if (priv->hcmd
3615 && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { 4548 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
3616 /* TODO: Do anything special? */
3617 } else {
3618 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); 4549 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3619 } 4550
3620 break; 4551 break;
3621 } 4552 }
3622 4553
@@ -3629,36 +4560,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3629 break; 4560 break;
3630 } 4561 }
3631 4562
3632 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { 4563 if (le32_to_cpu(x->state) ==
3633 if (priv->status & STATUS_SCANNING) { 4564 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
3634 /* Stop scan to keep fw from getting 4565 ipw_handle_missed_beacon(priv,
3635 * stuck... */ 4566 le32_to_cpu(x->
3636 queue_work(priv->workqueue, 4567 number));
3637 &priv->abort_scan);
3638 }
3639
3640 if (x->number > priv->missed_beacon_threshold &&
3641 priv->status & STATUS_ASSOCIATED) {
3642 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3643 IPW_DL_STATE,
3644 "Missed beacon: %d - disassociate\n",
3645 x->number);
3646 queue_work(priv->workqueue,
3647 &priv->disassociate);
3648 } else if (x->number > priv->roaming_threshold) {
3649 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3650 "Missed beacon: %d - initiate "
3651 "roaming\n", x->number);
3652 queue_work(priv->workqueue,
3653 &priv->roam);
3654 } else {
3655 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3656 x->number);
3657 }
3658
3659 priv->notif_missed_beacons = x->number;
3660
3661 }
3662 4568
3663 break; 4569 break;
3664 } 4570 }
@@ -3697,7 +4603,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3697 case HOST_NOTIFICATION_NOISE_STATS:{ 4603 case HOST_NOTIFICATION_NOISE_STATS:{
3698 if (notif->size == sizeof(u32)) { 4604 if (notif->size == sizeof(u32)) {
3699 priv->last_noise = 4605 priv->last_noise =
3700 (u8) (notif->u.noise.value & 0xff); 4606 (u8) (le32_to_cpu(notif->u.noise.value) &
4607 0xff);
3701 average_add(&priv->average_noise, 4608 average_add(&priv->average_noise,
3702 priv->last_noise); 4609 priv->last_noise);
3703 break; 4610 break;
@@ -3730,43 +4637,43 @@ static int ipw_queue_reset(struct ipw_priv *priv)
3730 ipw_tx_queue_free(priv); 4637 ipw_tx_queue_free(priv);
3731 /* Tx CMD queue */ 4638 /* Tx CMD queue */
3732 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd, 4639 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
3733 CX2_TX_CMD_QUEUE_READ_INDEX, 4640 IPW_TX_CMD_QUEUE_READ_INDEX,
3734 CX2_TX_CMD_QUEUE_WRITE_INDEX, 4641 IPW_TX_CMD_QUEUE_WRITE_INDEX,
3735 CX2_TX_CMD_QUEUE_BD_BASE, 4642 IPW_TX_CMD_QUEUE_BD_BASE,
3736 CX2_TX_CMD_QUEUE_BD_SIZE); 4643 IPW_TX_CMD_QUEUE_BD_SIZE);
3737 if (rc) { 4644 if (rc) {
3738 IPW_ERROR("Tx Cmd queue init failed\n"); 4645 IPW_ERROR("Tx Cmd queue init failed\n");
3739 goto error; 4646 goto error;
3740 } 4647 }
3741 /* Tx queue(s) */ 4648 /* Tx queue(s) */
3742 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, 4649 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
3743 CX2_TX_QUEUE_0_READ_INDEX, 4650 IPW_TX_QUEUE_0_READ_INDEX,
3744 CX2_TX_QUEUE_0_WRITE_INDEX, 4651 IPW_TX_QUEUE_0_WRITE_INDEX,
3745 CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE); 4652 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
3746 if (rc) { 4653 if (rc) {
3747 IPW_ERROR("Tx 0 queue init failed\n"); 4654 IPW_ERROR("Tx 0 queue init failed\n");
3748 goto error; 4655 goto error;
3749 } 4656 }
3750 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, 4657 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
3751 CX2_TX_QUEUE_1_READ_INDEX, 4658 IPW_TX_QUEUE_1_READ_INDEX,
3752 CX2_TX_QUEUE_1_WRITE_INDEX, 4659 IPW_TX_QUEUE_1_WRITE_INDEX,
3753 CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE); 4660 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
3754 if (rc) { 4661 if (rc) {
3755 IPW_ERROR("Tx 1 queue init failed\n"); 4662 IPW_ERROR("Tx 1 queue init failed\n");
3756 goto error; 4663 goto error;
3757 } 4664 }
3758 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, 4665 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
3759 CX2_TX_QUEUE_2_READ_INDEX, 4666 IPW_TX_QUEUE_2_READ_INDEX,
3760 CX2_TX_QUEUE_2_WRITE_INDEX, 4667 IPW_TX_QUEUE_2_WRITE_INDEX,
3761 CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE); 4668 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
3762 if (rc) { 4669 if (rc) {
3763 IPW_ERROR("Tx 2 queue init failed\n"); 4670 IPW_ERROR("Tx 2 queue init failed\n");
3764 goto error; 4671 goto error;
3765 } 4672 }
3766 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, 4673 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
3767 CX2_TX_QUEUE_3_READ_INDEX, 4674 IPW_TX_QUEUE_3_READ_INDEX,
3768 CX2_TX_QUEUE_3_WRITE_INDEX, 4675 IPW_TX_QUEUE_3_WRITE_INDEX,
3769 CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE); 4676 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
3770 if (rc) { 4677 if (rc) {
3771 IPW_ERROR("Tx 3 queue init failed\n"); 4678 IPW_ERROR("Tx 3 queue init failed\n");
3772 goto error; 4679 goto error;
@@ -3814,9 +4721,10 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3814 priv->tx_packets++; 4721 priv->tx_packets++;
3815 } 4722 }
3816 done: 4723 done:
3817 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { 4724 if ((ipw_queue_space(q) > q->low_mark) &&
3818 __maybe_wake_tx(priv); 4725 (qindex >= 0) &&
3819 } 4726 (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
4727 netif_wake_queue(priv->net_dev);
3820 used = q->first_empty - q->last_used; 4728 used = q->first_empty - q->last_used;
3821 if (used < 0) 4729 if (used < 0)
3822 used += q->n_bd; 4730 used += q->n_bd;
@@ -3857,7 +4765,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
3857 * Rx theory of operation 4765 * Rx theory of operation
3858 * 4766 *
3859 * The host allocates 32 DMA target addresses and passes the host address 4767 * The host allocates 32 DMA target addresses and passes the host address
3860 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is 4768 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
3861 * 0 to 31 4769 * 0 to 31
3862 * 4770 *
3863 * Rx Queue Indexes 4771 * Rx Queue Indexes
@@ -3941,7 +4849,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3941 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4849 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3942 list_del(element); 4850 list_del(element);
3943 4851
3944 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE, 4852 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
3945 rxb->dma_addr); 4853 rxb->dma_addr);
3946 rxq->queue[rxq->write] = rxb; 4854 rxq->queue[rxq->write] = rxb;
3947 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE; 4855 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
@@ -3956,7 +4864,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3956 4864
3957 /* If we've added more space for the firmware to place data, tell it */ 4865 /* If we've added more space for the firmware to place data, tell it */
3958 if (write != rxq->write) 4866 if (write != rxq->write)
3959 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write); 4867 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
3960} 4868}
3961 4869
3962/* 4870/*
@@ -3977,7 +4885,7 @@ static void ipw_rx_queue_replenish(void *data)
3977 while (!list_empty(&rxq->rx_used)) { 4885 while (!list_empty(&rxq->rx_used)) {
3978 element = rxq->rx_used.next; 4886 element = rxq->rx_used.next;
3979 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4887 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3980 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC); 4888 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
3981 if (!rxb->skb) { 4889 if (!rxb->skb) {
3982 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n", 4890 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
3983 priv->net_dev->name); 4891 priv->net_dev->name);
@@ -3991,7 +4899,7 @@ static void ipw_rx_queue_replenish(void *data)
3991 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; 4899 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
3992 rxb->dma_addr = 4900 rxb->dma_addr =
3993 pci_map_single(priv->pci_dev, rxb->skb->data, 4901 pci_map_single(priv->pci_dev, rxb->skb->data,
3994 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4902 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3995 4903
3996 list_add_tail(&rxb->list, &rxq->rx_free); 4904 list_add_tail(&rxb->list, &rxq->rx_free);
3997 rxq->free_count++; 4905 rxq->free_count++;
@@ -4001,6 +4909,14 @@ static void ipw_rx_queue_replenish(void *data)
4001 ipw_rx_queue_restock(priv); 4909 ipw_rx_queue_restock(priv);
4002} 4910}
4003 4911
4912static void ipw_bg_rx_queue_replenish(void *data)
4913{
4914 struct ipw_priv *priv = data;
4915 down(&priv->sem);
4916 ipw_rx_queue_replenish(data);
4917 up(&priv->sem);
4918}
4919
4004/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 4920/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4005 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL 4921 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
4006 * This free routine walks the list of POOL entries and if SKB is set to 4922 * This free routine walks the list of POOL entries and if SKB is set to
@@ -4016,7 +4932,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
4016 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { 4932 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4017 if (rxq->pool[i].skb != NULL) { 4933 if (rxq->pool[i].skb != NULL) {
4018 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 4934 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
4019 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4935 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4020 dev_kfree_skb(rxq->pool[i].skb); 4936 dev_kfree_skb(rxq->pool[i].skb);
4021 } 4937 }
4022 } 4938 }
@@ -4135,8 +5051,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4135 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); 5051 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
4136 rates->num_rates = 0; 5052 rates->num_rates = 0;
4137 for (i = 0; i < num_rates; i++) { 5053 for (i = 0; i < num_rates; i++) {
4138 if (!ipw_is_rate_in_mask 5054 if (!ipw_is_rate_in_mask(priv, network->mode,
4139 (priv, network->mode, network->rates[i])) { 5055 network->rates[i])) {
5056
5057 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
5058 IPW_DEBUG_SCAN("Adding masked mandatory "
5059 "rate %02X\n",
5060 network->rates[i]);
5061 rates->supported_rates[rates->num_rates++] =
5062 network->rates[i];
5063 continue;
5064 }
5065
4140 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5066 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4141 network->rates[i], priv->rates_mask); 5067 network->rates[i], priv->rates_mask);
4142 continue; 5068 continue;
@@ -4145,11 +5071,20 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4145 rates->supported_rates[rates->num_rates++] = network->rates[i]; 5071 rates->supported_rates[rates->num_rates++] = network->rates[i];
4146 } 5072 }
4147 5073
4148 num_rates = 5074 num_rates = min(network->rates_ex_len,
4149 min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); 5075 (u8) (IPW_MAX_RATES - num_rates));
4150 for (i = 0; i < num_rates; i++) { 5076 for (i = 0; i < num_rates; i++) {
4151 if (!ipw_is_rate_in_mask 5077 if (!ipw_is_rate_in_mask(priv, network->mode,
4152 (priv, network->mode, network->rates_ex[i])) { 5078 network->rates_ex[i])) {
5079 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
5080 IPW_DEBUG_SCAN("Adding masked mandatory "
5081 "rate %02X\n",
5082 network->rates_ex[i]);
5083 rates->supported_rates[rates->num_rates++] =
5084 network->rates[i];
5085 continue;
5086 }
5087
4153 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5088 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4154 network->rates_ex[i], priv->rates_mask); 5089 network->rates_ex[i], priv->rates_mask);
4155 continue; 5090 continue;
@@ -4159,7 +5094,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4159 network->rates_ex[i]; 5094 network->rates_ex[i];
4160 } 5095 }
4161 5096
4162 return rates->num_rates; 5097 return 1;
4163} 5098}
4164 5099
4165static inline void ipw_copy_rates(struct ipw_supported_rates *dest, 5100static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4241,6 +5176,216 @@ struct ipw_network_match {
4241 struct ipw_supported_rates rates; 5176 struct ipw_supported_rates rates;
4242}; 5177};
4243 5178
5179static int ipw_find_adhoc_network(struct ipw_priv *priv,
5180 struct ipw_network_match *match,
5181 struct ieee80211_network *network,
5182 int roaming)
5183{
5184 struct ipw_supported_rates rates;
5185
5186 /* Verify that this network's capability is compatible with the
5187 * current mode (AdHoc or Infrastructure) */
5188 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5189 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5190 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
5191 "capability mismatch.\n",
5192 escape_essid(network->ssid, network->ssid_len),
5193 MAC_ARG(network->bssid));
5194 return 0;
5195 }
5196
5197 /* If we do not have an ESSID for this AP, we can not associate with
5198 * it */
5199 if (network->flags & NETWORK_EMPTY_ESSID) {
5200 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5201 "because of hidden ESSID.\n",
5202 escape_essid(network->ssid, network->ssid_len),
5203 MAC_ARG(network->bssid));
5204 return 0;
5205 }
5206
5207 if (unlikely(roaming)) {
5208 /* If we are roaming, then ensure check if this is a valid
5209 * network to try and roam to */
5210 if ((network->ssid_len != match->network->ssid_len) ||
5211 memcmp(network->ssid, match->network->ssid,
5212 network->ssid_len)) {
5213 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5214 "because of non-network ESSID.\n",
5215 escape_essid(network->ssid,
5216 network->ssid_len),
5217 MAC_ARG(network->bssid));
5218 return 0;
5219 }
5220 } else {
5221 /* If an ESSID has been configured then compare the broadcast
5222 * ESSID to ours */
5223 if ((priv->config & CFG_STATIC_ESSID) &&
5224 ((network->ssid_len != priv->essid_len) ||
5225 memcmp(network->ssid, priv->essid,
5226 min(network->ssid_len, priv->essid_len)))) {
5227 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5228
5229 strncpy(escaped,
5230 escape_essid(network->ssid, network->ssid_len),
5231 sizeof(escaped));
5232 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5233 "because of ESSID mismatch: '%s'.\n",
5234 escaped, MAC_ARG(network->bssid),
5235 escape_essid(priv->essid,
5236 priv->essid_len));
5237 return 0;
5238 }
5239 }
5240
5241 /* If the old network rate is better than this one, don't bother
5242 * testing everything else. */
5243
5244 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5245 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5246 "current network.\n",
5247 escape_essid(match->network->ssid,
5248 match->network->ssid_len));
5249 return 0;
5250 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5251 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5252 "current network.\n",
5253 escape_essid(match->network->ssid,
5254 match->network->ssid_len));
5255 return 0;
5256 }
5257
5258 /* Now go through and see if the requested network is valid... */
5259 if (priv->ieee->scan_age != 0 &&
5260 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5261 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5262 "because of age: %lums.\n",
5263 escape_essid(network->ssid, network->ssid_len),
5264 MAC_ARG(network->bssid),
5265 1000 * (jiffies - network->last_scanned) / HZ);
5266 return 0;
5267 }
5268
5269 if ((priv->config & CFG_STATIC_CHANNEL) &&
5270 (network->channel != priv->channel)) {
5271 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5272 "because of channel mismatch: %d != %d.\n",
5273 escape_essid(network->ssid, network->ssid_len),
5274 MAC_ARG(network->bssid),
5275 network->channel, priv->channel);
5276 return 0;
5277 }
5278
5279 /* Verify privacy compatability */
5280 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5281 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5282 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5283 "because of privacy mismatch: %s != %s.\n",
5284 escape_essid(network->ssid, network->ssid_len),
5285 MAC_ARG(network->bssid),
5286 priv->
5287 capability & CAP_PRIVACY_ON ? "on" : "off",
5288 network->
5289 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5290 "off");
5291 return 0;
5292 }
5293
5294 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5295 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5296 "because of the same BSSID match: " MAC_FMT
5297 ".\n", escape_essid(network->ssid,
5298 network->ssid_len),
5299 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5300 return 0;
5301 }
5302
5303 /* Filter out any incompatible freq / mode combinations */
5304 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5305 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5306 "because of invalid frequency/mode "
5307 "combination.\n",
5308 escape_essid(network->ssid, network->ssid_len),
5309 MAC_ARG(network->bssid));
5310 return 0;
5311 }
5312
5313 /* Ensure that the rates supported by the driver are compatible with
5314 * this AP, including verification of basic rates (mandatory) */
5315 if (!ipw_compatible_rates(priv, network, &rates)) {
5316 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5317 "because configured rate mask excludes "
5318 "AP mandatory rate.\n",
5319 escape_essid(network->ssid, network->ssid_len),
5320 MAC_ARG(network->bssid));
5321 return 0;
5322 }
5323
5324 if (rates.num_rates == 0) {
5325 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5326 "because of no compatible rates.\n",
5327 escape_essid(network->ssid, network->ssid_len),
5328 MAC_ARG(network->bssid));
5329 return 0;
5330 }
5331
5332 /* TODO: Perform any further minimal comparititive tests. We do not
5333 * want to put too much policy logic here; intelligent scan selection
5334 * should occur within a generic IEEE 802.11 user space tool. */
5335
5336 /* Set up 'new' AP to this network */
5337 ipw_copy_rates(&match->rates, &rates);
5338 match->network = network;
5339 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5340 escape_essid(network->ssid, network->ssid_len),
5341 MAC_ARG(network->bssid));
5342
5343 return 1;
5344}
5345
5346static void ipw_merge_adhoc_network(void *data)
5347{
5348 struct ipw_priv *priv = data;
5349 struct ieee80211_network *network = NULL;
5350 struct ipw_network_match match = {
5351 .network = priv->assoc_network
5352 };
5353
5354 if ((priv->status & STATUS_ASSOCIATED) &&
5355 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5356 /* First pass through ROAM process -- look for a better
5357 * network */
5358 unsigned long flags;
5359
5360 spin_lock_irqsave(&priv->ieee->lock, flags);
5361 list_for_each_entry(network, &priv->ieee->network_list, list) {
5362 if (network != priv->assoc_network)
5363 ipw_find_adhoc_network(priv, &match, network,
5364 1);
5365 }
5366 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5367
5368 if (match.network == priv->assoc_network) {
5369 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5370 "merge to.\n");
5371 return;
5372 }
5373
5374 down(&priv->sem);
5375 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5376 IPW_DEBUG_MERGE("remove network %s\n",
5377 escape_essid(priv->essid,
5378 priv->essid_len));
5379 ipw_remove_current_network(priv);
5380 }
5381
5382 ipw_disassociate(priv);
5383 priv->assoc_network = match.network;
5384 up(&priv->sem);
5385 return;
5386 }
5387}
5388
4244static int ipw_best_network(struct ipw_priv *priv, 5389static int ipw_best_network(struct ipw_priv *priv,
4245 struct ipw_network_match *match, 5390 struct ipw_network_match *match,
4246 struct ieee80211_network *network, int roaming) 5391 struct ieee80211_network *network, int roaming)
@@ -4322,9 +5467,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4322 /* If this network has already had an association attempt within the 5467 /* If this network has already had an association attempt within the
4323 * last 3 seconds, do not try and associate again... */ 5468 * last 3 seconds, do not try and associate again... */
4324 if (network->last_associate && 5469 if (network->last_associate &&
4325 time_after(network->last_associate + (HZ * 5UL), jiffies)) { 5470 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
4326 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5471 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4327 "because of storming (%lu since last " 5472 "because of storming (%lus since last "
4328 "assoc attempt).\n", 5473 "assoc attempt).\n",
4329 escape_essid(network->ssid, network->ssid_len), 5474 escape_essid(network->ssid, network->ssid_len),
4330 MAC_ARG(network->bssid), 5475 MAC_ARG(network->bssid),
@@ -4334,12 +5479,12 @@ static int ipw_best_network(struct ipw_priv *priv,
4334 5479
4335 /* Now go through and see if the requested network is valid... */ 5480 /* Now go through and see if the requested network is valid... */
4336 if (priv->ieee->scan_age != 0 && 5481 if (priv->ieee->scan_age != 0 &&
4337 jiffies - network->last_scanned > priv->ieee->scan_age) { 5482 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5483 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4339 "because of age: %lums.\n", 5484 "because of age: %lums.\n",
4340 escape_essid(network->ssid, network->ssid_len), 5485 escape_essid(network->ssid, network->ssid_len),
4341 MAC_ARG(network->bssid), 5486 MAC_ARG(network->bssid),
4342 (jiffies - network->last_scanned) / (HZ / 100)); 5487 1000 * (jiffies - network->last_scanned) / HZ);
4343 return 0; 5488 return 0;
4344 } 5489 }
4345 5490
@@ -4367,6 +5512,15 @@ static int ipw_best_network(struct ipw_priv *priv,
4367 return 0; 5512 return 0;
4368 } 5513 }
4369 5514
5515 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5516 network->rsn_ie_len > 0)) {
5517 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5518 "because of WPA capability mismatch.\n",
5519 escape_essid(network->ssid, network->ssid_len),
5520 MAC_ARG(network->bssid));
5521 return 0;
5522 }
5523
4370 if ((priv->config & CFG_STATIC_BSSID) && 5524 if ((priv->config & CFG_STATIC_BSSID) &&
4371 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5525 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4372 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5526 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -4386,7 +5540,26 @@ static int ipw_best_network(struct ipw_priv *priv,
4386 return 0; 5540 return 0;
4387 } 5541 }
4388 5542
4389 ipw_compatible_rates(priv, network, &rates); 5543 /* Filter out invalid channel in current GEO */
5544 if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
5545 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5546 "because of invalid channel in current GEO\n",
5547 escape_essid(network->ssid, network->ssid_len),
5548 MAC_ARG(network->bssid));
5549 return 0;
5550 }
5551
5552 /* Ensure that the rates supported by the driver are compatible with
5553 * this AP, including verification of basic rates (mandatory) */
5554 if (!ipw_compatible_rates(priv, network, &rates)) {
5555 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5556 "because configured rate mask excludes "
5557 "AP mandatory rate.\n",
5558 escape_essid(network->ssid, network->ssid_len),
5559 MAC_ARG(network->bssid));
5560 return 0;
5561 }
5562
4390 if (rates.num_rates == 0) { 5563 if (rates.num_rates == 0) {
4391 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5564 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4392 "because of no compatible rates.\n", 5565 "because of no compatible rates.\n",
@@ -4413,6 +5586,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4413static void ipw_adhoc_create(struct ipw_priv *priv, 5586static void ipw_adhoc_create(struct ipw_priv *priv,
4414 struct ieee80211_network *network) 5587 struct ieee80211_network *network)
4415{ 5588{
5589 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5590 int i;
5591
4416 /* 5592 /*
4417 * For the purposes of scanning, we can set our wireless mode 5593 * For the purposes of scanning, we can set our wireless mode
4418 * to trigger scans across combinations of bands, but when it 5594 * to trigger scans across combinations of bands, but when it
@@ -4423,22 +5599,47 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4423 * chossen band. Attempting to create a new ad-hoc network 5599 * chossen band. Attempting to create a new ad-hoc network
4424 * with an invalid channel for wireless mode will trigger a 5600 * with an invalid channel for wireless mode will trigger a
4425 * FW fatal error. 5601 * FW fatal error.
5602 *
4426 */ 5603 */
4427 network->mode = is_valid_channel(priv->ieee->mode, priv->channel); 5604 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
4428 if (network->mode) { 5605 case IEEE80211_52GHZ_BAND:
4429 network->channel = priv->channel; 5606 network->mode = IEEE_A;
4430 } else { 5607 i = ipw_channel_to_index(priv->ieee, priv->channel);
5608 if (i == -1)
5609 BUG();
5610 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5611 IPW_WARNING("Overriding invalid channel\n");
5612 priv->channel = geo->a[0].channel;
5613 }
5614 break;
5615
5616 case IEEE80211_24GHZ_BAND:
5617 if (priv->ieee->mode & IEEE_G)
5618 network->mode = IEEE_G;
5619 else
5620 network->mode = IEEE_B;
5621 i = ipw_channel_to_index(priv->ieee, priv->channel);
5622 if (i == -1)
5623 BUG();
5624 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5625 IPW_WARNING("Overriding invalid channel\n");
5626 priv->channel = geo->bg[0].channel;
5627 }
5628 break;
5629
5630 default:
4431 IPW_WARNING("Overriding invalid channel\n"); 5631 IPW_WARNING("Overriding invalid channel\n");
4432 if (priv->ieee->mode & IEEE_A) { 5632 if (priv->ieee->mode & IEEE_A) {
4433 network->mode = IEEE_A; 5633 network->mode = IEEE_A;
4434 priv->channel = band_a_active_channel[0]; 5634 priv->channel = geo->a[0].channel;
4435 } else if (priv->ieee->mode & IEEE_G) { 5635 } else if (priv->ieee->mode & IEEE_G) {
4436 network->mode = IEEE_G; 5636 network->mode = IEEE_G;
4437 priv->channel = band_b_active_channel[0]; 5637 priv->channel = geo->bg[0].channel;
4438 } else { 5638 } else {
4439 network->mode = IEEE_B; 5639 network->mode = IEEE_B;
4440 priv->channel = band_b_active_channel[0]; 5640 priv->channel = geo->bg[0].channel;
4441 } 5641 }
5642 break;
4442 } 5643 }
4443 5644
4444 network->channel = priv->channel; 5645 network->channel = priv->channel;
@@ -4448,6 +5649,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4448 memcpy(network->ssid, priv->essid, priv->essid_len); 5649 memcpy(network->ssid, priv->essid, priv->essid_len);
4449 memset(&network->stats, 0, sizeof(network->stats)); 5650 memset(&network->stats, 0, sizeof(network->stats));
4450 network->capability = WLAN_CAPABILITY_IBSS; 5651 network->capability = WLAN_CAPABILITY_IBSS;
5652 if (!(priv->config & CFG_PREAMBLE_LONG))
5653 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
4451 if (priv->capability & CAP_PRIVACY_ON) 5654 if (priv->capability & CAP_PRIVACY_ON)
4452 network->capability |= WLAN_CAPABILITY_PRIVACY; 5655 network->capability |= WLAN_CAPABILITY_PRIVACY;
4453 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); 5656 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4464,13 +5667,35 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4464 network->beacon_interval = 100; /* Default */ 5667 network->beacon_interval = 100; /* Default */
4465 network->listen_interval = 10; /* Default */ 5668 network->listen_interval = 10; /* Default */
4466 network->atim_window = 0; /* Default */ 5669 network->atim_window = 0; /* Default */
4467#ifdef CONFIG_IEEE80211_WPA
4468 network->wpa_ie_len = 0; 5670 network->wpa_ie_len = 0;
4469 network->rsn_ie_len = 0; 5671 network->rsn_ie_len = 0;
4470#endif /* CONFIG_IEEE80211_WPA */
4471} 5672}
4472 5673
4473static void ipw_send_wep_keys(struct ipw_priv *priv) 5674static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5675{
5676 struct ipw_tgi_tx_key *key;
5677 struct host_cmd cmd = {
5678 .cmd = IPW_CMD_TGI_TX_KEY,
5679 .len = sizeof(*key)
5680 };
5681
5682 if (!(priv->ieee->sec.flags & (1 << index)))
5683 return;
5684
5685 key = (struct ipw_tgi_tx_key *)&cmd.param;
5686 key->key_id = index;
5687 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5688 key->security_type = type;
5689 key->station_index = 0; /* always 0 for BSS */
5690 key->flags = 0;
5691 /* 0 for new key; previous value of counter (after fatal error) */
5692 key->tx_counter[0] = 0;
5693 key->tx_counter[1] = 0;
5694
5695 ipw_send_cmd(priv, &cmd);
5696}
5697
5698static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
4474{ 5699{
4475 struct ipw_wep_key *key; 5700 struct ipw_wep_key *key;
4476 int i; 5701 int i;
@@ -4483,19 +5708,97 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
4483 key->cmd_id = DINO_CMD_WEP_KEY; 5708 key->cmd_id = DINO_CMD_WEP_KEY;
4484 key->seq_num = 0; 5709 key->seq_num = 0;
4485 5710
5711 /* Note: AES keys cannot be set for multiple times.
5712 * Only set it at the first time. */
4486 for (i = 0; i < 4; i++) { 5713 for (i = 0; i < 4; i++) {
4487 key->key_index = i; 5714 key->key_index = i | type;
4488 if (!(priv->sec.flags & (1 << i))) { 5715 if (!(priv->ieee->sec.flags & (1 << i))) {
4489 key->key_size = 0; 5716 key->key_size = 0;
4490 } else { 5717 continue;
4491 key->key_size = priv->sec.key_sizes[i];
4492 memcpy(key->key, priv->sec.keys[i], key->key_size);
4493 } 5718 }
4494 5719
4495 if (ipw_send_cmd(priv, &cmd)) { 5720 key->key_size = priv->ieee->sec.key_sizes[i];
4496 IPW_ERROR("failed to send WEP_KEY command\n"); 5721 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
4497 return; 5722
4498 } 5723 ipw_send_cmd(priv, &cmd);
5724 }
5725}
5726
5727static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5728{
5729 if (priv->ieee->host_encrypt)
5730 return;
5731
5732 switch (level) {
5733 case SEC_LEVEL_3:
5734 priv->sys_config.disable_unicast_decryption = 0;
5735 priv->ieee->host_decrypt = 0;
5736 break;
5737 case SEC_LEVEL_2:
5738 priv->sys_config.disable_unicast_decryption = 1;
5739 priv->ieee->host_decrypt = 1;
5740 break;
5741 case SEC_LEVEL_1:
5742 priv->sys_config.disable_unicast_decryption = 0;
5743 priv->ieee->host_decrypt = 0;
5744 break;
5745 case SEC_LEVEL_0:
5746 priv->sys_config.disable_unicast_decryption = 1;
5747 break;
5748 default:
5749 break;
5750 }
5751}
5752
5753static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5754{
5755 if (priv->ieee->host_encrypt)
5756 return;
5757
5758 switch (level) {
5759 case SEC_LEVEL_3:
5760 priv->sys_config.disable_multicast_decryption = 0;
5761 break;
5762 case SEC_LEVEL_2:
5763 priv->sys_config.disable_multicast_decryption = 1;
5764 break;
5765 case SEC_LEVEL_1:
5766 priv->sys_config.disable_multicast_decryption = 0;
5767 break;
5768 case SEC_LEVEL_0:
5769 priv->sys_config.disable_multicast_decryption = 1;
5770 break;
5771 default:
5772 break;
5773 }
5774}
5775
5776static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5777{
5778 switch (priv->ieee->sec.level) {
5779 case SEC_LEVEL_3:
5780 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5781 ipw_send_tgi_tx_key(priv,
5782 DCT_FLAG_EXT_SECURITY_CCM,
5783 priv->ieee->sec.active_key);
5784
5785 if (!priv->ieee->host_mc_decrypt)
5786 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5787 break;
5788 case SEC_LEVEL_2:
5789 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5790 ipw_send_tgi_tx_key(priv,
5791 DCT_FLAG_EXT_SECURITY_TKIP,
5792 priv->ieee->sec.active_key);
5793 break;
5794 case SEC_LEVEL_1:
5795 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
5796 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5797 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
5798 break;
5799 case SEC_LEVEL_0:
5800 default:
5801 break;
4499 } 5802 }
4500} 5803}
4501 5804
@@ -4503,9 +5806,12 @@ static void ipw_adhoc_check(void *data)
4503{ 5806{
4504 struct ipw_priv *priv = data; 5807 struct ipw_priv *priv = data;
4505 5808
4506 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold && 5809 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
4507 !(priv->config & CFG_ADHOC_PERSIST)) { 5810 !(priv->config & CFG_ADHOC_PERSIST)) {
4508 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n"); 5811 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
5812 IPW_DL_STATE | IPW_DL_ASSOC,
5813 "Missed beacon: %d - disassociate\n",
5814 priv->missed_adhoc_beacons);
4509 ipw_remove_current_network(priv); 5815 ipw_remove_current_network(priv);
4510 ipw_disassociate(priv); 5816 ipw_disassociate(priv);
4511 return; 5817 return;
@@ -4515,6 +5821,14 @@ static void ipw_adhoc_check(void *data)
4515 priv->assoc_request.beacon_interval); 5821 priv->assoc_request.beacon_interval);
4516} 5822}
4517 5823
5824static void ipw_bg_adhoc_check(void *data)
5825{
5826 struct ipw_priv *priv = data;
5827 down(&priv->sem);
5828 ipw_adhoc_check(data);
5829 up(&priv->sem);
5830}
5831
4518#ifdef CONFIG_IPW_DEBUG 5832#ifdef CONFIG_IPW_DEBUG
4519static void ipw_debug_config(struct ipw_priv *priv) 5833static void ipw_debug_config(struct ipw_priv *priv)
4520{ 5834{
@@ -4530,7 +5844,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
4530 else 5844 else
4531 IPW_DEBUG_INFO("ESSID unlocked.\n"); 5845 IPW_DEBUG_INFO("ESSID unlocked.\n");
4532 if (priv->config & CFG_STATIC_BSSID) 5846 if (priv->config & CFG_STATIC_BSSID)
4533 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel); 5847 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5848 MAC_ARG(priv->bssid));
4534 else 5849 else
4535 IPW_DEBUG_INFO("BSSID unlocked.\n"); 5850 IPW_DEBUG_INFO("BSSID unlocked.\n");
4536 if (priv->capability & CAP_PRIVACY_ON) 5851 if (priv->capability & CAP_PRIVACY_ON)
@@ -4543,8 +5858,7 @@ static void ipw_debug_config(struct ipw_priv *priv)
4543#define ipw_debug_config(x) do {} while (0) 5858#define ipw_debug_config(x) do {} while (0)
4544#endif 5859#endif
4545 5860
4546static inline void ipw_set_fixed_rate(struct ipw_priv *priv, 5861static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
4547 struct ieee80211_network *network)
4548{ 5862{
4549 /* TODO: Verify that this works... */ 5863 /* TODO: Verify that this works... */
4550 struct ipw_fixed_rate fr = { 5864 struct ipw_fixed_rate fr = {
@@ -4561,6 +5875,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4561 /* IEEE_A */ 5875 /* IEEE_A */
4562 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { 5876 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4563 /* Invalid fixed rate mask */ 5877 /* Invalid fixed rate mask */
5878 IPW_DEBUG_WX
5879 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4564 fr.tx_rates = 0; 5880 fr.tx_rates = 0;
4565 break; 5881 break;
4566 } 5882 }
@@ -4570,9 +5886,11 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4570 5886
4571 default: /* 2.4Ghz or Mixed */ 5887 default: /* 2.4Ghz or Mixed */
4572 /* IEEE_B */ 5888 /* IEEE_B */
4573 if (network->mode == IEEE_B) { 5889 if (mode == IEEE_B) {
4574 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 5890 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4575 /* Invalid fixed rate mask */ 5891 /* Invalid fixed rate mask */
5892 IPW_DEBUG_WX
5893 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4576 fr.tx_rates = 0; 5894 fr.tx_rates = 0;
4577 } 5895 }
4578 break; 5896 break;
@@ -4582,6 +5900,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4582 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 5900 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4583 IEEE80211_OFDM_RATES_MASK)) { 5901 IEEE80211_OFDM_RATES_MASK)) {
4584 /* Invalid fixed rate mask */ 5902 /* Invalid fixed rate mask */
5903 IPW_DEBUG_WX
5904 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4585 fr.tx_rates = 0; 5905 fr.tx_rates = 0;
4586 break; 5906 break;
4587 } 5907 }
@@ -4609,6 +5929,1112 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4609 ipw_write_reg32(priv, reg, *(u32 *) & fr); 5929 ipw_write_reg32(priv, reg, *(u32 *) & fr);
4610} 5930}
4611 5931
5932static void ipw_abort_scan(struct ipw_priv *priv)
5933{
5934 int err;
5935
5936 if (priv->status & STATUS_SCAN_ABORTING) {
5937 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5938 return;
5939 }
5940 priv->status |= STATUS_SCAN_ABORTING;
5941
5942 err = ipw_send_scan_abort(priv);
5943 if (err)
5944 IPW_DEBUG_HC("Request to abort scan failed.\n");
5945}
5946
5947static void ipw_add_scan_channels(struct ipw_priv *priv,
5948 struct ipw_scan_request_ext *scan,
5949 int scan_type)
5950{
5951 int channel_index = 0;
5952 const struct ieee80211_geo *geo;
5953 int i;
5954
5955 geo = ipw_get_geo(priv->ieee);
5956
5957 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5958 int start = channel_index;
5959 for (i = 0; i < geo->a_channels; i++) {
5960 if ((priv->status & STATUS_ASSOCIATED) &&
5961 geo->a[i].channel == priv->channel)
5962 continue;
5963 channel_index++;
5964 scan->channels_list[channel_index] = geo->a[i].channel;
5965 ipw_set_scan_type(scan, channel_index,
5966 geo->a[i].
5967 flags & IEEE80211_CH_PASSIVE_ONLY ?
5968 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
5969 scan_type);
5970 }
5971
5972 if (start != channel_index) {
5973 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
5974 (channel_index - start);
5975 channel_index++;
5976 }
5977 }
5978
5979 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5980 int start = channel_index;
5981 if (priv->config & CFG_SPEED_SCAN) {
5982 int index;
5983 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5984 /* nop out the list */
5985 [0] = 0
5986 };
5987
5988 u8 channel;
5989 while (channel_index < IPW_SCAN_CHANNELS) {
5990 channel =
5991 priv->speed_scan[priv->speed_scan_pos];
5992 if (channel == 0) {
5993 priv->speed_scan_pos = 0;
5994 channel = priv->speed_scan[0];
5995 }
5996 if ((priv->status & STATUS_ASSOCIATED) &&
5997 channel == priv->channel) {
5998 priv->speed_scan_pos++;
5999 continue;
6000 }
6001
6002 /* If this channel has already been
6003 * added in scan, break from loop
6004 * and this will be the first channel
6005 * in the next scan.
6006 */
6007 if (channels[channel - 1] != 0)
6008 break;
6009
6010 channels[channel - 1] = 1;
6011 priv->speed_scan_pos++;
6012 channel_index++;
6013 scan->channels_list[channel_index] = channel;
6014 index =
6015 ipw_channel_to_index(priv->ieee, channel);
6016 ipw_set_scan_type(scan, channel_index,
6017 geo->bg[index].
6018 flags &
6019 IEEE80211_CH_PASSIVE_ONLY ?
6020 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6021 : scan_type);
6022 }
6023 } else {
6024 for (i = 0; i < geo->bg_channels; i++) {
6025 if ((priv->status & STATUS_ASSOCIATED) &&
6026 geo->bg[i].channel == priv->channel)
6027 continue;
6028 channel_index++;
6029 scan->channels_list[channel_index] =
6030 geo->bg[i].channel;
6031 ipw_set_scan_type(scan, channel_index,
6032 geo->bg[i].
6033 flags &
6034 IEEE80211_CH_PASSIVE_ONLY ?
6035 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6036 : scan_type);
6037 }
6038 }
6039
6040 if (start != channel_index) {
6041 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6042 (channel_index - start);
6043 }
6044 }
6045}
6046
6047static int ipw_request_scan(struct ipw_priv *priv)
6048{
6049 struct ipw_scan_request_ext scan;
6050 int err = 0, scan_type;
6051
6052 if (!(priv->status & STATUS_INIT) ||
6053 (priv->status & STATUS_EXIT_PENDING))
6054 return 0;
6055
6056 down(&priv->sem);
6057
6058 if (priv->status & STATUS_SCANNING) {
6059 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
6060 priv->status |= STATUS_SCAN_PENDING;
6061 goto done;
6062 }
6063
6064 if (!(priv->status & STATUS_SCAN_FORCED) &&
6065 priv->status & STATUS_SCAN_ABORTING) {
6066 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6067 priv->status |= STATUS_SCAN_PENDING;
6068 goto done;
6069 }
6070
6071 if (priv->status & STATUS_RF_KILL_MASK) {
6072 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
6073 priv->status |= STATUS_SCAN_PENDING;
6074 goto done;
6075 }
6076
6077 memset(&scan, 0, sizeof(scan));
6078
6079 if (priv->config & CFG_SPEED_SCAN)
6080 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6081 cpu_to_le16(30);
6082 else
6083 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6084 cpu_to_le16(20);
6085
6086 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6087 cpu_to_le16(20);
6088 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6089
6090 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
6091
6092#ifdef CONFIG_IPW2200_MONITOR
6093 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6094 u8 channel;
6095 u8 band = 0;
6096
6097 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
6098 case IEEE80211_52GHZ_BAND:
6099 band = (u8) (IPW_A_MODE << 6) | 1;
6100 channel = priv->channel;
6101 break;
6102
6103 case IEEE80211_24GHZ_BAND:
6104 band = (u8) (IPW_B_MODE << 6) | 1;
6105 channel = priv->channel;
6106 break;
6107
6108 default:
6109 band = (u8) (IPW_B_MODE << 6) | 1;
6110 channel = 9;
6111 break;
6112 }
6113
6114 scan.channels_list[0] = band;
6115 scan.channels_list[1] = channel;
6116 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
6117
6118 /* NOTE: The card will sit on this channel for this time
6119 * period. Scan aborts are timing sensitive and frequently
6120 * result in firmware restarts. As such, it is best to
6121 * set a small dwell_time here and just keep re-issuing
6122 * scans. Otherwise fast channel hopping will not actually
6123 * hop channels.
6124 *
6125 * TODO: Move SPEED SCAN support to all modes and bands */
6126 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6127 cpu_to_le16(2000);
6128 } else {
6129#endif /* CONFIG_IPW2200_MONITOR */
6130 /* If we are roaming, then make this a directed scan for the
6131 * current network. Otherwise, ensure that every other scan
6132 * is a fast channel hop scan */
6133 if ((priv->status & STATUS_ROAMING)
6134 || (!(priv->status & STATUS_ASSOCIATED)
6135 && (priv->config & CFG_STATIC_ESSID)
6136 && (le32_to_cpu(scan.full_scan_index) % 2))) {
6137 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6138 if (err) {
6139 IPW_DEBUG_HC("Attempt to send SSID command "
6140 "failed.\n");
6141 goto done;
6142 }
6143
6144 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6145 } else
6146 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
6147
6148 ipw_add_scan_channels(priv, &scan, scan_type);
6149#ifdef CONFIG_IPW2200_MONITOR
6150 }
6151#endif
6152
6153 err = ipw_send_scan_request_ext(priv, &scan);
6154 if (err) {
6155 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
6156 goto done;
6157 }
6158
6159 priv->status |= STATUS_SCANNING;
6160 priv->status &= ~STATUS_SCAN_PENDING;
6161 queue_delayed_work(priv->workqueue, &priv->scan_check,
6162 IPW_SCAN_CHECK_WATCHDOG);
6163 done:
6164 up(&priv->sem);
6165 return err;
6166}
6167
6168static void ipw_bg_abort_scan(void *data)
6169{
6170 struct ipw_priv *priv = data;
6171 down(&priv->sem);
6172 ipw_abort_scan(data);
6173 up(&priv->sem);
6174}
6175
6176static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6177{
6178 /* This is called when wpa_supplicant loads and closes the driver
6179 * interface. */
6180 priv->ieee->wpa_enabled = value;
6181 return 0;
6182}
6183
6184static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6185{
6186 struct ieee80211_device *ieee = priv->ieee;
6187 struct ieee80211_security sec = {
6188 .flags = SEC_AUTH_MODE,
6189 };
6190 int ret = 0;
6191
6192 if (value & IW_AUTH_ALG_SHARED_KEY) {
6193 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6194 ieee->open_wep = 0;
6195 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6196 sec.auth_mode = WLAN_AUTH_OPEN;
6197 ieee->open_wep = 1;
6198 } else
6199 return -EINVAL;
6200
6201 if (ieee->set_security)
6202 ieee->set_security(ieee->dev, &sec);
6203 else
6204 ret = -EOPNOTSUPP;
6205
6206 return ret;
6207}
6208
6209void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6210{
6211 /* make sure WPA is enabled */
6212 ipw_wpa_enable(priv, 1);
6213
6214 ipw_disassociate(priv);
6215}
6216
6217static int ipw_set_rsn_capa(struct ipw_priv *priv,
6218 char *capabilities, int length)
6219{
6220 struct host_cmd cmd = {
6221 .cmd = IPW_CMD_RSN_CAPABILITIES,
6222 .len = length,
6223 };
6224
6225 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6226
6227 memcpy(cmd.param, capabilities, length);
6228 return ipw_send_cmd(priv, &cmd);
6229}
6230
6231/*
6232 * WE-18 support
6233 */
6234
6235/* SIOCSIWGENIE */
6236static int ipw_wx_set_genie(struct net_device *dev,
6237 struct iw_request_info *info,
6238 union iwreq_data *wrqu, char *extra)
6239{
6240 struct ipw_priv *priv = ieee80211_priv(dev);
6241 struct ieee80211_device *ieee = priv->ieee;
6242 u8 *buf;
6243 int err = 0;
6244
6245 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6246 (wrqu->data.length && extra == NULL))
6247 return -EINVAL;
6248
6249 //down(&priv->sem);
6250
6251 //if (!ieee->wpa_enabled) {
6252 // err = -EOPNOTSUPP;
6253 // goto out;
6254 //}
6255
6256 if (wrqu->data.length) {
6257 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6258 if (buf == NULL) {
6259 err = -ENOMEM;
6260 goto out;
6261 }
6262
6263 memcpy(buf, extra, wrqu->data.length);
6264 kfree(ieee->wpa_ie);
6265 ieee->wpa_ie = buf;
6266 ieee->wpa_ie_len = wrqu->data.length;
6267 } else {
6268 kfree(ieee->wpa_ie);
6269 ieee->wpa_ie = NULL;
6270 ieee->wpa_ie_len = 0;
6271 }
6272
6273 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6274 out:
6275 //up(&priv->sem);
6276 return err;
6277}
6278
6279/* SIOCGIWGENIE */
6280static int ipw_wx_get_genie(struct net_device *dev,
6281 struct iw_request_info *info,
6282 union iwreq_data *wrqu, char *extra)
6283{
6284 struct ipw_priv *priv = ieee80211_priv(dev);
6285 struct ieee80211_device *ieee = priv->ieee;
6286 int err = 0;
6287
6288 //down(&priv->sem);
6289
6290 //if (!ieee->wpa_enabled) {
6291 // err = -EOPNOTSUPP;
6292 // goto out;
6293 //}
6294
6295 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6296 wrqu->data.length = 0;
6297 goto out;
6298 }
6299
6300 if (wrqu->data.length < ieee->wpa_ie_len) {
6301 err = -E2BIG;
6302 goto out;
6303 }
6304
6305 wrqu->data.length = ieee->wpa_ie_len;
6306 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6307
6308 out:
6309 //up(&priv->sem);
6310 return err;
6311}
6312
6313static int wext_cipher2level(int cipher)
6314{
6315 switch (cipher) {
6316 case IW_AUTH_CIPHER_NONE:
6317 return SEC_LEVEL_0;
6318 case IW_AUTH_CIPHER_WEP40:
6319 case IW_AUTH_CIPHER_WEP104:
6320 return SEC_LEVEL_1;
6321 case IW_AUTH_CIPHER_TKIP:
6322 return SEC_LEVEL_2;
6323 case IW_AUTH_CIPHER_CCMP:
6324 return SEC_LEVEL_3;
6325 default:
6326 return -1;
6327 }
6328}
6329
6330/* SIOCSIWAUTH */
6331static int ipw_wx_set_auth(struct net_device *dev,
6332 struct iw_request_info *info,
6333 union iwreq_data *wrqu, char *extra)
6334{
6335 struct ipw_priv *priv = ieee80211_priv(dev);
6336 struct ieee80211_device *ieee = priv->ieee;
6337 struct iw_param *param = &wrqu->param;
6338 struct ieee80211_crypt_data *crypt;
6339 unsigned long flags;
6340 int ret = 0;
6341
6342 switch (param->flags & IW_AUTH_INDEX) {
6343 case IW_AUTH_WPA_VERSION:
6344 break;
6345 case IW_AUTH_CIPHER_PAIRWISE:
6346 ipw_set_hw_decrypt_unicast(priv,
6347 wext_cipher2level(param->value));
6348 break;
6349 case IW_AUTH_CIPHER_GROUP:
6350 ipw_set_hw_decrypt_multicast(priv,
6351 wext_cipher2level(param->value));
6352 break;
6353 case IW_AUTH_KEY_MGMT:
6354 /*
6355 * ipw2200 does not use these parameters
6356 */
6357 break;
6358
6359 case IW_AUTH_TKIP_COUNTERMEASURES:
6360 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6361 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6362 break;
6363
6364 flags = crypt->ops->get_flags(crypt->priv);
6365
6366 if (param->value)
6367 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6368 else
6369 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6370
6371 crypt->ops->set_flags(flags, crypt->priv);
6372
6373 break;
6374
6375 case IW_AUTH_DROP_UNENCRYPTED:{
6376 /* HACK:
6377 *
6378 * wpa_supplicant calls set_wpa_enabled when the driver
6379 * is loaded and unloaded, regardless of if WPA is being
6380 * used. No other calls are made which can be used to
6381 * determine if encryption will be used or not prior to
6382 * association being expected. If encryption is not being
6383 * used, drop_unencrypted is set to false, else true -- we
6384 * can use this to determine if the CAP_PRIVACY_ON bit should
6385 * be set.
6386 */
6387 struct ieee80211_security sec = {
6388 .flags = SEC_ENABLED,
6389 .enabled = param->value,
6390 };
6391 priv->ieee->drop_unencrypted = param->value;
6392 /* We only change SEC_LEVEL for open mode. Others
6393 * are set by ipw_wpa_set_encryption.
6394 */
6395 if (!param->value) {
6396 sec.flags |= SEC_LEVEL;
6397 sec.level = SEC_LEVEL_0;
6398 } else {
6399 sec.flags |= SEC_LEVEL;
6400 sec.level = SEC_LEVEL_1;
6401 }
6402 if (priv->ieee->set_security)
6403 priv->ieee->set_security(priv->ieee->dev, &sec);
6404 break;
6405 }
6406
6407 case IW_AUTH_80211_AUTH_ALG:
6408 ret = ipw_wpa_set_auth_algs(priv, param->value);
6409 break;
6410
6411 case IW_AUTH_WPA_ENABLED:
6412 ret = ipw_wpa_enable(priv, param->value);
6413 break;
6414
6415 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6416 ieee->ieee802_1x = param->value;
6417 break;
6418
6419 //case IW_AUTH_ROAMING_CONTROL:
6420 case IW_AUTH_PRIVACY_INVOKED:
6421 ieee->privacy_invoked = param->value;
6422 break;
6423
6424 default:
6425 return -EOPNOTSUPP;
6426 }
6427 return ret;
6428}
6429
6430/* SIOCGIWAUTH */
6431static int ipw_wx_get_auth(struct net_device *dev,
6432 struct iw_request_info *info,
6433 union iwreq_data *wrqu, char *extra)
6434{
6435 struct ipw_priv *priv = ieee80211_priv(dev);
6436 struct ieee80211_device *ieee = priv->ieee;
6437 struct ieee80211_crypt_data *crypt;
6438 struct iw_param *param = &wrqu->param;
6439 int ret = 0;
6440
6441 switch (param->flags & IW_AUTH_INDEX) {
6442 case IW_AUTH_WPA_VERSION:
6443 case IW_AUTH_CIPHER_PAIRWISE:
6444 case IW_AUTH_CIPHER_GROUP:
6445 case IW_AUTH_KEY_MGMT:
6446 /*
6447 * wpa_supplicant will control these internally
6448 */
6449 ret = -EOPNOTSUPP;
6450 break;
6451
6452 case IW_AUTH_TKIP_COUNTERMEASURES:
6453 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6454 if (!crypt || !crypt->ops->get_flags)
6455 break;
6456
6457 param->value = (crypt->ops->get_flags(crypt->priv) &
6458 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6459
6460 break;
6461
6462 case IW_AUTH_DROP_UNENCRYPTED:
6463 param->value = ieee->drop_unencrypted;
6464 break;
6465
6466 case IW_AUTH_80211_AUTH_ALG:
6467 param->value = ieee->sec.auth_mode;
6468 break;
6469
6470 case IW_AUTH_WPA_ENABLED:
6471 param->value = ieee->wpa_enabled;
6472 break;
6473
6474 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6475 param->value = ieee->ieee802_1x;
6476 break;
6477
6478 case IW_AUTH_ROAMING_CONTROL:
6479 case IW_AUTH_PRIVACY_INVOKED:
6480 param->value = ieee->privacy_invoked;
6481 break;
6482
6483 default:
6484 return -EOPNOTSUPP;
6485 }
6486 return 0;
6487}
6488
6489/* SIOCSIWENCODEEXT */
6490static int ipw_wx_set_encodeext(struct net_device *dev,
6491 struct iw_request_info *info,
6492 union iwreq_data *wrqu, char *extra)
6493{
6494 struct ipw_priv *priv = ieee80211_priv(dev);
6495 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6496
6497 if (hwcrypto) {
6498 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6499 /* IPW HW can't build TKIP MIC,
6500 host decryption still needed */
6501 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6502 priv->ieee->host_mc_decrypt = 1;
6503 else {
6504 priv->ieee->host_encrypt = 0;
6505 priv->ieee->host_encrypt_msdu = 1;
6506 priv->ieee->host_decrypt = 1;
6507 }
6508 } else {
6509 priv->ieee->host_encrypt = 0;
6510 priv->ieee->host_encrypt_msdu = 0;
6511 priv->ieee->host_decrypt = 0;
6512 priv->ieee->host_mc_decrypt = 0;
6513 }
6514 }
6515
6516 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6517}
6518
6519/* SIOCGIWENCODEEXT */
6520static int ipw_wx_get_encodeext(struct net_device *dev,
6521 struct iw_request_info *info,
6522 union iwreq_data *wrqu, char *extra)
6523{
6524 struct ipw_priv *priv = ieee80211_priv(dev);
6525 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6526}
6527
6528/* SIOCSIWMLME */
6529static int ipw_wx_set_mlme(struct net_device *dev,
6530 struct iw_request_info *info,
6531 union iwreq_data *wrqu, char *extra)
6532{
6533 struct ipw_priv *priv = ieee80211_priv(dev);
6534 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6535 u16 reason;
6536
6537 reason = cpu_to_le16(mlme->reason_code);
6538
6539 switch (mlme->cmd) {
6540 case IW_MLME_DEAUTH:
6541 // silently ignore
6542 break;
6543
6544 case IW_MLME_DISASSOC:
6545 ipw_disassociate(priv);
6546 break;
6547
6548 default:
6549 return -EOPNOTSUPP;
6550 }
6551 return 0;
6552}
6553
6554#ifdef CONFIG_IPW_QOS
6555
6556/* QoS */
6557/*
6558* get the modulation type of the current network or
6559* the card current mode
6560*/
6561u8 ipw_qos_current_mode(struct ipw_priv * priv)
6562{
6563 u8 mode = 0;
6564
6565 if (priv->status & STATUS_ASSOCIATED) {
6566 unsigned long flags;
6567
6568 spin_lock_irqsave(&priv->ieee->lock, flags);
6569 mode = priv->assoc_network->mode;
6570 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6571 } else {
6572 mode = priv->ieee->mode;
6573 }
6574 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6575 return mode;
6576}
6577
6578/*
6579* Handle management frame beacon and probe response
6580*/
6581static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6582 int active_network,
6583 struct ieee80211_network *network)
6584{
6585 u32 size = sizeof(struct ieee80211_qos_parameters);
6586
6587 if (network->capability & WLAN_CAPABILITY_IBSS)
6588 network->qos_data.active = network->qos_data.supported;
6589
6590 if (network->flags & NETWORK_HAS_QOS_MASK) {
6591 if (active_network &&
6592 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6593 network->qos_data.active = network->qos_data.supported;
6594
6595 if ((network->qos_data.active == 1) && (active_network == 1) &&
6596 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6597 (network->qos_data.old_param_count !=
6598 network->qos_data.param_count)) {
6599 network->qos_data.old_param_count =
6600 network->qos_data.param_count;
6601 schedule_work(&priv->qos_activate);
6602 IPW_DEBUG_QOS("QoS parameters change call "
6603 "qos_activate\n");
6604 }
6605 } else {
6606 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6607 memcpy(&network->qos_data.parameters,
6608 &def_parameters_CCK, size);
6609 else
6610 memcpy(&network->qos_data.parameters,
6611 &def_parameters_OFDM, size);
6612
6613 if ((network->qos_data.active == 1) && (active_network == 1)) {
6614 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6615 schedule_work(&priv->qos_activate);
6616 }
6617
6618 network->qos_data.active = 0;
6619 network->qos_data.supported = 0;
6620 }
6621 if ((priv->status & STATUS_ASSOCIATED) &&
6622 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6623 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
6624 if ((network->capability & WLAN_CAPABILITY_IBSS) &&
6625 !(network->flags & NETWORK_EMPTY_ESSID))
6626 if ((network->ssid_len ==
6627 priv->assoc_network->ssid_len) &&
6628 !memcmp(network->ssid,
6629 priv->assoc_network->ssid,
6630 network->ssid_len)) {
6631 queue_work(priv->workqueue,
6632 &priv->merge_networks);
6633 }
6634 }
6635
6636 return 0;
6637}
6638
6639/*
6640* This function set up the firmware to support QoS. It sends
6641* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6642*/
6643static int ipw_qos_activate(struct ipw_priv *priv,
6644 struct ieee80211_qos_data *qos_network_data)
6645{
6646 int err;
6647 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6648 struct ieee80211_qos_parameters *active_one = NULL;
6649 u32 size = sizeof(struct ieee80211_qos_parameters);
6650 u32 burst_duration;
6651 int i;
6652 u8 type;
6653
6654 type = ipw_qos_current_mode(priv);
6655
6656 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6657 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6658 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6659 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6660
6661 if (qos_network_data == NULL) {
6662 if (type == IEEE_B) {
6663 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6664 active_one = &def_parameters_CCK;
6665 } else
6666 active_one = &def_parameters_OFDM;
6667
6668 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6669 burst_duration = ipw_qos_get_burst_duration(priv);
6670 for (i = 0; i < QOS_QUEUE_NUM; i++)
6671 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6672 (u16) burst_duration;
6673 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6674 if (type == IEEE_B) {
6675 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6676 type);
6677 if (priv->qos_data.qos_enable == 0)
6678 active_one = &def_parameters_CCK;
6679 else
6680 active_one = priv->qos_data.def_qos_parm_CCK;
6681 } else {
6682 if (priv->qos_data.qos_enable == 0)
6683 active_one = &def_parameters_OFDM;
6684 else
6685 active_one = priv->qos_data.def_qos_parm_OFDM;
6686 }
6687 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6688 } else {
6689 unsigned long flags;
6690 int active;
6691
6692 spin_lock_irqsave(&priv->ieee->lock, flags);
6693 active_one = &(qos_network_data->parameters);
6694 qos_network_data->old_param_count =
6695 qos_network_data->param_count;
6696 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6697 active = qos_network_data->supported;
6698 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6699
6700 if (active == 0) {
6701 burst_duration = ipw_qos_get_burst_duration(priv);
6702 for (i = 0; i < QOS_QUEUE_NUM; i++)
6703 qos_parameters[QOS_PARAM_SET_ACTIVE].
6704 tx_op_limit[i] = (u16) burst_duration;
6705 }
6706 }
6707
6708 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6709 err = ipw_send_qos_params_command(priv,
6710 (struct ieee80211_qos_parameters *)
6711 &(qos_parameters[0]));
6712 if (err)
6713 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6714
6715 return err;
6716}
6717
6718/*
6719* send IPW_CMD_WME_INFO to the firmware
6720*/
6721static int ipw_qos_set_info_element(struct ipw_priv *priv)
6722{
6723 int ret = 0;
6724 struct ieee80211_qos_information_element qos_info;
6725
6726 if (priv == NULL)
6727 return -1;
6728
6729 qos_info.elementID = QOS_ELEMENT_ID;
6730 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6731
6732 qos_info.version = QOS_VERSION_1;
6733 qos_info.ac_info = 0;
6734
6735 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6736 qos_info.qui_type = QOS_OUI_TYPE;
6737 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6738
6739 ret = ipw_send_qos_info_command(priv, &qos_info);
6740 if (ret != 0) {
6741 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6742 }
6743 return ret;
6744}
6745
6746/*
6747* Set the QoS parameter with the association request structure
6748*/
6749static int ipw_qos_association(struct ipw_priv *priv,
6750 struct ieee80211_network *network)
6751{
6752 int err = 0;
6753 struct ieee80211_qos_data *qos_data = NULL;
6754 struct ieee80211_qos_data ibss_data = {
6755 .supported = 1,
6756 .active = 1,
6757 };
6758
6759 switch (priv->ieee->iw_mode) {
6760 case IW_MODE_ADHOC:
6761 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6762 BUG();
6763
6764 qos_data = &ibss_data;
6765 break;
6766
6767 case IW_MODE_INFRA:
6768 qos_data = &network->qos_data;
6769 break;
6770
6771 default:
6772 BUG();
6773 break;
6774 }
6775
6776 err = ipw_qos_activate(priv, qos_data);
6777 if (err) {
6778 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6779 return err;
6780 }
6781
6782 if (priv->qos_data.qos_enable && qos_data->supported) {
6783 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6784 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6785 return ipw_qos_set_info_element(priv);
6786 }
6787
6788 return 0;
6789}
6790
6791/*
6792* handling the beaconing responces. if we get different QoS setting
6793* of the network from the the associated setting adjust the QoS
6794* setting
6795*/
6796static int ipw_qos_association_resp(struct ipw_priv *priv,
6797 struct ieee80211_network *network)
6798{
6799 int ret = 0;
6800 unsigned long flags;
6801 u32 size = sizeof(struct ieee80211_qos_parameters);
6802 int set_qos_param = 0;
6803
6804 if ((priv == NULL) || (network == NULL) ||
6805 (priv->assoc_network == NULL))
6806 return ret;
6807
6808 if (!(priv->status & STATUS_ASSOCIATED))
6809 return ret;
6810
6811 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
6812 return ret;
6813
6814 spin_lock_irqsave(&priv->ieee->lock, flags);
6815 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
6816 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
6817 sizeof(struct ieee80211_qos_data));
6818 priv->assoc_network->qos_data.active = 1;
6819 if ((network->qos_data.old_param_count !=
6820 network->qos_data.param_count)) {
6821 set_qos_param = 1;
6822 network->qos_data.old_param_count =
6823 network->qos_data.param_count;
6824 }
6825
6826 } else {
6827 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
6828 memcpy(&priv->assoc_network->qos_data.parameters,
6829 &def_parameters_CCK, size);
6830 else
6831 memcpy(&priv->assoc_network->qos_data.parameters,
6832 &def_parameters_OFDM, size);
6833 priv->assoc_network->qos_data.active = 0;
6834 priv->assoc_network->qos_data.supported = 0;
6835 set_qos_param = 1;
6836 }
6837
6838 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6839
6840 if (set_qos_param == 1)
6841 schedule_work(&priv->qos_activate);
6842
6843 return ret;
6844}
6845
6846static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6847{
6848 u32 ret = 0;
6849
6850 if ((priv == NULL))
6851 return 0;
6852
6853 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
6854 ret = priv->qos_data.burst_duration_CCK;
6855 else
6856 ret = priv->qos_data.burst_duration_OFDM;
6857
6858 return ret;
6859}
6860
6861/*
6862* Initialize the setting of QoS global
6863*/
6864static void ipw_qos_init(struct ipw_priv *priv, int enable,
6865 int burst_enable, u32 burst_duration_CCK,
6866 u32 burst_duration_OFDM)
6867{
6868 priv->qos_data.qos_enable = enable;
6869
6870 if (priv->qos_data.qos_enable) {
6871 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6872 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6873 IPW_DEBUG_QOS("QoS is enabled\n");
6874 } else {
6875 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6876 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6877 IPW_DEBUG_QOS("QoS is not enabled\n");
6878 }
6879
6880 priv->qos_data.burst_enable = burst_enable;
6881
6882 if (burst_enable) {
6883 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6884 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6885 } else {
6886 priv->qos_data.burst_duration_CCK = 0;
6887 priv->qos_data.burst_duration_OFDM = 0;
6888 }
6889}
6890
6891/*
6892* map the packet priority to the right TX Queue
6893*/
6894static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6895{
6896 if (priority > 7 || !priv->qos_data.qos_enable)
6897 priority = 0;
6898
6899 return from_priority_to_tx_queue[priority] - 1;
6900}
6901
6902/*
6903* add QoS parameter to the TX command
6904*/
6905static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6906 u16 priority,
6907 struct tfd_data *tfd, u8 unicast)
6908{
6909 int ret = 0;
6910 int tx_queue_id = 0;
6911 struct ieee80211_qos_data *qos_data = NULL;
6912 int active, supported;
6913 unsigned long flags;
6914
6915 if (!(priv->status & STATUS_ASSOCIATED))
6916 return 0;
6917
6918 qos_data = &priv->assoc_network->qos_data;
6919
6920 spin_lock_irqsave(&priv->ieee->lock, flags);
6921
6922 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6923 if (unicast == 0)
6924 qos_data->active = 0;
6925 else
6926 qos_data->active = qos_data->supported;
6927 }
6928
6929 active = qos_data->active;
6930 supported = qos_data->supported;
6931
6932 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6933
6934 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
6935 "unicast %d\n",
6936 priv->qos_data.qos_enable, active, supported, unicast);
6937 if (active && priv->qos_data.qos_enable) {
6938 ret = from_priority_to_tx_queue[priority];
6939 tx_queue_id = ret - 1;
6940 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6941 if (priority <= 7) {
6942 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6943 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6944 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6945 IEEE80211_STYPE_QOS_DATA;
6946
6947 if (priv->qos_data.qos_no_ack_mask &
6948 (1UL << tx_queue_id)) {
6949 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6950 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6951 CTRL_QOS_NO_ACK;
6952 }
6953 }
6954 }
6955
6956 return ret;
6957}
6958
6959/*
6960* background support to run QoS activate functionality
6961*/
6962static void ipw_bg_qos_activate(void *data)
6963{
6964 struct ipw_priv *priv = data;
6965
6966 if (priv == NULL)
6967 return;
6968
6969 down(&priv->sem);
6970
6971 if (priv->status & STATUS_ASSOCIATED)
6972 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6973
6974 up(&priv->sem);
6975}
6976
6977static int ipw_handle_probe_response(struct net_device *dev,
6978 struct ieee80211_probe_response *resp,
6979 struct ieee80211_network *network)
6980{
6981 struct ipw_priv *priv = ieee80211_priv(dev);
6982 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6983 (network == priv->assoc_network));
6984
6985 ipw_qos_handle_probe_response(priv, active_network, network);
6986
6987 return 0;
6988}
6989
6990static int ipw_handle_beacon(struct net_device *dev,
6991 struct ieee80211_beacon *resp,
6992 struct ieee80211_network *network)
6993{
6994 struct ipw_priv *priv = ieee80211_priv(dev);
6995 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6996 (network == priv->assoc_network));
6997
6998 ipw_qos_handle_probe_response(priv, active_network, network);
6999
7000 return 0;
7001}
7002
7003static int ipw_handle_assoc_response(struct net_device *dev,
7004 struct ieee80211_assoc_response *resp,
7005 struct ieee80211_network *network)
7006{
7007 struct ipw_priv *priv = ieee80211_priv(dev);
7008 ipw_qos_association_resp(priv, network);
7009 return 0;
7010}
7011
7012static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7013 *qos_param)
7014{
7015 struct host_cmd cmd = {
7016 .cmd = IPW_CMD_QOS_PARAMETERS,
7017 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7018 };
7019
7020 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
7021 return ipw_send_cmd(priv, &cmd);
7022}
7023
7024static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7025 *qos_param)
7026{
7027 struct host_cmd cmd = {
7028 .cmd = IPW_CMD_WME_INFO,
7029 .len = sizeof(*qos_param)
7030 };
7031
7032 memcpy(cmd.param, qos_param, sizeof(*qos_param));
7033 return ipw_send_cmd(priv, &cmd);
7034}
7035
7036#endif /* CONFIG_IPW_QOS */
7037
4612static int ipw_associate_network(struct ipw_priv *priv, 7038static int ipw_associate_network(struct ipw_priv *priv,
4613 struct ieee80211_network *network, 7039 struct ieee80211_network *network,
4614 struct ipw_supported_rates *rates, int roaming) 7040 struct ipw_supported_rates *rates, int roaming)
@@ -4616,7 +7042,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4616 int err; 7042 int err;
4617 7043
4618 if (priv->config & CFG_FIXED_RATE) 7044 if (priv->config & CFG_FIXED_RATE)
4619 ipw_set_fixed_rate(priv, network); 7045 ipw_set_fixed_rate(priv, network->mode);
4620 7046
4621 if (!(priv->config & CFG_STATIC_ESSID)) { 7047 if (!(priv->config & CFG_STATIC_ESSID)) {
4622 priv->essid_len = min(network->ssid_len, 7048 priv->essid_len = min(network->ssid_len,
@@ -4631,14 +7057,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
4631 if ((priv->capability & CAP_PRIVACY_ON) && 7057 if ((priv->capability & CAP_PRIVACY_ON) &&
4632 (priv->capability & CAP_SHARED_KEY)) { 7058 (priv->capability & CAP_SHARED_KEY)) {
4633 priv->assoc_request.auth_type = AUTH_SHARED_KEY; 7059 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
4634 priv->assoc_request.auth_key = priv->sec.active_key; 7060 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7061
7062 if ((priv->capability & CAP_PRIVACY_ON) &&
7063 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7064 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7065 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
4635 } else { 7066 } else {
4636 priv->assoc_request.auth_type = AUTH_OPEN; 7067 priv->assoc_request.auth_type = AUTH_OPEN;
4637 priv->assoc_request.auth_key = 0; 7068 priv->assoc_request.auth_key = 0;
4638 } 7069 }
4639 7070
4640 if (priv->capability & CAP_PRIVACY_ON) 7071 if (priv->ieee->wpa_ie_len) {
4641 ipw_send_wep_keys(priv); 7072 priv->assoc_request.policy_support = 0x02; /* RSN active */
7073 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7074 priv->ieee->wpa_ie_len);
7075 }
4642 7076
4643 /* 7077 /*
4644 * It is valid for our ieee device to support multiple modes, but 7078 * It is valid for our ieee device to support multiple modes, but
@@ -4652,20 +7086,41 @@ static int ipw_associate_network(struct ipw_priv *priv,
4652 else if (network->mode & priv->ieee->mode & IEEE_B) 7086 else if (network->mode & priv->ieee->mode & IEEE_B)
4653 priv->assoc_request.ieee_mode = IPW_B_MODE; 7087 priv->assoc_request.ieee_mode = IPW_B_MODE;
4654 7088
7089 priv->assoc_request.capability = network->capability;
7090 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7091 && !(priv->config & CFG_PREAMBLE_LONG)) {
7092 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7093 } else {
7094 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7095
7096 /* Clear the short preamble if we won't be supporting it */
7097 priv->assoc_request.capability &=
7098 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
7099 }
7100
7101 /* Clear capability bits that aren't used in Ad Hoc */
7102 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7103 priv->assoc_request.capability &=
7104 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
7105
4655 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " 7106 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4656 "802.11%c [%d], enc=%s%s%s%c%c\n", 7107 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
4657 roaming ? "Rea" : "A", 7108 roaming ? "Rea" : "A",
4658 escape_essid(priv->essid, priv->essid_len), 7109 escape_essid(priv->essid, priv->essid_len),
4659 network->channel, 7110 network->channel,
4660 ipw_modes[priv->assoc_request.ieee_mode], 7111 ipw_modes[priv->assoc_request.ieee_mode],
4661 rates->num_rates, 7112 rates->num_rates,
7113 (priv->assoc_request.preamble_length ==
7114 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7115 network->capability &
7116 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
4662 priv->capability & CAP_PRIVACY_ON ? "on " : "off", 7117 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4663 priv->capability & CAP_PRIVACY_ON ? 7118 priv->capability & CAP_PRIVACY_ON ?
4664 (priv->capability & CAP_SHARED_KEY ? "(shared)" : 7119 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
4665 "(open)") : "", 7120 "(open)") : "",
4666 priv->capability & CAP_PRIVACY_ON ? " key=" : "", 7121 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
4667 priv->capability & CAP_PRIVACY_ON ? 7122 priv->capability & CAP_PRIVACY_ON ?
4668 '1' + priv->sec.active_key : '.', 7123 '1' + priv->ieee->sec.active_key : '.',
4669 priv->capability & CAP_PRIVACY_ON ? '.' : ' '); 7124 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
4670 7125
4671 priv->assoc_request.beacon_interval = network->beacon_interval; 7126 priv->assoc_request.beacon_interval = network->beacon_interval;
@@ -4683,17 +7138,16 @@ static int ipw_associate_network(struct ipw_priv *priv,
4683 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0]; 7138 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
4684 } 7139 }
4685 7140
4686 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN); 7141 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
4687 7142
4688 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7143 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
4689 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); 7144 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
4690 priv->assoc_request.atim_window = network->atim_window; 7145 priv->assoc_request.atim_window = network->atim_window;
4691 } else { 7146 } else {
4692 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); 7147 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
4693 priv->assoc_request.atim_window = 0; 7148 priv->assoc_request.atim_window = 0;
4694 } 7149 }
4695 7150
4696 priv->assoc_request.capability = network->capability;
4697 priv->assoc_request.listen_interval = network->listen_interval; 7151 priv->assoc_request.listen_interval = network->listen_interval;
4698 7152
4699 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 7153 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4710,6 +7164,12 @@ static int ipw_associate_network(struct ipw_priv *priv,
4710 priv->sys_config.dot11g_auto_detection = 1; 7164 priv->sys_config.dot11g_auto_detection = 1;
4711 else 7165 else
4712 priv->sys_config.dot11g_auto_detection = 0; 7166 priv->sys_config.dot11g_auto_detection = 0;
7167
7168 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7169 priv->sys_config.answer_broadcast_ssid_probe = 1;
7170 else
7171 priv->sys_config.answer_broadcast_ssid_probe = 0;
7172
4713 err = ipw_send_system_config(priv, &priv->sys_config); 7173 err = ipw_send_system_config(priv, &priv->sys_config);
4714 if (err) { 7174 if (err) {
4715 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7175 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -4717,7 +7177,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4717 } 7177 }
4718 7178
4719 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); 7179 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4720 err = ipw_set_sensitivity(priv, network->stats.rssi); 7180 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
4721 if (err) { 7181 if (err) {
4722 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7182 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4723 return err; 7183 return err;
@@ -4735,6 +7195,10 @@ static int ipw_associate_network(struct ipw_priv *priv,
4735 7195
4736 priv->assoc_network = network; 7196 priv->assoc_network = network;
4737 7197
7198#ifdef CONFIG_IPW_QOS
7199 ipw_qos_association(priv, network);
7200#endif
7201
4738 err = ipw_send_associate(priv, &priv->assoc_request); 7202 err = ipw_send_associate(priv, &priv->assoc_request);
4739 if (err) { 7203 if (err) {
4740 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7204 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
@@ -4782,12 +7246,15 @@ static void ipw_roam(void *data)
4782 if (priv->status & STATUS_ASSOCIATED) { 7246 if (priv->status & STATUS_ASSOCIATED) {
4783 /* First pass through ROAM process -- look for a better 7247 /* First pass through ROAM process -- look for a better
4784 * network */ 7248 * network */
7249 unsigned long flags;
4785 u8 rssi = priv->assoc_network->stats.rssi; 7250 u8 rssi = priv->assoc_network->stats.rssi;
4786 priv->assoc_network->stats.rssi = -128; 7251 priv->assoc_network->stats.rssi = -128;
7252 spin_lock_irqsave(&priv->ieee->lock, flags);
4787 list_for_each_entry(network, &priv->ieee->network_list, list) { 7253 list_for_each_entry(network, &priv->ieee->network_list, list) {
4788 if (network != priv->assoc_network) 7254 if (network != priv->assoc_network)
4789 ipw_best_network(priv, &match, network, 1); 7255 ipw_best_network(priv, &match, network, 1);
4790 } 7256 }
7257 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4791 priv->assoc_network->stats.rssi = rssi; 7258 priv->assoc_network->stats.rssi = rssi;
4792 7259
4793 if (match.network == priv->assoc_network) { 7260 if (match.network == priv->assoc_network) {
@@ -4810,7 +7277,15 @@ static void ipw_roam(void *data)
4810 priv->status &= ~STATUS_ROAMING; 7277 priv->status &= ~STATUS_ROAMING;
4811} 7278}
4812 7279
4813static void ipw_associate(void *data) 7280static void ipw_bg_roam(void *data)
7281{
7282 struct ipw_priv *priv = data;
7283 down(&priv->sem);
7284 ipw_roam(data);
7285 up(&priv->sem);
7286}
7287
7288static int ipw_associate(void *data)
4814{ 7289{
4815 struct ipw_priv *priv = data; 7290 struct ipw_priv *priv = data;
4816 7291
@@ -4820,14 +7295,41 @@ static void ipw_associate(void *data)
4820 }; 7295 };
4821 struct ipw_supported_rates *rates; 7296 struct ipw_supported_rates *rates;
4822 struct list_head *element; 7297 struct list_head *element;
7298 unsigned long flags;
7299
7300 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7301 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7302 return 0;
7303 }
7304
7305 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7306 IPW_DEBUG_ASSOC("Not attempting association (already in "
7307 "progress)\n");
7308 return 0;
7309 }
7310
7311 if (priv->status & STATUS_DISASSOCIATING) {
7312 IPW_DEBUG_ASSOC("Not attempting association (in "
7313 "disassociating)\n ");
7314 queue_work(priv->workqueue, &priv->associate);
7315 return 0;
7316 }
7317
7318 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7319 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7320 "initialized)\n");
7321 return 0;
7322 }
4823 7323
4824 if (!(priv->config & CFG_ASSOCIATE) && 7324 if (!(priv->config & CFG_ASSOCIATE) &&
4825 !(priv->config & (CFG_STATIC_ESSID | 7325 !(priv->config & (CFG_STATIC_ESSID |
4826 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) { 7326 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
4827 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); 7327 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
4828 return; 7328 return 0;
4829 } 7329 }
4830 7330
7331 /* Protect our use of the network_list */
7332 spin_lock_irqsave(&priv->ieee->lock, flags);
4831 list_for_each_entry(network, &priv->ieee->network_list, list) 7333 list_for_each_entry(network, &priv->ieee->network_list, list)
4832 ipw_best_network(priv, &match, network, 0); 7334 ipw_best_network(priv, &match, network, 0);
4833 7335
@@ -4838,6 +7340,7 @@ static void ipw_associate(void *data)
4838 priv->ieee->iw_mode == IW_MODE_ADHOC && 7340 priv->ieee->iw_mode == IW_MODE_ADHOC &&
4839 priv->config & CFG_ADHOC_CREATE && 7341 priv->config & CFG_ADHOC_CREATE &&
4840 priv->config & CFG_STATIC_ESSID && 7342 priv->config & CFG_STATIC_ESSID &&
7343 priv->config & CFG_STATIC_CHANNEL &&
4841 !list_empty(&priv->ieee->network_free_list)) { 7344 !list_empty(&priv->ieee->network_free_list)) {
4842 element = priv->ieee->network_free_list.next; 7345 element = priv->ieee->network_free_list.next;
4843 network = list_entry(element, struct ieee80211_network, list); 7346 network = list_entry(element, struct ieee80211_network, list);
@@ -4846,25 +7349,83 @@ static void ipw_associate(void *data)
4846 list_del(element); 7349 list_del(element);
4847 list_add_tail(&network->list, &priv->ieee->network_list); 7350 list_add_tail(&network->list, &priv->ieee->network_list);
4848 } 7351 }
7352 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4849 7353
4850 /* If we reached the end of the list, then we don't have any valid 7354 /* If we reached the end of the list, then we don't have any valid
4851 * matching APs */ 7355 * matching APs */
4852 if (!network) { 7356 if (!network) {
4853 ipw_debug_config(priv); 7357 ipw_debug_config(priv);
4854 7358
4855 queue_delayed_work(priv->workqueue, &priv->request_scan, 7359 if (!(priv->status & STATUS_SCANNING)) {
4856 SCAN_INTERVAL); 7360 if (!(priv->config & CFG_SPEED_SCAN))
7361 queue_delayed_work(priv->workqueue,
7362 &priv->request_scan,
7363 SCAN_INTERVAL);
7364 else
7365 queue_work(priv->workqueue,
7366 &priv->request_scan);
7367 }
4857 7368
4858 return; 7369 return 0;
4859 } 7370 }
4860 7371
4861 ipw_associate_network(priv, network, rates, 0); 7372 ipw_associate_network(priv, network, rates, 0);
7373
7374 return 1;
4862} 7375}
4863 7376
4864static inline void ipw_handle_data_packet(struct ipw_priv *priv, 7377static void ipw_bg_associate(void *data)
4865 struct ipw_rx_mem_buffer *rxb,
4866 struct ieee80211_rx_stats *stats)
4867{ 7378{
7379 struct ipw_priv *priv = data;
7380 down(&priv->sem);
7381 ipw_associate(data);
7382 up(&priv->sem);
7383}
7384
7385static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7386 struct sk_buff *skb)
7387{
7388 struct ieee80211_hdr *hdr;
7389 u16 fc;
7390
7391 hdr = (struct ieee80211_hdr *)skb->data;
7392 fc = le16_to_cpu(hdr->frame_ctl);
7393 if (!(fc & IEEE80211_FCTL_PROTECTED))
7394 return;
7395
7396 fc &= ~IEEE80211_FCTL_PROTECTED;
7397 hdr->frame_ctl = cpu_to_le16(fc);
7398 switch (priv->ieee->sec.level) {
7399 case SEC_LEVEL_3:
7400 /* Remove CCMP HDR */
7401 memmove(skb->data + IEEE80211_3ADDR_LEN,
7402 skb->data + IEEE80211_3ADDR_LEN + 8,
7403 skb->len - IEEE80211_3ADDR_LEN - 8);
7404 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
7405 break;
7406 case SEC_LEVEL_2:
7407 break;
7408 case SEC_LEVEL_1:
7409 /* Remove IV */
7410 memmove(skb->data + IEEE80211_3ADDR_LEN,
7411 skb->data + IEEE80211_3ADDR_LEN + 4,
7412 skb->len - IEEE80211_3ADDR_LEN - 4);
7413 skb_trim(skb, skb->len - 8); /* IV + ICV */
7414 break;
7415 case SEC_LEVEL_0:
7416 break;
7417 default:
7418 printk(KERN_ERR "Unknow security level %d\n",
7419 priv->ieee->sec.level);
7420 break;
7421 }
7422}
7423
7424static void ipw_handle_data_packet(struct ipw_priv *priv,
7425 struct ipw_rx_mem_buffer *rxb,
7426 struct ieee80211_rx_stats *stats)
7427{
7428 struct ieee80211_hdr_4addr *hdr;
4868 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; 7429 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
4869 7430
4870 /* We received data from the HW, so stop the watchdog */ 7431 /* We received data from the HW, so stop the watchdog */
@@ -4872,7 +7433,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4872 7433
4873 /* We only process data packets if the 7434 /* We only process data packets if the
4874 * interface is open */ 7435 * interface is open */
4875 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > 7436 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
4876 skb_tailroom(rxb->skb))) { 7437 skb_tailroom(rxb->skb))) {
4877 priv->ieee->stats.rx_errors++; 7438 priv->ieee->stats.rx_errors++;
4878 priv->wstats.discard.misc++; 7439 priv->wstats.discard.misc++;
@@ -4889,14 +7450,351 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4889 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data)); 7450 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
4890 7451
4891 /* Set the size of the skb to the size of the frame */ 7452 /* Set the size of the skb to the size of the frame */
4892 skb_put(rxb->skb, pkt->u.frame.length); 7453 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
4893 7454
4894 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 7455 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
4895 7456
7457 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7458 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7459 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7460 ((is_multicast_ether_addr(hdr->addr1) ||
7461 is_broadcast_ether_addr(hdr->addr1)) ?
7462 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7463 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7464
4896 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 7465 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
4897 priv->ieee->stats.rx_errors++; 7466 priv->ieee->stats.rx_errors++;
4898 else /* ieee80211_rx succeeded, so it now owns the SKB */ 7467 else { /* ieee80211_rx succeeded, so it now owns the SKB */
4899 rxb->skb = NULL; 7468 rxb->skb = NULL;
7469 __ipw_led_activity_on(priv);
7470 }
7471}
7472
7473#ifdef CONFIG_IEEE80211_RADIOTAP
7474static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7475 struct ipw_rx_mem_buffer *rxb,
7476 struct ieee80211_rx_stats *stats)
7477{
7478 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7479 struct ipw_rx_frame *frame = &pkt->u.frame;
7480
7481 /* initial pull of some data */
7482 u16 received_channel = frame->received_channel;
7483 u8 antennaAndPhy = frame->antennaAndPhy;
7484 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7485 u16 pktrate = frame->rate;
7486
7487 /* Magic struct that slots into the radiotap header -- no reason
7488 * to build this manually element by element, we can write it much
7489 * more efficiently than we can parse it. ORDER MATTERS HERE */
7490 struct ipw_rt_hdr {
7491 struct ieee80211_radiotap_header rt_hdr;
7492 u8 rt_flags; /* radiotap packet flags */
7493 u8 rt_rate; /* rate in 500kb/s */
7494 u16 rt_channel; /* channel in mhz */
7495 u16 rt_chbitmask; /* channel bitfield */
7496 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7497 u8 rt_antenna; /* antenna number */
7498 } *ipw_rt;
7499
7500 short len = le16_to_cpu(pkt->u.frame.length);
7501
7502 /* We received data from the HW, so stop the watchdog */
7503 priv->net_dev->trans_start = jiffies;
7504
7505 /* We only process data packets if the
7506 * interface is open */
7507 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7508 skb_tailroom(rxb->skb))) {
7509 priv->ieee->stats.rx_errors++;
7510 priv->wstats.discard.misc++;
7511 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7512 return;
7513 } else if (unlikely(!netif_running(priv->net_dev))) {
7514 priv->ieee->stats.rx_dropped++;
7515 priv->wstats.discard.misc++;
7516 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7517 return;
7518 }
7519
7520 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7521 * that now */
7522 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7523 /* FIXME: Should alloc bigger skb instead */
7524 priv->ieee->stats.rx_dropped++;
7525 priv->wstats.discard.misc++;
7526 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7527 return;
7528 }
7529
7530 /* copy the frame itself */
7531 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7532 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7533
7534 /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
7535 * part of our real header, saves a little time.
7536 *
7537 * No longer necessary since we fill in all our data. Purge before merging
7538 * patch officially.
7539 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7540 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7541 */
7542
7543 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7544
7545 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7546 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7547 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
7548
7549 /* Big bitfield of all the fields we provide in radiotap */
7550 ipw_rt->rt_hdr.it_present =
7551 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7552 (1 << IEEE80211_RADIOTAP_RATE) |
7553 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7554 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7555 (1 << IEEE80211_RADIOTAP_ANTENNA));
7556
7557 /* Zero the flags, we'll add to them as we go */
7558 ipw_rt->rt_flags = 0;
7559
7560 /* Convert signal to DBM */
7561 ipw_rt->rt_dbmsignal = antsignal;
7562
7563 /* Convert the channel data and set the flags */
7564 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7565 if (received_channel > 14) { /* 802.11a */
7566 ipw_rt->rt_chbitmask =
7567 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7568 } else if (antennaAndPhy & 32) { /* 802.11b */
7569 ipw_rt->rt_chbitmask =
7570 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7571 } else { /* 802.11g */
7572 ipw_rt->rt_chbitmask =
7573 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7574 }
7575
7576 /* set the rate in multiples of 500k/s */
7577 switch (pktrate) {
7578 case IPW_TX_RATE_1MB:
7579 ipw_rt->rt_rate = 2;
7580 break;
7581 case IPW_TX_RATE_2MB:
7582 ipw_rt->rt_rate = 4;
7583 break;
7584 case IPW_TX_RATE_5MB:
7585 ipw_rt->rt_rate = 10;
7586 break;
7587 case IPW_TX_RATE_6MB:
7588 ipw_rt->rt_rate = 12;
7589 break;
7590 case IPW_TX_RATE_9MB:
7591 ipw_rt->rt_rate = 18;
7592 break;
7593 case IPW_TX_RATE_11MB:
7594 ipw_rt->rt_rate = 22;
7595 break;
7596 case IPW_TX_RATE_12MB:
7597 ipw_rt->rt_rate = 24;
7598 break;
7599 case IPW_TX_RATE_18MB:
7600 ipw_rt->rt_rate = 36;
7601 break;
7602 case IPW_TX_RATE_24MB:
7603 ipw_rt->rt_rate = 48;
7604 break;
7605 case IPW_TX_RATE_36MB:
7606 ipw_rt->rt_rate = 72;
7607 break;
7608 case IPW_TX_RATE_48MB:
7609 ipw_rt->rt_rate = 96;
7610 break;
7611 case IPW_TX_RATE_54MB:
7612 ipw_rt->rt_rate = 108;
7613 break;
7614 default:
7615 ipw_rt->rt_rate = 0;
7616 break;
7617 }
7618
7619 /* antenna number */
7620 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7621
7622 /* set the preamble flag if we have it */
7623 if ((antennaAndPhy & 64))
7624 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7625
7626 /* Set the size of the skb to the size of the frame */
7627 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7628
7629 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7630
7631 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
7632 priv->ieee->stats.rx_errors++;
7633 else { /* ieee80211_rx succeeded, so it now owns the SKB */
7634 rxb->skb = NULL;
7635 /* no LED during capture */
7636 }
7637}
7638#endif
7639
7640static inline int is_network_packet(struct ipw_priv *priv,
7641 struct ieee80211_hdr_4addr *header)
7642{
7643 /* Filter incoming packets to determine if they are targetted toward
7644 * this network, discarding packets coming from ourselves */
7645 switch (priv->ieee->iw_mode) {
7646 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
7647 /* packets from our adapter are dropped (echo) */
7648 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7649 return 0;
7650
7651 /* {broad,multi}cast packets to our BSSID go through */
7652 if (is_multicast_ether_addr(header->addr1) ||
7653 is_broadcast_ether_addr(header->addr1))
7654 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
7655
7656 /* packets to our adapter go through */
7657 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7658 ETH_ALEN);
7659
7660 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
7661 /* packets from our adapter are dropped (echo) */
7662 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7663 return 0;
7664
7665 /* {broad,multi}cast packets to our BSS go through */
7666 if (is_multicast_ether_addr(header->addr1) ||
7667 is_broadcast_ether_addr(header->addr1))
7668 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7669
7670 /* packets to our adapter go through */
7671 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7672 ETH_ALEN);
7673 }
7674
7675 return 1;
7676}
7677
7678#define IPW_PACKET_RETRY_TIME HZ
7679
7680static inline int is_duplicate_packet(struct ipw_priv *priv,
7681 struct ieee80211_hdr_4addr *header)
7682{
7683 u16 sc = le16_to_cpu(header->seq_ctl);
7684 u16 seq = WLAN_GET_SEQ_SEQ(sc);
7685 u16 frag = WLAN_GET_SEQ_FRAG(sc);
7686 u16 *last_seq, *last_frag;
7687 unsigned long *last_time;
7688
7689 switch (priv->ieee->iw_mode) {
7690 case IW_MODE_ADHOC:
7691 {
7692 struct list_head *p;
7693 struct ipw_ibss_seq *entry = NULL;
7694 u8 *mac = header->addr2;
7695 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
7696
7697 __list_for_each(p, &priv->ibss_mac_hash[index]) {
7698 entry =
7699 list_entry(p, struct ipw_ibss_seq, list);
7700 if (!memcmp(entry->mac, mac, ETH_ALEN))
7701 break;
7702 }
7703 if (p == &priv->ibss_mac_hash[index]) {
7704 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
7705 if (!entry) {
7706 IPW_ERROR
7707 ("Cannot malloc new mac entry\n");
7708 return 0;
7709 }
7710 memcpy(entry->mac, mac, ETH_ALEN);
7711 entry->seq_num = seq;
7712 entry->frag_num = frag;
7713 entry->packet_time = jiffies;
7714 list_add(&entry->list,
7715 &priv->ibss_mac_hash[index]);
7716 return 0;
7717 }
7718 last_seq = &entry->seq_num;
7719 last_frag = &entry->frag_num;
7720 last_time = &entry->packet_time;
7721 break;
7722 }
7723 case IW_MODE_INFRA:
7724 last_seq = &priv->last_seq_num;
7725 last_frag = &priv->last_frag_num;
7726 last_time = &priv->last_packet_time;
7727 break;
7728 default:
7729 return 0;
7730 }
7731 if ((*last_seq == seq) &&
7732 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
7733 if (*last_frag == frag)
7734 goto drop;
7735 if (*last_frag + 1 != frag)
7736 /* out-of-order fragment */
7737 goto drop;
7738 } else
7739 *last_seq = seq;
7740
7741 *last_frag = frag;
7742 *last_time = jiffies;
7743 return 0;
7744
7745 drop:
7746 /* Comment this line now since we observed the card receives
7747 * duplicate packets but the FCTL_RETRY bit is not set in the
7748 * IBSS mode with fragmentation enabled.
7749 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
7750 return 1;
7751}
7752
7753static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7754 struct ipw_rx_mem_buffer *rxb,
7755 struct ieee80211_rx_stats *stats)
7756{
7757 struct sk_buff *skb = rxb->skb;
7758 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7759 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7760 (skb->data + IPW_RX_FRAME_SIZE);
7761
7762 ieee80211_rx_mgt(priv->ieee, header, stats);
7763
7764 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7765 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7766 IEEE80211_STYPE_PROBE_RESP) ||
7767 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7768 IEEE80211_STYPE_BEACON))) {
7769 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7770 ipw_add_station(priv, header->addr2);
7771 }
7772
7773 if (priv->config & CFG_NET_STATS) {
7774 IPW_DEBUG_HC("sending stat packet\n");
7775
7776 /* Set the size of the skb to the size of the full
7777 * ipw header and 802.11 frame */
7778 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7779 IPW_RX_FRAME_SIZE);
7780
7781 /* Advance past the ipw packet header to the 802.11 frame */
7782 skb_pull(skb, IPW_RX_FRAME_SIZE);
7783
7784 /* Push the ieee80211_rx_stats before the 802.11 frame */
7785 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7786
7787 skb->dev = priv->ieee->dev;
7788
7789 /* Point raw at the ieee80211_stats */
7790 skb->mac.raw = skb->data;
7791
7792 skb->pkt_type = PACKET_OTHERHOST;
7793 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7794 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7795 netif_rx(skb);
7796 rxb->skb = NULL;
7797 }
4900} 7798}
4901 7799
4902/* 7800/*
@@ -4912,8 +7810,8 @@ static void ipw_rx(struct ipw_priv *priv)
4912 u32 r, w, i; 7810 u32 r, w, i;
4913 u8 network_packet; 7811 u8 network_packet;
4914 7812
4915 r = ipw_read32(priv, CX2_RX_READ_INDEX); 7813 r = ipw_read32(priv, IPW_RX_READ_INDEX);
4916 w = ipw_read32(priv, CX2_RX_WRITE_INDEX); 7814 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
4917 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; 7815 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
4918 7816
4919 while (i != r) { 7817 while (i != r) {
@@ -4927,7 +7825,7 @@ static void ipw_rx(struct ipw_priv *priv)
4927 priv->rxq->queue[i] = NULL; 7825 priv->rxq->queue[i] = NULL;
4928 7826
4929 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 7827 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4930 CX2_RX_BUF_SIZE, 7828 IPW_RX_BUF_SIZE,
4931 PCI_DMA_FROMDEVICE); 7829 PCI_DMA_FROMDEVICE);
4932 7830
4933 pkt = (struct ipw_rx_packet *)rxb->skb->data; 7831 pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -4938,9 +7836,13 @@ static void ipw_rx(struct ipw_priv *priv)
4938 switch (pkt->header.message_type) { 7836 switch (pkt->header.message_type) {
4939 case RX_FRAME_TYPE: /* 802.11 frame */ { 7837 case RX_FRAME_TYPE: /* 802.11 frame */ {
4940 struct ieee80211_rx_stats stats = { 7838 struct ieee80211_rx_stats stats = {
4941 .rssi = pkt->u.frame.rssi_dbm - 7839 .rssi =
7840 le16_to_cpu(pkt->u.frame.rssi_dbm) -
4942 IPW_RSSI_TO_DBM, 7841 IPW_RSSI_TO_DBM,
4943 .signal = pkt->u.frame.signal, 7842 .signal =
7843 le16_to_cpu(pkt->u.frame.signal),
7844 .noise =
7845 le16_to_cpu(pkt->u.frame.noise),
4944 .rate = pkt->u.frame.rate, 7846 .rate = pkt->u.frame.rate,
4945 .mac_time = jiffies, 7847 .mac_time = jiffies,
4946 .received_channel = 7848 .received_channel =
@@ -4950,22 +7852,30 @@ static void ipw_rx(struct ipw_priv *priv)
4950 control & (1 << 0)) ? 7852 control & (1 << 0)) ?
4951 IEEE80211_24GHZ_BAND : 7853 IEEE80211_24GHZ_BAND :
4952 IEEE80211_52GHZ_BAND, 7854 IEEE80211_52GHZ_BAND,
4953 .len = pkt->u.frame.length, 7855 .len = le16_to_cpu(pkt->u.frame.length),
4954 }; 7856 };
4955 7857
4956 if (stats.rssi != 0) 7858 if (stats.rssi != 0)
4957 stats.mask |= IEEE80211_STATMASK_RSSI; 7859 stats.mask |= IEEE80211_STATMASK_RSSI;
4958 if (stats.signal != 0) 7860 if (stats.signal != 0)
4959 stats.mask |= IEEE80211_STATMASK_SIGNAL; 7861 stats.mask |= IEEE80211_STATMASK_SIGNAL;
7862 if (stats.noise != 0)
7863 stats.mask |= IEEE80211_STATMASK_NOISE;
4960 if (stats.rate != 0) 7864 if (stats.rate != 0)
4961 stats.mask |= IEEE80211_STATMASK_RATE; 7865 stats.mask |= IEEE80211_STATMASK_RATE;
4962 7866
4963 priv->rx_packets++; 7867 priv->rx_packets++;
4964 7868
4965#ifdef CONFIG_IPW_PROMISC 7869#ifdef CONFIG_IPW2200_MONITOR
4966 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 7870 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7871#ifdef CONFIG_IEEE80211_RADIOTAP
7872 ipw_handle_data_packet_monitor(priv,
7873 rxb,
7874 &stats);
7875#else
4967 ipw_handle_data_packet(priv, rxb, 7876 ipw_handle_data_packet(priv, rxb,
4968 &stats); 7877 &stats);
7878#endif
4969 break; 7879 break;
4970 } 7880 }
4971#endif 7881#endif
@@ -4979,35 +7889,9 @@ static void ipw_rx(struct ipw_priv *priv)
4979 * correctly -- we should probably use the 7889 * correctly -- we should probably use the
4980 * frame control of the packet and disregard 7890 * frame control of the packet and disregard
4981 * the current iw_mode */ 7891 * the current iw_mode */
4982 switch (priv->ieee->iw_mode) {
4983 case IW_MODE_ADHOC:
4984 network_packet =
4985 !memcmp(header->addr1,
4986 priv->net_dev->dev_addr,
4987 ETH_ALEN) ||
4988 !memcmp(header->addr3,
4989 priv->bssid, ETH_ALEN) ||
4990 is_broadcast_ether_addr(header->
4991 addr1)
4992 || is_multicast_ether_addr(header->
4993 addr1);
4994 break;
4995
4996 case IW_MODE_INFRA:
4997 default:
4998 network_packet =
4999 !memcmp(header->addr3,
5000 priv->bssid, ETH_ALEN) ||
5001 !memcmp(header->addr1,
5002 priv->net_dev->dev_addr,
5003 ETH_ALEN) ||
5004 is_broadcast_ether_addr(header->
5005 addr1)
5006 || is_multicast_ether_addr(header->
5007 addr1);
5008 break;
5009 }
5010 7892
7893 network_packet =
7894 is_network_packet(priv, header);
5011 if (network_packet && priv->assoc_network) { 7895 if (network_packet && priv->assoc_network) {
5012 priv->assoc_network->stats.rssi = 7896 priv->assoc_network->stats.rssi =
5013 stats.rssi; 7897 stats.rssi;
@@ -5017,9 +7901,10 @@ static void ipw_rx(struct ipw_priv *priv)
5017 } 7901 }
5018 7902
5019 IPW_DEBUG_RX("Frame: len=%u\n", 7903 IPW_DEBUG_RX("Frame: len=%u\n",
5020 pkt->u.frame.length); 7904 le16_to_cpu(pkt->u.frame.length));
5021 7905
5022 if (pkt->u.frame.length < frame_hdr_len(header)) { 7906 if (le16_to_cpu(pkt->u.frame.length) <
7907 frame_hdr_len(header)) {
5023 IPW_DEBUG_DROP 7908 IPW_DEBUG_DROP
5024 ("Received packet is too small. " 7909 ("Received packet is too small. "
5025 "Dropping.\n"); 7910 "Dropping.\n");
@@ -5028,34 +7913,22 @@ static void ipw_rx(struct ipw_priv *priv)
5028 break; 7913 break;
5029 } 7914 }
5030 7915
5031 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { 7916 switch (WLAN_FC_GET_TYPE
7917 (le16_to_cpu(header->frame_ctl))) {
7918
5032 case IEEE80211_FTYPE_MGMT: 7919 case IEEE80211_FTYPE_MGMT:
5033 ieee80211_rx_mgt(priv->ieee, header, 7920 ipw_handle_mgmt_packet(priv, rxb,
5034 &stats); 7921 &stats);
5035 if (priv->ieee->iw_mode == IW_MODE_ADHOC
5036 &&
5037 ((WLAN_FC_GET_STYPE
5038 (header->frame_ctl) ==
5039 IEEE80211_STYPE_PROBE_RESP)
5040 ||
5041 (WLAN_FC_GET_STYPE
5042 (header->frame_ctl) ==
5043 IEEE80211_STYPE_BEACON))
5044 && !memcmp(header->addr3,
5045 priv->bssid, ETH_ALEN))
5046 ipw_add_station(priv,
5047 header->addr2);
5048 break; 7922 break;
5049 7923
5050 case IEEE80211_FTYPE_CTL: 7924 case IEEE80211_FTYPE_CTL:
5051 break; 7925 break;
5052 7926
5053 case IEEE80211_FTYPE_DATA: 7927 case IEEE80211_FTYPE_DATA:
5054 if (network_packet) 7928 if (unlikely(!network_packet ||
5055 ipw_handle_data_packet(priv, 7929 is_duplicate_packet(priv,
5056 rxb, 7930 header)))
5057 &stats); 7931 {
5058 else
5059 IPW_DEBUG_DROP("Dropping: " 7932 IPW_DEBUG_DROP("Dropping: "
5060 MAC_FMT ", " 7933 MAC_FMT ", "
5061 MAC_FMT ", " 7934 MAC_FMT ", "
@@ -5066,6 +7939,12 @@ static void ipw_rx(struct ipw_priv *priv)
5066 addr2), 7939 addr2),
5067 MAC_ARG(header-> 7940 MAC_ARG(header->
5068 addr3)); 7941 addr3));
7942 break;
7943 }
7944
7945 ipw_handle_data_packet(priv, rxb,
7946 &stats);
7947
5069 break; 7948 break;
5070 } 7949 }
5071 break; 7950 break;
@@ -5096,7 +7975,7 @@ static void ipw_rx(struct ipw_priv *priv)
5096 } 7975 }
5097 7976
5098 pci_unmap_single(priv->pci_dev, rxb->dma_addr, 7977 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
5099 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 7978 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5100 list_add_tail(&rxb->list, &priv->rxq->rx_used); 7979 list_add_tail(&rxb->list, &priv->rxq->rx_used);
5101 7980
5102 i = (i + 1) % RX_QUEUE_SIZE; 7981 i = (i + 1) % RX_QUEUE_SIZE;
@@ -5108,128 +7987,129 @@ static void ipw_rx(struct ipw_priv *priv)
5108 ipw_rx_queue_restock(priv); 7987 ipw_rx_queue_restock(priv);
5109} 7988}
5110 7989
5111static void ipw_abort_scan(struct ipw_priv *priv) 7990#define DEFAULT_RTS_THRESHOLD 2304U
7991#define MIN_RTS_THRESHOLD 1U
7992#define MAX_RTS_THRESHOLD 2304U
7993#define DEFAULT_BEACON_INTERVAL 100U
7994#define DEFAULT_SHORT_RETRY_LIMIT 7U
7995#define DEFAULT_LONG_RETRY_LIMIT 4U
7996
7997static int ipw_sw_reset(struct ipw_priv *priv, int init)
5112{ 7998{
5113 int err; 7999 int band, modulation;
8000 int old_mode = priv->ieee->iw_mode;
5114 8001
5115 if (priv->status & STATUS_SCAN_ABORTING) { 8002 /* Initialize module parameter values here */
5116 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n"); 8003 priv->config = 0;
5117 return;
5118 }
5119 priv->status |= STATUS_SCAN_ABORTING;
5120 8004
5121 err = ipw_send_scan_abort(priv); 8005 /* We default to disabling the LED code as right now it causes
5122 if (err) 8006 * too many systems to lock up... */
5123 IPW_DEBUG_HC("Request to abort scan failed.\n"); 8007 if (!led)
5124} 8008 priv->config |= CFG_NO_LED;
5125 8009
5126static int ipw_request_scan(struct ipw_priv *priv) 8010 if (associate)
5127{ 8011 priv->config |= CFG_ASSOCIATE;
5128 struct ipw_scan_request_ext scan; 8012 else
5129 int channel_index = 0; 8013 IPW_DEBUG_INFO("Auto associate disabled.\n");
5130 int i, err, scan_type;
5131 8014
5132 if (priv->status & STATUS_EXIT_PENDING) { 8015 if (auto_create)
5133 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n"); 8016 priv->config |= CFG_ADHOC_CREATE;
5134 priv->status |= STATUS_SCAN_PENDING; 8017 else
5135 return 0; 8018 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
5136 }
5137 8019
5138 if (priv->status & STATUS_SCANNING) { 8020 if (disable) {
5139 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n"); 8021 priv->status |= STATUS_RF_KILL_SW;
5140 priv->status |= STATUS_SCAN_PENDING; 8022 IPW_DEBUG_INFO("Radio disabled.\n");
5141 ipw_abort_scan(priv);
5142 return 0;
5143 } 8023 }
5144 8024
5145 if (priv->status & STATUS_SCAN_ABORTING) { 8025 if (channel != 0) {
5146 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); 8026 priv->config |= CFG_STATIC_CHANNEL;
5147 priv->status |= STATUS_SCAN_PENDING; 8027 priv->channel = channel;
5148 return 0; 8028 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8029 /* TODO: Validate that provided channel is in range */
5149 } 8030 }
8031#ifdef CONFIG_IPW_QOS
8032 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8033 burst_duration_CCK, burst_duration_OFDM);
8034#endif /* CONFIG_IPW_QOS */
5150 8035
5151 if (priv->status & STATUS_RF_KILL_MASK) { 8036 switch (mode) {
5152 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); 8037 case 1:
5153 priv->status |= STATUS_SCAN_PENDING; 8038 priv->ieee->iw_mode = IW_MODE_ADHOC;
5154 return 0; 8039 priv->net_dev->type = ARPHRD_ETHER;
8040
8041 break;
8042#ifdef CONFIG_IPW2200_MONITOR
8043 case 2:
8044 priv->ieee->iw_mode = IW_MODE_MONITOR;
8045#ifdef CONFIG_IEEE80211_RADIOTAP
8046 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8047#else
8048 priv->net_dev->type = ARPHRD_IEEE80211;
8049#endif
8050 break;
8051#endif
8052 default:
8053 case 0:
8054 priv->net_dev->type = ARPHRD_ETHER;
8055 priv->ieee->iw_mode = IW_MODE_INFRA;
8056 break;
5155 } 8057 }
5156 8058
5157 memset(&scan, 0, sizeof(scan)); 8059 if (hwcrypto) {
8060 priv->ieee->host_encrypt = 0;
8061 priv->ieee->host_encrypt_msdu = 0;
8062 priv->ieee->host_decrypt = 0;
8063 priv->ieee->host_mc_decrypt = 0;
8064 }
8065 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
5158 8066
5159 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20; 8067 /* IPW2200/2915 is abled to do hardware fragmentation. */
5160 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20; 8068 priv->ieee->host_open_frag = 0;
5161 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5162
5163 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5164 /* If we are roaming, then make this a directed scan for the current
5165 * network. Otherwise, ensure that every other scan is a fast
5166 * channel hop scan */
5167 if ((priv->status & STATUS_ROAMING)
5168 || (!(priv->status & STATUS_ASSOCIATED)
5169 && (priv->config & CFG_STATIC_ESSID)
5170 && (scan.full_scan_index % 2))) {
5171 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5172 if (err) {
5173 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5174 return err;
5175 }
5176 8069
5177 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; 8070 if ((priv->pci_dev->device == 0x4223) ||
8071 (priv->pci_dev->device == 0x4224)) {
8072 if (init)
8073 printk(KERN_INFO DRV_NAME
8074 ": Detected Intel PRO/Wireless 2915ABG Network "
8075 "Connection\n");
8076 priv->ieee->abg_true = 1;
8077 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8078 modulation = IEEE80211_OFDM_MODULATION |
8079 IEEE80211_CCK_MODULATION;
8080 priv->adapter = IPW_2915ABG;
8081 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
5178 } else { 8082 } else {
5179 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; 8083 if (init)
5180 } 8084 printk(KERN_INFO DRV_NAME
5181 8085 ": Detected Intel PRO/Wireless 2200BG Network "
5182 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 8086 "Connection\n");
5183 int start = channel_index;
5184 for (i = 0; i < MAX_A_CHANNELS; i++) {
5185 if (band_a_active_channel[i] == 0)
5186 break;
5187 if ((priv->status & STATUS_ASSOCIATED) &&
5188 band_a_active_channel[i] == priv->channel)
5189 continue;
5190 channel_index++;
5191 scan.channels_list[channel_index] =
5192 band_a_active_channel[i];
5193 ipw_set_scan_type(&scan, channel_index, scan_type);
5194 }
5195 8087
5196 if (start != channel_index) { 8088 priv->ieee->abg_true = 0;
5197 scan.channels_list[start] = (u8) (IPW_A_MODE << 6) | 8089 band = IEEE80211_24GHZ_BAND;
5198 (channel_index - start); 8090 modulation = IEEE80211_OFDM_MODULATION |
5199 channel_index++; 8091 IEEE80211_CCK_MODULATION;
5200 } 8092 priv->adapter = IPW_2200BG;
8093 priv->ieee->mode = IEEE_G | IEEE_B;
5201 } 8094 }
5202 8095
5203 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { 8096 priv->ieee->freq_band = band;
5204 int start = channel_index; 8097 priv->ieee->modulation = modulation;
5205 for (i = 0; i < MAX_B_CHANNELS; i++) {
5206 if (band_b_active_channel[i] == 0)
5207 break;
5208 if ((priv->status & STATUS_ASSOCIATED) &&
5209 band_b_active_channel[i] == priv->channel)
5210 continue;
5211 channel_index++;
5212 scan.channels_list[channel_index] =
5213 band_b_active_channel[i];
5214 ipw_set_scan_type(&scan, channel_index, scan_type);
5215 }
5216 8098
5217 if (start != channel_index) { 8099 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
5218 scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
5219 (channel_index - start);
5220 }
5221 }
5222 8100
5223 err = ipw_send_scan_request_ext(priv, &scan); 8101 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
5224 if (err) { 8102 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
5225 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5226 return -EIO;
5227 }
5228 8103
5229 priv->status |= STATUS_SCANNING; 8104 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5230 priv->status &= ~STATUS_SCAN_PENDING; 8105 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8106 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
5231 8107
5232 return 0; 8108 /* If power management is turned on, default to AC mode */
8109 priv->power_mode = IPW_POWER_AC;
8110 priv->tx_power = IPW_TX_POWER_DEFAULT;
8111
8112 return old_mode == priv->ieee->iw_mode;
5233} 8113}
5234 8114
5235/* 8115/*
@@ -5247,12 +8127,16 @@ static int ipw_wx_get_name(struct net_device *dev,
5247 union iwreq_data *wrqu, char *extra) 8127 union iwreq_data *wrqu, char *extra)
5248{ 8128{
5249 struct ipw_priv *priv = ieee80211_priv(dev); 8129 struct ipw_priv *priv = ieee80211_priv(dev);
5250 if (!(priv->status & STATUS_ASSOCIATED)) 8130 down(&priv->sem);
8131 if (priv->status & STATUS_RF_KILL_MASK)
8132 strcpy(wrqu->name, "radio off");
8133 else if (!(priv->status & STATUS_ASSOCIATED))
5251 strcpy(wrqu->name, "unassociated"); 8134 strcpy(wrqu->name, "unassociated");
5252 else 8135 else
5253 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 8136 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
5254 ipw_modes[priv->assoc_request.ieee_mode]); 8137 ipw_modes[priv->assoc_request.ieee_mode]);
5255 IPW_DEBUG_WX("Name: %s\n", wrqu->name); 8138 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8139 up(&priv->sem);
5256 return 0; 8140 return 0;
5257} 8141}
5258 8142
@@ -5261,13 +8145,9 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5261 if (channel == 0) { 8145 if (channel == 0) {
5262 IPW_DEBUG_INFO("Setting channel to ANY (0)\n"); 8146 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
5263 priv->config &= ~CFG_STATIC_CHANNEL; 8147 priv->config &= ~CFG_STATIC_CHANNEL;
5264 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8148 IPW_DEBUG_ASSOC("Attempting to associate with new "
5265 STATUS_ASSOCIATING))) { 8149 "parameters.\n");
5266 IPW_DEBUG_ASSOC("Attempting to associate with new " 8150 ipw_associate(priv);
5267 "parameters.\n");
5268 ipw_associate(priv);
5269 }
5270
5271 return 0; 8151 return 0;
5272 } 8152 }
5273 8153
@@ -5282,14 +8162,32 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5282 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel); 8162 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
5283 priv->channel = channel; 8163 priv->channel = channel;
5284 8164
5285 /* If we are currently associated, or trying to associate 8165#ifdef CONFIG_IPW2200_MONITOR
5286 * then see if this is a new channel (causing us to disassociate) */ 8166 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5287 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8167 int i;
5288 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n"); 8168 if (priv->status & STATUS_SCANNING) {
5289 ipw_disassociate(priv); 8169 IPW_DEBUG_SCAN("Scan abort triggered due to "
5290 } else { 8170 "channel change.\n");
5291 ipw_associate(priv); 8171 ipw_abort_scan(priv);
8172 }
8173
8174 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8175 udelay(10);
8176
8177 if (priv->status & STATUS_SCANNING)
8178 IPW_DEBUG_SCAN("Still scanning...\n");
8179 else
8180 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8181 1000 - i);
8182
8183 return 0;
5292 } 8184 }
8185#endif /* CONFIG_IPW2200_MONITOR */
8186
8187 /* Network configuration changed -- force [re]association */
8188 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8189 if (!ipw_disassociate(priv))
8190 ipw_associate(priv);
5293 8191
5294 return 0; 8192 return 0;
5295} 8193}
@@ -5299,29 +8197,48 @@ static int ipw_wx_set_freq(struct net_device *dev,
5299 union iwreq_data *wrqu, char *extra) 8197 union iwreq_data *wrqu, char *extra)
5300{ 8198{
5301 struct ipw_priv *priv = ieee80211_priv(dev); 8199 struct ipw_priv *priv = ieee80211_priv(dev);
8200 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5302 struct iw_freq *fwrq = &wrqu->freq; 8201 struct iw_freq *fwrq = &wrqu->freq;
5303 8202 int ret = 0, i;
8203 u8 channel, flags;
8204 int band;
8205
8206 if (fwrq->m == 0) {
8207 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8208 down(&priv->sem);
8209 ret = ipw_set_channel(priv, 0);
8210 up(&priv->sem);
8211 return ret;
8212 }
5304 /* if setting by freq convert to channel */ 8213 /* if setting by freq convert to channel */
5305 if (fwrq->e == 1) { 8214 if (fwrq->e == 1) {
5306 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) { 8215 channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
5307 int f = fwrq->m / 100000; 8216 if (channel == 0)
5308 int c = 0; 8217 return -EINVAL;
8218 } else
8219 channel = fwrq->m;
8220
8221 if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
8222 return -EINVAL;
5309 8223
5310 while ((c < REG_MAX_CHANNEL) && 8224 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5311 (f != ipw_frequencies[c])) 8225 i = ipw_channel_to_index(priv->ieee, channel);
5312 c++; 8226 if (i == -1)
8227 return -EINVAL;
5313 8228
5314 /* hack to fall through */ 8229 flags = (band == IEEE80211_24GHZ_BAND) ?
5315 fwrq->e = 0; 8230 geo->bg[i].flags : geo->a[i].flags;
5316 fwrq->m = c + 1; 8231 if (flags & IEEE80211_CH_PASSIVE_ONLY) {
8232 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8233 return -EINVAL;
5317 } 8234 }
5318 } 8235 }
5319 8236
5320 if (fwrq->e > 0 || fwrq->m > 1000)
5321 return -EOPNOTSUPP;
5322
5323 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8237 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
5324 return ipw_set_channel(priv, (u8) fwrq->m); 8238 down(&priv->sem);
8239 ret = ipw_set_channel(priv, channel);
8240 up(&priv->sem);
8241 return ret;
5325} 8242}
5326 8243
5327static int ipw_wx_get_freq(struct net_device *dev, 8244static int ipw_wx_get_freq(struct net_device *dev,
@@ -5334,12 +8251,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
5334 8251
5335 /* If we are associated, trying to associate, or have a statically 8252 /* If we are associated, trying to associate, or have a statically
5336 * configured CHANNEL then return that; otherwise return ANY */ 8253 * configured CHANNEL then return that; otherwise return ANY */
8254 down(&priv->sem);
5337 if (priv->config & CFG_STATIC_CHANNEL || 8255 if (priv->config & CFG_STATIC_CHANNEL ||
5338 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8256 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
5339 wrqu->freq.m = priv->channel; 8257 wrqu->freq.m = priv->channel;
5340 else 8258 else
5341 wrqu->freq.m = 0; 8259 wrqu->freq.m = 0;
5342 8260
8261 up(&priv->sem);
5343 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8262 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
5344 return 0; 8263 return 0;
5345} 8264}
@@ -5353,11 +8272,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
5353 8272
5354 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode); 8273 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
5355 8274
5356 if (wrqu->mode == priv->ieee->iw_mode)
5357 return 0;
5358
5359 switch (wrqu->mode) { 8275 switch (wrqu->mode) {
5360#ifdef CONFIG_IPW_PROMISC 8276#ifdef CONFIG_IPW2200_MONITOR
5361 case IW_MODE_MONITOR: 8277 case IW_MODE_MONITOR:
5362#endif 8278#endif
5363 case IW_MODE_ADHOC: 8279 case IW_MODE_ADHOC:
@@ -5369,31 +8285,33 @@ static int ipw_wx_set_mode(struct net_device *dev,
5369 default: 8285 default:
5370 return -EINVAL; 8286 return -EINVAL;
5371 } 8287 }
8288 if (wrqu->mode == priv->ieee->iw_mode)
8289 return 0;
8290
8291 down(&priv->sem);
8292
8293 ipw_sw_reset(priv, 0);
5372 8294
5373#ifdef CONFIG_IPW_PROMISC 8295#ifdef CONFIG_IPW2200_MONITOR
5374 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8296 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5375 priv->net_dev->type = ARPHRD_ETHER; 8297 priv->net_dev->type = ARPHRD_ETHER;
5376 8298
5377 if (wrqu->mode == IW_MODE_MONITOR) 8299 if (wrqu->mode == IW_MODE_MONITOR)
8300#ifdef CONFIG_IEEE80211_RADIOTAP
8301 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8302#else
5378 priv->net_dev->type = ARPHRD_IEEE80211; 8303 priv->net_dev->type = ARPHRD_IEEE80211;
5379#endif /* CONFIG_IPW_PROMISC */ 8304#endif
8305#endif /* CONFIG_IPW2200_MONITOR */
5380 8306
5381#ifdef CONFIG_PM
5382 /* Free the existing firmware and reset the fw_loaded 8307 /* Free the existing firmware and reset the fw_loaded
5383 * flag so ipw_load() will bring in the new firmawre */ 8308 * flag so ipw_load() will bring in the new firmawre */
5384 if (fw_loaded) { 8309 free_firmware();
5385 fw_loaded = 0;
5386 }
5387
5388 release_firmware(bootfw);
5389 release_firmware(ucode);
5390 release_firmware(firmware);
5391 bootfw = ucode = firmware = NULL;
5392#endif
5393 8310
5394 priv->ieee->iw_mode = wrqu->mode; 8311 priv->ieee->iw_mode = wrqu->mode;
5395 ipw_adapter_restart(priv);
5396 8312
8313 queue_work(priv->workqueue, &priv->adapter_restart);
8314 up(&priv->sem);
5397 return err; 8315 return err;
5398} 8316}
5399 8317
@@ -5402,20 +8320,13 @@ static int ipw_wx_get_mode(struct net_device *dev,
5402 union iwreq_data *wrqu, char *extra) 8320 union iwreq_data *wrqu, char *extra)
5403{ 8321{
5404 struct ipw_priv *priv = ieee80211_priv(dev); 8322 struct ipw_priv *priv = ieee80211_priv(dev);
5405 8323 down(&priv->sem);
5406 wrqu->mode = priv->ieee->iw_mode; 8324 wrqu->mode = priv->ieee->iw_mode;
5407 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); 8325 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
5408 8326 up(&priv->sem);
5409 return 0; 8327 return 0;
5410} 8328}
5411 8329
5412#define DEFAULT_RTS_THRESHOLD 2304U
5413#define MIN_RTS_THRESHOLD 1U
5414#define MAX_RTS_THRESHOLD 2304U
5415#define DEFAULT_BEACON_INTERVAL 100U
5416#define DEFAULT_SHORT_RETRY_LIMIT 7U
5417#define DEFAULT_LONG_RETRY_LIMIT 4U
5418
5419/* Values are in microsecond */ 8330/* Values are in microsecond */
5420static const s32 timeout_duration[] = { 8331static const s32 timeout_duration[] = {
5421 350000, 8332 350000,
@@ -5439,8 +8350,8 @@ static int ipw_wx_get_range(struct net_device *dev,
5439{ 8350{
5440 struct ipw_priv *priv = ieee80211_priv(dev); 8351 struct ipw_priv *priv = ieee80211_priv(dev);
5441 struct iw_range *range = (struct iw_range *)extra; 8352 struct iw_range *range = (struct iw_range *)extra;
5442 u16 val; 8353 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5443 int i; 8354 int i = 0, j;
5444 8355
5445 wrqu->data.length = sizeof(*range); 8356 wrqu->data.length = sizeof(*range);
5446 memset(range, 0, sizeof(*range)); 8357 memset(range, 0, sizeof(*range));
@@ -5451,7 +8362,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5451 range->max_qual.qual = 100; 8362 range->max_qual.qual = 100;
5452 /* TODO: Find real max RSSI and stick here */ 8363 /* TODO: Find real max RSSI and stick here */
5453 range->max_qual.level = 0; 8364 range->max_qual.level = 0;
5454 range->max_qual.noise = 0; 8365 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
5455 range->max_qual.updated = 7; /* Updated all three */ 8366 range->max_qual.updated = 7; /* Updated all three */
5456 8367
5457 range->avg_qual.qual = 70; 8368 range->avg_qual.qual = 70;
@@ -5459,7 +8370,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5459 range->avg_qual.level = 0; /* FIXME to real average level */ 8370 range->avg_qual.level = 0; /* FIXME to real average level */
5460 range->avg_qual.noise = 0; 8371 range->avg_qual.noise = 0;
5461 range->avg_qual.updated = 7; /* Updated all three */ 8372 range->avg_qual.updated = 7; /* Updated all three */
5462 8373 down(&priv->sem);
5463 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); 8374 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
5464 8375
5465 for (i = 0; i < range->num_bitrates; i++) 8376 for (i = 0; i < range->num_bitrates; i++)
@@ -5479,19 +8390,35 @@ static int ipw_wx_get_range(struct net_device *dev,
5479 range->we_version_compiled = WIRELESS_EXT; 8390 range->we_version_compiled = WIRELESS_EXT;
5480 range->we_version_source = 16; 8391 range->we_version_source = 16;
5481 8392
5482 range->num_channels = FREQ_COUNT; 8393 i = 0;
5483 8394 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
5484 val = 0; 8395 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
5485 for (i = 0; i < FREQ_COUNT; i++) { 8396 i++, j++) {
5486 range->freq[val].i = i + 1; 8397 range->freq[i].i = geo->bg[j].channel;
5487 range->freq[val].m = ipw_frequencies[i] * 100000; 8398 range->freq[i].m = geo->bg[j].freq * 100000;
5488 range->freq[val].e = 1; 8399 range->freq[i].e = 1;
5489 val++; 8400 }
8401 }
5490 8402
5491 if (val == IW_MAX_FREQUENCIES) 8403 if (priv->ieee->mode & IEEE_A) {
5492 break; 8404 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
8405 i++, j++) {
8406 range->freq[i].i = geo->a[j].channel;
8407 range->freq[i].m = geo->a[j].freq * 100000;
8408 range->freq[i].e = 1;
8409 }
5493 } 8410 }
5494 range->num_frequency = val; 8411
8412 range->num_channels = i;
8413 range->num_frequency = i;
8414
8415 up(&priv->sem);
8416
8417 /* Event capability (kernel + driver) */
8418 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8419 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8420 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8421 range->event_capa[1] = IW_EVENT_CAPA_K_1;
5495 8422
5496 IPW_DEBUG_WX("GET Range\n"); 8423 IPW_DEBUG_WX("GET Range\n");
5497 return 0; 8424 return 0;
@@ -5512,25 +8439,23 @@ static int ipw_wx_set_wap(struct net_device *dev,
5512 8439
5513 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 8440 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
5514 return -EINVAL; 8441 return -EINVAL;
5515 8442 down(&priv->sem);
5516 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || 8443 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
5517 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8444 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5518 /* we disable mandatory BSSID association */ 8445 /* we disable mandatory BSSID association */
5519 IPW_DEBUG_WX("Setting AP BSSID to ANY\n"); 8446 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
5520 priv->config &= ~CFG_STATIC_BSSID; 8447 priv->config &= ~CFG_STATIC_BSSID;
5521 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8448 IPW_DEBUG_ASSOC("Attempting to associate with new "
5522 STATUS_ASSOCIATING))) { 8449 "parameters.\n");
5523 IPW_DEBUG_ASSOC("Attempting to associate with new " 8450 ipw_associate(priv);
5524 "parameters.\n"); 8451 up(&priv->sem);
5525 ipw_associate(priv);
5526 }
5527
5528 return 0; 8452 return 0;
5529 } 8453 }
5530 8454
5531 priv->config |= CFG_STATIC_BSSID; 8455 priv->config |= CFG_STATIC_BSSID;
5532 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8456 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5533 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 8457 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8458 up(&priv->sem);
5534 return 0; 8459 return 0;
5535 } 8460 }
5536 8461
@@ -5539,15 +8464,12 @@ static int ipw_wx_set_wap(struct net_device *dev,
5539 8464
5540 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN); 8465 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
5541 8466
5542 /* If we are currently associated, or trying to associate 8467 /* Network configuration changed -- force [re]association */
5543 * then see if this is a new BSSID (causing us to disassociate) */ 8468 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
5544 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8469 if (!ipw_disassociate(priv))
5545 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
5546 ipw_disassociate(priv);
5547 } else {
5548 ipw_associate(priv); 8470 ipw_associate(priv);
5549 }
5550 8471
8472 up(&priv->sem);
5551 return 0; 8473 return 0;
5552} 8474}
5553 8475
@@ -5558,15 +8480,17 @@ static int ipw_wx_get_wap(struct net_device *dev,
5558 struct ipw_priv *priv = ieee80211_priv(dev); 8480 struct ipw_priv *priv = ieee80211_priv(dev);
5559 /* If we are associated, trying to associate, or have a statically 8481 /* If we are associated, trying to associate, or have a statically
5560 * configured BSSID then return that; otherwise return ANY */ 8482 * configured BSSID then return that; otherwise return ANY */
8483 down(&priv->sem);
5561 if (priv->config & CFG_STATIC_BSSID || 8484 if (priv->config & CFG_STATIC_BSSID ||
5562 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8485 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5563 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 8486 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
5564 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 8487 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
5565 } else 8488 } else
5566 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 8489 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
5567 8490
5568 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", 8491 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
5569 MAC_ARG(wrqu->ap_addr.sa_data)); 8492 MAC_ARG(wrqu->ap_addr.sa_data));
8493 up(&priv->sem);
5570 return 0; 8494 return 0;
5571} 8495}
5572 8496
@@ -5577,21 +8501,22 @@ static int ipw_wx_set_essid(struct net_device *dev,
5577 struct ipw_priv *priv = ieee80211_priv(dev); 8501 struct ipw_priv *priv = ieee80211_priv(dev);
5578 char *essid = ""; /* ANY */ 8502 char *essid = ""; /* ANY */
5579 int length = 0; 8503 int length = 0;
5580 8504 down(&priv->sem);
5581 if (wrqu->essid.flags && wrqu->essid.length) { 8505 if (wrqu->essid.flags && wrqu->essid.length) {
5582 length = wrqu->essid.length - 1; 8506 length = wrqu->essid.length - 1;
5583 essid = extra; 8507 essid = extra;
5584 } 8508 }
5585 if (length == 0) { 8509 if (length == 0) {
5586 IPW_DEBUG_WX("Setting ESSID to ANY\n"); 8510 IPW_DEBUG_WX("Setting ESSID to ANY\n");
5587 priv->config &= ~CFG_STATIC_ESSID; 8511 if ((priv->config & CFG_STATIC_ESSID) &&
5588 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8512 !(priv->status & (STATUS_ASSOCIATED |
5589 STATUS_ASSOCIATING))) { 8513 STATUS_ASSOCIATING))) {
5590 IPW_DEBUG_ASSOC("Attempting to associate with new " 8514 IPW_DEBUG_ASSOC("Attempting to associate with new "
5591 "parameters.\n"); 8515 "parameters.\n");
8516 priv->config &= ~CFG_STATIC_ESSID;
5592 ipw_associate(priv); 8517 ipw_associate(priv);
5593 } 8518 }
5594 8519 up(&priv->sem);
5595 return 0; 8520 return 0;
5596 } 8521 }
5597 8522
@@ -5601,6 +8526,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
5601 8526
5602 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8527 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
5603 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8528 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8529 up(&priv->sem);
5604 return 0; 8530 return 0;
5605 } 8531 }
5606 8532
@@ -5610,15 +8536,12 @@ static int ipw_wx_set_essid(struct net_device *dev,
5610 priv->essid_len = length; 8536 priv->essid_len = length;
5611 memcpy(priv->essid, essid, priv->essid_len); 8537 memcpy(priv->essid, essid, priv->essid_len);
5612 8538
5613 /* If we are currently associated, or trying to associate 8539 /* Network configuration changed -- force [re]association */
5614 * then see if this is a new ESSID (causing us to disassociate) */ 8540 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
5615 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8541 if (!ipw_disassociate(priv))
5616 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
5617 ipw_disassociate(priv);
5618 } else {
5619 ipw_associate(priv); 8542 ipw_associate(priv);
5620 }
5621 8543
8544 up(&priv->sem);
5622 return 0; 8545 return 0;
5623} 8546}
5624 8547
@@ -5630,6 +8553,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5630 8553
5631 /* If we are associated, trying to associate, or have a statically 8554 /* If we are associated, trying to associate, or have a statically
5632 * configured ESSID then return that; otherwise return ANY */ 8555 * configured ESSID then return that; otherwise return ANY */
8556 down(&priv->sem);
5633 if (priv->config & CFG_STATIC_ESSID || 8557 if (priv->config & CFG_STATIC_ESSID ||
5634 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8558 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5635 IPW_DEBUG_WX("Getting essid: '%s'\n", 8559 IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -5642,7 +8566,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5642 wrqu->essid.length = 0; 8566 wrqu->essid.length = 0;
5643 wrqu->essid.flags = 0; /* active */ 8567 wrqu->essid.flags = 0; /* active */
5644 } 8568 }
5645 8569 up(&priv->sem);
5646 return 0; 8570 return 0;
5647} 8571}
5648 8572
@@ -5655,11 +8579,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
5655 IPW_DEBUG_WX("Setting nick to '%s'\n", extra); 8579 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
5656 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 8580 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
5657 return -E2BIG; 8581 return -E2BIG;
5658 8582 down(&priv->sem);
5659 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 8583 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
5660 memset(priv->nick, 0, sizeof(priv->nick)); 8584 memset(priv->nick, 0, sizeof(priv->nick));
5661 memcpy(priv->nick, extra, wrqu->data.length); 8585 memcpy(priv->nick, extra, wrqu->data.length);
5662 IPW_DEBUG_TRACE("<<\n"); 8586 IPW_DEBUG_TRACE("<<\n");
8587 up(&priv->sem);
5663 return 0; 8588 return 0;
5664 8589
5665} 8590}
@@ -5670,9 +8595,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
5670{ 8595{
5671 struct ipw_priv *priv = ieee80211_priv(dev); 8596 struct ipw_priv *priv = ieee80211_priv(dev);
5672 IPW_DEBUG_WX("Getting nick\n"); 8597 IPW_DEBUG_WX("Getting nick\n");
8598 down(&priv->sem);
5673 wrqu->data.length = strlen(priv->nick) + 1; 8599 wrqu->data.length = strlen(priv->nick) + 1;
5674 memcpy(extra, priv->nick, wrqu->data.length); 8600 memcpy(extra, priv->nick, wrqu->data.length);
5675 wrqu->data.flags = 1; /* active */ 8601 wrqu->data.flags = 1; /* active */
8602 up(&priv->sem);
5676 return 0; 8603 return 0;
5677} 8604}
5678 8605
@@ -5680,8 +8607,113 @@ static int ipw_wx_set_rate(struct net_device *dev,
5680 struct iw_request_info *info, 8607 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra) 8608 union iwreq_data *wrqu, char *extra)
5682{ 8609{
5683 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8610 /* TODO: We should use semaphores or locks for access to priv */
5684 return -EOPNOTSUPP; 8611 struct ipw_priv *priv = ieee80211_priv(dev);
8612 u32 target_rate = wrqu->bitrate.value;
8613 u32 fixed, mask;
8614
8615 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8616 /* value = X, fixed = 1 means only rate X */
8617 /* value = X, fixed = 0 means all rates lower equal X */
8618
8619 if (target_rate == -1) {
8620 fixed = 0;
8621 mask = IEEE80211_DEFAULT_RATES_MASK;
8622 /* Now we should reassociate */
8623 goto apply;
8624 }
8625
8626 mask = 0;
8627 fixed = wrqu->bitrate.fixed;
8628
8629 if (target_rate == 1000000 || !fixed)
8630 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8631 if (target_rate == 1000000)
8632 goto apply;
8633
8634 if (target_rate == 2000000 || !fixed)
8635 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8636 if (target_rate == 2000000)
8637 goto apply;
8638
8639 if (target_rate == 5500000 || !fixed)
8640 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8641 if (target_rate == 5500000)
8642 goto apply;
8643
8644 if (target_rate == 6000000 || !fixed)
8645 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8646 if (target_rate == 6000000)
8647 goto apply;
8648
8649 if (target_rate == 9000000 || !fixed)
8650 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8651 if (target_rate == 9000000)
8652 goto apply;
8653
8654 if (target_rate == 11000000 || !fixed)
8655 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8656 if (target_rate == 11000000)
8657 goto apply;
8658
8659 if (target_rate == 12000000 || !fixed)
8660 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8661 if (target_rate == 12000000)
8662 goto apply;
8663
8664 if (target_rate == 18000000 || !fixed)
8665 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8666 if (target_rate == 18000000)
8667 goto apply;
8668
8669 if (target_rate == 24000000 || !fixed)
8670 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8671 if (target_rate == 24000000)
8672 goto apply;
8673
8674 if (target_rate == 36000000 || !fixed)
8675 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8676 if (target_rate == 36000000)
8677 goto apply;
8678
8679 if (target_rate == 48000000 || !fixed)
8680 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8681 if (target_rate == 48000000)
8682 goto apply;
8683
8684 if (target_rate == 54000000 || !fixed)
8685 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8686 if (target_rate == 54000000)
8687 goto apply;
8688
8689 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8690 return -EINVAL;
8691
8692 apply:
8693 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8694 mask, fixed ? "fixed" : "sub-rates");
8695 down(&priv->sem);
8696 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
8697 priv->config &= ~CFG_FIXED_RATE;
8698 ipw_set_fixed_rate(priv, priv->ieee->mode);
8699 } else
8700 priv->config |= CFG_FIXED_RATE;
8701
8702 if (priv->rates_mask == mask) {
8703 IPW_DEBUG_WX("Mask set to current mask.\n");
8704 up(&priv->sem);
8705 return 0;
8706 }
8707
8708 priv->rates_mask = mask;
8709
8710 /* Network configuration changed -- force [re]association */
8711 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8712 if (!ipw_disassociate(priv))
8713 ipw_associate(priv);
8714
8715 up(&priv->sem);
8716 return 0;
5685} 8717}
5686 8718
5687static int ipw_wx_get_rate(struct net_device *dev, 8719static int ipw_wx_get_rate(struct net_device *dev,
@@ -5689,8 +8721,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
5689 union iwreq_data *wrqu, char *extra) 8721 union iwreq_data *wrqu, char *extra)
5690{ 8722{
5691 struct ipw_priv *priv = ieee80211_priv(dev); 8723 struct ipw_priv *priv = ieee80211_priv(dev);
8724 down(&priv->sem);
5692 wrqu->bitrate.value = priv->last_rate; 8725 wrqu->bitrate.value = priv->last_rate;
5693 8726 up(&priv->sem);
5694 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 8727 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
5695 return 0; 8728 return 0;
5696} 8729}
@@ -5700,18 +8733,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
5700 union iwreq_data *wrqu, char *extra) 8733 union iwreq_data *wrqu, char *extra)
5701{ 8734{
5702 struct ipw_priv *priv = ieee80211_priv(dev); 8735 struct ipw_priv *priv = ieee80211_priv(dev);
5703 8736 down(&priv->sem);
5704 if (wrqu->rts.disabled) 8737 if (wrqu->rts.disabled)
5705 priv->rts_threshold = DEFAULT_RTS_THRESHOLD; 8738 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5706 else { 8739 else {
5707 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 8740 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
5708 wrqu->rts.value > MAX_RTS_THRESHOLD) 8741 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8742 up(&priv->sem);
5709 return -EINVAL; 8743 return -EINVAL;
5710 8744 }
5711 priv->rts_threshold = wrqu->rts.value; 8745 priv->rts_threshold = wrqu->rts.value;
5712 } 8746 }
5713 8747
5714 ipw_send_rts_threshold(priv, priv->rts_threshold); 8748 ipw_send_rts_threshold(priv, priv->rts_threshold);
8749 up(&priv->sem);
5715 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 8750 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
5716 return 0; 8751 return 0;
5717} 8752}
@@ -5721,10 +8756,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
5721 union iwreq_data *wrqu, char *extra) 8756 union iwreq_data *wrqu, char *extra)
5722{ 8757{
5723 struct ipw_priv *priv = ieee80211_priv(dev); 8758 struct ipw_priv *priv = ieee80211_priv(dev);
8759 down(&priv->sem);
5724 wrqu->rts.value = priv->rts_threshold; 8760 wrqu->rts.value = priv->rts_threshold;
5725 wrqu->rts.fixed = 0; /* no auto select */ 8761 wrqu->rts.fixed = 0; /* no auto select */
5726 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 8762 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
5727 8763 up(&priv->sem);
5728 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 8764 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
5729 return 0; 8765 return 0;
5730} 8766}
@@ -5734,41 +8770,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
5734 union iwreq_data *wrqu, char *extra) 8770 union iwreq_data *wrqu, char *extra)
5735{ 8771{
5736 struct ipw_priv *priv = ieee80211_priv(dev); 8772 struct ipw_priv *priv = ieee80211_priv(dev);
5737 struct ipw_tx_power tx_power; 8773 int err = 0;
5738 int i;
5739
5740 if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
5741 return -EINPROGRESS;
5742
5743 if (wrqu->power.flags != IW_TXPOW_DBM)
5744 return -EINVAL;
5745 8774
5746 if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) 8775 down(&priv->sem);
5747 return -EINVAL; 8776 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8777 err = -EINPROGRESS;
8778 goto out;
8779 }
5748 8780
5749 priv->tx_power = wrqu->power.value; 8781 if (!wrqu->power.fixed)
8782 wrqu->power.value = IPW_TX_POWER_DEFAULT;
5750 8783
5751 memset(&tx_power, 0, sizeof(tx_power)); 8784 if (wrqu->power.flags != IW_TXPOW_DBM) {
5752 8785 err = -EINVAL;
5753 /* configure device for 'G' band */ 8786 goto out;
5754 tx_power.ieee_mode = IPW_G_MODE;
5755 tx_power.num_channels = 11;
5756 for (i = 0; i < 11; i++) {
5757 tx_power.channels_tx_power[i].channel_number = i + 1;
5758 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
5759 } 8787 }
5760 if (ipw_send_tx_power(priv, &tx_power))
5761 goto error;
5762 8788
5763 /* configure device to also handle 'B' band */ 8789 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
5764 tx_power.ieee_mode = IPW_B_MODE; 8790 (wrqu->power.value < IPW_TX_POWER_MIN)) {
5765 if (ipw_send_tx_power(priv, &tx_power)) 8791 err = -EINVAL;
5766 goto error; 8792 goto out;
5767 8793 }
5768 return 0;
5769 8794
5770 error: 8795 priv->tx_power = wrqu->power.value;
5771 return -EIO; 8796 err = ipw_set_tx_power(priv);
8797 out:
8798 up(&priv->sem);
8799 return err;
5772} 8800}
5773 8801
5774static int ipw_wx_get_txpow(struct net_device *dev, 8802static int ipw_wx_get_txpow(struct net_device *dev,
@@ -5776,14 +8804,15 @@ static int ipw_wx_get_txpow(struct net_device *dev,
5776 union iwreq_data *wrqu, char *extra) 8804 union iwreq_data *wrqu, char *extra)
5777{ 8805{
5778 struct ipw_priv *priv = ieee80211_priv(dev); 8806 struct ipw_priv *priv = ieee80211_priv(dev);
5779 8807 down(&priv->sem);
5780 wrqu->power.value = priv->tx_power; 8808 wrqu->power.value = priv->tx_power;
5781 wrqu->power.fixed = 1; 8809 wrqu->power.fixed = 1;
5782 wrqu->power.flags = IW_TXPOW_DBM; 8810 wrqu->power.flags = IW_TXPOW_DBM;
5783 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 8811 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
8812 up(&priv->sem);
5784 8813
5785 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 8814 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
5786 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); 8815 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
5787 8816
5788 return 0; 8817 return 0;
5789} 8818}
@@ -5793,18 +8822,21 @@ static int ipw_wx_set_frag(struct net_device *dev,
5793 union iwreq_data *wrqu, char *extra) 8822 union iwreq_data *wrqu, char *extra)
5794{ 8823{
5795 struct ipw_priv *priv = ieee80211_priv(dev); 8824 struct ipw_priv *priv = ieee80211_priv(dev);
5796 8825 down(&priv->sem);
5797 if (wrqu->frag.disabled) 8826 if (wrqu->frag.disabled)
5798 priv->ieee->fts = DEFAULT_FTS; 8827 priv->ieee->fts = DEFAULT_FTS;
5799 else { 8828 else {
5800 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 8829 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
5801 wrqu->frag.value > MAX_FRAG_THRESHOLD) 8830 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8831 up(&priv->sem);
5802 return -EINVAL; 8832 return -EINVAL;
8833 }
5803 8834
5804 priv->ieee->fts = wrqu->frag.value & ~0x1; 8835 priv->ieee->fts = wrqu->frag.value & ~0x1;
5805 } 8836 }
5806 8837
5807 ipw_send_frag_threshold(priv, wrqu->frag.value); 8838 ipw_send_frag_threshold(priv, wrqu->frag.value);
8839 up(&priv->sem);
5808 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 8840 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
5809 return 0; 8841 return 0;
5810} 8842}
@@ -5814,10 +8846,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
5814 union iwreq_data *wrqu, char *extra) 8846 union iwreq_data *wrqu, char *extra)
5815{ 8847{
5816 struct ipw_priv *priv = ieee80211_priv(dev); 8848 struct ipw_priv *priv = ieee80211_priv(dev);
8849 down(&priv->sem);
5817 wrqu->frag.value = priv->ieee->fts; 8850 wrqu->frag.value = priv->ieee->fts;
5818 wrqu->frag.fixed = 0; /* no auto select */ 8851 wrqu->frag.fixed = 0; /* no auto select */
5819 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 8852 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
5820 8853 up(&priv->sem);
5821 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 8854 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
5822 8855
5823 return 0; 8856 return 0;
@@ -5827,16 +8860,128 @@ static int ipw_wx_set_retry(struct net_device *dev,
5827 struct iw_request_info *info, 8860 struct iw_request_info *info,
5828 union iwreq_data *wrqu, char *extra) 8861 union iwreq_data *wrqu, char *extra)
5829{ 8862{
5830 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8863 struct ipw_priv *priv = ieee80211_priv(dev);
5831 return -EOPNOTSUPP; 8864
8865 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
8866 return -EINVAL;
8867
8868 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
8869 return 0;
8870
8871 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8872 return -EINVAL;
8873
8874 down(&priv->sem);
8875 if (wrqu->retry.flags & IW_RETRY_MIN)
8876 priv->short_retry_limit = (u8) wrqu->retry.value;
8877 else if (wrqu->retry.flags & IW_RETRY_MAX)
8878 priv->long_retry_limit = (u8) wrqu->retry.value;
8879 else {
8880 priv->short_retry_limit = (u8) wrqu->retry.value;
8881 priv->long_retry_limit = (u8) wrqu->retry.value;
8882 }
8883
8884 ipw_send_retry_limit(priv, priv->short_retry_limit,
8885 priv->long_retry_limit);
8886 up(&priv->sem);
8887 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8888 priv->short_retry_limit, priv->long_retry_limit);
8889 return 0;
5832} 8890}
5833 8891
5834static int ipw_wx_get_retry(struct net_device *dev, 8892static int ipw_wx_get_retry(struct net_device *dev,
5835 struct iw_request_info *info, 8893 struct iw_request_info *info,
5836 union iwreq_data *wrqu, char *extra) 8894 union iwreq_data *wrqu, char *extra)
5837{ 8895{
5838 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8896 struct ipw_priv *priv = ieee80211_priv(dev);
5839 return -EOPNOTSUPP; 8897
8898 down(&priv->sem);
8899 wrqu->retry.disabled = 0;
8900
8901 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8902 up(&priv->sem);
8903 return -EINVAL;
8904 }
8905
8906 if (wrqu->retry.flags & IW_RETRY_MAX) {
8907 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
8908 wrqu->retry.value = priv->long_retry_limit;
8909 } else if (wrqu->retry.flags & IW_RETRY_MIN) {
8910 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
8911 wrqu->retry.value = priv->short_retry_limit;
8912 } else {
8913 wrqu->retry.flags = IW_RETRY_LIMIT;
8914 wrqu->retry.value = priv->short_retry_limit;
8915 }
8916 up(&priv->sem);
8917
8918 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8919
8920 return 0;
8921}
8922
8923static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8924 int essid_len)
8925{
8926 struct ipw_scan_request_ext scan;
8927 int err = 0, scan_type;
8928
8929 down(&priv->sem);
8930
8931 if (priv->status & STATUS_RF_KILL_MASK) {
8932 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
8933 priv->status |= STATUS_SCAN_PENDING;
8934 goto done;
8935 }
8936
8937 IPW_DEBUG_HC("starting request direct scan!\n");
8938
8939 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
8940 err = wait_event_interruptible(priv->wait_state,
8941 !(priv->
8942 status & (STATUS_SCANNING |
8943 STATUS_SCAN_ABORTING)));
8944 if (err) {
8945 IPW_DEBUG_HC("aborting direct scan");
8946 goto done;
8947 }
8948 }
8949 memset(&scan, 0, sizeof(scan));
8950
8951 if (priv->config & CFG_SPEED_SCAN)
8952 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8953 cpu_to_le16(30);
8954 else
8955 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8956 cpu_to_le16(20);
8957
8958 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
8959 cpu_to_le16(20);
8960 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
8961 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
8962
8963 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
8964
8965 err = ipw_send_ssid(priv, essid, essid_len);
8966 if (err) {
8967 IPW_DEBUG_HC("Attempt to send SSID command failed\n");
8968 goto done;
8969 }
8970 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
8971
8972 ipw_add_scan_channels(priv, &scan, scan_type);
8973
8974 err = ipw_send_scan_request_ext(priv, &scan);
8975 if (err) {
8976 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
8977 goto done;
8978 }
8979
8980 priv->status |= STATUS_SCANNING;
8981
8982 done:
8983 up(&priv->sem);
8984 return err;
5840} 8985}
5841 8986
5842static int ipw_wx_set_scan(struct net_device *dev, 8987static int ipw_wx_set_scan(struct net_device *dev,
@@ -5844,9 +8989,21 @@ static int ipw_wx_set_scan(struct net_device *dev,
5844 union iwreq_data *wrqu, char *extra) 8989 union iwreq_data *wrqu, char *extra)
5845{ 8990{
5846 struct ipw_priv *priv = ieee80211_priv(dev); 8991 struct ipw_priv *priv = ieee80211_priv(dev);
8992 struct iw_scan_req *req = NULL;
8993 if (wrqu->data.length
8994 && wrqu->data.length == sizeof(struct iw_scan_req)) {
8995 req = (struct iw_scan_req *)extra;
8996 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
8997 ipw_request_direct_scan(priv, req->essid,
8998 req->essid_len);
8999 return 0;
9000 }
9001 }
9002
5847 IPW_DEBUG_WX("Start scan\n"); 9003 IPW_DEBUG_WX("Start scan\n");
5848 if (ipw_request_scan(priv)) 9004
5849 return -EIO; 9005 queue_work(priv->workqueue, &priv->request_scan);
9006
5850 return 0; 9007 return 0;
5851} 9008}
5852 9009
@@ -5863,7 +9020,21 @@ static int ipw_wx_set_encode(struct net_device *dev,
5863 union iwreq_data *wrqu, char *key) 9020 union iwreq_data *wrqu, char *key)
5864{ 9021{
5865 struct ipw_priv *priv = ieee80211_priv(dev); 9022 struct ipw_priv *priv = ieee80211_priv(dev);
5866 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); 9023 int ret;
9024 u32 cap = priv->capability;
9025
9026 down(&priv->sem);
9027 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
9028
9029 /* In IBSS mode, we need to notify the firmware to update
9030 * the beacon info after we changed the capability. */
9031 if (cap != priv->capability &&
9032 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9033 priv->status & STATUS_ASSOCIATED)
9034 ipw_disassociate(priv);
9035
9036 up(&priv->sem);
9037 return ret;
5867} 9038}
5868 9039
5869static int ipw_wx_get_encode(struct net_device *dev, 9040static int ipw_wx_get_encode(struct net_device *dev,
@@ -5880,17 +9051,17 @@ static int ipw_wx_set_power(struct net_device *dev,
5880{ 9051{
5881 struct ipw_priv *priv = ieee80211_priv(dev); 9052 struct ipw_priv *priv = ieee80211_priv(dev);
5882 int err; 9053 int err;
5883 9054 down(&priv->sem);
5884 if (wrqu->power.disabled) { 9055 if (wrqu->power.disabled) {
5885 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); 9056 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
5886 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); 9057 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
5887 if (err) { 9058 if (err) {
5888 IPW_DEBUG_WX("failed setting power mode.\n"); 9059 IPW_DEBUG_WX("failed setting power mode.\n");
9060 up(&priv->sem);
5889 return err; 9061 return err;
5890 } 9062 }
5891
5892 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 9063 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5893 9064 up(&priv->sem);
5894 return 0; 9065 return 0;
5895 } 9066 }
5896 9067
@@ -5902,6 +9073,7 @@ static int ipw_wx_set_power(struct net_device *dev,
5902 default: /* Otherwise we don't support it */ 9073 default: /* Otherwise we don't support it */
5903 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 9074 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
5904 wrqu->power.flags); 9075 wrqu->power.flags);
9076 up(&priv->sem);
5905 return -EOPNOTSUPP; 9077 return -EOPNOTSUPP;
5906 } 9078 }
5907 9079
@@ -5914,11 +9086,12 @@ static int ipw_wx_set_power(struct net_device *dev,
5914 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9086 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
5915 if (err) { 9087 if (err) {
5916 IPW_DEBUG_WX("failed setting power mode.\n"); 9088 IPW_DEBUG_WX("failed setting power mode.\n");
9089 up(&priv->sem);
5917 return err; 9090 return err;
5918 } 9091 }
5919 9092
5920 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 9093 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
5921 9094 up(&priv->sem);
5922 return 0; 9095 return 0;
5923} 9096}
5924 9097
@@ -5927,13 +9100,13 @@ static int ipw_wx_get_power(struct net_device *dev,
5927 union iwreq_data *wrqu, char *extra) 9100 union iwreq_data *wrqu, char *extra)
5928{ 9101{
5929 struct ipw_priv *priv = ieee80211_priv(dev); 9102 struct ipw_priv *priv = ieee80211_priv(dev);
5930 9103 down(&priv->sem);
5931 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 9104 if (!(priv->power_mode & IPW_POWER_ENABLED))
5932 wrqu->power.disabled = 1; 9105 wrqu->power.disabled = 1;
5933 } else { 9106 else
5934 wrqu->power.disabled = 0; 9107 wrqu->power.disabled = 0;
5935 }
5936 9108
9109 up(&priv->sem);
5937 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 9110 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
5938 9111
5939 return 0; 9112 return 0;
@@ -5946,7 +9119,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5946 struct ipw_priv *priv = ieee80211_priv(dev); 9119 struct ipw_priv *priv = ieee80211_priv(dev);
5947 int mode = *(int *)extra; 9120 int mode = *(int *)extra;
5948 int err; 9121 int err;
5949 9122 down(&priv->sem);
5950 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9123 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
5951 mode = IPW_POWER_AC; 9124 mode = IPW_POWER_AC;
5952 priv->power_mode = mode; 9125 priv->power_mode = mode;
@@ -5959,10 +9132,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5959 9132
5960 if (err) { 9133 if (err) {
5961 IPW_DEBUG_WX("failed setting power mode.\n"); 9134 IPW_DEBUG_WX("failed setting power mode.\n");
9135 up(&priv->sem);
5962 return err; 9136 return err;
5963 } 9137 }
5964 } 9138 }
5965 9139 up(&priv->sem);
5966 return 0; 9140 return 0;
5967} 9141}
5968 9142
@@ -6011,7 +9185,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6011 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); 9185 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
6012 return -EINVAL; 9186 return -EINVAL;
6013 } 9187 }
6014 9188 down(&priv->sem);
6015 if (priv->adapter == IPW_2915ABG) { 9189 if (priv->adapter == IPW_2915ABG) {
6016 priv->ieee->abg_true = 1; 9190 priv->ieee->abg_true = 1;
6017 if (mode & IEEE_A) { 9191 if (mode & IEEE_A) {
@@ -6023,6 +9197,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6023 if (mode & IEEE_A) { 9197 if (mode & IEEE_A) {
6024 IPW_WARNING("Attempt to set 2200BG into " 9198 IPW_WARNING("Attempt to set 2200BG into "
6025 "802.11a mode\n"); 9199 "802.11a mode\n");
9200 up(&priv->sem);
6026 return -EINVAL; 9201 return -EINVAL;
6027 } 9202 }
6028 9203
@@ -6046,20 +9221,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6046 priv->ieee->modulation = modulation; 9221 priv->ieee->modulation = modulation;
6047 init_supported_rates(priv, &priv->rates); 9222 init_supported_rates(priv, &priv->rates);
6048 9223
6049 /* If we are currently associated, or trying to associate 9224 /* Network configuration changed -- force [re]association */
6050 * then see if this is a new configuration (causing us to 9225 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
6051 * disassociate) */ 9226 if (!ipw_disassociate(priv)) {
6052 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6053 /* The resulting association will trigger
6054 * the new rates to be sent to the device */
6055 IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
6056 ipw_disassociate(priv);
6057 } else
6058 ipw_send_supported_rates(priv, &priv->rates); 9227 ipw_send_supported_rates(priv, &priv->rates);
9228 ipw_associate(priv);
9229 }
9230
9231 /* Update the band LEDs */
9232 ipw_led_band_on(priv);
6059 9233
6060 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 9234 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6061 mode & IEEE_A ? 'a' : '.', 9235 mode & IEEE_A ? 'a' : '.',
6062 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 9236 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9237 up(&priv->sem);
6063 return 0; 9238 return 0;
6064} 9239}
6065 9240
@@ -6068,124 +9243,234 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6068 union iwreq_data *wrqu, char *extra) 9243 union iwreq_data *wrqu, char *extra)
6069{ 9244{
6070 struct ipw_priv *priv = ieee80211_priv(dev); 9245 struct ipw_priv *priv = ieee80211_priv(dev);
6071 9246 down(&priv->sem);
6072 switch (priv->ieee->freq_band) { 9247 switch (priv->ieee->mode) {
6073 case IEEE80211_24GHZ_BAND: 9248 case IEEE_A:
6074 switch (priv->ieee->modulation) {
6075 case IEEE80211_CCK_MODULATION:
6076 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6077 break;
6078 case IEEE80211_OFDM_MODULATION:
6079 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6080 break;
6081 default:
6082 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6083 break;
6084 }
6085 break;
6086
6087 case IEEE80211_52GHZ_BAND:
6088 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 9249 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6089 break; 9250 break;
6090 9251 case IEEE_B:
6091 default: /* Mixed Band */ 9252 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6092 switch (priv->ieee->modulation) { 9253 break;
6093 case IEEE80211_CCK_MODULATION: 9254 case IEEE_A | IEEE_B:
6094 strncpy(extra, "802.11ab (3)", MAX_WX_STRING); 9255 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6095 break; 9256 break;
6096 case IEEE80211_OFDM_MODULATION: 9257 case IEEE_G:
6097 strncpy(extra, "802.11ag (5)", MAX_WX_STRING); 9258 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6098 break; 9259 break;
6099 default: 9260 case IEEE_A | IEEE_G:
6100 strncpy(extra, "802.11abg (7)", MAX_WX_STRING); 9261 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6101 break; 9262 break;
6102 } 9263 case IEEE_B | IEEE_G:
9264 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9265 break;
9266 case IEEE_A | IEEE_B | IEEE_G:
9267 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9268 break;
9269 default:
9270 strncpy(extra, "unknown", MAX_WX_STRING);
6103 break; 9271 break;
6104 } 9272 }
6105 9273
6106 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); 9274 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
6107 9275
6108 wrqu->data.length = strlen(extra) + 1; 9276 wrqu->data.length = strlen(extra) + 1;
9277 up(&priv->sem);
6109 9278
6110 return 0; 9279 return 0;
6111} 9280}
6112 9281
6113#ifdef CONFIG_IPW_PROMISC 9282static int ipw_wx_set_preamble(struct net_device *dev,
6114static int ipw_wx_set_promisc(struct net_device *dev, 9283 struct iw_request_info *info,
9284 union iwreq_data *wrqu, char *extra)
9285{
9286 struct ipw_priv *priv = ieee80211_priv(dev);
9287 int mode = *(int *)extra;
9288 down(&priv->sem);
9289 /* Switching from SHORT -> LONG requires a disassociation */
9290 if (mode == 1) {
9291 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9292 priv->config |= CFG_PREAMBLE_LONG;
9293
9294 /* Network configuration changed -- force [re]association */
9295 IPW_DEBUG_ASSOC
9296 ("[re]association triggered due to preamble change.\n");
9297 if (!ipw_disassociate(priv))
9298 ipw_associate(priv);
9299 }
9300 goto done;
9301 }
9302
9303 if (mode == 0) {
9304 priv->config &= ~CFG_PREAMBLE_LONG;
9305 goto done;
9306 }
9307 up(&priv->sem);
9308 return -EINVAL;
9309
9310 done:
9311 up(&priv->sem);
9312 return 0;
9313}
9314
9315static int ipw_wx_get_preamble(struct net_device *dev,
9316 struct iw_request_info *info,
9317 union iwreq_data *wrqu, char *extra)
9318{
9319 struct ipw_priv *priv = ieee80211_priv(dev);
9320 down(&priv->sem);
9321 if (priv->config & CFG_PREAMBLE_LONG)
9322 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9323 else
9324 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9325 up(&priv->sem);
9326 return 0;
9327}
9328
9329#ifdef CONFIG_IPW2200_MONITOR
9330static int ipw_wx_set_monitor(struct net_device *dev,
6115 struct iw_request_info *info, 9331 struct iw_request_info *info,
6116 union iwreq_data *wrqu, char *extra) 9332 union iwreq_data *wrqu, char *extra)
6117{ 9333{
6118 struct ipw_priv *priv = ieee80211_priv(dev); 9334 struct ipw_priv *priv = ieee80211_priv(dev);
6119 int *parms = (int *)extra; 9335 int *parms = (int *)extra;
6120 int enable = (parms[0] > 0); 9336 int enable = (parms[0] > 0);
6121 9337 down(&priv->sem);
6122 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]); 9338 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
6123 if (enable) { 9339 if (enable) {
6124 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9340 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9341#ifdef CONFIG_IEEE80211_RADIOTAP
9342 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9343#else
6125 priv->net_dev->type = ARPHRD_IEEE80211; 9344 priv->net_dev->type = ARPHRD_IEEE80211;
6126 ipw_adapter_restart(priv); 9345#endif
9346 queue_work(priv->workqueue, &priv->adapter_restart);
6127 } 9347 }
6128 9348
6129 ipw_set_channel(priv, parms[1]); 9349 ipw_set_channel(priv, parms[1]);
6130 } else { 9350 } else {
6131 if (priv->ieee->iw_mode != IW_MODE_MONITOR) 9351 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9352 up(&priv->sem);
6132 return 0; 9353 return 0;
9354 }
6133 priv->net_dev->type = ARPHRD_ETHER; 9355 priv->net_dev->type = ARPHRD_ETHER;
6134 ipw_adapter_restart(priv); 9356 queue_work(priv->workqueue, &priv->adapter_restart);
6135 } 9357 }
9358 up(&priv->sem);
6136 return 0; 9359 return 0;
6137} 9360}
6138 9361
9362#endif // CONFIG_IPW2200_MONITOR
9363
6139static int ipw_wx_reset(struct net_device *dev, 9364static int ipw_wx_reset(struct net_device *dev,
6140 struct iw_request_info *info, 9365 struct iw_request_info *info,
6141 union iwreq_data *wrqu, char *extra) 9366 union iwreq_data *wrqu, char *extra)
6142{ 9367{
6143 struct ipw_priv *priv = ieee80211_priv(dev); 9368 struct ipw_priv *priv = ieee80211_priv(dev);
6144 IPW_DEBUG_WX("RESET\n"); 9369 IPW_DEBUG_WX("RESET\n");
6145 ipw_adapter_restart(priv); 9370 queue_work(priv->workqueue, &priv->adapter_restart);
9371 return 0;
9372}
9373
9374static int ipw_wx_sw_reset(struct net_device *dev,
9375 struct iw_request_info *info,
9376 union iwreq_data *wrqu, char *extra)
9377{
9378 struct ipw_priv *priv = ieee80211_priv(dev);
9379 union iwreq_data wrqu_sec = {
9380 .encoding = {
9381 .flags = IW_ENCODE_DISABLED,
9382 },
9383 };
9384 int ret;
9385
9386 IPW_DEBUG_WX("SW_RESET\n");
9387
9388 down(&priv->sem);
9389
9390 ret = ipw_sw_reset(priv, 0);
9391 if (!ret) {
9392 free_firmware();
9393 ipw_adapter_restart(priv);
9394 }
9395
9396 /* The SW reset bit might have been toggled on by the 'disable'
9397 * module parameter, so take appropriate action */
9398 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9399
9400 up(&priv->sem);
9401 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9402 down(&priv->sem);
9403
9404 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9405 /* Configuration likely changed -- force [re]association */
9406 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9407 "reset.\n");
9408 if (!ipw_disassociate(priv))
9409 ipw_associate(priv);
9410 }
9411
9412 up(&priv->sem);
9413
6146 return 0; 9414 return 0;
6147} 9415}
6148#endif // CONFIG_IPW_PROMISC
6149 9416
6150/* Rebase the WE IOCTLs to zero for the handler array */ 9417/* Rebase the WE IOCTLs to zero for the handler array */
6151#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9418#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6152static iw_handler ipw_wx_handlers[] = { 9419static iw_handler ipw_wx_handlers[] = {
6153 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 9420 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6154 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 9421 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6155 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9422 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6156 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9423 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6157 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 9424 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6158 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9425 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6159 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9426 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6160 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9427 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6161 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 9428 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6162 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 9429 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6163 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 9430 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6164 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 9431 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6165 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 9432 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6166 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 9433 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6167 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 9434 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6168 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 9435 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6169 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 9436 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6170 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 9437 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6171 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 9438 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6172 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 9439 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6173 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 9440 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6174 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 9441 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6175 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 9442 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6176 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 9443 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6177 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 9444 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6178 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 9445 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6179 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 9446 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6180 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 9447 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
9448 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
9449 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
9450 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
9451 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
9452 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
9453 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
9454 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
9455 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
9456 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
9457 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
9458 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
6181}; 9459};
6182 9460
6183#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 9461enum {
6184#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1 9462 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
6185#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2 9463 IPW_PRIV_GET_POWER,
6186#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3 9464 IPW_PRIV_SET_MODE,
6187#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 9465 IPW_PRIV_GET_MODE,
6188#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 9466 IPW_PRIV_SET_PREAMBLE,
9467 IPW_PRIV_GET_PREAMBLE,
9468 IPW_PRIV_RESET,
9469 IPW_PRIV_SW_RESET,
9470#ifdef CONFIG_IPW2200_MONITOR
9471 IPW_PRIV_SET_MONITOR,
9472#endif
9473};
6189 9474
6190static struct iw_priv_args ipw_priv_args[] = { 9475static struct iw_priv_args ipw_priv_args[] = {
6191 { 9476 {
@@ -6204,14 +9489,25 @@ static struct iw_priv_args ipw_priv_args[] = {
6204 .cmd = IPW_PRIV_GET_MODE, 9489 .cmd = IPW_PRIV_GET_MODE,
6205 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 9490 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6206 .name = "get_mode"}, 9491 .name = "get_mode"},
6207#ifdef CONFIG_IPW_PROMISC
6208 { 9492 {
6209 IPW_PRIV_SET_PROMISC, 9493 .cmd = IPW_PRIV_SET_PREAMBLE,
6210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, 9494 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9495 .name = "set_preamble"},
9496 {
9497 .cmd = IPW_PRIV_GET_PREAMBLE,
9498 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9499 .name = "get_preamble"},
6211 { 9500 {
6212 IPW_PRIV_RESET, 9501 IPW_PRIV_RESET,
6213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, 9502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
6214#endif /* CONFIG_IPW_PROMISC */ 9503 {
9504 IPW_PRIV_SW_RESET,
9505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9506#ifdef CONFIG_IPW2200_MONITOR
9507 {
9508 IPW_PRIV_SET_MONITOR,
9509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9510#endif /* CONFIG_IPW2200_MONITOR */
6215}; 9511};
6216 9512
6217static iw_handler ipw_priv_handler[] = { 9513static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +9515,23 @@ static iw_handler ipw_priv_handler[] = {
6219 ipw_wx_get_powermode, 9515 ipw_wx_get_powermode,
6220 ipw_wx_set_wireless_mode, 9516 ipw_wx_set_wireless_mode,
6221 ipw_wx_get_wireless_mode, 9517 ipw_wx_get_wireless_mode,
6222#ifdef CONFIG_IPW_PROMISC 9518 ipw_wx_set_preamble,
6223 ipw_wx_set_promisc, 9519 ipw_wx_get_preamble,
6224 ipw_wx_reset, 9520 ipw_wx_reset,
9521 ipw_wx_sw_reset,
9522#ifdef CONFIG_IPW2200_MONITOR
9523 ipw_wx_set_monitor,
6225#endif 9524#endif
6226}; 9525};
6227 9526
6228static struct iw_handler_def ipw_wx_handler_def = { 9527static struct iw_handler_def ipw_wx_handler_def = {
6229 .standard = ipw_wx_handlers, 9528 .standard = ipw_wx_handlers,
6230 .num_standard = ARRAY_SIZE(ipw_wx_handlers), 9529 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6231 .num_private = ARRAY_SIZE(ipw_priv_handler), 9530 .num_private = ARRAY_SIZE(ipw_priv_handler),
6232 .num_private_args = ARRAY_SIZE(ipw_priv_args), 9531 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6233 .private = ipw_priv_handler, 9532 .private = ipw_priv_handler,
6234 .private_args = ipw_priv_args, 9533 .private_args = ipw_priv_args,
9534 .get_wireless_stats = ipw_get_wireless_stats,
6235}; 9535};
6236 9536
6237/* 9537/*
@@ -6246,8 +9546,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
6246 9546
6247 wstats = &priv->wstats; 9547 wstats = &priv->wstats;
6248 9548
6249 /* if hw is disabled, then ipw2100_get_ordinal() can't be called. 9549 /* if hw is disabled, then ipw_get_ordinal() can't be called.
6250 * ipw2100_wx_wireless_stats seems to be called before fw is 9550 * netdev->get_wireless_stats seems to be called before fw is
6251 * initialized. STATUS_ASSOCIATED will only be set if the hw is up 9551 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6252 * and associated; if not associcated, the values are all meaningless 9552 * and associated; if not associcated, the values are all meaningless
6253 * anyway, so set them all to NULL and INVALID */ 9553 * anyway, so set them all to NULL and INVALID */
@@ -6298,7 +9598,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
6298 sys_config->dot11g_auto_detection = 0; 9598 sys_config->dot11g_auto_detection = 0;
6299 sys_config->enable_cts_to_self = 0; 9599 sys_config->enable_cts_to_self = 0;
6300 sys_config->bt_coexist_collision_thr = 0; 9600 sys_config->bt_coexist_collision_thr = 0;
6301 sys_config->pass_noise_stats_to_host = 1; 9601 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
6302} 9602}
6303 9603
6304static int ipw_net_open(struct net_device *dev) 9604static int ipw_net_open(struct net_device *dev)
@@ -6306,9 +9606,11 @@ static int ipw_net_open(struct net_device *dev)
6306 struct ipw_priv *priv = ieee80211_priv(dev); 9606 struct ipw_priv *priv = ieee80211_priv(dev);
6307 IPW_DEBUG_INFO("dev->open\n"); 9607 IPW_DEBUG_INFO("dev->open\n");
6308 /* we should be verifying the device is ready to be opened */ 9608 /* we should be verifying the device is ready to be opened */
9609 down(&priv->sem);
6309 if (!(priv->status & STATUS_RF_KILL_MASK) && 9610 if (!(priv->status & STATUS_RF_KILL_MASK) &&
6310 (priv->status & STATUS_ASSOCIATED)) 9611 (priv->status & STATUS_ASSOCIATED))
6311 netif_start_queue(dev); 9612 netif_start_queue(dev);
9613 up(&priv->sem);
6312 return 0; 9614 return 0;
6313} 9615}
6314 9616
@@ -6326,22 +9628,34 @@ modify to send one tfd per fragment instead of using chunking. otherwise
6326we need to heavily modify the ieee80211_skb_to_txb. 9628we need to heavily modify the ieee80211_skb_to_txb.
6327*/ 9629*/
6328 9630
6329static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) 9631static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9632 int pri)
6330{ 9633{
6331 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) 9634 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
6332 txb->fragments[0]->data; 9635 txb->fragments[0]->data;
6333 int i = 0; 9636 int i = 0;
6334 struct tfd_frame *tfd; 9637 struct tfd_frame *tfd;
9638#ifdef CONFIG_IPW_QOS
9639 int tx_id = ipw_get_tx_queue_number(priv, pri);
9640 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9641#else
6335 struct clx2_tx_queue *txq = &priv->txq[0]; 9642 struct clx2_tx_queue *txq = &priv->txq[0];
9643#endif
6336 struct clx2_queue *q = &txq->q; 9644 struct clx2_queue *q = &txq->q;
6337 u8 id, hdr_len, unicast; 9645 u8 id, hdr_len, unicast;
6338 u16 remaining_bytes; 9646 u16 remaining_bytes;
9647 int fc;
9648
9649 /* If there isn't room in the queue, we return busy and let the
9650 * network stack requeue the packet for us */
9651 if (ipw_queue_space(q) < q->high_mark)
9652 return NETDEV_TX_BUSY;
6339 9653
6340 switch (priv->ieee->iw_mode) { 9654 switch (priv->ieee->iw_mode) {
6341 case IW_MODE_ADHOC: 9655 case IW_MODE_ADHOC:
6342 hdr_len = IEEE80211_3ADDR_LEN; 9656 hdr_len = IEEE80211_3ADDR_LEN;
6343 unicast = !is_broadcast_ether_addr(hdr->addr1) && 9657 unicast = !(is_multicast_ether_addr(hdr->addr1) ||
6344 !is_multicast_ether_addr(hdr->addr1); 9658 is_broadcast_ether_addr(hdr->addr1));
6345 id = ipw_find_station(priv, hdr->addr1); 9659 id = ipw_find_station(priv, hdr->addr1);
6346 if (id == IPW_INVALID_STATION) { 9660 if (id == IPW_INVALID_STATION) {
6347 id = ipw_add_station(priv, hdr->addr1); 9661 id = ipw_add_station(priv, hdr->addr1);
@@ -6356,8 +9670,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6356 9670
6357 case IW_MODE_INFRA: 9671 case IW_MODE_INFRA:
6358 default: 9672 default:
6359 unicast = !is_broadcast_ether_addr(hdr->addr3) && 9673 unicast = !(is_multicast_ether_addr(hdr->addr3) ||
6360 !is_multicast_ether_addr(hdr->addr3); 9674 is_broadcast_ether_addr(hdr->addr3));
6361 hdr_len = IEEE80211_3ADDR_LEN; 9675 hdr_len = IEEE80211_3ADDR_LEN;
6362 id = 0; 9676 id = 0;
6363 break; 9677 break;
@@ -6372,26 +9686,83 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6372 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK; 9686 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
6373 9687
6374 tfd->u.data.cmd_id = DINO_CMD_TX; 9688 tfd->u.data.cmd_id = DINO_CMD_TX;
6375 tfd->u.data.len = txb->payload_size; 9689 tfd->u.data.len = cpu_to_le16(txb->payload_size);
6376 remaining_bytes = txb->payload_size; 9690 remaining_bytes = txb->payload_size;
6377 if (unlikely(!unicast))
6378 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
6379 else
6380 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
6381 9691
6382 if (priv->assoc_request.ieee_mode == IPW_B_MODE) 9692 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
6383 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK; 9693 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
6384 else 9694 else
6385 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM; 9695 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
6386 9696
6387 if (priv->config & CFG_PREAMBLE) 9697 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
6388 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL; 9698 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
9699
9700 fc = le16_to_cpu(hdr->frame_ctl);
9701 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
6389 9702
6390 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 9703 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6391 9704
9705 if (likely(unicast))
9706 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9707
9708 if (txb->encrypted && !priv->ieee->host_encrypt) {
9709 switch (priv->ieee->sec.level) {
9710 case SEC_LEVEL_3:
9711 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9712 IEEE80211_FCTL_PROTECTED;
9713 /* XXX: ACK flag must be set for CCMP even if it
9714 * is a multicast/broadcast packet, because CCMP
9715 * group communication encrypted by GTK is
9716 * actually done by the AP. */
9717 if (!unicast)
9718 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9719
9720 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9721 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9722 tfd->u.data.key_index = 0;
9723 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9724 break;
9725 case SEC_LEVEL_2:
9726 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9727 IEEE80211_FCTL_PROTECTED;
9728 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9729 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9730 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9731 break;
9732 case SEC_LEVEL_1:
9733 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9734 IEEE80211_FCTL_PROTECTED;
9735 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9736 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9737 40)
9738 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9739 else
9740 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9741 break;
9742 case SEC_LEVEL_0:
9743 break;
9744 default:
9745 printk(KERN_ERR "Unknow security level %d\n",
9746 priv->ieee->sec.level);
9747 break;
9748 }
9749 } else
9750 /* No hardware encryption */
9751 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9752
9753#ifdef CONFIG_IPW_QOS
9754 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9755#endif /* CONFIG_IPW_QOS */
9756
6392 /* payload */ 9757 /* payload */
6393 tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); 9758 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
6394 for (i = 0; i < tfd->u.data.num_chunks; i++) { 9759 txb->nr_frags));
9760 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9761 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9762 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9763 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9764 i, le32_to_cpu(tfd->u.data.num_chunks),
9765 txb->fragments[i]->len - hdr_len);
6395 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", 9766 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
6396 i, tfd->u.data.num_chunks, 9767 i, tfd->u.data.num_chunks,
6397 txb->fragments[i]->len - hdr_len); 9768 txb->fragments[i]->len - hdr_len);
@@ -6399,11 +9770,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6399 txb->fragments[i]->len - hdr_len); 9770 txb->fragments[i]->len - hdr_len);
6400 9771
6401 tfd->u.data.chunk_ptr[i] = 9772 tfd->u.data.chunk_ptr[i] =
6402 pci_map_single(priv->pci_dev, 9773 cpu_to_le32(pci_map_single
6403 txb->fragments[i]->data + hdr_len, 9774 (priv->pci_dev,
6404 txb->fragments[i]->len - hdr_len, 9775 txb->fragments[i]->data + hdr_len,
6405 PCI_DMA_TODEVICE); 9776 txb->fragments[i]->len - hdr_len,
6406 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; 9777 PCI_DMA_TODEVICE));
9778 tfd->u.data.chunk_len[i] =
9779 cpu_to_le16(txb->fragments[i]->len - hdr_len);
6407 } 9780 }
6408 9781
6409 if (i != txb->nr_frags) { 9782 if (i != txb->nr_frags) {
@@ -6418,9 +9791,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6418 remaining_bytes); 9791 remaining_bytes);
6419 skb = alloc_skb(remaining_bytes, GFP_ATOMIC); 9792 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
6420 if (skb != NULL) { 9793 if (skb != NULL) {
6421 tfd->u.data.chunk_len[i] = remaining_bytes; 9794 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
6422 for (j = i; j < txb->nr_frags; j++) { 9795 for (j = i; j < txb->nr_frags; j++) {
6423 int size = txb->fragments[j]->len - hdr_len; 9796 int size = txb->fragments[j]->len - hdr_len;
9797
6424 printk(KERN_INFO "Adding frag %d %d...\n", 9798 printk(KERN_INFO "Adding frag %d %d...\n",
6425 j, size); 9799 j, size);
6426 memcpy(skb_put(skb, size), 9800 memcpy(skb_put(skb, size),
@@ -6429,10 +9803,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6429 dev_kfree_skb_any(txb->fragments[i]); 9803 dev_kfree_skb_any(txb->fragments[i]);
6430 txb->fragments[i] = skb; 9804 txb->fragments[i] = skb;
6431 tfd->u.data.chunk_ptr[i] = 9805 tfd->u.data.chunk_ptr[i] =
6432 pci_map_single(priv->pci_dev, skb->data, 9806 cpu_to_le32(pci_map_single
6433 tfd->u.data.chunk_len[i], 9807 (priv->pci_dev, skb->data,
6434 PCI_DMA_TODEVICE); 9808 tfd->u.data.chunk_len[i],
6435 tfd->u.data.num_chunks++; 9809 PCI_DMA_TODEVICE));
9810
9811 tfd->u.data.num_chunks =
9812 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9813 1);
6436 } 9814 }
6437 } 9815 }
6438 9816
@@ -6440,14 +9818,28 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6440 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); 9818 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
6441 ipw_write32(priv, q->reg_w, q->first_empty); 9819 ipw_write32(priv, q->reg_w, q->first_empty);
6442 9820
6443 if (ipw_queue_space(q) < q->high_mark) 9821 return NETDEV_TX_OK;
6444 netif_stop_queue(priv->net_dev);
6445
6446 return;
6447 9822
6448 drop: 9823 drop:
6449 IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); 9824 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
6450 ieee80211_txb_free(txb); 9825 ieee80211_txb_free(txb);
9826 return NETDEV_TX_OK;
9827}
9828
9829static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9830{
9831 struct ipw_priv *priv = ieee80211_priv(dev);
9832#ifdef CONFIG_IPW_QOS
9833 int tx_id = ipw_get_tx_queue_number(priv, pri);
9834 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9835#else
9836 struct clx2_tx_queue *txq = &priv->txq[0];
9837#endif /* CONFIG_IPW_QOS */
9838
9839 if (ipw_queue_space(&txq->q) < txq->q.high_mark)
9840 return 1;
9841
9842 return 0;
6451} 9843}
6452 9844
6453static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 9845static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
@@ -6455,9 +9847,9 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6455{ 9847{
6456 struct ipw_priv *priv = ieee80211_priv(dev); 9848 struct ipw_priv *priv = ieee80211_priv(dev);
6457 unsigned long flags; 9849 unsigned long flags;
9850 int ret;
6458 9851
6459 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); 9852 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
6460
6461 spin_lock_irqsave(&priv->lock, flags); 9853 spin_lock_irqsave(&priv->lock, flags);
6462 9854
6463 if (!(priv->status & STATUS_ASSOCIATED)) { 9855 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -6467,10 +9859,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6467 goto fail_unlock; 9859 goto fail_unlock;
6468 } 9860 }
6469 9861
6470 ipw_tx_skb(priv, txb); 9862 ret = ipw_tx_skb(priv, txb, pri);
6471 9863 if (ret == NETDEV_TX_OK)
9864 __ipw_led_activity_on(priv);
6472 spin_unlock_irqrestore(&priv->lock, flags); 9865 spin_unlock_irqrestore(&priv->lock, flags);
6473 return 0; 9866
9867 return ret;
6474 9868
6475 fail_unlock: 9869 fail_unlock:
6476 spin_unlock_irqrestore(&priv->lock, flags); 9870 spin_unlock_irqrestore(&priv->lock, flags);
@@ -6497,11 +9891,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
6497 struct sockaddr *addr = p; 9891 struct sockaddr *addr = p;
6498 if (!is_valid_ether_addr(addr->sa_data)) 9892 if (!is_valid_ether_addr(addr->sa_data))
6499 return -EADDRNOTAVAIL; 9893 return -EADDRNOTAVAIL;
9894 down(&priv->sem);
6500 priv->config |= CFG_CUSTOM_MAC; 9895 priv->config |= CFG_CUSTOM_MAC;
6501 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 9896 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
6502 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 9897 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
6503 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 9898 priv->net_dev->name, MAC_ARG(priv->mac_addr));
6504 ipw_adapter_restart(priv); 9899 queue_work(priv->workqueue, &priv->adapter_restart);
9900 up(&priv->sem);
6505 return 0; 9901 return 0;
6506} 9902}
6507 9903
@@ -6524,7 +9920,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6524 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", 9920 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
6525 vers, date); 9921 vers, date);
6526 strcpy(info->bus_info, pci_name(p->pci_dev)); 9922 strcpy(info->bus_info, pci_name(p->pci_dev));
6527 info->eedump_len = CX2_EEPROM_IMAGE_SIZE; 9923 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
6528} 9924}
6529 9925
6530static u32 ipw_ethtool_get_link(struct net_device *dev) 9926static u32 ipw_ethtool_get_link(struct net_device *dev)
@@ -6535,7 +9931,7 @@ static u32 ipw_ethtool_get_link(struct net_device *dev)
6535 9931
6536static int ipw_ethtool_get_eeprom_len(struct net_device *dev) 9932static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
6537{ 9933{
6538 return CX2_EEPROM_IMAGE_SIZE; 9934 return IPW_EEPROM_IMAGE_SIZE;
6539} 9935}
6540 9936
6541static int ipw_ethtool_get_eeprom(struct net_device *dev, 9937static int ipw_ethtool_get_eeprom(struct net_device *dev,
@@ -6543,10 +9939,11 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
6543{ 9939{
6544 struct ipw_priv *p = ieee80211_priv(dev); 9940 struct ipw_priv *p = ieee80211_priv(dev);
6545 9941
6546 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9942 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6547 return -EINVAL; 9943 return -EINVAL;
6548 9944 down(&p->sem);
6549 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len); 9945 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
9946 up(&p->sem);
6550 return 0; 9947 return 0;
6551} 9948}
6552 9949
@@ -6556,23 +9953,23 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
6556 struct ipw_priv *p = ieee80211_priv(dev); 9953 struct ipw_priv *p = ieee80211_priv(dev);
6557 int i; 9954 int i;
6558 9955
6559 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9956 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6560 return -EINVAL; 9957 return -EINVAL;
6561 9958 down(&p->sem);
6562 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len); 9959 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
6563 for (i = IPW_EEPROM_DATA; 9960 for (i = IPW_EEPROM_DATA;
6564 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) 9961 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
6565 ipw_write8(p, i, p->eeprom[i]); 9962 ipw_write8(p, i, p->eeprom[i]);
6566 9963 up(&p->sem);
6567 return 0; 9964 return 0;
6568} 9965}
6569 9966
6570static struct ethtool_ops ipw_ethtool_ops = { 9967static struct ethtool_ops ipw_ethtool_ops = {
6571 .get_link = ipw_ethtool_get_link, 9968 .get_link = ipw_ethtool_get_link,
6572 .get_drvinfo = ipw_ethtool_get_drvinfo, 9969 .get_drvinfo = ipw_ethtool_get_drvinfo,
6573 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 9970 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6574 .get_eeprom = ipw_ethtool_get_eeprom, 9971 .get_eeprom = ipw_ethtool_get_eeprom,
6575 .set_eeprom = ipw_ethtool_set_eeprom, 9972 .set_eeprom = ipw_ethtool_set_eeprom,
6576}; 9973};
6577 9974
6578static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) 9975static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6590,8 +9987,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6590 goto none; 9987 goto none;
6591 } 9988 }
6592 9989
6593 inta = ipw_read32(priv, CX2_INTA_RW); 9990 inta = ipw_read32(priv, IPW_INTA_RW);
6594 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 9991 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
6595 9992
6596 if (inta == 0xFFFFFFFF) { 9993 if (inta == 0xFFFFFFFF) {
6597 /* Hardware disappeared */ 9994 /* Hardware disappeared */
@@ -6599,7 +9996,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6599 goto none; 9996 goto none;
6600 } 9997 }
6601 9998
6602 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) { 9999 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
6603 /* Shared interrupt */ 10000 /* Shared interrupt */
6604 goto none; 10001 goto none;
6605 } 10002 }
@@ -6608,8 +10005,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6608 ipw_disable_interrupts(priv); 10005 ipw_disable_interrupts(priv);
6609 10006
6610 /* ack current interrupts */ 10007 /* ack current interrupts */
6611 inta &= (CX2_INTA_MASK_ALL & inta_mask); 10008 inta &= (IPW_INTA_MASK_ALL & inta_mask);
6612 ipw_write32(priv, CX2_INTA_RW, inta); 10009 ipw_write32(priv, IPW_INTA_RW, inta);
6613 10010
6614 /* Cache INTA value for our tasklet */ 10011 /* Cache INTA value for our tasklet */
6615 priv->isr_inta = inta; 10012 priv->isr_inta = inta;
@@ -6655,28 +10052,116 @@ static void ipw_rf_kill(void *adapter)
6655 spin_unlock_irqrestore(&priv->lock, flags); 10052 spin_unlock_irqrestore(&priv->lock, flags);
6656} 10053}
6657 10054
10055static void ipw_bg_rf_kill(void *data)
10056{
10057 struct ipw_priv *priv = data;
10058 down(&priv->sem);
10059 ipw_rf_kill(data);
10060 up(&priv->sem);
10061}
10062
10063void ipw_link_up(struct ipw_priv *priv)
10064{
10065 priv->last_seq_num = -1;
10066 priv->last_frag_num = -1;
10067 priv->last_packet_time = 0;
10068
10069 netif_carrier_on(priv->net_dev);
10070 if (netif_queue_stopped(priv->net_dev)) {
10071 IPW_DEBUG_NOTIF("waking queue\n");
10072 netif_wake_queue(priv->net_dev);
10073 } else {
10074 IPW_DEBUG_NOTIF("starting queue\n");
10075 netif_start_queue(priv->net_dev);
10076 }
10077
10078 cancel_delayed_work(&priv->request_scan);
10079 ipw_reset_stats(priv);
10080 /* Ensure the rate is updated immediately */
10081 priv->last_rate = ipw_get_current_rate(priv);
10082 ipw_gather_stats(priv);
10083 ipw_led_link_up(priv);
10084 notify_wx_assoc_event(priv);
10085
10086 if (priv->config & CFG_BACKGROUND_SCAN)
10087 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
10088}
10089
10090static void ipw_bg_link_up(void *data)
10091{
10092 struct ipw_priv *priv = data;
10093 down(&priv->sem);
10094 ipw_link_up(data);
10095 up(&priv->sem);
10096}
10097
10098void ipw_link_down(struct ipw_priv *priv)
10099{
10100 ipw_led_link_down(priv);
10101 netif_carrier_off(priv->net_dev);
10102 netif_stop_queue(priv->net_dev);
10103 notify_wx_assoc_event(priv);
10104
10105 /* Cancel any queued work ... */
10106 cancel_delayed_work(&priv->request_scan);
10107 cancel_delayed_work(&priv->adhoc_check);
10108 cancel_delayed_work(&priv->gather_stats);
10109
10110 ipw_reset_stats(priv);
10111
10112 if (!(priv->status & STATUS_EXIT_PENDING)) {
10113 /* Queue up another scan... */
10114 queue_work(priv->workqueue, &priv->request_scan);
10115 }
10116}
10117
10118static void ipw_bg_link_down(void *data)
10119{
10120 struct ipw_priv *priv = data;
10121 down(&priv->sem);
10122 ipw_link_down(data);
10123 up(&priv->sem);
10124}
10125
6658static int ipw_setup_deferred_work(struct ipw_priv *priv) 10126static int ipw_setup_deferred_work(struct ipw_priv *priv)
6659{ 10127{
6660 int ret = 0; 10128 int ret = 0;
6661 10129
6662 priv->workqueue = create_workqueue(DRV_NAME); 10130 priv->workqueue = create_workqueue(DRV_NAME);
6663 init_waitqueue_head(&priv->wait_command_queue); 10131 init_waitqueue_head(&priv->wait_command_queue);
6664 10132 init_waitqueue_head(&priv->wait_state);
6665 INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv); 10133
6666 INIT_WORK(&priv->associate, ipw_associate, priv); 10134 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
6667 INIT_WORK(&priv->disassociate, ipw_disassociate, priv); 10135 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
6668 INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv); 10136 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
6669 INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv); 10137 INIT_WORK(&priv->system_config, ipw_system_config, priv);
6670 INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv); 10138 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
6671 INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv); 10139 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
6672 INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv); 10140 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
10141 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
10142 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
6673 INIT_WORK(&priv->request_scan, 10143 INIT_WORK(&priv->request_scan,
6674 (void (*)(void *))ipw_request_scan, priv); 10144 (void (*)(void *))ipw_request_scan, priv);
6675 INIT_WORK(&priv->gather_stats, 10145 INIT_WORK(&priv->gather_stats,
6676 (void (*)(void *))ipw_gather_stats, priv); 10146 (void (*)(void *))ipw_bg_gather_stats, priv);
6677 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); 10147 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
6678 INIT_WORK(&priv->roam, ipw_roam, priv); 10148 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
6679 INIT_WORK(&priv->scan_check, ipw_scan_check, priv); 10149 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
10150 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
10151 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
10152 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
10153 priv);
10154 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
10155 priv);
10156 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
10157 priv);
10158 INIT_WORK(&priv->merge_networks,
10159 (void (*)(void *))ipw_merge_adhoc_network, priv);
10160
10161#ifdef CONFIG_IPW_QOS
10162 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
10163 priv);
10164#endif /* CONFIG_IPW_QOS */
6680 10165
6681 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 10166 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6682 ipw_irq_tasklet, (unsigned long)priv); 10167 ipw_irq_tasklet, (unsigned long)priv);
@@ -6689,34 +10174,36 @@ static void shim__set_security(struct net_device *dev,
6689{ 10174{
6690 struct ipw_priv *priv = ieee80211_priv(dev); 10175 struct ipw_priv *priv = ieee80211_priv(dev);
6691 int i; 10176 int i;
6692
6693 for (i = 0; i < 4; i++) { 10177 for (i = 0; i < 4; i++) {
6694 if (sec->flags & (1 << i)) { 10178 if (sec->flags & (1 << i)) {
6695 priv->sec.key_sizes[i] = sec->key_sizes[i]; 10179 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
10180 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
6696 if (sec->key_sizes[i] == 0) 10181 if (sec->key_sizes[i] == 0)
6697 priv->sec.flags &= ~(1 << i); 10182 priv->ieee->sec.flags &= ~(1 << i);
6698 else 10183 else {
6699 memcpy(priv->sec.keys[i], sec->keys[i], 10184 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
6700 sec->key_sizes[i]); 10185 sec->key_sizes[i]);
6701 priv->sec.flags |= (1 << i); 10186 priv->ieee->sec.flags |= (1 << i);
10187 }
6702 priv->status |= STATUS_SECURITY_UPDATED; 10188 priv->status |= STATUS_SECURITY_UPDATED;
6703 } 10189 } else if (sec->level != SEC_LEVEL_1)
10190 priv->ieee->sec.flags &= ~(1 << i);
6704 } 10191 }
6705 10192
6706 if ((sec->flags & SEC_ACTIVE_KEY) && 10193 if (sec->flags & SEC_ACTIVE_KEY) {
6707 priv->sec.active_key != sec->active_key) {
6708 if (sec->active_key <= 3) { 10194 if (sec->active_key <= 3) {
6709 priv->sec.active_key = sec->active_key; 10195 priv->ieee->sec.active_key = sec->active_key;
6710 priv->sec.flags |= SEC_ACTIVE_KEY; 10196 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
6711 } else 10197 } else
6712 priv->sec.flags &= ~SEC_ACTIVE_KEY; 10198 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6713 priv->status |= STATUS_SECURITY_UPDATED; 10199 priv->status |= STATUS_SECURITY_UPDATED;
6714 } 10200 } else
10201 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6715 10202
6716 if ((sec->flags & SEC_AUTH_MODE) && 10203 if ((sec->flags & SEC_AUTH_MODE) &&
6717 (priv->sec.auth_mode != sec->auth_mode)) { 10204 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
6718 priv->sec.auth_mode = sec->auth_mode; 10205 priv->ieee->sec.auth_mode = sec->auth_mode;
6719 priv->sec.flags |= SEC_AUTH_MODE; 10206 priv->ieee->sec.flags |= SEC_AUTH_MODE;
6720 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY) 10207 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
6721 priv->capability |= CAP_SHARED_KEY; 10208 priv->capability |= CAP_SHARED_KEY;
6722 else 10209 else
@@ -6724,9 +10211,9 @@ static void shim__set_security(struct net_device *dev,
6724 priv->status |= STATUS_SECURITY_UPDATED; 10211 priv->status |= STATUS_SECURITY_UPDATED;
6725 } 10212 }
6726 10213
6727 if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { 10214 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
6728 priv->sec.flags |= SEC_ENABLED; 10215 priv->ieee->sec.flags |= SEC_ENABLED;
6729 priv->sec.enabled = sec->enabled; 10216 priv->ieee->sec.enabled = sec->enabled;
6730 priv->status |= STATUS_SECURITY_UPDATED; 10217 priv->status |= STATUS_SECURITY_UPDATED;
6731 if (sec->enabled) 10218 if (sec->enabled)
6732 priv->capability |= CAP_PRIVACY_ON; 10219 priv->capability |= CAP_PRIVACY_ON;
@@ -6734,12 +10221,18 @@ static void shim__set_security(struct net_device *dev,
6734 priv->capability &= ~CAP_PRIVACY_ON; 10221 priv->capability &= ~CAP_PRIVACY_ON;
6735 } 10222 }
6736 10223
6737 if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { 10224 if (sec->flags & SEC_ENCRYPT)
6738 priv->sec.level = sec->level; 10225 priv->ieee->sec.encrypt = sec->encrypt;
6739 priv->sec.flags |= SEC_LEVEL; 10226
10227 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10228 priv->ieee->sec.level = sec->level;
10229 priv->ieee->sec.flags |= SEC_LEVEL;
6740 priv->status |= STATUS_SECURITY_UPDATED; 10230 priv->status |= STATUS_SECURITY_UPDATED;
6741 } 10231 }
6742 10232
10233 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10234 ipw_set_hwcrypto_keys(priv);
10235
6743 /* To match current functionality of ipw2100 (which works well w/ 10236 /* To match current functionality of ipw2100 (which works well w/
6744 * various supplicants, we don't force a disassociate if the 10237 * various supplicants, we don't force a disassociate if the
6745 * privacy capability changes ... */ 10238 * privacy capability changes ... */
@@ -6788,29 +10281,10 @@ static int init_supported_rates(struct ipw_priv *priv,
6788 10281
6789static int ipw_config(struct ipw_priv *priv) 10282static int ipw_config(struct ipw_priv *priv)
6790{ 10283{
6791 int i;
6792 struct ipw_tx_power tx_power;
6793
6794 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
6795 memset(&tx_power, 0, sizeof(tx_power));
6796
6797 /* This is only called from ipw_up, which resets/reloads the firmware 10284 /* This is only called from ipw_up, which resets/reloads the firmware
6798 so, we don't need to first disable the card before we configure 10285 so, we don't need to first disable the card before we configure
6799 it */ 10286 it */
6800 10287 if (ipw_set_tx_power(priv))
6801 /* configure device for 'G' band */
6802 tx_power.ieee_mode = IPW_G_MODE;
6803 tx_power.num_channels = 11;
6804 for (i = 0; i < 11; i++) {
6805 tx_power.channels_tx_power[i].channel_number = i + 1;
6806 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
6807 }
6808 if (ipw_send_tx_power(priv, &tx_power))
6809 goto error;
6810
6811 /* configure device to also handle 'B' band */
6812 tx_power.ieee_mode = IPW_B_MODE;
6813 if (ipw_send_tx_power(priv, &tx_power))
6814 goto error; 10288 goto error;
6815 10289
6816 /* initialize adapter address */ 10290 /* initialize adapter address */
@@ -6819,6 +10293,11 @@ static int ipw_config(struct ipw_priv *priv)
6819 10293
6820 /* set basic system config settings */ 10294 /* set basic system config settings */
6821 init_sys_config(&priv->sys_config); 10295 init_sys_config(&priv->sys_config);
10296 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10297 priv->sys_config.answer_broadcast_ssid_probe = 1;
10298 else
10299 priv->sys_config.answer_broadcast_ssid_probe = 0;
10300
6822 if (ipw_send_system_config(priv, &priv->sys_config)) 10301 if (ipw_send_system_config(priv, &priv->sys_config))
6823 goto error; 10302 goto error;
6824 10303
@@ -6831,6 +10310,10 @@ static int ipw_config(struct ipw_priv *priv)
6831 if (ipw_send_rts_threshold(priv, priv->rts_threshold)) 10310 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
6832 goto error; 10311 goto error;
6833 } 10312 }
10313#ifdef CONFIG_IPW_QOS
10314 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10315 ipw_qos_activate(priv, NULL);
10316#endif /* CONFIG_IPW_QOS */
6834 10317
6835 if (ipw_set_random_seed(priv)) 10318 if (ipw_set_random_seed(priv))
6836 goto error; 10319 goto error;
@@ -6839,9 +10322,17 @@ static int ipw_config(struct ipw_priv *priv)
6839 if (ipw_send_host_complete(priv)) 10322 if (ipw_send_host_complete(priv))
6840 goto error; 10323 goto error;
6841 10324
6842 /* If configured to try and auto-associate, kick off a scan */ 10325 priv->status |= STATUS_INIT;
6843 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) 10326
6844 goto error; 10327 ipw_led_init(priv);
10328 ipw_led_radio_on(priv);
10329 priv->notif_missed_beacons = 0;
10330
10331 /* Set hardware WEP key if it is configured. */
10332 if ((priv->capability & CAP_PRIVACY_ON) &&
10333 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10334 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10335 ipw_set_hwcrypto_keys(priv);
6845 10336
6846 return 0; 10337 return 0;
6847 10338
@@ -6849,20 +10340,379 @@ static int ipw_config(struct ipw_priv *priv)
6849 return -EIO; 10340 return -EIO;
6850} 10341}
6851 10342
10343/*
10344 * NOTE:
10345 *
10346 * These tables have been tested in conjunction with the
10347 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
10348 *
10349 * Altering this values, using it on other hardware, or in geographies
10350 * not intended for resale of the above mentioned Intel adapters has
10351 * not been tested.
10352 *
10353 */
10354static const struct ieee80211_geo ipw_geos[] = {
10355 { /* Restricted */
10356 "---",
10357 .bg_channels = 11,
10358 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10359 {2427, 4}, {2432, 5}, {2437, 6},
10360 {2442, 7}, {2447, 8}, {2452, 9},
10361 {2457, 10}, {2462, 11}},
10362 },
10363
10364 { /* Custom US/Canada */
10365 "ZZF",
10366 .bg_channels = 11,
10367 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10368 {2427, 4}, {2432, 5}, {2437, 6},
10369 {2442, 7}, {2447, 8}, {2452, 9},
10370 {2457, 10}, {2462, 11}},
10371 .a_channels = 8,
10372 .a = {{5180, 36},
10373 {5200, 40},
10374 {5220, 44},
10375 {5240, 48},
10376 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10377 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10378 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10379 {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
10380 },
10381
10382 { /* Rest of World */
10383 "ZZD",
10384 .bg_channels = 13,
10385 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10386 {2427, 4}, {2432, 5}, {2437, 6},
10387 {2442, 7}, {2447, 8}, {2452, 9},
10388 {2457, 10}, {2462, 11}, {2467, 12},
10389 {2472, 13}},
10390 },
10391
10392 { /* Custom USA & Europe & High */
10393 "ZZA",
10394 .bg_channels = 11,
10395 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10396 {2427, 4}, {2432, 5}, {2437, 6},
10397 {2442, 7}, {2447, 8}, {2452, 9},
10398 {2457, 10}, {2462, 11}},
10399 .a_channels = 13,
10400 .a = {{5180, 36},
10401 {5200, 40},
10402 {5220, 44},
10403 {5240, 48},
10404 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10405 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10406 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10407 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10408 {5745, 149},
10409 {5765, 153},
10410 {5785, 157},
10411 {5805, 161},
10412 {5825, 165}},
10413 },
10414
10415 { /* Custom NA & Europe */
10416 "ZZB",
10417 .bg_channels = 11,
10418 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10419 {2427, 4}, {2432, 5}, {2437, 6},
10420 {2442, 7}, {2447, 8}, {2452, 9},
10421 {2457, 10}, {2462, 11}},
10422 .a_channels = 13,
10423 .a = {{5180, 36},
10424 {5200, 40},
10425 {5220, 44},
10426 {5240, 48},
10427 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10428 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10429 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10430 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10431 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10432 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10433 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10434 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10435 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10436 },
10437
10438 { /* Custom Japan */
10439 "ZZC",
10440 .bg_channels = 11,
10441 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10442 {2427, 4}, {2432, 5}, {2437, 6},
10443 {2442, 7}, {2447, 8}, {2452, 9},
10444 {2457, 10}, {2462, 11}},
10445 .a_channels = 4,
10446 .a = {{5170, 34}, {5190, 38},
10447 {5210, 42}, {5230, 46}},
10448 },
10449
10450 { /* Custom */
10451 "ZZM",
10452 .bg_channels = 11,
10453 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10454 {2427, 4}, {2432, 5}, {2437, 6},
10455 {2442, 7}, {2447, 8}, {2452, 9},
10456 {2457, 10}, {2462, 11}},
10457 },
10458
10459 { /* Europe */
10460 "ZZE",
10461 .bg_channels = 13,
10462 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10463 {2427, 4}, {2432, 5}, {2437, 6},
10464 {2442, 7}, {2447, 8}, {2452, 9},
10465 {2457, 10}, {2462, 11}, {2467, 12},
10466 {2472, 13}},
10467 .a_channels = 19,
10468 .a = {{5180, 36},
10469 {5200, 40},
10470 {5220, 44},
10471 {5240, 48},
10472 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10473 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10474 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10475 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10476 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10477 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10478 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10479 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10480 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10481 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10482 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10483 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10484 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10485 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10486 {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
10487 },
10488
10489 { /* Custom Japan */
10490 "ZZJ",
10491 .bg_channels = 14,
10492 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10493 {2427, 4}, {2432, 5}, {2437, 6},
10494 {2442, 7}, {2447, 8}, {2452, 9},
10495 {2457, 10}, {2462, 11}, {2467, 12},
10496 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
10497 .a_channels = 4,
10498 .a = {{5170, 34}, {5190, 38},
10499 {5210, 42}, {5230, 46}},
10500 },
10501
10502 { /* Rest of World */
10503 "ZZR",
10504 .bg_channels = 14,
10505 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10506 {2427, 4}, {2432, 5}, {2437, 6},
10507 {2442, 7}, {2447, 8}, {2452, 9},
10508 {2457, 10}, {2462, 11}, {2467, 12},
10509 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
10510 IEEE80211_CH_PASSIVE_ONLY}},
10511 },
10512
10513 { /* High Band */
10514 "ZZH",
10515 .bg_channels = 13,
10516 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10517 {2427, 4}, {2432, 5}, {2437, 6},
10518 {2442, 7}, {2447, 8}, {2452, 9},
10519 {2457, 10}, {2462, 11},
10520 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10521 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10522 .a_channels = 4,
10523 .a = {{5745, 149}, {5765, 153},
10524 {5785, 157}, {5805, 161}},
10525 },
10526
10527 { /* Custom Europe */
10528 "ZZG",
10529 .bg_channels = 13,
10530 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10531 {2427, 4}, {2432, 5}, {2437, 6},
10532 {2442, 7}, {2447, 8}, {2452, 9},
10533 {2457, 10}, {2462, 11},
10534 {2467, 12}, {2472, 13}},
10535 .a_channels = 4,
10536 .a = {{5180, 36}, {5200, 40},
10537 {5220, 44}, {5240, 48}},
10538 },
10539
10540 { /* Europe */
10541 "ZZK",
10542 .bg_channels = 13,
10543 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10544 {2427, 4}, {2432, 5}, {2437, 6},
10545 {2442, 7}, {2447, 8}, {2452, 9},
10546 {2457, 10}, {2462, 11},
10547 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10548 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10549 .a_channels = 24,
10550 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10551 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10552 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10553 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10554 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10555 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10556 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10557 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10558 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10559 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10560 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10561 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10562 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10563 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10564 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10565 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10566 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10567 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10568 {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
10569 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10570 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10571 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10572 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10573 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10574 },
10575
10576 { /* Europe */
10577 "ZZL",
10578 .bg_channels = 11,
10579 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10580 {2427, 4}, {2432, 5}, {2437, 6},
10581 {2442, 7}, {2447, 8}, {2452, 9},
10582 {2457, 10}, {2462, 11}},
10583 .a_channels = 13,
10584 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10585 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10586 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10587 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10588 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10589 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10590 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10591 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10592 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10593 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10594 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10595 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10596 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10597 }
10598};
10599
10600/* GEO code borrowed from ieee80211_geo.c */
10601static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10602{
10603 int i;
10604
10605 /* Driver needs to initialize the geography map before using
10606 * these helper functions */
10607 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10608
10609 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10610 for (i = 0; i < ieee->geo.bg_channels; i++)
10611 /* NOTE: If G mode is currently supported but
10612 * this is a B only channel, we don't see it
10613 * as valid. */
10614 if ((ieee->geo.bg[i].channel == channel) &&
10615 (!(ieee->mode & IEEE_G) ||
10616 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10617 return IEEE80211_24GHZ_BAND;
10618
10619 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10620 for (i = 0; i < ieee->geo.a_channels; i++)
10621 if (ieee->geo.a[i].channel == channel)
10622 return IEEE80211_52GHZ_BAND;
10623
10624 return 0;
10625}
10626
10627static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10628{
10629 int i;
10630
10631 /* Driver needs to initialize the geography map before using
10632 * these helper functions */
10633 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10634
10635 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10636 for (i = 0; i < ieee->geo.bg_channels; i++)
10637 if (ieee->geo.bg[i].channel == channel)
10638 return i;
10639
10640 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10641 for (i = 0; i < ieee->geo.a_channels; i++)
10642 if (ieee->geo.a[i].channel == channel)
10643 return i;
10644
10645 return -1;
10646}
10647
10648static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10649{
10650 int i;
10651
10652 /* Driver needs to initialize the geography map before using
10653 * these helper functions */
10654 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10655
10656 freq /= 100000;
10657
10658 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10659 for (i = 0; i < ieee->geo.bg_channels; i++)
10660 if (ieee->geo.bg[i].freq == freq)
10661 return ieee->geo.bg[i].channel;
10662
10663 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10664 for (i = 0; i < ieee->geo.a_channels; i++)
10665 if (ieee->geo.a[i].freq == freq)
10666 return ieee->geo.a[i].channel;
10667
10668 return 0;
10669}
10670
10671static int ipw_set_geo(struct ieee80211_device *ieee,
10672 const struct ieee80211_geo *geo)
10673{
10674 memcpy(ieee->geo.name, geo->name, 3);
10675 ieee->geo.name[3] = '\0';
10676 ieee->geo.bg_channels = geo->bg_channels;
10677 ieee->geo.a_channels = geo->a_channels;
10678 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10679 sizeof(struct ieee80211_channel));
10680 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10681 sizeof(struct ieee80211_channel));
10682 return 0;
10683}
10684
10685static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10686{
10687 return &ieee->geo;
10688}
10689
6852#define MAX_HW_RESTARTS 5 10690#define MAX_HW_RESTARTS 5
6853static int ipw_up(struct ipw_priv *priv) 10691static int ipw_up(struct ipw_priv *priv)
6854{ 10692{
6855 int rc, i; 10693 int rc, i, j;
6856 10694
6857 if (priv->status & STATUS_EXIT_PENDING) 10695 if (priv->status & STATUS_EXIT_PENDING)
6858 return -EIO; 10696 return -EIO;
6859 10697
10698 if (cmdlog && !priv->cmdlog) {
10699 priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
10700 GFP_KERNEL);
10701 if (priv->cmdlog == NULL) {
10702 IPW_ERROR("Error allocating %d command log entries.\n",
10703 cmdlog);
10704 } else {
10705 memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
10706 priv->cmdlog_len = cmdlog;
10707 }
10708 }
10709
6860 for (i = 0; i < MAX_HW_RESTARTS; i++) { 10710 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6861 /* Load the microcode, firmware, and eeprom. 10711 /* Load the microcode, firmware, and eeprom.
6862 * Also start the clocks. */ 10712 * Also start the clocks. */
6863 rc = ipw_load(priv); 10713 rc = ipw_load(priv);
6864 if (rc) { 10714 if (rc) {
6865 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc); 10715 IPW_ERROR("Unable to load firmware: %d\n", rc);
6866 return rc; 10716 return rc;
6867 } 10717 }
6868 10718
@@ -6871,20 +10721,50 @@ static int ipw_up(struct ipw_priv *priv)
6871 eeprom_parse_mac(priv, priv->mac_addr); 10721 eeprom_parse_mac(priv, priv->mac_addr);
6872 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 10722 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
6873 10723
6874 if (priv->status & STATUS_RF_KILL_MASK) 10724 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
10725 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
10726 ipw_geos[j].name, 3))
10727 break;
10728 }
10729 if (j == ARRAY_SIZE(ipw_geos)) {
10730 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
10731 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
10732 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
10733 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10734 j = 0;
10735 }
10736 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
10737 IPW_WARNING("Could not set geography.");
10738 return 0;
10739 }
10740
10741 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10742 j, priv->ieee->geo.name);
10743
10744 if (priv->status & STATUS_RF_KILL_SW) {
10745 IPW_WARNING("Radio disabled by module parameter.\n");
10746 return 0;
10747 } else if (rf_kill_active(priv)) {
10748 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
10749 "Kill switch must be turned off for "
10750 "wireless networking to work.\n");
10751 queue_delayed_work(priv->workqueue, &priv->rf_kill,
10752 2 * HZ);
6875 return 0; 10753 return 0;
10754 }
6876 10755
6877 rc = ipw_config(priv); 10756 rc = ipw_config(priv);
6878 if (!rc) { 10757 if (!rc) {
6879 IPW_DEBUG_INFO("Configured device on count %i\n", i); 10758 IPW_DEBUG_INFO("Configured device on count %i\n", i);
6880 priv->notif_missed_beacons = 0; 10759
6881 netif_start_queue(priv->net_dev); 10760 /* If configure to try and auto-associate, kick
10761 * off a scan. */
10762 queue_work(priv->workqueue, &priv->request_scan);
10763
6882 return 0; 10764 return 0;
6883 } else {
6884 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
6885 rc);
6886 } 10765 }
6887 10766
10767 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
6888 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n", 10768 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
6889 i, MAX_HW_RESTARTS); 10769 i, MAX_HW_RESTARTS);
6890 10770
@@ -6896,47 +10776,101 @@ static int ipw_up(struct ipw_priv *priv)
6896 /* tried to restart and config the device for as long as our 10776 /* tried to restart and config the device for as long as our
6897 * patience could withstand */ 10777 * patience could withstand */
6898 IPW_ERROR("Unable to initialize device after %d attempts.\n", i); 10778 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
10779
6899 return -EIO; 10780 return -EIO;
6900} 10781}
6901 10782
6902static void ipw_down(struct ipw_priv *priv) 10783static void ipw_bg_up(void *data)
10784{
10785 struct ipw_priv *priv = data;
10786 down(&priv->sem);
10787 ipw_up(data);
10788 up(&priv->sem);
10789}
10790
10791static void ipw_deinit(struct ipw_priv *priv)
6903{ 10792{
10793 int i;
10794
10795 if (priv->status & STATUS_SCANNING) {
10796 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
10797 ipw_abort_scan(priv);
10798 }
10799
10800 if (priv->status & STATUS_ASSOCIATED) {
10801 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
10802 ipw_disassociate(priv);
10803 }
10804
10805 ipw_led_shutdown(priv);
10806
10807 /* Wait up to 1s for status to change to not scanning and not
10808 * associated (disassociation can take a while for a ful 802.11
10809 * exchange */
10810 for (i = 1000; i && (priv->status &
10811 (STATUS_DISASSOCIATING |
10812 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
10813 udelay(10);
10814
10815 if (priv->status & (STATUS_DISASSOCIATING |
10816 STATUS_ASSOCIATED | STATUS_SCANNING))
10817 IPW_DEBUG_INFO("Still associated or scanning...\n");
10818 else
10819 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
10820
6904 /* Attempt to disable the card */ 10821 /* Attempt to disable the card */
6905#if 0
6906 ipw_send_card_disable(priv, 0); 10822 ipw_send_card_disable(priv, 0);
6907#endif 10823
10824 priv->status &= ~STATUS_INIT;
10825}
10826
10827static void ipw_down(struct ipw_priv *priv)
10828{
10829 int exit_pending = priv->status & STATUS_EXIT_PENDING;
10830
10831 priv->status |= STATUS_EXIT_PENDING;
10832
10833 if (ipw_is_init(priv))
10834 ipw_deinit(priv);
10835
10836 /* Wipe out the EXIT_PENDING status bit if we are not actually
10837 * exiting the module */
10838 if (!exit_pending)
10839 priv->status &= ~STATUS_EXIT_PENDING;
6908 10840
6909 /* tell the device to stop sending interrupts */ 10841 /* tell the device to stop sending interrupts */
6910 ipw_disable_interrupts(priv); 10842 ipw_disable_interrupts(priv);
6911 10843
6912 /* Clear all bits but the RF Kill */ 10844 /* Clear all bits but the RF Kill */
6913 priv->status &= STATUS_RF_KILL_MASK; 10845 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
6914
6915 netif_carrier_off(priv->net_dev); 10846 netif_carrier_off(priv->net_dev);
6916 netif_stop_queue(priv->net_dev); 10847 netif_stop_queue(priv->net_dev);
6917 10848
6918 ipw_stop_nic(priv); 10849 ipw_stop_nic(priv);
10850
10851 ipw_led_radio_off(priv);
10852}
10853
10854static void ipw_bg_down(void *data)
10855{
10856 struct ipw_priv *priv = data;
10857 down(&priv->sem);
10858 ipw_down(data);
10859 up(&priv->sem);
6919} 10860}
6920 10861
6921/* Called by register_netdev() */ 10862/* Called by register_netdev() */
6922static int ipw_net_init(struct net_device *dev) 10863static int ipw_net_init(struct net_device *dev)
6923{ 10864{
6924 struct ipw_priv *priv = ieee80211_priv(dev); 10865 struct ipw_priv *priv = ieee80211_priv(dev);
10866 down(&priv->sem);
6925 10867
6926 if (priv->status & STATUS_RF_KILL_SW) { 10868 if (ipw_up(priv)) {
6927 IPW_WARNING("Radio disabled by module parameter.\n"); 10869 up(&priv->sem);
6928 return 0;
6929 } else if (rf_kill_active(priv)) {
6930 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
6931 "Kill switch must be turned off for "
6932 "wireless networking to work.\n");
6933 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
6934 return 0;
6935 }
6936
6937 if (ipw_up(priv))
6938 return -EIO; 10870 return -EIO;
10871 }
6939 10872
10873 up(&priv->sem);
6940 return 0; 10874 return 0;
6941} 10875}
6942 10876
@@ -6961,7 +10895,7 @@ static struct pci_device_id card_ids[] = {
6961 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, 10895 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
6962 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 10896 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
6963 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ 10897 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6964 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ 10898 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6965 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10899 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6966 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10900 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6967 10901
@@ -6981,11 +10915,16 @@ static struct attribute *ipw_sysfs_entries[] = {
6981 &dev_attr_nic_type.attr, 10915 &dev_attr_nic_type.attr,
6982 &dev_attr_status.attr, 10916 &dev_attr_status.attr,
6983 &dev_attr_cfg.attr, 10917 &dev_attr_cfg.attr,
6984 &dev_attr_dump_errors.attr, 10918 &dev_attr_error.attr,
6985 &dev_attr_dump_events.attr, 10919 &dev_attr_event_log.attr,
10920 &dev_attr_cmd_log.attr,
6986 &dev_attr_eeprom_delay.attr, 10921 &dev_attr_eeprom_delay.attr,
6987 &dev_attr_ucode_version.attr, 10922 &dev_attr_ucode_version.attr,
6988 &dev_attr_rtc.attr, 10923 &dev_attr_rtc.attr,
10924 &dev_attr_scan_age.attr,
10925 &dev_attr_led.attr,
10926 &dev_attr_speed_scan.attr,
10927 &dev_attr_net_stats.attr,
6989 NULL 10928 NULL
6990}; 10929};
6991 10930
@@ -7001,7 +10940,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7001 void __iomem *base; 10940 void __iomem *base;
7002 u32 length, val; 10941 u32 length, val;
7003 struct ipw_priv *priv; 10942 struct ipw_priv *priv;
7004 int band, modulation; 10943 int i;
7005 10944
7006 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 10945 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
7007 if (net_dev == NULL) { 10946 if (net_dev == NULL) {
@@ -7011,13 +10950,17 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7011 10950
7012 priv = ieee80211_priv(net_dev); 10951 priv = ieee80211_priv(net_dev);
7013 priv->ieee = netdev_priv(net_dev); 10952 priv->ieee = netdev_priv(net_dev);
10953
7014 priv->net_dev = net_dev; 10954 priv->net_dev = net_dev;
7015 priv->pci_dev = pdev; 10955 priv->pci_dev = pdev;
7016#ifdef CONFIG_IPW_DEBUG 10956#ifdef CONFIG_IPW_DEBUG
7017 ipw_debug_level = debug; 10957 ipw_debug_level = debug;
7018#endif 10958#endif
7019 spin_lock_init(&priv->lock); 10959 spin_lock_init(&priv->lock);
10960 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10961 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
7020 10962
10963 init_MUTEX(&priv->sem);
7021 if (pci_enable_device(pdev)) { 10964 if (pci_enable_device(pdev)) {
7022 err = -ENODEV; 10965 err = -ENODEV;
7023 goto out_free_ieee80211; 10966 goto out_free_ieee80211;
@@ -7064,90 +11007,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7064 goto out_iounmap; 11007 goto out_iounmap;
7065 } 11008 }
7066 11009
7067 /* Initialize module parameter values here */ 11010 ipw_sw_reset(priv, 1);
7068 if (ifname)
7069 strncpy(net_dev->name, ifname, IFNAMSIZ);
7070
7071 if (associate)
7072 priv->config |= CFG_ASSOCIATE;
7073 else
7074 IPW_DEBUG_INFO("Auto associate disabled.\n");
7075
7076 if (auto_create)
7077 priv->config |= CFG_ADHOC_CREATE;
7078 else
7079 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
7080
7081 if (disable) {
7082 priv->status |= STATUS_RF_KILL_SW;
7083 IPW_DEBUG_INFO("Radio disabled.\n");
7084 }
7085
7086 if (channel != 0) {
7087 priv->config |= CFG_STATIC_CHANNEL;
7088 priv->channel = channel;
7089 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7090 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7091 /* TODO: Validate that provided channel is in range */
7092 }
7093
7094 switch (mode) {
7095 case 1:
7096 priv->ieee->iw_mode = IW_MODE_ADHOC;
7097 break;
7098#ifdef CONFIG_IPW_PROMISC
7099 case 2:
7100 priv->ieee->iw_mode = IW_MODE_MONITOR;
7101 break;
7102#endif
7103 default:
7104 case 0:
7105 priv->ieee->iw_mode = IW_MODE_INFRA;
7106 break;
7107 }
7108
7109 if ((priv->pci_dev->device == 0x4223) ||
7110 (priv->pci_dev->device == 0x4224)) {
7111 printk(KERN_INFO DRV_NAME
7112 ": Detected Intel PRO/Wireless 2915ABG Network "
7113 "Connection\n");
7114 priv->ieee->abg_true = 1;
7115 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
7116 modulation = IEEE80211_OFDM_MODULATION |
7117 IEEE80211_CCK_MODULATION;
7118 priv->adapter = IPW_2915ABG;
7119 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
7120 } else {
7121 if (priv->pci_dev->device == 0x4221)
7122 printk(KERN_INFO DRV_NAME
7123 ": Detected Intel PRO/Wireless 2225BG Network "
7124 "Connection\n");
7125 else
7126 printk(KERN_INFO DRV_NAME
7127 ": Detected Intel PRO/Wireless 2200BG Network "
7128 "Connection\n");
7129
7130 priv->ieee->abg_true = 0;
7131 band = IEEE80211_24GHZ_BAND;
7132 modulation = IEEE80211_OFDM_MODULATION |
7133 IEEE80211_CCK_MODULATION;
7134 priv->adapter = IPW_2200BG;
7135 priv->ieee->mode = IEEE_G | IEEE_B;
7136 }
7137
7138 priv->ieee->freq_band = band;
7139 priv->ieee->modulation = modulation;
7140
7141 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
7142
7143 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
7144 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
7145
7146 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7147
7148 /* If power management is turned on, default to AC mode */
7149 priv->power_mode = IPW_POWER_AC;
7150 priv->tx_power = IPW_DEFAULT_TX_POWER;
7151 11011
7152 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); 11012 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
7153 if (err) { 11013 if (err) {
@@ -7158,8 +11018,20 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7158 SET_MODULE_OWNER(net_dev); 11018 SET_MODULE_OWNER(net_dev);
7159 SET_NETDEV_DEV(net_dev, &pdev->dev); 11019 SET_NETDEV_DEV(net_dev, &pdev->dev);
7160 11020
11021 down(&priv->sem);
11022
7161 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 11023 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7162 priv->ieee->set_security = shim__set_security; 11024 priv->ieee->set_security = shim__set_security;
11025 priv->ieee->is_queue_full = ipw_net_is_queue_full;
11026
11027#ifdef CONFIG_IPW_QOS
11028 priv->ieee->handle_probe_response = ipw_handle_beacon;
11029 priv->ieee->handle_beacon = ipw_handle_probe_response;
11030 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
11031#endif /* CONFIG_IPW_QOS */
11032
11033 priv->ieee->perfect_rssi = -20;
11034 priv->ieee->worst_rssi = -85;
7163 11035
7164 net_dev->open = ipw_net_open; 11036 net_dev->open = ipw_net_open;
7165 net_dev->stop = ipw_net_stop; 11037 net_dev->stop = ipw_net_stop;
@@ -7167,7 +11039,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7167 net_dev->get_stats = ipw_net_get_stats; 11039 net_dev->get_stats = ipw_net_get_stats;
7168 net_dev->set_multicast_list = ipw_net_set_multicast_list; 11040 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7169 net_dev->set_mac_address = ipw_net_set_mac_address; 11041 net_dev->set_mac_address = ipw_net_set_mac_address;
7170 net_dev->get_wireless_stats = ipw_get_wireless_stats; 11042 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11043 priv->wireless_data.ieee80211 = priv->ieee;
11044 net_dev->wireless_data = &priv->wireless_data;
7171 net_dev->wireless_handlers = &ipw_wx_handler_def; 11045 net_dev->wireless_handlers = &ipw_wx_handler_def;
7172 net_dev->ethtool_ops = &ipw_ethtool_ops; 11046 net_dev->ethtool_ops = &ipw_ethtool_ops;
7173 net_dev->irq = pdev->irq; 11047 net_dev->irq = pdev->irq;
@@ -7178,18 +11052,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7178 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); 11052 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
7179 if (err) { 11053 if (err) {
7180 IPW_ERROR("failed to create sysfs device attributes\n"); 11054 IPW_ERROR("failed to create sysfs device attributes\n");
11055 up(&priv->sem);
7181 goto out_release_irq; 11056 goto out_release_irq;
7182 } 11057 }
7183 11058
11059 up(&priv->sem);
7184 err = register_netdev(net_dev); 11060 err = register_netdev(net_dev);
7185 if (err) { 11061 if (err) {
7186 IPW_ERROR("failed to register network device\n"); 11062 IPW_ERROR("failed to register network device\n");
7187 goto out_remove_group; 11063 goto out_remove_sysfs;
7188 } 11064 }
7189
7190 return 0; 11065 return 0;
7191 11066
7192 out_remove_group: 11067 out_remove_sysfs:
7193 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11068 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7194 out_release_irq: 11069 out_release_irq:
7195 free_irq(pdev->irq, priv); 11070 free_irq(pdev->irq, priv);
@@ -7212,14 +11087,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7212static void ipw_pci_remove(struct pci_dev *pdev) 11087static void ipw_pci_remove(struct pci_dev *pdev)
7213{ 11088{
7214 struct ipw_priv *priv = pci_get_drvdata(pdev); 11089 struct ipw_priv *priv = pci_get_drvdata(pdev);
11090 struct list_head *p, *q;
11091 int i;
11092
7215 if (!priv) 11093 if (!priv)
7216 return; 11094 return;
7217 11095
7218 priv->status |= STATUS_EXIT_PENDING; 11096 down(&priv->sem);
7219 11097
11098 priv->status |= STATUS_EXIT_PENDING;
11099 ipw_down(priv);
7220 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11100 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7221 11101
7222 ipw_down(priv); 11102 up(&priv->sem);
7223 11103
7224 unregister_netdev(priv->net_dev); 11104 unregister_netdev(priv->net_dev);
7225 11105
@@ -7229,16 +11109,31 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7229 } 11109 }
7230 ipw_tx_queue_free(priv); 11110 ipw_tx_queue_free(priv);
7231 11111
11112 if (priv->cmdlog) {
11113 kfree(priv->cmdlog);
11114 priv->cmdlog = NULL;
11115 }
7232 /* ipw_down will ensure that there is no more pending work 11116 /* ipw_down will ensure that there is no more pending work
7233 * in the workqueue's, so we can safely remove them now. */ 11117 * in the workqueue's, so we can safely remove them now. */
7234 if (priv->workqueue) { 11118 cancel_delayed_work(&priv->adhoc_check);
7235 cancel_delayed_work(&priv->adhoc_check); 11119 cancel_delayed_work(&priv->gather_stats);
7236 cancel_delayed_work(&priv->gather_stats); 11120 cancel_delayed_work(&priv->request_scan);
7237 cancel_delayed_work(&priv->request_scan); 11121 cancel_delayed_work(&priv->rf_kill);
7238 cancel_delayed_work(&priv->rf_kill); 11122 cancel_delayed_work(&priv->scan_check);
7239 cancel_delayed_work(&priv->scan_check); 11123 destroy_workqueue(priv->workqueue);
7240 destroy_workqueue(priv->workqueue); 11124 priv->workqueue = NULL;
7241 priv->workqueue = NULL; 11125
11126 /* Free MAC hash list for ADHOC */
11127 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11128 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11129 kfree(list_entry(p, struct ipw_ibss_seq, list));
11130 list_del(p);
11131 }
11132 }
11133
11134 if (priv->error) {
11135 ipw_free_error_log(priv->error);
11136 priv->error = NULL;
7242 } 11137 }
7243 11138
7244 free_irq(pdev->irq, priv); 11139 free_irq(pdev->irq, priv);
@@ -7247,15 +11142,7 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7247 pci_disable_device(pdev); 11142 pci_disable_device(pdev);
7248 pci_set_drvdata(pdev, NULL); 11143 pci_set_drvdata(pdev, NULL);
7249 free_ieee80211(priv->net_dev); 11144 free_ieee80211(priv->net_dev);
7250 11145 free_firmware();
7251#ifdef CONFIG_PM
7252 if (fw_loaded) {
7253 release_firmware(bootfw);
7254 release_firmware(ucode);
7255 release_firmware(firmware);
7256 fw_loaded = 0;
7257 }
7258#endif
7259} 11146}
7260 11147
7261#ifdef CONFIG_PM 11148#ifdef CONFIG_PM
@@ -7287,13 +11174,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
7287 11174
7288 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 11175 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7289 11176
7290 pci_set_power_state(pdev, 0); 11177 pci_set_power_state(pdev, PCI_D0);
7291 pci_enable_device(pdev); 11178 pci_enable_device(pdev);
7292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7293 pci_restore_state(pdev, priv->pm_state);
7294#else
7295 pci_restore_state(pdev); 11179 pci_restore_state(pdev);
7296#endif 11180
7297 /* 11181 /*
7298 * Suspend/Resume resets the PCI configuration space, so we have to 11182 * Suspend/Resume resets the PCI configuration space, so we have to
7299 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries 11183 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7365,16 +11249,33 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
7365module_param(auto_create, int, 0444); 11249module_param(auto_create, int, 0444);
7366MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 11250MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
7367 11251
11252module_param(led, int, 0444);
11253MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11254
7368module_param(debug, int, 0444); 11255module_param(debug, int, 0444);
7369MODULE_PARM_DESC(debug, "debug output mask"); 11256MODULE_PARM_DESC(debug, "debug output mask");
7370 11257
7371module_param(channel, int, 0444); 11258module_param(channel, int, 0444);
7372MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11259MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7373 11260
7374module_param(ifname, charp, 0444); 11261#ifdef CONFIG_IPW_QOS
7375MODULE_PARM_DESC(ifname, "network device name (default eth%d)"); 11262module_param(qos_enable, int, 0444);
11263MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
11264
11265module_param(qos_burst_enable, int, 0444);
11266MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11267
11268module_param(qos_no_ack_mask, int, 0444);
11269MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
7376 11270
7377#ifdef CONFIG_IPW_PROMISC 11271module_param(burst_duration_CCK, int, 0444);
11272MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
11273
11274module_param(burst_duration_OFDM, int, 0444);
11275MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11276#endif /* CONFIG_IPW_QOS */
11277
11278#ifdef CONFIG_IPW2200_MONITOR
7378module_param(mode, int, 0444); 11279module_param(mode, int, 0444);
7379MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 11280MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7380#else 11281#else
@@ -7382,5 +11283,12 @@ module_param(mode, int, 0444);
7382MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11283MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
7383#endif 11284#endif
7384 11285
11286module_param(hwcrypto, int, 0444);
11287MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
11288
11289module_param(cmdlog, int, 0444);
11290MODULE_PARM_DESC(cmdlog,
11291 "allocate a ring buffer for logging firmware commands");
11292
7385module_exit(ipw_exit); 11293module_exit(ipw_exit);
7386module_init(ipw_init); 11294module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index e9cf32bf3e31..1c98db0652c9 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,6 @@
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/init.h> 35#include <linux/init.h>
36 36
37#include <linux/version.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
39#include <linux/netdevice.h> 38#include <linux/netdevice.h>
40#include <linux/ethtool.h> 39#include <linux/ethtool.h>
@@ -50,6 +49,7 @@
50#include <asm/io.h> 49#include <asm/io.h>
51 50
52#include <net/ieee80211.h> 51#include <net/ieee80211.h>
52#include <net/ieee80211_radiotap.h>
53 53
54#define DRV_NAME "ipw2200" 54#define DRV_NAME "ipw2200"
55 55
@@ -161,6 +161,16 @@ enum connection_manager_assoc_states {
161 * TX Queue Flag Definitions 161 * TX Queue Flag Definitions
162 */ 162 */
163 163
164/* tx wep key definition */
165#define DCT_WEP_KEY_NOT_IMMIDIATE 0x00
166#define DCT_WEP_KEY_64Bit 0x40
167#define DCT_WEP_KEY_128Bit 0x80
168#define DCT_WEP_KEY_128bitIV 0xC0
169#define DCT_WEP_KEY_SIZE_MASK 0xC0
170
171#define DCT_WEP_KEY_INDEX_MASK 0x0F
172#define DCT_WEP_INDEX_USE_IMMEDIATE 0x20
173
164/* abort attempt if mgmt frame is rx'd */ 174/* abort attempt if mgmt frame is rx'd */
165#define DCT_FLAG_ABORT_MGMT 0x01 175#define DCT_FLAG_ABORT_MGMT 0x01
166 176
@@ -168,7 +178,8 @@ enum connection_manager_assoc_states {
168#define DCT_FLAG_CTS_REQUIRED 0x02 178#define DCT_FLAG_CTS_REQUIRED 0x02
169 179
170/* use short preamble */ 180/* use short preamble */
171#define DCT_FLAG_SHORT_PREMBL 0x04 181#define DCT_FLAG_LONG_PREAMBLE 0x00
182#define DCT_FLAG_SHORT_PREAMBLE 0x04
172 183
173/* RTS/CTS first */ 184/* RTS/CTS first */
174#define DCT_FLAG_RTS_REQD 0x08 185#define DCT_FLAG_RTS_REQD 0x08
@@ -185,9 +196,23 @@ enum connection_manager_assoc_states {
185/* ACK rx is expected to follow */ 196/* ACK rx is expected to follow */
186#define DCT_FLAG_ACK_REQD 0x80 197#define DCT_FLAG_ACK_REQD 0x80
187 198
199/* TX flags extension */
188#define DCT_FLAG_EXT_MODE_CCK 0x01 200#define DCT_FLAG_EXT_MODE_CCK 0x01
189#define DCT_FLAG_EXT_MODE_OFDM 0x00 201#define DCT_FLAG_EXT_MODE_OFDM 0x00
190 202
203#define DCT_FLAG_EXT_SECURITY_WEP 0x00
204#define DCT_FLAG_EXT_SECURITY_NO DCT_FLAG_EXT_SECURITY_WEP
205#define DCT_FLAG_EXT_SECURITY_CKIP 0x04
206#define DCT_FLAG_EXT_SECURITY_CCM 0x08
207#define DCT_FLAG_EXT_SECURITY_TKIP 0x0C
208#define DCT_FLAG_EXT_SECURITY_MASK 0x0C
209
210#define DCT_FLAG_EXT_QOS_ENABLED 0x10
211
212#define DCT_FLAG_EXT_HC_NO_SIFS_PIFS 0x00
213#define DCT_FLAG_EXT_HC_SIFS 0x20
214#define DCT_FLAG_EXT_HC_PIFS 0x40
215
191#define TX_RX_TYPE_MASK 0xFF 216#define TX_RX_TYPE_MASK 0xFF
192#define TX_FRAME_TYPE 0x00 217#define TX_FRAME_TYPE 0x00
193#define TX_HOST_COMMAND_TYPE 0x01 218#define TX_HOST_COMMAND_TYPE 0x01
@@ -233,6 +258,117 @@ enum connection_manager_assoc_states {
233#define DCR_TYPE_SNIFFER 0x06 258#define DCR_TYPE_SNIFFER 0x06
234#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS 259#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
235 260
261/* QoS definitions */
262
263#define CW_MIN_OFDM 15
264#define CW_MAX_OFDM 1023
265#define CW_MIN_CCK 31
266#define CW_MAX_CCK 1023
267
268#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM
269#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM
270#define QOS_TX2_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
271#define QOS_TX3_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 4 - 1 )
272
273#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK
274#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK
275#define QOS_TX2_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
276#define QOS_TX3_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 4 - 1 )
277
278#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM
279#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM
280#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM
281#define QOS_TX3_CW_MAX_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
282
283#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK
284#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK
285#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK
286#define QOS_TX3_CW_MAX_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
287
288#define QOS_TX0_AIFS (3 - QOS_AIFSN_MIN_VALUE)
289#define QOS_TX1_AIFS (7 - QOS_AIFSN_MIN_VALUE)
290#define QOS_TX2_AIFS (2 - QOS_AIFSN_MIN_VALUE)
291#define QOS_TX3_AIFS (2 - QOS_AIFSN_MIN_VALUE)
292
293#define QOS_TX0_ACM 0
294#define QOS_TX1_ACM 0
295#define QOS_TX2_ACM 0
296#define QOS_TX3_ACM 0
297
298#define QOS_TX0_TXOP_LIMIT_CCK 0
299#define QOS_TX1_TXOP_LIMIT_CCK 0
300#define QOS_TX2_TXOP_LIMIT_CCK 6016
301#define QOS_TX3_TXOP_LIMIT_CCK 3264
302
303#define QOS_TX0_TXOP_LIMIT_OFDM 0
304#define QOS_TX1_TXOP_LIMIT_OFDM 0
305#define QOS_TX2_TXOP_LIMIT_OFDM 3008
306#define QOS_TX3_TXOP_LIMIT_OFDM 1504
307
308#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM
309#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM
310#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM
311#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM
312
313#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK
314#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK
315#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK
316#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK
317
318#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM
319#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM
320#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM
321#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM
322
323#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK
324#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK
325#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK
326#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK
327
328#define DEF_TX0_AIFS 0
329#define DEF_TX1_AIFS 0
330#define DEF_TX2_AIFS 0
331#define DEF_TX3_AIFS 0
332
333#define DEF_TX0_ACM 0
334#define DEF_TX1_ACM 0
335#define DEF_TX2_ACM 0
336#define DEF_TX3_ACM 0
337
338#define DEF_TX0_TXOP_LIMIT_CCK 0
339#define DEF_TX1_TXOP_LIMIT_CCK 0
340#define DEF_TX2_TXOP_LIMIT_CCK 0
341#define DEF_TX3_TXOP_LIMIT_CCK 0
342
343#define DEF_TX0_TXOP_LIMIT_OFDM 0
344#define DEF_TX1_TXOP_LIMIT_OFDM 0
345#define DEF_TX2_TXOP_LIMIT_OFDM 0
346#define DEF_TX3_TXOP_LIMIT_OFDM 0
347
348#define QOS_QOS_SETS 3
349#define QOS_PARAM_SET_ACTIVE 0
350#define QOS_PARAM_SET_DEF_CCK 1
351#define QOS_PARAM_SET_DEF_OFDM 2
352
353#define CTRL_QOS_NO_ACK (0x0020)
354
355#define IPW_TX_QUEUE_1 1
356#define IPW_TX_QUEUE_2 2
357#define IPW_TX_QUEUE_3 3
358#define IPW_TX_QUEUE_4 4
359
360/* QoS sturctures */
361struct ipw_qos_info {
362 int qos_enable;
363 struct ieee80211_qos_parameters *def_qos_parm_OFDM;
364 struct ieee80211_qos_parameters *def_qos_parm_CCK;
365 u32 burst_duration_CCK;
366 u32 burst_duration_OFDM;
367 u16 qos_no_ack_mask;
368 int burst_enable;
369};
370
371/**************************************************************/
236/** 372/**
237 * Generic queue structure 373 * Generic queue structure
238 * 374 *
@@ -402,9 +538,9 @@ struct clx2_tx_queue {
402#define RX_FREE_BUFFERS 32 538#define RX_FREE_BUFFERS 32
403#define RX_LOW_WATERMARK 8 539#define RX_LOW_WATERMARK 8
404 540
405#define SUP_RATE_11A_MAX_NUM_CHANNELS (8) 541#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
406#define SUP_RATE_11B_MAX_NUM_CHANNELS (4) 542#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
407#define SUP_RATE_11G_MAX_NUM_CHANNELS (12) 543#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
408 544
409// Used for passing to driver number of successes and failures per rate 545// Used for passing to driver number of successes and failures per rate
410struct rate_histogram { 546struct rate_histogram {
@@ -453,6 +589,9 @@ struct notif_channel_result {
453 u8 uReserved; 589 u8 uReserved;
454} __attribute__ ((packed)); 590} __attribute__ ((packed));
455 591
592#define SCAN_COMPLETED_STATUS_COMPLETE 1
593#define SCAN_COMPLETED_STATUS_ABORTED 2
594
456struct notif_scan_complete { 595struct notif_scan_complete {
457 u8 scan_type; 596 u8 scan_type;
458 u8 num_channels; 597 u8 num_channels;
@@ -563,8 +702,8 @@ struct ipw_rx_packet {
563} __attribute__ ((packed)); 702} __attribute__ ((packed));
564 703
565#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12 704#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
566#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \ 705#define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \
567 sizeof(struct ipw_rx_frame) 706 sizeof(struct ipw_rx_frame))
568 707
569struct ipw_rx_mem_buffer { 708struct ipw_rx_mem_buffer {
570 dma_addr_t dma_addr; 709 dma_addr_t dma_addr;
@@ -657,6 +796,19 @@ struct ipw_multicast_addr {
657 u8 mac4[6]; 796 u8 mac4[6];
658} __attribute__ ((packed)); 797} __attribute__ ((packed));
659 798
799#define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */
800#define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */
801
802#define DCW_WEP_KEY_SEC_TYPE_WEP 0x00
803#define DCW_WEP_KEY_SEC_TYPE_CCM 0x20
804#define DCW_WEP_KEY_SEC_TYPE_TKIP 0x30
805
806#define DCW_WEP_KEY_INVALID_SIZE 0x00 /* 0 = Invalid key */
807#define DCW_WEP_KEY64Bit_SIZE 0x05 /* 64-bit encryption */
808#define DCW_WEP_KEY128Bit_SIZE 0x0D /* 128-bit encryption */
809#define DCW_CCM_KEY128Bit_SIZE 0x10 /* 128-bit key */
810//#define DCW_WEP_KEY128BitIV_SIZE 0x10 /* 128-bit key and 128-bit IV */
811
660struct ipw_wep_key { 812struct ipw_wep_key {
661 u8 cmd_id; 813 u8 cmd_id;
662 u8 seq_num; 814 u8 seq_num;
@@ -818,14 +970,6 @@ struct ipw_tx_power {
818 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; 970 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
819} __attribute__ ((packed)); 971} __attribute__ ((packed));
820 972
821struct ipw_qos_parameters {
822 u16 cw_min[4];
823 u16 cw_max[4];
824 u8 aifs[4];
825 u8 flag[4];
826 u16 tx_op_limit[4];
827} __attribute__ ((packed));
828
829struct ipw_rsn_capabilities { 973struct ipw_rsn_capabilities {
830 u8 id; 974 u8 id;
831 u8 length; 975 u8 length;
@@ -888,6 +1032,10 @@ struct ipw_cmd {
888#define STATUS_SCAN_PENDING (1<<20) 1032#define STATUS_SCAN_PENDING (1<<20)
889#define STATUS_SCANNING (1<<21) 1033#define STATUS_SCANNING (1<<21)
890#define STATUS_SCAN_ABORTING (1<<22) 1034#define STATUS_SCAN_ABORTING (1<<22)
1035#define STATUS_SCAN_FORCED (1<<23)
1036
1037#define STATUS_LED_LINK_ON (1<<24)
1038#define STATUS_LED_ACT_ON (1<<25)
891 1039
892#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ 1040#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
893#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ 1041#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
@@ -899,11 +1047,15 @@ struct ipw_cmd {
899#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ 1047#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
900#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ 1048#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
901#define CFG_CUSTOM_MAC (1<<3) 1049#define CFG_CUSTOM_MAC (1<<3)
902#define CFG_PREAMBLE (1<<4) 1050#define CFG_PREAMBLE_LONG (1<<4)
903#define CFG_ADHOC_PERSIST (1<<5) 1051#define CFG_ADHOC_PERSIST (1<<5)
904#define CFG_ASSOCIATE (1<<6) 1052#define CFG_ASSOCIATE (1<<6)
905#define CFG_FIXED_RATE (1<<7) 1053#define CFG_FIXED_RATE (1<<7)
906#define CFG_ADHOC_CREATE (1<<8) 1054#define CFG_ADHOC_CREATE (1<<8)
1055#define CFG_NO_LED (1<<9)
1056#define CFG_BACKGROUND_SCAN (1<<10)
1057#define CFG_SPEED_SCAN (1<<11)
1058#define CFG_NET_STATS (1<<12)
907 1059
908#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 1060#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
909#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 1061#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -925,13 +1077,50 @@ struct average {
925 s32 sum; 1077 s32 sum;
926}; 1078};
927 1079
1080#define MAX_SPEED_SCAN 100
1081#define IPW_IBSS_MAC_HASH_SIZE 31
1082
1083struct ipw_ibss_seq {
1084 u8 mac[ETH_ALEN];
1085 u16 seq_num;
1086 u16 frag_num;
1087 unsigned long packet_time;
1088 struct list_head list;
1089};
1090
1091struct ipw_error_elem {
1092 u32 desc;
1093 u32 time;
1094 u32 blink1;
1095 u32 blink2;
1096 u32 link1;
1097 u32 link2;
1098 u32 data;
1099};
1100
1101struct ipw_event {
1102 u32 event;
1103 u32 time;
1104 u32 data;
1105} __attribute__ ((packed));
1106
1107struct ipw_fw_error {
1108 unsigned long jiffies;
1109 u32 status;
1110 u32 config;
1111 u32 elem_len;
1112 u32 log_len;
1113 struct ipw_error_elem *elem;
1114 struct ipw_event *log;
1115 u8 payload[0];
1116} __attribute__ ((packed));
1117
928struct ipw_priv { 1118struct ipw_priv {
929 /* ieee device used by generic ieee processing code */ 1119 /* ieee device used by generic ieee processing code */
930 struct ieee80211_device *ieee; 1120 struct ieee80211_device *ieee;
931 struct ieee80211_security sec;
932 1121
933 /* spinlock */
934 spinlock_t lock; 1122 spinlock_t lock;
1123 struct semaphore sem;
935 1124
936 /* basic pci-network driver stuff */ 1125 /* basic pci-network driver stuff */
937 struct pci_dev *pci_dev; 1126 struct pci_dev *pci_dev;
@@ -966,7 +1155,7 @@ struct ipw_priv {
966 int rx_bufs_min; /**< minimum number of bufs in Rx queue */ 1155 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
967 int rx_pend_max; /**< maximum pending buffers for one IRQ */ 1156 int rx_pend_max; /**< maximum pending buffers for one IRQ */
968 u32 hcmd_seq; /**< sequence number for hcmd */ 1157 u32 hcmd_seq; /**< sequence number for hcmd */
969 u32 missed_beacon_threshold; 1158 u32 disassociate_threshold;
970 u32 roaming_threshold; 1159 u32 roaming_threshold;
971 1160
972 struct ipw_associate assoc_request; 1161 struct ipw_associate assoc_request;
@@ -1007,6 +1196,8 @@ struct ipw_priv {
1007 u8 mac_addr[ETH_ALEN]; 1196 u8 mac_addr[ETH_ALEN];
1008 u8 num_stations; 1197 u8 num_stations;
1009 u8 stations[MAX_STATIONS][ETH_ALEN]; 1198 u8 stations[MAX_STATIONS][ETH_ALEN];
1199 u8 short_retry_limit;
1200 u8 long_retry_limit;
1010 1201
1011 u32 notif_missed_beacons; 1202 u32 notif_missed_beacons;
1012 1203
@@ -1024,17 +1215,29 @@ struct ipw_priv {
1024 u32 tx_packets; 1215 u32 tx_packets;
1025 u32 quality; 1216 u32 quality;
1026 1217
1218 u8 speed_scan[MAX_SPEED_SCAN];
1219 u8 speed_scan_pos;
1220
1221 u16 last_seq_num;
1222 u16 last_frag_num;
1223 unsigned long last_packet_time;
1224 struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
1225
1027 /* eeprom */ 1226 /* eeprom */
1028 u8 eeprom[0x100]; /* 256 bytes of eeprom */ 1227 u8 eeprom[0x100]; /* 256 bytes of eeprom */
1228 u8 country[4];
1029 int eeprom_delay; 1229 int eeprom_delay;
1030 1230
1031 struct iw_statistics wstats; 1231 struct iw_statistics wstats;
1032 1232
1233 struct iw_public_data wireless_data;
1234
1033 struct workqueue_struct *workqueue; 1235 struct workqueue_struct *workqueue;
1034 1236
1035 struct work_struct adhoc_check; 1237 struct work_struct adhoc_check;
1036 struct work_struct associate; 1238 struct work_struct associate;
1037 struct work_struct disassociate; 1239 struct work_struct disassociate;
1240 struct work_struct system_config;
1038 struct work_struct rx_replenish; 1241 struct work_struct rx_replenish;
1039 struct work_struct request_scan; 1242 struct work_struct request_scan;
1040 struct work_struct adapter_restart; 1243 struct work_struct adapter_restart;
@@ -1045,25 +1248,51 @@ struct ipw_priv {
1045 struct work_struct abort_scan; 1248 struct work_struct abort_scan;
1046 struct work_struct roam; 1249 struct work_struct roam;
1047 struct work_struct scan_check; 1250 struct work_struct scan_check;
1251 struct work_struct link_up;
1252 struct work_struct link_down;
1048 1253
1049 struct tasklet_struct irq_tasklet; 1254 struct tasklet_struct irq_tasklet;
1050 1255
1256 /* LED related variables and work_struct */
1257 u8 nic_type;
1258 u32 led_activity_on;
1259 u32 led_activity_off;
1260 u32 led_association_on;
1261 u32 led_association_off;
1262 u32 led_ofdm_on;
1263 u32 led_ofdm_off;
1264
1265 struct work_struct led_link_on;
1266 struct work_struct led_link_off;
1267 struct work_struct led_act_off;
1268 struct work_struct merge_networks;
1269
1270 struct ipw_cmd_log *cmdlog;
1271 int cmdlog_len;
1272 int cmdlog_pos;
1273
1051#define IPW_2200BG 1 1274#define IPW_2200BG 1
1052#define IPW_2915ABG 2 1275#define IPW_2915ABG 2
1053 u8 adapter; 1276 u8 adapter;
1054 1277
1055#define IPW_DEFAULT_TX_POWER 0x14 1278 s8 tx_power;
1056 u8 tx_power;
1057 1279
1058#ifdef CONFIG_PM 1280#ifdef CONFIG_PM
1059 u32 pm_state[16]; 1281 u32 pm_state[16];
1060#endif 1282#endif
1061 1283
1284 struct ipw_fw_error *error;
1285
1062 /* network state */ 1286 /* network state */
1063 1287
1064 /* Used to pass the current INTA value from ISR to Tasklet */ 1288 /* Used to pass the current INTA value from ISR to Tasklet */
1065 u32 isr_inta; 1289 u32 isr_inta;
1066 1290
1291 /* QoS */
1292 struct ipw_qos_info qos_data;
1293 struct work_struct qos_activate;
1294 /*********************************/
1295
1067 /* debugging info */ 1296 /* debugging info */
1068 u32 indirect_dword; 1297 u32 indirect_dword;
1069 u32 direct_dword; 1298 u32 direct_dword;
@@ -1125,6 +1354,8 @@ do { if (ipw_debug_level & (level)) \
1125#define IPW_DL_RF_KILL (1<<17) 1354#define IPW_DL_RF_KILL (1<<17)
1126#define IPW_DL_FW_ERRORS (1<<18) 1355#define IPW_DL_FW_ERRORS (1<<18)
1127 1356
1357#define IPW_DL_LED (1<<19)
1358
1128#define IPW_DL_ORD (1<<20) 1359#define IPW_DL_ORD (1<<20)
1129 1360
1130#define IPW_DL_FRAG (1<<21) 1361#define IPW_DL_FRAG (1<<21)
@@ -1137,6 +1368,8 @@ do { if (ipw_debug_level & (level)) \
1137#define IPW_DL_TRACE (1<<28) 1368#define IPW_DL_TRACE (1<<28)
1138 1369
1139#define IPW_DL_STATS (1<<29) 1370#define IPW_DL_STATS (1<<29)
1371#define IPW_DL_MERGE (1<<30)
1372#define IPW_DL_QOS (1<<31)
1140 1373
1141#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) 1374#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
1142#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) 1375#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1150,6 +1383,7 @@ do { if (ipw_debug_level & (level)) \
1150#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1383#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1151#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) 1384#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1152#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1385#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1386#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
1153#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1387#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1154#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1388#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1155#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1389#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1163,6 +1397,8 @@ do { if (ipw_debug_level & (level)) \
1163#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1397#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1164#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1398#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1165#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) 1399#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
1400#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
1401#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a)
1166 1402
1167#include <linux/ctype.h> 1403#include <linux/ctype.h>
1168 1404
@@ -1177,59 +1413,65 @@ do { if (ipw_debug_level & (level)) \
1177#define DINO_RXFIFO_DATA 0x01 1413#define DINO_RXFIFO_DATA 0x01
1178#define DINO_CONTROL_REG 0x00200000 1414#define DINO_CONTROL_REG 0x00200000
1179 1415
1180#define CX2_INTA_RW 0x00000008 1416#define IPW_INTA_RW 0x00000008
1181#define CX2_INTA_MASK_R 0x0000000C 1417#define IPW_INTA_MASK_R 0x0000000C
1182#define CX2_INDIRECT_ADDR 0x00000010 1418#define IPW_INDIRECT_ADDR 0x00000010
1183#define CX2_INDIRECT_DATA 0x00000014 1419#define IPW_INDIRECT_DATA 0x00000014
1184#define CX2_AUTOINC_ADDR 0x00000018 1420#define IPW_AUTOINC_ADDR 0x00000018
1185#define CX2_AUTOINC_DATA 0x0000001C 1421#define IPW_AUTOINC_DATA 0x0000001C
1186#define CX2_RESET_REG 0x00000020 1422#define IPW_RESET_REG 0x00000020
1187#define CX2_GP_CNTRL_RW 0x00000024 1423#define IPW_GP_CNTRL_RW 0x00000024
1188 1424
1189#define CX2_READ_INT_REGISTER 0xFF4 1425#define IPW_READ_INT_REGISTER 0xFF4
1190 1426
1191#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004 1427#define IPW_GP_CNTRL_BIT_INIT_DONE 0x00000004
1192 1428
1193#define CX2_REGISTER_DOMAIN1_END 0x00001000 1429#define IPW_REGISTER_DOMAIN1_END 0x00001000
1194#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4 1430#define IPW_SRAM_READ_INT_REGISTER 0x00000ff4
1195 1431
1196#define CX2_SHARED_LOWER_BOUND 0x00000200 1432#define IPW_SHARED_LOWER_BOUND 0x00000200
1197#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80 1433#define IPW_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
1198 1434
1199#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000 1435#define IPW_NIC_SRAM_LOWER_BOUND 0x00000000
1200#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000 1436#define IPW_NIC_SRAM_UPPER_BOUND 0x00030000
1201 1437
1202#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29) 1438#define IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
1203#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001 1439#define IPW_GP_CNTRL_BIT_CLOCK_READY 0x00000001
1204#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002 1440#define IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
1205 1441
1206/* 1442/*
1207 * RESET Register Bit Indexes 1443 * RESET Register Bit Indexes
1208 */ 1444 */
1209#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ 1445#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
1210#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ 1446#define IPW_START_STANDBY (1<<2)
1211#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ 1447#define IPW_ACTIVITY_LED (1<<4)
1212#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ 1448#define IPW_ASSOCIATED_LED (1<<5)
1213#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ 1449#define IPW_OFDM_LED (1<<6)
1214#define CX2_START_STANDBY 0x00000004 /* Bit 2 */ 1450#define IPW_RESET_REG_SW_RESET (1<<7)
1215 1451#define IPW_RESET_REG_MASTER_DISABLED (1<<8)
1216#define CX2_CSR_CIS_UPPER_BOUND 0x00000200 1452#define IPW_RESET_REG_STOP_MASTER (1<<9)
1217#define CX2_DOMAIN_0_END 0x1000 1453#define IPW_GATE_ODMA (1<<25)
1454#define IPW_GATE_IDMA (1<<26)
1455#define IPW_ARC_KESHET_CONFIG (1<<27)
1456#define IPW_GATE_ADMA (1<<29)
1457
1458#define IPW_CSR_CIS_UPPER_BOUND 0x00000200
1459#define IPW_DOMAIN_0_END 0x1000
1218#define CLX_MEM_BAR_SIZE 0x1000 1460#define CLX_MEM_BAR_SIZE 0x1000
1219 1461
1220#define CX2_BASEBAND_CONTROL_STATUS 0X00200000 1462#define IPW_BASEBAND_CONTROL_STATUS 0X00200000
1221#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004 1463#define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004
1222#define CX2_BASEBAND_RX_FIFO_READ 0X00200004 1464#define IPW_BASEBAND_RX_FIFO_READ 0X00200004
1223#define CX2_BASEBAND_CONTROL_STORE 0X00200010 1465#define IPW_BASEBAND_CONTROL_STORE 0X00200010
1224 1466
1225#define CX2_INTERNAL_CMD_EVENT 0X00300004 1467#define IPW_INTERNAL_CMD_EVENT 0X00300004
1226#define CX2_BASEBAND_POWER_DOWN 0x00000001 1468#define IPW_BASEBAND_POWER_DOWN 0x00000001
1227 1469
1228#define CX2_MEM_HALT_AND_RESET 0x003000e0 1470#define IPW_MEM_HALT_AND_RESET 0x003000e0
1229 1471
1230/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */ 1472/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
1231#define CX2_BIT_HALT_RESET_ON 0x80000000 1473#define IPW_BIT_HALT_RESET_ON 0x80000000
1232#define CX2_BIT_HALT_RESET_OFF 0x00000000 1474#define IPW_BIT_HALT_RESET_OFF 0x00000000
1233 1475
1234#define CB_LAST_VALID 0x20000000 1476#define CB_LAST_VALID 0x20000000
1235#define CB_INT_ENABLED 0x40000000 1477#define CB_INT_ENABLED 0x40000000
@@ -1248,63 +1490,63 @@ do { if (ipw_debug_level & (level)) \
1248#define DMA_CB_STOP_AND_ABORT 0x00000C00 1490#define DMA_CB_STOP_AND_ABORT 0x00000C00
1249#define DMA_CB_START 0x00000100 1491#define DMA_CB_START 0x00000100
1250 1492
1251#define CX2_SHARED_SRAM_SIZE 0x00030000 1493#define IPW_SHARED_SRAM_SIZE 0x00030000
1252#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 1494#define IPW_SHARED_SRAM_DMA_CONTROL 0x00027000
1253#define CB_MAX_LENGTH 0x1FFF 1495#define CB_MAX_LENGTH 0x1FFF
1254 1496
1255#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 1497#define IPW_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
1256#define CX2_EEPROM_IMAGE_SIZE 0x100 1498#define IPW_EEPROM_IMAGE_SIZE 0x100
1257 1499
1258/* DMA defs */ 1500/* DMA defs */
1259#define CX2_DMA_I_CURRENT_CB 0x003000D0 1501#define IPW_DMA_I_CURRENT_CB 0x003000D0
1260#define CX2_DMA_O_CURRENT_CB 0x003000D4 1502#define IPW_DMA_O_CURRENT_CB 0x003000D4
1261#define CX2_DMA_I_DMA_CONTROL 0x003000A4 1503#define IPW_DMA_I_DMA_CONTROL 0x003000A4
1262#define CX2_DMA_I_CB_BASE 0x003000A0 1504#define IPW_DMA_I_CB_BASE 0x003000A0
1263 1505
1264#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200) 1506#define IPW_TX_CMD_QUEUE_BD_BASE 0x00000200
1265#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204) 1507#define IPW_TX_CMD_QUEUE_BD_SIZE 0x00000204
1266#define CX2_TX_QUEUE_0_BD_BASE (0x00000208) 1508#define IPW_TX_QUEUE_0_BD_BASE 0x00000208
1267#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C) 1509#define IPW_TX_QUEUE_0_BD_SIZE (0x0000020C)
1268#define CX2_TX_QUEUE_1_BD_BASE (0x00000210) 1510#define IPW_TX_QUEUE_1_BD_BASE 0x00000210
1269#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214) 1511#define IPW_TX_QUEUE_1_BD_SIZE 0x00000214
1270#define CX2_TX_QUEUE_2_BD_BASE (0x00000218) 1512#define IPW_TX_QUEUE_2_BD_BASE 0x00000218
1271#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C) 1513#define IPW_TX_QUEUE_2_BD_SIZE (0x0000021C)
1272#define CX2_TX_QUEUE_3_BD_BASE (0x00000220) 1514#define IPW_TX_QUEUE_3_BD_BASE 0x00000220
1273#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224) 1515#define IPW_TX_QUEUE_3_BD_SIZE 0x00000224
1274#define CX2_RX_BD_BASE (0x00000240) 1516#define IPW_RX_BD_BASE 0x00000240
1275#define CX2_RX_BD_SIZE (0x00000244) 1517#define IPW_RX_BD_SIZE 0x00000244
1276#define CX2_RFDS_TABLE_LOWER (0x00000500) 1518#define IPW_RFDS_TABLE_LOWER 0x00000500
1277 1519
1278#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280) 1520#define IPW_TX_CMD_QUEUE_READ_INDEX 0x00000280
1279#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284) 1521#define IPW_TX_QUEUE_0_READ_INDEX 0x00000284
1280#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288) 1522#define IPW_TX_QUEUE_1_READ_INDEX 0x00000288
1281#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C) 1523#define IPW_TX_QUEUE_2_READ_INDEX (0x0000028C)
1282#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290) 1524#define IPW_TX_QUEUE_3_READ_INDEX 0x00000290
1283#define CX2_RX_READ_INDEX (0x000002A0) 1525#define IPW_RX_READ_INDEX (0x000002A0)
1284 1526
1285#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80) 1527#define IPW_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
1286#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84) 1528#define IPW_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
1287#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88) 1529#define IPW_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
1288#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C) 1530#define IPW_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
1289#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90) 1531#define IPW_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
1290#define CX2_RX_WRITE_INDEX (0x00000FA0) 1532#define IPW_RX_WRITE_INDEX (0x00000FA0)
1291 1533
1292/* 1534/*
1293 * EEPROM Related Definitions 1535 * EEPROM Related Definitions
1294 */ 1536 */
1295 1537
1296#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814) 1538#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
1297#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818) 1539#define IPW_EEPROM_DATA_SRAM_SIZE (IPW_SHARED_LOWER_BOUND + 0x818)
1298#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C) 1540#define IPW_EEPROM_LOAD_DISABLE (IPW_SHARED_LOWER_BOUND + 0x81C)
1299#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820) 1541#define IPW_EEPROM_DATA (IPW_SHARED_LOWER_BOUND + 0x820)
1300#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0) 1542#define IPW_EEPROM_UPPER_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x9E0)
1301 1543
1302#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C) 1544#define IPW_STATION_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0xA0C)
1303#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C) 1545#define IPW_STATION_TABLE_UPPER (IPW_SHARED_LOWER_BOUND + 0xB0C)
1304#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C) 1546#define IPW_REQUEST_ATIM (IPW_SHARED_LOWER_BOUND + 0xB0C)
1305#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10) 1547#define IPW_ATIM_SENT (IPW_SHARED_LOWER_BOUND + 0xB10)
1306#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) 1548#define IPW_WHO_IS_AWAKE (IPW_SHARED_LOWER_BOUND + 0xB14)
1307#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) 1549#define IPW_DURING_ATIM_WINDOW (IPW_SHARED_LOWER_BOUND + 0xB18)
1308 1550
1309#define MSB 1 1551#define MSB 1
1310#define LSB 0 1552#define LSB 0
@@ -1326,15 +1568,15 @@ do { if (ipw_debug_level & (level)) \
1326#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ 1568#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1327 1569
1328/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ 1570/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1329#define EEPROM_NIC_TYPE_STANDARD 0 1571#define EEPROM_NIC_TYPE_0 0
1330#define EEPROM_NIC_TYPE_DELL 1 1572#define EEPROM_NIC_TYPE_1 1
1331#define EEPROM_NIC_TYPE_FUJITSU 2 1573#define EEPROM_NIC_TYPE_2 2
1332#define EEPROM_NIC_TYPE_IBM 3 1574#define EEPROM_NIC_TYPE_3 3
1333#define EEPROM_NIC_TYPE_HP 4 1575#define EEPROM_NIC_TYPE_4 4
1334 1576
1335#define FW_MEM_REG_LOWER_BOUND 0x00300000 1577#define FW_MEM_REG_LOWER_BOUND 0x00300000
1336#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) 1578#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1337 1579#define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
1338#define EEPROM_BIT_SK (1<<0) 1580#define EEPROM_BIT_SK (1<<0)
1339#define EEPROM_BIT_CS (1<<1) 1581#define EEPROM_BIT_CS (1<<1)
1340#define EEPROM_BIT_DI (1<<2) 1582#define EEPROM_BIT_DI (1<<2)
@@ -1343,50 +1585,47 @@ do { if (ipw_debug_level & (level)) \
1343#define EEPROM_CMD_READ 0x2 1585#define EEPROM_CMD_READ 0x2
1344 1586
1345/* Interrupts masks */ 1587/* Interrupts masks */
1346#define CX2_INTA_NONE 0x00000000 1588#define IPW_INTA_NONE 0x00000000
1347 1589
1348#define CX2_INTA_BIT_RX_TRANSFER 0x00000002 1590#define IPW_INTA_BIT_RX_TRANSFER 0x00000002
1349#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010 1591#define IPW_INTA_BIT_STATUS_CHANGE 0x00000010
1350#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020 1592#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
1351 1593
1352//Inta Bits for CF 1594//Inta Bits for CF
1353#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800 1595#define IPW_INTA_BIT_TX_CMD_QUEUE 0x00000800
1354#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000 1596#define IPW_INTA_BIT_TX_QUEUE_1 0x00001000
1355#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000 1597#define IPW_INTA_BIT_TX_QUEUE_2 0x00002000
1356#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000 1598#define IPW_INTA_BIT_TX_QUEUE_3 0x00004000
1357#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000 1599#define IPW_INTA_BIT_TX_QUEUE_4 0x00008000
1358 1600
1359#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000 1601#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
1360 1602
1361#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000 1603#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
1362#define CX2_INTA_BIT_POWER_DOWN 0x00200000 1604#define IPW_INTA_BIT_POWER_DOWN 0x00200000
1363 1605
1364#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000 1606#define IPW_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
1365#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000 1607#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
1366#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000 1608#define IPW_INTA_BIT_RF_KILL_DONE 0x04000000
1367#define CX2_INTA_BIT_FATAL_ERROR 0x40000000 1609#define IPW_INTA_BIT_FATAL_ERROR 0x40000000
1368#define CX2_INTA_BIT_PARITY_ERROR 0x80000000 1610#define IPW_INTA_BIT_PARITY_ERROR 0x80000000
1369 1611
1370/* Interrupts enabled at init time. */ 1612/* Interrupts enabled at init time. */
1371#define CX2_INTA_MASK_ALL \ 1613#define IPW_INTA_MASK_ALL \
1372 (CX2_INTA_BIT_TX_QUEUE_1 | \ 1614 (IPW_INTA_BIT_TX_QUEUE_1 | \
1373 CX2_INTA_BIT_TX_QUEUE_2 | \ 1615 IPW_INTA_BIT_TX_QUEUE_2 | \
1374 CX2_INTA_BIT_TX_QUEUE_3 | \ 1616 IPW_INTA_BIT_TX_QUEUE_3 | \
1375 CX2_INTA_BIT_TX_QUEUE_4 | \ 1617 IPW_INTA_BIT_TX_QUEUE_4 | \
1376 CX2_INTA_BIT_TX_CMD_QUEUE | \ 1618 IPW_INTA_BIT_TX_CMD_QUEUE | \
1377 CX2_INTA_BIT_RX_TRANSFER | \ 1619 IPW_INTA_BIT_RX_TRANSFER | \
1378 CX2_INTA_BIT_FATAL_ERROR | \ 1620 IPW_INTA_BIT_FATAL_ERROR | \
1379 CX2_INTA_BIT_PARITY_ERROR | \ 1621 IPW_INTA_BIT_PARITY_ERROR | \
1380 CX2_INTA_BIT_STATUS_CHANGE | \ 1622 IPW_INTA_BIT_STATUS_CHANGE | \
1381 CX2_INTA_BIT_FW_INITIALIZATION_DONE | \ 1623 IPW_INTA_BIT_FW_INITIALIZATION_DONE | \
1382 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \ 1624 IPW_INTA_BIT_BEACON_PERIOD_EXPIRED | \
1383 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \ 1625 IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
1384 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \ 1626 IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
1385 CX2_INTA_BIT_POWER_DOWN | \ 1627 IPW_INTA_BIT_POWER_DOWN | \
1386 CX2_INTA_BIT_RF_KILL_DONE ) 1628 IPW_INTA_BIT_RF_KILL_DONE )
1387
1388#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
1389#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
1390 1629
1391/* FW event log definitions */ 1630/* FW event log definitions */
1392#define EVENT_ELEM_SIZE (3 * sizeof(u32)) 1631#define EVENT_ELEM_SIZE (3 * sizeof(u32))
@@ -1396,6 +1635,11 @@ do { if (ipw_debug_level & (level)) \
1396#define ERROR_ELEM_SIZE (7 * sizeof(u32)) 1635#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1397#define ERROR_START_OFFSET (1 * sizeof(u32)) 1636#define ERROR_START_OFFSET (1 * sizeof(u32))
1398 1637
1638/* TX power level (dbm) */
1639#define IPW_TX_POWER_MIN -12
1640#define IPW_TX_POWER_MAX 20
1641#define IPW_TX_POWER_DEFAULT IPW_TX_POWER_MAX
1642
1399enum { 1643enum {
1400 IPW_FW_ERROR_OK = 0, 1644 IPW_FW_ERROR_OK = 0,
1401 IPW_FW_ERROR_FAIL, 1645 IPW_FW_ERROR_FAIL,
@@ -1408,8 +1652,8 @@ enum {
1408 IPW_FW_ERROR_ALLOC_FAIL, 1652 IPW_FW_ERROR_ALLOC_FAIL,
1409 IPW_FW_ERROR_DMA_UNDERRUN, 1653 IPW_FW_ERROR_DMA_UNDERRUN,
1410 IPW_FW_ERROR_DMA_STATUS, 1654 IPW_FW_ERROR_DMA_STATUS,
1411 IPW_FW_ERROR_DINOSTATUS_ERROR, 1655 IPW_FW_ERROR_DINO_ERROR,
1412 IPW_FW_ERROR_EEPROMSTATUS_ERROR, 1656 IPW_FW_ERROR_EEPROM_ERROR,
1413 IPW_FW_ERROR_SYSASSERT, 1657 IPW_FW_ERROR_SYSASSERT,
1414 IPW_FW_ERROR_FATAL_ERROR 1658 IPW_FW_ERROR_FATAL_ERROR
1415}; 1659};
@@ -1425,6 +1669,8 @@ enum {
1425#define HC_IBSS_RECONF 4 1669#define HC_IBSS_RECONF 4
1426#define HC_DISASSOC_QUIET 5 1670#define HC_DISASSOC_QUIET 5
1427 1671
1672#define HC_QOS_SUPPORT_ASSOC 0x01
1673
1428#define IPW_RATE_CAPABILITIES 1 1674#define IPW_RATE_CAPABILITIES 1
1429#define IPW_RATE_CONNECT 0 1675#define IPW_RATE_CONNECT 0
1430 1676
@@ -1595,18 +1841,20 @@ enum {
1595 IPW_ORD_TABLE_7_LAST 1841 IPW_ORD_TABLE_7_LAST
1596}; 1842};
1597 1843
1598#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500) 1844#define IPW_ERROR_LOG (IPW_SHARED_LOWER_BOUND + 0x410)
1599#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180) 1845#define IPW_EVENT_LOG (IPW_SHARED_LOWER_BOUND + 0x414)
1600#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184) 1846#define IPW_ORDINALS_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0x500)
1601#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188) 1847#define IPW_ORDINALS_TABLE_0 (IPW_SHARED_LOWER_BOUND + 0x180)
1602#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C) 1848#define IPW_ORDINALS_TABLE_1 (IPW_SHARED_LOWER_BOUND + 0x184)
1849#define IPW_ORDINALS_TABLE_2 (IPW_SHARED_LOWER_BOUND + 0x188)
1850#define IPW_MEM_FIXED_OVERRIDE (IPW_SHARED_LOWER_BOUND + 0x41C)
1603 1851
1604struct ipw_fixed_rate { 1852struct ipw_fixed_rate {
1605 u16 tx_rates; 1853 u16 tx_rates;
1606 u16 reserved; 1854 u16 reserved;
1607} __attribute__ ((packed)); 1855} __attribute__ ((packed));
1608 1856
1609#define CX2_INDIRECT_ADDR_MASK (~0x3ul) 1857#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
1610 1858
1611struct host_cmd { 1859struct host_cmd {
1612 u8 cmd; 1860 u8 cmd;
@@ -1615,6 +1863,12 @@ struct host_cmd {
1615 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; 1863 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
1616} __attribute__ ((packed)); 1864} __attribute__ ((packed));
1617 1865
1866struct ipw_cmd_log {
1867 unsigned long jiffies;
1868 int retcode;
1869 struct host_cmd cmd;
1870};
1871
1618#define CFG_BT_COEXISTENCE_MIN 0x00 1872#define CFG_BT_COEXISTENCE_MIN 0x00
1619#define CFG_BT_COEXISTENCE_DEFER 0x02 1873#define CFG_BT_COEXISTENCE_DEFER 0x02
1620#define CFG_BT_COEXISTENCE_KILL 0x04 1874#define CFG_BT_COEXISTENCE_KILL 0x04
@@ -1643,15 +1897,6 @@ struct host_cmd {
1643#define REG_CHANNEL_MASK 0x00003FFF 1897#define REG_CHANNEL_MASK 0x00003FFF
1644#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff 1898#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
1645 1899
1646static const long ipw_frequencies[] = {
1647 2412, 2417, 2422, 2427,
1648 2432, 2437, 2442, 2447,
1649 2452, 2457, 2462, 2467,
1650 2472, 2484
1651};
1652
1653#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
1654
1655#define IPW_MAX_CONFIG_RETRIES 10 1900#define IPW_MAX_CONFIG_RETRIES 10
1656 1901
1657static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr) 1902static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 7a17bb31fc89..f5d856db92a1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -12,7 +12,6 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/wireless.h> 13#include <linux/wireless.h>
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include <linux/version.h>
16 15
17#include "hermes.h" 16#include "hermes.h"
18 17
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499136dc..109a96d90007 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -112,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
112void 111void
113isl38xx_trigger_device(int asleep, void __iomem *device_base) 112isl38xx_trigger_device(int asleep, void __iomem *device_base)
114{ 113{
115 u32 reg, counter = 0; 114 u32 reg;
116 115
117#if VERBOSE > SHOW_ERROR_MESSAGES 116#if VERBOSE > SHOW_ERROR_MESSAGES
117 u32 counter = 0;
118 struct timeval current_time; 118 struct timeval current_time;
119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); 119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
120#endif 120#endif
@@ -131,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
131 current_time.tv_sec, (long)current_time.tv_usec, 131 current_time.tv_sec, (long)current_time.tv_usec,
132 readl(device_base + ISL38XX_CTRL_STAT_REG)); 132 readl(device_base + ISL38XX_CTRL_STAT_REG));
133#endif 133#endif
134 udelay(ISL38XX_WRITEIO_DELAY);
135 134
136 reg = readl(device_base + ISL38XX_INT_IDENT_REG); 135 reg = readl(device_base + ISL38XX_INT_IDENT_REG);
137 if (reg == 0xabadface) { 136 if (reg == 0xabadface) {
@@ -145,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
145 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), 144 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
146 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { 145 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
147 udelay(ISL38XX_WRITEIO_DELAY); 146 udelay(ISL38XX_WRITEIO_DELAY);
147#if VERBOSE > SHOW_ERROR_MESSAGES
148 counter++; 148 counter++;
149#endif
149 } 150 }
150 151
151#if VERBOSE > SHOW_ERROR_MESSAGES 152#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
153 "%08li.%08li Device register read %08x\n", 154 "%08li.%08li Device register read %08x\n",
154 current_time.tv_sec, (long)current_time.tv_usec, 155 current_time.tv_sec, (long)current_time.tv_usec,
155 readl(device_base + ISL38XX_CTRL_STAT_REG)); 156 readl(device_base + ISL38XX_CTRL_STAT_REG));
156#endif
157 udelay(ISL38XX_WRITEIO_DELAY);
158
159#if VERBOSE > SHOW_ERROR_MESSAGES
160 do_gettimeofday(&current_time); 157 do_gettimeofday(&current_time);
161 DEBUG(SHOW_TRACING, 158 DEBUG(SHOW_TRACING,
162 "%08li.%08li Device asleep counter %i\n", 159 "%08li.%08li Device asleep counter %i\n",
@@ -171,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
171 168
172 /* perform another read on the Device Status Register */ 169 /* perform another read on the Device Status Register */
173 reg = readl(device_base + ISL38XX_CTRL_STAT_REG); 170 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
174 udelay(ISL38XX_WRITEIO_DELAY);
175 171
176#if VERBOSE > SHOW_ERROR_MESSAGES 172#if VERBOSE > SHOW_ERROR_MESSAGES
177 do_gettimeofday(&current_time); 173 do_gettimeofday(&current_time);
@@ -187,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
187 183
188 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, 184 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
189 ISL38XX_DEV_INT_REG); 185 ISL38XX_DEV_INT_REG);
190 udelay(ISL38XX_WRITEIO_DELAY);
191 } 186 }
192} 187}
193 188
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index e83e4912ab66..8af20980af8d 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -20,7 +20,6 @@
20#ifndef _ISL_38XX_H 20#ifndef _ISL_38XX_H
21#define _ISL_38XX_H 21#define _ISL_38XX_H
22 22
23#include <linux/version.h>
24#include <asm/io.h> 23#include <asm/io.h>
25#include <asm/byteorder.h> 24#include <asm/byteorder.h>
26 25
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5c1a1adf1ff8..135a156db25d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/if_arp.h> 25#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 78bdb359835e..5ddf29599032 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24 23
25#include <linux/netdevice.h> 24#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index efbed4397951..07053165e4c5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -23,7 +23,6 @@
23#ifndef _ISLPCI_DEV_H 23#ifndef _ISLPCI_DEV_H
24#define _ISLPCI_DEV_H 24#define _ISLPCI_DEV_H
25 25
26#include <linux/version.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
28#include <linux/wireless.h> 27#include <linux/wireless.h>
29#include <net/iw_handler.h> 28#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index fc1eb3564832..33d64d2ee53f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,7 +17,6 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/version.h>
21#include <linux/module.h> 20#include <linux/module.h>
22 21
23#include <linux/pci.h> 22#include <linux/pci.h>
@@ -227,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
227 priv->data_low_tx_full = 1; 226 priv->data_low_tx_full = 1;
228 } 227 }
229 228
229 /* set the transmission time */
230 ndev->trans_start = jiffies;
231 priv->statistics.tx_packets++;
232 priv->statistics.tx_bytes += skb->len;
233
230 /* trigger the device */ 234 /* trigger the device */
231 islpci_trigger(priv); 235 islpci_trigger(priv);
232 236
233 /* unlock the driver code */ 237 /* unlock the driver code */
234 spin_unlock_irqrestore(&priv->slock, flags); 238 spin_unlock_irqrestore(&priv->slock, flags);
235 239
236 /* set the transmission time */
237 ndev->trans_start = jiffies;
238 priv->statistics.tx_packets++;
239 priv->statistics.tx_bytes += skb->len;
240
241 return 0; 240 return 0;
242 241
243 drop_free: 242 drop_free:
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index dc040caab7d7..b41d666fea3c 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 4b3c98f5c564..c822cad3333f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4608,9 +4608,8 @@ wavelan_attach(void)
4608#endif 4608#endif
4609 4609
4610 /* Initialize the dev_link_t structure */ 4610 /* Initialize the dev_link_t structure */
4611 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4612 if (!link) return NULL;
4613 memset(link, 0, sizeof(struct dev_link_t));
4614 4613
4615 /* The io structure describes IO port mapping */ 4614 /* The io structure describes IO port mapping */
4616 link->io.NumPorts1 = 8; 4615 link->io.NumPorts1 = 8;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 3f8c27f0871b..978fdc606781 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
1965 int ret; 1965 int ret;
1966 1966
1967 /* Initialize the dev_link_t structure */ 1967 /* Initialize the dev_link_t structure */
1968 link = kmalloc(sizeof(*link), GFP_KERNEL); 1968 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1969 if (!link)
1970 goto out; 1970 goto out;
1971 memset(link, 0, sizeof(struct dev_link_t));
1972 1971
1973 /* The io structure describes IO port mapping */ 1972 /* The io structure describes IO port mapping */
1974 link->io.NumPorts1 = 16; 1973 link->io.NumPorts1 = 16;
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d414a3bb50b9..86c0808d6a05 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -30,7 +30,6 @@
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/version.h>
34#include <linux/types.h> 33#include <linux/types.h>
35 34
36#include <pcmcia/cs_types.h> 35#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index f113b69d699b..01a895bc9a47 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -35,7 +35,6 @@
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/mm.h> 36#include <linux/mm.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40 39
41#include <pcmcia/cs_types.h> 40#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index fe5ea36e7de3..56c58831e80e 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -22,16 +22,20 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25#ifdef CONFIG_SA1100_COLLIE
26#include <asm/arch-sa1100/collie.h>
27#else
28#include <asm/arch-pxa/pxa-regs.h>
29#endif
30 25
31#include "soc_common.h" 26#include "soc_common.h"
32 27
33#define NO_KEEP_VS 0x0001 28#define NO_KEEP_VS 0x0001
34 29
30/* PCMCIA to Scoop linkage
31
32 There is no easy way to link multiple scoop devices into one
33 single entity for the pxa2xx_pcmcia device so this structure
34 is used which is setup by the platform code
35*/
36struct scoop_pcmcia_config *platform_scoop_config;
37#define SCOOP_DEV platform_scoop_config->devs
38
35static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) 39static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
36{ 40{
37 reset_scoop(scoopdev->dev); 41 reset_scoop(scoopdev->dev);
@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43{ 47{
44 int ret; 48 int ret;
45 49
46#ifndef CONFIG_SA1100_COLLIE 50 if (platform_scoop_config->pcmcia_init)
47 /* 51 platform_scoop_config->pcmcia_init();
48 * Setup default state of GPIO outputs
49 * before we enable them as outputs.
50 */
51 GPSR(GPIO48_nPOE) =
52 GPIO_bit(GPIO48_nPOE) |
53 GPIO_bit(GPIO49_nPWE) |
54 GPIO_bit(GPIO50_nPIOR) |
55 GPIO_bit(GPIO51_nPIOW) |
56 GPIO_bit(GPIO52_nPCE_1) |
57 GPIO_bit(GPIO53_nPCE_2);
58
59 pxa_gpio_mode(GPIO48_nPOE_MD);
60 pxa_gpio_mode(GPIO49_nPWE_MD);
61 pxa_gpio_mode(GPIO50_nPIOR_MD);
62 pxa_gpio_mode(GPIO51_nPIOW_MD);
63 pxa_gpio_mode(GPIO52_nPCE_1_MD);
64 pxa_gpio_mode(GPIO53_nPCE_2_MD);
65 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
66 pxa_gpio_mode(GPIO55_nPREG_MD);
67 pxa_gpio_mode(GPIO56_nPWAIT_MD);
68 pxa_gpio_mode(GPIO57_nIOIS16_MD);
69#endif
70 52
71 /* Register interrupts */ 53 /* Register interrupts */
72 if (scoop_devs[skt->nr].cd_irq >= 0) { 54 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
73 struct pcmcia_irqs cd_irq; 55 struct pcmcia_irqs cd_irq;
74 56
75 cd_irq.sock = skt->nr; 57 cd_irq.sock = skt->nr;
76 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 58 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
77 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 59 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
78 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); 60 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
79 61
80 if (ret) { 62 if (ret) {
@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
83 } 65 }
84 } 66 }
85 67
86 skt->irq = scoop_devs[skt->nr].irq; 68 skt->irq = SCOOP_DEV[skt->nr].irq;
87 69
88 return 0; 70 return 0;
89} 71}
90 72
91static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 73static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{ 74{
93 if (scoop_devs[skt->nr].cd_irq >= 0) { 75 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
94 struct pcmcia_irqs cd_irq; 76 struct pcmcia_irqs cd_irq;
95 77
96 cd_irq.sock = skt->nr; 78 cd_irq.sock = skt->nr;
97 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 79 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
98 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 80 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
99 soc_pcmcia_free_irqs(skt, &cd_irq, 1); 81 soc_pcmcia_free_irqs(skt, &cd_irq, 1);
100 } 82 }
101} 83}
@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
105 struct pcmcia_state *state) 87 struct pcmcia_state *state)
106{ 88{
107 unsigned short cpr, csr; 89 unsigned short cpr, csr;
108 struct device *scoop = scoop_devs[skt->nr].dev; 90 struct device *scoop = SCOOP_DEV[skt->nr].dev;
109 91
110 cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); 92 cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
111 93
112 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); 94 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
113 write_scoop_reg(scoop, SCOOP_ISR, 0x0000); 95 write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
116 if (csr & 0x0004) { 98 if (csr & 0x0004) {
117 /* card eject */ 99 /* card eject */
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 100 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
119 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 101 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
120 } 102 }
121 else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { 103 else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
122 /* keep vs1,vs2 */ 104 /* keep vs1,vs2 */
123 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 105 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
124 csr |= scoop_devs[skt->nr].keep_vs; 106 csr |= SCOOP_DEV[skt->nr].keep_vs;
125 } 107 }
126 else if (cpr & 0x0003) { 108 else if (cpr & 0x0003) {
127 /* power on */ 109 /* power on */
128 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 110 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
129 scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); 111 SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
130 } 112 }
131 else { 113 else {
132 /* card detect */ 114 /* card detect */
133 write_scoop_reg(scoop, SCOOP_CDR, 0x0002); 115 if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
116 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
117 } else {
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
119 }
134 } 120 }
135 121
136 state->detect = (csr & 0x0004) ? 0 : 1; 122 state->detect = (csr & 0x0004) ? 0 : 1;
@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
144 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { 130 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
145 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); 131 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
146 } 132 }
147
148} 133}
149 134
150 135
@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
152 const socket_state_t *state) 137 const socket_state_t *state)
153{ 138{
154 unsigned long flags; 139 unsigned long flags;
155 struct device *scoop = scoop_devs[skt->nr].dev; 140 struct device *scoop = SCOOP_DEV[skt->nr].dev;
156 141
157 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; 142 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
158 143
@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
177 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; 162 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
178 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; 163 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
179 164
180 ncpr |= (state->Vcc == 33) ? 0x0001 : 165 if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
181 (state->Vcc == 50) ? 0x0002 : 0; 166 ncpr |= (state->Vcc == 33) ? 0x0002 :
167 (state->Vcc == 50) ? 0x0002 : 0;
168 } else {
169 ncpr |= (state->Vcc == 33) ? 0x0001 :
170 (state->Vcc == 50) ? 0x0002 : 0;
171 }
182 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; 172 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
183 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; 173 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
184 nccr |= (state->flags&SS_RESET)? 0x0080: 0; 174 nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
190 ((skt->status&SS_WRPROT) ? 0x0008 : 0); 180 ((skt->status&SS_WRPROT) ? 0x0008 : 0);
191 181
192 if (!(ncpr & 0x0003)) { 182 if (!(ncpr & 0x0003)) {
193 scoop_devs[skt->nr].keep_rd = 0; 183 SCOOP_DEV[skt->nr].keep_rd = 0;
194 } else if (!scoop_devs[skt->nr].keep_rd) { 184 } else if (!SCOOP_DEV[skt->nr].keep_rd) {
195 if (nccr & 0x0080) 185 if (nccr & 0x0080)
196 scoop_devs[skt->nr].keep_rd = 1; 186 SCOOP_DEV[skt->nr].keep_rd = 1;
197 else 187 else
198 nccr |= 0x0080; 188 nccr |= 0x0080;
199 } 189 }
200 190
201 if (mcr != nmcr) 191 if (mcr != nmcr)
202 write_scoop_reg(scoop, SCOOP_MCR, nmcr); 192 write_scoop_reg(scoop, SCOOP_MCR, nmcr);
203 if (cpr != ncpr) 193 if (cpr != ncpr) {
204 write_scoop_reg(scoop, SCOOP_CPR, ncpr); 194 if (platform_scoop_config->power_ctrl)
195 platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
196 else
197 write_scoop_reg(scoop, SCOOP_CPR, ncpr);
198 }
205 if (ccr != nccr) 199 if (ccr != nccr)
206 write_scoop_reg(scoop, SCOOP_CCR, nccr); 200 write_scoop_reg(scoop, SCOOP_CCR, nccr);
207 if (imr != nimr) 201 if (imr != nimr)
@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
214 208
215static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 209static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
216{ 210{
217 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 211 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
218 212
219 /* Enable interrupt */ 213 /* Enable interrupt */
220 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); 214 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
221 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); 215 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
222 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 216 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
223 217
224 if (machine_is_collie()) 218 if (machine_is_collie())
225 /* We need to disable SS_OUTPUT_ENA here. */ 219 /* We need to disable SS_OUTPUT_ENA here. */
226 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 220 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
227} 221}
228 222
229static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 223static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
230{ 224{
231 /* CF_BUS_OFF */ 225 /* CF_BUS_OFF */
232 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 226 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
233 227
234 if (machine_is_collie()) 228 if (machine_is_collie())
235 /* We need to disable SS_OUTPUT_ENA here. */ 229 /* We need to disable SS_OUTPUT_ENA here. */
236 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 230 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
237} 231}
238 232
239static struct pcmcia_low_level sharpsl_pcmcia_ops = { 233static struct pcmcia_low_level sharpsl_pcmcia_ops = {
240 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
241 .hw_init = sharpsl_pcmcia_hw_init, 235 .hw_init = sharpsl_pcmcia_hw_init,
242 .hw_shutdown = sharpsl_pcmcia_hw_shutdown, 236 .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
243 .socket_state = sharpsl_pcmcia_socket_state, 237 .socket_state = sharpsl_pcmcia_socket_state,
244 .configure_socket = sharpsl_pcmcia_configure_socket, 238 .configure_socket = sharpsl_pcmcia_configure_socket,
245 .socket_init = sharpsl_pcmcia_socket_init, 239 .socket_init = sharpsl_pcmcia_socket_init,
246 .socket_suspend = sharpsl_pcmcia_socket_suspend, 240 .socket_suspend = sharpsl_pcmcia_socket_suspend,
247 .first = 0, 241 .first = 0,
248 .nr = 0, 242 .nr = 0,
249}; 243};
250 244
251static struct platform_device *sharpsl_pcmcia_device;
252
253#ifdef CONFIG_SA1100_COLLIE 245#ifdef CONFIG_SA1100_COLLIE
246#include "sa11xx_base.h"
247
254int __init pcmcia_collie_init(struct device *dev) 248int __init pcmcia_collie_init(struct device *dev)
255{ 249{
256 int ret = -ENODEV; 250 int ret = -ENODEV;
@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
263 257
264#else 258#else
265 259
260static struct platform_device *sharpsl_pcmcia_device;
261
266static int __init sharpsl_pcmcia_init(void) 262static int __init sharpsl_pcmcia_init(void)
267{ 263{
268 int ret; 264 int ret;
269 265
270 sharpsl_pcmcia_ops.nr=scoop_num; 266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
271 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
272 if (!sharpsl_pcmcia_device) 268 if (!sharpsl_pcmcia_device)
273 return -ENOMEM; 269 return -ENOMEM;
@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
275 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); 271 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
276 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; 272 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
277 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 273 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
278 sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; 274 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
279 275
280 ret = platform_device_register(sharpsl_pcmcia_device); 276 ret = platform_device_register(sharpsl_pcmcia_device);
281 if (ret) 277 if (ret)
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 3b4da5a9cf79..f7bf45c6bf0d 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -41,14 +41,14 @@ int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long);
41/* 41/*
42 * Helper Functions. 42 * Helper Functions.
43 */ 43 */
44extern inline void 44static inline void
45kbd_put_queue(struct tty_struct *tty, int ch) 45kbd_put_queue(struct tty_struct *tty, int ch)
46{ 46{
47 tty_insert_flip_char(tty, ch, 0); 47 tty_insert_flip_char(tty, ch, 0);
48 tty_schedule_flip(tty); 48 tty_schedule_flip(tty);
49} 49}
50 50
51extern inline void 51static inline void
52kbd_puts_queue(struct tty_struct *tty, char *cp) 52kbd_puts_queue(struct tty_struct *tty, char *cp)
53{ 53{
54 while (*cp) 54 while (*cp)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 6b8aa6a852be..328e31cc6854 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -265,7 +265,7 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
265/* 265/*
266 * Some instructions as assembly 266 * Some instructions as assembly
267 */ 267 */
268extern __inline__ int 268static inline int
269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
270{ 270{
271 int cc; 271 int cc;
@@ -300,7 +300,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
300 return cc; 300 return cc;
301} 301}
302 302
303extern __inline__ int 303static inline int
304do_siga_input(unsigned int irq, unsigned int mask) 304do_siga_input(unsigned int irq, unsigned int mask)
305{ 305{
306 int cc; 306 int cc;
@@ -334,7 +334,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
334 return cc; 334 return cc;
335} 335}
336 336
337extern __inline__ int 337static inline int
338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) 338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
339{ 339{
340 int cc; 340 int cc;
@@ -401,7 +401,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
401 return cc; 401 return cc;
402} 402}
403 403
404extern __inline__ unsigned long 404static inline unsigned long
405do_clear_global_summary(void) 405do_clear_global_summary(void)
406{ 406{
407 407
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 04c2ef778ec6..4010f2bb85af 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -37,7 +37,6 @@
37#include <linux/kobject_uevent.h> 37#include <linux/kobject_uevent.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/syscalls.h> 39#include <linux/syscalls.h>
40#include <linux/version.h>
41#include "z90crypt.h" 40#include "z90crypt.h"
42#include "z90common.h" 41#include "z90common.h"
43 42
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 1a1c3decea72..6b63d21612ec 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -88,7 +88,6 @@
88#include <linux/tcp.h> 88#include <linux/tcp.h>
89#include <linux/timer.h> 89#include <linux/timer.h>
90#include <linux/types.h> 90#include <linux/types.h>
91#include <linux/version.h>
92 91
93#include "cu3088.h" 92#include "cu3088.h"
94#include "claw.h" 93#include "claw.h"
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index 1b8a7e7c34f3..5b98253be7aa 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -140,7 +140,7 @@ fsm_record_history(fsm_instance *fi, int state, int event);
140 * 1 if current state or event is out of range 140 * 1 if current state or event is out of range
141 * !0 if state and event in range, but no action defined. 141 * !0 if state and event in range, but no action defined.
142 */ 142 */
143extern __inline__ int 143static inline int
144fsm_event(fsm_instance *fi, int event, void *arg) 144fsm_event(fsm_instance *fi, int event, void *arg)
145{ 145{
146 fsm_function_t r; 146 fsm_function_t r;
@@ -188,7 +188,7 @@ fsm_event(fsm_instance *fi, int event, void *arg)
188 * @param fi Pointer to FSM 188 * @param fi Pointer to FSM
189 * @param state The new state for this FSM. 189 * @param state The new state for this FSM.
190 */ 190 */
191extern __inline__ void 191static inline void
192fsm_newstate(fsm_instance *fi, int newstate) 192fsm_newstate(fsm_instance *fi, int newstate)
193{ 193{
194 atomic_set(&fi->state,newstate); 194 atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
208 * 208 *
209 * @return The current state of the FSM. 209 * @return The current state of the FSM.
210 */ 210 */
211extern __inline__ int 211static inline int
212fsm_getstate(fsm_instance *fi) 212fsm_getstate(fsm_instance *fi)
213{ 213{
214 return atomic_read(&fi->state); 214 return atomic_read(&fi->state);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 4eaa70179182..d9ea7ed2e46e 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -88,7 +88,7 @@ struct crw {
88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ 88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */ 89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
90 90
91extern __inline__ int stcrw(struct crw *pcrw ) 91static inline int stcrw(struct crw *pcrw )
92{ 92{
93 int ccode; 93 int ccode;
94 94
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 071ae24be892..fd2cc7782f76 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -407,7 +407,7 @@ static long wd_compat_ioctl(struct file *file, unsigned int cmd,
407 case WIOCGSTAT: 407 case WIOCGSTAT:
408 lock_kernel(); 408 lock_kernel();
409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg); 409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
410 lock_kernel(); 410 unlock_kernel();
411 break; 411 break;
412 /* everything else is handled by the generic compat layer */ 412 /* everything else is handled by the generic compat layer */
413 default: 413 default:
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 39f54213a6d5..2c86a4b809cd 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -161,7 +161,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 writeb(regs, d7s_regs); 161 writeb(regs, d7s_regs);
162 break; 162 break;
163 }; 163 };
164 lock_kernel(); 164 unlock_kernel();
165 165
166 return error; 166 return error;
167} 167}
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 5028ac214326..383a95f34a0d 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -596,6 +596,8 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
596 lock_kernel(); 596 lock_kernel();
597 break; 597 break;
598 } 598 }
599
600 return rval;
599} 601}
600 602
601static int openprom_open(struct inode * inode, struct file * file) 603static int openprom_open(struct inode * inode, struct file * file)
@@ -623,6 +625,7 @@ static struct file_operations openprom_fops = {
623 .owner = THIS_MODULE, 625 .owner = THIS_MODULE,
624 .llseek = no_llseek, 626 .llseek = no_llseek,
625 .ioctl = openprom_ioctl, 627 .ioctl = openprom_ioctl,
628 .compat_ioctl = openprom_compat_ioctl,
626 .open = openprom_open, 629 .open = openprom_open,
627 .release = openprom_release, 630 .release = openprom_release,
628}; 631};
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..5774bdd0e26f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,6 +210,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
210 } 210 }
211} 211}
212 212
213static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
214 unsigned long arg)
215{
216 int rval = -ENOIOCTLCMD;
217
218 switch (cmd) {
219 /*
220 * These two are specific to this driver, the generic rtc ioctls
221 * are hanlded elsewhere.
222 */
223 case RTCGET:
224 case RTCSET:
225 lock_kernel();
226 rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
227 unlock_kernel();
228 break;
229 }
230
231 return rval;
232}
233
213static int rtc_open(struct inode *inode, struct file *file) 234static int rtc_open(struct inode *inode, struct file *file)
214{ 235{
215 int ret; 236 int ret;
@@ -237,6 +258,7 @@ static struct file_operations rtc_fops = {
237 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
238 .llseek = no_llseek, 259 .llseek = no_llseek,
239 .ioctl = rtc_ioctl, 260 .ioctl = rtc_ioctl,
261 .compat_ioctl = rtc_compat_ioctl,
240 .open = rtc_open, 262 .open = rtc_open,
241 .release = rtc_release, 263 .release = rtc_release,
242}; 264};
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 98bad773f240..4f81fc39ec57 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -54,7 +54,6 @@
54#ifndef _3W_XXXX_H 54#ifndef _3W_XXXX_H
55#define _3W_XXXX_H 55#define _3W_XXXX_H
56 56
57#include <linux/version.h>
58#include <linux/types.h> 57#include <linux/types.h>
59 58
60/* AEN strings */ 59/* AEN strings */
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 1589007e5a2a..54996eaae979 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 10f90d39374a..10c470e7d316 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -42,8 +42,8 @@
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
46#include <scsi/scsi_cmnd.h>
47#include <linux/libata.h> 47#include <linux/libata.h>
48#include <asm/io.h> 48#include <asm/io.h>
49 49
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 052c6619accc..bc44222d6cc3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -49,7 +49,6 @@
49#include <linux/ioport.h> 49#include <linux/ioport.h>
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/smp_lock.h> 51#include <linux/smp_lock.h>
52#include <linux/version.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
54#include <linux/module.h> 53#include <linux/module.h>
55#include <linux/slab.h> 54#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..f2a95447142c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -66,7 +66,6 @@
66#include <linux/ioport.h> 66#include <linux/ioport.h>
67#include <linux/pci.h> 67#include <linux/pci.h>
68#include <linux/smp_lock.h> 68#include <linux/smp_lock.h>
69#include <linux/version.h>
70#include <linux/interrupt.h> 69#include <linux/interrupt.h>
71#include <linux/module.h> 70#include <linux/module.h>
72#include <linux/slab.h> 71#include <linux/slab.h>
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index e02db80cab33..c0844fa32c5d 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/zorro.h> 15#include <linux/zorro.h>
17#include <linux/stat.h> 16#include <linux/stat.h>
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 7fc8873de0b6..a1bd8d95623c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -46,7 +46,6 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/device.h> 48#include <linux/device.h>
49#include "scsi.h"
50#include <scsi/scsi_host.h> 49#include <scsi/scsi_host.h>
51#include <linux/libata.h> 50#include <linux/libata.h>
52 51
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 3c43928ab402..2958b8c2bfb7 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11#include <linux/zorro.h> 10#include <linux/zorro.h>
12 11
13#include <asm/setup.h> 12#include <asm/setup.h>
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 4b310cb7c93a..5b154498056d 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 05ecc911e94c..b60c1b9270f1 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -18,12 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#ifndef LINUX_VERSION_CODE
22#include <linux/version.h>
23#endif
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
25#error "This driver works only with kernel 2.5.45 or higher!"
26#endif
27#include <linux/module.h> 21#include <linux/module.h>
28#include <linux/kernel.h> 22#include <linux/kernel.h>
29#include <linux/types.h> 23#include <linux/types.h>
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 179140f48a91..f46c382e5599 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -50,6 +50,7 @@
50#ifndef _IPS_H_ 50#ifndef _IPS_H_
51 #define _IPS_H_ 51 #define _IPS_H_
52 52
53#include <linux/version.h>
53 #include <asm/uaccess.h> 54 #include <asm/uaccess.h>
54 #include <asm/io.h> 55 #include <asm/io.h>
55 56
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1c1a7caf785e..a74b4071a662 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -51,8 +51,8 @@
51#include <linux/jiffies.h> 51#include <linux/jiffies.h>
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <scsi/scsi.h> 53#include <scsi/scsi.h>
54#include "scsi.h"
55#include "scsi_priv.h" 54#include "scsi_priv.h"
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_host.h> 56#include <scsi/scsi_host.h>
57#include <linux/libata.h> 57#include <linux/libata.h>
58#include <asm/io.h> 58#include <asm/io.h>
@@ -1144,7 +1144,7 @@ retry:
1144 * ATA software reset (SRST, the default) does not appear 1144 * ATA software reset (SRST, the default) does not appear
1145 * to have this problem. 1145 * to have this problem.
1146 */ 1146 */
1147 if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) { 1147 if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
1148 u8 err = qc->tf.feature; 1148 u8 err = qc->tf.feature;
1149 if (err & ATA_ABORTED) { 1149 if (err & ATA_ABORTED) {
1150 dev->class = ATA_DEV_ATAPI; 1150 dev->class = ATA_DEV_ATAPI;
@@ -2713,7 +2713,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
2713/** 2713/**
2714 * ata_poll_qc_complete - turn irq back on and finish qc 2714 * ata_poll_qc_complete - turn irq back on and finish qc
2715 * @qc: Command to complete 2715 * @qc: Command to complete
2716 * @drv_stat: ATA status register content 2716 * @err_mask: ATA status register content
2717 * 2717 *
2718 * LOCKING: 2718 * LOCKING:
2719 * None. (grabs host lock) 2719 * None. (grabs host lock)
@@ -2747,7 +2747,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2747 u8 status; 2747 u8 status;
2748 unsigned int poll_state = HSM_ST_UNKNOWN; 2748 unsigned int poll_state = HSM_ST_UNKNOWN;
2749 unsigned int reg_state = HSM_ST_UNKNOWN; 2749 unsigned int reg_state = HSM_ST_UNKNOWN;
2750 const unsigned int tmout_state = HSM_ST_TMOUT;
2751 2750
2752 switch (ap->hsm_task_state) { 2751 switch (ap->hsm_task_state) {
2753 case HSM_ST: 2752 case HSM_ST:
@@ -2768,7 +2767,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2768 status = ata_chk_status(ap); 2767 status = ata_chk_status(ap);
2769 if (status & ATA_BUSY) { 2768 if (status & ATA_BUSY) {
2770 if (time_after(jiffies, ap->pio_task_timeout)) { 2769 if (time_after(jiffies, ap->pio_task_timeout)) {
2771 ap->hsm_task_state = tmout_state; 2770 ap->hsm_task_state = HSM_ST_TMOUT;
2772 return 0; 2771 return 0;
2773 } 2772 }
2774 ap->hsm_task_state = poll_state; 2773 ap->hsm_task_state = poll_state;
@@ -3478,7 +3477,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
3478/** 3477/**
3479 * ata_qc_complete - Complete an active ATA command 3478 * ata_qc_complete - Complete an active ATA command
3480 * @qc: Command to complete 3479 * @qc: Command to complete
3481 * @drv_stat: ATA Status register contents 3480 * @err_mask: ATA Status register contents
3482 * 3481 *
3483 * Indicate to the mid and upper layers that an ATA 3482 * Indicate to the mid and upper layers that an ATA
3484 * command has completed, with either an ok or not-ok status. 3483 * command has completed, with either an ok or not-ok status.
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index eb604b0a8990..bb30fcdc9297 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,9 +37,9 @@
37#include <linux/blkdev.h> 37#include <linux/blkdev.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <scsi/scsi.h> 39#include <scsi/scsi.h>
40#include "scsi.h"
41#include <scsi/scsi_host.h> 40#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h> 41#include <scsi/scsi_device.h>
42#include <scsi/scsi_request.h>
43#include <linux/libata.h> 43#include <linux/libata.h>
44#include <linux/hdreg.h> 44#include <linux/hdreg.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -131,7 +131,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
131 131
132/** 132/**
133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl 133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
134 * @dev: Device to whom we are issuing command 134 * @scsidev: Device to which we are issuing command
135 * @arg: User provided data for issuing command 135 * @arg: User provided data for issuing command
136 * 136 *
137 * LOCKING: 137 * LOCKING:
@@ -217,7 +217,7 @@ error:
217 217
218/** 218/**
219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl 219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
220 * @dev: Device to whom we are issuing command 220 * @scsidev: Device to which we are issuing command
221 * @arg: User provided data for issuing command 221 * @arg: User provided data for issuing command
222 * 222 *
223 * LOCKING: 223 * LOCKING:
@@ -416,6 +416,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
416 416
417/** 417/**
418 * ata_to_sense_error - convert ATA error to SCSI error 418 * ata_to_sense_error - convert ATA error to SCSI error
419 * @id: ATA device number
419 * @drv_stat: value contained in ATA status register 420 * @drv_stat: value contained in ATA status register
420 * @drv_err: value contained in ATA error register 421 * @drv_err: value contained in ATA error register
421 * @sk: the sense key we'll fill out 422 * @sk: the sense key we'll fill out
@@ -2231,7 +2232,7 @@ ata_scsi_map_proto(u8 byte1)
2231/** 2232/**
2232 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 2233 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
2233 * @qc: command structure to be initialized 2234 * @qc: command structure to be initialized
2234 * @cmd: SCSI command to convert 2235 * @scsicmd: SCSI command to convert
2235 * 2236 *
2236 * Handles either 12 or 16-byte versions of the CDB. 2237 * Handles either 12 or 16-byte versions of the CDB.
2237 * 2238 *
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 5accdee9bbfb..4675343228ad 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/version.h>
29#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
31#include <asm/semaphore.h> 30#include <asm/semaphore.h>
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
index 7e36c46e7c43..eb8c390a0fa3 100644
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -18,7 +18,6 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/moduleparam.h> 22#include <linux/moduleparam.h>
24#include <linux/pci.h> 23#include <linux/pci.h>
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 2463f47adfda..3c32e69afcd9 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/version.h>
30#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/spinlock.h> 31#include <linux/spinlock.h>
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index c44382d6ae5d..cb367c2c5c78 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/interrupt.h> 5#include <linux/interrupt.h>
7 6
8#include <asm/page.h> 7#include <asm/page.h>
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index 9b43dc4148f5..890e9e232dab 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11 10
12#include <asm/page.h> 11#include <asm/page.h>
13#include <asm/pgtable.h> 12#include <asm/pgtable.h>
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 5664398fa0ad..5addf9fb1e15 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -16,6 +16,7 @@
16#ifndef _NSP32_H 16#ifndef _NSP32_H
17#define _NSP32_H 17#define _NSP32_H
18 18
19#include <linux/version.h>
19//#define NSP32_DEBUG 9 20//#define NSP32_DEBUG 9
20 21
21/* 22/*
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index f945a4232e5d..0ebd8ce9e1de 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -26,9 +26,6 @@
26#ifndef PSI_EIDE_SCSIOP 26#ifndef PSI_EIDE_SCSIOP
27#define PSI_EIDE_SCSIOP 1 27#define PSI_EIDE_SCSIOP 1
28 28
29#ifndef LINUX_VERSION_CODE
30#include <linux/version.h>
31#endif
32#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) 29#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
33 30
34/************************************************/ 31/************************************************/
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 340ef38b4521..78b4ff117af6 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -41,7 +41,6 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/device.h> 43#include <linux/device.h>
44#include "scsi.h"
45#include <scsi/scsi_host.h> 44#include <scsi/scsi_host.h>
46#include <asm/io.h> 45#include <asm/io.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 1066c2610eb4..93d55233af7b 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -30,8 +30,8 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include "scsi.h"
34#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
34#include <scsi/scsi_cmnd.h>
35#include <linux/libata.h> 35#include <linux/libata.h>
36#include <asm/io.h> 36#include <asm/io.h>
37 37
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index f57aa2607918..37a4fae95ed4 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -62,7 +62,6 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/device.h> 64#include <linux/device.h>
65#include "scsi.h"
66#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
67#include <linux/libata.h> 66#include <linux/libata.h>
68 67
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 0bfb82b669d5..9edc9d91efc3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index c9aed15c8f4d..d274ab235781 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -36,7 +36,6 @@
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include "scsi.h"
40#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
41#include <asm/io.h> 40#include <asm/io.h>
42#include <linux/libata.h> 41#include <linux/libata.h>
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 6c986a0824b1..d0e3c3c6c25f 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -42,7 +42,6 @@
42#include <linux/delay.h> 42#include <linux/delay.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48 47
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 0c2d2fd0ec76..4682a50650b4 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -37,7 +37,7 @@
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
40#include "scsi.h" 40#include <scsi/scsi_cmnd.h>
41#include <linux/libata.h> 41#include <linux/libata.h>
42#include <asm/io.h> 42#include <asm/io.h>
43 43
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 223c835842e0..42d7c4e92501 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -39,7 +39,6 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
44#include <linux/libata.h> 43#include <linux/libata.h>
45 44
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 86644f91f898..9895d1caefcf 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/interrupt.h> 46#include <linux/interrupt.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include "scsi.h"
49#include <scsi/scsi_host.h> 48#include <scsi/scsi_host.h>
50#include <linux/libata.h> 49#include <linux/libata.h>
51 50
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 8e79745e4e9f..d5a38784352b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 8c1d71495bd5..cf0baaa4e045 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include "scsi.h"
37#include <scsi/scsi_host.h> 36#include <scsi/scsi_host.h>
38#include <linux/libata.h> 37#include <linux/libata.h>
39 38
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 09d3d96de0c3..ab19d2ba2a4b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -42,7 +42,6 @@
42#include <linux/blkdev.h> 42#include <linux/blkdev.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48#include <asm/io.h> 47#include <asm/io.h>
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index bbc3d8abbd64..ce8a2fd7da84 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -43,7 +43,6 @@
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/dma-mapping.h> 44#include <linux/dma-mapping.h>
45#include <linux/device.h> 45#include <linux/device.h>
46#include "scsi.h"
47#include <scsi/scsi_host.h> 46#include <scsi/scsi_host.h>
48#include <linux/libata.h> 47#include <linux/libata.h>
49 48
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 9eb08b15c0b1..3ded9daaf4a0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -48,10 +48,6 @@
48 48
49#include <linux/stat.h> 49#include <linux/stat.h>
50 50
51#ifndef LINUX_VERSION_CODE
52#include <linux/version.h>
53#endif
54
55#include "scsi_logging.h" 51#include "scsi_logging.h"
56#include "scsi_debug.h" 52#include "scsi_debug.h"
57 53
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 62e3f340cc52..72ec59456e69 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -68,10 +68,6 @@ static int sg_proc_init(void);
68static void sg_proc_cleanup(void); 68static void sg_proc_cleanup(void);
69#endif 69#endif
70 70
71#ifndef LINUX_VERSION_CODE
72#include <linux/version.h>
73#endif /* LINUX_VERSION_CODE */
74
75#define SG_ALLOW_DIO_DEF 0 71#define SG_ALLOW_DIO_DEF 0
76#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ 72#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
77 73
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 0a0d8a908c74..bf2ceb54354c 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -15,7 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/version.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5754445fb36a..fd63add6a577 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -77,7 +77,6 @@
77#include <linux/sched.h> 77#include <linux/sched.h>
78#include <linux/string.h> 78#include <linux/string.h>
79#include <linux/delay.h> 79#include <linux/delay.h>
80#include <linux/version.h>
81#include <linux/init.h> 80#include <linux/init.h>
82#include <linux/blkdev.h> 81#include <linux/blkdev.h>
83#include <asm/irq.h> 82#include <asm/irq.h>
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 51e3f7f6597b..fbea4541c234 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -40,7 +40,6 @@
40 *****************************************************************************/ 40 *****************************************************************************/
41#define IXJ_VERSION 3031 41#define IXJ_VERSION 3031
42 42
43#include <linux/version.h>
44#include <linux/types.h> 43#include <linux/types.h>
45 44
46#include <linux/ixjuser.h> 45#include <linux/ixjuser.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 975ace3f5b1e..904519085334 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -49,7 +49,6 @@
49#include <linux/timer.h> 49#include <linux/timer.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/version.h>
53#include <linux/platform_device.h> 52#include <linux/platform_device.h>
54#include <linux/usb.h> 53#include <linux/usb.h>
55#include <linux/usb_gadget.h> 54#include <linux/usb_gadget.h>
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1bb455c045a9..9b2e6f7cbb8b 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -29,7 +29,6 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/version.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index ee9cd7869d92..510d28a924db 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -32,7 +32,6 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/version.h>
36#include <linux/errno.h> 35#include <linux/errno.h>
37#include <linux/delay.h> 36#include <linux/delay.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 06b6eba925b5..9689efeb364c 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,7 +28,6 @@
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/version.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/list.h> 32#include <linux/list.h>
34#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index a8267cf17db4..0eaabeb37ac3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -14,7 +14,6 @@
14#include <linux/unistd.h> 14#include <linux/unistd.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/list.h> 17#include <linux/list.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20 19
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index b77e65c03659..5524fd70210b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -62,6 +62,7 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
66 67
67#include "pwc.h" 68#include "pwc.h"
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 267869dab185..6dd76bb3dff1 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -25,8 +25,6 @@
25#ifndef PWC_H 25#ifndef PWC_H
26#define PWC_H 26#define PWC_H
27 27
28#include <linux/version.h>
29
30#include <linux/config.h> 28#include <linux/config.h>
31#include <linux/module.h> 29#include <linux/module.h>
32#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index f36c0b6c6e36..67612c81cb9f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -25,7 +25,6 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/ 26 ***************************************************************************/
27 27
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/kmod.h> 30#include <linux/kmod.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index c946c9a538a0..41ef2b606751 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/signal.h> 42#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 401ff21d7881..1d7a77cc7c4a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -37,6 +37,7 @@
37#ifndef _SISUSB_H_ 37#ifndef _SISUSB_H_
38#define _SISUSB_H_ 38#define _SISUSB_H_
39 39
40#include <linux/version.h>
40#ifdef CONFIG_COMPAT 41#ifdef CONFIG_COMPAT
41#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) 42#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
42#include <linux/ioctl32.h> 43#include <linux/ioctl32.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 24584463553d..be5c1a25ae21 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,7 +48,6 @@
48 */ 48 */
49 49
50#include <linux/config.h> 50#include <linux/config.h>
51#include <linux/version.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/kernel.h> 52#include <linux/kernel.h>
54#include <linux/signal.h> 53#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index f28bc240f9b6..044fa4482f9f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 44b6ca290ce3..25b6ca6ad081 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -593,38 +593,6 @@ config FB_EPSON1355
593 framebuffer. Product specs at 593 framebuffer. Product specs at
594 <http://www.erd.epson.com/vdc/html/products.htm>. 594 <http://www.erd.epson.com/vdc/html/products.htm>.
595 595
596config FB_E1356
597 tristate "Epson SED1356 framebuffer support"
598 depends on FB && EXPERIMENTAL && PCI && MIPS
599
600config PB1000_CRT
601 bool "Use CRT on Pb1000 (J65)"
602 depends on MIPS_PB1000=y && FB_E1356
603
604config PB1000_NTSC
605 bool "Use Compsite NTSC on Pb1000 (J63)"
606 depends on MIPS_PB1000=y && FB_E1356
607
608config PB1000_TFT
609 bool "Use TFT Panel on Pb1000 (J64)"
610 depends on MIPS_PB1000=y && FB_E1356
611
612config PB1500_CRT
613 bool "Use CRT on Pb1500 " if MIPS_PB1500=y
614 depends on FB_E1356
615
616config PB1500_CRT
617 prompt "Use CRT on Pb1100 "
618 depends on FB_E1356 && MIPS_PB1100=y
619
620config PB1500_TFT
621 bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
622 depends on FB_E1356
623
624config PB1500_TFT
625 prompt "Use TFT Panel on Pb1100 "
626 depends on FB_E1356 && MIPS_PB1100=y
627
628config FB_S1D13XXX 596config FB_S1D13XXX
629 tristate "Epson S1D13XXX framebuffer support" 597 tristate "Epson S1D13XXX framebuffer support"
630 depends on FB 598 depends on FB
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 467a1d7ebbde..a3c2c45e29e0 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -518,7 +518,7 @@ static struct amba_driver clcd_driver = {
518 .id_table = clcdfb_id_table, 518 .id_table = clcdfb_id_table,
519}; 519};
520 520
521int __init amba_clcdfb_init(void) 521static int __init amba_clcdfb_init(void)
522{ 522{
523 if (fb_get_options("ambafb", NULL)) 523 if (fb_get_options("ambafb", NULL))
524 return -ENODEV; 524 return -ENODEV;
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index acc81cb01d56..9d5015e99372 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 470e6f0ee4dd..68c690605aa7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index da664cea7eca..a7770c4f17d0 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -80,10 +80,12 @@ static u32 cfb_tab32[] = {
80#define LEFT_POS(bpp) (32 - bpp) 80#define LEFT_POS(bpp) (32 - bpp)
81#define SHIFT_HIGH(val, bits) ((val) >> (bits)) 81#define SHIFT_HIGH(val, bits) ((val) >> (bits))
82#define SHIFT_LOW(val, bits) ((val) << (bits)) 82#define SHIFT_LOW(val, bits) ((val) << (bits))
83#define BIT_NR(b) (7 - (b))
83#else 84#else
84#define LEFT_POS(bpp) (0) 85#define LEFT_POS(bpp) (0)
85#define SHIFT_HIGH(val, bits) ((val) << (bits)) 86#define SHIFT_HIGH(val, bits) ((val) << (bits))
86#define SHIFT_LOW(val, bits) ((val) >> (bits)) 87#define SHIFT_LOW(val, bits) ((val) >> (bits))
88#define BIT_NR(b) (b)
87#endif 89#endif
88 90
89static inline void color_imageblit(const struct fb_image *image, 91static inline void color_imageblit(const struct fb_image *image,
@@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
177 179
178 while (j--) { 180 while (j--) {
179 l--; 181 l--;
180 color = (*s & (1 << l)) ? fgcolor : bgcolor; 182 color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
181 color <<= LEFT_POS(bpp); 183 color <<= LEFT_POS(bpp);
182 val |= SHIFT_HIGH(color, shift); 184 val |= SHIFT_HIGH(color, shift);
183 185
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fadf7c5d216e..94c5f1392cce 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -101,6 +101,16 @@ config FRAMEBUFFER_CONSOLE
101 help 101 help
102 Low-level framebuffer-based console driver. 102 Low-level framebuffer-based console driver.
103 103
104config FRAMEBUFFER_CONSOLE_ROTATION
105 bool "Framebuffer Console Rotation"
106 depends on FRAMEBUFFER_CONSOLE
107 help
108 Enable display rotation for the framebuffer console. This is done
109 in software and may be significantly slower than a normally oriented
110 display. Note that the rotation is done at the console level only
111 such that other users of the framebuffer will remain normally
112 oriented.
113
104config STI_CONSOLE 114config STI_CONSOLE
105 tristate "STI text console" 115 tristate "STI text console"
106 depends on PARISC 116 depends on PARISC
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 5222628accce..fed600c9ca55 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -31,6 +31,10 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
31ifeq ($(CONFIG_FB_TILEBLITTING),y) 31ifeq ($(CONFIG_FB_TILEBLITTING),y)
32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o 32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
33endif 33endif
34ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
35obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
36 fbcon_ccw.o
37endif
34 38
35obj-$(CONFIG_FB_STI) += sticore.o font.o 39obj-$(CONFIG_FB_STI) += sticore.o font.o
36 40
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 67857b3cfc8b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25#define FBCON_ATTRIBUTE_UNDERLINE 1
26#define FBCON_ATTRIBUTE_REVERSE 2
27#define FBCON_ATTRIBUTE_BOLD 4
28
29static inline int real_y(struct display *p, int ypos)
30{
31 int rows = p->vrows;
32
33 ypos += p->yscroll;
34 return ypos < rows ? ypos : ypos - rows;
35}
36
37
38static inline int get_attribute(struct fb_info *info, u16 c)
39{
40 int attribute = 0;
41
42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c))
46 attribute |= FBCON_ATTRIBUTE_REVERSE;
47 if (attr_bold(c))
48 attribute |= FBCON_ATTRIBUTE_BOLD;
49 }
50
51 return attribute;
52}
53
54static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static inline void update_attr(u8 *dst, u8 *src, int attribute,
55 struct vc_data *vc) 26 struct vc_data *vc)
56{ 27{
@@ -418,6 +389,18 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
418 ops->cursor_reset = 0; 389 ops->cursor_reset = 0;
419} 390}
420 391
392static int bit_update_start(struct fb_info *info)
393{
394 struct fbcon_ops *ops = info->fbcon_par;
395 int err;
396
397 err = fb_pan_display(info, &ops->var);
398 ops->var.xoffset = info->var.xoffset;
399 ops->var.yoffset = info->var.yoffset;
400 ops->var.vmode = info->var.vmode;
401 return err;
402}
403
421void fbcon_set_bitops(struct fbcon_ops *ops) 404void fbcon_set_bitops(struct fbcon_ops *ops)
422{ 405{
423 ops->bmove = bit_bmove; 406 ops->bmove = bit_bmove;
@@ -425,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
425 ops->putcs = bit_putcs; 408 ops->putcs = bit_putcs;
426 ops->clear_margins = bit_clear_margins; 409 ops->clear_margins = bit_clear_margins;
427 ops->cursor = bit_cursor; 410 ops->cursor = bit_cursor;
411 ops->update_start = bit_update_start;
412 ops->rotate_font = NULL;
413
414 if (ops->rotate)
415 fbcon_set_rotate(ops);
428} 416}
429 417
430EXPORT_SYMBOL(fbcon_set_bitops); 418EXPORT_SYMBOL(fbcon_set_bitops);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3cf1b61ff1f8..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
107}; 107};
108 108
109struct display fb_display[MAX_NR_CONSOLES]; 109struct display fb_display[MAX_NR_CONSOLES];
110EXPORT_SYMBOL(fb_display);
111
110static signed char con2fb_map[MAX_NR_CONSOLES]; 112static signed char con2fb_map[MAX_NR_CONSOLES];
111static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 113static signed char con2fb_map_boot[MAX_NR_CONSOLES];
112static int logo_height; 114static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
130/* current fb_info */ 132/* current fb_info */
131static int info_idx = -1; 133static int info_idx = -1;
132 134
135/* console rotation */
136static int rotate;
137
133static const struct consw fb_con; 138static const struct consw fb_con;
134 139
135#define CM_SOFTBACK (8) 140#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
176/* 181/*
177 * Internal routines 182 * Internal routines
178 */ 183 */
179static __inline__ int real_y(struct display *p, int ypos);
180static __inline__ void ywrap_up(struct vc_data *vc, int count); 184static __inline__ void ywrap_up(struct vc_data *vc, int count);
181static __inline__ void ywrap_down(struct vc_data *vc, int count); 185static __inline__ void ywrap_down(struct vc_data *vc, int count);
182static __inline__ void ypan_up(struct vc_data *vc, int count); 186static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
189 int unit); 193 int unit);
190static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 194static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
191 int line, int count, int dy); 195 int line, int count, int dy);
196static void fbcon_modechanged(struct fb_info *info);
197static void fbcon_set_all_vcs(struct fb_info *info);
192 198
193#ifdef CONFIG_MAC 199#ifdef CONFIG_MAC
194/* 200/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
203} 209}
204#endif 210#endif
205 211
212#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
213static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
214{
215 struct fbcon_ops *ops = info->fbcon_par;
216
217 if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
218 p->con_rotate < 4)
219 ops->rotate = p->con_rotate;
220 else
221 ops->rotate = 0;
222}
223
224static void fbcon_rotate(struct fb_info *info, u32 rotate)
225{
226 struct fbcon_ops *ops= info->fbcon_par;
227 struct fb_info *fb_info;
228
229 if (!ops || ops->currcon == -1)
230 return;
231
232 fb_info = registered_fb[con2fb_map[ops->currcon]];
233
234 if (info == fb_info) {
235 struct display *p = &fb_display[ops->currcon];
236
237 if (rotate < 4)
238 p->con_rotate = rotate;
239 else
240 p->con_rotate = 0;
241
242 fbcon_modechanged(info);
243 }
244}
245
246static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
247{
248 struct fbcon_ops *ops = info->fbcon_par;
249 struct vc_data *vc;
250 struct display *p;
251 int i;
252
253 if (!ops || ops->currcon < 0 || rotate > 3)
254 return;
255
256 for (i = 0; i < MAX_NR_CONSOLES; i++) {
257 vc = vc_cons[i].d;
258 if (!vc || vc->vc_mode != KD_TEXT ||
259 registered_fb[con2fb_map[i]] != info)
260 continue;
261
262 p = &fb_display[vc->vc_num];
263 p->con_rotate = rotate;
264 }
265
266 fbcon_set_all_vcs(info);
267}
268#else
269static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
270{
271 struct fbcon_ops *ops = info->fbcon_par;
272
273 ops->rotate = FB_ROTATE_UR;
274}
275
276static void fbcon_rotate(struct fb_info *info, u32 rotate)
277{
278 return;
279}
280
281static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
282{
283 return;
284}
285#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
286
287static int fbcon_get_rotate(struct fb_info *info)
288{
289 struct fbcon_ops *ops = info->fbcon_par;
290
291 return (ops) ? ops->rotate : 0;
292}
293
206static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 294static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
207{ 295{
208 struct fbcon_ops *ops = info->fbcon_par; 296 struct fbcon_ops *ops = info->fbcon_par;
@@ -422,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
422 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 510 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
423 fbcon_is_default = 0; 511 fbcon_is_default = 0;
424 } 512 }
513
514 if (!strncmp(options, "rotate:", 7)) {
515 options += 7;
516 if (*options)
517 rotate = simple_strtoul(options, &options, 0);
518 if (rotate > 3)
519 rotate = 0;
520 }
425 } 521 }
426 return 0; 522 return 0;
427} 523}
@@ -480,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
480 int cols, int rows, int new_cols, int new_rows) 576 int cols, int rows, int new_cols, int new_rows)
481{ 577{
482 /* Need to make room for the logo */ 578 /* Need to make room for the logo */
579 struct fbcon_ops *ops = info->fbcon_par;
483 int cnt, erase = vc->vc_video_erase_char, step; 580 int cnt, erase = vc->vc_video_erase_char, step;
484 unsigned short *save = NULL, *r, *q; 581 unsigned short *save = NULL, *r, *q;
485 582
@@ -489,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
489 */ 586 */
490 if (fb_get_color_depth(&info->var, &info->fix) == 1) 587 if (fb_get_color_depth(&info->var, &info->fix) == 1)
491 erase &= ~0x400; 588 erase &= ~0x400;
492 logo_height = fb_prepare_logo(info); 589 logo_height = fb_prepare_logo(info, ops->rotate);
493 logo_lines = (logo_height + vc->vc_font.height - 1) / 590 logo_lines = (logo_height + vc->vc_font.height - 1) /
494 vc->vc_font.height; 591 vc->vc_font.height;
495 q = (unsigned short *) (vc->vc_origin + 592 q = (unsigned short *) (vc->vc_origin +
@@ -558,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
558 655
559 if ((info->flags & FBINFO_MISC_TILEBLITTING)) 656 if ((info->flags & FBINFO_MISC_TILEBLITTING))
560 fbcon_set_tileops(vc, info, p, ops); 657 fbcon_set_tileops(vc, info, p, ops);
561 else 658 else {
659 struct display *disp;
660
661 disp = (p) ? p : &fb_display[vc->vc_num];
662 fbcon_set_rotation(info, disp);
562 fbcon_set_bitops(ops); 663 fbcon_set_bitops(ops);
664 }
563} 665}
564#else 666#else
565static void set_blitting_type(struct vc_data *vc, struct fb_info *info, 667static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
566 struct display *p) 668 struct display *p)
567{ 669{
568 struct fbcon_ops *ops = info->fbcon_par; 670 struct fbcon_ops *ops = info->fbcon_par;
671 struct display *disp;
569 672
570 info->flags &= ~FBINFO_MISC_TILEBLITTING; 673 info->flags &= ~FBINFO_MISC_TILEBLITTING;
674 disp = (p) ? p : &fb_display[vc->vc_num];
675 fbcon_set_rotation(info, disp);
571 fbcon_set_bitops(ops); 676 fbcon_set_bitops(ops);
572} 677}
573#endif /* CONFIG_MISC_TILEBLITTING */ 678#endif /* CONFIG_MISC_TILEBLITTING */
@@ -627,6 +732,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
627 fbcon_del_cursor_timer(oldinfo); 732 fbcon_del_cursor_timer(oldinfo);
628 kfree(ops->cursor_state.mask); 733 kfree(ops->cursor_state.mask);
629 kfree(ops->cursor_data); 734 kfree(ops->cursor_data);
735 kfree(ops->fontbuffer);
630 kfree(oldinfo->fbcon_par); 736 kfree(oldinfo->fbcon_par);
631 oldinfo->fbcon_par = NULL; 737 oldinfo->fbcon_par = NULL;
632 module_put(oldinfo->fbops->owner); 738 module_put(oldinfo->fbops->owner);
@@ -827,7 +933,9 @@ static const char *fbcon_startup(void)
827 memset(ops, 0, sizeof(struct fbcon_ops)); 933 memset(ops, 0, sizeof(struct fbcon_ops));
828 ops->currcon = -1; 934 ops->currcon = -1;
829 ops->graphics = 1; 935 ops->graphics = 1;
936 ops->cur_rotate = -1;
830 info->fbcon_par = ops; 937 info->fbcon_par = ops;
938 p->con_rotate = rotate;
831 set_blitting_type(vc, info, NULL); 939 set_blitting_type(vc, info, NULL);
832 940
833 if (info->fix.type != FB_TYPE_TEXT) { 941 if (info->fix.type != FB_TYPE_TEXT) {
@@ -866,8 +974,10 @@ static const char *fbcon_startup(void)
866 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 974 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
867 } 975 }
868 976
869 cols = info->var.xres / vc->vc_font.width; 977 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
870 rows = info->var.yres / vc->vc_font.height; 978 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
979 cols /= vc->vc_font.width;
980 rows /= vc->vc_font.height;
871 vc_resize(vc, cols, rows); 981 vc_resize(vc, cols, rows);
872 982
873 DPRINTK("mode: %s\n", info->fix.id); 983 DPRINTK("mode: %s\n", info->fix.id);
@@ -953,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
953 (info->fix.type == FB_TYPE_TEXT)) 1063 (info->fix.type == FB_TYPE_TEXT))
954 logo = 0; 1064 logo = 0;
955 1065
956 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
957
958 if (var_to_display(p, &info->var, info)) 1066 if (var_to_display(p, &info->var, info))
959 return; 1067 return;
960 1068
@@ -986,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
986 if (!*vc->vc_uni_pagedir_loc) 1094 if (!*vc->vc_uni_pagedir_loc)
987 con_copy_unimap(vc, svc); 1095 con_copy_unimap(vc, svc);
988 1096
1097 ops = info->fbcon_par;
1098 p->con_rotate = rotate;
1099 set_blitting_type(vc, info, NULL);
1100
989 cols = vc->vc_cols; 1101 cols = vc->vc_cols;
990 rows = vc->vc_rows; 1102 rows = vc->vc_rows;
991 new_cols = info->var.xres / vc->vc_font.width; 1103 new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
992 new_rows = info->var.yres / vc->vc_font.height; 1104 new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1105 new_cols /= vc->vc_font.width;
1106 new_rows /= vc->vc_font.height;
993 vc_resize(vc, new_cols, new_rows); 1107 vc_resize(vc, new_cols, new_rows);
994 1108
995 ops = info->fbcon_par;
996 /* 1109 /*
997 * We must always set the mode. The mode of the previous console 1110 * We must always set the mode. The mode of the previous console
998 * driver could be in the same resolution but we are using different 1111 * driver could be in the same resolution but we are using different
@@ -1030,6 +1143,12 @@ static void fbcon_init(struct vc_data *vc, int init)
1030 1143
1031 if (vc == svc && softback_buf) 1144 if (vc == svc && softback_buf)
1032 fbcon_update_softback(vc); 1145 fbcon_update_softback(vc);
1146
1147 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
1148 ops->rotate = FB_ROTATE_UR;
1149 set_blitting_type(vc, info, p);
1150 }
1151
1033} 1152}
1034 1153
1035static void fbcon_deinit(struct vc_data *vc) 1154static void fbcon_deinit(struct vc_data *vc)
@@ -1066,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
1066 * restriction is simplicity & efficiency at the moment. 1185 * restriction is simplicity & efficiency at the moment.
1067 */ 1186 */
1068 1187
1069static __inline__ int real_y(struct display *p, int ypos)
1070{
1071 int rows = p->vrows;
1072
1073 ypos += p->yscroll;
1074 return ypos < rows ? ypos : ypos - rows;
1075}
1076
1077
1078static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 1188static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1079 int width) 1189 int width)
1080{ 1190{
@@ -1162,13 +1272,6 @@ static int scrollback_phys_max = 0;
1162static int scrollback_max = 0; 1272static int scrollback_max = 0;
1163static int scrollback_current = 0; 1273static int scrollback_current = 0;
1164 1274
1165static int update_var(int con, struct fb_info *info)
1166{
1167 if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
1168 return fb_pan_display(info, &info->var);
1169 return 0;
1170}
1171
1172/* 1275/*
1173 * If no vc is existent yet, just set struct display 1276 * If no vc is existent yet, just set struct display
1174 */ 1277 */
@@ -1178,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
1178 struct display *p = &fb_display[unit]; 1281 struct display *p = &fb_display[unit];
1179 struct display *t = &fb_display[fg_console]; 1282 struct display *t = &fb_display[fg_console];
1180 1283
1181 var->xoffset = var->yoffset = p->yscroll = 0;
1182 if (var_to_display(p, var, info)) 1284 if (var_to_display(p, var, info))
1183 return; 1285 return;
1184 1286
@@ -1194,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1194 struct display *p = &fb_display[vc->vc_num], *t; 1296 struct display *p = &fb_display[vc->vc_num], *t;
1195 struct vc_data **default_mode = vc->vc_display_fg; 1297 struct vc_data **default_mode = vc->vc_display_fg;
1196 struct vc_data *svc = *default_mode; 1298 struct vc_data *svc = *default_mode;
1299 struct fbcon_ops *ops = info->fbcon_par;
1197 int rows, cols, charcnt = 256; 1300 int rows, cols, charcnt = 256;
1198 1301
1199 var->xoffset = var->yoffset = p->yscroll = 0;
1200 if (var_to_display(p, var, info)) 1302 if (var_to_display(p, var, info))
1201 return; 1303 return;
1202 t = &fb_display[svc->vc_num]; 1304 t = &fb_display[svc->vc_num];
@@ -1213,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1213 1315
1214 var->activate = FB_ACTIVATE_NOW; 1316 var->activate = FB_ACTIVATE_NOW;
1215 info->var.activate = var->activate; 1317 info->var.activate = var->activate;
1216 info->var.yoffset = info->var.xoffset = 0; 1318 var->yoffset = info->var.yoffset;
1319 var->xoffset = info->var.xoffset;
1217 fb_set_var(info, var); 1320 fb_set_var(info, var);
1218 1321 ops->var = info->var;
1219 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1322 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1220 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1323 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1221 if (charcnt == 256) { 1324 if (charcnt == 256) {
@@ -1231,9 +1334,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1231 if (!*vc->vc_uni_pagedir_loc) 1334 if (!*vc->vc_uni_pagedir_loc)
1232 con_copy_unimap(vc, svc); 1335 con_copy_unimap(vc, svc);
1233 1336
1234 cols = var->xres / vc->vc_font.width; 1337 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1235 rows = var->yres / vc->vc_font.height; 1338 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1339 cols /= vc->vc_font.width;
1340 rows /= vc->vc_font.height;
1236 vc_resize(vc, cols, rows); 1341 vc_resize(vc, cols, rows);
1342
1237 if (CON_IS_VISIBLE(vc)) { 1343 if (CON_IS_VISIBLE(vc)) {
1238 update_screen(vc); 1344 update_screen(vc);
1239 if (softback_buf) 1345 if (softback_buf)
@@ -1244,15 +1350,16 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1244static __inline__ void ywrap_up(struct vc_data *vc, int count) 1350static __inline__ void ywrap_up(struct vc_data *vc, int count)
1245{ 1351{
1246 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1352 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353 struct fbcon_ops *ops = info->fbcon_par;
1247 struct display *p = &fb_display[vc->vc_num]; 1354 struct display *p = &fb_display[vc->vc_num];
1248 1355
1249 p->yscroll += count; 1356 p->yscroll += count;
1250 if (p->yscroll >= p->vrows) /* Deal with wrap */ 1357 if (p->yscroll >= p->vrows) /* Deal with wrap */
1251 p->yscroll -= p->vrows; 1358 p->yscroll -= p->vrows;
1252 info->var.xoffset = 0; 1359 ops->var.xoffset = 0;
1253 info->var.yoffset = p->yscroll * vc->vc_font.height; 1360 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1254 info->var.vmode |= FB_VMODE_YWRAP; 1361 ops->var.vmode |= FB_VMODE_YWRAP;
1255 update_var(vc->vc_num, info); 1362 ops->update_start(info);
1256 scrollback_max += count; 1363 scrollback_max += count;
1257 if (scrollback_max > scrollback_phys_max) 1364 if (scrollback_max > scrollback_phys_max)
1258 scrollback_max = scrollback_phys_max; 1365 scrollback_max = scrollback_phys_max;
@@ -1262,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
1262static __inline__ void ywrap_down(struct vc_data *vc, int count) 1369static __inline__ void ywrap_down(struct vc_data *vc, int count)
1263{ 1370{
1264 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1371 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1372 struct fbcon_ops *ops = info->fbcon_par;
1265 struct display *p = &fb_display[vc->vc_num]; 1373 struct display *p = &fb_display[vc->vc_num];
1266 1374
1267 p->yscroll -= count; 1375 p->yscroll -= count;
1268 if (p->yscroll < 0) /* Deal with wrap */ 1376 if (p->yscroll < 0) /* Deal with wrap */
1269 p->yscroll += p->vrows; 1377 p->yscroll += p->vrows;
1270 info->var.xoffset = 0; 1378 ops->var.xoffset = 0;
1271 info->var.yoffset = p->yscroll * vc->vc_font.height; 1379 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1272 info->var.vmode |= FB_VMODE_YWRAP; 1380 ops->var.vmode |= FB_VMODE_YWRAP;
1273 update_var(vc->vc_num, info); 1381 ops->update_start(info);
1274 scrollback_max -= count; 1382 scrollback_max -= count;
1275 if (scrollback_max < 0) 1383 if (scrollback_max < 0)
1276 scrollback_max = 0; 1384 scrollback_max = 0;
@@ -1289,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1289 0, 0, 0, vc->vc_rows, vc->vc_cols); 1397 0, 0, 0, vc->vc_rows, vc->vc_cols);
1290 p->yscroll -= p->vrows - vc->vc_rows; 1398 p->yscroll -= p->vrows - vc->vc_rows;
1291 } 1399 }
1292 info->var.xoffset = 0; 1400
1293 info->var.yoffset = p->yscroll * vc->vc_font.height; 1401 ops->var.xoffset = 0;
1294 info->var.vmode &= ~FB_VMODE_YWRAP; 1402 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1295 update_var(vc->vc_num, info); 1403 ops->var.vmode &= ~FB_VMODE_YWRAP;
1404 ops->update_start(info);
1296 fbcon_clear_margins(vc, 1); 1405 fbcon_clear_margins(vc, 1);
1297 scrollback_max += count; 1406 scrollback_max += count;
1298 if (scrollback_max > scrollback_phys_max) 1407 if (scrollback_max > scrollback_phys_max)
@@ -1303,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1303static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) 1412static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1304{ 1413{
1305 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1414 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1415 struct fbcon_ops *ops = info->fbcon_par;
1306 struct display *p = &fb_display[vc->vc_num]; 1416 struct display *p = &fb_display[vc->vc_num];
1307 int redraw = 0; 1417 int redraw = 0;
1308 1418
@@ -1312,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1312 redraw = 1; 1422 redraw = 1;
1313 } 1423 }
1314 1424
1315 info->var.xoffset = 0;
1316 info->var.yoffset = p->yscroll * vc->vc_font.height;
1317 info->var.vmode &= ~FB_VMODE_YWRAP;
1318 if (redraw) 1425 if (redraw)
1319 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); 1426 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
1320 update_var(vc->vc_num, info); 1427
1428 ops->var.xoffset = 0;
1429 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1430 ops->var.vmode &= ~FB_VMODE_YWRAP;
1431 ops->update_start(info);
1321 fbcon_clear_margins(vc, 1); 1432 fbcon_clear_margins(vc, 1);
1322 scrollback_max += count; 1433 scrollback_max += count;
1323 if (scrollback_max > scrollback_phys_max) 1434 if (scrollback_max > scrollback_phys_max)
@@ -1337,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1337 0, vc->vc_rows, vc->vc_cols); 1448 0, vc->vc_rows, vc->vc_cols);
1338 p->yscroll += p->vrows - vc->vc_rows; 1449 p->yscroll += p->vrows - vc->vc_rows;
1339 } 1450 }
1340 info->var.xoffset = 0; 1451
1341 info->var.yoffset = p->yscroll * vc->vc_font.height; 1452 ops->var.xoffset = 0;
1342 info->var.vmode &= ~FB_VMODE_YWRAP; 1453 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1343 update_var(vc->vc_num, info); 1454 ops->var.vmode &= ~FB_VMODE_YWRAP;
1455 ops->update_start(info);
1344 fbcon_clear_margins(vc, 1); 1456 fbcon_clear_margins(vc, 1);
1345 scrollback_max -= count; 1457 scrollback_max -= count;
1346 if (scrollback_max < 0) 1458 if (scrollback_max < 0)
@@ -1351,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1351static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) 1463static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1352{ 1464{
1353 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1465 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1466 struct fbcon_ops *ops = info->fbcon_par;
1354 struct display *p = &fb_display[vc->vc_num]; 1467 struct display *p = &fb_display[vc->vc_num];
1355 int redraw = 0; 1468 int redraw = 0;
1356 1469
@@ -1359,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1359 p->yscroll += p->vrows - vc->vc_rows; 1472 p->yscroll += p->vrows - vc->vc_rows;
1360 redraw = 1; 1473 redraw = 1;
1361 } 1474 }
1362 info->var.xoffset = 0; 1475
1363 info->var.yoffset = p->yscroll * vc->vc_font.height;
1364 info->var.vmode &= ~FB_VMODE_YWRAP;
1365 if (redraw) 1476 if (redraw)
1366 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); 1477 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
1367 update_var(vc->vc_num, info); 1478
1479 ops->var.xoffset = 0;
1480 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1481 ops->var.vmode &= ~FB_VMODE_YWRAP;
1482 ops->update_start(info);
1368 fbcon_clear_margins(vc, 1); 1483 fbcon_clear_margins(vc, 1);
1369 scrollback_max -= count; 1484 scrollback_max -= count;
1370 if (scrollback_max < 0) 1485 if (scrollback_max < 0)
@@ -1838,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1838 height, width); 1953 height, width);
1839} 1954}
1840 1955
1841static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, 1956static __inline__ void updatescrollmode(struct display *p,
1957 struct fb_info *info,
1842 struct vc_data *vc) 1958 struct vc_data *vc)
1843{ 1959{
1960 struct fbcon_ops *ops = info->fbcon_par;
1844 int fh = vc->vc_font.height; 1961 int fh = vc->vc_font.height;
1845 int cap = info->flags; 1962 int cap = info->flags;
1846 int good_pan = (cap & FBINFO_HWACCEL_YPAN) 1963 u16 t = 0;
1847 && divides(info->fix.ypanstep, vc->vc_font.height) 1964 int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1848 && info->var.yres_virtual > info->var.yres; 1965 info->fix.xpanstep);
1849 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) 1966 int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
1850 && divides(info->fix.ywrapstep, vc->vc_font.height) 1967 int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1851 && divides(vc->vc_font.height, info->var.yres_virtual); 1968 int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
1969 info->var.xres_virtual);
1970 int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1971 divides(ypan, vc->vc_font.height) && vyres > yres;
1972 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1973 divides(ywrap, vc->vc_font.height) &&
1974 divides(vc->vc_font.height, vyres);
1852 int reading_fast = cap & FBINFO_READS_FAST; 1975 int reading_fast = cap & FBINFO_READS_FAST;
1853 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); 1976 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1854 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); 1977 !(cap & FBINFO_HWACCEL_DISABLED);
1855 1978 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1856 p->vrows = info->var.yres_virtual/fh; 1979 !(cap & FBINFO_HWACCEL_DISABLED);
1857 if (info->var.yres > (fh * (vc->vc_rows + 1))) 1980
1858 p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; 1981 p->vrows = vyres/fh;
1859 if ((info->var.yres % fh) && (info->var.yres_virtual % fh < 1982 if (yres > (fh * (vc->vc_rows + 1)))
1860 info->var.yres % fh)) 1983 p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1984 if ((yres % fh) && (vyres % fh < yres % fh))
1861 p->vrows--; 1985 p->vrows--;
1862 1986
1863 if (good_wrap || good_pan) { 1987 if (good_wrap || good_pan) {
1864 if (reading_fast || fast_copyarea) 1988 if (reading_fast || fast_copyarea)
1865 p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; 1989 p->scrollmode = good_wrap ?
1990 SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1866 else 1991 else
1867 p->scrollmode = good_wrap ? SCROLL_REDRAW : 1992 p->scrollmode = good_wrap ? SCROLL_REDRAW :
1868 SCROLL_PAN_REDRAW; 1993 SCROLL_PAN_REDRAW;
@@ -1878,17 +2003,23 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1878 unsigned int height) 2003 unsigned int height)
1879{ 2004{
1880 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2005 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2006 struct fbcon_ops *ops = info->fbcon_par;
1881 struct display *p = &fb_display[vc->vc_num]; 2007 struct display *p = &fb_display[vc->vc_num];
1882 struct fb_var_screeninfo var = info->var; 2008 struct fb_var_screeninfo var = info->var;
1883 int x_diff, y_diff; 2009 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
1884 int fw = vc->vc_font.width; 2010
1885 int fh = vc->vc_font.height; 2011 virt_w = FBCON_SWAP(ops->rotate, width, height);
1886 2012 virt_h = FBCON_SWAP(ops->rotate, height, width);
1887 var.xres = width * fw; 2013 virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
1888 var.yres = height * fh; 2014 vc->vc_font.height);
2015 virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
2016 vc->vc_font.width);
2017 var.xres = virt_w * virt_fw;
2018 var.yres = virt_h * virt_fh;
1889 x_diff = info->var.xres - var.xres; 2019 x_diff = info->var.xres - var.xres;
1890 y_diff = info->var.yres - var.yres; 2020 y_diff = info->var.yres - var.yres;
1891 if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { 2021 if (x_diff < 0 || x_diff > virt_fw ||
2022 y_diff < 0 || y_diff > virt_fh) {
1892 struct fb_videomode *mode; 2023 struct fb_videomode *mode;
1893 2024
1894 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); 2025 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
@@ -1898,7 +2029,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1898 display_to_var(&var, p); 2029 display_to_var(&var, p);
1899 fb_videomode_to_var(&var, mode); 2030 fb_videomode_to_var(&var, mode);
1900 2031
1901 if (width > var.xres/fw || height > var.yres/fh) 2032 if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
1902 return -EINVAL; 2033 return -EINVAL;
1903 2034
1904 DPRINTK("resize now %ix%i\n", var.xres, var.yres); 2035 DPRINTK("resize now %ix%i\n", var.xres, var.yres);
@@ -1908,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1908 fb_set_var(info, &var); 2039 fb_set_var(info, &var);
1909 } 2040 }
1910 var_to_display(p, &info->var, info); 2041 var_to_display(p, &info->var, info);
2042 ops->var = info->var;
1911 } 2043 }
1912 updatescrollmode(p, info, vc); 2044 updatescrollmode(p, info, vc);
1913 return 0; 2045 return 0;
@@ -1916,11 +2048,13 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1916static int fbcon_switch(struct vc_data *vc) 2048static int fbcon_switch(struct vc_data *vc)
1917{ 2049{
1918 struct fb_info *info, *old_info = NULL; 2050 struct fb_info *info, *old_info = NULL;
2051 struct fbcon_ops *ops;
1919 struct display *p = &fb_display[vc->vc_num]; 2052 struct display *p = &fb_display[vc->vc_num];
1920 struct fb_var_screeninfo var; 2053 struct fb_var_screeninfo var;
1921 int i, prev_console; 2054 int i, prev_console;
1922 2055
1923 info = registered_fb[con2fb_map[vc->vc_num]]; 2056 info = registered_fb[con2fb_map[vc->vc_num]];
2057 ops = info->fbcon_par;
1924 2058
1925 if (softback_top) { 2059 if (softback_top) {
1926 if (softback_lines) 2060 if (softback_lines)
@@ -1939,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
1939 logo_shown = FBCON_LOGO_CANSHOW; 2073 logo_shown = FBCON_LOGO_CANSHOW;
1940 } 2074 }
1941 2075
1942 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 2076 prev_console = ops->currcon;
1943 if (prev_console != -1) 2077 if (prev_console != -1)
1944 old_info = registered_fb[con2fb_map[prev_console]]; 2078 old_info = registered_fb[con2fb_map[prev_console]];
1945 /* 2079 /*
@@ -1952,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
1952 */ 2086 */
1953 for (i = 0; i < FB_MAX; i++) { 2087 for (i = 0; i < FB_MAX; i++) {
1954 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { 2088 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
1955 struct fbcon_ops *ops = registered_fb[i]->fbcon_par; 2089 struct fbcon_ops *o = registered_fb[i]->fbcon_par;
1956 2090
1957 ops->currcon = vc->vc_num; 2091 o->currcon = vc->vc_num;
1958 } 2092 }
1959 } 2093 }
1960 memset(&var, 0, sizeof(struct fb_var_screeninfo)); 2094 memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1966,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
1966 * in fb_set_var() 2100 * in fb_set_var()
1967 */ 2101 */
1968 info->var.activate = var.activate; 2102 info->var.activate = var.activate;
1969 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 2103 var.yoffset = info->var.yoffset;
2104 var.xoffset = info->var.xoffset;
2105 var.vmode = info->var.vmode;
1970 fb_set_var(info, &var); 2106 fb_set_var(info, &var);
2107 ops->var = info->var;
1971 2108
1972 if (old_info != NULL && old_info != info) { 2109 if (old_info != NULL && old_info != info) {
1973 if (info->fbops->fb_set_par) 2110 if (info->fbops->fb_set_par)
@@ -1977,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
1977 } 2114 }
1978 2115
1979 set_blitting_type(vc, info, p); 2116 set_blitting_type(vc, info, p);
1980 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 2117 ops->cursor_reset = 1;
2118
2119 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
2120 ops->rotate = FB_ROTATE_UR;
2121 set_blitting_type(vc, info, p);
2122 }
1981 2123
1982 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 2124 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1983 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 2125 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -1997,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
1997 scrollback_phys_max = 0; 2139 scrollback_phys_max = 0;
1998 break; 2140 break;
1999 } 2141 }
2142
2000 scrollback_max = 0; 2143 scrollback_max = 0;
2001 scrollback_current = 0; 2144 scrollback_current = 0;
2002 2145 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2003 update_var(vc->vc_num, info); 2146 ops->update_start(info);
2004 fbcon_set_palette(vc, color_table); 2147 fbcon_set_palette(vc, color_table);
2005 fbcon_clear_margins(vc, 0); 2148 fbcon_clear_margins(vc, 0);
2006 2149
@@ -2008,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
2008 2151
2009 logo_shown = fg_console; 2152 logo_shown = fg_console;
2010 /* This is protected above by initmem_freed */ 2153 /* This is protected above by initmem_freed */
2011 fb_show_logo(info); 2154 fb_show_logo(info, ops->rotate);
2012 update_region(vc, 2155 update_region(vc,
2013 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2156 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2014 vc->vc_size_row * (vc->vc_bottom - 2157 vc->vc_size_row * (vc->vc_bottom -
@@ -2047,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2047 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 2190 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
2048 fb_set_var(info, &var); 2191 fb_set_var(info, &var);
2049 ops->graphics = 0; 2192 ops->graphics = 0;
2193 ops->var = info->var;
2050 } 2194 }
2051 } 2195 }
2052 2196
@@ -2135,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2135 const u8 * data, int userfont) 2279 const u8 * data, int userfont)
2136{ 2280{
2137 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2281 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2282 struct fbcon_ops *ops = info->fbcon_par;
2138 struct display *p = &fb_display[vc->vc_num]; 2283 struct display *p = &fb_display[vc->vc_num];
2139 int resize; 2284 int resize;
2140 int cnt; 2285 int cnt;
@@ -2214,9 +2359,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2214 } 2359 }
2215 2360
2216 if (resize) { 2361 if (resize) {
2217 /* reset wrap/pan */ 2362 int cols, rows;
2218 info->var.xoffset = info->var.yoffset = p->yscroll = 0; 2363
2219 vc_resize(vc, info->var.xres / w, info->var.yres / h); 2364 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2365 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2366 cols /= w;
2367 rows /= h;
2368 vc_resize(vc, cols, rows);
2220 if (CON_IS_VISIBLE(vc) && softback_buf) 2369 if (CON_IS_VISIBLE(vc) && softback_buf)
2221 fbcon_update_softback(vc); 2370 fbcon_update_softback(vc);
2222 } else if (CON_IS_VISIBLE(vc) 2371 } else if (CON_IS_VISIBLE(vc)
@@ -2444,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
2444static int fbcon_scrolldelta(struct vc_data *vc, int lines) 2593static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2445{ 2594{
2446 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2595 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2596 struct fbcon_ops *ops = info->fbcon_par;
2447 struct display *p = &fb_display[fg_console]; 2597 struct display *p = &fb_display[fg_console];
2448 int offset, limit, scrollback_old; 2598 int offset, limit, scrollback_old;
2449 2599
@@ -2520,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2520 offset += limit; 2670 offset += limit;
2521 else if (offset >= limit) 2671 else if (offset >= limit)
2522 offset -= limit; 2672 offset -= limit;
2523 info->var.xoffset = 0; 2673
2524 info->var.yoffset = offset * vc->vc_font.height; 2674 ops->var.xoffset = 0;
2525 update_var(vc->vc_num, info); 2675 ops->var.yoffset = offset * vc->vc_font.height;
2676 ops->update_start(info);
2677
2526 if (!scrollback_current) 2678 if (!scrollback_current)
2527 fbcon_cursor(vc, CM_DRAW); 2679 fbcon_cursor(vc, CM_DRAW);
2528 return 0; 2680 return 0;
@@ -2570,22 +2722,25 @@ static void fbcon_modechanged(struct fb_info *info)
2570 if (!ops || ops->currcon < 0) 2722 if (!ops || ops->currcon < 0)
2571 return; 2723 return;
2572 vc = vc_cons[ops->currcon].d; 2724 vc = vc_cons[ops->currcon].d;
2573 if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) 2725 if (vc->vc_mode != KD_TEXT ||
2726 registered_fb[con2fb_map[ops->currcon]] != info)
2574 return; 2727 return;
2575 2728
2576 p = &fb_display[vc->vc_num]; 2729 p = &fb_display[vc->vc_num];
2577 2730 set_blitting_type(vc, info, p);
2578 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2579 2731
2580 if (CON_IS_VISIBLE(vc)) { 2732 if (CON_IS_VISIBLE(vc)) {
2581 var_to_display(p, &info->var, info); 2733 var_to_display(p, &info->var, info);
2582 cols = info->var.xres / vc->vc_font.width; 2734 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2583 rows = info->var.yres / vc->vc_font.height; 2735 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2736 cols /= vc->vc_font.width;
2737 rows /= vc->vc_font.height;
2584 vc_resize(vc, cols, rows); 2738 vc_resize(vc, cols, rows);
2585 updatescrollmode(p, info, vc); 2739 updatescrollmode(p, info, vc);
2586 scrollback_max = 0; 2740 scrollback_max = 0;
2587 scrollback_current = 0; 2741 scrollback_current = 0;
2588 update_var(vc->vc_num, info); 2742 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2743 ops->update_start(info);
2589 fbcon_set_palette(vc, color_table); 2744 fbcon_set_palette(vc, color_table);
2590 update_screen(vc); 2745 update_screen(vc);
2591 if (softback_buf) 2746 if (softback_buf)
@@ -2610,18 +2765,20 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2610 continue; 2765 continue;
2611 2766
2612 p = &fb_display[vc->vc_num]; 2767 p = &fb_display[vc->vc_num];
2613 2768 set_blitting_type(vc, info, p);
2614 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2615 var_to_display(p, &info->var, info); 2769 var_to_display(p, &info->var, info);
2616 cols = info->var.xres / vc->vc_font.width; 2770 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2617 rows = info->var.yres / vc->vc_font.height; 2771 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2772 cols /= vc->vc_font.width;
2773 rows /= vc->vc_font.height;
2618 vc_resize(vc, cols, rows); 2774 vc_resize(vc, cols, rows);
2619 2775
2620 if (CON_IS_VISIBLE(vc)) { 2776 if (CON_IS_VISIBLE(vc)) {
2621 updatescrollmode(p, info, vc); 2777 updatescrollmode(p, info, vc);
2622 scrollback_max = 0; 2778 scrollback_max = 0;
2623 scrollback_current = 0; 2779 scrollback_current = 0;
2624 update_var(vc->vc_num, info); 2780 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2781 ops->update_start(info);
2625 fbcon_set_palette(vc, color_table); 2782 fbcon_set_palette(vc, color_table);
2626 update_screen(vc); 2783 update_screen(vc);
2627 if (softback_buf) 2784 if (softback_buf)
@@ -2771,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2771 case FB_EVENT_NEW_MODELIST: 2928 case FB_EVENT_NEW_MODELIST:
2772 fbcon_new_modelist(info); 2929 fbcon_new_modelist(info);
2773 break; 2930 break;
2931 case FB_EVENT_SET_CON_ROTATE:
2932 fbcon_rotate(info, *(int *)event->data);
2933 break;
2934 case FB_EVENT_GET_CON_ROTATE:
2935 ret = fbcon_get_rotate(info);
2936 break;
2937 case FB_EVENT_SET_CON_ROTATE_ALL:
2938 fbcon_rotate_all(info, *(int *)event->data);
2774 } 2939 }
2775 2940
2776 return ret; 2941 return ret;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index b68e0e2c2d16..accfd7bd8e93 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -27,15 +27,15 @@
27 */ 27 */
28 28
29struct display { 29struct display {
30 /* Filled in by the frame buffer device */
31 u_short inverse; /* != 0 text black on white as default */
32 /* Filled in by the low-level console driver */ 30 /* Filled in by the low-level console driver */
33 const u_char *fontdata; 31 const u_char *fontdata;
34 int userfont; /* != 0 if fontdata kmalloc()ed */ 32 int userfont; /* != 0 if fontdata kmalloc()ed */
35 u_short scrollmode; /* Scroll Method */ 33 u_short scrollmode; /* Scroll Method */
34 u_short inverse; /* != 0 text black on white as default */
36 short yscroll; /* Hardware scrolling */ 35 short yscroll; /* Hardware scrolling */
37 int vrows; /* number of virtual rows */ 36 int vrows; /* number of virtual rows */
38 int cursor_shape; 37 int cursor_shape;
38 int con_rotate;
39 u32 xres_virtual; 39 u32 xres_virtual;
40 u32 yres_virtual; 40 u32 yres_virtual;
41 u32 height; 41 u32 height;
@@ -52,6 +52,8 @@ struct display {
52 struct fb_videomode *mode; 52 struct fb_videomode *mode;
53}; 53};
54 54
55extern struct display fb_display[];
56
55struct fbcon_ops { 57struct fbcon_ops {
56 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, 58 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
57 int sx, int dy, int dx, int height, int width); 59 int sx, int dy, int dx, int height, int width);
@@ -63,8 +65,12 @@ struct fbcon_ops {
63 void (*clear_margins)(struct vc_data *vc, struct fb_info *info, 65 void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
64 int bottom_only); 66 int bottom_only);
65 void (*cursor)(struct vc_data *vc, struct fb_info *info, 67 void (*cursor)(struct vc_data *vc, struct fb_info *info,
66 struct display *p, int mode, int softback_lines, int fg, int bg); 68 struct display *p, int mode, int softback_lines,
67 69 int fg, int bg);
70 int (*update_start)(struct fb_info *info);
71 int (*rotate_font)(struct fb_info *info, struct vc_data *vc,
72 struct display *p);
73 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
68 struct timer_list cursor_timer; /* Cursor timer */ 74 struct timer_list cursor_timer; /* Cursor timer */
69 struct fb_cursor cursor_state; 75 struct fb_cursor cursor_state;
70 int currcon; /* Current VC. */ 76 int currcon; /* Current VC. */
@@ -73,7 +79,12 @@ struct fbcon_ops {
73 int blank_state; 79 int blank_state;
74 int graphics; 80 int graphics;
75 int flags; 81 int flags;
82 int rotate;
83 int cur_rotate;
76 char *cursor_data; 84 char *cursor_data;
85 u8 *fontbuffer;
86 u8 *fontdata;
87 u32 fd_size;
77}; 88};
78 /* 89 /*
79 * Attribute Decoding 90 * Attribute Decoding
@@ -168,4 +179,47 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
168#endif 179#endif
169extern void fbcon_set_bitops(struct fbcon_ops *ops); 180extern void fbcon_set_bitops(struct fbcon_ops *ops);
170extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); 181extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
182
183#define FBCON_ATTRIBUTE_UNDERLINE 1
184#define FBCON_ATTRIBUTE_REVERSE 2
185#define FBCON_ATTRIBUTE_BOLD 4
186
187static inline int real_y(struct display *p, int ypos)
188{
189 int rows = p->vrows;
190
191 ypos += p->yscroll;
192 return ypos < rows ? ypos : ypos - rows;
193}
194
195
196static inline int get_attribute(struct fb_info *info, u16 c)
197{
198 int attribute = 0;
199
200 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
201 if (attr_underline(c))
202 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
203 if (attr_reverse(c))
204 attribute |= FBCON_ATTRIBUTE_REVERSE;
205 if (attr_bold(c))
206 attribute |= FBCON_ATTRIBUTE_BOLD;
207 }
208
209 return attribute;
210}
211
212#define FBCON_SWAP(i,r,v) ({ \
213 typeof(r) _r = (r); \
214 typeof(v) _v = (v); \
215 (void) (&_r == &_v); \
216 (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
217
218#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
219extern void fbcon_set_rotate(struct fbcon_ops *ops);
220#else
221#define fbcon_set_rotate(x) do {} while(0)
222#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
223
171#endif /* _VIDEO_FBCON_H */ 224#endif /* _VIDEO_FBCON_H */
225
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
new file mode 100644
index 000000000000..680aabab73c5
--- /dev/null
+++ b/drivers/video/console/fbcon_ccw.c
@@ -0,0 +1,428 @@
1/*
2 * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 270 degrees
23 */
24
25static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 int mod = vc->vc_font.height % 8;
31 u8 c, msk = ~(0xff << offset), msk1 = 0;
32
33 if (mod)
34 msk <<= (8 - mod);
35
36 if (offset > mod)
37 set_bit(FBCON_BIT(7), (void *)&msk1);
38
39 for (i = 0; i < vc->vc_font.width; i++) {
40 for (j = 0; j < width; j++) {
41 c = *src;
42
43 if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
44 if (j == width - 1)
45 c |= msk;
46
47 if (msk1 && j == width - 2)
48 c |= msk1;
49 }
50
51 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
52 *(dst - width) |= c;
53
54 if (attribute & FBCON_ATTRIBUTE_REVERSE)
55 c = ~c;
56 src++;
57 *dst++ = c;
58 }
59 }
60}
61
62
63static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
64 int sx, int dy, int dx, int height, int width)
65{
66 struct display *p = &fb_display[vc->vc_num];
67 struct fb_copyarea area;
68 u32 vyres = GETVYRES(p->scrollmode, info);
69
70 area.sx = sy * vc->vc_font.height;
71 area.sy = vyres - ((sx + width) * vc->vc_font.width);
72 area.dx = dy * vc->vc_font.height;
73 area.dy = vyres - ((dx + width) * vc->vc_font.width);
74 area.width = height * vc->vc_font.height;
75 area.height = width * vc->vc_font.width;
76
77 info->fbops->fb_copyarea(info, &area);
78}
79
80static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
81 int sx, int height, int width)
82{
83 struct display *p = &fb_display[vc->vc_num];
84 struct fb_fillrect region;
85 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
86 u32 vyres = GETVYRES(p->scrollmode, info);
87
88 region.color = attr_bgcol_ec(bgshift,vc);
89 region.dx = sy * vc->vc_font.height;
90 region.dy = vyres - ((sx + width) * vc->vc_font.width);
91 region.height = width * vc->vc_font.width;
92 region.width = height * vc->vc_font.height;
93 region.rop = ROP_COPY;
94
95 info->fbops->fb_fillrect(info, &region);
96}
97
98static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
99 const u16 *s, u32 attr, u32 cnt,
100 u32 d_pitch, u32 s_pitch, u32 cellsize,
101 struct fb_image *image, u8 *buf, u8 *dst)
102{
103 struct fbcon_ops *ops = info->fbcon_par;
104 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
105 u32 idx = (vc->vc_font.height + 7) >> 3;
106 u8 *src;
107
108 while (cnt--) {
109 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
110
111 if (attr) {
112 ccw_update_attr(buf, src, attr, vc);
113 src = buf;
114 }
115
116 if (likely(idx == 1))
117 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
118 vc->vc_font.width);
119 else
120 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
121 vc->vc_font.width);
122
123 dst += d_pitch * vc->vc_font.width;
124 }
125
126 info->fbops->fb_imageblit(info, image);
127}
128
129static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
130 const unsigned short *s, int count, int yy, int xx,
131 int fg, int bg)
132{
133 struct fb_image image;
134 struct display *p = &fb_display[vc->vc_num];
135 struct fbcon_ops *ops = info->fbcon_par;
136 u32 width = (vc->vc_font.height + 7)/8;
137 u32 cellsize = width * vc->vc_font.width;
138 u32 maxcnt = info->pixmap.size/cellsize;
139 u32 scan_align = info->pixmap.scan_align - 1;
140 u32 buf_align = info->pixmap.buf_align - 1;
141 u32 cnt, pitch, size;
142 u32 attribute = get_attribute(info, scr_readw(s));
143 u8 *dst, *buf = NULL;
144 u32 vyres = GETVYRES(p->scrollmode, info);
145
146 if (!ops->fontbuffer)
147 return;
148
149 image.fg_color = fg;
150 image.bg_color = bg;
151 image.dx = yy * vc->vc_font.height;
152 image.dy = vyres - ((xx + count) * vc->vc_font.width);
153 image.width = vc->vc_font.height;
154 image.depth = 1;
155
156 if (attribute) {
157 buf = kmalloc(cellsize, GFP_KERNEL);
158 if (!buf)
159 return;
160 }
161
162 s += count - 1;
163
164 while (count) {
165 if (count > maxcnt)
166 cnt = maxcnt;
167 else
168 cnt = count;
169
170 image.height = vc->vc_font.width * cnt;
171 pitch = ((image.width + 7) >> 3) + scan_align;
172 pitch &= ~scan_align;
173 size = pitch * image.height + buf_align;
174 size &= ~buf_align;
175 dst = fb_get_buffer_offset(info, &info->pixmap, size);
176 image.data = dst;
177 ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
178 width, cellsize, &image, buf, dst);
179 image.dy += image.height;
180 count -= cnt;
181 s -= cnt;
182 }
183
184 /* buf is always NULL except when in monochrome mode, so in this case
185 it's a gain to check buf against NULL even though kfree() handles
186 NULL pointers just fine */
187 if (unlikely(buf))
188 kfree(buf);
189
190}
191
192static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
193 int bottom_only)
194{
195 unsigned int cw = vc->vc_font.width;
196 unsigned int ch = vc->vc_font.height;
197 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
198 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
199 unsigned int bs = vc->vc_rows*ch;
200 struct fb_fillrect region;
201 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
202
203 region.color = attr_bgcol_ec(bgshift,vc);
204 region.rop = ROP_COPY;
205
206 if (rw && !bottom_only) {
207 region.dx = 0;
208 region.dy = info->var.yoffset;
209 region.height = rw;
210 region.width = info->var.xres_virtual;
211 info->fbops->fb_fillrect(info, &region);
212 }
213
214 if (bh) {
215 region.dx = info->var.xoffset + bs;
216 region.dy = 0;
217 region.height = info->var.yres_virtual;
218 region.width = bh;
219 info->fbops->fb_fillrect(info, &region);
220 }
221}
222
223static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
224 struct display *p, int mode, int softback_lines,
225 int fg, int bg)
226{
227 struct fb_cursor cursor;
228 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
229 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
230 int w = (vc->vc_font.height + 7) >> 3, c;
231 int y = real_y(p, vc->vc_y);
232 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
233 int err = 1, dx, dy;
234 char *src;
235 u32 vyres = GETVYRES(p->scrollmode, info);
236
237 if (!ops->fontbuffer)
238 return;
239
240 cursor.set = 0;
241
242 if (softback_lines) {
243 if (y + softback_lines >= vc->vc_rows) {
244 mode = CM_ERASE;
245 ops->cursor_flash = 0;
246 return;
247 } else
248 y += softback_lines;
249 }
250
251 c = scr_readw((u16 *) vc->vc_pos);
252 attribute = get_attribute(info, c);
253 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
254
255 if (ops->cursor_state.image.data != src ||
256 ops->cursor_reset) {
257 ops->cursor_state.image.data = src;
258 cursor.set |= FB_CUR_SETIMAGE;
259 }
260
261 if (attribute) {
262 u8 *dst;
263
264 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
265 if (!dst)
266 return;
267 kfree(ops->cursor_data);
268 ops->cursor_data = dst;
269 ccw_update_attr(dst, src, attribute, vc);
270 src = dst;
271 }
272
273 if (ops->cursor_state.image.fg_color != fg ||
274 ops->cursor_state.image.bg_color != bg ||
275 ops->cursor_reset) {
276 ops->cursor_state.image.fg_color = fg;
277 ops->cursor_state.image.bg_color = bg;
278 cursor.set |= FB_CUR_SETCMAP;
279 }
280
281 if (ops->cursor_state.image.height != vc->vc_font.width ||
282 ops->cursor_state.image.width != vc->vc_font.height ||
283 ops->cursor_reset) {
284 ops->cursor_state.image.height = vc->vc_font.width;
285 ops->cursor_state.image.width = vc->vc_font.height;
286 cursor.set |= FB_CUR_SETSIZE;
287 }
288
289 dx = y * vc->vc_font.height;
290 dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
291
292 if (ops->cursor_state.image.dx != dx ||
293 ops->cursor_state.image.dy != dy ||
294 ops->cursor_reset) {
295 ops->cursor_state.image.dx = dx;
296 ops->cursor_state.image.dy = dy;
297 cursor.set |= FB_CUR_SETPOS;
298 }
299
300 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
301 ops->cursor_reset) {
302 ops->cursor_state.hot.x = cursor.hot.y = 0;
303 cursor.set |= FB_CUR_SETHOT;
304 }
305
306 if (cursor.set & FB_CUR_SETSIZE ||
307 vc->vc_cursor_type != p->cursor_shape ||
308 ops->cursor_state.mask == NULL ||
309 ops->cursor_reset) {
310 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
311 int cur_height, size, i = 0;
312 int width = (vc->vc_font.width + 7)/8;
313
314 if (!mask)
315 return;
316
317 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
318
319 if (!tmp) {
320 kfree(mask);
321 return;
322 }
323
324 kfree(ops->cursor_state.mask);
325 ops->cursor_state.mask = mask;
326
327 p->cursor_shape = vc->vc_cursor_type;
328 cursor.set |= FB_CUR_SETSHAPE;
329
330 switch (p->cursor_shape & CUR_HWMASK) {
331 case CUR_NONE:
332 cur_height = 0;
333 break;
334 case CUR_UNDERLINE:
335 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
336 break;
337 case CUR_LOWER_THIRD:
338 cur_height = vc->vc_font.height/3;
339 break;
340 case CUR_LOWER_HALF:
341 cur_height = vc->vc_font.height >> 1;
342 break;
343 case CUR_TWO_THIRDS:
344 cur_height = (vc->vc_font.height << 1)/3;
345 break;
346 case CUR_BLOCK:
347 default:
348 cur_height = vc->vc_font.height;
349 break;
350 }
351
352 size = (vc->vc_font.height - cur_height) * width;
353 while (size--)
354 tmp[i++] = 0;
355 size = cur_height * width;
356 while (size--)
357 tmp[i++] = 0xff;
358 memset(mask, 0, w * vc->vc_font.width);
359 rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
360 kfree(tmp);
361 }
362
363 switch (mode) {
364 case CM_ERASE:
365 ops->cursor_state.enable = 0;
366 break;
367 case CM_DRAW:
368 case CM_MOVE:
369 default:
370 ops->cursor_state.enable = (use_sw) ? 0 : 1;
371 break;
372 }
373
374 cursor.image.data = src;
375 cursor.image.fg_color = ops->cursor_state.image.fg_color;
376 cursor.image.bg_color = ops->cursor_state.image.bg_color;
377 cursor.image.dx = ops->cursor_state.image.dx;
378 cursor.image.dy = ops->cursor_state.image.dy;
379 cursor.image.height = ops->cursor_state.image.height;
380 cursor.image.width = ops->cursor_state.image.width;
381 cursor.hot.x = ops->cursor_state.hot.x;
382 cursor.hot.y = ops->cursor_state.hot.y;
383 cursor.mask = ops->cursor_state.mask;
384 cursor.enable = ops->cursor_state.enable;
385 cursor.image.depth = 1;
386 cursor.rop = ROP_XOR;
387
388 if (info->fbops->fb_cursor)
389 err = info->fbops->fb_cursor(info, &cursor);
390
391 if (err)
392 soft_cursor(info, &cursor);
393
394 ops->cursor_reset = 0;
395}
396
397int ccw_update_start(struct fb_info *info)
398{
399 struct fbcon_ops *ops = info->fbcon_par;
400 struct display *p = &fb_display[ops->currcon];
401 u32 yoffset;
402 u32 vyres = GETVYRES(p->scrollmode, info);
403 int err;
404
405 yoffset = (vyres - info->var.yres) - ops->var.xoffset;
406 ops->var.xoffset = ops->var.yoffset;
407 ops->var.yoffset = yoffset;
408 err = fb_pan_display(info, &ops->var);
409 ops->var.xoffset = info->var.xoffset;
410 ops->var.yoffset = info->var.yoffset;
411 ops->var.vmode = info->var.vmode;
412 return err;
413}
414
415void fbcon_rotate_ccw(struct fbcon_ops *ops)
416{
417 ops->bmove = ccw_bmove;
418 ops->clear = ccw_clear;
419 ops->putcs = ccw_putcs;
420 ops->clear_margins = ccw_clear_margins;
421 ops->cursor = ccw_cursor;
422 ops->update_start = ccw_update_start;
423}
424EXPORT_SYMBOL(fbcon_rotate_ccw);
425
426MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
427MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
428MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
new file mode 100644
index 000000000000..6c6f3b6dd175
--- /dev/null
+++ b/drivers/video/console/fbcon_cw.c
@@ -0,0 +1,412 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 90 degrees
23 */
24
25static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 u8 c, t = 0, msk = ~(0xff >> offset);
31
32 for (i = 0; i < vc->vc_font.width; i++) {
33 for (j = 0; j < width; j++) {
34 c = *src;
35 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
36 c |= msk;
37 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
38 c |= *(src-width);
39 if (attribute & FBCON_ATTRIBUTE_REVERSE)
40 c = ~c;
41 src++;
42 *dst++ = c;
43 t = c;
44 }
45 }
46}
47
48
49static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
50 int sx, int dy, int dx, int height, int width)
51{
52 struct display *p = &fb_display[vc->vc_num];
53 struct fb_copyarea area;
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sx = vxres - ((sy + height) * vc->vc_font.height);
57 area.sy = sx * vc->vc_font.width;
58 area.dx = vxres - ((dy + height) * vc->vc_font.height);
59 area.dy = dx * vc->vc_font.width;
60 area.width = height * vc->vc_font.height;
61 area.height = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vxres = GETVXRES(p->scrollmode, info);
73
74 region.color = attr_bgcol_ec(bgshift,vc);
75 region.dx = vxres - ((sy + height) * vc->vc_font.height);
76 region.dy = sx * vc->vc_font.width;
77 region.height = width * vc->vc_font.width;
78 region.width = height * vc->vc_font.height;
79 region.rop = ROP_COPY;
80
81 info->fbops->fb_fillrect(info, &region);
82}
83
84static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
85 const u16 *s, u32 attr, u32 cnt,
86 u32 d_pitch, u32 s_pitch, u32 cellsize,
87 struct fb_image *image, u8 *buf, u8 *dst)
88{
89 struct fbcon_ops *ops = info->fbcon_par;
90 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
91 u32 idx = (vc->vc_font.height + 7) >> 3;
92 u8 *src;
93
94 while (cnt--) {
95 src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
96
97 if (attr) {
98 cw_update_attr(buf, src, attr, vc);
99 src = buf;
100 }
101
102 if (likely(idx == 1))
103 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
104 vc->vc_font.width);
105 else
106 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
107 vc->vc_font.width);
108
109 dst += d_pitch * vc->vc_font.width;
110 }
111
112 info->fbops->fb_imageblit(info, image);
113}
114
115static void cw_putcs(struct vc_data *vc, struct fb_info *info,
116 const unsigned short *s, int count, int yy, int xx,
117 int fg, int bg)
118{
119 struct fb_image image;
120 struct display *p = &fb_display[vc->vc_num];
121 struct fbcon_ops *ops = info->fbcon_par;
122 u32 width = (vc->vc_font.height + 7)/8;
123 u32 cellsize = width * vc->vc_font.width;
124 u32 maxcnt = info->pixmap.size/cellsize;
125 u32 scan_align = info->pixmap.scan_align - 1;
126 u32 buf_align = info->pixmap.buf_align - 1;
127 u32 cnt, pitch, size;
128 u32 attribute = get_attribute(info, scr_readw(s));
129 u8 *dst, *buf = NULL;
130 u32 vxres = GETVXRES(p->scrollmode, info);
131
132 if (!ops->fontbuffer)
133 return;
134
135 image.fg_color = fg;
136 image.bg_color = bg;
137 image.dx = vxres - ((yy + 1) * vc->vc_font.height);
138 image.dy = xx * vc->vc_font.width;
139 image.width = vc->vc_font.height;
140 image.depth = 1;
141
142 if (attribute) {
143 buf = kmalloc(cellsize, GFP_KERNEL);
144 if (!buf)
145 return;
146 }
147
148 while (count) {
149 if (count > maxcnt)
150 cnt = maxcnt;
151 else
152 cnt = count;
153
154 image.height = vc->vc_font.width * cnt;
155 pitch = ((image.width + 7) >> 3) + scan_align;
156 pitch &= ~scan_align;
157 size = pitch * image.height + buf_align;
158 size &= ~buf_align;
159 dst = fb_get_buffer_offset(info, &info->pixmap, size);
160 image.data = dst;
161 cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
162 width, cellsize, &image, buf, dst);
163 image.dy += image.height;
164 count -= cnt;
165 s += cnt;
166 }
167
168 /* buf is always NULL except when in monochrome mode, so in this case
169 it's a gain to check buf against NULL even though kfree() handles
170 NULL pointers just fine */
171 if (unlikely(buf))
172 kfree(buf);
173
174}
175
176static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
177 int bottom_only)
178{
179 unsigned int cw = vc->vc_font.width;
180 unsigned int ch = vc->vc_font.height;
181 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
182 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
183 unsigned int rs = info->var.yres - rw;
184 struct fb_fillrect region;
185 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
186
187 region.color = attr_bgcol_ec(bgshift,vc);
188 region.rop = ROP_COPY;
189
190 if (rw && !bottom_only) {
191 region.dx = 0;
192 region.dy = info->var.yoffset + rs;
193 region.height = rw;
194 region.width = info->var.xres_virtual;
195 info->fbops->fb_fillrect(info, &region);
196 }
197
198 if (bh) {
199 region.dx = info->var.xoffset;
200 region.dy = info->var.yoffset;
201 region.height = info->var.yres;
202 region.width = bh;
203 info->fbops->fb_fillrect(info, &region);
204 }
205}
206
207static void cw_cursor(struct vc_data *vc, struct fb_info *info,
208 struct display *p, int mode, int softback_lines,
209 int fg, int bg)
210{
211 struct fb_cursor cursor;
212 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
213 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
214 int w = (vc->vc_font.height + 7) >> 3, c;
215 int y = real_y(p, vc->vc_y);
216 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
217 int err = 1, dx, dy;
218 char *src;
219 u32 vxres = GETVXRES(p->scrollmode, info);
220
221 if (!ops->fontbuffer)
222 return;
223
224 cursor.set = 0;
225
226 if (softback_lines) {
227 if (y + softback_lines >= vc->vc_rows) {
228 mode = CM_ERASE;
229 ops->cursor_flash = 0;
230 return;
231 } else
232 y += softback_lines;
233 }
234
235 c = scr_readw((u16 *) vc->vc_pos);
236 attribute = get_attribute(info, c);
237 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
238
239 if (ops->cursor_state.image.data != src ||
240 ops->cursor_reset) {
241 ops->cursor_state.image.data = src;
242 cursor.set |= FB_CUR_SETIMAGE;
243 }
244
245 if (attribute) {
246 u8 *dst;
247
248 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
249 if (!dst)
250 return;
251 kfree(ops->cursor_data);
252 ops->cursor_data = dst;
253 cw_update_attr(dst, src, attribute, vc);
254 src = dst;
255 }
256
257 if (ops->cursor_state.image.fg_color != fg ||
258 ops->cursor_state.image.bg_color != bg ||
259 ops->cursor_reset) {
260 ops->cursor_state.image.fg_color = fg;
261 ops->cursor_state.image.bg_color = bg;
262 cursor.set |= FB_CUR_SETCMAP;
263 }
264
265 if (ops->cursor_state.image.height != vc->vc_font.width ||
266 ops->cursor_state.image.width != vc->vc_font.height ||
267 ops->cursor_reset) {
268 ops->cursor_state.image.height = vc->vc_font.width;
269 ops->cursor_state.image.width = vc->vc_font.height;
270 cursor.set |= FB_CUR_SETSIZE;
271 }
272
273 dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
274 dy = vc->vc_x * vc->vc_font.width;
275
276 if (ops->cursor_state.image.dx != dx ||
277 ops->cursor_state.image.dy != dy ||
278 ops->cursor_reset) {
279 ops->cursor_state.image.dx = dx;
280 ops->cursor_state.image.dy = dy;
281 cursor.set |= FB_CUR_SETPOS;
282 }
283
284 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
285 ops->cursor_reset) {
286 ops->cursor_state.hot.x = cursor.hot.y = 0;
287 cursor.set |= FB_CUR_SETHOT;
288 }
289
290 if (cursor.set & FB_CUR_SETSIZE ||
291 vc->vc_cursor_type != p->cursor_shape ||
292 ops->cursor_state.mask == NULL ||
293 ops->cursor_reset) {
294 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
295 int cur_height, size, i = 0;
296 int width = (vc->vc_font.width + 7)/8;
297
298 if (!mask)
299 return;
300
301 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
302
303 if (!tmp) {
304 kfree(mask);
305 return;
306 }
307
308 kfree(ops->cursor_state.mask);
309 ops->cursor_state.mask = mask;
310
311 p->cursor_shape = vc->vc_cursor_type;
312 cursor.set |= FB_CUR_SETSHAPE;
313
314 switch (p->cursor_shape & CUR_HWMASK) {
315 case CUR_NONE:
316 cur_height = 0;
317 break;
318 case CUR_UNDERLINE:
319 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
320 break;
321 case CUR_LOWER_THIRD:
322 cur_height = vc->vc_font.height/3;
323 break;
324 case CUR_LOWER_HALF:
325 cur_height = vc->vc_font.height >> 1;
326 break;
327 case CUR_TWO_THIRDS:
328 cur_height = (vc->vc_font.height << 1)/3;
329 break;
330 case CUR_BLOCK:
331 default:
332 cur_height = vc->vc_font.height;
333 break;
334 }
335
336 size = (vc->vc_font.height - cur_height) * width;
337 while (size--)
338 tmp[i++] = 0;
339 size = cur_height * width;
340 while (size--)
341 tmp[i++] = 0xff;
342 memset(mask, 0, w * vc->vc_font.width);
343 rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
344 kfree(tmp);
345 }
346
347 switch (mode) {
348 case CM_ERASE:
349 ops->cursor_state.enable = 0;
350 break;
351 case CM_DRAW:
352 case CM_MOVE:
353 default:
354 ops->cursor_state.enable = (use_sw) ? 0 : 1;
355 break;
356 }
357
358 cursor.image.data = src;
359 cursor.image.fg_color = ops->cursor_state.image.fg_color;
360 cursor.image.bg_color = ops->cursor_state.image.bg_color;
361 cursor.image.dx = ops->cursor_state.image.dx;
362 cursor.image.dy = ops->cursor_state.image.dy;
363 cursor.image.height = ops->cursor_state.image.height;
364 cursor.image.width = ops->cursor_state.image.width;
365 cursor.hot.x = ops->cursor_state.hot.x;
366 cursor.hot.y = ops->cursor_state.hot.y;
367 cursor.mask = ops->cursor_state.mask;
368 cursor.enable = ops->cursor_state.enable;
369 cursor.image.depth = 1;
370 cursor.rop = ROP_XOR;
371
372 if (info->fbops->fb_cursor)
373 err = info->fbops->fb_cursor(info, &cursor);
374
375 if (err)
376 soft_cursor(info, &cursor);
377
378 ops->cursor_reset = 0;
379}
380
381int cw_update_start(struct fb_info *info)
382{
383 struct fbcon_ops *ops = info->fbcon_par;
384 struct display *p = &fb_display[ops->currcon];
385 u32 vxres = GETVXRES(p->scrollmode, info);
386 u32 xoffset;
387 int err;
388
389 xoffset = vxres - (info->var.xres + ops->var.yoffset);
390 ops->var.yoffset = ops->var.xoffset;
391 ops->var.xoffset = xoffset;
392 err = fb_pan_display(info, &ops->var);
393 ops->var.xoffset = info->var.xoffset;
394 ops->var.yoffset = info->var.yoffset;
395 ops->var.vmode = info->var.vmode;
396 return err;
397}
398
399void fbcon_rotate_cw(struct fbcon_ops *ops)
400{
401 ops->bmove = cw_bmove;
402 ops->clear = cw_clear;
403 ops->putcs = cw_putcs;
404 ops->clear_margins = cw_clear_margins;
405 ops->cursor = cw_cursor;
406 ops->update_start = cw_update_start;
407}
408EXPORT_SYMBOL(fbcon_rotate_cw);
409
410MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
411MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
412MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
new file mode 100644
index 000000000000..ec0dd8fe241c
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.c
@@ -0,0 +1,117 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
22 struct display *p)
23{
24 struct fbcon_ops *ops = info->fbcon_par;
25 int len, err = 0;
26 int s_cellsize, d_cellsize, i;
27 const u8 *src;
28 u8 *dst;
29
30 if (vc->vc_font.data == ops->fontdata &&
31 p->con_rotate == ops->cur_rotate)
32 goto finished;
33
34 src = ops->fontdata = vc->vc_font.data;
35 ops->cur_rotate = p->con_rotate;
36 len = (!p->userfont) ? 256 : FNTCHARCNT(src);
37 s_cellsize = ((vc->vc_font.width + 7)/8) *
38 vc->vc_font.height;
39 d_cellsize = s_cellsize;
40
41 if (ops->rotate == FB_ROTATE_CW ||
42 ops->rotate == FB_ROTATE_CCW)
43 d_cellsize = ((vc->vc_font.height + 7)/8) *
44 vc->vc_font.width;
45
46 if (info->fbops->fb_sync)
47 info->fbops->fb_sync(info);
48
49 if (ops->fd_size < d_cellsize * len) {
50 dst = kmalloc(d_cellsize * len, GFP_KERNEL);
51
52 if (dst == NULL) {
53 err = -ENOMEM;
54 goto finished;
55 }
56
57 ops->fd_size = d_cellsize * len;
58 kfree(ops->fontbuffer);
59 ops->fontbuffer = dst;
60 }
61
62 dst = ops->fontbuffer;
63 memset(dst, 0, ops->fd_size);
64
65 switch (ops->rotate) {
66 case FB_ROTATE_UD:
67 for (i = len; i--; ) {
68 rotate_ud(src, dst, vc->vc_font.width,
69 vc->vc_font.height);
70
71 src += s_cellsize;
72 dst += d_cellsize;
73 }
74 break;
75 case FB_ROTATE_CW:
76 for (i = len; i--; ) {
77 rotate_cw(src, dst, vc->vc_font.width,
78 vc->vc_font.height);
79 src += s_cellsize;
80 dst += d_cellsize;
81 }
82 break;
83 case FB_ROTATE_CCW:
84 for (i = len; i--; ) {
85 rotate_ccw(src, dst, vc->vc_font.width,
86 vc->vc_font.height);
87 src += s_cellsize;
88 dst += d_cellsize;
89 }
90 break;
91 }
92
93finished:
94 return err;
95}
96
97void fbcon_set_rotate(struct fbcon_ops *ops)
98{
99 ops->rotate_font = fbcon_rotate_font;
100
101 switch(ops->rotate) {
102 case FB_ROTATE_CW:
103 fbcon_rotate_cw(ops);
104 break;
105 case FB_ROTATE_UD:
106 fbcon_rotate_ud(ops);
107 break;
108 case FB_ROTATE_CCW:
109 fbcon_rotate_ccw(ops);
110 break;
111 }
112}
113EXPORT_SYMBOL(fbcon_set_rotate);
114
115MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
116MODULE_DESCRIPTION("Console Rotation Support");
117MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
new file mode 100644
index 000000000000..90c672096c2e
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.h
@@ -0,0 +1,105 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _FBCON_ROTATE_H
12#define _FBCON_ROTATE_H
13
14#define FNTCHARCNT(fd) (((int *)(fd))[-3])
15
16#define GETVYRES(s,i) ({ \
17 (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
18 (i)->var.yres : (i)->var.yres_virtual; })
19
20#define GETVXRES(s,i) ({ \
21 (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
22 (i)->var.xres : (i)->var.xres_virtual; })
23
24/*
25 * The bitmap is always big endian
26 */
27#if defined(__LITTLE_ENDIAN)
28#define FBCON_BIT(b) (7 - (b))
29#else
30#define FBCON_BIT(b) (b)
31#endif
32
33static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
34{
35 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
36
37 pat +=index;
38 return (test_bit(FBCON_BIT(bit), (void *)pat));
39}
40
41static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
42{
43 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
44
45 pat += index;
46 set_bit(FBCON_BIT(bit), (void *)pat);
47}
48
49static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
50{
51 int i, j;
52 int shift = width % 8;
53
54 width = (width + 7) & ~7;
55
56 for (i = 0; i < height; i++) {
57 for (j = 0; j < width; j++) {
58 if (pattern_test_bit(j, i, width, in))
59 pattern_set_bit(width - (1 + j + shift),
60 height - (1 + i),
61 width, out);
62 }
63
64 }
65}
66
67static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
68{
69 int i, j, h = height, w = width;
70 int shift = (8 - (height % 8)) & 7;
71
72 width = (width + 7) & ~7;
73 height = (height + 7) & ~7;
74
75 for (i = 0; i < h; i++) {
76 for (j = 0; j < w; j++) {
77 if (pattern_test_bit(j, i, width, in))
78 pattern_set_bit(height - 1 - i - shift, j,
79 height, out);
80
81 }
82 }
83}
84
85static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
86{
87 int i, j, h = height, w = width;
88 int shift = width % 8;
89
90 width = (width + 7) & ~7;
91 height = (height + 7) & ~7;
92
93 for (i = 0; i < h; i++) {
94 for (j = 0; j < w; j++) {
95 if (pattern_test_bit(j, i, width, in))
96 pattern_set_bit(i, width - 1 - j - shift,
97 height, out);
98 }
99 }
100}
101
102extern void fbcon_rotate_cw(struct fbcon_ops *ops);
103extern void fbcon_rotate_ud(struct fbcon_ops *ops);
104extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
105#endif
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
new file mode 100644
index 000000000000..2e1d9d4249cd
--- /dev/null
+++ b/drivers/video/console/fbcon_ud.c
@@ -0,0 +1,454 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 180 degrees
23 */
24
25static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.width + 7) >> 3;
30 unsigned int cellsize = vc->vc_font.height * width;
31 u8 c;
32
33 offset = offset * width;
34
35 for (i = 0; i < cellsize; i++) {
36 c = src[i];
37 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
38 c = 0xff;
39 if (attribute & FBCON_ATTRIBUTE_BOLD)
40 c |= c << 1;
41 if (attribute & FBCON_ATTRIBUTE_REVERSE)
42 c = ~c;
43 dst[i] = c;
44 }
45}
46
47
48static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
49 int sx, int dy, int dx, int height, int width)
50{
51 struct display *p = &fb_display[vc->vc_num];
52 struct fb_copyarea area;
53 u32 vyres = GETVYRES(p->scrollmode, info);
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sy = vyres - ((sy + height) * vc->vc_font.height);
57 area.sx = vxres - ((sx + width) * vc->vc_font.width);
58 area.dy = vyres - ((dy + height) * vc->vc_font.height);
59 area.dx = vxres - ((dx + width) * vc->vc_font.width);
60 area.height = height * vc->vc_font.height;
61 area.width = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vyres = GETVYRES(p->scrollmode, info);
73 u32 vxres = GETVXRES(p->scrollmode, info);
74
75 region.color = attr_bgcol_ec(bgshift,vc);
76 region.dy = vyres - ((sy + height) * vc->vc_font.height);
77 region.dx = vxres - ((sx + width) * vc->vc_font.width);
78 region.width = width * vc->vc_font.width;
79 region.height = height * vc->vc_font.height;
80 region.rop = ROP_COPY;
81
82 info->fbops->fb_fillrect(info, &region);
83}
84
85static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
86 const u16 *s, u32 attr, u32 cnt,
87 u32 d_pitch, u32 s_pitch, u32 cellsize,
88 struct fb_image *image, u8 *buf, u8 *dst)
89{
90 struct fbcon_ops *ops = info->fbcon_par;
91 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
92 u32 idx = vc->vc_font.width >> 3;
93 u8 *src;
94
95 while (cnt--) {
96 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
97
98 if (attr) {
99 ud_update_attr(buf, src, attr, vc);
100 src = buf;
101 }
102
103 if (likely(idx == 1))
104 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
105 image->height);
106 else
107 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
108 image->height);
109
110 dst += s_pitch;
111 }
112
113 info->fbops->fb_imageblit(info, image);
114}
115
116static inline void ud_putcs_unaligned(struct vc_data *vc,
117 struct fb_info *info, const u16 *s,
118 u32 attr, u32 cnt, u32 d_pitch,
119 u32 s_pitch, u32 cellsize,
120 struct fb_image *image, u8 *buf,
121 u8 *dst)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
125 u32 shift_low = 0, mod = vc->vc_font.width % 8;
126 u32 shift_high = 8;
127 u32 idx = vc->vc_font.width >> 3;
128 u8 *src;
129
130 while (cnt--) {
131 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
132
133 if (attr) {
134 ud_update_attr(buf, src, attr, vc);
135 src = buf;
136 }
137
138 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
139 image->height, shift_high,
140 shift_low, mod);
141 shift_low += mod;
142 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
143 shift_low &= 7;
144 shift_high = 8 - shift_low;
145 }
146
147 info->fbops->fb_imageblit(info, image);
148
149}
150
151static void ud_putcs(struct vc_data *vc, struct fb_info *info,
152 const unsigned short *s, int count, int yy, int xx,
153 int fg, int bg)
154{
155 struct fb_image image;
156 struct display *p = &fb_display[vc->vc_num];
157 struct fbcon_ops *ops = info->fbcon_par;
158 u32 width = (vc->vc_font.width + 7)/8;
159 u32 cellsize = width * vc->vc_font.height;
160 u32 maxcnt = info->pixmap.size/cellsize;
161 u32 scan_align = info->pixmap.scan_align - 1;
162 u32 buf_align = info->pixmap.buf_align - 1;
163 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
164 u32 attribute = get_attribute(info, scr_readw(s));
165 u8 *dst, *buf = NULL;
166 u32 vyres = GETVYRES(p->scrollmode, info);
167 u32 vxres = GETVXRES(p->scrollmode, info);
168
169 if (!ops->fontbuffer)
170 return;
171
172 image.fg_color = fg;
173 image.bg_color = bg;
174 image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
175 image.dx = vxres - ((xx + count) * vc->vc_font.width);
176 image.height = vc->vc_font.height;
177 image.depth = 1;
178
179 if (attribute) {
180 buf = kmalloc(cellsize, GFP_KERNEL);
181 if (!buf)
182 return;
183 }
184
185 s += count - 1;
186
187 while (count) {
188 if (count > maxcnt)
189 cnt = maxcnt;
190 else
191 cnt = count;
192
193 image.width = vc->vc_font.width * cnt;
194 pitch = ((image.width + 7) >> 3) + scan_align;
195 pitch &= ~scan_align;
196 size = pitch * image.height + buf_align;
197 size &= ~buf_align;
198 dst = fb_get_buffer_offset(info, &info->pixmap, size);
199 image.data = dst;
200
201 if (!mod)
202 ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
203 width, cellsize, &image, buf, dst);
204 else
205 ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
206 width, cellsize, &image,
207 buf, dst);
208
209 image.dx += image.width;
210 count -= cnt;
211 s -= cnt;
212 xx += cnt;
213 }
214
215 /* buf is always NULL except when in monochrome mode, so in this case
216 it's a gain to check buf against NULL even though kfree() handles
217 NULL pointers just fine */
218 if (unlikely(buf))
219 kfree(buf);
220
221}
222
223static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
224 int bottom_only)
225{
226 unsigned int cw = vc->vc_font.width;
227 unsigned int ch = vc->vc_font.height;
228 unsigned int rw = info->var.xres - (vc->vc_cols*cw);
229 unsigned int bh = info->var.yres - (vc->vc_rows*ch);
230 struct fb_fillrect region;
231 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
232
233 region.color = attr_bgcol_ec(bgshift,vc);
234 region.rop = ROP_COPY;
235
236 if (rw && !bottom_only) {
237 region.dy = 0;
238 region.dx = info->var.xoffset;
239 region.width = rw;
240 region.height = info->var.yres_virtual;
241 info->fbops->fb_fillrect(info, &region);
242 }
243
244 if (bh) {
245 region.dy = info->var.yoffset;
246 region.dx = info->var.xoffset;
247 region.height = bh;
248 region.width = info->var.xres;
249 info->fbops->fb_fillrect(info, &region);
250 }
251}
252
253static void ud_cursor(struct vc_data *vc, struct fb_info *info,
254 struct display *p, int mode, int softback_lines,
255 int fg, int bg)
256{
257 struct fb_cursor cursor;
258 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
259 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
260 int w = (vc->vc_font.width + 7) >> 3, c;
261 int y = real_y(p, vc->vc_y);
262 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
263 int err = 1, dx, dy;
264 char *src;
265 u32 vyres = GETVYRES(p->scrollmode, info);
266 u32 vxres = GETVXRES(p->scrollmode, info);
267
268 if (!ops->fontbuffer)
269 return;
270
271 cursor.set = 0;
272
273 if (softback_lines) {
274 if (y + softback_lines >= vc->vc_rows) {
275 mode = CM_ERASE;
276 ops->cursor_flash = 0;
277 return;
278 } else
279 y += softback_lines;
280 }
281
282 c = scr_readw((u16 *) vc->vc_pos);
283 attribute = get_attribute(info, c);
284 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
285
286 if (ops->cursor_state.image.data != src ||
287 ops->cursor_reset) {
288 ops->cursor_state.image.data = src;
289 cursor.set |= FB_CUR_SETIMAGE;
290 }
291
292 if (attribute) {
293 u8 *dst;
294
295 dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
296 if (!dst)
297 return;
298 kfree(ops->cursor_data);
299 ops->cursor_data = dst;
300 ud_update_attr(dst, src, attribute, vc);
301 src = dst;
302 }
303
304 if (ops->cursor_state.image.fg_color != fg ||
305 ops->cursor_state.image.bg_color != bg ||
306 ops->cursor_reset) {
307 ops->cursor_state.image.fg_color = fg;
308 ops->cursor_state.image.bg_color = bg;
309 cursor.set |= FB_CUR_SETCMAP;
310 }
311
312 if (ops->cursor_state.image.height != vc->vc_font.height ||
313 ops->cursor_state.image.width != vc->vc_font.width ||
314 ops->cursor_reset) {
315 ops->cursor_state.image.height = vc->vc_font.height;
316 ops->cursor_state.image.width = vc->vc_font.width;
317 cursor.set |= FB_CUR_SETSIZE;
318 }
319
320 dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
321 dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
322
323 if (ops->cursor_state.image.dx != dx ||
324 ops->cursor_state.image.dy != dy ||
325 ops->cursor_reset) {
326 ops->cursor_state.image.dx = dx;
327 ops->cursor_state.image.dy = dy;
328 cursor.set |= FB_CUR_SETPOS;
329 }
330
331 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
332 ops->cursor_reset) {
333 ops->cursor_state.hot.x = cursor.hot.y = 0;
334 cursor.set |= FB_CUR_SETHOT;
335 }
336
337 if (cursor.set & FB_CUR_SETSIZE ||
338 vc->vc_cursor_type != p->cursor_shape ||
339 ops->cursor_state.mask == NULL ||
340 ops->cursor_reset) {
341 char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
342 int cur_height, size, i = 0;
343 u8 msk = 0xff;
344
345 if (!mask)
346 return;
347
348 kfree(ops->cursor_state.mask);
349 ops->cursor_state.mask = mask;
350
351 p->cursor_shape = vc->vc_cursor_type;
352 cursor.set |= FB_CUR_SETSHAPE;
353
354 switch (p->cursor_shape & CUR_HWMASK) {
355 case CUR_NONE:
356 cur_height = 0;
357 break;
358 case CUR_UNDERLINE:
359 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
360 break;
361 case CUR_LOWER_THIRD:
362 cur_height = vc->vc_font.height/3;
363 break;
364 case CUR_LOWER_HALF:
365 cur_height = vc->vc_font.height >> 1;
366 break;
367 case CUR_TWO_THIRDS:
368 cur_height = (vc->vc_font.height << 1)/3;
369 break;
370 case CUR_BLOCK:
371 default:
372 cur_height = vc->vc_font.height;
373 break;
374 }
375
376 size = cur_height * w;
377
378 while (size--)
379 mask[i++] = msk;
380
381 size = (vc->vc_font.height - cur_height) * w;
382
383 while (size--)
384 mask[i++] = ~msk;
385 }
386
387 switch (mode) {
388 case CM_ERASE:
389 ops->cursor_state.enable = 0;
390 break;
391 case CM_DRAW:
392 case CM_MOVE:
393 default:
394 ops->cursor_state.enable = (use_sw) ? 0 : 1;
395 break;
396 }
397
398 cursor.image.data = src;
399 cursor.image.fg_color = ops->cursor_state.image.fg_color;
400 cursor.image.bg_color = ops->cursor_state.image.bg_color;
401 cursor.image.dx = ops->cursor_state.image.dx;
402 cursor.image.dy = ops->cursor_state.image.dy;
403 cursor.image.height = ops->cursor_state.image.height;
404 cursor.image.width = ops->cursor_state.image.width;
405 cursor.hot.x = ops->cursor_state.hot.x;
406 cursor.hot.y = ops->cursor_state.hot.y;
407 cursor.mask = ops->cursor_state.mask;
408 cursor.enable = ops->cursor_state.enable;
409 cursor.image.depth = 1;
410 cursor.rop = ROP_XOR;
411
412 if (info->fbops->fb_cursor)
413 err = info->fbops->fb_cursor(info, &cursor);
414
415 if (err)
416 soft_cursor(info, &cursor);
417
418 ops->cursor_reset = 0;
419}
420
421int ud_update_start(struct fb_info *info)
422{
423 struct fbcon_ops *ops = info->fbcon_par;
424 struct display *p = &fb_display[ops->currcon];
425 u32 xoffset, yoffset;
426 u32 vyres = GETVYRES(p->scrollmode, info);
427 u32 vxres = GETVXRES(p->scrollmode, info);
428 int err;
429
430 xoffset = (vxres - info->var.xres) - ops->var.xoffset;
431 yoffset = (vyres - info->var.yres) - ops->var.yoffset;
432 ops->var.xoffset = xoffset;
433 ops->var.yoffset = yoffset;
434 err = fb_pan_display(info, &ops->var);
435 ops->var.xoffset = info->var.xoffset;
436 ops->var.yoffset = info->var.yoffset;
437 ops->var.vmode = info->var.vmode;
438 return err;
439}
440
441void fbcon_rotate_ud(struct fbcon_ops *ops)
442{
443 ops->bmove = ud_bmove;
444 ops->clear = ud_clear;
445 ops->putcs = ud_putcs;
446 ops->clear_margins = ud_clear_margins;
447 ops->cursor = ud_cursor;
448 ops->update_start = ud_update_start;
449}
450EXPORT_SYMBOL(fbcon_rotate_ud);
451
452MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
453MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
454MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 7f76e2c6a4a1..cb25324a5635 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info,
118 info->tileops->fb_tilecursor(info, &cursor); 118 info->tileops->fb_tilecursor(info, &cursor);
119} 119}
120 120
121static int tile_update_start(struct fb_info *info)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 int err;
125
126 err = fb_pan_display(info, &ops->var);
127 ops->var.xoffset = info->var.xoffset;
128 ops->var.yoffset = info->var.yoffset;
129 ops->var.vmode = info->var.vmode;
130 return err;
131}
132
121void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, 133void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
122 struct display *p, struct fbcon_ops *ops) 134 struct display *p, struct fbcon_ops *ops)
123{ 135{
@@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
128 ops->putcs = tile_putcs; 140 ops->putcs = tile_putcs;
129 ops->clear_margins = tile_clear_margins; 141 ops->clear_margins = tile_clear_margins;
130 ops->cursor = tile_cursor; 142 ops->cursor = tile_cursor;
143 ops->update_start = tile_update_start;
131 144
132 if (p) { 145 if (p) {
133 map.width = vc->vc_font.width; 146 map.width = vc->vc_font.width;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2667ddab3f1..9f180096c896 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16 16
17#include <linux/compat.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/sched.h> 20#include <linux/sched.h>
@@ -323,9 +324,103 @@ static struct logo_data {
323 const struct linux_logo *logo; 324 const struct linux_logo *logo;
324} fb_logo; 325} fb_logo;
325 326
326int fb_prepare_logo(struct fb_info *info) 327static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
328{
329 u32 size = width * height, i;
330
331 out += size - 1;
332
333 for (i = size; i--; )
334 *out-- = *in++;
335}
336
337static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
338{
339 int i, j, w = width - 1;
340
341 for (i = 0; i < height; i++)
342 for (j = 0; j < width; j++)
343 out[height * j + w - i] = *in++;
344}
345
346static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
347{
348 int i, j, w = width - 1;
349
350 for (i = 0; i < height; i++)
351 for (j = 0; j < width; j++)
352 out[height * (w - j) + i] = *in++;
353}
354
355static void fb_rotate_logo(struct fb_info *info, u8 *dst,
356 struct fb_image *image, int rotate)
357{
358 u32 tmp;
359
360 if (rotate == FB_ROTATE_UD) {
361 image->dx = info->var.xres - image->width;
362 image->dy = info->var.yres - image->height;
363 fb_rotate_logo_ud(image->data, dst, image->width,
364 image->height);
365 } else if (rotate == FB_ROTATE_CW) {
366 tmp = image->width;
367 image->width = image->height;
368 image->height = tmp;
369 image->dx = info->var.xres - image->height;
370 fb_rotate_logo_cw(image->data, dst, image->width,
371 image->height);
372 } else if (rotate == FB_ROTATE_CCW) {
373 tmp = image->width;
374 image->width = image->height;
375 image->height = tmp;
376 image->dy = info->var.yres - image->width;
377 fb_rotate_logo_ccw(image->data, dst, image->width,
378 image->height);
379 }
380
381 image->data = dst;
382}
383
384static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
385 int rotate)
386{
387 int x;
388
389 if (rotate == FB_ROTATE_UR) {
390 for (x = 0; x < num_online_cpus() &&
391 x * (fb_logo.logo->width + 8) <=
392 info->var.xres - fb_logo.logo->width; x++) {
393 info->fbops->fb_imageblit(info, image);
394 image->dx += fb_logo.logo->width + 8;
395 }
396 } else if (rotate == FB_ROTATE_UD) {
397 for (x = 0; x < num_online_cpus() &&
398 x * (fb_logo.logo->width + 8) <=
399 info->var.xres - fb_logo.logo->width; x++) {
400 info->fbops->fb_imageblit(info, image);
401 image->dx -= fb_logo.logo->width + 8;
402 }
403 } else if (rotate == FB_ROTATE_CW) {
404 for (x = 0; x < num_online_cpus() &&
405 x * (fb_logo.logo->width + 8) <=
406 info->var.yres - fb_logo.logo->width; x++) {
407 info->fbops->fb_imageblit(info, image);
408 image->dy += fb_logo.logo->width + 8;
409 }
410 } else if (rotate == FB_ROTATE_CCW) {
411 for (x = 0; x < num_online_cpus() &&
412 x * (fb_logo.logo->width + 8) <=
413 info->var.yres - fb_logo.logo->width; x++) {
414 info->fbops->fb_imageblit(info, image);
415 image->dy -= fb_logo.logo->width + 8;
416 }
417 }
418}
419
420int fb_prepare_logo(struct fb_info *info, int rotate)
327{ 421{
328 int depth = fb_get_color_depth(&info->var, &info->fix); 422 int depth = fb_get_color_depth(&info->var, &info->fix);
423 int yres;
329 424
330 memset(&fb_logo, 0, sizeof(struct logo_data)); 425 memset(&fb_logo, 0, sizeof(struct logo_data));
331 426
@@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info)
358 /* Return if no suitable logo was found */ 453 /* Return if no suitable logo was found */
359 fb_logo.logo = fb_find_logo(depth); 454 fb_logo.logo = fb_find_logo(depth);
360 455
361 if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { 456 if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
457 yres = info->var.yres;
458 else
459 yres = info->var.xres;
460
461 if (fb_logo.logo && fb_logo.logo->height > yres) {
362 fb_logo.logo = NULL; 462 fb_logo.logo = NULL;
363 return 0; 463 return 0;
364 } 464 }
465
365 /* What depth we asked for might be different from what we get */ 466 /* What depth we asked for might be different from what we get */
366 if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 467 if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
367 fb_logo.depth = 8; 468 fb_logo.depth = 8;
@@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info)
372 return fb_logo.logo->height; 473 return fb_logo.logo->height;
373} 474}
374 475
375int fb_show_logo(struct fb_info *info) 476int fb_show_logo(struct fb_info *info, int rotate)
376{ 477{
377 u32 *palette = NULL, *saved_pseudo_palette = NULL; 478 u32 *palette = NULL, *saved_pseudo_palette = NULL;
378 unsigned char *logo_new = NULL; 479 unsigned char *logo_new = NULL, *logo_rotate = NULL;
379 struct fb_image image; 480 struct fb_image image;
380 int x;
381 481
382 /* Return if the frame buffer is not mapped or suspended */ 482 /* Return if the frame buffer is not mapped or suspended */
383 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 483 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info)
417 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); 517 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
418 } 518 }
419 519
520 image.dx = 0;
521 image.dy = 0;
420 image.width = fb_logo.logo->width; 522 image.width = fb_logo.logo->width;
421 image.height = fb_logo.logo->height; 523 image.height = fb_logo.logo->height;
422 image.dy = 0;
423 524
424 for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && 525 if (rotate) {
425 x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { 526 logo_rotate = kmalloc(fb_logo.logo->width *
426 image.dx = x; 527 fb_logo.logo->height, GFP_KERNEL);
427 info->fbops->fb_imageblit(info, &image); 528 if (logo_rotate)
529 fb_rotate_logo(info, logo_rotate, &image, rotate);
428 } 530 }
429 531
532 fb_do_show_logo(info, &image, rotate);
533
430 kfree(palette); 534 kfree(palette);
431 if (saved_pseudo_palette != NULL) 535 if (saved_pseudo_palette != NULL)
432 info->pseudo_palette = saved_pseudo_palette; 536 info->pseudo_palette = saved_pseudo_palette;
433 kfree(logo_new); 537 kfree(logo_new);
538 kfree(logo_rotate);
434 return fb_logo.logo->height; 539 return fb_logo.logo->height;
435} 540}
436#else 541#else
437int fb_prepare_logo(struct fb_info *info) { return 0; } 542int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
438int fb_show_logo(struct fb_info *info) { return 0; } 543int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
439#endif /* CONFIG_LOGO */ 544#endif /* CONFIG_LOGO */
440 545
441static int fbmem_read_proc(char *buf, char **start, off_t offset, 546static int fbmem_read_proc(char *buf, char **start, off_t offset,
@@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
829} 934}
830 935
831#ifdef CONFIG_COMPAT 936#ifdef CONFIG_COMPAT
937struct fb_fix_screeninfo32 {
938 char id[16];
939 compat_caddr_t smem_start;
940 u32 smem_len;
941 u32 type;
942 u32 type_aux;
943 u32 visual;
944 u16 xpanstep;
945 u16 ypanstep;
946 u16 ywrapstep;
947 u32 line_length;
948 compat_caddr_t mmio_start;
949 u32 mmio_len;
950 u32 accel;
951 u16 reserved[3];
952};
953
954struct fb_cmap32 {
955 u32 start;
956 u32 len;
957 compat_caddr_t red;
958 compat_caddr_t green;
959 compat_caddr_t blue;
960 compat_caddr_t transp;
961};
962
963static int fb_getput_cmap(struct inode *inode, struct file *file,
964 unsigned int cmd, unsigned long arg)
965{
966 struct fb_cmap_user __user *cmap;
967 struct fb_cmap32 __user *cmap32;
968 __u32 data;
969 int err;
970
971 cmap = compat_alloc_user_space(sizeof(*cmap));
972 cmap32 = compat_ptr(arg);
973
974 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
975 return -EFAULT;
976
977 if (get_user(data, &cmap32->red) ||
978 put_user(compat_ptr(data), &cmap->red) ||
979 get_user(data, &cmap32->green) ||
980 put_user(compat_ptr(data), &cmap->green) ||
981 get_user(data, &cmap32->blue) ||
982 put_user(compat_ptr(data), &cmap->blue) ||
983 get_user(data, &cmap32->transp) ||
984 put_user(compat_ptr(data), &cmap->transp))
985 return -EFAULT;
986
987 err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
988
989 if (!err) {
990 if (copy_in_user(&cmap32->start,
991 &cmap->start,
992 2 * sizeof(__u32)))
993 err = -EFAULT;
994 }
995 return err;
996}
997
998static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
999 struct fb_fix_screeninfo32 __user *fix32)
1000{
1001 __u32 data;
1002 int err;
1003
1004 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
1005
1006 data = (__u32) (unsigned long) fix->smem_start;
1007 err |= put_user(data, &fix32->smem_start);
1008
1009 err |= put_user(fix->smem_len, &fix32->smem_len);
1010 err |= put_user(fix->type, &fix32->type);
1011 err |= put_user(fix->type_aux, &fix32->type_aux);
1012 err |= put_user(fix->visual, &fix32->visual);
1013 err |= put_user(fix->xpanstep, &fix32->xpanstep);
1014 err |= put_user(fix->ypanstep, &fix32->ypanstep);
1015 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
1016 err |= put_user(fix->line_length, &fix32->line_length);
1017
1018 data = (__u32) (unsigned long) fix->mmio_start;
1019 err |= put_user(data, &fix32->mmio_start);
1020
1021 err |= put_user(fix->mmio_len, &fix32->mmio_len);
1022 err |= put_user(fix->accel, &fix32->accel);
1023 err |= copy_to_user(fix32->reserved, fix->reserved,
1024 sizeof(fix->reserved));
1025
1026 return err;
1027}
1028
1029static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
1030 unsigned int cmd, unsigned long arg)
1031{
1032 mm_segment_t old_fs;
1033 struct fb_fix_screeninfo fix;
1034 struct fb_fix_screeninfo32 __user *fix32;
1035 int err;
1036
1037 fix32 = compat_ptr(arg);
1038
1039 old_fs = get_fs();
1040 set_fs(KERNEL_DS);
1041 err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
1042 set_fs(old_fs);
1043
1044 if (!err)
1045 err = do_fscreeninfo_to_user(&fix, fix32);
1046
1047 return err;
1048}
1049
832static long 1050static long
833fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1051fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
834{ 1052{
835 int fbidx = iminor(file->f_dentry->d_inode); 1053 struct inode *inode = file->f_dentry->d_inode;
1054 int fbidx = iminor(inode);
836 struct fb_info *info = registered_fb[fbidx]; 1055 struct fb_info *info = registered_fb[fbidx];
837 struct fb_ops *fb = info->fbops; 1056 struct fb_ops *fb = info->fbops;
838 long ret; 1057 long ret = -ENOIOCTLCMD;
839 1058
840 if (fb->fb_compat_ioctl == NULL)
841 return -ENOIOCTLCMD;
842 lock_kernel(); 1059 lock_kernel();
843 ret = fb->fb_compat_ioctl(file, cmd, arg, info); 1060 switch(cmd) {
1061 case FBIOGET_VSCREENINFO:
1062 case FBIOPUT_VSCREENINFO:
1063 case FBIOPAN_DISPLAY:
1064 case FBIOGET_CON2FBMAP:
1065 case FBIOPUT_CON2FBMAP:
1066 arg = (unsigned long) compat_ptr(arg);
1067 case FBIOBLANK:
1068 ret = fb_ioctl(inode, file, cmd, arg);
1069 break;
1070
1071 case FBIOGET_FSCREENINFO:
1072 ret = fb_get_fscreeninfo(inode, file, cmd, arg);
1073 break;
1074
1075 case FBIOGETCMAP:
1076 case FBIOPUTCMAP:
1077 ret = fb_getput_cmap(inode, file, cmd, arg);
1078 break;
1079
1080 default:
1081 if (fb->fb_compat_ioctl)
1082 ret = fb->fb_compat_ioctl(file, cmd, arg, info);
1083 break;
1084 }
844 unlock_kernel(); 1085 unlock_kernel();
845 return ret; 1086 return ret;
846} 1087}
@@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info)
1215 return err; 1456 return err;
1216} 1457}
1217 1458
1459/**
1460 * fb_con_duit - user<->fbcon passthrough
1461 * @info: struct fb_info
1462 * @event: notification event to be passed to fbcon
1463 * @data: private data
1464 *
1465 * DESCRIPTION
1466 * This function is an fbcon-user event passing channel
1467 * which bypasses fbdev. This is hopefully temporary
1468 * until a user interface for fbcon is created
1469 */
1470int fb_con_duit(struct fb_info *info, int event, void *data)
1471{
1472 struct fb_event evnt;
1473
1474 evnt.info = info;
1475 evnt.data = data;
1476
1477 return notifier_call_chain(&fb_notifier_list, event, &evnt);
1478}
1479EXPORT_SYMBOL(fb_con_duit);
1480
1218static char *video_options[FB_MAX]; 1481static char *video_options[FB_MAX];
1219static int ofonly; 1482static int ofonly;
1220 1483
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 007c8e9b2b39..08dac9580d15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf)
213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); 213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
214} 214}
215 215
216static ssize_t store_rotate(struct class_device *class_device, const char *buf,
217 size_t count)
218{
219 struct fb_info *fb_info = class_get_devdata(class_device);
220 struct fb_var_screeninfo var;
221 char **last = NULL;
222 int err;
223
224 var = fb_info->var;
225 var.rotate = simple_strtoul(buf, last, 0);
226
227 if ((err = activate(fb_info, &var)))
228 return err;
229
230 return count;
231}
232
233
234static ssize_t show_rotate(struct class_device *class_device, char *buf)
235{
236 struct fb_info *fb_info = class_get_devdata(class_device);
237
238 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
239}
240
241static ssize_t store_con_rotate(struct class_device *class_device,
242 const char *buf, size_t count)
243{
244 struct fb_info *fb_info = class_get_devdata(class_device);
245 int rotate;
246 char **last = NULL;
247
248 acquire_console_sem();
249 rotate = simple_strtoul(buf, last, 0);
250 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
251 release_console_sem();
252 return count;
253}
254
255static ssize_t store_con_rotate_all(struct class_device *class_device,
256 const char *buf, size_t count)
257{
258 struct fb_info *fb_info = class_get_devdata(class_device);
259 int rotate;
260 char **last = NULL;
261
262 acquire_console_sem();
263 rotate = simple_strtoul(buf, last, 0);
264 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
265 release_console_sem();
266 return count;
267}
268
269static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
270{
271 struct fb_info *fb_info = class_get_devdata(class_device);
272 int rotate;
273
274 acquire_console_sem();
275 rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
276 release_console_sem();
277 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
278}
279
216static ssize_t store_virtual(struct class_device *class_device, 280static ssize_t store_virtual(struct class_device *class_device,
217 const char * buf, size_t count) 281 const char * buf, size_t count)
218{ 282{
@@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = {
440 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), 504 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
441 __ATTR(name, S_IRUGO, show_name, NULL), 505 __ATTR(name, S_IRUGO, show_name, NULL),
442 __ATTR(stride, S_IRUGO, show_stride, NULL), 506 __ATTR(stride, S_IRUGO, show_stride, NULL),
507 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
508 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
509 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
443}; 510};
444 511
445int fb_init_class_device(struct fb_info *fb_info) 512int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 0799b999b314..427689e584da 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -122,7 +122,6 @@
122#include <linux/pci.h> 122#include <linux/pci.h>
123#include <linux/vmalloc.h> 123#include <linux/vmalloc.h>
124#include <linux/pagemap.h> 124#include <linux/pagemap.h>
125#include <linux/version.h>
126 125
127#include <asm/io.h> 126#include <asm/io.h>
128 127
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index ac94c2e5ff85..624c4bc96f0d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -34,7 +34,6 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/version.h>
38 37
39#include <asm/io.h> 38#include <asm/io.h>
40 39
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 1789a52d776a..1da2f84bdc25 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = {
251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, 251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
254 }, 258 },
255}; 259};
256 260
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index f0dfb35e3191..09e2f2841901 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1315,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info)
1315 info->fix.line_length = info->var.xres_virtual * 1315 info->fix.line_length = info->var.xres_virtual *
1316 info->var.bits_per_pixel / 8; 1316 info->var.bits_per_pixel / 8;
1317 1317
1318 if (info->var.bits_per_pixel == 8) 1318 if (info->var.bits_per_pixel == 8) {
1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1320 else 1320 info->fix.xpanstep = 4;
1321 } else {
1321 info->fix.visual = FB_VISUAL_TRUECOLOR; 1322 info->fix.visual = FB_VISUAL_TRUECOLOR;
1323 info->fix.xpanstep = 2;
1324 }
1325
1322} 1326}
1323 1327
1324#if defined(CONFIG_FB_SAVAGE_ACCEL) 1328#if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -1363,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info)
1363 par->minClock = 10000; 1367 par->minClock = 10000;
1364 1368
1365 savagefb_set_par_int (par); 1369 savagefb_set_par_int (par);
1366 savagefb_update_start (par, var);
1367 fb_set_cmap (&info->cmap, info); 1370 fb_set_cmap (&info->cmap, info);
1368 savagefb_set_fix(info); 1371 savagefb_set_fix(info);
1369 savagefb_set_clip(info); 1372 savagefb_set_clip(info);
@@ -1873,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1873 1876
1874 info->fix.type = FB_TYPE_PACKED_PIXELS; 1877 info->fix.type = FB_TYPE_PACKED_PIXELS;
1875 info->fix.type_aux = 0; 1878 info->fix.type_aux = 0;
1876 info->fix.xpanstep = 2;
1877 info->fix.ypanstep = 1; 1879 info->fix.ypanstep = 1;
1878 info->fix.ywrapstep = 0; 1880 info->fix.ywrapstep = 0;
1879 info->fix.accel = id->driver_data; 1881 info->fix.accel = id->driver_data;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 690bb6fe8281..226ae8a88482 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <video/vga.h> 27#include <video/vga.h>
@@ -51,35 +52,33 @@
51 * card parameters 52 * card parameters
52 */ 53 */
53 54
54static struct fb_info vga16fb; 55struct vga16fb_par {
55
56static struct vga16fb_par {
57 /* structure holding original VGA register settings when the 56 /* structure holding original VGA register settings when the
58 screen is blanked */ 57 screen is blanked */
59 struct { 58 struct {
60 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ 59 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
61 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ 60 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
62 unsigned char CrtMiscIO; /* Miscellaneous register */ 61 unsigned char CrtMiscIO; /* Miscellaneous register */
63 unsigned char HorizontalTotal; /* CRT-Controller:00h */ 62 unsigned char HorizontalTotal; /* CRT-Controller:00h */
64 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ 63 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
65 unsigned char StartHorizRetrace; /* CRT-Controller:04h */ 64 unsigned char StartHorizRetrace;/* CRT-Controller:04h */
66 unsigned char EndHorizRetrace; /* CRT-Controller:05h */ 65 unsigned char EndHorizRetrace; /* CRT-Controller:05h */
67 unsigned char Overflow; /* CRT-Controller:07h */ 66 unsigned char Overflow; /* CRT-Controller:07h */
68 unsigned char StartVertRetrace; /* CRT-Controller:10h */ 67 unsigned char StartVertRetrace; /* CRT-Controller:10h */
69 unsigned char EndVertRetrace; /* CRT-Controller:11h */ 68 unsigned char EndVertRetrace; /* CRT-Controller:11h */
70 unsigned char ModeControl; /* CRT-Controller:17h */ 69 unsigned char ModeControl; /* CRT-Controller:17h */
71 unsigned char ClockingMode; /* Seq-Controller:01h */ 70 unsigned char ClockingMode; /* Seq-Controller:01h */
72 } vga_state; 71 } vga_state;
73 struct vgastate state; 72 struct vgastate state;
74 atomic_t ref_count; 73 atomic_t ref_count;
75 int palette_blanked, vesa_blanked, mode, isVGA; 74 int palette_blanked, vesa_blanked, mode, isVGA;
76 u8 misc, pel_msk, vss, clkdiv; 75 u8 misc, pel_msk, vss, clkdiv;
77 u8 crtc[VGA_CRT_C]; 76 u8 crtc[VGA_CRT_C];
78} vga16_par; 77};
79 78
80/* --------------------------------------------------------------------- */ 79/* --------------------------------------------------------------------- */
81 80
82static struct fb_var_screeninfo vga16fb_defined = { 81static struct fb_var_screeninfo vga16fb_defined __initdata = {
83 .xres = 640, 82 .xres = 640,
84 .yres = 480, 83 .yres = 480,
85 .xres_virtual = 640, 84 .xres_virtual = 640,
@@ -205,7 +204,7 @@ static inline void setindex(int index)
205static void vga16fb_pan_var(struct fb_info *info, 204static void vga16fb_pan_var(struct fb_info *info,
206 struct fb_var_screeninfo *var) 205 struct fb_var_screeninfo *var)
207{ 206{
208 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 207 struct vga16fb_par *par = info->par;
209 u32 xoffset, pos; 208 u32 xoffset, pos;
210 209
211 xoffset = var->xoffset; 210 xoffset = var->xoffset;
@@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
300 299
301static int vga16fb_open(struct fb_info *info, int user) 300static int vga16fb_open(struct fb_info *info, int user)
302{ 301{
303 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 302 struct vga16fb_par *par = info->par;
304 int cnt = atomic_read(&par->ref_count); 303 int cnt = atomic_read(&par->ref_count);
305 304
306 if (!cnt) { 305 if (!cnt) {
@@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user)
315 314
316static int vga16fb_release(struct fb_info *info, int user) 315static int vga16fb_release(struct fb_info *info, int user)
317{ 316{
318 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 317 struct vga16fb_par *par = info->par;
319 int cnt = atomic_read(&par->ref_count); 318 int cnt = atomic_read(&par->ref_count);
320 319
321 if (!cnt) 320 if (!cnt)
@@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user)
330static int vga16fb_check_var(struct fb_var_screeninfo *var, 329static int vga16fb_check_var(struct fb_var_screeninfo *var,
331 struct fb_info *info) 330 struct fb_info *info)
332{ 331{
333 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 332 struct vga16fb_par *par = info->par;
334 u32 xres, right, hslen, left, xtotal; 333 u32 xres, right, hslen, left, xtotal;
335 u32 yres, lower, vslen, upper, ytotal; 334 u32 yres, lower, vslen, upper, ytotal;
336 u32 vxres, xoffset, vyres, yoffset; 335 u32 vxres, xoffset, vyres, yoffset;
@@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
535 534
536static int vga16fb_set_par(struct fb_info *info) 535static int vga16fb_set_par(struct fb_info *info)
537{ 536{
538 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 537 struct vga16fb_par *par = info->par;
539 u8 gdc[VGA_GFX_C]; 538 u8 gdc[VGA_GFX_C];
540 u8 seq[VGA_SEQ_C]; 539 u8 seq[VGA_SEQ_C];
541 u8 atc[VGA_ATT_C]; 540 u8 atc[VGA_ATT_C];
@@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
677 unsigned blue, unsigned transp, 676 unsigned blue, unsigned transp,
678 struct fb_info *info) 677 struct fb_info *info)
679{ 678{
680 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 679 struct vga16fb_par *par = info->par;
681 int gray; 680 int gray;
682 681
683 /* 682 /*
@@ -850,7 +849,7 @@ static void vga_pal_blank(void)
850/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 849/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
851static int vga16fb_blank(int blank, struct fb_info *info) 850static int vga16fb_blank(int blank, struct fb_info *info)
852{ 851{
853 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 852 struct vga16fb_par *par = info->par;
854 853
855 switch (blank) { 854 switch (blank) {
856 case FB_BLANK_UNBLANK: /* Unblank */ 855 case FB_BLANK_UNBLANK: /* Unblank */
@@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im
1201{ 1200{
1202 char __iomem *where = info->screen_base + (image->dx/8) + 1201 char __iomem *where = info->screen_base + (image->dx/8) +
1203 image->dy * info->fix.line_length; 1202 image->dy * info->fix.line_length;
1204 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1203 struct vga16fb_par *par = info->par;
1205 char *cdat = (char *) image->data; 1204 char *cdat = (char *) image->data;
1206 char __iomem *dst; 1205 char __iomem *dst;
1207 int x, y; 1206 int x, y;
@@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima
1266 /* 1265 /*
1267 * Draw logo 1266 * Draw logo
1268 */ 1267 */
1269 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1268 struct vga16fb_par *par = info->par;
1270 char __iomem *where = 1269 char __iomem *where =
1271 info->screen_base + image->dy * info->fix.line_length + 1270 info->screen_base + image->dy * info->fix.line_length +
1272 image->dx/8; 1271 image->dx/8;
@@ -1343,89 +1342,141 @@ static int vga16fb_setup(char *options)
1343} 1342}
1344#endif 1343#endif
1345 1344
1346static int __init vga16fb_init(void) 1345static int __init vga16fb_probe(struct device *device)
1347{ 1346{
1347 struct platform_device *dev = to_platform_device(device);
1348 struct fb_info *info;
1349 struct vga16fb_par *par;
1348 int i; 1350 int i;
1349 int ret; 1351 int ret = 0;
1350#ifndef MODULE
1351 char *option = NULL;
1352 1352
1353 if (fb_get_options("vga16fb", &option))
1354 return -ENODEV;
1355
1356 vga16fb_setup(option);
1357#endif
1358 printk(KERN_DEBUG "vga16fb: initializing\n"); 1353 printk(KERN_DEBUG "vga16fb: initializing\n");
1354 info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
1355
1356 if (!info) {
1357 ret = -ENOMEM;
1358 goto err_fb_alloc;
1359 }
1359 1360
1360 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1361 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1362 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
1361 1363
1362 vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1364 if (!info->screen_base) {
1363 if (!vga16fb.screen_base) {
1364 printk(KERN_ERR "vga16fb: unable to map device\n"); 1365 printk(KERN_ERR "vga16fb: unable to map device\n");
1365 ret = -ENOMEM; 1366 ret = -ENOMEM;
1366 goto err_ioremap; 1367 goto err_ioremap;
1367 } 1368 }
1368 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
1369 1369
1370 vga16_par.isVGA = ORIG_VIDEO_ISVGA; 1370 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
1371 vga16_par.palette_blanked = 0; 1371 par = info->par;
1372 vga16_par.vesa_blanked = 0;
1373 1372
1374 i = vga16_par.isVGA? 6 : 2; 1373 par->isVGA = ORIG_VIDEO_ISVGA;
1374 par->palette_blanked = 0;
1375 par->vesa_blanked = 0;
1376
1377 i = par->isVGA? 6 : 2;
1375 1378
1376 vga16fb_defined.red.length = i; 1379 vga16fb_defined.red.length = i;
1377 vga16fb_defined.green.length = i; 1380 vga16fb_defined.green.length = i;
1378 vga16fb_defined.blue.length = i; 1381 vga16fb_defined.blue.length = i;
1379 1382
1380 /* name should not depend on EGA/VGA */ 1383 /* name should not depend on EGA/VGA */
1381 vga16fb.fbops = &vga16fb_ops; 1384 info->fbops = &vga16fb_ops;
1382 vga16fb.var = vga16fb_defined; 1385 info->var = vga16fb_defined;
1383 vga16fb.fix = vga16fb_fix; 1386 info->fix = vga16fb_fix;
1384 vga16fb.par = &vga16_par; 1387 info->flags = FBINFO_FLAG_DEFAULT |
1385 vga16fb.flags = FBINFO_FLAG_DEFAULT |
1386 FBINFO_HWACCEL_YPAN; 1388 FBINFO_HWACCEL_YPAN;
1387 1389
1388 i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; 1390 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
1389 ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); 1391 ret = fb_alloc_cmap(&info->cmap, i, 0);
1390 if (ret) { 1392 if (ret) {
1391 printk(KERN_ERR "vga16fb: unable to allocate colormap\n"); 1393 printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
1392 ret = -ENOMEM; 1394 ret = -ENOMEM;
1393 goto err_alloc_cmap; 1395 goto err_alloc_cmap;
1394 } 1396 }
1395 1397
1396 if (vga16fb_check_var(&vga16fb.var, &vga16fb)) { 1398 if (vga16fb_check_var(&info->var, info)) {
1397 printk(KERN_ERR "vga16fb: unable to validate variable\n"); 1399 printk(KERN_ERR "vga16fb: unable to validate variable\n");
1398 ret = -EINVAL; 1400 ret = -EINVAL;
1399 goto err_check_var; 1401 goto err_check_var;
1400 } 1402 }
1401 1403
1402 vga16fb_update_fix(&vga16fb); 1404 vga16fb_update_fix(info);
1403 1405
1404 if (register_framebuffer(&vga16fb) < 0) { 1406 if (register_framebuffer(info) < 0) {
1405 printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); 1407 printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
1406 ret = -EINVAL; 1408 ret = -EINVAL;
1407 goto err_check_var; 1409 goto err_check_var;
1408 } 1410 }
1409 1411
1410 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1412 printk(KERN_INFO "fb%d: %s frame buffer device\n",
1411 vga16fb.node, vga16fb.fix.id); 1413 info->node, info->fix.id);
1414 dev_set_drvdata(device, info);
1412 1415
1413 return 0; 1416 return 0;
1414 1417
1415 err_check_var: 1418 err_check_var:
1416 fb_dealloc_cmap(&vga16fb.cmap); 1419 fb_dealloc_cmap(&info->cmap);
1417 err_alloc_cmap: 1420 err_alloc_cmap:
1418 iounmap(vga16fb.screen_base); 1421 iounmap(info->screen_base);
1419 err_ioremap: 1422 err_ioremap:
1423 framebuffer_release(info);
1424 err_fb_alloc:
1425 return ret;
1426}
1427
1428static int vga16fb_remove(struct device *device)
1429{
1430 struct fb_info *info = dev_get_drvdata(device);
1431
1432 if (info) {
1433 unregister_framebuffer(info);
1434 iounmap(info->screen_base);
1435 fb_dealloc_cmap(&info->cmap);
1436 /* XXX unshare VGA regions */
1437 framebuffer_release(info);
1438 }
1439
1440 return 0;
1441}
1442
1443static struct device_driver vga16fb_driver = {
1444 .name = "vga16fb",
1445 .bus = &platform_bus_type,
1446 .probe = vga16fb_probe,
1447 .remove = vga16fb_remove,
1448};
1449
1450static struct platform_device vga16fb_device = {
1451 .name = "vga16fb",
1452};
1453
1454static int __init vga16fb_init(void)
1455{
1456 int ret;
1457#ifndef MODULE
1458 char *option = NULL;
1459
1460 if (fb_get_options("vga16fb", &option))
1461 return -ENODEV;
1462
1463 vga16fb_setup(option);
1464#endif
1465 ret = driver_register(&vga16fb_driver);
1466
1467 if (!ret) {
1468 ret = platform_device_register(&vga16fb_device);
1469 if (ret)
1470 driver_unregister(&vga16fb_driver);
1471 }
1472
1420 return ret; 1473 return ret;
1421} 1474}
1422 1475
1423static void __exit vga16fb_exit(void) 1476static void __exit vga16fb_exit(void)
1424{ 1477{
1425 unregister_framebuffer(&vga16fb); 1478 platform_device_unregister(&vga16fb_device);
1426 iounmap(vga16fb.screen_base); 1479 driver_unregister(&vga16fb_driver);
1427 fb_dealloc_cmap(&vga16fb.cmap);
1428 /* XXX unshare VGA regions */
1429} 1480}
1430 1481
1431MODULE_LICENSE("GPL"); 1482MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index ca92940f3943..d9e01daee630 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state)
485 return 0; 485 return 0;
486} 486}
487 487
488#ifdef MODULE
489int init_module(void) { return 0; };
490void cleanup_module(void) {};
491#endif
492
493EXPORT_SYMBOL(save_vga); 488EXPORT_SYMBOL(save_vga);
494EXPORT_SYMBOL(restore_vga); 489EXPORT_SYMBOL(restore_vga);
495 490