aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig54
-rw-r--r--drivers/media/Makefile5
-rw-r--r--drivers/media/common/Kconfig12
-rw-r--r--drivers/media/common/Makefile6
-rw-r--r--drivers/media/common/ir-common.c381
-rw-r--r--drivers/media/common/saa7146_core.c547
-rw-r--r--drivers/media/common/saa7146_fops.c564
-rw-r--r--drivers/media/common/saa7146_hlp.c1036
-rw-r--r--drivers/media/common/saa7146_i2c.c421
-rw-r--r--drivers/media/common/saa7146_vbi.c508
-rw-r--r--drivers/media/common/saa7146_video.c1509
-rw-r--r--drivers/media/common/saa7146_vv_ksyms.c12
-rw-r--r--drivers/media/dvb/Kconfig47
-rw-r--r--drivers/media/dvb/Makefile5
-rw-r--r--drivers/media/dvb/b2c2/Kconfig26
-rw-r--r--drivers/media/dvb/b2c2/Makefile6
-rw-r--r--drivers/media/dvb/b2c2/b2c2-common.c214
-rw-r--r--drivers/media/dvb/b2c2/b2c2-usb-core.c549
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c2644
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig19
-rw-r--r--drivers/media/dvb/bt8xx/Makefile5
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c588
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h147
-rw-r--r--drivers/media/dvb/bt8xx/dst.c1089
-rw-r--r--drivers/media/dvb/bt8xx/dst.h40
-rw-r--r--drivers/media/dvb/bt8xx/dst_priv.h36
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c797
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h59
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig85
-rw-r--r--drivers/media/dvb/cinergyT2/Makefile3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c965
-rw-r--r--drivers/media/dvb/dibusb/Kconfig62
-rw-r--r--drivers/media/dvb/dibusb/Makefile11
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-core.c558
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-dvb.c185
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c582
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-firmware.c87
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-remote.c316
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-usb.c303
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb.h327
-rw-r--r--drivers/media/dvb/dibusb/dvb-fe-dtt200u.c263
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig11
-rw-r--r--drivers/media/dvb/dvb-core/Makefile9
-rw-r--r--drivers/media/dvb/dvb-core/demux.h301
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c1137
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h128
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1778
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h134
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c1294
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h146
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.c603
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.h246
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c915
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h126
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c1381
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.h46
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c270
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h173
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c449
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h104
-rw-r--r--drivers/media/dvb/frontends/Kconfig172
-rw-r--r--drivers/media/dvb/frontends/Makefile30
-rw-r--r--drivers/media/dvb/frontends/at76c651.c450
-rw-r--r--drivers/media/dvb/frontends/at76c651.h47
-rw-r--r--drivers/media/dvb/frontends/cx22700.c435
-rw-r--r--drivers/media/dvb/frontends/cx22700.h41
-rw-r--r--drivers/media/dvb/frontends/cx22702.c519
-rw-r--r--drivers/media/dvb/frontends/cx22702.h46
-rw-r--r--drivers/media/dvb/frontends/cx24110.c657
-rw-r--r--drivers/media/dvb/frontends/cx24110.h45
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c83
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h137
-rw-r--r--drivers/media/dvb/frontends/dib3000.h54
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c784
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h467
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c931
-rw-r--r--drivers/media/dvb/frontends/dib3000mc_priv.h428
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c168
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h34
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c279
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h32
-rw-r--r--drivers/media/dvb/frontends/l64781.c602
-rw-r--r--drivers/media/dvb/frontends/l64781.h42
-rw-r--r--drivers/media/dvb/frontends/mt312.c729
-rw-r--r--drivers/media/dvb/frontends/mt312.h47
-rw-r--r--drivers/media/dvb/frontends/mt312_priv.h162
-rw-r--r--drivers/media/dvb/frontends/mt352.c610
-rw-r--r--drivers/media/dvb/frontends/mt352.h72
-rw-r--r--drivers/media/dvb/frontends/mt352_priv.h127
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c705
-rw-r--r--drivers/media/dvb/frontends/nxt2002.h23
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c554
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h43
-rw-r--r--drivers/media/dvb/frontends/nxt6000_priv.h265
-rw-r--r--drivers/media/dvb/frontends/or51132.c628
-rw-r--r--drivers/media/dvb/frontends/or51132.h48
-rw-r--r--drivers/media/dvb/frontends/or51211.c631
-rw-r--r--drivers/media/dvb/frontends/or51211.h44
-rw-r--r--drivers/media/dvb/frontends/sp8870.c614
-rw-r--r--drivers/media/dvb/frontends/sp8870.h45
-rw-r--r--drivers/media/dvb/frontends/sp887x.c606
-rw-r--r--drivers/media/dvb/frontends/sp887x.h29
-rw-r--r--drivers/media/dvb/frontends/stv0297.c798
-rw-r--r--drivers/media/dvb/frontends/stv0297.h44
-rw-r--r--drivers/media/dvb/frontends/stv0299.c731
-rw-r--r--drivers/media/dvb/frontends/stv0299.h104
-rw-r--r--drivers/media/dvb/frontends/tda10021.c469
-rw-r--r--drivers/media/dvb/frontends/tda10021.h42
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c1206
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h56
-rw-r--r--drivers/media/dvb/frontends/tda8083.c456
-rw-r--r--drivers/media/dvb/frontends/tda8083.h45
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c734
-rw-r--r--drivers/media/dvb/frontends/tda80xx.h51
-rw-r--r--drivers/media/dvb/frontends/ves1820.c450
-rw-r--r--drivers/media/dvb/frontends/ves1820.h51
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c545
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h50
-rw-r--r--drivers/media/dvb/ttpci/Kconfig134
-rw-r--r--drivers/media/dvb/ttpci/Makefile23
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2739
-rw-r--r--drivers/media/dvb/ttpci/av7110.h284
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c1459
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.h29
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c390
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.h14
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c1170
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h500
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.c403
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.h12
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c212
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c771
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c1014
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c995
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c754
-rw-r--r--drivers/media/dvb/ttpci/budget.c573
-rw-r--r--drivers/media/dvb/ttpci/budget.h110
-rw-r--r--drivers/media/dvb/ttpci/fdump.c44
-rw-r--r--drivers/media/dvb/ttpci/ttpci-eeprom.c146
-rw-r--r--drivers/media/dvb/ttpci/ttpci-eeprom.h33
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig15
-rw-r--r--drivers/media/dvb/ttusb-budget/Makefile3
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c1610
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h1644
-rw-r--r--drivers/media/dvb/ttusb-dec/Kconfig21
-rw-r--r--drivers/media/dvb/ttusb-dec/Makefile3
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c1744
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c255
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.h38
-rw-r--r--drivers/media/radio/Kconfig354
-rw-r--r--drivers/media/radio/Makefile22
-rw-r--r--drivers/media/radio/miropcm20-radio.c264
-rw-r--r--drivers/media/radio/miropcm20-rds-core.c210
-rw-r--r--drivers/media/radio/miropcm20-rds-core.h19
-rw-r--r--drivers/media/radio/miropcm20-rds.c133
-rw-r--r--drivers/media/radio/radio-aimslab.c368
-rw-r--r--drivers/media/radio/radio-aztech.c315
-rw-r--r--drivers/media/radio/radio-cadet.c620
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c416
-rw-r--r--drivers/media/radio/radio-gemtek.c304
-rw-r--r--drivers/media/radio/radio-maestro.c332
-rw-r--r--drivers/media/radio/radio-maxiradio.c349
-rw-r--r--drivers/media/radio/radio-rtrack2.c266
-rw-r--r--drivers/media/radio/radio-sf16fmi.c328
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c434
-rw-r--r--drivers/media/radio/radio-terratec.c341
-rw-r--r--drivers/media/radio/radio-trust.c320
-rw-r--r--drivers/media/radio/radio-typhoon.c383
-rw-r--r--drivers/media/radio/radio-zoltrix.c385
-rw-r--r--drivers/media/video/Kconfig360
-rw-r--r--drivers/media/video/Makefile56
-rw-r--r--drivers/media/video/adv7170.c535
-rw-r--r--drivers/media/video/adv7175.c585
-rw-r--r--drivers/media/video/arv.c916
-rw-r--r--drivers/media/video/bt819.c660
-rw-r--r--drivers/media/video/bt832.c271
-rw-r--r--drivers/media/video/bt832.h305
-rw-r--r--drivers/media/video/bt848.h366
-rw-r--r--drivers/media/video/bt856.c442
-rw-r--r--drivers/media/video/btcx-risc.c262
-rw-r--r--drivers/media/video/btcx-risc.h35
-rw-r--r--drivers/media/video/bttv-cards.c4350
-rw-r--r--drivers/media/video/bttv-driver.c4116
-rw-r--r--drivers/media/video/bttv-gpio.c190
-rw-r--r--drivers/media/video/bttv-i2c.c461
-rw-r--r--drivers/media/video/bttv-if.c160
-rw-r--r--drivers/media/video/bttv-risc.c802
-rw-r--r--drivers/media/video/bttv-vbi.c235
-rw-r--r--drivers/media/video/bttv.h338
-rw-r--r--drivers/media/video/bttvp.h399
-rw-r--r--drivers/media/video/bw-qcam.c1027
-rw-r--r--drivers/media/video/bw-qcam.h68
-rw-r--r--drivers/media/video/c-qcam.c855
-rw-r--r--drivers/media/video/cpia.c4073
-rw-r--r--drivers/media/video/cpia.h430
-rw-r--r--drivers/media/video/cpia_pp.c886
-rw-r--r--drivers/media/video/cpia_usb.c662
-rw-r--r--drivers/media/video/cs8420.h50
-rw-r--r--drivers/media/video/cx88/Makefile11
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c911
-rw-r--r--drivers/media/video/cx88/cx88-cards.c938
-rw-r--r--drivers/media/video/cx88/cx88-core.c1239
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c381
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c213
-rw-r--r--drivers/media/video/cx88/cx88-input.c396
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c466
-rw-r--r--drivers/media/video/cx88/cx88-reg.h787
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1032
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c248
-rw-r--r--drivers/media/video/cx88/cx88-video.c2277
-rw-r--r--drivers/media/video/cx88/cx88.h551
-rw-r--r--drivers/media/video/dpc7146.c401
-rw-r--r--drivers/media/video/hexium_gemini.c556
-rw-r--r--drivers/media/video/hexium_orion.c522
-rw-r--r--drivers/media/video/ibmmpeg2.h94
-rw-r--r--drivers/media/video/ir-kbd-gpio.c444
-rw-r--r--drivers/media/video/ir-kbd-i2c.c492
-rw-r--r--drivers/media/video/meye.c2041
-rw-r--r--drivers/media/video/meye.h318
-rw-r--r--drivers/media/video/msp3400.c1876
-rw-r--r--drivers/media/video/msp3400.h36
-rw-r--r--drivers/media/video/mt20xx.c558
-rw-r--r--drivers/media/video/mxb.c1035
-rw-r--r--drivers/media/video/mxb.h42
-rw-r--r--drivers/media/video/ovcamchip/Makefile4
-rw-r--r--drivers/media/video/ovcamchip/ov6x20.c415
-rw-r--r--drivers/media/video/ovcamchip/ov6x30.c374
-rw-r--r--drivers/media/video/ovcamchip/ov76be.c303
-rw-r--r--drivers/media/video/ovcamchip/ov7x10.c335
-rw-r--r--drivers/media/video/ovcamchip/ov7x20.c455
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c444
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h87
-rw-r--r--drivers/media/video/planb.c2303
-rw-r--r--drivers/media/video/planb.h231
-rw-r--r--drivers/media/video/pms.c1060
-rw-r--r--drivers/media/video/saa5246a.c843
-rw-r--r--drivers/media/video/saa5246a.h364
-rw-r--r--drivers/media/video/saa5249.c725
-rw-r--r--drivers/media/video/saa7110.c623
-rw-r--r--drivers/media/video/saa7111.c627
-rw-r--r--drivers/media/video/saa7114.c1241
-rw-r--r--drivers/media/video/saa7121.h132
-rw-r--r--drivers/media/video/saa7134/Makefile11
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c543
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c2018
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1237
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c266
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c436
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c453
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c491
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c857
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h366
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c243
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1031
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c270
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2406
-rw-r--r--drivers/media/video/saa7134/saa7134.h618
-rw-r--r--drivers/media/video/saa7146.h115
-rw-r--r--drivers/media/video/saa7146reg.h283
-rw-r--r--drivers/media/video/saa7185.c524
-rw-r--r--drivers/media/video/saa7196.h117
-rw-r--r--drivers/media/video/stradis.c2258
-rw-r--r--drivers/media/video/tda7432.c556
-rw-r--r--drivers/media/video/tda8290.c224
-rw-r--r--drivers/media/video/tda9840.c254
-rw-r--r--drivers/media/video/tda9840.h35
-rw-r--r--drivers/media/video/tda9875.c423
-rw-r--r--drivers/media/video/tda9887.c801
-rw-r--r--drivers/media/video/tea6415c.c223
-rw-r--r--drivers/media/video/tea6415c.h39
-rw-r--r--drivers/media/video/tea6420.c200
-rw-r--r--drivers/media/video/tea6420.h17
-rw-r--r--drivers/media/video/tuner-3036.c220
-rw-r--r--drivers/media/video/tuner-core.c443
-rw-r--r--drivers/media/video/tuner-simple.c474
-rw-r--r--drivers/media/video/tvaudio.c1740
-rw-r--r--drivers/media/video/tvaudio.h14
-rw-r--r--drivers/media/video/tveeprom.c587
-rw-r--r--drivers/media/video/tvmixer.c367
-rw-r--r--drivers/media/video/v4l1-compat.c1036
-rw-r--r--drivers/media/video/v4l2-common.c282
-rw-r--r--drivers/media/video/video-buf-dvb.c251
-rw-r--r--drivers/media/video/video-buf.c1290
-rw-r--r--drivers/media/video/videocodec.c490
-rw-r--r--drivers/media/video/videocodec.h358
-rw-r--r--drivers/media/video/videodev.c436
-rw-r--r--drivers/media/video/vino.c347
-rw-r--r--drivers/media/video/vino.h131
-rw-r--r--drivers/media/video/vpx3220.c754
-rw-r--r--drivers/media/video/w9966.c984
-rw-r--r--drivers/media/video/zoran.h515
-rw-r--r--drivers/media/video/zoran_card.c1583
-rw-r--r--drivers/media/video/zoran_card.h45
-rw-r--r--drivers/media/video/zoran_device.c1785
-rw-r--r--drivers/media/video/zoran_device.h91
-rw-r--r--drivers/media/video/zoran_driver.c4699
-rw-r--r--drivers/media/video/zoran_procfs.c233
-rw-r--r--drivers/media/video/zoran_procfs.h36
-rw-r--r--drivers/media/video/zr36016.c532
-rw-r--r--drivers/media/video/zr36016.h111
-rw-r--r--drivers/media/video/zr36050.c907
-rw-r--r--drivers/media/video/zr36050.h184
-rw-r--r--drivers/media/video/zr36057.h168
-rw-r--r--drivers/media/video/zr36060.c1016
-rw-r--r--drivers/media/video/zr36060.h220
-rw-r--r--drivers/media/video/zr36120.c2073
-rw-r--r--drivers/media/video/zr36120.h279
-rw-r--r--drivers/media/video/zr36120_i2c.c132
-rw-r--r--drivers/media/video/zr36120_mem.c79
-rw-r--r--drivers/media/video/zr36120_mem.h3
311 files changed, 160942 insertions, 0 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
new file mode 100644
index 000000000000..c2602b340491
--- /dev/null
+++ b/drivers/media/Kconfig
@@ -0,0 +1,54 @@
1#
2# Multimedia device configuration
3#
4
5menu "Multimedia devices"
6
7config VIDEO_DEV
8 tristate "Video For Linux"
9 ---help---
10 Support for audio/video capture and overlay devices and FM radio
11 cards. The exact capabilities of each device vary. User tools for
12 this are available from
13 <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
14
15 This kernel includes support for the new Video for Linux Two API,
16 (V4L2) as well as the original system. Drivers and applications
17 need to be rewritten to use V4L2, but drivers for popular cards
18 and applications for most video capture functions already exist.
19
20 Documentation for the original API is included in the file
21 <file:Documentation/video4linux/API.html>. Documentation for V4L2 is
22 available on the web at <http://bytesex.org/v4l/>.
23
24 To compile this driver as a module, choose M here: the
25 module will be called videodev.
26
27source "drivers/media/video/Kconfig"
28
29source "drivers/media/radio/Kconfig"
30
31source "drivers/media/dvb/Kconfig"
32
33source "drivers/media/common/Kconfig"
34
35config VIDEO_TUNER
36 tristate
37
38config VIDEO_BUF
39 tristate
40
41config VIDEO_BUF_DVB
42 tristate
43
44config VIDEO_BTCX
45 tristate
46
47config VIDEO_IR
48 tristate
49
50config VIDEO_TVEEPROM
51 tristate
52
53endmenu
54
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
new file mode 100644
index 000000000000..772d6112fb3b
--- /dev/null
+++ b/drivers/media/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the kernel multimedia device drivers.
3#
4
5obj-y := video/ radio/ dvb/ common/
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
new file mode 100644
index 000000000000..caebd0a1c021
--- /dev/null
+++ b/drivers/media/common/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_SAA7146
2 tristate
3 select I2C
4
5config VIDEO_SAA7146_VV
6 tristate
7 select VIDEO_BUF
8 select VIDEO_VIDEOBUF
9 select VIDEO_SAA7146
10
11config VIDEO_VIDEOBUF
12 tristate
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
new file mode 100644
index 000000000000..97b4341255ea
--- /dev/null
+++ b/drivers/media/common/Makefile
@@ -0,0 +1,6 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3
4obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
5obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
6obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
new file mode 100644
index 000000000000..8c842e2f59a2
--- /dev/null
+++ b/drivers/media/common/ir-common.c
@@ -0,0 +1,381 @@
1/*
2 * $Id: ir-common.c,v 1.8 2005/02/22 12:28:40 kraxel Exp $
3 *
4 * some common structs and functions to handle infrared remotes via
5 * input layer ...
6 *
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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 <media/ir-common.h>
27
28/* -------------------------------------------------------------------------- */
29
30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
31MODULE_LICENSE("GPL");
32
33static int repeat = 1;
34module_param(repeat, int, 0444);
35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
36
37static int debug = 0; /* debug level (0,1,2) */
38module_param(debug, int, 0644);
39
40#define dprintk(level, fmt, arg...) if (debug >= level) \
41 printk(KERN_DEBUG fmt , ## arg)
42
43/* -------------------------------------------------------------------------- */
44
45/* generic RC5 keytable */
46/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
47/* used by old (black) Hauppauge remotes */
48IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
49 [ 0x00 ] = KEY_KP0, // 0
50 [ 0x01 ] = KEY_KP1, // 1
51 [ 0x02 ] = KEY_KP2, // 2
52 [ 0x03 ] = KEY_KP3, // 3
53 [ 0x04 ] = KEY_KP4, // 4
54 [ 0x05 ] = KEY_KP5, // 5
55 [ 0x06 ] = KEY_KP6, // 6
56 [ 0x07 ] = KEY_KP7, // 7
57 [ 0x08 ] = KEY_KP8, // 8
58 [ 0x09 ] = KEY_KP9, // 9
59
60 [ 0x0b ] = KEY_CHANNEL, // channel / program (japan: 11)
61 [ 0x0c ] = KEY_POWER, // standby
62 [ 0x0d ] = KEY_MUTE, // mute / demute
63 [ 0x0f ] = KEY_TV, // display
64 [ 0x10 ] = KEY_VOLUMEUP, // volume +
65 [ 0x11 ] = KEY_VOLUMEDOWN, // volume -
66 [ 0x12 ] = KEY_BRIGHTNESSUP, // brightness +
67 [ 0x13 ] = KEY_BRIGHTNESSDOWN, // brightness -
68 [ 0x1e ] = KEY_SEARCH, // search +
69 [ 0x20 ] = KEY_CHANNELUP, // channel / program +
70 [ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
71 [ 0x22 ] = KEY_CHANNEL, // alt / channel
72 [ 0x23 ] = KEY_LANGUAGE, // 1st / 2nd language
73 [ 0x26 ] = KEY_SLEEP, // sleeptimer
74 [ 0x2e ] = KEY_MENU, // 2nd controls (USA: menu)
75 [ 0x30 ] = KEY_PAUSE, // pause
76 [ 0x32 ] = KEY_REWIND, // rewind
77 [ 0x33 ] = KEY_GOTO, // go to
78 [ 0x35 ] = KEY_PLAY, // play
79 [ 0x36 ] = KEY_STOP, // stop
80 [ 0x37 ] = KEY_RECORD, // recording
81 [ 0x3c ] = KEY_TEXT, // teletext submode (Japan: 12)
82 [ 0x3d ] = KEY_SUSPEND, // system standby
83
84#if 0 /* FIXME */
85 [ 0x0a ] = KEY_RESERVED, // 1/2/3 digits (japan: 10)
86 [ 0x0e ] = KEY_RESERVED, // P.P. (personal preference)
87 [ 0x14 ] = KEY_RESERVED, // colour saturation +
88 [ 0x15 ] = KEY_RESERVED, // colour saturation -
89 [ 0x16 ] = KEY_RESERVED, // bass +
90 [ 0x17 ] = KEY_RESERVED, // bass -
91 [ 0x18 ] = KEY_RESERVED, // treble +
92 [ 0x19 ] = KEY_RESERVED, // treble -
93 [ 0x1a ] = KEY_RESERVED, // balance right
94 [ 0x1b ] = KEY_RESERVED, // balance left
95 [ 0x1c ] = KEY_RESERVED, // contrast +
96 [ 0x1d ] = KEY_RESERVED, // contrast -
97 [ 0x1f ] = KEY_RESERVED, // tint/hue +
98 [ 0x24 ] = KEY_RESERVED, // spacial stereo on/off
99 [ 0x25 ] = KEY_RESERVED, // mono / stereo (USA)
100 [ 0x27 ] = KEY_RESERVED, // tint / hue -
101 [ 0x28 ] = KEY_RESERVED, // RF switch/PIP select
102 [ 0x29 ] = KEY_RESERVED, // vote
103 [ 0x2a ] = KEY_RESERVED, // timed page/channel clck
104 [ 0x2b ] = KEY_RESERVED, // increment (USA)
105 [ 0x2c ] = KEY_RESERVED, // decrement (USA)
106 [ 0x2d ] = KEY_RESERVED, //
107 [ 0x2f ] = KEY_RESERVED, // PIP shift
108 [ 0x31 ] = KEY_RESERVED, // erase
109 [ 0x34 ] = KEY_RESERVED, // wind
110 [ 0x38 ] = KEY_RESERVED, // external 1
111 [ 0x39 ] = KEY_RESERVED, // external 2
112 [ 0x3a ] = KEY_RESERVED, // PIP display mode
113 [ 0x3b ] = KEY_RESERVED, // view data mode / advance
114 [ 0x3e ] = KEY_RESERVED, // crispener on/off
115 [ 0x3f ] = KEY_RESERVED, // system select
116#endif
117};
118EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
119
120/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
121IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
122 [ 5 ] = KEY_KP1,
123 [ 6 ] = KEY_KP2,
124 [ 7 ] = KEY_KP3,
125 [ 9 ] = KEY_KP4,
126 [ 10 ] = KEY_KP5,
127 [ 11 ] = KEY_KP6,
128 [ 13 ] = KEY_KP7,
129 [ 14 ] = KEY_KP8,
130 [ 15 ] = KEY_KP9,
131 [ 18 ] = KEY_KP0,
132
133 [ 0 ] = KEY_POWER,
134// [ 27 ] = MTS button
135 [ 2 ] = KEY_TUNER, // TV/FM
136 [ 30 ] = KEY_VIDEO,
137// [ 22 ] = display button
138 [ 4 ] = KEY_VOLUMEUP,
139 [ 8 ] = KEY_VOLUMEDOWN,
140 [ 12 ] = KEY_CHANNELUP,
141 [ 16 ] = KEY_CHANNELDOWN,
142 [ 3 ] = KEY_ZOOM, // fullscreen
143 [ 31 ] = KEY_SUBTITLE, // closed caption/teletext
144 [ 32 ] = KEY_SLEEP,
145// [ 41 ] = boss key
146 [ 20 ] = KEY_MUTE,
147 [ 43 ] = KEY_RED,
148 [ 44 ] = KEY_GREEN,
149 [ 45 ] = KEY_YELLOW,
150 [ 46 ] = KEY_BLUE,
151 [ 24 ] = KEY_KPPLUS, //fine tune +
152 [ 25 ] = KEY_KPMINUS, //fine tune -
153// [ 42 ] = picture in picture
154 [ 33 ] = KEY_KPDOT,
155 [ 19 ] = KEY_KPENTER,
156// [ 17 ] = recall
157 [ 34 ] = KEY_BACK,
158 [ 35 ] = KEY_PLAYPAUSE,
159 [ 36 ] = KEY_NEXT,
160// [ 37 ] = time shifting
161 [ 38 ] = KEY_STOP,
162 [ 39 ] = KEY_RECORD
163// [ 40 ] = snapshot
164};
165EXPORT_SYMBOL_GPL(ir_codes_winfast);
166
167/* empty keytable, can be used as placeholder for not-yet created keytables */
168IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
169 [ 42 ] = KEY_COFFEE,
170};
171EXPORT_SYMBOL_GPL(ir_codes_empty);
172
173/* Hauppauge: the newer, gray remotes (seems there are multiple
174 * slightly different versions), shipped with cx88+ivtv cards.
175 * almost rc5 coding, but some non-standard keys */
176IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
177 [ 0x00 ] = KEY_KP0, // 0
178 [ 0x01 ] = KEY_KP1, // 1
179 [ 0x02 ] = KEY_KP2, // 2
180 [ 0x03 ] = KEY_KP3, // 3
181 [ 0x04 ] = KEY_KP4, // 4
182 [ 0x05 ] = KEY_KP5, // 5
183 [ 0x06 ] = KEY_KP6, // 6
184 [ 0x07 ] = KEY_KP7, // 7
185 [ 0x08 ] = KEY_KP8, // 8
186 [ 0x09 ] = KEY_KP9, // 9
187 [ 0x0b ] = KEY_RED, // red button
188 [ 0x0c ] = KEY_OPTION, // black key without text
189 [ 0x0d ] = KEY_MENU, // menu
190 [ 0x0f ] = KEY_MUTE, // mute
191 [ 0x10 ] = KEY_VOLUMEUP, // volume +
192 [ 0x11 ] = KEY_VOLUMEDOWN, // volume -
193 [ 0x1e ] = KEY_NEXT, // skip >|
194 [ 0x1f ] = KEY_EXIT, // back/exit
195 [ 0x20 ] = KEY_CHANNELUP, // channel / program +
196 [ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
197 [ 0x22 ] = KEY_CHANNEL, // source (old black remote)
198 [ 0x24 ] = KEY_PREVIOUS, // replay |<
199 [ 0x25 ] = KEY_ENTER, // OK
200 [ 0x26 ] = KEY_SLEEP, // minimize (old black remote)
201 [ 0x29 ] = KEY_BLUE, // blue key
202 [ 0x2e ] = KEY_GREEN, // green button
203 [ 0x30 ] = KEY_PAUSE, // pause
204 [ 0x32 ] = KEY_REWIND, // backward <<
205 [ 0x34 ] = KEY_FASTFORWARD, // forward >>
206 [ 0x35 ] = KEY_PLAY, // play
207 [ 0x36 ] = KEY_STOP, // stop
208 [ 0x37 ] = KEY_RECORD, // recording
209 [ 0x38 ] = KEY_YELLOW, // yellow key
210 [ 0x3b ] = KEY_SELECT, // top right button
211 [ 0x3c ] = KEY_ZOOM, // full
212 [ 0x3d ] = KEY_POWER, // system power (green button)
213};
214EXPORT_SYMBOL(ir_codes_hauppauge_new);
215
216/* -------------------------------------------------------------------------- */
217
218static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
219{
220 if (KEY_RESERVED == ir->keycode) {
221 printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
222 dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
223 return;
224 }
225 dprintk(1,"%s: key event code=%d down=%d\n",
226 dev->name,ir->keycode,ir->keypressed);
227 input_report_key(dev,ir->keycode,ir->keypressed);
228 input_sync(dev);
229}
230
231/* -------------------------------------------------------------------------- */
232
233void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
234 int ir_type, IR_KEYTAB_TYPE *ir_codes)
235{
236 int i;
237
238 ir->ir_type = ir_type;
239 if (ir_codes)
240 memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
241
242 init_input_dev(dev);
243 dev->keycode = ir->ir_codes;
244 dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
245 dev->keycodemax = IR_KEYTAB_SIZE;
246 for (i = 0; i < IR_KEYTAB_SIZE; i++)
247 set_bit(ir->ir_codes[i], dev->keybit);
248 clear_bit(0, dev->keybit);
249
250 set_bit(EV_KEY, dev->evbit);
251 if (repeat)
252 set_bit(EV_REP, dev->evbit);
253}
254
255void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
256{
257 if (ir->keypressed) {
258 ir->keypressed = 0;
259 ir_input_key_event(dev,ir);
260 }
261}
262
263void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
264 u32 ir_key, u32 ir_raw)
265{
266 u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
267
268 if (ir->keypressed && ir->keycode != keycode) {
269 ir->keypressed = 0;
270 ir_input_key_event(dev,ir);
271 }
272 if (!ir->keypressed) {
273 ir->ir_key = ir_key;
274 ir->ir_raw = ir_raw;
275 ir->keycode = keycode;
276 ir->keypressed = 1;
277 ir_input_key_event(dev,ir);
278 }
279#if 0
280 /* maybe do something like this ??? */
281 input_event(a, EV_IR, ir->ir_type, ir->ir_raw);
282#endif
283}
284
285/* -------------------------------------------------------------------------- */
286
287u32 ir_extract_bits(u32 data, u32 mask)
288{
289 int mbit, vbit;
290 u32 value;
291
292 value = 0;
293 vbit = 0;
294 for (mbit = 0; mbit < 32; mbit++) {
295 if (!(mask & ((u32)1 << mbit)))
296 continue;
297 if (data & ((u32)1 << mbit))
298 value |= (1 << vbit);
299 vbit++;
300 }
301 return value;
302}
303
304static int inline getbit(u32 *samples, int bit)
305{
306 return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
307}
308
309/* sump raw samples for visual debugging ;) */
310int ir_dump_samples(u32 *samples, int count)
311{
312 int i, bit, start;
313
314 printk(KERN_DEBUG "ir samples: ");
315 start = 0;
316 for (i = 0; i < count * 32; i++) {
317 bit = getbit(samples,i);
318 if (bit)
319 start = 1;
320 if (0 == start)
321 continue;
322 printk("%s", bit ? "#" : "_");
323 }
324 printk("\n");
325 return 0;
326}
327
328/* decode raw samples, biphase coding, used by rc5 for example */
329int ir_decode_biphase(u32 *samples, int count, int low, int high)
330{
331 int i,last,bit,len,flips;
332 u32 value;
333
334 /* find start bit (1) */
335 for (i = 0; i < 32; i++) {
336 bit = getbit(samples,i);
337 if (bit)
338 break;
339 }
340
341 /* go decoding */
342 len = 0;
343 flips = 0;
344 value = 1;
345 for (; i < count * 32; i++) {
346 if (len > high)
347 break;
348 if (flips > 1)
349 break;
350 last = bit;
351 bit = getbit(samples,i);
352 if (last == bit) {
353 len++;
354 continue;
355 }
356 if (len < low) {
357 len++;
358 flips++;
359 continue;
360 }
361 value <<= 1;
362 value |= bit;
363 flips = 0;
364 len = 1;
365 }
366 return value;
367}
368
369EXPORT_SYMBOL_GPL(ir_input_init);
370EXPORT_SYMBOL_GPL(ir_input_nokey);
371EXPORT_SYMBOL_GPL(ir_input_keydown);
372
373EXPORT_SYMBOL_GPL(ir_extract_bits);
374EXPORT_SYMBOL_GPL(ir_dump_samples);
375EXPORT_SYMBOL_GPL(ir_decode_biphase);
376
377/*
378 * Local variables:
379 * c-basic-offset: 8
380 * End:
381 */
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
new file mode 100644
index 000000000000..9f6c19ac1285
--- /dev/null
+++ b/drivers/media/common/saa7146_core.c
@@ -0,0 +1,547 @@
1/*
2 saa7146.o - driver for generic saa7146-based hardware
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
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
21#include <media/saa7146.h>
22
23LIST_HEAD(saa7146_devices);
24DECLARE_MUTEX(saa7146_devices_lock);
25
26static int saa7146_num = 0;
27
28unsigned int saa7146_debug = 0;
29
30module_param(saa7146_debug, int, 0644);
31MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
32
33#if 0
34static void dump_registers(struct saa7146_dev* dev)
35{
36 int i = 0;
37
38 INFO((" @ %li jiffies:\n",jiffies));
39 for(i = 0; i <= 0x148; i+=4) {
40 printk("0x%03x: 0x%08x\n",i,saa7146_read(dev,i));
41 }
42}
43#endif
44
45/****************************************************************************
46 * gpio and debi helper functions
47 ****************************************************************************/
48
49void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
50{
51 u32 value = 0;
52
53 BUG_ON(port > 3);
54
55 value = saa7146_read(dev, GPIO_CTRL);
56 value &= ~(0xff << (8*port));
57 value |= (data << (8*port));
58 saa7146_write(dev, GPIO_CTRL, value);
59}
60
61/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
63{
64 unsigned long start;
65
66 /* wait for registers to be programmed */
67 start = jiffies;
68 while (1) {
69 if (saa7146_read(dev, MC2) & 2)
70 break;
71 if (time_after(jiffies, start + HZ/20)) {
72 DEB_S(("timed out while waiting for registers getting programmed\n"));
73 return -ETIMEDOUT;
74 }
75 if (nobusyloop)
76 msleep(1);
77 }
78
79 /* wait for transfer to complete */
80 start = jiffies;
81 while (1) {
82 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
83 break;
84 saa7146_read(dev, MC2);
85 if (time_after(jiffies, start + HZ/4)) {
86 DEB_S(("timed out while waiting for transfer completion\n"));
87 return -ETIMEDOUT;
88 }
89 if (nobusyloop)
90 msleep(1);
91 }
92
93 return 0;
94}
95
96/****************************************************************************
97 * general helper functions
98 ****************************************************************************/
99
100/* this is videobuf_vmalloc_to_sg() from video-buf.c
101 make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
102 may be triggered on highmem machines */
103static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
104{
105 struct scatterlist *sglist;
106 struct page *pg;
107 int i;
108
109 sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
110 if (NULL == sglist)
111 return NULL;
112 memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
113 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
114 pg = vmalloc_to_page(virt);
115 if (NULL == pg)
116 goto err;
117 if (PageHighMem(pg))
118 BUG();
119 sglist[i].page = pg;
120 sglist[i].length = PAGE_SIZE;
121 }
122 return sglist;
123
124 err:
125 kfree(sglist);
126 return NULL;
127}
128
129/********************************************************************************/
130/* common page table functions */
131
132char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
133{
134 int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
135 char *mem = vmalloc_32(length);
136 int slen = 0;
137
138 if (NULL == mem) {
139 return NULL;
140 }
141
142 if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
143 vfree(mem);
144 return NULL;
145 }
146
147 if (saa7146_pgtable_alloc(pci, pt)) {
148 kfree(pt->slist);
149 pt->slist = NULL;
150 vfree(mem);
151 return NULL;
152 }
153
154 slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
155 if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
156 return NULL;
157 }
158
159 return mem;
160}
161
162void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
163{
164 if (NULL == pt->cpu)
165 return;
166 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
167 pt->cpu = NULL;
168 if (NULL != pt->slist) {
169 kfree(pt->slist);
170 pt->slist = NULL;
171 }
172}
173
174int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
175{
176 u32 *cpu;
177 dma_addr_t dma_addr;
178
179 cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr);
180 if (NULL == cpu) {
181 return -ENOMEM;
182 }
183 pt->size = PAGE_SIZE;
184 pt->cpu = cpu;
185 pt->dma = dma_addr;
186
187 return 0;
188}
189
190int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
191 struct scatterlist *list, int sglen )
192{
193 u32 *ptr, fill;
194 int nr_pages = 0;
195 int i,p;
196
197 BUG_ON(0 == sglen);
198 BUG_ON(list->offset > PAGE_SIZE);
199
200 /* if we have a user buffer, the first page may not be
201 aligned to a page boundary. */
202 pt->offset = list->offset;
203
204 ptr = pt->cpu;
205 for (i = 0; i < sglen; i++, list++) {
206/*
207 printk("i:%d, adr:0x%08x, len:%d, offset:%d\n", i,sg_dma_address(list), sg_dma_len(list), list->offset);
208*/
209 for (p = 0; p * 4096 < list->length; p++, ptr++) {
210 *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
211 nr_pages++;
212 }
213 }
214
215
216 /* safety; fill the page table up with the last valid page */
217 fill = *(ptr-1);
218 for(i=nr_pages;i<1024;i++) {
219 *ptr++ = fill;
220 }
221
222/*
223 ptr = pt->cpu;
224 printk("offset: %d\n",pt->offset);
225 for(i=0;i<5;i++) {
226 printk("ptr1 %d: 0x%08x\n",i,ptr[i]);
227 }
228*/
229 return 0;
230}
231
232/********************************************************************************/
233/* interrupt handler */
234static irqreturn_t interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
235{
236 struct saa7146_dev *dev = dev_id;
237 u32 isr = 0;
238
239 /* read out the interrupt status register */
240 isr = saa7146_read(dev, ISR);
241
242 /* is this our interrupt? */
243 if ( 0 == isr ) {
244 /* nope, some other device */
245 return IRQ_NONE;
246 }
247
248 saa7146_write(dev, ISR, isr);
249
250 if( 0 != (dev->ext)) {
251 if( 0 != (dev->ext->irq_mask & isr )) {
252 if( 0 != dev->ext->irq_func ) {
253 dev->ext->irq_func(dev, &isr);
254 }
255 isr &= ~dev->ext->irq_mask;
256 }
257 }
258 if (0 != (isr & (MASK_27))) {
259 DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
260 if( 0 != dev->vv_data && 0 != dev->vv_callback) {
261 dev->vv_callback(dev,isr);
262 }
263 isr &= ~MASK_27;
264 }
265 if (0 != (isr & (MASK_28))) {
266 if( 0 != dev->vv_data && 0 != dev->vv_callback) {
267 dev->vv_callback(dev,isr);
268 }
269 isr &= ~MASK_28;
270 }
271 if (0 != (isr & (MASK_16|MASK_17))) {
272 u32 status = saa7146_read(dev, I2C_STATUS);
273 if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
274 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
275 /* only wake up if we expect something */
276 if( 0 != dev->i2c_op ) {
277 u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
278 u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
279 DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
280 dev->i2c_op = 0;
281 wake_up(&dev->i2c_wq);
282 } else {
283 DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
284 }
285 } else {
286 DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
287 }
288 isr &= ~(MASK_16|MASK_17);
289 }
290 if( 0 != isr ) {
291 ERR(("warning: interrupt enabled, but not handled properly.(0x%08x)\n",isr));
292 ERR(("disabling interrupt source(s)!\n"));
293 SAA7146_IER_DISABLE(dev,isr);
294 }
295 return IRQ_HANDLED;
296}
297
298/*********************************************************************************/
299/* configuration-functions */
300
301static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
302{
303 struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
304 struct saa7146_extension *ext = pci_ext->ext;
305 struct saa7146_dev *dev;
306 int err = -ENOMEM;
307
308 dev = kmalloc(sizeof(struct saa7146_dev), GFP_KERNEL);
309 if (!dev) {
310 ERR(("out of memory.\n"));
311 goto out;
312 }
313
314 /* clear out mem for sure */
315 memset(dev, 0x0, sizeof(struct saa7146_dev));
316
317 DEB_EE(("pci:%p\n",pci));
318
319 err = pci_enable_device(pci);
320 if (err < 0) {
321 ERR(("pci_enable_device() failed.\n"));
322 goto err_free;
323 }
324
325 /* enable bus-mastering */
326 pci_set_master(pci);
327
328 dev->pci = pci;
329
330 /* get chip-revision; this is needed to enable bug-fixes */
331 err = pci_read_config_dword(pci, PCI_CLASS_REVISION, &dev->revision);
332 if (err < 0) {
333 ERR(("pci_read_config_dword() failed.\n"));
334 goto err_disable;
335 }
336 dev->revision &= 0xf;
337
338 /* remap the memory from virtual to physical adress */
339
340 err = pci_request_region(pci, 0, "saa7146");
341 if (err < 0)
342 goto err_disable;
343
344 dev->mem = ioremap(pci_resource_start(pci, 0),
345 pci_resource_len(pci, 0));
346 if (!dev->mem) {
347 ERR(("ioremap() failed.\n"));
348 err = -ENODEV;
349 goto err_release;
350 }
351
352 /* we don't do a master reset here anymore, it screws up
353 some boards that don't have an i2c-eeprom for configuration
354 values */
355/*
356 saa7146_write(dev, MC1, MASK_31);
357*/
358
359 /* disable all irqs */
360 saa7146_write(dev, IER, 0);
361
362 /* shut down all dma transfers and rps tasks */
363 saa7146_write(dev, MC1, 0x30ff0000);
364
365 /* clear out any rps-signals pending */
366 saa7146_write(dev, MC2, 0xf8000000);
367
368 /* request an interrupt for the saa7146 */
369 err = request_irq(pci->irq, interrupt_hw, SA_SHIRQ | SA_INTERRUPT,
370 dev->name, dev);
371 if (err < 0) {
372 ERR(("request_irq() failed.\n"));
373 goto err_unmap;
374 }
375
376 err = -ENOMEM;
377
378 /* get memory for various stuff */
379 dev->d_rps0.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
380 &dev->d_rps0.dma_handle);
381 if (!dev->d_rps0.cpu_addr)
382 goto err_free_irq;
383 memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);
384
385 dev->d_rps1.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
386 &dev->d_rps1.dma_handle);
387 if (!dev->d_rps1.cpu_addr)
388 goto err_free_rps0;
389 memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);
390
391 dev->d_i2c.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
392 &dev->d_i2c.dma_handle);
393 if (!dev->d_i2c.cpu_addr)
394 goto err_free_rps1;
395 memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);
396
397 /* the rest + print status message */
398
399 /* create a nice device name */
400 sprintf(dev->name, "saa7146 (%d)", saa7146_num);
401
402 INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
403 dev->ext = ext;
404
405 pci_set_drvdata(pci, dev);
406
407 init_MUTEX(&dev->lock);
408 spin_lock_init(&dev->int_slock);
409 spin_lock_init(&dev->slock);
410
411 init_MUTEX(&dev->i2c_lock);
412
413 dev->module = THIS_MODULE;
414 init_waitqueue_head(&dev->i2c_wq);
415
416 /* set some sane pci arbitrition values */
417 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
418
419 /* TODO: use the status code of the callback */
420
421 err = -ENODEV;
422
423 if (ext->probe && ext->probe(dev)) {
424 DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));
425 goto err_free_i2c;
426 }
427
428 if (ext->attach(dev, pci_ext)) {
429 DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
430 goto err_unprobe;
431 }
432
433 INIT_LIST_HEAD(&dev->item);
434 list_add_tail(&dev->item,&saa7146_devices);
435 saa7146_num++;
436
437 err = 0;
438out:
439 return err;
440
441err_unprobe:
442 pci_set_drvdata(pci, NULL);
443err_free_i2c:
444 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
445 dev->d_i2c.dma_handle);
446err_free_rps1:
447 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr,
448 dev->d_rps1.dma_handle);
449err_free_rps0:
450 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr,
451 dev->d_rps0.dma_handle);
452err_free_irq:
453 free_irq(pci->irq, (void *)dev);
454err_unmap:
455 iounmap(dev->mem);
456err_release:
457 pci_release_region(pci, 0);
458err_disable:
459 pci_disable_device(pci);
460err_free:
461 kfree(dev);
462 goto out;
463}
464
465static void saa7146_remove_one(struct pci_dev *pdev)
466{
467 struct saa7146_dev* dev = pci_get_drvdata(pdev);
468 struct {
469 void *addr;
470 dma_addr_t dma;
471 } dev_map[] = {
472 { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle },
473 { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle },
474 { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle },
475 { NULL, 0 }
476 }, *p;
477
478 DEB_EE(("dev:%p\n",dev));
479
480 dev->ext->detach(dev);
481
482 /* shut down all video dma transfers */
483 saa7146_write(dev, MC1, 0x00ff0000);
484
485 /* disable all irqs, release irq-routine */
486 saa7146_write(dev, IER, 0);
487
488 free_irq(pdev->irq, dev);
489
490 for (p = dev_map; p->addr; p++)
491 pci_free_consistent(pdev, SAA7146_RPS_MEM, p->addr, p->dma);
492
493 iounmap(dev->mem);
494 pci_release_region(pdev, 0);
495 list_del(&dev->item);
496 pci_disable_device(pdev);
497 kfree(dev);
498
499 saa7146_num--;
500}
501
502/*********************************************************************************/
503/* extension handling functions */
504
505int saa7146_register_extension(struct saa7146_extension* ext)
506{
507 DEB_EE(("ext:%p\n",ext));
508
509 ext->driver.name = ext->name;
510 ext->driver.id_table = ext->pci_tbl;
511 ext->driver.probe = saa7146_init_one;
512 ext->driver.remove = saa7146_remove_one;
513
514 printk("saa7146: register extension '%s'.\n",ext->name);
515 return pci_module_init(&ext->driver);
516}
517
518int saa7146_unregister_extension(struct saa7146_extension* ext)
519{
520 DEB_EE(("ext:%p\n",ext));
521 printk("saa7146: unregister extension '%s'.\n",ext->name);
522 pci_unregister_driver(&ext->driver);
523 return 0;
524}
525
526EXPORT_SYMBOL_GPL(saa7146_register_extension);
527EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
528
529/* misc functions used by extension modules */
530EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
531EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
532EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
533EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
534EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
535
536EXPORT_SYMBOL_GPL(saa7146_setgpio);
537
538EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
539EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
540
541EXPORT_SYMBOL_GPL(saa7146_debug);
542EXPORT_SYMBOL_GPL(saa7146_devices);
543EXPORT_SYMBOL_GPL(saa7146_devices_lock);
544
545MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
546MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
547MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
new file mode 100644
index 000000000000..cb826c9adfe7
--- /dev/null
+++ b/drivers/media/common/saa7146_fops.c
@@ -0,0 +1,564 @@
1#include <media/saa7146_vv.h>
2#include <linux/version.h>
3
4#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
5
6/****************************************************************************/
7/* resource management functions, shamelessly stolen from saa7134 driver */
8
9int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
10{
11 struct saa7146_dev *dev = fh->dev;
12 struct saa7146_vv *vv = dev->vv_data;
13
14 if (fh->resources & bit) {
15 DEB_D(("already allocated! want: 0x%02x, cur:0x%02x\n",bit,vv->resources));
16 /* have it already allocated */
17 return 1;
18 }
19
20 /* is it free? */
21 down(&dev->lock);
22 if (vv->resources & bit) {
23 DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
24 /* no, someone else uses it */
25 up(&dev->lock);
26 return 0;
27 }
28 /* it's free, grab it */
29 fh->resources |= bit;
30 vv->resources |= bit;
31 DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
32 up(&dev->lock);
33 return 1;
34}
35
36void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
37{
38 struct saa7146_dev *dev = fh->dev;
39 struct saa7146_vv *vv = dev->vv_data;
40
41 if ((fh->resources & bits) != bits)
42 BUG();
43
44 down(&dev->lock);
45 fh->resources &= ~bits;
46 vv->resources &= ~bits;
47 DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
48 up(&dev->lock);
49}
50
51
52/********************************************************************************/
53/* common dma functions */
54
55void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
56{
57 DEB_EE(("dev:%p, buf:%p\n",dev,buf));
58
59 if (in_interrupt())
60 BUG();
61
62 videobuf_waiton(&buf->vb,0,0);
63 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
64 videobuf_dma_free(&buf->vb.dma);
65 buf->vb.state = STATE_NEEDS_INIT;
66}
67
68
69/********************************************************************************/
70/* common buffer functions */
71
72int saa7146_buffer_queue(struct saa7146_dev *dev,
73 struct saa7146_dmaqueue *q,
74 struct saa7146_buf *buf)
75{
76 assert_spin_locked(&dev->slock);
77 DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf));
78
79 BUG_ON(!q);
80
81 if (NULL == q->curr) {
82 q->curr = buf;
83 DEB_D(("immediately activating buffer %p\n", buf));
84 buf->activate(dev,buf,NULL);
85 } else {
86 list_add_tail(&buf->vb.queue,&q->queue);
87 buf->vb.state = STATE_QUEUED;
88 DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf));
89 }
90 return 0;
91}
92
93void saa7146_buffer_finish(struct saa7146_dev *dev,
94 struct saa7146_dmaqueue *q,
95 int state)
96{
97 assert_spin_locked(&dev->slock);
98 DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
99 DEB_EE(("q->curr:%p\n",q->curr));
100
101 BUG_ON(!q->curr);
102
103 /* finish current buffer */
104 if (NULL == q->curr) {
105 DEB_D(("aiii. no current buffer\n"));
106 return;
107 }
108
109 q->curr->vb.state = state;
110 do_gettimeofday(&q->curr->vb.ts);
111 wake_up(&q->curr->vb.done);
112
113 q->curr = NULL;
114}
115
116void saa7146_buffer_next(struct saa7146_dev *dev,
117 struct saa7146_dmaqueue *q, int vbi)
118{
119 struct saa7146_buf *buf,*next = NULL;
120
121 BUG_ON(!q);
122
123 DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
124
125 assert_spin_locked(&dev->slock);
126 if (!list_empty(&q->queue)) {
127 /* activate next one from queue */
128 buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
129 list_del(&buf->vb.queue);
130 if (!list_empty(&q->queue))
131 next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
132 q->curr = buf;
133 DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
134 buf->activate(dev,buf,next);
135 } else {
136 DEB_INT(("no next buffer. stopping.\n"));
137 if( 0 != vbi ) {
138 /* turn off video-dma3 */
139 saa7146_write(dev,MC1, MASK_20);
140 } else {
141 /* nothing to do -- just prevent next video-dma1 transfer
142 by lowering the protection address */
143
144 // fixme: fix this for vflip != 0
145
146 saa7146_write(dev, PROT_ADDR1, 0);
147 saa7146_write(dev, MC2, (MASK_02|MASK_18));
148
149 /* write the address of the rps-program */
150 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
151 /* turn on rps */
152 saa7146_write(dev, MC1, (MASK_12 | MASK_28));
153
154/*
155 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
156 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
157 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
158 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
159 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
160 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
161*/
162 }
163 del_timer(&q->timeout);
164 }
165}
166
167void saa7146_buffer_timeout(unsigned long data)
168{
169 struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
170 struct saa7146_dev *dev = q->dev;
171 unsigned long flags;
172
173 DEB_EE(("dev:%p, dmaq:%p\n", dev, q));
174
175 spin_lock_irqsave(&dev->slock,flags);
176 if (q->curr) {
177 DEB_D(("timeout on %p\n", q->curr));
178 saa7146_buffer_finish(dev,q,STATE_ERROR);
179 }
180
181 /* we don't restart the transfer here like other drivers do. when
182 a streaming capture is disabled, the timeout function will be
183 called for the current buffer. if we activate the next buffer now,
184 we mess up our capture logic. if a timeout occurs on another buffer,
185 then something is seriously broken before, so no need to buffer the
186 next capture IMHO... */
187/*
188 saa7146_buffer_next(dev,q);
189*/
190 spin_unlock_irqrestore(&dev->slock,flags);
191}
192
193/********************************************************************************/
194/* file operations */
195
196static int fops_open(struct inode *inode, struct file *file)
197{
198 unsigned int minor = iminor(inode);
199 struct saa7146_dev *h = NULL, *dev = NULL;
200 struct list_head *list;
201 struct saa7146_fh *fh = NULL;
202 int result = 0;
203
204 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
205
206 DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
207
208 if (down_interruptible(&saa7146_devices_lock))
209 return -ERESTARTSYS;
210
211 list_for_each(list,&saa7146_devices) {
212 h = list_entry(list, struct saa7146_dev, item);
213 if( NULL == h->vv_data ) {
214 DEB_D(("device %p has not registered video devices.\n",h));
215 continue;
216 }
217 DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
218
219 if (h->vv_data->video_minor == minor) {
220 dev = h;
221 }
222 if (h->vv_data->vbi_minor == minor) {
223 type = V4L2_BUF_TYPE_VBI_CAPTURE;
224 dev = h;
225 }
226 }
227 if (NULL == dev) {
228 DEB_S(("no such video device.\n"));
229 result = -ENODEV;
230 goto out;
231 }
232
233 DEB_D(("using: %p\n",dev));
234
235 /* check if an extension is registered */
236 if( NULL == dev->ext ) {
237 DEB_S(("no extension registered for this device.\n"));
238 result = -ENODEV;
239 goto out;
240 }
241
242 /* allocate per open data */
243 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
244 if (NULL == fh) {
245 DEB_S(("cannot allocate memory for per open data.\n"));
246 result = -ENOMEM;
247 goto out;
248 }
249 memset(fh,0,sizeof(*fh));
250
251 file->private_data = fh;
252 fh->dev = dev;
253 fh->type = type;
254
255 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
256 DEB_S(("initializing vbi...\n"));
257 result = saa7146_vbi_uops.open(dev,file);
258 } else {
259 DEB_S(("initializing video...\n"));
260 result = saa7146_video_uops.open(dev,file);
261 }
262
263 if (0 != result) {
264 goto out;
265 }
266
267 if( 0 == try_module_get(dev->ext->module)) {
268 result = -EINVAL;
269 goto out;
270 }
271
272 result = 0;
273out:
274 if( fh != 0 && result != 0 ) {
275 kfree(fh);
276 file->private_data = NULL;
277 }
278 up(&saa7146_devices_lock);
279 return result;
280}
281
282static int fops_release(struct inode *inode, struct file *file)
283{
284 struct saa7146_fh *fh = file->private_data;
285 struct saa7146_dev *dev = fh->dev;
286
287 DEB_EE(("inode:%p, file:%p\n",inode,file));
288
289 if (down_interruptible(&saa7146_devices_lock))
290 return -ERESTARTSYS;
291
292 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
293 saa7146_vbi_uops.release(dev,file);
294 } else {
295 saa7146_video_uops.release(dev,file);
296 }
297
298 module_put(dev->ext->module);
299 file->private_data = NULL;
300 kfree(fh);
301
302 up(&saa7146_devices_lock);
303
304 return 0;
305}
306
307int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
308static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
309{
310/*
311 DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
312*/
313 return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
314}
315
316static int fops_mmap(struct file *file, struct vm_area_struct * vma)
317{
318 struct saa7146_fh *fh = file->private_data;
319 struct videobuf_queue *q;
320
321 switch (fh->type) {
322 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
323 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma));
324 q = &fh->video_q;
325 break;
326 }
327 case V4L2_BUF_TYPE_VBI_CAPTURE: {
328 DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma));
329 q = &fh->vbi_q;
330 break;
331 }
332 default:
333 BUG();
334 return 0;
335 }
336 return videobuf_mmap_mapper(q,vma);
337}
338
339static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
340{
341 struct saa7146_fh *fh = file->private_data;
342 struct videobuf_buffer *buf = NULL;
343 struct videobuf_queue *q;
344
345 DEB_EE(("file:%p, poll:%p\n",file, wait));
346
347 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
348 if( 0 == fh->vbi_q.streaming )
349 return videobuf_poll_stream(file, &fh->vbi_q, wait);
350 q = &fh->vbi_q;
351 } else {
352 DEB_D(("using video queue.\n"));
353 q = &fh->video_q;
354 }
355
356 if (!list_empty(&q->stream))
357 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
358
359 if (!buf) {
360 DEB_D(("buf == NULL!\n"));
361 return POLLERR;
362 }
363
364 poll_wait(file, &buf->done, wait);
365 if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
366 DEB_D(("poll succeeded!\n"));
367 return POLLIN|POLLRDNORM;
368 }
369
370 DEB_D(("nothing to poll for, buf->state:%d\n",buf->state));
371 return 0;
372}
373
374static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
375{
376 struct saa7146_fh *fh = file->private_data;
377
378 switch (fh->type) {
379 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
380// DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
381 return saa7146_video_uops.read(file,data,count,ppos);
382 }
383 case V4L2_BUF_TYPE_VBI_CAPTURE: {
384// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
385 return saa7146_vbi_uops.read(file,data,count,ppos);
386 }
387 break;
388 default:
389 BUG();
390 return 0;
391 }
392}
393
394static struct file_operations video_fops =
395{
396 .owner = THIS_MODULE,
397 .open = fops_open,
398 .release = fops_release,
399 .read = fops_read,
400 .poll = fops_poll,
401 .mmap = fops_mmap,
402 .ioctl = fops_ioctl,
403 .llseek = no_llseek,
404};
405
406void vv_callback(struct saa7146_dev *dev, unsigned long status)
407{
408 u32 isr = status;
409
410 DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));
411
412 if (0 != (isr & (MASK_27))) {
413 DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
414 saa7146_video_uops.irq_done(dev,isr);
415 }
416
417 if (0 != (isr & (MASK_28))) {
418 u32 mc2 = saa7146_read(dev, MC2);
419 if( 0 != (mc2 & MASK_15)) {
420 DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
421 wake_up(&dev->vv_data->vbi_wq);
422 saa7146_write(dev,MC2, MASK_31);
423 return;
424 }
425 DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
426 saa7146_vbi_uops.irq_done(dev,isr);
427 }
428}
429
430static struct video_device device_template =
431{
432 .hardware = VID_HARDWARE_SAA7146,
433 .fops = &video_fops,
434 .minor = -1,
435};
436
437int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
438{
439 struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
440 if( NULL == vv ) {
441 ERR(("out of memory. aborting.\n"));
442 return -1;
443 }
444 memset(vv, 0x0, sizeof(*vv));
445
446 DEB_EE(("dev:%p\n",dev));
447
448 /* set default values for video parts of the saa7146 */
449 saa7146_write(dev, BCS_CTRL, 0x80400040);
450
451 /* enable video-port pins */
452 saa7146_write(dev, MC1, (MASK_10 | MASK_26));
453
454 /* save per-device extension data (one extension can
455 handle different devices that might need different
456 configuration data) */
457 dev->ext_vv_data = ext_vv;
458
459 vv->video_minor = -1;
460 vv->vbi_minor = -1;
461
462 vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
463 if( NULL == vv->d_clipping.cpu_addr ) {
464 ERR(("out of memory. aborting.\n"));
465 kfree(vv);
466 return -1;
467 }
468 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
469
470 saa7146_video_uops.init(dev,vv);
471 saa7146_vbi_uops.init(dev,vv);
472
473 dev->vv_data = vv;
474 dev->vv_callback = &vv_callback;
475
476 return 0;
477}
478
479int saa7146_vv_release(struct saa7146_dev* dev)
480{
481 struct saa7146_vv *vv = dev->vv_data;
482
483 DEB_EE(("dev:%p\n",dev));
484
485 pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
486 kfree(vv);
487 dev->vv_data = NULL;
488 dev->vv_callback = NULL;
489
490 return 0;
491}
492
493int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
494 char *name, int type)
495{
496 struct saa7146_vv *vv = dev->vv_data;
497 struct video_device *vfd;
498
499 DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
500
501 // released by vfd->release
502 vfd = video_device_alloc();
503 if (vfd == NULL)
504 return -ENOMEM;
505
506 memcpy(vfd, &device_template, sizeof(struct video_device));
507 strlcpy(vfd->name, name, sizeof(vfd->name));
508 vfd->release = video_device_release;
509 vfd->priv = dev;
510
511 // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
512 if (video_register_device(vfd, type, -1) < 0) {
513 ERR(("cannot register v4l2 device. skipping.\n"));
514 return -1;
515 }
516
517 if( VFL_TYPE_GRABBER == type ) {
518 vv->video_minor = vfd->minor;
519 INFO(("%s: registered device video%d [v4l2]\n",
520 dev->name, vfd->minor & 0x1f));
521 } else {
522 vv->vbi_minor = vfd->minor;
523 INFO(("%s: registered device vbi%d [v4l2]\n",
524 dev->name, vfd->minor & 0x1f));
525 }
526
527 *vid = vfd;
528 return 0;
529}
530
531int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
532{
533 struct saa7146_vv *vv = dev->vv_data;
534
535 DEB_EE(("dev:%p\n",dev));
536
537 if( VFL_TYPE_GRABBER == (*vid)->type ) {
538 vv->video_minor = -1;
539 } else {
540 vv->vbi_minor = -1;
541 }
542
543 video_unregister_device(*vid);
544 *vid = NULL;
545
546 return 0;
547}
548
549static int __init saa7146_vv_init_module(void)
550{
551 return 0;
552}
553
554
555static void __exit saa7146_vv_cleanup_module(void)
556{
557}
558
559module_init(saa7146_vv_init_module);
560module_exit(saa7146_vv_cleanup_module);
561
562MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
563MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
564MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
new file mode 100644
index 000000000000..ec52dff8cb69
--- /dev/null
+++ b/drivers/media/common/saa7146_hlp.c
@@ -0,0 +1,1036 @@
1#include <linux/kernel.h>
2#include <media/saa7146_vv.h>
3
4static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
5{
6 /* clear out the necessary bits */
7 *clip_format &= 0x0000ffff;
8 /* set these bits new */
9 *clip_format |= (( ((palette&0xf00)>>8) << 30) | ((palette&0x00f) << 24) | (((palette&0x0f0)>>4) << 16));
10}
11
12static void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync, u32* hps_ctrl)
13{
14 *hps_ctrl &= ~(MASK_30 | MASK_31 | MASK_28);
15 *hps_ctrl |= (source << 30) | (sync << 28);
16}
17
18static void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl)
19{
20 int hyo = 0, hxo = 0;
21
22 hyo = vv->standard->v_offset;
23 hxo = vv->standard->h_offset;
24
25 *hps_h_scale &= ~(MASK_B0 | 0xf00);
26 *hps_h_scale |= (hxo << 0);
27
28 *hps_ctrl &= ~(MASK_W0 | MASK_B2);
29 *hps_ctrl |= (hyo << 12);
30}
31
32/* helper functions for the calculation of the horizontal- and vertical
33 scaling registers, clip-format-register etc ...
34 these functions take pointers to the (most-likely read-out
35 original-values) and manipulate them according to the requested
36 changes.
37*/
38
39/* hps_coeff used for CXY and CXUV; scale 1/1 -> scale 1/64 */
40static struct {
41 u16 hps_coeff;
42 u16 weight_sum;
43} hps_h_coeff_tab [] = {
44 {0x00, 2}, {0x02, 4}, {0x00, 4}, {0x06, 8}, {0x02, 8},
45 {0x08, 8}, {0x00, 8}, {0x1E, 16}, {0x0E, 8}, {0x26, 8},
46 {0x06, 8}, {0x42, 8}, {0x02, 8}, {0x80, 8}, {0x00, 8},
47 {0xFE, 16}, {0xFE, 8}, {0x7E, 8}, {0x7E, 8}, {0x3E, 8},
48 {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, {0x0E, 8}, {0x0E, 8},
49 {0x06, 8}, {0x06, 8}, {0x02, 8}, {0x02, 8}, {0x00, 8},
50 {0x00, 8}, {0xFE, 16}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
51 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
52 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
53 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0x7E, 8},
54 {0x7E, 8}, {0x3E, 8}, {0x3E, 8}, {0x1E, 8}, {0x1E, 8},
55 {0x0E, 8}, {0x0E, 8}, {0x06, 8}, {0x06, 8}, {0x02, 8},
56 {0x02, 8}, {0x00, 8}, {0x00, 8}, {0xFE, 16}
57};
58
59/* table of attenuation values for horizontal scaling */
60static u8 h_attenuation[] = { 1, 2, 4, 8, 2, 4, 8, 16, 0};
61
62/* calculate horizontal scale registers */
63static int calculate_h_scale_registers(struct saa7146_dev *dev,
64 int in_x, int out_x, int flip_lr,
65 u32* hps_ctrl, u32* hps_v_gain, u32* hps_h_prescale, u32* hps_h_scale)
66{
67 /* horizontal prescaler */
68 u32 dcgx = 0, xpsc = 0, xacm = 0, cxy = 0, cxuv = 0;
69 /* horizontal scaler */
70 u32 xim = 0, xp = 0, xsci =0;
71 /* vertical scale & gain */
72 u32 pfuv = 0;
73
74 /* helper variables */
75 u32 h_atten = 0, i = 0;
76
77 if ( 0 == out_x ) {
78 return -EINVAL;
79 }
80
81 /* mask out vanity-bit */
82 *hps_ctrl &= ~MASK_29;
83
84 /* calculate prescale-(xspc)-value: [n .. 1/2) : 1
85 [1/2 .. 1/3) : 2
86 [1/3 .. 1/4) : 3
87 ... */
88 if (in_x > out_x) {
89 xpsc = in_x / out_x;
90 }
91 else {
92 /* zooming */
93 xpsc = 1;
94 }
95
96 /* if flip_lr-bit is set, number of pixels after
97 horizontal prescaling must be < 384 */
98 if ( 0 != flip_lr ) {
99
100 /* set vanity bit */
101 *hps_ctrl |= MASK_29;
102
103 while (in_x / xpsc >= 384 )
104 xpsc++;
105 }
106 /* if zooming is wanted, number of pixels after
107 horizontal prescaling must be < 768 */
108 else {
109 while ( in_x / xpsc >= 768 )
110 xpsc++;
111 }
112
113 /* maximum prescale is 64 (p.69) */
114 if ( xpsc > 64 )
115 xpsc = 64;
116
117 /* keep xacm clear*/
118 xacm = 0;
119
120 /* set horizontal filter parameters (CXY = CXUV) */
121 cxy = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].hps_coeff;
122 cxuv = cxy;
123
124 /* calculate and set horizontal fine scale (xsci) */
125
126 /* bypass the horizontal scaler ? */
127 if ( (in_x == out_x) && ( 1 == xpsc ) )
128 xsci = 0x400;
129 else
130 xsci = ( (1024 * in_x) / (out_x * xpsc) ) + xpsc;
131
132 /* set start phase for horizontal fine scale (xp) to 0 */
133 xp = 0;
134
135 /* set xim, if we bypass the horizontal scaler */
136 if ( 0x400 == xsci )
137 xim = 1;
138 else
139 xim = 0;
140
141 /* if the prescaler is bypassed, enable horizontal
142 accumulation mode (xacm) and clear dcgx */
143 if( 1 == xpsc ) {
144 xacm = 1;
145 dcgx = 0;
146 } else {
147 xacm = 0;
148 /* get best match in the table of attenuations
149 for horizontal scaling */
150 h_atten = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].weight_sum;
151
152 for (i = 0; h_attenuation[i] != 0; i++) {
153 if (h_attenuation[i] >= h_atten)
154 break;
155 }
156
157 dcgx = i;
158 }
159
160 /* the horizontal scaling increment controls the UV filter
161 to reduce the bandwith to improve the display quality,
162 so set it ... */
163 if ( xsci == 0x400)
164 pfuv = 0x00;
165 else if ( xsci < 0x600)
166 pfuv = 0x01;
167 else if ( xsci < 0x680)
168 pfuv = 0x11;
169 else if ( xsci < 0x700)
170 pfuv = 0x22;
171 else
172 pfuv = 0x33;
173
174
175 *hps_v_gain &= MASK_W0|MASK_B2;
176 *hps_v_gain |= (pfuv << 24);
177
178 *hps_h_scale &= ~(MASK_W1 | 0xf000);
179 *hps_h_scale |= (xim << 31) | (xp << 24) | (xsci << 12);
180
181 *hps_h_prescale |= (dcgx << 27) | ((xpsc-1) << 18) | (xacm << 17) | (cxy << 8) | (cxuv << 0);
182
183 return 0;
184}
185
186static struct {
187 u16 hps_coeff;
188 u16 weight_sum;
189} hps_v_coeff_tab [] = {
190 {0x0100, 2}, {0x0102, 4}, {0x0300, 4}, {0x0106, 8}, {0x0502, 8},
191 {0x0708, 8}, {0x0F00, 8}, {0x011E, 16}, {0x110E, 16}, {0x1926, 16},
192 {0x3906, 16}, {0x3D42, 16}, {0x7D02, 16}, {0x7F80, 16}, {0xFF00, 16},
193 {0x01FE, 32}, {0x01FE, 32}, {0x817E, 32}, {0x817E, 32}, {0xC13E, 32},
194 {0xC13E, 32}, {0xE11E, 32}, {0xE11E, 32}, {0xF10E, 32}, {0xF10E, 32},
195 {0xF906, 32}, {0xF906, 32}, {0xFD02, 32}, {0xFD02, 32}, {0xFF00, 32},
196 {0xFF00, 32}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
197 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
198 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
199 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x817E, 64},
200 {0x817E, 64}, {0xC13E, 64}, {0xC13E, 64}, {0xE11E, 64}, {0xE11E, 64},
201 {0xF10E, 64}, {0xF10E, 64}, {0xF906, 64}, {0xF906, 64}, {0xFD02, 64},
202 {0xFD02, 64}, {0xFF00, 64}, {0xFF00, 64}, {0x01FE, 128}
203};
204
205/* table of attenuation values for vertical scaling */
206static u16 v_attenuation[] = { 2, 4, 8, 16, 32, 64, 128, 256, 0};
207
208/* calculate vertical scale registers */
209static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field field,
210 int in_y, int out_y, u32* hps_v_scale, u32* hps_v_gain)
211{
212 int lpi = 0;
213
214 /* vertical scaling */
215 u32 yacm = 0, ysci = 0, yacl = 0, ypo = 0, ype = 0;
216 /* vertical scale & gain */
217 u32 dcgy = 0, cya_cyb = 0;
218
219 /* helper variables */
220 u32 v_atten = 0, i = 0;
221
222 /* error, if vertical zooming */
223 if ( in_y < out_y ) {
224 return -EINVAL;
225 }
226
227 /* linear phase interpolation may be used
228 if scaling is between 1 and 1/2 (both fields used)
229 or scaling is between 1/2 and 1/4 (if only one field is used) */
230
231 if (V4L2_FIELD_HAS_BOTH(field)) {
232 if( 2*out_y >= in_y) {
233 lpi = 1;
234 }
235 } else if (field == V4L2_FIELD_TOP
236 || field == V4L2_FIELD_ALTERNATE
237 || field == V4L2_FIELD_BOTTOM) {
238 if( 4*out_y >= in_y ) {
239 lpi = 1;
240 }
241 out_y *= 2;
242 }
243 if( 0 != lpi ) {
244
245 yacm = 0;
246 yacl = 0;
247 cya_cyb = 0x00ff;
248
249 /* calculate scaling increment */
250 if ( in_y > out_y )
251 ysci = ((1024 * in_y) / (out_y + 1)) - 1024;
252 else
253 ysci = 0;
254
255 dcgy = 0;
256
257 /* calculate ype and ypo */
258 ype = ysci / 16;
259 ypo = ype + (ysci / 64);
260
261 } else {
262 yacm = 1;
263
264 /* calculate scaling increment */
265 ysci = (((10 * 1024 * (in_y - out_y - 1)) / in_y) + 9) / 10;
266
267 /* calculate ype and ypo */
268 ypo = ype = ((ysci + 15) / 16);
269
270 /* the sequence length interval (yacl) has to be set according
271 to the prescale value, e.g. [n .. 1/2) : 0
272 [1/2 .. 1/3) : 1
273 [1/3 .. 1/4) : 2
274 ... */
275 if ( ysci < 512) {
276 yacl = 0;
277 } else {
278 yacl = ( ysci / (1024 - ysci) );
279 }
280
281 /* get filter coefficients for cya, cyb from table hps_v_coeff_tab */
282 cya_cyb = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].hps_coeff;
283
284 /* get best match in the table of attenuations for vertical scaling */
285 v_atten = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].weight_sum;
286
287 for (i = 0; v_attenuation[i] != 0; i++) {
288 if (v_attenuation[i] >= v_atten)
289 break;
290 }
291
292 dcgy = i;
293 }
294
295 /* ypo and ype swapped in spec ? */
296 *hps_v_scale |= (yacm << 31) | (ysci << 21) | (yacl << 15) | (ypo << 8 ) | (ype << 1);
297
298 *hps_v_gain &= ~(MASK_W0|MASK_B2);
299 *hps_v_gain |= (dcgy << 16) | (cya_cyb << 0);
300
301 return 0;
302}
303
304/* simple bubble-sort algorithm with duplicate elimination */
305static int sort_and_eliminate(u32* values, int* count)
306{
307 int low = 0, high = 0, top = 0, temp = 0;
308 int cur = 0, next = 0;
309
310 /* sanity checks */
311 if( (0 > *count) || (NULL == values) ) {
312 return -EINVAL;
313 }
314
315 /* bubble sort the first ´count´ items of the array ´values´ */
316 for( top = *count; top > 0; top--) {
317 for( low = 0, high = 1; high < top; low++, high++) {
318 if( values[low] > values[high] ) {
319 temp = values[low];
320 values[low] = values[high];
321 values[high] = temp;
322 }
323 }
324 }
325
326 /* remove duplicate items */
327 for( cur = 0, next = 1; next < *count; next++) {
328 if( values[cur] != values[next])
329 values[++cur] = values[next];
330 }
331
332 *count = cur + 1;
333
334 return 0;
335}
336
337static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh,
338 struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field)
339{
340 struct saa7146_vv *vv = dev->vv_data;
341 u32 *clipping = vv->d_clipping.cpu_addr;
342
343 int width = fh->ov.win.w.width;
344 int height = fh->ov.win.w.height;
345 int clipcount = fh->ov.nclips;
346
347 u32 line_list[32];
348 u32 pixel_list[32];
349 int numdwords = 0;
350
351 int i = 0, j = 0;
352 int cnt_line = 0, cnt_pixel = 0;
353
354 int x[32], y[32], w[32], h[32];
355
356 /* clear out memory */
357 memset(&line_list[0], 0x00, sizeof(u32)*32);
358 memset(&pixel_list[0], 0x00, sizeof(u32)*32);
359 memset(clipping, 0x00, SAA7146_CLIPPING_MEM);
360
361 /* fill the line and pixel-lists */
362 for(i = 0; i < clipcount; i++) {
363 int l = 0, r = 0, t = 0, b = 0;
364
365 x[i] = fh->ov.clips[i].c.left;
366 y[i] = fh->ov.clips[i].c.top;
367 w[i] = fh->ov.clips[i].c.width;
368 h[i] = fh->ov.clips[i].c.height;
369
370 if( w[i] < 0) {
371 x[i] += w[i]; w[i] = -w[i];
372 }
373 if( h[i] < 0) {
374 y[i] += h[i]; h[i] = -h[i];
375 }
376 if( x[i] < 0) {
377 w[i] += x[i]; x[i] = 0;
378 }
379 if( y[i] < 0) {
380 h[i] += y[i]; y[i] = 0;
381 }
382 if( 0 != vv->vflip ) {
383 y[i] = height - y[i] - h[i];
384 }
385
386 l = x[i];
387 r = x[i]+w[i];
388 t = y[i];
389 b = y[i]+h[i];
390
391 /* insert left/right coordinates */
392 pixel_list[ 2*i ] = min_t(int, l, width);
393 pixel_list[(2*i)+1] = min_t(int, r, width);
394 /* insert top/bottom coordinates */
395 line_list[ 2*i ] = min_t(int, t, height);
396 line_list[(2*i)+1] = min_t(int, b, height);
397 }
398
399 /* sort and eliminate lists */
400 cnt_line = cnt_pixel = 2*clipcount;
401 sort_and_eliminate( &pixel_list[0], &cnt_pixel );
402 sort_and_eliminate( &line_list[0], &cnt_line );
403
404 /* calculate the number of used u32s */
405 numdwords = max_t(int, (cnt_line+1), (cnt_pixel+1))*2;
406 numdwords = max_t(int, 4, numdwords);
407 numdwords = min_t(int, 64, numdwords);
408
409 /* fill up cliptable */
410 for(i = 0; i < cnt_pixel; i++) {
411 clipping[2*i] |= cpu_to_le32(pixel_list[i] << 16);
412 }
413 for(i = 0; i < cnt_line; i++) {
414 clipping[(2*i)+1] |= cpu_to_le32(line_list[i] << 16);
415 }
416
417 /* fill up cliptable with the display infos */
418 for(j = 0; j < clipcount; j++) {
419
420 for(i = 0; i < cnt_pixel; i++) {
421
422 if( x[j] < 0)
423 x[j] = 0;
424
425 if( pixel_list[i] < (x[j] + w[j])) {
426
427 if ( pixel_list[i] >= x[j] ) {
428 clipping[2*i] |= cpu_to_le32(1 << j);
429 }
430 }
431 }
432 for(i = 0; i < cnt_line; i++) {
433
434 if( y[j] < 0)
435 y[j] = 0;
436
437 if( line_list[i] < (y[j] + h[j]) ) {
438
439 if( line_list[i] >= y[j] ) {
440 clipping[(2*i)+1] |= cpu_to_le32(1 << j);
441 }
442 }
443 }
444 }
445
446 /* adjust arbitration control register */
447 *arbtr_ctrl &= 0xffff00ff;
448 *arbtr_ctrl |= 0x00001c00;
449
450 vdma2->base_even = vv->d_clipping.dma_handle;
451 vdma2->base_odd = vv->d_clipping.dma_handle;
452 vdma2->prot_addr = vv->d_clipping.dma_handle+((sizeof(u32))*(numdwords));
453 vdma2->base_page = 0x04;
454 vdma2->pitch = 0x00;
455 vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) );
456
457 /* set clipping-mode. this depends on the field(s) used */
458 *clip_format &= 0xfffffff7;
459 if (V4L2_FIELD_HAS_BOTH(field)) {
460 *clip_format |= 0x00000008;
461 } else {
462 *clip_format |= 0x00000000;
463 }
464}
465
466/* disable clipping */
467static void saa7146_disable_clipping(struct saa7146_dev *dev)
468{
469 u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
470
471 /* mask out relevant bits (=lower word)*/
472 clip_format &= MASK_W1;
473
474 /* upload clipping-registers*/
475 saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
476 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
477
478 /* disable video dma2 */
479 saa7146_write(dev, MC1, MASK_21);
480}
481
482static void saa7146_set_clipping_rect(struct saa7146_fh *fh)
483{
484 struct saa7146_dev *dev = fh->dev;
485 enum v4l2_field field = fh->ov.win.field;
486 struct saa7146_video_dma vdma2;
487 u32 clip_format;
488 u32 arbtr_ctrl;
489
490 /* check clipcount, disable clipping if clipcount == 0*/
491 if( fh->ov.nclips == 0 ) {
492 saa7146_disable_clipping(dev);
493 return;
494 }
495
496 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
497 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
498
499 calculate_clipping_registers_rect(dev, fh, &vdma2, &clip_format, &arbtr_ctrl, field);
500
501 /* set clipping format */
502 clip_format &= 0xffff0008;
503 clip_format |= (SAA7146_CLIPPING_RECT << 4);
504
505 /* prepare video dma2 */
506 saa7146_write(dev, BASE_EVEN2, vdma2.base_even);
507 saa7146_write(dev, BASE_ODD2, vdma2.base_odd);
508 saa7146_write(dev, PROT_ADDR2, vdma2.prot_addr);
509 saa7146_write(dev, BASE_PAGE2, vdma2.base_page);
510 saa7146_write(dev, PITCH2, vdma2.pitch);
511 saa7146_write(dev, NUM_LINE_BYTE2, vdma2.num_line_byte);
512
513 /* prepare the rest */
514 saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
515 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
516
517 /* upload clip_control-register, clipping-registers, enable video dma2 */
518 saa7146_write(dev, MC2, (MASK_05 | MASK_21 | MASK_03 | MASK_19));
519 saa7146_write(dev, MC1, (MASK_05 | MASK_21));
520}
521
522static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field)
523{
524 struct saa7146_vv *vv = dev->vv_data;
525
526 int source = vv->current_hps_source;
527 int sync = vv->current_hps_sync;
528
529 u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;
530
531 /* set vertical scale */
532 hps_v_scale = 0; /* all bits get set by the function-call */
533 hps_v_gain = 0; /* fixme: saa7146_read(dev, HPS_V_GAIN);*/
534 calculate_v_scale_registers(dev, field, vv->standard->v_field*2, height, &hps_v_scale, &hps_v_gain);
535
536 /* set horizontal scale */
537 hps_ctrl = 0;
538 hps_h_prescale = 0; /* all bits get set in the function */
539 hps_h_scale = 0;
540 calculate_h_scale_registers(dev, vv->standard->h_pixels, width, vv->hflip, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);
541
542 /* set hyo and hxo */
543 calculate_hxo_and_hyo(vv, &hps_h_scale, &hps_ctrl);
544 calculate_hps_source_and_sync(dev, source, sync, &hps_ctrl);
545
546 /* write out new register contents */
547 saa7146_write(dev, HPS_V_SCALE, hps_v_scale);
548 saa7146_write(dev, HPS_V_GAIN, hps_v_gain);
549 saa7146_write(dev, HPS_CTRL, hps_ctrl);
550 saa7146_write(dev, HPS_H_PRESCALE,hps_h_prescale);
551 saa7146_write(dev, HPS_H_SCALE, hps_h_scale);
552
553 /* upload shadow-ram registers */
554 saa7146_write(dev, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) );
555}
556
557/* calculate the new memory offsets for a desired position */
558static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
559{
560 struct saa7146_vv *vv = dev->vv_data;
561 struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
562
563 int b_depth = vv->ov_fmt->depth;
564 int b_bpl = vv->ov_fb.fmt.bytesperline;
565 u32 base = (u32)vv->ov_fb.base;
566
567 struct saa7146_video_dma vdma1;
568
569 /* calculate memory offsets for picture, look if we shall top-down-flip */
570 vdma1.pitch = 2*b_bpl;
571 if ( 0 == vv->vflip ) {
572 vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
573 vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2);
574 vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
575 }
576 else {
577 vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
578 vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2);
579 vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2));
580 }
581
582 if (V4L2_FIELD_HAS_BOTH(field)) {
583 } else if (field == V4L2_FIELD_ALTERNATE) {
584 /* fixme */
585 vdma1.base_odd = vdma1.prot_addr;
586 vdma1.pitch /= 2;
587 } else if (field == V4L2_FIELD_TOP) {
588 vdma1.base_odd = vdma1.prot_addr;
589 vdma1.pitch /= 2;
590 } else if (field == V4L2_FIELD_BOTTOM) {
591 vdma1.base_odd = vdma1.base_even;
592 vdma1.base_even = vdma1.prot_addr;
593 vdma1.pitch /= 2;
594 }
595
596 if ( 0 != vv->vflip ) {
597 vdma1.pitch *= -1;
598 }
599
600 vdma1.base_page = sfmt->swap;
601 vdma1.num_line_byte = (vv->standard->v_field<<16)+vv->standard->h_pixels;
602
603 saa7146_write_out_dma(dev, 1, &vdma1);
604}
605
606static void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette)
607{
608 u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
609
610 /* call helper function */
611 calculate_output_format_register(dev,palette,&clip_format);
612
613 /* update the hps registers */
614 saa7146_write(dev, CLIP_FORMAT_CTRL, clip_format);
615 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
616}
617
618/* select input-source */
619void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync)
620{
621 struct saa7146_vv *vv = dev->vv_data;
622 u32 hps_ctrl = 0;
623
624 /* read old state */
625 hps_ctrl = saa7146_read(dev, HPS_CTRL);
626
627 hps_ctrl &= ~( MASK_31 | MASK_30 | MASK_28 );
628 hps_ctrl |= (source << 30) | (sync << 28);
629
630 /* write back & upload register */
631 saa7146_write(dev, HPS_CTRL, hps_ctrl);
632 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
633
634 vv->current_hps_source = source;
635 vv->current_hps_sync = sync;
636}
637
638int saa7146_enable_overlay(struct saa7146_fh *fh)
639{
640 struct saa7146_dev *dev = fh->dev;
641 struct saa7146_vv *vv = dev->vv_data;
642
643 saa7146_set_window(dev, fh->ov.win.w.width, fh->ov.win.w.height, fh->ov.win.field);
644 saa7146_set_position(dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field, vv->ov_fmt->pixelformat);
645 saa7146_set_output_format(dev, vv->ov_fmt->trans);
646 saa7146_set_clipping_rect(fh);
647
648 /* enable video dma1 */
649 saa7146_write(dev, MC1, (MASK_06 | MASK_22));
650 return 0;
651}
652
653void saa7146_disable_overlay(struct saa7146_fh *fh)
654{
655 struct saa7146_dev *dev = fh->dev;
656
657 /* disable clipping + video dma1 */
658 saa7146_disable_clipping(dev);
659 saa7146_write(dev, MC1, MASK_22);
660}
661
662void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma)
663{
664 int where = 0;
665
666 if( which < 1 || which > 3) {
667 return;
668 }
669
670 /* calculate starting address */
671 where = (which-1)*0x18;
672
673 saa7146_write(dev, where, vdma->base_odd);
674 saa7146_write(dev, where+0x04, vdma->base_even);
675 saa7146_write(dev, where+0x08, vdma->prot_addr);
676 saa7146_write(dev, where+0x0c, vdma->pitch);
677 saa7146_write(dev, where+0x10, vdma->base_page);
678 saa7146_write(dev, where+0x14, vdma->num_line_byte);
679
680 /* upload */
681 saa7146_write(dev, MC2, (MASK_02<<(which-1))|(MASK_18<<(which-1)));
682/*
683 printk("vdma%d.base_even: 0x%08x\n", which,vdma->base_even);
684 printk("vdma%d.base_odd: 0x%08x\n", which,vdma->base_odd);
685 printk("vdma%d.prot_addr: 0x%08x\n", which,vdma->prot_addr);
686 printk("vdma%d.base_page: 0x%08x\n", which,vdma->base_page);
687 printk("vdma%d.pitch: 0x%08x\n", which,vdma->pitch);
688 printk("vdma%d.num_line_byte: 0x%08x\n", which,vdma->num_line_byte);
689*/
690}
691
692static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf)
693{
694 struct saa7146_vv *vv = dev->vv_data;
695 struct saa7146_video_dma vdma1;
696
697 struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
698
699 int width = buf->fmt->width;
700 int height = buf->fmt->height;
701 int bytesperline = buf->fmt->bytesperline;
702 enum v4l2_field field = buf->fmt->field;
703
704 int depth = sfmt->depth;
705
706 DEB_CAP(("[size=%dx%d,fields=%s]\n",
707 width,height,v4l2_field_names[field]));
708
709 if( bytesperline != 0) {
710 vdma1.pitch = bytesperline*2;
711 } else {
712 vdma1.pitch = (width*depth*2)/8;
713 }
714 vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
715 vdma1.base_page = buf->pt[0].dma | ME1 | sfmt->swap;
716
717 if( 0 != vv->vflip ) {
718 vdma1.prot_addr = buf->pt[0].offset;
719 vdma1.base_even = buf->pt[0].offset+(vdma1.pitch/2)*height;
720 vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
721 } else {
722 vdma1.base_even = buf->pt[0].offset;
723 vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2);
724 vdma1.prot_addr = buf->pt[0].offset+(vdma1.pitch/2)*height;
725 }
726
727 if (V4L2_FIELD_HAS_BOTH(field)) {
728 } else if (field == V4L2_FIELD_ALTERNATE) {
729 /* fixme */
730 if ( vv->last_field == V4L2_FIELD_TOP ) {
731 vdma1.base_odd = vdma1.prot_addr;
732 vdma1.pitch /= 2;
733 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
734 vdma1.base_odd = vdma1.base_even;
735 vdma1.base_even = vdma1.prot_addr;
736 vdma1.pitch /= 2;
737 }
738 } else if (field == V4L2_FIELD_TOP) {
739 vdma1.base_odd = vdma1.prot_addr;
740 vdma1.pitch /= 2;
741 } else if (field == V4L2_FIELD_BOTTOM) {
742 vdma1.base_odd = vdma1.base_even;
743 vdma1.base_even = vdma1.prot_addr;
744 vdma1.pitch /= 2;
745 }
746
747 if( 0 != vv->vflip ) {
748 vdma1.pitch *= -1;
749 }
750
751 saa7146_write_out_dma(dev, 1, &vdma1);
752 return 0;
753}
754
755static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
756{
757 int height = buf->fmt->height;
758 int width = buf->fmt->width;
759
760 vdma2->pitch = width;
761 vdma3->pitch = width;
762
763 /* fixme: look at bytesperline! */
764
765 if( 0 != vv->vflip ) {
766 vdma2->prot_addr = buf->pt[1].offset;
767 vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[1].offset;
768 vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2);
769
770 vdma3->prot_addr = buf->pt[2].offset;
771 vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[2].offset;
772 vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2);
773 } else {
774 vdma3->base_even = buf->pt[2].offset;
775 vdma3->base_odd = vdma3->base_even + (vdma3->pitch/2);
776 vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset;
777
778 vdma2->base_even = buf->pt[1].offset;
779 vdma2->base_odd = vdma2->base_even + (vdma2->pitch/2);
780 vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset;
781 }
782
783 return 0;
784}
785
786static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
787{
788 int height = buf->fmt->height;
789 int width = buf->fmt->width;
790
791 vdma2->pitch = width/2;
792 vdma3->pitch = width/2;
793
794 if( 0 != vv->vflip ) {
795 vdma2->prot_addr = buf->pt[2].offset;
796 vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[2].offset;
797 vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2);
798
799 vdma3->prot_addr = buf->pt[1].offset;
800 vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[1].offset;
801 vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2);
802
803 } else {
804 vdma3->base_even = buf->pt[2].offset;
805 vdma3->base_odd = vdma3->base_even + (vdma3->pitch);
806 vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset;
807
808 vdma2->base_even = buf->pt[1].offset;
809 vdma2->base_odd = vdma2->base_even + (vdma2->pitch);
810 vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset;
811 }
812 return 0;
813}
814
815static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf)
816{
817 struct saa7146_vv *vv = dev->vv_data;
818 struct saa7146_video_dma vdma1;
819 struct saa7146_video_dma vdma2;
820 struct saa7146_video_dma vdma3;
821
822 struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
823
824 int width = buf->fmt->width;
825 int height = buf->fmt->height;
826 enum v4l2_field field = buf->fmt->field;
827
828 BUG_ON(0 == buf->pt[0].dma);
829 BUG_ON(0 == buf->pt[1].dma);
830 BUG_ON(0 == buf->pt[2].dma);
831
832 DEB_CAP(("[size=%dx%d,fields=%s]\n",
833 width,height,v4l2_field_names[field]));
834
835 /* fixme: look at bytesperline! */
836
837 /* fixme: what happens for user space buffers here?. The offsets are
838 most likely wrong, this version here only works for page-aligned
839 buffers, modifications to the pagetable-functions are necessary...*/
840
841 vdma1.pitch = width*2;
842 vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
843 vdma1.base_page = buf->pt[0].dma | ME1;
844
845 if( 0 != vv->vflip ) {
846 vdma1.prot_addr = buf->pt[0].offset;
847 vdma1.base_even = ((vdma1.pitch/2)*height)+buf->pt[0].offset;
848 vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
849 } else {
850 vdma1.base_even = buf->pt[0].offset;
851 vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2);
852 vdma1.prot_addr = (vdma1.pitch/2)*height+buf->pt[0].offset;
853 }
854
855 vdma2.num_line_byte = 0; /* unused */
856 vdma2.base_page = buf->pt[1].dma | ME1;
857
858 vdma3.num_line_byte = 0; /* unused */
859 vdma3.base_page = buf->pt[2].dma | ME1;
860
861 switch( sfmt->depth ) {
862 case 12: {
863 calc_planar_420(vv,buf,&vdma2,&vdma3);
864 break;
865 }
866 case 16: {
867 calc_planar_422(vv,buf,&vdma2,&vdma3);
868 break;
869 }
870 default: {
871 return -1;
872 }
873 }
874
875 if (V4L2_FIELD_HAS_BOTH(field)) {
876 } else if (field == V4L2_FIELD_ALTERNATE) {
877 /* fixme */
878 vdma1.base_odd = vdma1.prot_addr;
879 vdma1.pitch /= 2;
880 vdma2.base_odd = vdma2.prot_addr;
881 vdma2.pitch /= 2;
882 vdma3.base_odd = vdma3.prot_addr;
883 vdma3.pitch /= 2;
884 } else if (field == V4L2_FIELD_TOP) {
885 vdma1.base_odd = vdma1.prot_addr;
886 vdma1.pitch /= 2;
887 vdma2.base_odd = vdma2.prot_addr;
888 vdma2.pitch /= 2;
889 vdma3.base_odd = vdma3.prot_addr;
890 vdma3.pitch /= 2;
891 } else if (field == V4L2_FIELD_BOTTOM) {
892 vdma1.base_odd = vdma1.base_even;
893 vdma1.base_even = vdma1.prot_addr;
894 vdma1.pitch /= 2;
895 vdma2.base_odd = vdma2.base_even;
896 vdma2.base_even = vdma2.prot_addr;
897 vdma2.pitch /= 2;
898 vdma3.base_odd = vdma3.base_even;
899 vdma3.base_even = vdma3.prot_addr;
900 vdma3.pitch /= 2;
901 }
902
903 if( 0 != vv->vflip ) {
904 vdma1.pitch *= -1;
905 vdma2.pitch *= -1;
906 vdma3.pitch *= -1;
907 }
908
909 saa7146_write_out_dma(dev, 1, &vdma1);
910 if( (sfmt->flags & FORMAT_BYTE_SWAP) != 0 ) {
911 saa7146_write_out_dma(dev, 3, &vdma2);
912 saa7146_write_out_dma(dev, 2, &vdma3);
913 } else {
914 saa7146_write_out_dma(dev, 2, &vdma2);
915 saa7146_write_out_dma(dev, 3, &vdma3);
916 }
917 return 0;
918}
919
920static void program_capture_engine(struct saa7146_dev *dev, int planar)
921{
922 struct saa7146_vv *vv = dev->vv_data;
923 int count = 0;
924
925 unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
926 unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
927
928 /* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/
929 WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait);
930 WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
931
932 /* set rps register 0 */
933 WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4));
934 WRITE_RPS0(MASK_27 | MASK_11);
935
936 /* turn on video-dma1 */
937 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
938 WRITE_RPS0(MASK_06 | MASK_22); /* => mask */
939 WRITE_RPS0(MASK_06 | MASK_22); /* => values */
940 if( 0 != planar ) {
941 /* turn on video-dma2 */
942 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
943 WRITE_RPS0(MASK_05 | MASK_21); /* => mask */
944 WRITE_RPS0(MASK_05 | MASK_21); /* => values */
945
946 /* turn on video-dma3 */
947 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
948 WRITE_RPS0(MASK_04 | MASK_20); /* => mask */
949 WRITE_RPS0(MASK_04 | MASK_20); /* => values */
950 }
951
952 /* wait for o_fid_a/b / e_fid_a/b toggle */
953 if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
954 WRITE_RPS0(CMD_PAUSE | o_wait);
955 WRITE_RPS0(CMD_PAUSE | e_wait);
956 } else if ( vv->last_field == V4L2_FIELD_TOP ) {
957 WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
958 WRITE_RPS0(CMD_PAUSE | o_wait);
959 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
960 WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
961 WRITE_RPS0(CMD_PAUSE | e_wait);
962 }
963
964 /* turn off video-dma1 */
965 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
966 WRITE_RPS0(MASK_22 | MASK_06); /* => mask */
967 WRITE_RPS0(MASK_22); /* => values */
968 if( 0 != planar ) {
969 /* turn off video-dma2 */
970 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
971 WRITE_RPS0(MASK_05 | MASK_21); /* => mask */
972 WRITE_RPS0(MASK_21); /* => values */
973
974 /* turn off video-dma3 */
975 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
976 WRITE_RPS0(MASK_04 | MASK_20); /* => mask */
977 WRITE_RPS0(MASK_20); /* => values */
978 }
979
980 /* generate interrupt */
981 WRITE_RPS0(CMD_INTERRUPT);
982
983 /* stop */
984 WRITE_RPS0(CMD_STOP);
985}
986
987void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
988{
989 struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
990 struct saa7146_vv *vv = dev->vv_data;
991 u32 vdma1_prot_addr;
992
993 DEB_CAP(("buf:%p, next:%p\n",buf,next));
994
995 vdma1_prot_addr = saa7146_read(dev, PROT_ADDR1);
996 if( 0 == vdma1_prot_addr ) {
997 /* clear out beginning of streaming bit (rps register 0)*/
998 DEB_CAP(("forcing sync to new frame\n"));
999 saa7146_write(dev, MC2, MASK_27 );
1000 }
1001
1002 saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
1003 saa7146_set_output_format(dev, sfmt->trans);
1004 saa7146_disable_clipping(dev);
1005
1006 if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
1007 } else if ( vv->last_field == V4L2_FIELD_TOP ) {
1008 vv->last_field = V4L2_FIELD_BOTTOM;
1009 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
1010 vv->last_field = V4L2_FIELD_TOP;
1011 }
1012
1013 if( 0 != IS_PLANAR(sfmt->trans)) {
1014 calculate_video_dma_grab_planar(dev, buf);
1015 program_capture_engine(dev,1);
1016 } else {
1017 calculate_video_dma_grab_packed(dev, buf);
1018 program_capture_engine(dev,0);
1019 }
1020
1021/*
1022 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
1023 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
1024 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
1025 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
1026 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
1027 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
1028 printk("vdma%d => vptr : 0x%08x\n", 1,saa7146_read(dev,PCI_VDP1));
1029*/
1030
1031 /* write the address of the rps-program */
1032 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
1033
1034 /* turn on rps */
1035 saa7146_write(dev, MC1, (MASK_12 | MASK_28));
1036}
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
new file mode 100644
index 000000000000..781f23f0cbcc
--- /dev/null
+++ b/drivers/media/common/saa7146_i2c.c
@@ -0,0 +1,421 @@
1#include <linux/version.h>
2#include <media/saa7146_vv.h>
3
4static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
5{
6//fm DEB_I2C(("'%s'.\n", adapter->name));
7
8 return I2C_FUNC_I2C
9 | I2C_FUNC_SMBUS_QUICK
10 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE
11 | I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
12}
13
14/* this function returns the status-register of our i2c-device */
15static inline u32 saa7146_i2c_status(struct saa7146_dev *dev)
16{
17 u32 iicsta = saa7146_read(dev, I2C_STATUS);
18/*
19 DEB_I2C(("status: 0x%08x\n",iicsta));
20*/
21 return iicsta;
22}
23
24/* this function runs through the i2c-messages and prepares the data to be
25 sent through the saa7146. have a look at the specifications p. 122 ff
26 to understand this. it returns the number of u32s to send, or -1
27 in case of an error. */
28static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
29{
30 int h1, h2;
31 int i, j, addr;
32 int mem = 0, op_count = 0;
33
34 /* first determine size of needed memory */
35 for(i = 0; i < num; i++) {
36 mem += m[i].len + 1;
37 }
38
39 /* worst case: we need one u32 for three bytes to be send
40 plus one extra byte to address the device */
41 mem = 1 + ((mem-1) / 3);
42
43 /* we assume that op points to a memory of at least SAA7146_I2C_MEM bytes
44 size. if we exceed this limit... */
45 if ( (4*mem) > SAA7146_I2C_MEM ) {
46//fm DEB_I2C(("cannot prepare i2c-message.\n"));
47 return -ENOMEM;
48 }
49
50 /* be careful: clear out the i2c-mem first */
51 memset(op,0,sizeof(u32)*mem);
52
53 /* loop through all messages */
54 for(i = 0; i < num; i++) {
55
56 /* insert the address of the i2c-slave.
57 note: we get 7 bit i2c-addresses,
58 so we have to perform a translation */
59 addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0);
60 h1 = op_count/3; h2 = op_count%3;
61 op[h1] |= ( (u8)addr << ((3-h2)*8));
62 op[h1] |= (SAA7146_I2C_START << ((3-h2)*2));
63 op_count++;
64
65 /* loop through all bytes of message i */
66 for(j = 0; j < m[i].len; j++) {
67 /* insert the data bytes */
68 h1 = op_count/3; h2 = op_count%3;
69 op[h1] |= ( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
70 op[h1] |= ( SAA7146_I2C_CONT << ((3-h2)*2));
71 op_count++;
72 }
73
74 }
75
76 /* have a look at the last byte inserted:
77 if it was: ...CONT change it to ...STOP */
78 h1 = (op_count-1)/3; h2 = (op_count-1)%3;
79 if ( SAA7146_I2C_CONT == (0x3 & (op[h1] >> ((3-h2)*2))) ) {
80 op[h1] &= ~(0x2 << ((3-h2)*2));
81 op[h1] |= (SAA7146_I2C_STOP << ((3-h2)*2));
82 }
83
84 /* return the number of u32s to send */
85 return mem;
86}
87
88/* this functions loops through all i2c-messages. normally, it should determine
89 which bytes were read through the adapter and write them back to the corresponding
90 i2c-message. but instead, we simply write back all bytes.
91 fixme: this could be improved. */
92static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op)
93{
94 int i, j;
95 int op_count = 0;
96
97 /* loop through all messages */
98 for(i = 0; i < num; i++) {
99
100 op_count++;
101
102 /* loop throgh all bytes of message i */
103 for(j = 0; j < m[i].len; j++) {
104 /* write back all bytes that could have been read */
105 m[i].buf[j] = (op[op_count/3] >> ((3-(op_count%3))*8));
106 op_count++;
107 }
108 }
109
110 return 0;
111}
112
113/* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */
114static int saa7146_i2c_reset(struct saa7146_dev *dev)
115{
116 /* get current status */
117 u32 status = saa7146_i2c_status(dev);
118
119 /* clear registers for sure */
120 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
121 saa7146_write(dev, I2C_TRANSFER, 0);
122
123 /* check if any operation is still in progress */
124 if ( 0 != ( status & SAA7146_I2C_BUSY) ) {
125
126 /* yes, kill ongoing operation */
127 DEB_I2C(("busy_state detected.\n"));
128
129 /* set "ABORT-OPERATION"-bit (bit 7)*/
130 saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
131 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
132 msleep(SAA7146_I2C_DELAY);
133
134 /* clear all error-bits pending; this is needed because p.123, note 1 */
135 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
136 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
137 msleep(SAA7146_I2C_DELAY);
138 }
139
140 /* check if any error is (still) present. (this can be necessary because p.123, note 1) */
141 status = saa7146_i2c_status(dev);
142
143 if ( dev->i2c_bitrate != status ) {
144
145 DEB_I2C(("error_state detected. status:0x%08x\n",status));
146
147 /* Repeat the abort operation. This seems to be necessary
148 after serious protocol errors caused by e.g. the SAA7740 */
149 saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
150 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
151 msleep(SAA7146_I2C_DELAY);
152
153 /* clear all error-bits pending */
154 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
155 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
156 msleep(SAA7146_I2C_DELAY);
157
158 /* the data sheet says it might be necessary to clear the status
159 twice after an abort */
160 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
161 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
162 msleep(SAA7146_I2C_DELAY);
163 }
164
165 /* if any error is still present, a fatal error has occured ... */
166 status = saa7146_i2c_status(dev);
167 if ( dev->i2c_bitrate != status ) {
168 DEB_I2C(("fatal error. status:0x%08x\n",status));
169 return -1;
170 }
171
172 return 0;
173}
174
175/* this functions writes out the data-byte 'dword' to the i2c-device.
176 it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
177 failed badly (e.g. address error) */
178static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
179{
180 u32 status = 0, mc2 = 0;
181 int trial = 0;
182 unsigned long timeout;
183
184 /* write out i2c-command */
185 DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op));
186
187 if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
188
189 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
190 saa7146_write(dev, I2C_TRANSFER, *dword);
191
192 dev->i2c_op = 1;
193 SAA7146_IER_ENABLE(dev, MASK_16|MASK_17);
194 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
195
196 wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0);
197 if (signal_pending (current)) {
198 /* a signal arrived */
199 return -ERESTARTSYS;
200 }
201 status = saa7146_read(dev, I2C_STATUS);
202 } else {
203 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
204 saa7146_write(dev, I2C_TRANSFER, *dword);
205 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
206
207 /* do not poll for i2c-status before upload is complete */
208 timeout = jiffies + HZ/100 + 1; /* 10ms */
209 while(1) {
210 mc2 = (saa7146_read(dev, MC2) & 0x1);
211 if( 0 != mc2 ) {
212 break;
213 }
214 if (time_after(jiffies,timeout)) {
215 printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
216 return -EIO;
217 }
218 }
219 /* wait until we get a transfer done or error */
220 timeout = jiffies + HZ/100 + 1; /* 10ms */
221 while(1) {
222 /**
223 * first read usually delivers bogus results...
224 */
225 saa7146_i2c_status(dev);
226 status = saa7146_i2c_status(dev);
227 if ((status & 0x3) != 1)
228 break;
229 if (time_after(jiffies,timeout)) {
230 /* this is normal when probing the bus
231 * (no answer from nonexisistant device...)
232 */
233 DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
234 return -EIO;
235 }
236 if ((++trial < 20) && short_delay)
237 udelay(10);
238 else
239 msleep(1);
240 }
241 }
242
243 /* give a detailed status report */
244 if ( 0 != (status & SAA7146_I2C_ERR)) {
245
246 if( 0 != (status & SAA7146_I2C_SPERR) ) {
247 DEB_I2C(("error due to invalid start/stop condition.\n"));
248 }
249 if( 0 != (status & SAA7146_I2C_DTERR) ) {
250 DEB_I2C(("error in data transmission.\n"));
251 }
252 if( 0 != (status & SAA7146_I2C_DRERR) ) {
253 DEB_I2C(("error when receiving data.\n"));
254 }
255 if( 0 != (status & SAA7146_I2C_AL) ) {
256 DEB_I2C(("error because arbitration lost.\n"));
257 }
258
259 /* we handle address-errors here */
260 if( 0 != (status & SAA7146_I2C_APERR) ) {
261 DEB_I2C(("error in address phase.\n"));
262 return -EREMOTEIO;
263 }
264
265 return -EIO;
266 }
267
268 /* read back data, just in case we were reading ... */
269 *dword = saa7146_read(dev, I2C_TRANSFER);
270
271 DEB_I2C(("after: 0x%08x\n",*dword));
272 return 0;
273}
274
275int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
276{
277 int i = 0, count = 0;
278 u32* buffer = dev->d_i2c.cpu_addr;
279 int err = 0;
280 int address_err = 0;
281 int short_delay = 0;
282
283 if (down_interruptible (&dev->i2c_lock))
284 return -ERESTARTSYS;
285
286 for(i=0;i<num;i++) {
287 DEB_I2C(("msg:%d/%d\n",i+1,num));
288 }
289
290 /* prepare the message(s), get number of u32s to transfer */
291 count = saa7146_i2c_msg_prepare(msgs, num, buffer);
292 if ( 0 > count ) {
293 err = -1;
294 goto out;
295 }
296
297 if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) )
298 short_delay = 1;
299
300 do {
301 /* reset the i2c-device if necessary */
302 err = saa7146_i2c_reset(dev);
303 if ( 0 > err ) {
304 DEB_I2C(("could not reset i2c-device.\n"));
305 goto out;
306 }
307
308 /* write out the u32s one after another */
309 for(i = 0; i < count; i++) {
310 err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
311 if ( 0 != err) {
312 /* this one is unsatisfying: some i2c slaves on some
313 dvb cards don't acknowledge correctly, so the saa7146
314 thinks that an address error occured. in that case, the
315 transaction should be retrying, even if an address error
316 occured. analog saa7146 based cards extensively rely on
317 i2c address probing, however, and address errors indicate that a
318 device is really *not* there. retrying in that case
319 increases the time the device needs to probe greatly, so
320 it should be avoided. because of the fact, that only
321 analog based cards use irq based i2c transactions (for dvb
322 cards, this screwes up other interrupt sources), we bail out
323 completely for analog cards after an address error and trust
324 the saa7146 address error detection. */
325 if ( -EREMOTEIO == err ) {
326 if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
327 goto out;
328 }
329 address_err++;
330 }
331 DEB_I2C(("error while sending message(s). starting again.\n"));
332 break;
333 }
334 }
335 if( 0 == err ) {
336 err = num;
337 break;
338 }
339
340 /* delay a bit before retrying */
341 msleep(10);
342
343 } while (err != num && retries--);
344
345 /* if every retry had an address error, exit right away */
346 if (address_err == retries) {
347 goto out;
348 }
349
350 /* if any things had to be read, get the results */
351 if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
352 DEB_I2C(("could not cleanup i2c-message.\n"));
353 err = -1;
354 goto out;
355 }
356
357 /* return the number of delivered messages */
358 DEB_I2C(("transmission successful. (msg:%d).\n",err));
359out:
360 /* another bug in revision 0: the i2c-registers get uploaded randomly by other
361 uploads, so we better clear them out before continueing */
362 if( 0 == dev->revision ) {
363 u32 zero = 0;
364 saa7146_i2c_reset(dev);
365 if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
366 INFO(("revision 0 error. this should never happen.\n"));
367 }
368 }
369
370 up(&dev->i2c_lock);
371 return err;
372}
373
374/* utility functions */
375static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
376{
377 struct saa7146_dev* dev = i2c_get_adapdata(adapter);
378
379 /* use helper function to transfer data */
380 return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
381}
382
383
384/*****************************************************************************/
385/* i2c-adapter helper functions */
386#include <linux/i2c-id.h>
387
388/* exported algorithm data */
389static struct i2c_algorithm saa7146_algo = {
390 .name = "saa7146 i2c algorithm",
391 .id = I2C_ALGO_SAA7146,
392 .master_xfer = saa7146_i2c_xfer,
393 .functionality = saa7146_i2c_func,
394};
395
396int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate)
397{
398 DEB_EE(("bitrate: 0x%08x\n",bitrate));
399
400 /* enable i2c-port pins */
401 saa7146_write(dev, MC1, (MASK_08 | MASK_24));
402
403 dev->i2c_bitrate = bitrate;
404 saa7146_i2c_reset(dev);
405
406 if( NULL != i2c_adapter ) {
407#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
408 i2c_adapter->data = dev;
409#else
410 BUG_ON(!i2c_adapter->class);
411 i2c_set_adapdata(i2c_adapter,dev);
412#endif
413 i2c_adapter->algo = &saa7146_algo;
414 i2c_adapter->algo_data = NULL;
415 i2c_adapter->id = I2C_ALGO_SAA7146;
416 i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
417 i2c_adapter->retries = SAA7146_I2C_RETRIES;
418 }
419
420 return 0;
421}
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
new file mode 100644
index 000000000000..cb86a97fda1f
--- /dev/null
+++ b/drivers/media/common/saa7146_vbi.c
@@ -0,0 +1,508 @@
1#include <media/saa7146_vv.h>
2
3static int vbi_pixel_to_capture = 720 * 2;
4
5static int vbi_workaround(struct saa7146_dev *dev)
6{
7 struct saa7146_vv *vv = dev->vv_data;
8
9 u32 *cpu;
10 dma_addr_t dma_addr;
11
12 int count = 0;
13 int i;
14
15 DECLARE_WAITQUEUE(wait, current);
16
17 DEB_VBI(("dev:%p\n",dev));
18
19 /* once again, a bug in the saa7146: the brs acquisition
20 is buggy and especially the BXO-counter does not work
21 as specified. there is this workaround, but please
22 don't let me explain it. ;-) */
23
24 cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
25 if (NULL == cpu)
26 return -ENOMEM;
27
28 /* setup some basic programming, just for the workaround */
29 saa7146_write(dev, BASE_EVEN3, dma_addr);
30 saa7146_write(dev, BASE_ODD3, dma_addr+vbi_pixel_to_capture);
31 saa7146_write(dev, PROT_ADDR3, dma_addr+4096);
32 saa7146_write(dev, PITCH3, vbi_pixel_to_capture);
33 saa7146_write(dev, BASE_PAGE3, 0x0);
34 saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
35 saa7146_write(dev, MC2, MASK_04|MASK_20);
36
37 /* load brs-control register */
38 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
39 /* BXO = 1h, BRS to outbound */
40 WRITE_RPS1(0xc000008c);
41 /* wait for vbi_a or vbi_b*/
42 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
43 DEB_D(("...using port b\n"));
44 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
45 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
46/*
47 WRITE_RPS1(CMD_PAUSE | MASK_09);
48*/
49 } else {
50 DEB_D(("...using port a\n"));
51 WRITE_RPS1(CMD_PAUSE | MASK_10);
52 }
53 /* upload brs */
54 WRITE_RPS1(CMD_UPLOAD | MASK_08);
55 /* load brs-control register */
56 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
57 /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
58 WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
59 /* wait for brs_done */
60 WRITE_RPS1(CMD_PAUSE | MASK_08);
61 /* upload brs */
62 WRITE_RPS1(CMD_UPLOAD | MASK_08);
63 /* load video-dma3 NumLines3 and NumBytes3 */
64 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
65 /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
66 WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
67 /* load brs-control register */
68 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
69 /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
70 WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start
71 /* wait for brs_done */
72 WRITE_RPS1(CMD_PAUSE | MASK_08);
73 /* upload brs and video-dma3*/
74 WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
75 /* load mc2 register: enable dma3 */
76 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
77 WRITE_RPS1(MASK_20 | MASK_04);
78 /* generate interrupt */
79 WRITE_RPS1(CMD_INTERRUPT);
80 /* stop rps1 */
81 WRITE_RPS1(CMD_STOP);
82
83 /* we have to do the workaround twice to be sure that
84 everything is ok */
85 for(i = 0; i < 2; i++) {
86
87 /* indicate to the irq handler that we do the workaround */
88 saa7146_write(dev, MC2, MASK_31|MASK_15);
89
90 saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
91 saa7146_write(dev, MC2, MASK_04|MASK_20);
92
93 /* enable rps1 irqs */
94 SAA7146_IER_ENABLE(dev,MASK_28);
95
96 /* prepare to wait to be woken up by the irq-handler */
97 add_wait_queue(&vv->vbi_wq, &wait);
98 current->state = TASK_INTERRUPTIBLE;
99
100 /* start rps1 to enable workaround */
101 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
102 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
103
104 schedule();
105
106 DEB_VBI(("brs bug workaround %d/1.\n",i));
107
108 remove_wait_queue(&vv->vbi_wq, &wait);
109 current->state = TASK_RUNNING;
110
111 /* disable rps1 irqs */
112 SAA7146_IER_DISABLE(dev,MASK_28);
113
114 /* stop video-dma3 */
115 saa7146_write(dev, MC1, MASK_20);
116
117 if(signal_pending(current)) {
118
119 DEB_VBI(("aborted (rps:0x%08x).\n",saa7146_read(dev,RPS_ADDR1)));
120
121 /* stop rps1 for sure */
122 saa7146_write(dev, MC1, MASK_29);
123
124 pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
125 return -EINTR;
126 }
127 }
128
129 pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
130 return 0;
131}
132
133static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
134{
135 struct saa7146_vv *vv = dev->vv_data;
136
137 struct saa7146_video_dma vdma3;
138
139 int count = 0;
140 unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
141 unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
142
143/*
144 vdma3.base_even = 0xc8000000+2560*70;
145 vdma3.base_odd = 0xc8000000;
146 vdma3.prot_addr = 0xc8000000+2560*164;
147 vdma3.pitch = 2560;
148 vdma3.base_page = 0;
149 vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
150*/
151 vdma3.base_even = buf->pt[2].offset;
152 vdma3.base_odd = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
153 vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
154 vdma3.pitch = vbi_pixel_to_capture;
155 vdma3.base_page = buf->pt[2].dma | ME1;
156 vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
157
158 saa7146_write_out_dma(dev, 3, &vdma3);
159
160 /* write beginning of rps-program */
161 count = 0;
162
163 /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
164
165 /* we don't wait here for the first field anymore. this is different from the video
166 capture and might cause that the first buffer is only half filled (with only
167 one field). but since this is some sort of streaming data, this is not that negative.
168 but by doing this, we can use the whole engine from video-buf.c... */
169
170/*
171 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
172 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
173*/
174 /* set bit 1 */
175 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
176 WRITE_RPS1(MASK_28 | MASK_12);
177
178 /* turn on video-dma3 */
179 WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
180 WRITE_RPS1(MASK_04 | MASK_20); /* => mask */
181 WRITE_RPS1(MASK_04 | MASK_20); /* => values */
182
183 /* wait for o_fid_a/b / e_fid_a/b toggle */
184 WRITE_RPS1(CMD_PAUSE | o_wait);
185 WRITE_RPS1(CMD_PAUSE | e_wait);
186
187 /* generate interrupt */
188 WRITE_RPS1(CMD_INTERRUPT);
189
190 /* stop */
191 WRITE_RPS1(CMD_STOP);
192
193 /* enable rps1 irqs */
194 SAA7146_IER_ENABLE(dev, MASK_28);
195
196 /* write the address of the rps-program */
197 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
198
199 /* turn on rps */
200 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
201}
202
203static int buffer_activate(struct saa7146_dev *dev,
204 struct saa7146_buf *buf,
205 struct saa7146_buf *next)
206{
207 struct saa7146_vv *vv = dev->vv_data;
208 buf->vb.state = STATE_ACTIVE;
209
210 DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
211 saa7146_set_vbi_capture(dev,buf,next);
212
213 mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
214 return 0;
215}
216
217static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
218{
219 struct file *file = q->priv_data;
220 struct saa7146_fh *fh = file->private_data;
221 struct saa7146_dev *dev = fh->dev;
222 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
223
224 int err = 0;
225 int lines, llength, size;
226
227 lines = 16 * 2 ; /* 2 fields */
228 llength = vbi_pixel_to_capture;
229 size = lines * llength;
230
231 DEB_VBI(("vb:%p\n",vb));
232
233 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
234 DEB_VBI(("size mismatch.\n"));
235 return -EINVAL;
236 }
237
238 if (buf->vb.size != size)
239 saa7146_dma_free(dev,buf);
240
241 if (STATE_NEEDS_INIT == buf->vb.state) {
242 buf->vb.width = llength;
243 buf->vb.height = lines;
244 buf->vb.size = size;
245 buf->vb.field = field; // FIXME: check this
246
247 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
248 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
249
250 err = videobuf_iolock(dev->pci,&buf->vb, NULL);
251 if (err)
252 goto oops;
253 err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
254 if (0 != err)
255 return err;
256 }
257 buf->vb.state = STATE_PREPARED;
258 buf->activate = buffer_activate;
259
260 return 0;
261
262 oops:
263 DEB_VBI(("error out.\n"));
264 saa7146_dma_free(dev,buf);
265
266 return err;
267}
268
269static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
270{
271 int llength,lines;
272
273 lines = 16 * 2 ; /* 2 fields */
274 llength = vbi_pixel_to_capture;
275
276 *size = lines * llength;
277 *count = 2;
278
279 DEB_VBI(("count:%d, size:%d\n",*count,*size));
280
281 return 0;
282}
283
284static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
285{
286 struct file *file = q->priv_data;
287 struct saa7146_fh *fh = file->private_data;
288 struct saa7146_dev *dev = fh->dev;
289 struct saa7146_vv *vv = dev->vv_data;
290 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
291
292 DEB_VBI(("vb:%p\n",vb));
293 saa7146_buffer_queue(dev,&vv->vbi_q,buf);
294}
295
296static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
297{
298 struct file *file = q->priv_data;
299 struct saa7146_fh *fh = file->private_data;
300 struct saa7146_dev *dev = fh->dev;
301 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
302
303 DEB_VBI(("vb:%p\n",vb));
304 saa7146_dma_free(dev,buf);
305}
306
307static struct videobuf_queue_ops vbi_qops = {
308 .buf_setup = buffer_setup,
309 .buf_prepare = buffer_prepare,
310 .buf_queue = buffer_queue,
311 .buf_release = buffer_release,
312};
313
314/* ------------------------------------------------------------------ */
315
316static void vbi_stop(struct saa7146_fh *fh, struct file *file)
317{
318 struct saa7146_dev *dev = fh->dev;
319 struct saa7146_vv *vv = dev->vv_data;
320 unsigned long flags;
321 DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
322
323 spin_lock_irqsave(&dev->slock,flags);
324
325 /* disable rps1 */
326 saa7146_write(dev, MC1, MASK_29);
327
328 /* disable rps1 irqs */
329 SAA7146_IER_DISABLE(dev, MASK_28);
330
331 /* shut down dma 3 transfers */
332 saa7146_write(dev, MC1, MASK_20);
333
334 if (vv->vbi_q.curr) {
335 saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
336 }
337
338 videobuf_queue_cancel(&fh->vbi_q);
339
340 vv->vbi_streaming = NULL;
341
342 del_timer(&vv->vbi_q.timeout);
343 del_timer(&fh->vbi_read_timeout);
344
345 spin_unlock_irqrestore(&dev->slock, flags);
346}
347
348static void vbi_read_timeout(unsigned long data)
349{
350 struct file *file = (struct file*)data;
351 struct saa7146_fh *fh = file->private_data;
352 struct saa7146_dev *dev = fh->dev;
353
354 DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
355
356 vbi_stop(fh, file);
357}
358
359static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
360{
361 DEB_VBI(("dev:%p\n",dev));
362
363 INIT_LIST_HEAD(&vv->vbi_q.queue);
364
365 init_timer(&vv->vbi_q.timeout);
366 vv->vbi_q.timeout.function = saa7146_buffer_timeout;
367 vv->vbi_q.timeout.data = (unsigned long)(&vv->vbi_q);
368 vv->vbi_q.dev = dev;
369
370 init_waitqueue_head(&vv->vbi_wq);
371}
372
373static int vbi_open(struct saa7146_dev *dev, struct file *file)
374{
375 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
376
377 u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
378 int ret = 0;
379
380 DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
381
382 ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
383 if (0 == ret) {
384 DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
385 return -EBUSY;
386 }
387
388 /* adjust arbitrition control for video dma 3 */
389 arbtr_ctrl &= ~0x1f0000;
390 arbtr_ctrl |= 0x1d0000;
391 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
392 saa7146_write(dev, MC2, (MASK_04|MASK_20));
393
394 memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
395
396 fh->vbi_fmt.sampling_rate = 27000000;
397 fh->vbi_fmt.offset = 248; /* todo */
398 fh->vbi_fmt.samples_per_line = vbi_pixel_to_capture;
399 fh->vbi_fmt.sample_format = V4L2_PIX_FMT_GREY;
400
401 /* fixme: this only works for PAL */
402 fh->vbi_fmt.start[0] = 5;
403 fh->vbi_fmt.count[0] = 16;
404 fh->vbi_fmt.start[1] = 312;
405 fh->vbi_fmt.count[1] = 16;
406
407 videobuf_queue_init(&fh->vbi_q, &vbi_qops,
408 dev->pci, &dev->slock,
409 V4L2_BUF_TYPE_VBI_CAPTURE,
410 V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
411 sizeof(struct saa7146_buf),
412 file);
413 init_MUTEX(&fh->vbi_q.lock);
414
415 init_timer(&fh->vbi_read_timeout);
416 fh->vbi_read_timeout.function = vbi_read_timeout;
417 fh->vbi_read_timeout.data = (unsigned long)file;
418
419 /* initialize the brs */
420 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
421 saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
422 } else {
423 saa7146_write(dev, BRS_CTRL, 0x00000001);
424
425 if (0 != (ret = vbi_workaround(dev))) {
426 DEB_VBI(("vbi workaround failed!\n"));
427 /* return ret;*/
428 }
429 }
430
431 /* upload brs register */
432 saa7146_write(dev, MC2, (MASK_08|MASK_24));
433 return 0;
434}
435
436static void vbi_close(struct saa7146_dev *dev, struct file *file)
437{
438 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
439 struct saa7146_vv *vv = dev->vv_data;
440 DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
441
442 if( fh == vv->vbi_streaming ) {
443 vbi_stop(fh, file);
444 }
445 saa7146_res_free(fh, RESOURCE_DMA3_BRS);
446}
447
448static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
449{
450 struct saa7146_vv *vv = dev->vv_data;
451 spin_lock(&dev->slock);
452
453 if (vv->vbi_q.curr) {
454 DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
455 /* this must be += 2, one count for each field */
456 vv->vbi_fieldcount+=2;
457 vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
458 saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
459 } else {
460 DEB_VBI(("dev:%p\n",dev));
461 }
462 saa7146_buffer_next(dev,&vv->vbi_q,1);
463
464 spin_unlock(&dev->slock);
465}
466
467static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
468{
469 struct saa7146_fh *fh = file->private_data;
470 struct saa7146_dev *dev = fh->dev;
471 struct saa7146_vv *vv = dev->vv_data;
472 ssize_t ret = 0;
473
474 DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
475
476 if( NULL == vv->vbi_streaming ) {
477 // fixme: check if dma3 is available
478 // fixme: activate vbi engine here if necessary. (really?)
479 vv->vbi_streaming = fh;
480 }
481
482 if( fh != vv->vbi_streaming ) {
483 DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
484 return -EBUSY;
485 }
486
487 mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
488 ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
489 file->f_flags & O_NONBLOCK);
490/*
491 printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3));
492 printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3));
493 printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3));
494 printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3));
495 printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3));
496 printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
497 printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL));
498*/
499 return ret;
500}
501
502struct saa7146_use_ops saa7146_vbi_uops = {
503 .init = vbi_init,
504 .open = vbi_open,
505 .release = vbi_close,
506 .irq_done = vbi_irq_done,
507 .read = vbi_read,
508};
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
new file mode 100644
index 000000000000..8dd4d15ca36d
--- /dev/null
+++ b/drivers/media/common/saa7146_video.c
@@ -0,0 +1,1509 @@
1#include <media/saa7146_vv.h>
2
3static int max_memory = 32;
4
5module_param(max_memory, int, 0644);
6MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)");
7
8#define IS_CAPTURE_ACTIVE(fh) \
9 (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh))
10
11#define IS_OVERLAY_ACTIVE(fh) \
12 (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh))
13
14/* format descriptions for capture and preview */
15static struct saa7146_format formats[] = {
16 {
17 .name = "RGB-8 (3-3-2)",
18 .pixelformat = V4L2_PIX_FMT_RGB332,
19 .trans = RGB08_COMPOSED,
20 .depth = 8,
21 .flags = 0,
22 }, {
23 .name = "RGB-16 (5/B-6/G-5/R)",
24 .pixelformat = V4L2_PIX_FMT_RGB565,
25 .trans = RGB16_COMPOSED,
26 .depth = 16,
27 .flags = 0,
28 }, {
29 .name = "RGB-24 (B-G-R)",
30 .pixelformat = V4L2_PIX_FMT_BGR24,
31 .trans = RGB24_COMPOSED,
32 .depth = 24,
33 .flags = 0,
34 }, {
35 .name = "RGB-32 (B-G-R)",
36 .pixelformat = V4L2_PIX_FMT_BGR32,
37 .trans = RGB32_COMPOSED,
38 .depth = 32,
39 .flags = 0,
40 }, {
41 .name = "RGB-32 (R-G-B)",
42 .pixelformat = V4L2_PIX_FMT_RGB32,
43 .trans = RGB32_COMPOSED,
44 .depth = 32,
45 .flags = 0,
46 .swap = 0x2,
47 }, {
48 .name = "Greyscale-8",
49 .pixelformat = V4L2_PIX_FMT_GREY,
50 .trans = Y8,
51 .depth = 8,
52 .flags = 0,
53 }, {
54 .name = "YUV 4:2:2 planar (Y-Cb-Cr)",
55 .pixelformat = V4L2_PIX_FMT_YUV422P,
56 .trans = YUV422_DECOMPOSED,
57 .depth = 16,
58 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
59 }, {
60 .name = "YVU 4:2:0 planar (Y-Cb-Cr)",
61 .pixelformat = V4L2_PIX_FMT_YVU420,
62 .trans = YUV420_DECOMPOSED,
63 .depth = 12,
64 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
65 }, {
66 .name = "YUV 4:2:0 planar (Y-Cb-Cr)",
67 .pixelformat = V4L2_PIX_FMT_YUV420,
68 .trans = YUV420_DECOMPOSED,
69 .depth = 12,
70 .flags = FORMAT_IS_PLANAR,
71 }, {
72 .name = "YUV 4:2:2 (U-Y-V-Y)",
73 .pixelformat = V4L2_PIX_FMT_UYVY,
74 .trans = YUV422_COMPOSED,
75 .depth = 16,
76 .flags = 0,
77 }
78};
79
80/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
81 due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
82 (like V4L2_PIX_FMT_YUYV) ... 8-( */
83
84static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
85
86struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
87{
88 int i, j = NUM_FORMATS;
89
90 for (i = 0; i < j; i++) {
91 if (formats[i].pixelformat == fourcc) {
92 return formats+i;
93 }
94 }
95
96 DEB_D(("unknown pixelformat:'%4.4s'\n",(char *)&fourcc));
97 return NULL;
98}
99
100static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
101{
102 struct saa7146_dev *dev = fh->dev;
103 DEB_EE(("dev:%p, fh:%p\n",dev,fh));
104
105 switch (f->type) {
106 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
107 f->fmt.pix = fh->video_fmt;
108 return 0;
109 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
110 f->fmt.win = fh->ov.win;
111 return 0;
112 case V4L2_BUF_TYPE_VBI_CAPTURE:
113 {
114 f->fmt.vbi = fh->vbi_fmt;
115 return 0;
116 }
117 default:
118 DEB_D(("invalid format type '%d'.\n",f->type));
119 return -EINVAL;
120 }
121}
122
123static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
124{
125 struct saa7146_vv *vv = dev->vv_data;
126 enum v4l2_field field;
127 int maxw, maxh;
128
129 DEB_EE(("dev:%p\n",dev));
130
131 if (NULL == vv->ov_fb.base) {
132 DEB_D(("no fb base set.\n"));
133 return -EINVAL;
134 }
135 if (NULL == vv->ov_fmt) {
136 DEB_D(("no fb fmt set.\n"));
137 return -EINVAL;
138 }
139 if (win->w.width < 48 || win->w.height < 32) {
140 DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
141 return -EINVAL;
142 }
143 if (win->clipcount > 16) {
144 DEB_D(("clipcount too big.\n"));
145 return -EINVAL;
146 }
147
148 field = win->field;
149 maxw = vv->standard->h_max_out;
150 maxh = vv->standard->v_max_out;
151
152 if (V4L2_FIELD_ANY == field) {
153 field = (win->w.height > maxh/2)
154 ? V4L2_FIELD_INTERLACED
155 : V4L2_FIELD_TOP;
156 }
157 switch (field) {
158 case V4L2_FIELD_TOP:
159 case V4L2_FIELD_BOTTOM:
160 case V4L2_FIELD_ALTERNATE:
161 maxh = maxh / 2;
162 break;
163 case V4L2_FIELD_INTERLACED:
164 break;
165 default: {
166 DEB_D(("no known field mode '%d'.\n",field));
167 return -EINVAL;
168 }
169 }
170
171 win->field = field;
172 if (win->w.width > maxw)
173 win->w.width = maxw;
174 if (win->w.height > maxh)
175 win->w.height = maxh;
176
177 return 0;
178}
179
180static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
181{
182 struct saa7146_dev *dev = fh->dev;
183 struct saa7146_vv *vv = dev->vv_data;
184 int err;
185
186 switch (f->type) {
187 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
188 {
189 struct saa7146_format *fmt;
190 enum v4l2_field field;
191 int maxw, maxh;
192 int calc_bpl;
193
194 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
195
196 fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
197 if (NULL == fmt) {
198 return -EINVAL;
199 }
200
201 field = f->fmt.pix.field;
202 maxw = vv->standard->h_max_out;
203 maxh = vv->standard->v_max_out;
204
205 if (V4L2_FIELD_ANY == field) {
206 field = (f->fmt.pix.height > maxh/2)
207 ? V4L2_FIELD_INTERLACED
208 : V4L2_FIELD_BOTTOM;
209 }
210 switch (field) {
211 case V4L2_FIELD_ALTERNATE: {
212 vv->last_field = V4L2_FIELD_TOP;
213 maxh = maxh / 2;
214 break;
215 }
216 case V4L2_FIELD_TOP:
217 case V4L2_FIELD_BOTTOM:
218 vv->last_field = V4L2_FIELD_INTERLACED;
219 maxh = maxh / 2;
220 break;
221 case V4L2_FIELD_INTERLACED:
222 vv->last_field = V4L2_FIELD_INTERLACED;
223 break;
224 default: {
225 DEB_D(("no known field mode '%d'.\n",field));
226 return -EINVAL;
227 }
228 }
229
230 f->fmt.pix.field = field;
231 if (f->fmt.pix.width > maxw)
232 f->fmt.pix.width = maxw;
233 if (f->fmt.pix.height > maxh)
234 f->fmt.pix.height = maxh;
235
236 calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
237
238 if (f->fmt.pix.bytesperline < calc_bpl)
239 f->fmt.pix.bytesperline = calc_bpl;
240
241 if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
242 f->fmt.pix.bytesperline = calc_bpl;
243
244 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
245 DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
246
247 return 0;
248 }
249 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
250 DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
251 err = try_win(dev,&f->fmt.win);
252 if (0 != err) {
253 return err;
254 }
255 return 0;
256 default:
257 DEB_EE(("unknown format type '%d'\n",f->type));
258 return -EINVAL;
259 }
260}
261
262int saa7146_start_preview(struct saa7146_fh *fh)
263{
264 struct saa7146_dev *dev = fh->dev;
265 struct saa7146_vv *vv = dev->vv_data;
266 int ret = 0, err = 0;
267
268 DEB_EE(("dev:%p, fh:%p\n",dev,fh));
269
270 /* check if we have overlay informations */
271 if( NULL == fh->ov.fh ) {
272 DEB_D(("no overlay data available. try S_FMT first.\n"));
273 return -EAGAIN;
274 }
275
276 /* check if streaming capture is running */
277 if (IS_CAPTURE_ACTIVE(fh) != 0) {
278 DEB_D(("streaming capture is active.\n"));
279 return -EBUSY;
280 }
281
282 /* check if overlay is running */
283 if (IS_OVERLAY_ACTIVE(fh) != 0) {
284 if (vv->video_fh == fh) {
285 DEB_D(("overlay is already active.\n"));
286 return 0;
287 }
288 DEB_D(("overlay is already active in another open.\n"));
289 return -EBUSY;
290 }
291
292 if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
293 DEB_D(("cannot get necessary overlay resources\n"));
294 return -EBUSY;
295 }
296
297 err = try_win(dev,&fh->ov.win);
298 if (0 != err) {
299 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
300 return -EBUSY;
301 }
302
303 vv->ov_data = &fh->ov;
304
305 DEB_D(("%dx%d+%d+%d %s field=%s\n",
306 fh->ov.win.w.width,fh->ov.win.w.height,
307 fh->ov.win.w.left,fh->ov.win.w.top,
308 vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
309
310 if (0 != (ret = saa7146_enable_overlay(fh))) {
311 DEB_D(("enabling overlay failed: %d\n",ret));
312 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
313 return ret;
314 }
315
316 vv->video_status = STATUS_OVERLAY;
317 vv->video_fh = fh;
318
319 return 0;
320}
321
322int saa7146_stop_preview(struct saa7146_fh *fh)
323{
324 struct saa7146_dev *dev = fh->dev;
325 struct saa7146_vv *vv = dev->vv_data;
326
327 DEB_EE(("dev:%p, fh:%p\n",dev,fh));
328
329 /* check if streaming capture is running */
330 if (IS_CAPTURE_ACTIVE(fh) != 0) {
331 DEB_D(("streaming capture is active.\n"));
332 return -EBUSY;
333 }
334
335 /* check if overlay is running at all */
336 if ((vv->video_status & STATUS_OVERLAY) == 0) {
337 DEB_D(("no active overlay.\n"));
338 return 0;
339 }
340
341 if (vv->video_fh != fh) {
342 DEB_D(("overlay is active, but in another open.\n"));
343 return -EBUSY;
344 }
345
346 vv->video_status = 0;
347 vv->video_fh = NULL;
348
349 saa7146_disable_overlay(fh);
350
351 saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
352
353 return 0;
354}
355
356static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
357{
358 struct saa7146_dev *dev = fh->dev;
359 struct saa7146_vv *vv = dev->vv_data;
360
361 int err;
362
363 switch (f->type) {
364 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
365 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
366 if (IS_CAPTURE_ACTIVE(fh) != 0) {
367 DEB_EE(("streaming capture is active\n"));
368 return -EBUSY;
369 }
370 err = try_fmt(fh,f);
371 if (0 != err)
372 return err;
373 fh->video_fmt = f->fmt.pix;
374 DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
375 return 0;
376 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
377 DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
378 err = try_win(dev,&f->fmt.win);
379 if (0 != err)
380 return err;
381 down(&dev->lock);
382 fh->ov.win = f->fmt.win;
383 fh->ov.nclips = f->fmt.win.clipcount;
384 if (fh->ov.nclips > 16)
385 fh->ov.nclips = 16;
386 if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
387 up(&dev->lock);
388 return -EFAULT;
389 }
390
391 /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
392 fh->ov.fh = fh;
393
394 up(&dev->lock);
395
396 /* check if our current overlay is active */
397 if (IS_OVERLAY_ACTIVE(fh) != 0) {
398 saa7146_stop_preview(fh);
399 saa7146_start_preview(fh);
400 }
401 return 0;
402 default:
403 DEB_D(("unknown format type '%d'\n",f->type));
404 return -EINVAL;
405 }
406}
407
408/********************************************************************************/
409/* device controls */
410
411static struct v4l2_queryctrl controls[] = {
412 {
413 .id = V4L2_CID_BRIGHTNESS,
414 .name = "Brightness",
415 .minimum = 0,
416 .maximum = 255,
417 .step = 1,
418 .default_value = 128,
419 .type = V4L2_CTRL_TYPE_INTEGER,
420 },{
421 .id = V4L2_CID_CONTRAST,
422 .name = "Contrast",
423 .minimum = 0,
424 .maximum = 127,
425 .step = 1,
426 .default_value = 64,
427 .type = V4L2_CTRL_TYPE_INTEGER,
428 },{
429 .id = V4L2_CID_SATURATION,
430 .name = "Saturation",
431 .minimum = 0,
432 .maximum = 127,
433 .step = 1,
434 .default_value = 64,
435 .type = V4L2_CTRL_TYPE_INTEGER,
436 },{
437 .id = V4L2_CID_VFLIP,
438 .name = "Vertical flip",
439 .minimum = 0,
440 .maximum = 1,
441 .type = V4L2_CTRL_TYPE_BOOLEAN,
442 },{
443 .id = V4L2_CID_HFLIP,
444 .name = "Horizontal flip",
445 .minimum = 0,
446 .maximum = 1,
447 .type = V4L2_CTRL_TYPE_BOOLEAN,
448 },
449};
450static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
451
452#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0)
453
454static struct v4l2_queryctrl* ctrl_by_id(int id)
455{
456 int i;
457
458 for (i = 0; i < NUM_CONTROLS; i++)
459 if (controls[i].id == id)
460 return controls+i;
461 return NULL;
462}
463
464static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
465{
466 struct saa7146_dev *dev = fh->dev;
467 struct saa7146_vv *vv = dev->vv_data;
468
469 const struct v4l2_queryctrl* ctrl;
470 u32 value = 0;
471
472 ctrl = ctrl_by_id(c->id);
473 if (NULL == ctrl)
474 return -EINVAL;
475 switch (c->id) {
476 case V4L2_CID_BRIGHTNESS:
477 value = saa7146_read(dev, BCS_CTRL);
478 c->value = 0xff & (value >> 24);
479 DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
480 break;
481 case V4L2_CID_CONTRAST:
482 value = saa7146_read(dev, BCS_CTRL);
483 c->value = 0x7f & (value >> 16);
484 DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
485 break;
486 case V4L2_CID_SATURATION:
487 value = saa7146_read(dev, BCS_CTRL);
488 c->value = 0x7f & (value >> 0);
489 DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
490 break;
491 case V4L2_CID_VFLIP:
492 c->value = vv->vflip;
493 DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
494 break;
495 case V4L2_CID_HFLIP:
496 c->value = vv->hflip;
497 DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
498 break;
499 default:
500 return -EINVAL;
501 }
502
503 return 0;
504}
505
506static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
507{
508 struct saa7146_dev *dev = fh->dev;
509 struct saa7146_vv *vv = dev->vv_data;
510
511 const struct v4l2_queryctrl* ctrl;
512
513 ctrl = ctrl_by_id(c->id);
514 if (NULL == ctrl) {
515 DEB_D(("unknown control %d\n",c->id));
516 return -EINVAL;
517 }
518
519 down(&dev->lock);
520
521 switch (ctrl->type) {
522 case V4L2_CTRL_TYPE_BOOLEAN:
523 case V4L2_CTRL_TYPE_MENU:
524 case V4L2_CTRL_TYPE_INTEGER:
525 if (c->value < ctrl->minimum)
526 c->value = ctrl->minimum;
527 if (c->value > ctrl->maximum)
528 c->value = ctrl->maximum;
529 break;
530 default:
531 /* nothing */;
532 };
533
534 switch (c->id) {
535 case V4L2_CID_BRIGHTNESS: {
536 u32 value = saa7146_read(dev, BCS_CTRL);
537 value &= 0x00ffffff;
538 value |= (c->value << 24);
539 saa7146_write(dev, BCS_CTRL, value);
540 saa7146_write(dev, MC2, MASK_22 | MASK_06 );
541 break;
542 }
543 case V4L2_CID_CONTRAST: {
544 u32 value = saa7146_read(dev, BCS_CTRL);
545 value &= 0xff00ffff;
546 value |= (c->value << 16);
547 saa7146_write(dev, BCS_CTRL, value);
548 saa7146_write(dev, MC2, MASK_22 | MASK_06 );
549 break;
550 }
551 case V4L2_CID_SATURATION: {
552 u32 value = saa7146_read(dev, BCS_CTRL);
553 value &= 0xffffff00;
554 value |= (c->value << 0);
555 saa7146_write(dev, BCS_CTRL, value);
556 saa7146_write(dev, MC2, MASK_22 | MASK_06 );
557 break;
558 }
559 case V4L2_CID_HFLIP:
560 /* fixme: we can support changing VFLIP and HFLIP here... */
561 if (IS_CAPTURE_ACTIVE(fh) != 0) {
562 DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
563 up(&dev->lock);
564 return -EINVAL;
565 }
566 vv->hflip = c->value;
567 break;
568 case V4L2_CID_VFLIP:
569 if (IS_CAPTURE_ACTIVE(fh) != 0) {
570 DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
571 up(&dev->lock);
572 return -EINVAL;
573 }
574 vv->vflip = c->value;
575 break;
576 default: {
577 return -EINVAL;
578 }
579 }
580 up(&dev->lock);
581
582 if (IS_OVERLAY_ACTIVE(fh) != 0) {
583 saa7146_stop_preview(fh);
584 saa7146_start_preview(fh);
585 }
586 return 0;
587}
588
589/********************************************************************************/
590/* common pagetable functions */
591
592static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
593{
594 struct pci_dev *pci = dev->pci;
595 struct scatterlist *list = buf->vb.dma.sglist;
596 int length = buf->vb.dma.sglen;
597 struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
598
599 DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
600
601 if( 0 != IS_PLANAR(sfmt->trans)) {
602 struct saa7146_pgtable *pt1 = &buf->pt[0];
603 struct saa7146_pgtable *pt2 = &buf->pt[1];
604 struct saa7146_pgtable *pt3 = &buf->pt[2];
605 u32 *ptr1, *ptr2, *ptr3;
606 u32 fill;
607
608 int size = buf->fmt->width*buf->fmt->height;
609 int i,p,m1,m2,m3,o1,o2;
610
611 switch( sfmt->depth ) {
612 case 12: {
613 /* create some offsets inside the page table */
614 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
615 m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
616 m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
617 o1 = size%PAGE_SIZE;
618 o2 = (size+(size/4))%PAGE_SIZE;
619 DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
620 break;
621 }
622 case 16: {
623 /* create some offsets inside the page table */
624 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
625 m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
626 m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
627 o1 = size%PAGE_SIZE;
628 o2 = (size+(size/2))%PAGE_SIZE;
629 DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
630 break;
631 }
632 default: {
633 return -1;
634 }
635 }
636
637 ptr1 = pt1->cpu;
638 ptr2 = pt2->cpu;
639 ptr3 = pt3->cpu;
640
641 /* walk all pages, copy all page addresses to ptr1 */
642 for (i = 0; i < length; i++, list++) {
643 for (p = 0; p * 4096 < list->length; p++, ptr1++) {
644 *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset);
645 }
646 }
647/*
648 ptr1 = pt1->cpu;
649 for(j=0;j<40;j++) {
650 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
651 }
652*/
653
654 /* if we have a user buffer, the first page may not be
655 aligned to a page boundary. */
656 pt1->offset = buf->vb.dma.sglist->offset;
657 pt2->offset = pt1->offset+o1;
658 pt3->offset = pt1->offset+o2;
659
660 /* create video-dma2 page table */
661 ptr1 = pt1->cpu;
662 for(i = m1; i <= m2 ; i++, ptr2++) {
663 *ptr2 = ptr1[i];
664 }
665 fill = *(ptr2-1);
666 for(;i<1024;i++,ptr2++) {
667 *ptr2 = fill;
668 }
669 /* create video-dma3 page table */
670 ptr1 = pt1->cpu;
671 for(i = m2; i <= m3; i++,ptr3++) {
672 *ptr3 = ptr1[i];
673 }
674 fill = *(ptr3-1);
675 for(;i<1024;i++,ptr3++) {
676 *ptr3 = fill;
677 }
678 /* finally: finish up video-dma1 page table */
679 ptr1 = pt1->cpu+m1;
680 fill = pt1->cpu[m1];
681 for(i=m1;i<1024;i++,ptr1++) {
682 *ptr1 = fill;
683 }
684/*
685 ptr1 = pt1->cpu;
686 ptr2 = pt2->cpu;
687 ptr3 = pt3->cpu;
688 for(j=0;j<40;j++) {
689 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
690 }
691 for(j=0;j<40;j++) {
692 printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
693 }
694 for(j=0;j<40;j++) {
695 printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
696 }
697*/
698 } else {
699 struct saa7146_pgtable *pt = &buf->pt[0];
700 return saa7146_pgtable_build_single(pci, pt, list, length);
701 }
702
703 return 0;
704}
705
706
707/********************************************************************************/
708/* file operations */
709
710static int video_begin(struct saa7146_fh *fh)
711{
712 struct saa7146_dev *dev = fh->dev;
713 struct saa7146_vv *vv = dev->vv_data;
714 struct saa7146_format *fmt = NULL;
715 unsigned int resource;
716 int ret = 0, err = 0;
717
718 DEB_EE(("dev:%p, fh:%p\n",dev,fh));
719
720 if ((vv->video_status & STATUS_CAPTURE) != 0) {
721 if (vv->video_fh == fh) {
722 DEB_S(("already capturing.\n"));
723 return 0;
724 }
725 DEB_S(("already capturing in another open.\n"));
726 return -EBUSY;
727 }
728
729 if ((vv->video_status & STATUS_OVERLAY) != 0) {
730 DEB_S(("warning: suspending overlay video for streaming capture.\n"));
731 vv->ov_suspend = vv->video_fh;
732 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
733 if (0 != err) {
734 DEB_D(("suspending video failed. aborting\n"));
735 return err;
736 }
737 }
738
739 fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
740 /* we need to have a valid format set here */
741 BUG_ON(NULL == fmt);
742
743 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
744 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
745 } else {
746 resource = RESOURCE_DMA1_HPS;
747 }
748
749 ret = saa7146_res_get(fh, resource);
750 if (0 == ret) {
751 DEB_S(("cannot get capture resource %d\n",resource));
752 if (vv->ov_suspend != NULL) {
753 saa7146_start_preview(vv->ov_suspend);
754 vv->ov_suspend = NULL;
755 }
756 return -EBUSY;
757 }
758
759 /* clear out beginning of streaming bit (rps register 0)*/
760 saa7146_write(dev, MC2, MASK_27 );
761
762 /* enable rps0 irqs */
763 SAA7146_IER_ENABLE(dev, MASK_27);
764
765 vv->video_fh = fh;
766 vv->video_status = STATUS_CAPTURE;
767
768 return 0;
769}
770
771static int video_end(struct saa7146_fh *fh, struct file *file)
772{
773 struct saa7146_dev *dev = fh->dev;
774 struct saa7146_vv *vv = dev->vv_data;
775 struct saa7146_format *fmt = NULL;
776 unsigned long flags;
777 unsigned int resource;
778 u32 dmas = 0;
779 DEB_EE(("dev:%p, fh:%p\n",dev,fh));
780
781 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
782 DEB_S(("not capturing.\n"));
783 return 0;
784 }
785
786 if (vv->video_fh != fh) {
787 DEB_S(("capturing, but in another open.\n"));
788 return -EBUSY;
789 }
790
791 fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
792 /* we need to have a valid format set here */
793 BUG_ON(NULL == fmt);
794
795 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
796 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
797 dmas = MASK_22 | MASK_21 | MASK_20;
798 } else {
799 resource = RESOURCE_DMA1_HPS;
800 dmas = MASK_22;
801 }
802 spin_lock_irqsave(&dev->slock,flags);
803
804 /* disable rps0 */
805 saa7146_write(dev, MC1, MASK_28);
806
807 /* disable rps0 irqs */
808 SAA7146_IER_DISABLE(dev, MASK_27);
809
810 /* shut down all used video dma transfers */
811 saa7146_write(dev, MC1, dmas);
812
813 spin_unlock_irqrestore(&dev->slock, flags);
814
815 vv->video_fh = NULL;
816 vv->video_status = 0;
817
818 saa7146_res_free(fh, resource);
819
820 if (vv->ov_suspend != NULL) {
821 saa7146_start_preview(vv->ov_suspend);
822 vv->ov_suspend = NULL;
823 }
824
825 return 0;
826}
827
828/*
829 * This function is _not_ called directly, but from
830 * video_generic_ioctl (and maybe others). userspace
831 * copying is done already, arg is a kernel pointer.
832 */
833
834int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
835{
836 struct saa7146_fh *fh = file->private_data;
837 struct saa7146_dev *dev = fh->dev;
838 struct saa7146_vv *vv = dev->vv_data;
839
840 int err = 0, result = 0, ee = 0;
841
842 struct saa7146_use_ops *ops;
843 struct videobuf_queue *q;
844
845 /* check if extension handles the command */
846 for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
847 if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
848 break;
849 }
850
851 if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
852 DEB_D(("extension handles ioctl exclusive.\n"));
853 result = dev->ext_vv_data->ioctl(fh, cmd, arg);
854 return result;
855 }
856 if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
857 DEB_D(("extension handles ioctl before.\n"));
858 result = dev->ext_vv_data->ioctl(fh, cmd, arg);
859 if( -EAGAIN != result ) {
860 return result;
861 }
862 }
863
864 /* fixme: add handle "after" case (is it still needed?) */
865
866 switch (fh->type) {
867 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
868 ops = &saa7146_video_uops;
869 q = &fh->video_q;
870 break;
871 }
872 case V4L2_BUF_TYPE_VBI_CAPTURE: {
873 ops = &saa7146_vbi_uops;
874 q = &fh->vbi_q;
875 break;
876 }
877 default:
878 BUG();
879 return 0;
880 }
881
882 switch (cmd) {
883 case VIDIOC_QUERYCAP:
884 {
885 struct v4l2_capability *cap = arg;
886 memset(cap,0,sizeof(*cap));
887
888 DEB_EE(("VIDIOC_QUERYCAP\n"));
889
890 strcpy(cap->driver, "saa7146 v4l2");
891 strlcpy(cap->card, dev->ext->name, sizeof(cap->card));
892 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
893 cap->version = SAA7146_VERSION_CODE;
894 cap->capabilities =
895 V4L2_CAP_VIDEO_CAPTURE |
896 V4L2_CAP_VIDEO_OVERLAY |
897 V4L2_CAP_READWRITE |
898 V4L2_CAP_STREAMING;
899 cap->capabilities |= dev->ext_vv_data->capabilities;
900 return 0;
901 }
902 case VIDIOC_G_FBUF:
903 {
904 struct v4l2_framebuffer *fb = arg;
905
906 DEB_EE(("VIDIOC_G_FBUF\n"));
907
908 *fb = vv->ov_fb;
909 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
910 return 0;
911 }
912 case VIDIOC_S_FBUF:
913 {
914 struct v4l2_framebuffer *fb = arg;
915 struct saa7146_format *fmt;
916
917 DEB_EE(("VIDIOC_S_FBUF\n"));
918
919 if(!capable(CAP_SYS_ADMIN) &&
920 !capable(CAP_SYS_RAWIO))
921 return -EPERM;
922
923 /* check args */
924 fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
925 if (NULL == fmt) {
926 return -EINVAL;
927 }
928
929 /* planar formats are not allowed for overlay video, clipping and video dma would clash */
930 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
931 DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
932 }
933
934 /* check if overlay is running */
935 if (IS_OVERLAY_ACTIVE(fh) != 0) {
936 if (vv->video_fh != fh) {
937 DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
938 return -EBUSY;
939 }
940 }
941
942 down(&dev->lock);
943
944 /* ok, accept it */
945 vv->ov_fb = *fb;
946 vv->ov_fmt = fmt;
947 if (0 == vv->ov_fb.fmt.bytesperline)
948 vv->ov_fb.fmt.bytesperline =
949 vv->ov_fb.fmt.width*fmt->depth/8;
950
951 up(&dev->lock);
952
953 return 0;
954 }
955 case VIDIOC_ENUM_FMT:
956 {
957 struct v4l2_fmtdesc *f = arg;
958 int index;
959
960 switch (f->type) {
961 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
962 case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
963 index = f->index;
964 if (index < 0 || index >= NUM_FORMATS) {
965 return -EINVAL;
966 }
967 memset(f,0,sizeof(*f));
968 f->index = index;
969 strlcpy(f->description,formats[index].name,sizeof(f->description));
970 f->pixelformat = formats[index].pixelformat;
971 break;
972 }
973 default:
974 return -EINVAL;
975 }
976
977 DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
978 return 0;
979 }
980 case VIDIOC_QUERYCTRL:
981 {
982 const struct v4l2_queryctrl *ctrl;
983 struct v4l2_queryctrl *c = arg;
984
985 if ((c->id < V4L2_CID_BASE ||
986 c->id >= V4L2_CID_LASTP1) &&
987 (c->id < V4L2_CID_PRIVATE_BASE ||
988 c->id >= V4L2_CID_PRIVATE_LASTP1))
989 return -EINVAL;
990
991 ctrl = ctrl_by_id(c->id);
992 if( NULL == ctrl ) {
993 return -EINVAL;
994/*
995 c->flags = V4L2_CTRL_FLAG_DISABLED;
996 return 0;
997*/
998 }
999
1000 DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
1001 *c = *ctrl;
1002 return 0;
1003 }
1004 case VIDIOC_G_CTRL: {
1005 DEB_EE(("VIDIOC_G_CTRL\n"));
1006 return get_control(fh,arg);
1007 }
1008 case VIDIOC_S_CTRL:
1009 {
1010 DEB_EE(("VIDIOC_S_CTRL\n"));
1011 err = set_control(fh,arg);
1012 return err;
1013 }
1014 case VIDIOC_G_PARM:
1015 {
1016 struct v4l2_streamparm *parm = arg;
1017 if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
1018 return -EINVAL;
1019 }
1020 memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
1021 parm->parm.capture.readbuffers = 1;
1022 // fixme: only for PAL!
1023 parm->parm.capture.timeperframe.numerator = 1;
1024 parm->parm.capture.timeperframe.denominator = 25;
1025 return 0;
1026 }
1027 case VIDIOC_G_FMT:
1028 {
1029 struct v4l2_format *f = arg;
1030 DEB_EE(("VIDIOC_G_FMT\n"));
1031 return g_fmt(fh,f);
1032 }
1033 case VIDIOC_S_FMT:
1034 {
1035 struct v4l2_format *f = arg;
1036 DEB_EE(("VIDIOC_S_FMT\n"));
1037 return s_fmt(fh,f);
1038 }
1039 case VIDIOC_TRY_FMT:
1040 {
1041 struct v4l2_format *f = arg;
1042 DEB_EE(("VIDIOC_TRY_FMT\n"));
1043 return try_fmt(fh,f);
1044 }
1045 case VIDIOC_G_STD:
1046 {
1047 v4l2_std_id *id = arg;
1048 DEB_EE(("VIDIOC_G_STD\n"));
1049 *id = vv->standard->id;
1050 return 0;
1051 }
1052 /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
1053 PAL / NTSC / SECAM. if your hardware does not (or does more)
1054 -- override this function in your extension */
1055 case VIDIOC_ENUMSTD:
1056 {
1057 struct v4l2_standard *e = arg;
1058 if (e->index < 0 )
1059 return -EINVAL;
1060 if( e->index < dev->ext_vv_data->num_stds ) {
1061 DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
1062 v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
1063 return 0;
1064 }
1065 return -EINVAL;
1066 }
1067 case VIDIOC_S_STD:
1068 {
1069 v4l2_std_id *id = arg;
1070 int found = 0;
1071 int i, err;
1072
1073 DEB_EE(("VIDIOC_S_STD\n"));
1074
1075 if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
1076 DEB_D(("cannot change video standard while streaming capture is active\n"));
1077 return -EBUSY;
1078 }
1079
1080 if ((vv->video_status & STATUS_OVERLAY) != 0) {
1081 vv->ov_suspend = vv->video_fh;
1082 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
1083 if (0 != err) {
1084 DEB_D(("suspending video failed. aborting\n"));
1085 return err;
1086 }
1087 }
1088
1089 down(&dev->lock);
1090
1091 for(i = 0; i < dev->ext_vv_data->num_stds; i++)
1092 if (*id & dev->ext_vv_data->stds[i].id)
1093 break;
1094 if (i != dev->ext_vv_data->num_stds) {
1095 vv->standard = &dev->ext_vv_data->stds[i];
1096 if( NULL != dev->ext_vv_data->std_callback )
1097 dev->ext_vv_data->std_callback(dev, vv->standard);
1098 found = 1;
1099 }
1100
1101 up(&dev->lock);
1102
1103 if (vv->ov_suspend != NULL) {
1104 saa7146_start_preview(vv->ov_suspend);
1105 vv->ov_suspend = NULL;
1106 }
1107
1108 if( 0 == found ) {
1109 DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
1110 return -EINVAL;
1111 }
1112
1113 DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
1114 return 0;
1115 }
1116 case VIDIOC_OVERLAY:
1117
1118
1119
1120
1121 {
1122 int on = *(int *)arg;
1123 int err = 0;
1124
1125 DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
1126 if (on != 0) {
1127 err = saa7146_start_preview(fh);
1128 } else {
1129 err = saa7146_stop_preview(fh);
1130 }
1131 return err;
1132 }
1133 case VIDIOC_REQBUFS: {
1134 struct v4l2_requestbuffers *req = arg;
1135 DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
1136 return videobuf_reqbufs(q,req);
1137 }
1138 case VIDIOC_QUERYBUF: {
1139 struct v4l2_buffer *buf = arg;
1140 DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
1141 return videobuf_querybuf(q,buf);
1142 }
1143 case VIDIOC_QBUF: {
1144 struct v4l2_buffer *buf = arg;
1145 int ret = 0;
1146 ret = videobuf_qbuf(q,buf);
1147 DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
1148 return ret;
1149 }
1150 case VIDIOC_DQBUF: {
1151 struct v4l2_buffer *buf = arg;
1152 int ret = 0;
1153 ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK);
1154 DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
1155 return ret;
1156 }
1157 case VIDIOC_STREAMON: {
1158 int *type = arg;
1159 DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
1160
1161 err = video_begin(fh);
1162 if( 0 != err) {
1163 return err;
1164 }
1165 err = videobuf_streamon(q);
1166 return err;
1167 }
1168 case VIDIOC_STREAMOFF: {
1169 int *type = arg;
1170
1171 DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
1172
1173 /* ugly: we need to copy some checks from video_end(),
1174 because videobuf_streamoff() relies on the capture running.
1175 check and fix this */
1176 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
1177 DEB_S(("not capturing.\n"));
1178 return 0;
1179 }
1180
1181 if (vv->video_fh != fh) {
1182 DEB_S(("capturing, but in another open.\n"));
1183 return -EBUSY;
1184 }
1185
1186 err = videobuf_streamoff(q);
1187 if (0 != err) {
1188 DEB_D(("warning: videobuf_streamoff() failed.\n"));
1189 video_end(fh, file);
1190 } else {
1191 err = video_end(fh, file);
1192 }
1193 return err;
1194 }
1195 case VIDIOCGMBUF:
1196 {
1197 struct video_mbuf *mbuf = arg;
1198 struct videobuf_queue *q;
1199 int i;
1200
1201 /* fixme: number of capture buffers and sizes for v4l apps */
1202 int gbuffers = 2;
1203 int gbufsize = 768*576*4;
1204
1205 DEB_D(("VIDIOCGMBUF \n"));
1206
1207 q = &fh->video_q;
1208 down(&q->lock);
1209 err = videobuf_mmap_setup(q,gbuffers,gbufsize,
1210 V4L2_MEMORY_MMAP);
1211 if (err < 0) {
1212 up(&q->lock);
1213 return err;
1214 }
1215 memset(mbuf,0,sizeof(*mbuf));
1216 mbuf->frames = gbuffers;
1217 mbuf->size = gbuffers * gbufsize;
1218 for (i = 0; i < gbuffers; i++)
1219 mbuf->offsets[i] = i * gbufsize;
1220 up(&q->lock);
1221 return 0;
1222 }
1223 default:
1224 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1225 saa7146_video_do_ioctl);
1226 }
1227 return 0;
1228}
1229
1230/*********************************************************************************/
1231/* buffer handling functions */
1232
1233static int buffer_activate (struct saa7146_dev *dev,
1234 struct saa7146_buf *buf,
1235 struct saa7146_buf *next)
1236{
1237 struct saa7146_vv *vv = dev->vv_data;
1238
1239 buf->vb.state = STATE_ACTIVE;
1240 saa7146_set_capture(dev,buf,next);
1241
1242 mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
1243 return 0;
1244}
1245
1246static int buffer_prepare(struct videobuf_queue *q,
1247 struct videobuf_buffer *vb, enum v4l2_field field)
1248{
1249 struct file *file = q->priv_data;
1250 struct saa7146_fh *fh = file->private_data;
1251 struct saa7146_dev *dev = fh->dev;
1252 struct saa7146_vv *vv = dev->vv_data;
1253 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1254 int size,err = 0;
1255
1256 DEB_CAP(("vbuf:%p\n",vb));
1257
1258 /* sanity checks */
1259 if (fh->video_fmt.width < 48 ||
1260 fh->video_fmt.height < 32 ||
1261 fh->video_fmt.width > vv->standard->h_max_out ||
1262 fh->video_fmt.height > vv->standard->v_max_out) {
1263 DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
1264 return -EINVAL;
1265 }
1266
1267 size = fh->video_fmt.sizeimage;
1268 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1269 DEB_D(("size mismatch.\n"));
1270 return -EINVAL;
1271 }
1272
1273 DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1274 fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
1275 if (buf->vb.width != fh->video_fmt.width ||
1276 buf->vb.bytesperline != fh->video_fmt.bytesperline ||
1277 buf->vb.height != fh->video_fmt.height ||
1278 buf->vb.size != size ||
1279 buf->vb.field != field ||
1280 buf->vb.field != fh->video_fmt.field ||
1281 buf->fmt != &fh->video_fmt) {
1282 saa7146_dma_free(dev,buf);
1283 }
1284
1285 if (STATE_NEEDS_INIT == buf->vb.state) {
1286 struct saa7146_format *sfmt;
1287
1288 buf->vb.bytesperline = fh->video_fmt.bytesperline;
1289 buf->vb.width = fh->video_fmt.width;
1290 buf->vb.height = fh->video_fmt.height;
1291 buf->vb.size = size;
1292 buf->vb.field = field;
1293 buf->fmt = &fh->video_fmt;
1294 buf->vb.field = fh->video_fmt.field;
1295
1296 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
1297
1298 if( 0 != IS_PLANAR(sfmt->trans)) {
1299 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1300 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1301 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1302
1303 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1304 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1305 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1306 } else {
1307 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1308 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1309 }
1310
1311 err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
1312 if (err)
1313 goto oops;
1314 err = saa7146_pgtable_build(dev,buf);
1315 if (err)
1316 goto oops;
1317 }
1318 buf->vb.state = STATE_PREPARED;
1319 buf->activate = buffer_activate;
1320
1321 return 0;
1322
1323 oops:
1324 DEB_D(("error out.\n"));
1325 saa7146_dma_free(dev,buf);
1326
1327 return err;
1328}
1329
1330static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1331{
1332 struct file *file = q->priv_data;
1333 struct saa7146_fh *fh = file->private_data;
1334
1335 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1336 *count = MAX_SAA7146_CAPTURE_BUFFERS;
1337
1338 *size = fh->video_fmt.sizeimage;
1339
1340 /* check if we exceed the "max_memory" parameter */
1341 if( (*count * *size) > (max_memory*1048576) ) {
1342 *count = (max_memory*1048576) / *size;
1343 }
1344
1345 DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
1346
1347 return 0;
1348}
1349
1350static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1351{
1352 struct file *file = q->priv_data;
1353 struct saa7146_fh *fh = file->private_data;
1354 struct saa7146_dev *dev = fh->dev;
1355 struct saa7146_vv *vv = dev->vv_data;
1356 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1357
1358 DEB_CAP(("vbuf:%p\n",vb));
1359 saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
1360}
1361
1362
1363static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1364{
1365 struct file *file = q->priv_data;
1366 struct saa7146_fh *fh = file->private_data;
1367 struct saa7146_dev *dev = fh->dev;
1368 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1369
1370 DEB_CAP(("vbuf:%p\n",vb));
1371 saa7146_dma_free(dev,buf);
1372}
1373
1374static struct videobuf_queue_ops video_qops = {
1375 .buf_setup = buffer_setup,
1376 .buf_prepare = buffer_prepare,
1377 .buf_queue = buffer_queue,
1378 .buf_release = buffer_release,
1379};
1380
1381/********************************************************************************/
1382/* file operations */
1383
1384static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1385{
1386 INIT_LIST_HEAD(&vv->video_q.queue);
1387
1388 init_timer(&vv->video_q.timeout);
1389 vv->video_q.timeout.function = saa7146_buffer_timeout;
1390 vv->video_q.timeout.data = (unsigned long)(&vv->video_q);
1391 vv->video_q.dev = dev;
1392
1393 /* set some default values */
1394 vv->standard = &dev->ext_vv_data->stds[0];
1395
1396 /* FIXME: what's this? */
1397 vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
1398 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1399}
1400
1401
1402static int video_open(struct saa7146_dev *dev, struct file *file)
1403{
1404 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
1405 struct saa7146_format *sfmt;
1406
1407 fh->video_fmt.width = 384;
1408 fh->video_fmt.height = 288;
1409 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1410 fh->video_fmt.bytesperline = 0;
1411 fh->video_fmt.field = V4L2_FIELD_ANY;
1412 sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
1413 fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1414
1415 videobuf_queue_init(&fh->video_q, &video_qops,
1416 dev->pci, &dev->slock,
1417 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1418 V4L2_FIELD_INTERLACED,
1419 sizeof(struct saa7146_buf),
1420 file);
1421
1422 init_MUTEX(&fh->video_q.lock);
1423
1424 return 0;
1425}
1426
1427
1428static void video_close(struct saa7146_dev *dev, struct file *file)
1429{
1430 struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
1431 struct saa7146_vv *vv = dev->vv_data;
1432 int err;
1433
1434 if (IS_CAPTURE_ACTIVE(fh) != 0) {
1435 err = video_end(fh, file);
1436 } else if (IS_OVERLAY_ACTIVE(fh) != 0) {
1437 err = saa7146_stop_preview(fh);
1438 }
1439
1440 /* hmm, why is this function declared void? */
1441 /* return err */
1442}
1443
1444
1445static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1446{
1447 struct saa7146_vv *vv = dev->vv_data;
1448 struct saa7146_dmaqueue *q = &vv->video_q;
1449
1450 spin_lock(&dev->slock);
1451 DEB_CAP(("called.\n"));
1452
1453 /* only finish the buffer if we have one... */
1454 if( NULL != q->curr ) {
1455 saa7146_buffer_finish(dev,q,STATE_DONE);
1456 }
1457 saa7146_buffer_next(dev,q,0);
1458
1459 spin_unlock(&dev->slock);
1460}
1461
1462static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1463{
1464 struct saa7146_fh *fh = file->private_data;
1465 struct saa7146_dev *dev = fh->dev;
1466 struct saa7146_vv *vv = dev->vv_data;
1467 ssize_t ret = 0;
1468
1469 DEB_EE(("called.\n"));
1470
1471 if ((vv->video_status & STATUS_CAPTURE) != 0) {
1472 /* fixme: should we allow read() captures while streaming capture? */
1473 if (vv->video_fh == fh) {
1474 DEB_S(("already capturing.\n"));
1475 return -EBUSY;
1476 }
1477 DEB_S(("already capturing in another open.\n"));
1478 return -EBUSY;
1479 }
1480
1481 ret = video_begin(fh);
1482 if( 0 != ret) {
1483 goto out;
1484 }
1485
1486 ret = videobuf_read_one(&fh->video_q , data, count, ppos,
1487 file->f_flags & O_NONBLOCK);
1488 if (ret != 0) {
1489 video_end(fh, file);
1490 } else {
1491 ret = video_end(fh, file);
1492 }
1493out:
1494 /* restart overlay if it was active before */
1495 if (vv->ov_suspend != NULL) {
1496 saa7146_start_preview(vv->ov_suspend);
1497 vv->ov_suspend = NULL;
1498 }
1499
1500 return ret;
1501}
1502
1503struct saa7146_use_ops saa7146_video_uops = {
1504 .init = video_init,
1505 .open = video_open,
1506 .release = video_close,
1507 .irq_done = video_irq_done,
1508 .read = video_read,
1509};
diff --git a/drivers/media/common/saa7146_vv_ksyms.c b/drivers/media/common/saa7146_vv_ksyms.c
new file mode 100644
index 000000000000..62226eb4753b
--- /dev/null
+++ b/drivers/media/common/saa7146_vv_ksyms.c
@@ -0,0 +1,12 @@
1#include <linux/module.h>
2#include <media/saa7146_vv.h>
3
4EXPORT_SYMBOL_GPL(saa7146_start_preview);
5EXPORT_SYMBOL_GPL(saa7146_stop_preview);
6
7EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
8EXPORT_SYMBOL_GPL(saa7146_register_device);
9EXPORT_SYMBOL_GPL(saa7146_unregister_device);
10
11EXPORT_SYMBOL_GPL(saa7146_vv_init);
12EXPORT_SYMBOL_GPL(saa7146_vv_release);
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
new file mode 100644
index 000000000000..883ec08490f4
--- /dev/null
+++ b/drivers/media/dvb/Kconfig
@@ -0,0 +1,47 @@
1#
2# Multimedia device configuration
3#
4
5menu "Digital Video Broadcasting Devices"
6
7config DVB
8 bool "DVB For Linux"
9 depends on NET && INET
10 ---help---
11 Support Digital Video Broadcasting hardware. Enable this if you
12 own a DVB adapter and want to use it or if you compile Linux for
13 a digital SetTopBox.
14
15 API specs and user tools are available from <http://www.linuxtv.org/>.
16
17 Please report problems regarding this driver to the LinuxDVB
18 mailing list.
19
20 If unsure say N.
21
22source "drivers/media/dvb/dvb-core/Kconfig"
23
24comment "Supported SAA7146 based PCI Adapters"
25 depends on DVB_CORE && PCI
26source "drivers/media/dvb/ttpci/Kconfig"
27
28comment "Supported USB Adapters"
29 depends on DVB_CORE && USB
30source "drivers/media/dvb/ttusb-budget/Kconfig"
31source "drivers/media/dvb/ttusb-dec/Kconfig"
32source "drivers/media/dvb/dibusb/Kconfig"
33source "drivers/media/dvb/cinergyT2/Kconfig"
34
35comment "Supported FlexCopII (B2C2) Adapters"
36 depends on DVB_CORE && PCI
37source "drivers/media/dvb/b2c2/Kconfig"
38
39comment "Supported BT878 Adapters"
40 depends on DVB_CORE && PCI
41source "drivers/media/dvb/bt8xx/Kconfig"
42
43comment "Supported DVB Frontends"
44 depends on DVB_CORE
45source "drivers/media/dvb/frontends/Kconfig"
46
47endmenu
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
new file mode 100644
index 000000000000..520fc3902819
--- /dev/null
+++ b/drivers/media/dvb/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the kernel multimedia device drivers.
3#
4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
new file mode 100644
index 000000000000..52596907a0be
--- /dev/null
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -0,0 +1,26 @@
1config DVB_B2C2_SKYSTAR
2 tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
3 depends on DVB_CORE && PCI
4 select DVB_STV0299
5 select DVB_MT352
6 select DVB_MT312
7 select DVB_NXT2002
8 help
9 Support for the Skystar2 PCI DVB card by Technisat, which
10 is equipped with the FlexCopII chipset by B2C2, and
11 for the B2C2/BBTI Air2PC-ATSC card.
12
13 Say Y if you own such a device and want to use it.
14
15config DVB_B2C2_USB
16 tristate "B2C2/Technisat Air/Sky/Cable2PC USB"
17 depends on DVB_CORE && USB && EXPERIMENTAL
18 select DVB_STV0299
19 select DVB_MT352
20 help
21 Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
22 the does nothing, but providing basic function for the used usb
23 protocol.
24
25 Say Y if you own such a device and want to use it.
26
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
new file mode 100644
index 000000000000..9fb1247bfab8
--- /dev/null
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -0,0 +1,6 @@
1obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o
2
3obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
4obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o
5
6EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/b2c2-common.c b/drivers/media/dvb/b2c2/b2c2-common.c
new file mode 100644
index 000000000000..000d60c405e3
--- /dev/null
+++ b/drivers/media/dvb/b2c2/b2c2-common.c
@@ -0,0 +1,214 @@
1/*
2 * b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and
3 * for the B2C2/Technisat Sky/Cable/AirStar USB devices
4 * based on the FlexCopII/FlexCopIII by B2C2, Inc.
5 *
6 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
7 *
8 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
9 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
10 * Vincenzo Di Massa, hawk.it at tiscalinet.it
11 *
12 * Converted to Linux coding style
13 * Misc reorganization, polishing, restyling
14 * Roberto Ragusa, r.ragusa at libero.it
15 *
16 * Added hardware filtering support,
17 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (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 Lesser 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#include "stv0299.h"
35#include "mt352.h"
36#include "mt312.h"
37
38static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
39{
40 u8 aclk = 0;
41 u8 bclk = 0;
42
43 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
44 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
45 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
46 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
47 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
48 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
49
50 stv0299_writereg (fe, 0x13, aclk);
51 stv0299_writereg (fe, 0x14, bclk);
52 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
53 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
54 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
55
56 return 0;
57}
58
59static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
60{
61 u8 buf[4];
62 u32 div;
63 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
64// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
65
66 div = params->frequency / 125;
67
68 buf[0] = (div >> 8) & 0x7f;
69 buf[1] = div & 0xff;
70 buf[2] = 0x84; // 0xC4
71 buf[3] = 0x08;
72
73 if (params->frequency < 1500000) buf[3] |= 0x10;
74
75// if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
76 return 0;
77}
78
79static u8 samsung_tbmu24112_inittab[] = {
80 0x01, 0x15,
81 0x02, 0x30,
82 0x03, 0x00,
83 0x04, 0x7D,
84 0x05, 0x35,
85 0x06, 0x02,
86 0x07, 0x00,
87 0x08, 0xC3,
88 0x0C, 0x00,
89 0x0D, 0x81,
90 0x0E, 0x23,
91 0x0F, 0x12,
92 0x10, 0x7E,
93 0x11, 0x84,
94 0x12, 0xB9,
95 0x13, 0x88,
96 0x14, 0x89,
97 0x15, 0xC9,
98 0x16, 0x00,
99 0x17, 0x5C,
100 0x18, 0x00,
101 0x19, 0x00,
102 0x1A, 0x00,
103 0x1C, 0x00,
104 0x1D, 0x00,
105 0x1E, 0x00,
106 0x1F, 0x3A,
107 0x20, 0x2E,
108 0x21, 0x80,
109 0x22, 0xFF,
110 0x23, 0xC1,
111 0x28, 0x00,
112 0x29, 0x1E,
113 0x2A, 0x14,
114 0x2B, 0x0F,
115 0x2C, 0x09,
116 0x2D, 0x05,
117 0x31, 0x1F,
118 0x32, 0x19,
119 0x33, 0xFE,
120 0x34, 0x93,
121 0xff, 0xff,
122};
123
124static struct stv0299_config samsung_tbmu24112_config = {
125 .demod_address = 0x68,
126 .inittab = samsung_tbmu24112_inittab,
127 .mclk = 88000000UL,
128 .invert = 0,
129 .enhanced_tuning = 0,
130 .skip_reinit = 0,
131 .lock_output = STV0229_LOCKOUTPUT_LK,
132 .volt13_op0_op1 = STV0299_VOLT13_OP1,
133 .min_delay_ms = 100,
134 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
135 .pll_set = samsung_tbmu24112_pll_set,
136};
137
138
139
140
141
142static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
143{
144 static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d };
145 static u8 mt352_reset [] = { 0x50, 0x80 };
146 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
147 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
148 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
149
150 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
151 udelay(2000);
152 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
153 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
154
155 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
156 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
157
158 return 0;
159}
160
161static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
162{
163 u32 div;
164 unsigned char bs = 0;
165
166 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
167 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
168
169 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
170 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
171 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
172
173 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
174 pllbuf[1] = div >> 8;
175 pllbuf[2] = div & 0xff;
176 pllbuf[3] = 0xcc;
177 pllbuf[4] = bs;
178
179 return 0;
180}
181
182static struct mt352_config samsung_tdtc9251dh0_config = {
183
184 .demod_address = 0x0f,
185 .demod_init = samsung_tdtc9251dh0_demod_init,
186 .pll_set = samsung_tdtc9251dh0_pll_set,
187};
188
189static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
190{
191 u8 buf[4];
192 u32 div;
193 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
194// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
195
196 div = (params->frequency + (125/2)) / 125;
197
198 buf[0] = (div >> 8) & 0x7f;
199 buf[1] = (div >> 0) & 0xff;
200 buf[2] = 0x84 | ((div >> 10) & 0x60);
201 buf[3] = 0x80;
202
203 if (params->frequency < 1550000)
204 buf[3] |= 0x02;
205
206 //if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
207 return 0;
208}
209
210static struct mt312_config skystar23_samsung_tbdu18132_config = {
211
212 .demod_address = 0x0e,
213 .pll_set = skystar23_samsung_tbdu18132_pll_set,
214};
diff --git a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
new file mode 100644
index 000000000000..9306da046c91
--- /dev/null
+++ b/drivers/media/dvb/b2c2/b2c2-usb-core.c
@@ -0,0 +1,549 @@
1/*
2 * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>,
3 * Luca Bertagnolio <>,
4 *
5 * based on information provided by John Jurrius from BBTI, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/usb.h>
16#include <linux/moduleparam.h>
17#include <linux/pci.h>
18#include <linux/version.h>
19
20#include "dmxdev.h"
21#include "dvb_demux.h"
22#include "dvb_filter.h"
23#include "dvb_net.h"
24#include "dvb_frontend.h"
25
26/* debug */
27#define dprintk(level,args...) \
28 do { if ((debug & level)) { printk(args); } } while (0)
29#define debug_dump(b,l) if (debug) {\
30 int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
31 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
32 deb_xfer("\n");\
33}
34
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
38
39#define deb_info(args...) dprintk(0x01,args)
40#define deb_ts(args...) dprintk(0x02,args)
41#define deb_ctrl(args...) dprintk(0x04,args)
42
43/* Version information */
44#define DRIVER_VERSION "0.0"
45#define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices"
46#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
47
48/* transfer parameters */
49#define B2C2_USB_FRAMES_PER_ISO 4
50#define B2C2_USB_NUM_ISO_URB 4 /* TODO check out a good value */
51
52#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(b2c2->udev,0)
53#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(b2c2->udev,0)
54#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(b2c2->udev,0x81)
55
56struct usb_b2c2_usb {
57 struct usb_device *udev;
58 struct usb_interface *uintf;
59
60 u8 *iso_buffer;
61 int buffer_size;
62 dma_addr_t iso_dma_handle;
63 struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
64};
65
66
67/*
68 * USB
69 * 10 90 34 12 78 56 04 00
70 * usb_control_msg(udev, usb_sndctrlpipe(udev,0),
71 * 0x90,
72 * 0x10,
73 * 0x1234,
74 * 0x5678,
75 * buf,
76 * 4,
77 * 5*HZ);
78 *
79 * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
80 * __u8 request,
81 * __u8 requesttype,
82 * __u16 value,
83 * __u16 index,
84 * void *data,
85 * __u16 size,
86 * int timeout);
87 *
88 */
89
90/* request types */
91typedef enum {
92
93/* something is wrong with this part
94 RTYPE_READ_DW = (1 << 6),
95 RTYPE_WRITE_DW_1 = (3 << 6),
96 RTYPE_READ_V8_MEMORY = (6 << 6),
97 RTYPE_WRITE_V8_MEMORY = (7 << 6),
98 RTYPE_WRITE_V8_FLASH = (8 << 6),
99 RTYPE_GENERIC = (9 << 6),
100*/
101 RTYPE_READ_DW = (3 << 6),
102 RTYPE_WRITE_DW_1 = (1 << 6),
103
104 RTYPE_READ_V8_MEMORY = (6 << 6),
105 RTYPE_WRITE_V8_MEMORY = (7 << 6),
106 RTYPE_WRITE_V8_FLASH = (8 << 6),
107 RTYPE_GENERIC = (9 << 6),
108} b2c2_usb_request_type_t;
109
110/* request */
111typedef enum {
112 B2C2_USB_WRITE_V8_MEM = 0x04,
113 B2C2_USB_READ_V8_MEM = 0x05,
114 B2C2_USB_READ_REG = 0x08,
115 B2C2_USB_WRITE_REG = 0x0A,
116/* B2C2_USB_WRITEREGLO = 0x0A, */
117 B2C2_USB_WRITEREGHI = 0x0B,
118 B2C2_USB_FLASH_BLOCK = 0x10,
119 B2C2_USB_I2C_REQUEST = 0x11,
120 B2C2_USB_UTILITY = 0x12,
121} b2c2_usb_request_t;
122
123/* function definition for I2C_REQUEST */
124typedef enum {
125 USB_FUNC_I2C_WRITE = 0x01,
126 USB_FUNC_I2C_MULTIWRITE = 0x02,
127 USB_FUNC_I2C_READ = 0x03,
128 USB_FUNC_I2C_REPEATWRITE = 0x04,
129 USB_FUNC_GET_DESCRIPTOR = 0x05,
130 USB_FUNC_I2C_REPEATREAD = 0x06,
131/* DKT 020208 - add this to support special case of DiSEqC */
132 USB_FUNC_I2C_CHECKWRITE = 0x07,
133 USB_FUNC_I2C_CHECKRESULT = 0x08,
134} b2c2_usb_i2c_function_t;
135
136/*
137 * function definition for UTILITY request 0x12
138 * DKT 020304 - new utility function
139 */
140typedef enum {
141 UTILITY_SET_FILTER = 0x01,
142 UTILITY_DATA_ENABLE = 0x02,
143 UTILITY_FLEX_MULTIWRITE = 0x03,
144 UTILITY_SET_BUFFER_SIZE = 0x04,
145 UTILITY_FLEX_OPERATOR = 0x05,
146 UTILITY_FLEX_RESET300_START = 0x06,
147 UTILITY_FLEX_RESET300_STOP = 0x07,
148 UTILITY_FLEX_RESET300 = 0x08,
149 UTILITY_SET_ISO_SIZE = 0x09,
150 UTILITY_DATA_RESET = 0x0A,
151 UTILITY_GET_DATA_STATUS = 0x10,
152 UTILITY_GET_V8_REG = 0x11,
153/* DKT 020326 - add function for v1.14 */
154 UTILITY_SRAM_WRITE = 0x12,
155 UTILITY_SRAM_READ = 0x13,
156 UTILITY_SRAM_TESTFILL = 0x14,
157 UTILITY_SRAM_TESTSET = 0x15,
158 UTILITY_SRAM_TESTVERIFY = 0x16,
159} b2c2_usb_utility_function_t;
160
161#define B2C2_WAIT_FOR_OPERATION_RW 1 // 1 s
162#define B2C2_WAIT_FOR_OPERATION_RDW 3 // 3 s
163#define B2C2_WAIT_FOR_OPERATION_WDW 1 // 1 s
164
165#define B2C2_WAIT_FOR_OPERATION_V8READ 3 // 3 s
166#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3 // 3 s
167#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3 // 3 s
168
169/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
170 * in the IBI address, to make the V8 code simpler.
171 * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
172 * in general: 0000 0HHH 000L LL00
173 * IBI ADDRESS FORMAT: RHHH BLLL
174 *
175 * where R is the read(1)/write(0) bit, B is the busy bit
176 * and HHH and LLL are the two sets of three bits from the PCI address.
177 */
178#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
179#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
180
181/*
182 * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register
183 * deal with DWORD or 4 bytes, that should be should from now on
184 */
185static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI)
186{
187 u32 val;
188 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080;
189 int len = usb_control_msg(b2c2->udev,
190 B2C2_USB_CTRL_PIPE_IN,
191 B2C2_USB_READ_REG,
192 RTYPE_READ_DW,
193 wAddress,
194 0,
195 &val,
196 sizeof(u32),
197 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
198
199 if (len != sizeof(u32)) {
200 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
201 return -EIO;
202 } else
203 return val;
204}
205
206/*
207 * DKT 020228 - from now on, we don't support anything older than firm 1.00
208 * I eliminated the write register as a 2 trip of writing hi word and lo word
209 * and force this to write only 4 bytes at a time.
210 * NOTE: this should work with all the firmware from 1.00 and newer
211 */
212static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val)
213{
214 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI);
215 int len = usb_control_msg(b2c2->udev,
216 B2C2_USB_CTRL_PIPE_OUT,
217 B2C2_USB_WRITE_REG,
218 RTYPE_WRITE_DW_1,
219 wAddress,
220 0,
221 &val,
222 sizeof(u32),
223 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
224
225 if (len != sizeof(u32)) {
226 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
227 return -EIO;
228 } else
229 return 0;
230}
231
232/*
233 * DKT 010817 - add support for V8 memory read/write and flash update
234 */
235static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2,
236 b2c2_usb_request_t req, u8 page, u16 wAddress,
237 u16 buflen, u8 *pbBuffer)
238{
239 u8 dwRequestType;
240 u16 wIndex;
241 int nWaitTime,pipe,len;
242
243 wIndex = page << 8;
244
245 switch (req) {
246 case B2C2_USB_READ_V8_MEM:
247 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
248 dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
249 pipe = B2C2_USB_CTRL_PIPE_IN;
250 break;
251 case B2C2_USB_WRITE_V8_MEM:
252 wIndex |= pbBuffer[0];
253 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
254 dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
255 pipe = B2C2_USB_CTRL_PIPE_OUT;
256 break;
257 case B2C2_USB_FLASH_BLOCK:
258 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
259 dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
260 pipe = B2C2_USB_CTRL_PIPE_OUT;
261 break;
262 default:
263 deb_info("unsupported request for v8_mem_req %x.\n",req);
264 return -EINVAL;
265 }
266 len = usb_control_msg(b2c2->udev,pipe,
267 req,
268 dwRequestType,
269 wAddress,
270 wIndex,
271 pbBuffer,
272 buflen,
273 nWaitTime * 1000);
274 return len == buflen ? 0 : -EIO;
275}
276
277static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2,
278 b2c2_usb_request_t req, b2c2_usb_i2c_function_t func,
279 u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf)
280{
281 u16 wValue, wIndex;
282 int nWaitTime,pipe,len;
283 u8 dwRequestType;
284
285 switch (func) {
286 case USB_FUNC_I2C_WRITE:
287 case USB_FUNC_I2C_MULTIWRITE:
288 case USB_FUNC_I2C_REPEATWRITE:
289 /* DKT 020208 - add this to support special case of DiSEqC */
290 case USB_FUNC_I2C_CHECKWRITE:
291 pipe = B2C2_USB_CTRL_PIPE_OUT;
292 nWaitTime = 2;
293 dwRequestType = (u8) RTYPE_GENERIC;
294 break;
295 case USB_FUNC_I2C_READ:
296 case USB_FUNC_I2C_REPEATREAD:
297 pipe = B2C2_USB_CTRL_PIPE_IN;
298 nWaitTime = 2;
299 dwRequestType = (u8) RTYPE_GENERIC;
300 break;
301 default:
302 deb_info("unsupported function for i2c_req %x\n",func);
303 return -EINVAL;
304 }
305 wValue = (func << 8 ) | port;
306 wIndex = (chipaddr << 8 ) | addr;
307
308 len = usb_control_msg(b2c2->udev,pipe,
309 req,
310 dwRequestType,
311 addr,
312 wIndex,
313 buf,
314 buflen,
315 nWaitTime * 1000);
316 return len == buflen ? 0 : -EIO;
317}
318
319int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set,
320 b2c2_usb_utility_function_t func, u8 extra, u16 wIndex,
321 u16 buflen, u8 *pvBuffer)
322{
323 u16 wValue;
324 int nWaitTime = 2,
325 pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
326 len;
327
328 wValue = (func << 8) | extra;
329
330 len = usb_control_msg(b2c2->udev,pipe,
331 B2C2_USB_UTILITY,
332 (u8) RTYPE_GENERIC,
333 wValue,
334 wIndex,
335 pvBuffer,
336 buflen,
337 nWaitTime * 1000);
338 return len == buflen ? 0 : -EIO;
339}
340
341
342
343static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs)
344{
345 u32 r0,r1,r2,r3;
346 r0 = r1 = r2 = r3 = 0;
347 r0 = b2c2_usb_read_dw(b2c2,offs);
348 r1 = b2c2_usb_read_dw(b2c2,offs + 0x04);
349 r2 = b2c2_usb_read_dw(b2c2,offs + 0x08);
350 r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c);
351 deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3);
352}
353
354static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs)
355{
356 struct usb_b2c2_usb *b2c2 = urb->context;
357 deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length);
358
359// urb_submit_urb(urb,GFP_ATOMIC); enable for real action
360}
361
362static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2)
363{
364 int i;
365 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
366 if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */
367 deb_info("unlinking/killing urb no. %d\n",i);
368#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
369 usb_unlink_urb(b2c2->iso_urb[i]);
370#else
371 usb_kill_urb(b2c2->iso_urb[i]);
372#endif
373 usb_free_urb(b2c2->iso_urb[i]);
374 }
375
376 if (b2c2->iso_buffer != NULL)
377 pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle);
378
379}
380
381static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
382{
383 u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
384 int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
385 int buffer_offset = 0;
386
387 deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
388 B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
389
390 b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle);
391 if (b2c2->iso_buffer == NULL)
392 return -ENOMEM;
393 memset(b2c2->iso_buffer, 0, bufsize);
394 b2c2->buffer_size = bufsize;
395
396 /* creating iso urbs */
397 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
398 if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
399 ret = -ENOMEM;
400 goto urb_error;
401 }
402 /* initialising and submitting iso urbs */
403 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
404 int frame_offset = 0;
405 struct urb *urb = b2c2->iso_urb[i];
406 deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
407
408 urb->dev = b2c2->udev;
409 urb->context = b2c2;
410 urb->complete = b2c2_urb_complete;
411 urb->pipe = B2C2_USB_DATA_PIPE;
412 urb->transfer_flags = URB_ISO_ASAP;
413 urb->interval = 1;
414 urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
415 urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
416 urb->transfer_buffer = b2c2->iso_buffer + buffer_offset;
417
418 buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
419 for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
420 deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
421 urb->iso_frame_desc[j].offset = frame_offset;
422 urb->iso_frame_desc[j].length = frame_size;
423 frame_offset += frame_size;
424 }
425
426 if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) {
427 err("submitting urb %d failed with %d.",i,ret);
428 goto urb_error;
429 }
430 deb_info("submitted urb no. %d.\n",i);
431 }
432
433 ret = 0;
434 goto success;
435urb_error:
436 b2c2_exit_usb(b2c2);
437success:
438 return ret;
439}
440
441static int b2c2_usb_probe(struct usb_interface *intf,
442 const struct usb_device_id *id)
443{
444 struct usb_device *udev = interface_to_usbdev(intf);
445 struct usb_b2c2_usb *b2c2 = NULL;
446 int ret;
447
448 b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL);
449 if (b2c2 == NULL) {
450 err("no memory");
451 return -ENOMEM;
452 }
453 b2c2->udev = udev;
454 b2c2->uintf = intf;
455
456 /* use the alternate setting with the larges buffer */
457 usb_set_interface(udev,0,1);
458
459 if ((ret = b2c2_init_usb(b2c2)))
460 goto usb_init_error;
461
462 usb_set_intfdata(intf,b2c2);
463
464 switch (udev->speed) {
465 case USB_SPEED_LOW:
466 err("cannot handle USB speed because it is to sLOW.");
467 break;
468 case USB_SPEED_FULL:
469 info("running at FULL speed.");
470 break;
471 case USB_SPEED_HIGH:
472 info("running at HIGH speed.");
473 break;
474 case USB_SPEED_UNKNOWN: /* fall through */
475 default:
476 err("cannot handle USB speed because it is unkown.");
477 break;
478 }
479
480 b2c2_dumpfourreg(b2c2,0x200);
481 b2c2_dumpfourreg(b2c2,0x300);
482 b2c2_dumpfourreg(b2c2,0x400);
483 b2c2_dumpfourreg(b2c2,0x700);
484
485
486 if (ret == 0)
487 info("%s successfully initialized and connected.",DRIVER_DESC);
488 else
489 info("%s error while loading driver (%d)",DRIVER_DESC,ret);
490
491 ret = 0;
492 goto success;
493
494usb_init_error:
495 kfree(b2c2);
496success:
497 return ret;
498}
499
500static void b2c2_usb_disconnect(struct usb_interface *intf)
501{
502 struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf);
503 usb_set_intfdata(intf,NULL);
504 if (b2c2 != NULL) {
505 b2c2_exit_usb(b2c2);
506 kfree(b2c2);
507 }
508 info("%s successfully deinitialized and disconnected.",DRIVER_DESC);
509
510}
511
512static struct usb_device_id b2c2_usb_table [] = {
513 { USB_DEVICE(0x0af7, 0x0101) }
514};
515
516/* usb specific object needed to register this driver with the usb subsystem */
517static struct usb_driver b2c2_usb_driver = {
518 .owner = THIS_MODULE,
519 .name = "dvb_b2c2_usb",
520 .probe = b2c2_usb_probe,
521 .disconnect = b2c2_usb_disconnect,
522 .id_table = b2c2_usb_table,
523};
524
525/* module stuff */
526static int __init b2c2_usb_init(void)
527{
528 int result;
529 if ((result = usb_register(&b2c2_usb_driver))) {
530 err("usb_register failed. Error number %d",result);
531 return result;
532 }
533
534 return 0;
535}
536
537static void __exit b2c2_usb_exit(void)
538{
539 /* deregister this driver from the USB subsystem */
540 usb_deregister(&b2c2_usb_driver);
541}
542
543module_init (b2c2_usb_init);
544module_exit (b2c2_usb_exit);
545
546MODULE_AUTHOR(DRIVER_AUTHOR);
547MODULE_DESCRIPTION(DRIVER_DESC);
548MODULE_LICENSE("GPL");
549MODULE_DEVICE_TABLE(usb, b2c2_usb_table);
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
new file mode 100644
index 000000000000..336c178fcd5f
--- /dev/null
+++ b/drivers/media/dvb/b2c2/skystar2.c
@@ -0,0 +1,2644 @@
1/*
2 * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
3 * based on the FlexCopII by B2C2,Inc.
4 *
5 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
6 *
7 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
8 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
9 * Vincenzo Di Massa, hawk.it at tiscalinet.it
10 *
11 * Converted to Linux coding style
12 * Misc reorganization, polishing, restyling
13 * Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
14 *
15 * Added hardware filtering support,
16 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
17 *
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (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 Lesser 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#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/delay.h>
37#include <linux/pci.h>
38#include <linux/init.h>
39#include <linux/version.h>
40
41#include <asm/io.h>
42
43#include "dvb_frontend.h"
44
45#include <linux/dvb/frontend.h>
46#include <linux/dvb/dmx.h>
47#include "dvb_demux.h"
48#include "dmxdev.h"
49#include "dvb_filter.h"
50#include "dvbdev.h"
51#include "demux.h"
52#include "dvb_net.h"
53#include "stv0299.h"
54#include "mt352.h"
55#include "mt312.h"
56#include "nxt2002.h"
57
58static int debug;
59static int enable_hw_filters = 2;
60
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
63module_param(enable_hw_filters, int, 0444);
64MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
65
66#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
67#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
68
69#define SIZE_OF_BUF_DMA1 0x3ac00
70#define SIZE_OF_BUF_DMA2 0x758
71
72#define MAX_N_HW_FILTERS (6+32)
73#define N_PID_SLOTS 256
74
75struct dmaq {
76 u32 bus_addr;
77 u32 head;
78 u32 tail;
79 u32 buffer_size;
80 u8 *buffer;
81};
82
83#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
84#define __iomem
85#endif
86
87struct adapter {
88 struct pci_dev *pdev;
89
90 u8 card_revision;
91 u32 b2c2_revision;
92 u32 pid_filter_max;
93 u32 mac_filter_max;
94 u32 irq;
95 void __iomem *io_mem;
96 unsigned long io_port;
97 u8 mac_addr[8];
98 u32 dw_sram_type;
99
100 struct dvb_adapter *dvb_adapter;
101 struct dvb_demux demux;
102 struct dmxdev dmxdev;
103 struct dmx_frontend hw_frontend;
104 struct dmx_frontend mem_frontend;
105 struct i2c_adapter i2c_adap;
106 struct dvb_net dvbnet;
107
108 struct semaphore i2c_sem;
109
110 struct dmaq dmaq1;
111 struct dmaq dmaq2;
112
113 u32 dma_ctrl;
114 u32 dma_status;
115
116 int capturing;
117
118 spinlock_t lock;
119
120 int useable_hw_filters;
121 u16 hw_pids[MAX_N_HW_FILTERS];
122 u16 pid_list[N_PID_SLOTS];
123 int pid_rc[N_PID_SLOTS]; // ref counters for the pids
124 int pid_count;
125 int whole_bandwidth_count;
126 u32 mac_filter;
127
128 struct dvb_frontend* fe;
129 int (*fe_sleep)(struct dvb_frontend* fe);
130};
131
132#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
133#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
134
135static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
136{
137 u32 tmp;
138
139 tmp = read_reg_dw(adapter, reg);
140 tmp = (tmp & ~zeromask) | orvalue;
141 write_reg_dw(adapter, reg, tmp);
142}
143
144/* i2c functions */
145static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
146{
147 int i;
148 u32 value;
149
150 write_reg_dw(adapter, 0x100, 0);
151 write_reg_dw(adapter, 0x100, command);
152
153 for (i = 0; i < retries; i++) {
154 value = read_reg_dw(adapter, 0x100);
155
156 if ((value & 0x40000000) == 0) {
157 if ((value & 0x81000000) == 0x80000000) {
158 if (buf != 0)
159 *buf = (value >> 0x10) & 0xff;
160
161 return 1;
162 }
163 } else {
164 write_reg_dw(adapter, 0x100, 0);
165 write_reg_dw(adapter, 0x100, command);
166 }
167 }
168
169 return 0;
170}
171
172/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
173static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
174{
175 *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
176
177 if (op != 0)
178 *command = *command | 0x03000000;
179 else
180 *command = *command | 0x01000000;
181}
182
183static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
184{
185 u32 command;
186 u32 value;
187
188 int result, i;
189
190 i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
191
192 result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
193
194 if ((result & 0xff) != 0) {
195 if (len > 1) {
196 value = read_reg_dw(adapter, 0x104);
197
198 for (i = 1; i < len; i++) {
199 buf[i] = value & 0xff;
200 value = value >> 8;
201 }
202 }
203 }
204
205 return result;
206}
207
208static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
209{
210 u32 command;
211 u32 value;
212 int i;
213
214 if (len > 1) {
215 value = 0;
216
217 for (i = len; i > 1; i--) {
218 value = value << 8;
219 value = value | buf[i - 1];
220 }
221
222 write_reg_dw(adapter, 0x104, value);
223 }
224
225 i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
226
227 return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
228}
229
230static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
231{
232 if (device == 0x20000000)
233 *ret = bus | ((addr >> 8) & 3);
234 else
235 *ret = bus;
236}
237
238static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
239{
240 u32 chipaddr;
241 u32 bytes_to_transfer;
242 u8 *start;
243
244 ddprintk("%s:\n", __FUNCTION__);
245
246 start = buf;
247
248 while (len != 0) {
249 bytes_to_transfer = len;
250
251 if (bytes_to_transfer > 4)
252 bytes_to_transfer = 4;
253
254 fixchipaddr(device, bus, addr, &chipaddr);
255
256 if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
257 return buf - start;
258
259 buf = buf + bytes_to_transfer;
260 addr = addr + bytes_to_transfer;
261 len = len - bytes_to_transfer;
262 };
263
264 return buf - start;
265}
266
267static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
268{
269 u32 chipaddr;
270 u32 bytes_to_transfer;
271 u8 *start;
272
273 ddprintk("%s:\n", __FUNCTION__);
274
275 start = buf;
276
277 while (len != 0) {
278 bytes_to_transfer = len;
279
280 if (bytes_to_transfer > 4)
281 bytes_to_transfer = 4;
282
283 fixchipaddr(device, bus, addr, &chipaddr);
284
285 if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
286 return buf - start;
287
288 buf = buf + bytes_to_transfer;
289 addr = addr + bytes_to_transfer;
290 len = len - bytes_to_transfer;
291 }
292
293 return buf - start;
294}
295
296static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
297{
298 struct adapter *tmp = i2c_get_adapdata(adapter);
299 int i, ret = 0;
300
301 if (down_interruptible(&tmp->i2c_sem))
302 return -ERESTARTSYS;
303
304 ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
305
306 for (i = 0; i < num; i++) {
307 ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
308 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
309 }
310
311 // read command
312 if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
313
314 ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
315
316 up(&tmp->i2c_sem);
317
318 if (ret != msgs[1].len) {
319 dprintk("%s: read error !\n", __FUNCTION__);
320
321 for (i = 0; i < 2; i++) {
322 dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
323 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
324 }
325
326 return -EREMOTEIO;
327 }
328
329 return num;
330 }
331 // write command
332 for (i = 0; i < num; i++) {
333
334 if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
335 return -EINVAL;
336
337 ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
338
339 up(&tmp->i2c_sem);
340
341 if (ret != msgs[0].len - 1) {
342 dprintk("%s: write error %i !\n", __FUNCTION__, ret);
343
344 dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
345 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
346
347 return -EREMOTEIO;
348 }
349
350 return num;
351 }
352
353 printk("%s: unknown command format !\n", __FUNCTION__);
354
355 return -EINVAL;
356}
357
358/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
359 but it seems that FlexCopII can work with more than one chip) */
360static void sram_set_net_dest(struct adapter *adapter, u8 dest)
361{
362 u32 tmp;
363
364 udelay(1000);
365
366 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
367
368 udelay(1000);
369
370 write_reg_dw(adapter, 0x714, tmp);
371 write_reg_dw(adapter, 0x714, tmp);
372
373 udelay(1000);
374
375 /* return value is never used? */
376/* return tmp; */
377}
378
379static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
380{
381 u32 tmp;
382
383 udelay(1000);
384
385 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
386
387 udelay(1000);
388 udelay(1000);
389
390 write_reg_dw(adapter, 0x714, tmp);
391 write_reg_dw(adapter, 0x714, tmp);
392
393 udelay(1000);
394
395 /* return value is never used? */
396/* return tmp; */
397}
398
399static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
400{
401 u32 tmp;
402
403 udelay(1000);
404
405 tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
406
407 udelay(1000);
408 udelay(1000);
409
410 write_reg_dw(adapter, 0x714, tmp);
411 write_reg_dw(adapter, 0x714, tmp);
412
413 udelay(1000);
414
415 /* return value is never used? */
416/* return tmp; */
417}
418
419static void sram_set_media_dest(struct adapter *adapter, u8 dest)
420{
421 u32 tmp;
422
423 udelay(1000);
424
425 tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
426
427 udelay(1000);
428 udelay(1000);
429
430 write_reg_dw(adapter, 0x714, tmp);
431 write_reg_dw(adapter, 0x714, tmp);
432
433 udelay(1000);
434
435 /* return value is never used? */
436/* return tmp; */
437}
438
439/* SRAM memory is accessed through a buffer register in the FlexCop
440 chip (0x700). This register has the following structure:
441 bits 0-14 : address
442 bit 15 : read/write flag
443 bits 16-23 : 8-bit word to write
444 bits 24-27 : = 4
445 bits 28-29 : memory bank selector
446 bit 31 : busy flag
447*/
448static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
449{
450 int i, retries;
451 u32 command;
452
453 for (i = 0; i < len; i++) {
454 command = bank | addr | 0x04000000 | (*buf << 0x10);
455
456 retries = 2;
457
458 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
459 mdelay(1);
460 retries--;
461 };
462
463 if (retries == 0)
464 printk("%s: SRAM timeout\n", __FUNCTION__);
465
466 write_reg_dw(adapter, 0x700, command);
467
468 buf++;
469 addr++;
470 }
471}
472
473static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
474{
475 int i, retries;
476 u32 command, value;
477
478 for (i = 0; i < len; i++) {
479 command = bank | addr | 0x04008000;
480
481 retries = 10000;
482
483 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
484 mdelay(1);
485 retries--;
486 };
487
488 if (retries == 0)
489 printk("%s: SRAM timeout\n", __FUNCTION__);
490
491 write_reg_dw(adapter, 0x700, command);
492
493 retries = 10000;
494
495 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
496 mdelay(1);
497 retries--;
498 };
499
500 if (retries == 0)
501 printk("%s: SRAM timeout\n", __FUNCTION__);
502
503 value = read_reg_dw(adapter, 0x700) >> 0x10;
504
505 *buf = (value & 0xff);
506
507 addr++;
508 buf++;
509 }
510}
511
512static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
513{
514 u32 bank;
515
516 bank = 0;
517
518 if (adapter->dw_sram_type == 0x20000) {
519 bank = (addr & 0x18000) << 0x0d;
520 }
521
522 if (adapter->dw_sram_type == 0x00000) {
523 if ((addr >> 0x0f) == 0)
524 bank = 0x20000000;
525 else
526 bank = 0x10000000;
527 }
528
529 flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
530}
531
532static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
533{
534 u32 bank;
535
536 bank = 0;
537
538 if (adapter->dw_sram_type == 0x20000) {
539 bank = (addr & 0x18000) << 0x0d;
540 }
541
542 if (adapter->dw_sram_type == 0x00000) {
543 if ((addr >> 0x0f) == 0)
544 bank = 0x20000000;
545 else
546 bank = 0x10000000;
547 }
548
549 flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
550}
551
552static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
553{
554 u32 length;
555
556 while (len != 0) {
557 length = len;
558
559 // check if the address range belongs to the same
560 // 32K memory chip. If not, the data is read from
561 // one chip at a time.
562 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
563 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
564 }
565
566 sram_read_chunk(adapter, addr, buf, length);
567
568 addr = addr + length;
569 buf = buf + length;
570 len = len - length;
571 }
572}
573
574static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
575{
576 u32 length;
577
578 while (len != 0) {
579 length = len;
580
581 // check if the address range belongs to the same
582 // 32K memory chip. If not, the data is written to
583 // one chip at a time.
584 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
585 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
586 }
587
588 sram_write_chunk(adapter, addr, buf, length);
589
590 addr = addr + length;
591 buf = buf + length;
592 len = len - length;
593 }
594}
595
596static void sram_set_size(struct adapter *adapter, u32 mask)
597{
598 write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
599}
600
601static void sram_init(struct adapter *adapter)
602{
603 u32 tmp;
604
605 tmp = read_reg_dw(adapter, 0x71c);
606
607 write_reg_dw(adapter, 0x71c, 1);
608
609 if (read_reg_dw(adapter, 0x71c) != 0) {
610 write_reg_dw(adapter, 0x71c, tmp);
611
612 adapter->dw_sram_type = tmp & 0x30000;
613
614 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
615
616 } else {
617
618 adapter->dw_sram_type = 0x10000;
619
620 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
621 }
622
623 /* return value is never used? */
624/* return adapter->dw_sram_type; */
625}
626
627static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
628{
629 u8 tmp1, tmp2;
630
631 dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
632
633 sram_set_size(adapter, mask);
634 sram_init(adapter);
635
636 tmp2 = 0xa5;
637 tmp1 = 0x4f;
638
639 sram_write(adapter, addr, &tmp2, 1);
640 sram_write(adapter, addr + 4, &tmp1, 1);
641
642 tmp2 = 0;
643
644 mdelay(20);
645
646 sram_read(adapter, addr, &tmp2, 1);
647 sram_read(adapter, addr, &tmp2, 1);
648
649 dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
650
651 if (tmp2 != 0xa5)
652 return 0;
653
654 tmp2 = 0x5a;
655 tmp1 = 0xf4;
656
657 sram_write(adapter, addr, &tmp2, 1);
658 sram_write(adapter, addr + 4, &tmp1, 1);
659
660 tmp2 = 0;
661
662 mdelay(20);
663
664 sram_read(adapter, addr, &tmp2, 1);
665 sram_read(adapter, addr, &tmp2, 1);
666
667 dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
668
669 if (tmp2 != 0x5a)
670 return 0;
671
672 return 1;
673}
674
675static u32 sram_length(struct adapter *adapter)
676{
677 if (adapter->dw_sram_type == 0x10000)
678 return 32768; // 32K
679 if (adapter->dw_sram_type == 0x00000)
680 return 65536; // 64K
681 if (adapter->dw_sram_type == 0x20000)
682 return 131072; // 128K
683
684 return 32768; // 32K
685}
686
687/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
688 - for 128K there are 4x32K chips at bank 0,1,2,3.
689 - for 64K there are 2x32K chips at bank 1,2.
690 - for 32K there is one 32K chip at bank 0.
691
692 FlexCop works only with one bank at a time. The bank is selected
693 by bits 28-29 of the 0x700 register.
694
695 bank 0 covers addresses 0x00000-0x07fff
696 bank 1 covers addresses 0x08000-0x0ffff
697 bank 2 covers addresses 0x10000-0x17fff
698 bank 3 covers addresses 0x18000-0x1ffff
699*/
700static int sram_detect_for_flex2(struct adapter *adapter)
701{
702 u32 tmp, tmp2, tmp3;
703
704 dprintk("%s:\n", __FUNCTION__);
705
706 tmp = read_reg_dw(adapter, 0x208);
707 write_reg_dw(adapter, 0x208, 0);
708
709 tmp2 = read_reg_dw(adapter, 0x71c);
710
711 dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
712
713 write_reg_dw(adapter, 0x71c, 1);
714
715 tmp3 = read_reg_dw(adapter, 0x71c);
716
717 dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
718
719 write_reg_dw(adapter, 0x71c, tmp2);
720
721 // check for internal SRAM ???
722 tmp3--;
723 if (tmp3 != 0) {
724 sram_set_size(adapter, 0x10000);
725 sram_init(adapter);
726 write_reg_dw(adapter, 0x208, tmp);
727
728 dprintk("%s: sram size = 32K\n", __FUNCTION__);
729
730 return 32;
731 }
732
733 if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
734 sram_set_size(adapter, 0x20000);
735 sram_init(adapter);
736 write_reg_dw(adapter, 0x208, tmp);
737
738 dprintk("%s: sram size = 128K\n", __FUNCTION__);
739
740 return 128;
741 }
742
743 if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
744 sram_set_size(adapter, 0x00000);
745 sram_init(adapter);
746 write_reg_dw(adapter, 0x208, tmp);
747
748 dprintk("%s: sram size = 64K\n", __FUNCTION__);
749
750 return 64;
751 }
752
753 if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
754 sram_set_size(adapter, 0x10000);
755 sram_init(adapter);
756 write_reg_dw(adapter, 0x208, tmp);
757
758 dprintk("%s: sram size = 32K\n", __FUNCTION__);
759
760 return 32;
761 }
762
763 sram_set_size(adapter, 0x10000);
764 sram_init(adapter);
765 write_reg_dw(adapter, 0x208, tmp);
766
767 dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
768
769 return 0;
770}
771
772static void sll_detect_sram_size(struct adapter *adapter)
773{
774 sram_detect_for_flex2(adapter);
775}
776
777/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
778/*
779static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
780{
781 return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
782}
783*/
784
785static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
786{
787 return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
788}
789
790static u8 calc_lrc(u8 *buf, int len)
791{
792 int i;
793 u8 sum;
794
795 sum = 0;
796
797 for (i = 0; i < len; i++)
798 sum = sum ^ buf[i];
799
800 return sum;
801}
802
803static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
804{
805 int i;
806
807 for (i = 0; i < retries; i++) {
808 if (eeprom_read(adapter, addr, buf, len) == len) {
809 if (calc_lrc(buf, len - 1) == buf[len - 1])
810 return 1;
811 }
812 }
813
814 return 0;
815}
816
817/*
818static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
819{
820 int i;
821
822 for (i = 0; i < retries; i++) {
823 if (eeprom_write(adapter, addr, wbuf, len) == len) {
824 if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
825 return 1;
826 }
827 }
828
829 return 0;
830}
831*/
832
833
834/* These functions could be used to unlock SkyStar2 cards. */
835
836/*
837static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
838{
839 u8 rbuf[20];
840 u8 wbuf[20];
841
842 if (len != 16)
843 return 0;
844
845 memcpy(wbuf, key, len);
846
847 wbuf[16] = 0;
848 wbuf[17] = 0;
849 wbuf[18] = 0;
850 wbuf[19] = calc_lrc(wbuf, 19);
851
852 return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
853}
854
855static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
856{
857 u8 buf[20];
858
859 if (len != 16)
860 return 0;
861
862 if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
863 return 0;
864
865 memcpy(key, buf, len);
866
867 return 1;
868}
869*/
870
871static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
872{
873 u8 tmp[8];
874
875 if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
876 if (type != 0) {
877 mac[0] = tmp[0];
878 mac[1] = tmp[1];
879 mac[2] = tmp[2];
880 mac[3] = 0xfe;
881 mac[4] = 0xff;
882 mac[5] = tmp[3];
883 mac[6] = tmp[4];
884 mac[7] = tmp[5];
885
886 } else {
887
888 mac[0] = tmp[0];
889 mac[1] = tmp[1];
890 mac[2] = tmp[2];
891 mac[3] = tmp[3];
892 mac[4] = tmp[4];
893 mac[5] = tmp[5];
894 }
895
896 return 1;
897
898 } else {
899
900 if (type == 0) {
901 memset(mac, 0, 6);
902
903 } else {
904
905 memset(mac, 0, 8);
906 }
907
908 return 0;
909 }
910}
911
912/*
913static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
914{
915 u8 tmp[8];
916
917 if (type != 0) {
918 tmp[0] = mac[0];
919 tmp[1] = mac[1];
920 tmp[2] = mac[2];
921 tmp[3] = mac[5];
922 tmp[4] = mac[6];
923 tmp[5] = mac[7];
924
925 } else {
926
927 tmp[0] = mac[0];
928 tmp[1] = mac[1];
929 tmp[2] = mac[2];
930 tmp[3] = mac[3];
931 tmp[4] = mac[4];
932 tmp[5] = mac[5];
933 }
934
935 tmp[6] = 0;
936 tmp[7] = calc_lrc(tmp, 7);
937
938 if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
939 return 1;
940
941 return 0;
942}
943*/
944
945/* PID filter */
946
947/* every flexcop has 6 "lower" hw PID filters */
948/* these are enabled by setting bits 0-5 of 0x208 */
949/* for the 32 additional filters we have to select one */
950/* of them through 0x310 and modify through 0x314 */
951/* op: 0=disable, 1=enable */
952static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
953{
954 dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
955 if (id <= 5) {
956 u32 mask = (0x00000001 << id);
957 write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
958 } else {
959 /* select */
960 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
961 /* modify */
962 write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
963 }
964}
965
966/* this sets the PID that should pass the specified filter */
967static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
968{
969 dprintk("%s: id=%d pid=%d\n", __FUNCTION__, id, pid);
970 if (id <= 5) {
971 u32 adr = 0x300 + ((id & 6) << 1);
972 int shift = (id & 1) ? 16 : 0;
973 dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
974 write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
975 } else {
976 /* select */
977 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
978 /* modify */
979 write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
980 }
981}
982
983
984/*
985static void filter_enable_null_filter(struct adapter *adapter, u32 op)
986{
987 dprintk("%s: op=%x\n", __FUNCTION__, op);
988
989 write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
990}
991*/
992
993static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
994{
995 dprintk("%s: op=%x\n", __FUNCTION__, op);
996
997 write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
998}
999
1000
1001static void ctrl_enable_mac(struct adapter *adapter, u32 op)
1002{
1003 write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
1004}
1005
1006static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
1007{
1008 u32 tmp1, tmp2;
1009
1010 tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
1011 tmp2 = (mac[5] << 0x08) | mac[4];
1012
1013 write_reg_dw(adapter, 0x418, tmp1);
1014 write_reg_dw(adapter, 0x41c, tmp2);
1015
1016 return 0;
1017}
1018
1019/*
1020static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
1021{
1022 if (op != 0) {
1023 write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
1024 adapter->mac_filter = 1;
1025 } else {
1026 if (adapter->mac_filter != 0) {
1027 adapter->mac_filter = 0;
1028 write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
1029 }
1030 }
1031}
1032*/
1033
1034/*
1035static void check_null_filter_enable(struct adapter *adapter)
1036{
1037 filter_enable_null_filter(adapter, 1);
1038 filter_enable_mask_filter(adapter, 1);
1039}
1040*/
1041
1042static void pid_set_group_pid(struct adapter *adapter, u16 pid)
1043{
1044 u32 value;
1045
1046 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1047 value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
1048 write_reg_dw(adapter, 0x30c, value);
1049}
1050
1051static void pid_set_group_mask(struct adapter *adapter, u16 pid)
1052{
1053 u32 value;
1054
1055 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1056 value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
1057 write_reg_dw(adapter, 0x30c, value);
1058}
1059
1060/*
1061static int pid_get_group_pid(struct adapter *adapter)
1062{
1063 return read_reg_dw(adapter, 0x30c) & 0x00001fff;
1064}
1065
1066static int pid_get_group_mask(struct adapter *adapter)
1067{
1068 return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
1069}
1070*/
1071
1072/*
1073static void reset_hardware_pid_filter(struct adapter *adapter)
1074{
1075 pid_set_stream1_pid(adapter, 0x1fff);
1076
1077 pid_set_stream2_pid(adapter, 0x1fff);
1078 filter_enable_stream2_filter(adapter, 0);
1079
1080 pid_set_pcr_pid(adapter, 0x1fff);
1081 filter_enable_pcr_filter(adapter, 0);
1082
1083 pid_set_pmt_pid(adapter, 0x1fff);
1084 filter_enable_pmt_filter(adapter, 0);
1085
1086 pid_set_ecm_pid(adapter, 0x1fff);
1087 filter_enable_ecm_filter(adapter, 0);
1088
1089 pid_set_emm_pid(adapter, 0x1fff);
1090 filter_enable_emm_filter(adapter, 0);
1091}
1092*/
1093
1094static void init_pids(struct adapter *adapter)
1095{
1096 int i;
1097
1098 adapter->pid_count = 0;
1099 adapter->whole_bandwidth_count = 0;
1100 for (i = 0; i < adapter->useable_hw_filters; i++) {
1101 dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
1102 adapter->hw_pids[i] = 0x1fff;
1103 pid_set_hw_pid(adapter, i, 0x1fff);
1104}
1105
1106 pid_set_group_pid(adapter, 0);
1107 pid_set_group_mask(adapter, 0x1fe0);
1108}
1109
1110static void open_whole_bandwidth(struct adapter *adapter)
1111{
1112 dprintk("%s:\n", __FUNCTION__);
1113 pid_set_group_pid(adapter, 0);
1114 pid_set_group_mask(adapter, 0);
1115/*
1116 filter_enable_mask_filter(adapter, 1);
1117*/
1118}
1119
1120static void close_whole_bandwidth(struct adapter *adapter)
1121{
1122 dprintk("%s:\n", __FUNCTION__);
1123 pid_set_group_pid(adapter, 0);
1124 pid_set_group_mask(adapter, 0x1fe0);
1125/*
1126 filter_enable_mask_filter(adapter, 1);
1127*/
1128}
1129
1130static void whole_bandwidth_inc(struct adapter *adapter)
1131{
1132 if (adapter->whole_bandwidth_count++ == 0)
1133 open_whole_bandwidth(adapter);
1134}
1135
1136static void whole_bandwidth_dec(struct adapter *adapter)
1137{
1138 if (--adapter->whole_bandwidth_count <= 0)
1139 close_whole_bandwidth(adapter);
1140}
1141
1142/* The specified PID has to be let through the
1143 hw filters.
1144 We try to allocate an hardware filter and open whole
1145 bandwidth when allocation is impossible.
1146 All pids<=0x1f pass through the group filter.
1147 Returns 1 on success, -1 on error */
1148static int add_hw_pid(struct adapter *adapter, u16 pid)
1149{
1150 int i;
1151
1152 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1153
1154 if (pid <= 0x1f)
1155 return 1;
1156
1157 /* we can't use a filter for 0x2000, so no search */
1158 if (pid != 0x2000) {
1159 /* find an unused hardware filter */
1160 for (i = 0; i < adapter->useable_hw_filters; i++) {
1161 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1162 if (adapter->hw_pids[i] == 0x1fff) {
1163 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1164 adapter->hw_pids[i] = pid;
1165 pid_set_hw_pid(adapter, i, pid);
1166 filter_enable_hw_filter(adapter, i, 1);
1167 return 1;
1168 }
1169 }
1170 }
1171 /* if we have not used a filter, this pid depends on whole bandwidth */
1172 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1173 whole_bandwidth_inc(adapter);
1174 return 1;
1175 }
1176
1177/* returns -1 if the pid was not present in the filters */
1178static int remove_hw_pid(struct adapter *adapter, u16 pid)
1179{
1180 int i;
1181
1182 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1183
1184 if (pid <= 0x1f)
1185 return 1;
1186
1187 /* we can't use a filter for 0x2000, so no search */
1188 if (pid != 0x2000) {
1189 for (i = 0; i < adapter->useable_hw_filters; i++) {
1190 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1191 if (adapter->hw_pids[i] == pid) { // find the pid slot
1192 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1193 adapter->hw_pids[i] = 0x1fff;
1194 pid_set_hw_pid(adapter, i, 0x1fff);
1195 filter_enable_hw_filter(adapter, i, 0);
1196 return 1;
1197 }
1198 }
1199 }
1200 /* if we have not used a filter, this pid depended on whole bandwith */
1201 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1202 whole_bandwidth_dec(adapter);
1203 return 1;
1204 }
1205
1206/* Adds a PID to the filters.
1207 Adding a pid more than once is possible, we keep reference counts.
1208 Whole stream available through pid==0x2000.
1209 Returns 1 on success, -1 on error */
1210static int add_pid(struct adapter *adapter, u16 pid)
1211{
1212 int i;
1213
1214 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1215
1216 if (pid > 0x1ffe && pid != 0x2000)
1217 return -1;
1218
1219 // check if the pid is already present
1220 for (i = 0; i < adapter->pid_count; i++)
1221 if (adapter->pid_list[i] == pid) {
1222 adapter->pid_rc[i]++; // increment ref counter
1223 return 1;
1224 }
1225
1226 if (adapter->pid_count == N_PID_SLOTS)
1227 return -1; // no more pids can be added
1228 adapter->pid_list[adapter->pid_count] = pid; // register pid
1229 adapter->pid_rc[adapter->pid_count] = 1;
1230 adapter->pid_count++;
1231 // hardware setting
1232 add_hw_pid(adapter, pid);
1233
1234 return 1;
1235 }
1236
1237/* Removes a PID from the filters. */
1238static int remove_pid(struct adapter *adapter, u16 pid)
1239{
1240 int i;
1241
1242 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1243
1244 if (pid > 0x1ffe && pid != 0x2000)
1245 return -1;
1246
1247 // check if the pid is present (it must be!)
1248 for (i = 0; i < adapter->pid_count; i++) {
1249 if (adapter->pid_list[i] == pid) {
1250 adapter->pid_rc[i]--;
1251 if (adapter->pid_rc[i] <= 0) {
1252 // remove from the list
1253 adapter->pid_count--;
1254 adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
1255 adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
1256 // hardware setting
1257 remove_hw_pid(adapter, pid);
1258 }
1259 return 1;
1260 }
1261 }
1262
1263 return -1;
1264}
1265
1266
1267/* dma & irq */
1268static void ctrl_enable_smc(struct adapter *adapter, u32 op)
1269{
1270 write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
1271}
1272
1273static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
1274{
1275 adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
1276
1277 if (flag1 == 0) {
1278 if (flag2 == 0)
1279 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
1280 else
1281 adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
1282
1283 if (flag3 == 0)
1284 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
1285 else
1286 adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
1287
1288 } else {
1289
1290 if (flag2 == 0)
1291 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
1292 else
1293 adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
1294
1295 if (flag3 == 0)
1296 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
1297 else
1298 adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
1299 }
1300}
1301
1302static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
1303{
1304 u32 value;
1305
1306 value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
1307
1308 if (op != 0)
1309 value = value | (adapter->dma_ctrl & 0x000f0000);
1310
1311 write_reg_dw(adapter, 0x208, value);
1312}
1313
1314/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
1315 system memory.
1316
1317 The DMA1 buffer is divided in 2 subbuffers of equal size.
1318 FlexCopII will transfer TS data to one subbuffer, signal an interrupt
1319 when the subbuffer is full and continue fillig the second subbuffer.
1320
1321 For DMA1:
1322 subbuffer size in 32-bit words is stored in the first 24 bits of
1323 register 0x004. The last 8 bits of register 0x004 contain the number
1324 of subbuffers.
1325
1326 the first 30 bits of register 0x000 contain the address of the first
1327 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1328 when dma1 is enabled.
1329
1330 the first 30 bits of register 0x00c contain the address of the second
1331 subbuffer. the last 2 bits contain 1.
1332
1333 register 0x008 will contain the address of the subbuffer that was filled
1334 with TS data, when FlexCopII will generate an interrupt.
1335
1336 For DMA2:
1337 subbuffer size in 32-bit words is stored in the first 24 bits of
1338 register 0x014. The last 8 bits of register 0x014 contain the number
1339 of subbuffers.
1340
1341 the first 30 bits of register 0x010 contain the address of the first
1342 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1343 when dma1 is enabled.
1344
1345 the first 30 bits of register 0x01c contain the address of the second
1346 subbuffer. the last 2 bits contain 1.
1347
1348 register 0x018 contains the address of the subbuffer that was filled
1349 with TS data, when FlexCopII generates an interrupt.
1350*/
1351static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
1352{
1353 u32 subbuffers, subbufsize, subbuf0, subbuf1;
1354
1355 if (dma_channel == 0) {
1356 dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
1357
1358 subbuffers = 2;
1359
1360 subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
1361
1362 subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
1363
1364 subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
1365
1366 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1367 udelay(1000);
1368 write_reg_dw(adapter, 0x000, subbuf0);
1369
1370 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1371 udelay(1000);
1372 write_reg_dw(adapter, 0x004, subbufsize);
1373
1374 dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
1375 udelay(1000);
1376 write_reg_dw(adapter, 0x00c, subbuf1);
1377
1378 dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
1379 write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
1380 udelay(1000);
1381
1382 dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
1383
1384 irq_dma_enable_disable_irq(adapter, 1);
1385
1386 sram_set_media_dest(adapter, 1);
1387 sram_set_net_dest(adapter, 1);
1388 sram_set_cai_dest(adapter, 2);
1389 sram_set_cao_dest(adapter, 2);
1390 }
1391
1392 if (dma_channel == 1) {
1393 dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
1394
1395 subbuffers = 2;
1396
1397 subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
1398
1399 subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
1400
1401 subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
1402
1403 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1404 udelay(1000);
1405 write_reg_dw(adapter, 0x010, subbuf0);
1406
1407 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1408 udelay(1000);
1409 write_reg_dw(adapter, 0x014, subbufsize);
1410
1411 dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
1412 udelay(1000);
1413 write_reg_dw(adapter, 0x01c, subbuf1);
1414
1415 sram_set_cai_dest(adapter, 2);
1416 }
1417
1418 return 0;
1419}
1420
1421static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
1422{
1423 if (op == 0) {
1424 write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
1425 adapter->dma_status = adapter->dma_status & ~0x00000004;
1426 } else {
1427 write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
1428 adapter->dma_status = adapter->dma_status | 0x00000004;
1429 }
1430}
1431
1432/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
1433 bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
1434*/
1435static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
1436{
1437 u32 dma_enable, dma1_enable, dma2_enable;
1438
1439 dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
1440
1441 if (start_stop == 1) {
1442 dprintk("%s: starting dma\n", __FUNCTION__);
1443
1444 dma1_enable = 0;
1445 dma2_enable = 0;
1446
1447 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
1448 adapter->dma_status = adapter->dma_status | 1;
1449 dma1_enable = 1;
1450 }
1451
1452 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
1453 adapter->dma_status = adapter->dma_status | 2;
1454 dma2_enable = 1;
1455 }
1456 // enable dma1 and dma2
1457 if ((dma1_enable == 1) && (dma2_enable == 1)) {
1458 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1459 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1460 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1461
1462 ctrl_enable_receive_data(adapter, 1);
1463
1464 return;
1465 }
1466 // enable dma1
1467 if ((dma1_enable == 1) && (dma2_enable == 0)) {
1468 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1469 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1470
1471 ctrl_enable_receive_data(adapter, 1);
1472
1473 return;
1474 }
1475 // enable dma2
1476 if ((dma1_enable == 0) && (dma2_enable == 1)) {
1477 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1478
1479 ctrl_enable_receive_data(adapter, 1);
1480
1481 return;
1482 }
1483 // start dma
1484 if ((dma1_enable == 0) && (dma2_enable == 0)) {
1485 ctrl_enable_receive_data(adapter, 1);
1486
1487 return;
1488 }
1489
1490 } else {
1491
1492 dprintk("%s: stopping dma\n", __FUNCTION__);
1493
1494 dma_enable = adapter->dma_status & 0x00000003;
1495
1496 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
1497 dma_enable = dma_enable & 0xfffffffe;
1498 }
1499
1500 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
1501 dma_enable = dma_enable & 0xfffffffd;
1502 }
1503 //stop dma
1504 if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
1505 ctrl_enable_receive_data(adapter, 0);
1506
1507 udelay(3000);
1508 }
1509 //disable dma1
1510 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
1511 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
1512 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1513
1514 adapter->dma_status = adapter->dma_status & ~0x00000001;
1515 }
1516 //disable dma2
1517 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
1518 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
1519
1520 adapter->dma_status = adapter->dma_status & ~0x00000002;
1521 }
1522 }
1523}
1524
1525static void open_stream(struct adapter *adapter, u16 pid)
1526{
1527 u32 dma_mask;
1528
1529 ++adapter->capturing;
1530
1531 filter_enable_mask_filter(adapter, 1);
1532
1533 add_pid(adapter, pid);
1534
1535 dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1536
1537 if ((adapter->dma_status & 7) != 7) {
1538 dma_mask = 0;
1539
1540 if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
1541 dma_mask = dma_mask | 1;
1542
1543 adapter->dmaq1.head = 0;
1544 adapter->dmaq1.tail = 0;
1545
1546 memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
1547 }
1548
1549 if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
1550 dma_mask = dma_mask | 2;
1551
1552 adapter->dmaq2.head = 0;
1553 adapter->dmaq2.tail = 0;
1554 }
1555
1556 if (dma_mask != 0) {
1557 irq_dma_enable_disable_irq(adapter, 1);
1558
1559 dma_start_stop(adapter, dma_mask, 1);
1560 }
1561 }
1562}
1563
1564static void close_stream(struct adapter *adapter, u16 pid)
1565{
1566 if (adapter->capturing > 0)
1567 --adapter->capturing;
1568
1569 dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1570
1571 if (adapter->capturing == 0) {
1572 u32 dma_mask = 0;
1573
1574 if ((adapter->dma_status & 1) != 0)
1575 dma_mask = dma_mask | 0x00000001;
1576 if ((adapter->dma_status & 2) != 0)
1577 dma_mask = dma_mask | 0x00000002;
1578
1579 if (dma_mask != 0) {
1580 dma_start_stop(adapter, dma_mask, 0);
1581 }
1582 }
1583 remove_pid(adapter, pid);
1584}
1585
1586static void interrupt_service_dma1(struct adapter *adapter)
1587{
1588 struct dvb_demux *dvbdmx = &adapter->demux;
1589
1590 int n_cur_dma_counter;
1591 u32 n_num_bytes_parsed;
1592 u32 n_num_new_bytes_transferred;
1593 u32 dw_default_packet_size = 188;
1594 u8 gb_tmp_buffer[188];
1595 u8 *pb_dma_buf_cur_pos;
1596
1597 n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
1598 n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
1599
1600 if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
1601 dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
1602 return;
1603 }
1604
1605 adapter->dmaq1.head = n_cur_dma_counter;
1606
1607 if (adapter->dmaq1.tail <= n_cur_dma_counter) {
1608 n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
1609
1610 } else {
1611
1612 n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
1613 }
1614
1615 ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
1616 ddprintk("%s: dmaq1.tail = %d\n", __FUNCTION__, adapter->dmaq1.tail);
1617 ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
1618
1619 if (n_num_new_bytes_transferred < dw_default_packet_size)
1620 return;
1621
1622 n_num_bytes_parsed = 0;
1623
1624 while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
1625 pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
1626
1627 if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
1628 memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
1629 adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
1630 memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
1631 (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
1632
1633 pb_dma_buf_cur_pos = gb_tmp_buffer;
1634 }
1635
1636 if (adapter->capturing != 0) {
1637 dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
1638 }
1639
1640 n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
1641
1642 adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
1643
1644 if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
1645 adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
1646 };
1647}
1648
1649static void interrupt_service_dma2(struct adapter *adapter)
1650{
1651 printk("%s:\n", __FUNCTION__);
1652}
1653
1654static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
1655{
1656 struct adapter *tmp = dev_id;
1657
1658 u32 value;
1659
1660 ddprintk("%s:\n", __FUNCTION__);
1661
1662 spin_lock_irq(&tmp->lock);
1663
1664 if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
1665 spin_unlock_irq(&tmp->lock);
1666 return IRQ_NONE;
1667 }
1668
1669 while (value != 0) {
1670 if ((value & 0x03) != 0)
1671 interrupt_service_dma1(tmp);
1672 if ((value & 0x0c) != 0)
1673 interrupt_service_dma2(tmp);
1674 value = read_reg_dw(tmp, 0x20c) & 0x0f;
1675 }
1676
1677 spin_unlock_irq(&tmp->lock);
1678 return IRQ_HANDLED;
1679}
1680
1681static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
1682 int size, int dmaq_offset)
1683{
1684 struct pci_dev *pdev = adapter->pdev;
1685 dma_addr_t dma_addr;
1686
1687 dmaq->head = 0;
1688 dmaq->tail = 0;
1689
1690 dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
1691 if (!dmaq->buffer)
1692 return -ENOMEM;
1693
1694 dmaq->bus_addr = dma_addr;
1695 dmaq->buffer_size = size;
1696
1697 dma_init_dma(adapter, dmaq_offset);
1698
1699 ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
1700 __FUNCTION__, dmaq->buffer, size);
1701
1702 return 0;
1703 }
1704
1705static int init_dma_queue(struct adapter *adapter)
1706{
1707 struct {
1708 struct dmaq *dmaq;
1709 u32 dma_status;
1710 int size;
1711 } dmaq_desc[] = {
1712 { &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
1713 { &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
1714 }, *p = dmaq_desc;
1715 int i;
1716
1717 for (i = 0; i < 2; i++, p++) {
1718 if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
1719 adapter->dma_status &= ~p->dma_status;
1720 else
1721 adapter->dma_status |= p->dma_status;
1722 }
1723 return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
1724}
1725
1726static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
1727{
1728 if (dmaq->buffer) {
1729 pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
1730 dmaq->buffer, dmaq->bus_addr);
1731 memset(dmaq, 0, sizeof(*dmaq));
1732 }
1733}
1734
1735static void free_dma_queue(struct adapter *adapter)
1736{
1737 struct dmaq *dmaq[] = {
1738 &adapter->dmaq1,
1739 &adapter->dmaq2,
1740 NULL
1741 }, **p;
1742
1743 for (p = dmaq; *p; p++)
1744 free_dma_queue_one(adapter, *p);
1745 }
1746
1747static void release_adapter(struct adapter *adapter)
1748{
1749 struct pci_dev *pdev = adapter->pdev;
1750
1751 iounmap(adapter->io_mem);
1752 pci_disable_device(pdev);
1753 pci_release_region(pdev, 0);
1754 pci_release_region(pdev, 1);
1755}
1756
1757static void free_adapter_object(struct adapter *adapter)
1758{
1759 dprintk("%s:\n", __FUNCTION__);
1760
1761 close_stream(adapter, 0);
1762 free_irq(adapter->irq, adapter);
1763 free_dma_queue(adapter);
1764 release_adapter(adapter);
1765 kfree(adapter);
1766}
1767
1768static struct pci_driver skystar2_pci_driver;
1769
1770static int claim_adapter(struct adapter *adapter)
1771{
1772 struct pci_dev *pdev = adapter->pdev;
1773 u16 var;
1774 int ret;
1775
1776 ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
1777 if (ret < 0)
1778 goto out;
1779
1780 ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
1781 if (ret < 0)
1782 goto err_pci_release_1;
1783
1784 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
1785
1786 dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
1787
1788 ret = pci_enable_device(pdev);
1789 if (ret < 0)
1790 goto err_pci_release_0;
1791
1792 pci_read_config_word(pdev, 4, &var);
1793
1794 if ((var & 4) == 0)
1795 pci_set_master(pdev);
1796
1797 adapter->io_port = pdev->resource[1].start;
1798
1799 adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
1800
1801 if (!adapter->io_mem) {
1802 dprintk("%s: can not map io memory\n", __FUNCTION__);
1803 ret = -EIO;
1804 goto err_pci_disable;
1805 }
1806
1807 dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
1808
1809 ret = 1;
1810out:
1811 return ret;
1812
1813err_pci_disable:
1814 pci_disable_device(pdev);
1815err_pci_release_0:
1816 pci_release_region(pdev, 0);
1817err_pci_release_1:
1818 pci_release_region(pdev, 1);
1819 goto out;
1820}
1821
1822/*
1823static int sll_reset_flexcop(struct adapter *adapter)
1824{
1825 write_reg_dw(adapter, 0x208, 0);
1826 write_reg_dw(adapter, 0x210, 0xb2ff);
1827
1828 return 0;
1829}
1830*/
1831
1832static void decide_how_many_hw_filters(struct adapter *adapter)
1833{
1834 int hw_filters;
1835 int mod_option_hw_filters;
1836
1837 // FlexCop IIb & III have 6+32 hw filters
1838 // FlexCop II has 6 hw filters, every other should have at least 6
1839 switch (adapter->b2c2_revision) {
1840 case 0x82: /* II */
1841 hw_filters = 6;
1842 break;
1843 case 0xc3: /* IIB */
1844 hw_filters = 6 + 32;
1845 break;
1846 case 0xc0: /* III */
1847 hw_filters = 6 + 32;
1848 break;
1849 default:
1850 hw_filters = 6;
1851 break;
1852 }
1853 printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
1854
1855 mod_option_hw_filters = 0;
1856 if (enable_hw_filters >= 1)
1857 mod_option_hw_filters += 6;
1858 if (enable_hw_filters >= 2)
1859 mod_option_hw_filters += 32;
1860
1861 if (mod_option_hw_filters >= hw_filters) {
1862 adapter->useable_hw_filters = hw_filters;
1863 } else {
1864 adapter->useable_hw_filters = mod_option_hw_filters;
1865 printk(", but only %d will be used because of module option", mod_option_hw_filters);
1866 }
1867 printk("\n");
1868 dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
1869}
1870
1871static int driver_initialize(struct pci_dev *pdev)
1872{
1873 struct adapter *adapter;
1874 u32 tmp;
1875 int ret = -ENOMEM;
1876
1877 adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
1878 if (!adapter) {
1879 dprintk("%s: out of memory!\n", __FUNCTION__);
1880 goto out;
1881 }
1882
1883 memset(adapter, 0, sizeof(struct adapter));
1884
1885 pci_set_drvdata(pdev,adapter);
1886
1887 adapter->pdev = pdev;
1888 adapter->irq = pdev->irq;
1889
1890 ret = claim_adapter(adapter);
1891 if (ret < 0)
1892 goto err_kfree;
1893
1894 irq_dma_enable_disable_irq(adapter, 0);
1895
1896 ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
1897 if (ret < 0) {
1898 dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
1899 goto err_release_adapter;
1900 }
1901
1902 read_reg_dw(adapter, 0x208);
1903 write_reg_dw(adapter, 0x208, 0);
1904 write_reg_dw(adapter, 0x210, 0xb2ff);
1905 write_reg_dw(adapter, 0x208, 0x40);
1906
1907 ret = init_dma_queue(adapter);
1908 if (ret < 0)
1909 goto err_free_irq;
1910
1911 adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
1912
1913 switch (adapter->b2c2_revision) {
1914 case 0x82:
1915 printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
1916 break;
1917 case 0xc3:
1918 printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
1919 break;
1920 case 0xc0:
1921 printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
1922 break;
1923 default:
1924 printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
1925 printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
1926 ret = -ENODEV;
1927 goto err_free_dma_queue;
1928 }
1929
1930 decide_how_many_hw_filters(adapter);
1931
1932 init_pids(adapter);
1933
1934 tmp = read_reg_dw(adapter, 0x204);
1935
1936 write_reg_dw(adapter, 0x204, 0);
1937 mdelay(20);
1938
1939 write_reg_dw(adapter, 0x204, tmp);
1940 mdelay(10);
1941
1942 tmp = read_reg_dw(adapter, 0x308);
1943 write_reg_dw(adapter, 0x308, 0x4000 | tmp);
1944
1945 adapter->dw_sram_type = 0x10000;
1946
1947 sll_detect_sram_size(adapter);
1948
1949 dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
1950
1951 sram_set_media_dest(adapter, 1);
1952 sram_set_net_dest(adapter, 1);
1953
1954 ctrl_enable_smc(adapter, 0);
1955
1956 sram_set_cai_dest(adapter, 2);
1957 sram_set_cao_dest(adapter, 2);
1958
1959 dma_enable_disable_irq(adapter, 1, 0, 0);
1960
1961 if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
1962 printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
1963 adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
1964 adapter->mac_addr[6], adapter->mac_addr[7]
1965 );
1966
1967 ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
1968 ctrl_enable_mac(adapter, 1);
1969 }
1970
1971 spin_lock_init(&adapter->lock);
1972
1973out:
1974 return ret;
1975
1976err_free_dma_queue:
1977 free_dma_queue(adapter);
1978err_free_irq:
1979 free_irq(pdev->irq, adapter);
1980err_release_adapter:
1981 release_adapter(adapter);
1982err_kfree:
1983 pci_set_drvdata(pdev, NULL);
1984 kfree(adapter);
1985 goto out;
1986}
1987
1988static void driver_halt(struct pci_dev *pdev)
1989{
1990 struct adapter *adapter = pci_get_drvdata(pdev);
1991
1992 irq_dma_enable_disable_irq(adapter, 0);
1993
1994 ctrl_enable_receive_data(adapter, 0);
1995
1996 free_adapter_object(adapter);
1997
1998 pci_set_drvdata(pdev, NULL);
1999}
2000
2001static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
2002{
2003 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2004 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2005
2006 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2007
2008 open_stream(adapter, dvbdmxfeed->pid);
2009
2010 return 0;
2011}
2012
2013static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
2014{
2015 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2016 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2017
2018 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2019
2020 close_stream(adapter, dvbdmxfeed->pid);
2021
2022 return 0;
2023}
2024
2025/* lnb control */
2026static void set_tuner_tone(struct adapter *adapter, u8 tone)
2027{
2028 u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
2029 u16 ax;
2030
2031 dprintk("%s: %u\n", __FUNCTION__, tone);
2032
2033 switch (tone) {
2034 case 1:
2035 ax = wz_half_period_for_45_mhz[0];
2036 break;
2037 case 2:
2038 ax = wz_half_period_for_45_mhz[1];
2039 break;
2040 case 3:
2041 ax = wz_half_period_for_45_mhz[2];
2042 break;
2043 case 4:
2044 ax = wz_half_period_for_45_mhz[3];
2045 break;
2046
2047 default:
2048 ax = 0;
2049 }
2050
2051 if (ax != 0) {
2052 write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
2053
2054 } else {
2055
2056 write_reg_dw(adapter, 0x200, 0x40ff8000);
2057 }
2058}
2059
2060static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
2061{
2062 u32 var;
2063
2064 dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
2065
2066 var = read_reg_dw(adapter, 0x204);
2067
2068 if (polarity == 0) {
2069 dprintk("%s: LNB power off\n", __FUNCTION__);
2070 var = var | 1;
2071 };
2072
2073 if (polarity == 1) {
2074 var = var & ~1;
2075 var = var & ~4;
2076 };
2077
2078 if (polarity == 2) {
2079 var = var & ~1;
2080 var = var | 4;
2081 }
2082
2083 write_reg_dw(adapter, 0x204, var);
2084}
2085
2086static void diseqc_send_bit(struct adapter *adapter, int data)
2087{
2088 set_tuner_tone(adapter, 1);
2089 udelay(data ? 500 : 1000);
2090 set_tuner_tone(adapter, 0);
2091 udelay(data ? 1000 : 500);
2092}
2093
2094
2095static void diseqc_send_byte(struct adapter *adapter, int data)
2096 {
2097 int i, par = 1, d;
2098
2099 for (i = 7; i >= 0; i--) {
2100 d = (data >> i) & 1;
2101 par ^= d;
2102 diseqc_send_bit(adapter, d);
2103 }
2104
2105 diseqc_send_bit(adapter, par);
2106 }
2107
2108
2109static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
2110{
2111 int i;
2112
2113 set_tuner_tone(adapter, 0);
2114 mdelay(16);
2115
2116 for (i = 0; i < len; i++)
2117 diseqc_send_byte(adapter, msg[i]);
2118
2119 mdelay(16);
2120
2121 if (burst != -1) {
2122 if (burst)
2123 diseqc_send_byte(adapter, 0xff);
2124 else {
2125 set_tuner_tone(adapter, 1);
2126 udelay(12500);
2127 set_tuner_tone(adapter, 0);
2128 }
2129 msleep(20);
2130 }
2131
2132 return 0;
2133}
2134
2135static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2136{
2137 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2138
2139 switch(tone) {
2140 case SEC_TONE_ON:
2141 set_tuner_tone(adapter, 1);
2142 break;
2143 case SEC_TONE_OFF:
2144 set_tuner_tone(adapter, 0);
2145 break;
2146 default:
2147 return -EINVAL;
2148 };
2149
2150 return 0;
2151}
2152
2153static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
2154 {
2155 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2156
2157 send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
2158
2159 return 0;
2160 }
2161
2162static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2163{
2164 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2165
2166 send_diseqc_msg(adapter, 0, NULL, minicmd);
2167
2168 return 0;
2169}
2170
2171static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2172 {
2173 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2174
2175 dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
2176
2177 switch (voltage) {
2178 case SEC_VOLTAGE_13:
2179 dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
2180 set_tuner_polarity(adapter, 1);
2181 return 0;
2182
2183 case SEC_VOLTAGE_18:
2184 dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
2185 set_tuner_polarity(adapter, 2);
2186 return 0;
2187
2188 default:
2189 return -EINVAL;
2190 }
2191 }
2192
2193static int flexcop_sleep(struct dvb_frontend* fe)
2194 {
2195 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2196
2197 dprintk("%s: FE_SLEEP\n", __FUNCTION__);
2198 set_tuner_polarity(adapter, 0);
2199
2200 if (adapter->fe_sleep) return adapter->fe_sleep(fe);
2201 return 0;
2202 }
2203
2204static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
2205 {
2206 printk("flexcop_i2c_func\n");
2207
2208 return I2C_FUNC_I2C;
2209}
2210
2211static struct i2c_algorithm flexcop_algo = {
2212 .name = "flexcop i2c algorithm",
2213 .id = I2C_ALGO_BIT,
2214 .master_xfer = master_xfer,
2215 .functionality = flexcop_i2c_func,
2216};
2217
2218
2219
2220
2221static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
2222{
2223 u8 aclk = 0;
2224 u8 bclk = 0;
2225
2226 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
2227 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
2228 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
2229 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
2230 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
2231 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
2232
2233 stv0299_writereg (fe, 0x13, aclk);
2234 stv0299_writereg (fe, 0x14, bclk);
2235 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
2236 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
2237 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
2238
2239 return 0;
2240}
2241
2242static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2243{
2244 u8 buf[4];
2245 u32 div;
2246 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2247 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2248
2249 div = params->frequency / 125;
2250
2251 buf[0] = (div >> 8) & 0x7f;
2252 buf[1] = div & 0xff;
2253 buf[2] = 0x84; // 0xC4
2254 buf[3] = 0x08;
2255
2256 if (params->frequency < 1500000) buf[3] |= 0x10;
2257
2258 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2259 return 0;
2260}
2261
2262static u8 samsung_tbmu24112_inittab[] = {
2263 0x01, 0x15,
2264 0x02, 0x30,
2265 0x03, 0x00,
2266 0x04, 0x7D,
2267 0x05, 0x35,
2268 0x06, 0x02,
2269 0x07, 0x00,
2270 0x08, 0xC3,
2271 0x0C, 0x00,
2272 0x0D, 0x81,
2273 0x0E, 0x23,
2274 0x0F, 0x12,
2275 0x10, 0x7E,
2276 0x11, 0x84,
2277 0x12, 0xB9,
2278 0x13, 0x88,
2279 0x14, 0x89,
2280 0x15, 0xC9,
2281 0x16, 0x00,
2282 0x17, 0x5C,
2283 0x18, 0x00,
2284 0x19, 0x00,
2285 0x1A, 0x00,
2286 0x1C, 0x00,
2287 0x1D, 0x00,
2288 0x1E, 0x00,
2289 0x1F, 0x3A,
2290 0x20, 0x2E,
2291 0x21, 0x80,
2292 0x22, 0xFF,
2293 0x23, 0xC1,
2294 0x28, 0x00,
2295 0x29, 0x1E,
2296 0x2A, 0x14,
2297 0x2B, 0x0F,
2298 0x2C, 0x09,
2299 0x2D, 0x05,
2300 0x31, 0x1F,
2301 0x32, 0x19,
2302 0x33, 0xFE,
2303 0x34, 0x93,
2304 0xff, 0xff,
2305 };
2306
2307static struct stv0299_config samsung_tbmu24112_config = {
2308 .demod_address = 0x68,
2309 .inittab = samsung_tbmu24112_inittab,
2310 .mclk = 88000000UL,
2311 .invert = 0,
2312 .enhanced_tuning = 0,
2313 .skip_reinit = 0,
2314 .lock_output = STV0229_LOCKOUTPUT_LK,
2315 .volt13_op0_op1 = STV0299_VOLT13_OP1,
2316 .min_delay_ms = 100,
2317 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
2318 .pll_set = samsung_tbmu24112_pll_set,
2319};
2320
2321
2322
2323static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
2324{
2325 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2326
2327 return request_firmware(fw, name, &adapter->pdev->dev);
2328}
2329
2330
2331static struct nxt2002_config samsung_tbmv_config = {
2332 .demod_address = 0x0A,
2333 .request_firmware = nxt2002_request_firmware,
2334};
2335
2336static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
2337{
2338 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
2339 static u8 mt352_reset [] = { 0x50, 0x80 };
2340 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
2341 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
2342 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
2343
2344 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
2345 udelay(2000);
2346 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
2347 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
2348
2349 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
2350 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
2351
2352 return 0;
2353}
2354
2355static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
2356{
2357 u32 div;
2358 unsigned char bs = 0;
2359
2360 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
2361 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
2362
2363 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
2364 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
2365 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
2366
2367 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
2368 pllbuf[1] = div >> 8;
2369 pllbuf[2] = div & 0xff;
2370 pllbuf[3] = 0xcc;
2371 pllbuf[4] = bs;
2372
2373 return 0;
2374}
2375
2376static struct mt352_config samsung_tdtc9251dh0_config = {
2377
2378 .demod_address = 0x0f,
2379 .demod_init = samsung_tdtc9251dh0_demod_init,
2380 .pll_set = samsung_tdtc9251dh0_pll_set,
2381};
2382
2383static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2384{
2385 u8 buf[4];
2386 u32 div;
2387 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2388 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2389
2390 div = (params->frequency + (125/2)) / 125;
2391
2392 buf[0] = (div >> 8) & 0x7f;
2393 buf[1] = (div >> 0) & 0xff;
2394 buf[2] = 0x84 | ((div >> 10) & 0x60);
2395 buf[3] = 0x80;
2396
2397 if (params->frequency < 1550000)
2398 buf[3] |= 0x02;
2399
2400 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2401 return 0;
2402}
2403
2404static struct mt312_config skystar23_samsung_tbdu18132_config = {
2405
2406 .demod_address = 0x0e,
2407 .pll_set = skystar23_samsung_tbdu18132_pll_set,
2408};
2409
2410
2411
2412
2413static void frontend_init(struct adapter *skystar2)
2414{
2415 switch(skystar2->pdev->device) {
2416 case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
2417
2418 // Attempt to load the Nextwave nxt2002 for ATSC support
2419 skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
2420 if (skystar2->fe != NULL) {
2421 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2422 skystar2->fe->ops->sleep = flexcop_sleep;
2423 break;
2424 }
2425
2426 // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
2427 skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
2428 if (skystar2->fe != NULL) {
2429 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2430 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2431 skystar2->fe->ops->sleep = flexcop_sleep;
2432 break;
2433}
2434
2435 // try the airstar2 (mt352/Samsung tdtc9251dh0(??))
2436 skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
2437 if (skystar2->fe != NULL) {
2438 skystar2->fe->ops->info.frequency_min = 474000000;
2439 skystar2->fe->ops->info.frequency_max = 858000000;
2440 break;
2441 }
2442
2443 // try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
2444 skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
2445 if (skystar2->fe != NULL) {
2446 skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
2447 skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
2448 skystar2->fe->ops->set_tone = flexcop_set_tone;
2449 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2450 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2451 skystar2->fe->ops->sleep = flexcop_sleep;
2452 break;
2453 }
2454 break;
2455 }
2456
2457 if (skystar2->fe == NULL) {
2458 printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2459 skystar2->pdev->vendor,
2460 skystar2->pdev->device,
2461 skystar2->pdev->subsystem_vendor,
2462 skystar2->pdev->subsystem_device);
2463 } else {
2464 if (dvb_register_frontend(skystar2->dvb_adapter, skystar2->fe)) {
2465 printk("skystar2: Frontend registration failed!\n");
2466 if (skystar2->fe->ops->release)
2467 skystar2->fe->ops->release(skystar2->fe);
2468 skystar2->fe = NULL;
2469 }
2470 }
2471}
2472
2473
2474static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2475{
2476 struct adapter *adapter;
2477 struct dvb_adapter *dvb_adapter;
2478 struct dvb_demux *dvbdemux;
2479 struct dmx_demux *dmx;
2480 int ret = -ENODEV;
2481
2482 if (!pdev)
2483 goto out;
2484
2485 ret = driver_initialize(pdev);
2486 if (ret < 0)
2487 goto out;
2488
2489 ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name,
2490 THIS_MODULE);
2491 if (ret < 0) {
2492 printk("%s: Error registering DVB adapter\n", __FUNCTION__);
2493 goto err_halt;
2494 }
2495
2496 adapter = pci_get_drvdata(pdev);
2497
2498 dvb_adapter->priv = adapter;
2499 adapter->dvb_adapter = dvb_adapter;
2500
2501
2502 init_MUTEX(&adapter->i2c_sem);
2503
2504
2505 memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
2506 strcpy(adapter->i2c_adap.name, "SkyStar2");
2507
2508 i2c_set_adapdata(&adapter->i2c_adap, adapter);
2509
2510#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2511 adapter->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2512#else
2513 adapter->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2514#endif
2515 adapter->i2c_adap.algo = &flexcop_algo;
2516 adapter->i2c_adap.algo_data = NULL;
2517 adapter->i2c_adap.id = I2C_ALGO_BIT;
2518
2519 ret = i2c_add_adapter(&adapter->i2c_adap);
2520 if (ret < 0)
2521 goto err_dvb_unregister;
2522
2523 dvbdemux = &adapter->demux;
2524
2525 dvbdemux->priv = adapter;
2526 dvbdemux->filternum = N_PID_SLOTS;
2527 dvbdemux->feednum = N_PID_SLOTS;
2528 dvbdemux->start_feed = dvb_start_feed;
2529 dvbdemux->stop_feed = dvb_stop_feed;
2530 dvbdemux->write_to_decoder = NULL;
2531 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
2532
2533 ret = dvb_dmx_init(&adapter->demux);
2534 if (ret < 0)
2535 goto err_i2c_del;
2536
2537 dmx = &dvbdemux->dmx;
2538
2539 adapter->hw_frontend.source = DMX_FRONTEND_0;
2540 adapter->dmxdev.filternum = N_PID_SLOTS;
2541 adapter->dmxdev.demux = dmx;
2542 adapter->dmxdev.capabilities = 0;
2543
2544 ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
2545 if (ret < 0)
2546 goto err_dmx_release;
2547
2548 ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
2549 if (ret < 0)
2550 goto err_dmxdev_release;
2551
2552 adapter->mem_frontend.source = DMX_MEMORY_FE;
2553
2554 ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
2555 if (ret < 0)
2556 goto err_remove_hw_frontend;
2557
2558 ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
2559 if (ret < 0)
2560 goto err_remove_mem_frontend;
2561
2562 dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
2563
2564 frontend_init(adapter);
2565out:
2566 return ret;
2567
2568err_remove_mem_frontend:
2569 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
2570err_remove_hw_frontend:
2571 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
2572err_dmxdev_release:
2573 dvb_dmxdev_release(&adapter->dmxdev);
2574err_dmx_release:
2575 dvb_dmx_release(&adapter->demux);
2576err_i2c_del:
2577 i2c_del_adapter(&adapter->i2c_adap);
2578err_dvb_unregister:
2579 dvb_unregister_adapter(adapter->dvb_adapter);
2580err_halt:
2581 driver_halt(pdev);
2582 goto out;
2583}
2584
2585static void skystar2_remove(struct pci_dev *pdev)
2586{
2587 struct adapter *adapter = pci_get_drvdata(pdev);
2588 struct dvb_demux *dvbdemux;
2589 struct dmx_demux *dmx;
2590
2591 if (!adapter)
2592 return;
2593
2594 dvb_net_release(&adapter->dvbnet);
2595 dvbdemux = &adapter->demux;
2596 dmx = &dvbdemux->dmx;
2597
2598 dmx->close(dmx);
2599 dmx->remove_frontend(dmx, &adapter->hw_frontend);
2600 dmx->remove_frontend(dmx, &adapter->mem_frontend);
2601
2602 dvb_dmxdev_release(&adapter->dmxdev);
2603 dvb_dmx_release(dvbdemux);
2604
2605 if (adapter->fe != NULL)
2606 dvb_unregister_frontend(adapter->fe);
2607
2608 dvb_unregister_adapter(adapter->dvb_adapter);
2609
2610 i2c_del_adapter(&adapter->i2c_adap);
2611
2612 driver_halt(pdev);
2613 }
2614
2615static struct pci_device_id skystar2_pci_tbl[] = {
2616 {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
2617/* {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */ //FCIII
2618 {0,},
2619};
2620
2621MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
2622
2623static struct pci_driver skystar2_pci_driver = {
2624 .name = "SkyStar2",
2625 .id_table = skystar2_pci_tbl,
2626 .probe = skystar2_probe,
2627 .remove = skystar2_remove,
2628};
2629
2630static int skystar2_init(void)
2631{
2632 return pci_register_driver(&skystar2_pci_driver);
2633}
2634
2635static void skystar2_cleanup(void)
2636{
2637 pci_unregister_driver(&skystar2_pci_driver);
2638}
2639
2640module_init(skystar2_init);
2641module_exit(skystar2_cleanup);
2642
2643MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
2644MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
new file mode 100644
index 000000000000..e7d11e0667a8
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -0,0 +1,19 @@
1config DVB_BT8XX
2 tristate "Nebula/Pinnacle PCTV/Twinhan PCI cards"
3 depends on DVB_CORE && PCI && VIDEO_BT848
4 select DVB_MT352
5 select DVB_SP887X
6 select DVB_NXT6000
7 select DVB_CX24110
8 select DVB_OR51211
9 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
12 pcHDTV HD2000 cards.
13
14 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need
16 an external software decoder to watch TV on your computer.
17
18 Say Y if you own such a device and want to use it.
19
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
new file mode 100644
index 000000000000..9da8604b9e18
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -0,0 +1,5 @@
1
2obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o
3
4EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
5
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
new file mode 100644
index 000000000000..213ff7902024
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -0,0 +1,588 @@
1/*
2 * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
3 *
4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
5 *
6 * large parts based on the bttv driver
7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 * & Marcus Metzler (mocm@thp.uni-koeln.de)
9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kernel.h>
33#include <linux/pci.h>
34#include <asm/io.h>
35#include <linux/ioport.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/types.h>
39#include <linux/interrupt.h>
40#include <linux/kmod.h>
41#include <linux/vmalloc.h>
42#include <linux/init.h>
43
44#include "dmxdev.h"
45#include "dvbdev.h"
46#include "bt878.h"
47#include "dst_priv.h"
48
49
50/**************************************/
51/* Miscellaneous utility definitions */
52/**************************************/
53
54static unsigned int bt878_verbose = 1;
55static unsigned int bt878_debug;
56
57module_param_named(verbose, bt878_verbose, int, 0444);
58MODULE_PARM_DESC(verbose,
59 "verbose startup messages, default is 1 (yes)");
60module_param_named(debug, bt878_debug, int, 0644);
61MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
62
63int bt878_num;
64struct bt878 bt878[BT878_MAX];
65
66EXPORT_SYMBOL(bt878_debug);
67EXPORT_SYMBOL(bt878_verbose);
68EXPORT_SYMBOL(bt878_num);
69EXPORT_SYMBOL(bt878);
70
71#define btwrite(dat,adr) bmtwrite((dat), (bt->bt878_mem+(adr)))
72#define btread(adr) bmtread(bt->bt878_mem+(adr))
73
74#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
75#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
76#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
77
78#if defined(dprintk)
79#undef dprintk
80#endif
81#define dprintk if(bt878_debug) printk
82
83static void bt878_mem_free(struct bt878 *bt)
84{
85 if (bt->buf_cpu) {
86 pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
87 bt->buf_dma);
88 bt->buf_cpu = NULL;
89 }
90
91 if (bt->risc_cpu) {
92 pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
93 bt->risc_dma);
94 bt->risc_cpu = NULL;
95 }
96}
97
98static int bt878_mem_alloc(struct bt878 *bt)
99{
100 if (!bt->buf_cpu) {
101 bt->buf_size = 128 * 1024;
102
103 bt->buf_cpu =
104 pci_alloc_consistent(bt->dev, bt->buf_size,
105 &bt->buf_dma);
106
107 if (!bt->buf_cpu)
108 return -ENOMEM;
109
110 memset(bt->buf_cpu, 0, bt->buf_size);
111 }
112
113 if (!bt->risc_cpu) {
114 bt->risc_size = PAGE_SIZE;
115 bt->risc_cpu =
116 pci_alloc_consistent(bt->dev, bt->risc_size,
117 &bt->risc_dma);
118
119 if (!bt->risc_cpu) {
120 bt878_mem_free(bt);
121 return -ENOMEM;
122 }
123
124 memset(bt->risc_cpu, 0, bt->risc_size);
125 }
126
127 return 0;
128}
129
130/* RISC instructions */
131#define RISC_WRITE (0x01 << 28)
132#define RISC_JUMP (0x07 << 28)
133#define RISC_SYNC (0x08 << 28)
134
135/* RISC bits */
136#define RISC_WR_SOL (1 << 27)
137#define RISC_WR_EOL (1 << 26)
138#define RISC_IRQ (1 << 24)
139#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
140#define RISC_SYNC_RESYNC (1 << 15)
141#define RISC_SYNC_FM1 0x06
142#define RISC_SYNC_VRO 0x0C
143
144#define RISC_FLUSH() bt->risc_pos = 0
145#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
146
147static int bt878_make_risc(struct bt878 *bt)
148{
149 bt->block_bytes = bt->buf_size >> 4;
150 bt->block_count = 1 << 4;
151 bt->line_bytes = bt->block_bytes;
152 bt->line_count = bt->block_count;
153
154 while (bt->line_bytes > 4095) {
155 bt->line_bytes >>= 1;
156 bt->line_count <<= 1;
157 }
158
159 if (bt->line_count > 255) {
160 printk("bt878: buffer size error!\n");
161 return -EINVAL;
162 }
163 return 0;
164}
165
166
167static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
168{
169 u32 buf_pos = 0;
170 u32 line;
171
172 RISC_FLUSH();
173 RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
174 RISC_INSTR(0);
175
176 dprintk("bt878: risc len lines %u, bytes per line %u\n",
177 bt->line_count, bt->line_bytes);
178 for (line = 0; line < bt->line_count; line++) {
179 // At the beginning of every block we issue an IRQ with previous (finished) block number set
180 if (!(buf_pos % bt->block_bytes))
181 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
182 RISC_IRQ |
183 RISC_STATUS(((buf_pos /
184 bt->block_bytes) +
185 (bt->block_count -
186 1)) %
187 bt->block_count) | bt->
188 line_bytes);
189 else
190 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
191 bt->line_bytes);
192 RISC_INSTR(bt->buf_dma + buf_pos);
193 buf_pos += bt->line_bytes;
194 }
195
196 RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
197 RISC_INSTR(0);
198
199 RISC_INSTR(RISC_JUMP);
200 RISC_INSTR(bt->risc_dma);
201
202 btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
203}
204
205/*****************************/
206/* Start/Stop grabbing funcs */
207/*****************************/
208
209void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
210 u32 irq_err_ignore)
211{
212 u32 int_mask;
213
214 dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
215 /* complete the writing of the risc dma program now we have
216 * the card specifics
217 */
218 bt878_risc_program(bt, op_sync_orin);
219 controlreg &= ~0x1f;
220 controlreg |= 0x1b;
221
222 btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
223
224 /* original int mask had :
225 * 6 2 8 4 0
226 * 1111 1111 1000 0000 0000
227 * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
228 * Hacked for DST to:
229 * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
230 */
231 int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
232 BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
233 BT878_AFBUS | BT878_ARISCI;
234
235
236 /* ignore pesky bits */
237 int_mask &= ~irq_err_ignore;
238
239 btwrite(int_mask, BT878_AINT_MASK);
240 btwrite(controlreg, BT878_AGPIO_DMA_CTL);
241}
242
243void bt878_stop(struct bt878 *bt)
244{
245 u32 stat;
246 int i = 0;
247
248 dprintk("bt878 debug: bt878_stop\n");
249
250 btwrite(0, BT878_AINT_MASK);
251 btand(~0x13, BT878_AGPIO_DMA_CTL);
252
253 do {
254 stat = btread(BT878_AINT_STAT);
255 if (!(stat & BT878_ARISC_EN))
256 break;
257 i++;
258 } while (i < 500);
259
260 dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
261 bt->nr, i, stat);
262}
263
264EXPORT_SYMBOL(bt878_start);
265EXPORT_SYMBOL(bt878_stop);
266
267/*****************************/
268/* Interrupt service routine */
269/*****************************/
270
271static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs)
272{
273 u32 stat, astat, mask;
274 int count;
275 struct bt878 *bt;
276
277 bt = (struct bt878 *) dev_id;
278
279 count = 0;
280 while (1) {
281 stat = btread(BT878_AINT_STAT);
282 mask = btread(BT878_AINT_MASK);
283 if (!(astat = (stat & mask)))
284 return IRQ_NONE; /* this interrupt is not for me */
285/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
286 btwrite(astat, BT878_AINT_STAT); /* try to clear interupt condition */
287
288
289 if (astat & (BT878_ASCERR | BT878_AOCERR)) {
290 if (bt878_verbose) {
291 printk("bt878(%d): irq%s%s risc_pc=%08x\n",
292 bt->nr,
293 (astat & BT878_ASCERR) ? " SCERR" :
294 "",
295 (astat & BT878_AOCERR) ? " OCERR" :
296 "", btread(BT878_ARISC_PC));
297 }
298 }
299 if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
300 if (bt878_verbose) {
301 printk
302 ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
303 bt->nr,
304 (astat & BT878_APABORT) ? " PABORT" :
305 "",
306 (astat & BT878_ARIPERR) ? " RIPERR" :
307 "",
308 (astat & BT878_APPERR) ? " PPERR" :
309 "", btread(BT878_ARISC_PC));
310 }
311 }
312 if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
313 if (bt878_verbose) {
314 printk
315 ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
316 bt->nr,
317 (astat & BT878_AFDSR) ? " FDSR" : "",
318 (astat & BT878_AFTRGT) ? " FTRGT" :
319 "",
320 (astat & BT878_AFBUS) ? " FBUS" : "",
321 btread(BT878_ARISC_PC));
322 }
323 }
324 if (astat & BT878_ARISCI) {
325 bt->finished_block = (stat & BT878_ARISCS) >> 28;
326 tasklet_schedule(&bt->tasklet);
327 break;
328 }
329 count++;
330 if (count > 20) {
331 btwrite(0, BT878_AINT_MASK);
332 printk(KERN_ERR
333 "bt878(%d): IRQ lockup, cleared int mask\n",
334 bt->nr);
335 break;
336 }
337 }
338 return IRQ_HANDLED;
339}
340
341int
342bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
343{
344 int retval;
345
346 retval = 0;
347 if (down_interruptible (&bt->gpio_lock))
348 return -ERESTARTSYS;
349 /* special gpio signal */
350 switch (cmd) {
351 case DST_IG_ENABLE:
352 // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
353 retval = bttv_gpio_enable(bt->bttv_nr,
354 mp->enb.mask,
355 mp->enb.enable);
356 break;
357 case DST_IG_WRITE:
358 // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
359 retval = bttv_write_gpio(bt->bttv_nr,
360 mp->outp.mask,
361 mp->outp.highvals);
362
363 break;
364 case DST_IG_READ:
365 /* read */
366 retval = bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
367 // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
368 break;
369 case DST_IG_TS:
370 /* Set packet size */
371 bt->TS_Size = mp->psize;
372 break;
373
374 default:
375 retval = -EINVAL;
376 break;
377 }
378 up(&bt->gpio_lock);
379 return retval;
380}
381
382EXPORT_SYMBOL(bt878_device_control);
383
384/***********************/
385/* PCI device handling */
386/***********************/
387
388static int __devinit bt878_probe(struct pci_dev *dev,
389 const struct pci_device_id *pci_id)
390{
391 int result;
392 unsigned char lat;
393 struct bt878 *bt;
394#if defined(__powerpc__)
395 unsigned int cmd;
396#endif
397
398 printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
399 bt878_num);
400 if (pci_enable_device(dev))
401 return -EIO;
402
403 bt = &bt878[bt878_num];
404 bt->dev = dev;
405 bt->nr = bt878_num;
406 bt->shutdown = 0;
407
408 bt->id = dev->device;
409 bt->irq = dev->irq;
410 bt->bt878_adr = pci_resource_start(dev, 0);
411 if (!request_mem_region(pci_resource_start(dev, 0),
412 pci_resource_len(dev, 0), "bt878")) {
413 result = -EBUSY;
414 goto fail0;
415 }
416
417 pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
418 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
419 printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
420 bt878_num, bt->id, bt->revision, dev->bus->number,
421 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
422 printk("irq: %d, latency: %d, memory: 0x%lx\n",
423 bt->irq, lat, bt->bt878_adr);
424
425
426#if defined(__powerpc__)
427 /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
428 /* response on cards with no firmware is not enabled by OF */
429 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
430 cmd = (cmd | PCI_COMMAND_MEMORY);
431 pci_write_config_dword(dev, PCI_COMMAND, cmd);
432#endif
433
434#ifdef __sparc__
435 bt->bt878_mem = (unsigned char *) bt->bt878_adr;
436#else
437 bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
438#endif
439
440 /* clear interrupt mask */
441 btwrite(0, BT848_INT_MASK);
442
443 result = request_irq(bt->irq, bt878_irq,
444 SA_SHIRQ | SA_INTERRUPT, "bt878",
445 (void *) bt);
446 if (result == -EINVAL) {
447 printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
448 bt878_num);
449 goto fail1;
450 }
451 if (result == -EBUSY) {
452 printk(KERN_ERR
453 "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
454 bt878_num, bt->irq);
455 goto fail1;
456 }
457 if (result < 0)
458 goto fail1;
459
460 pci_set_master(dev);
461 pci_set_drvdata(dev, bt);
462
463/* if(init_bt878(btv) < 0) {
464 bt878_remove(dev);
465 return -EIO;
466 }
467*/
468
469 if ((result = bt878_mem_alloc(bt))) {
470 printk("bt878: failed to allocate memory!\n");
471 goto fail2;
472 }
473
474 bt878_make_risc(bt);
475 btwrite(0, BT878_AINT_MASK);
476 bt878_num++;
477
478 return 0;
479
480 fail2:
481 free_irq(bt->irq, bt);
482 fail1:
483 release_mem_region(pci_resource_start(bt->dev, 0),
484 pci_resource_len(bt->dev, 0));
485 fail0:
486 pci_disable_device(dev);
487 return result;
488}
489
490static void __devexit bt878_remove(struct pci_dev *pci_dev)
491{
492 u8 command;
493 struct bt878 *bt = pci_get_drvdata(pci_dev);
494
495 if (bt878_verbose)
496 printk("bt878(%d): unloading\n", bt->nr);
497
498 /* turn off all capturing, DMA and IRQs */
499 btand(~0x13, BT878_AGPIO_DMA_CTL);
500
501 /* first disable interrupts before unmapping the memory! */
502 btwrite(0, BT878_AINT_MASK);
503 btwrite(~0U, BT878_AINT_STAT);
504
505 /* disable PCI bus-mastering */
506 pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
507 /* Should this be &=~ ?? */
508 command &= ~PCI_COMMAND_MASTER;
509 pci_write_config_byte(bt->dev, PCI_COMMAND, command);
510
511 free_irq(bt->irq, bt);
512 printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
513 if (bt->bt878_mem)
514 iounmap(bt->bt878_mem);
515
516 release_mem_region(pci_resource_start(bt->dev, 0),
517 pci_resource_len(bt->dev, 0));
518 /* wake up any waiting processes
519 because shutdown flag is set, no new processes (in this queue)
520 are expected
521 */
522 bt->shutdown = 1;
523 bt878_mem_free(bt);
524
525 pci_set_drvdata(pci_dev, NULL);
526 pci_disable_device(pci_dev);
527 return;
528}
529
530static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
531 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BROOKTREE_878,
532 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
533 {0,}
534};
535
536MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
537
538static struct pci_driver bt878_pci_driver = {
539 .name = "bt878",
540 .id_table = bt878_pci_tbl,
541 .probe = bt878_probe,
542 .remove = bt878_remove,
543};
544
545static int bt878_pci_driver_registered = 0;
546
547/*******************************/
548/* Module management functions */
549/*******************************/
550
551static int bt878_init_module(void)
552{
553 bt878_num = 0;
554 bt878_pci_driver_registered = 0;
555
556 printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
557 (BT878_VERSION_CODE >> 16) & 0xff,
558 (BT878_VERSION_CODE >> 8) & 0xff,
559 BT878_VERSION_CODE & 0xff);
560/*
561 bt878_check_chipset();
562*/
563 /* later we register inside of bt878_find_audio_dma()
564 * because we may want to ignore certain cards */
565 bt878_pci_driver_registered = 1;
566 return pci_register_driver(&bt878_pci_driver);
567}
568
569static void bt878_cleanup_module(void)
570{
571 if (bt878_pci_driver_registered) {
572 bt878_pci_driver_registered = 0;
573 pci_unregister_driver(&bt878_pci_driver);
574 }
575 return;
576}
577
578module_init(bt878_init_module);
579module_exit(bt878_cleanup_module);
580
581//MODULE_AUTHOR("XXX");
582MODULE_LICENSE("GPL");
583
584/*
585 * Local variables:
586 * c-basic-offset: 8
587 * End:
588 */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
new file mode 100644
index 000000000000..e1b9809d1b08
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -0,0 +1,147 @@
1/*
2 bt878.h - Bt878 audio module (register offsets)
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
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
21#ifndef _BT878_H_
22#define _BT878_H_
23
24#include <linux/interrupt.h>
25#include <linux/pci.h>
26#include <linux/sched.h>
27#include <linux/spinlock.h>
28#include "bt848.h"
29#include "bttv.h"
30
31#define BT878_VERSION_CODE 0x000000
32
33#define BT878_AINT_STAT 0x100
34#define BT878_ARISCS (0xf<<28)
35#define BT878_ARISC_EN (1<<27)
36#define BT878_ASCERR (1<<19)
37#define BT878_AOCERR (1<<18)
38#define BT878_APABORT (1<<17)
39#define BT878_ARIPERR (1<<16)
40#define BT878_APPERR (1<<15)
41#define BT878_AFDSR (1<<14)
42#define BT878_AFTRGT (1<<13)
43#define BT878_AFBUS (1<<12)
44#define BT878_ARISCI (1<<11)
45#define BT878_AOFLOW (1<<3)
46
47#define BT878_AINT_MASK 0x104
48
49#define BT878_AGPIO_DMA_CTL 0x10c
50#define BT878_A_GAIN (0xf<<28)
51#define BT878_A_G2X (1<<27)
52#define BT878_A_PWRDN (1<<26)
53#define BT878_A_SEL (3<<24)
54#define BT878_DA_SCE (1<<23)
55#define BT878_DA_LRI (1<<22)
56#define BT878_DA_MLB (1<<21)
57#define BT878_DA_LRD (0x1f<<16)
58#define BT878_DA_DPM (1<<15)
59#define BT878_DA_SBR (1<<14)
60#define BT878_DA_ES2 (1<<13)
61#define BT878_DA_LMT (1<<12)
62#define BT878_DA_SDR (0xf<<8)
63#define BT878_DA_IOM (3<<6)
64#define BT878_DA_APP (1<<5)
65#define BT878_ACAP_EN (1<<4)
66#define BT878_PKTP (3<<2)
67#define BT878_RISC_EN (1<<1)
68#define BT878_FIFO_EN 1
69
70#define BT878_APACK_LEN 0x110
71#define BT878_AFP_LEN (0xff<<16)
72#define BT878_ALP_LEN 0xfff
73
74#define BT878_ARISC_START 0x114
75
76#define BT878_ARISC_PC 0x120
77
78/* BT878 FUNCTION 0 REGISTERS */
79#define BT878_GPIO_DMA_CTL 0x10c
80
81/* Interrupt register */
82#define BT878_INT_STAT 0x100
83#define BT878_INT_MASK 0x104
84#define BT878_I2CRACK (1<<25)
85#define BT878_I2CDONE (1<<8)
86
87#define BT878_MAX 4
88
89#define BT878_RISC_SYNC_MASK (1 << 15)
90
91extern int bt878_num;
92
93struct bt878 {
94 struct semaphore gpio_lock;
95 unsigned int nr;
96 unsigned int bttv_nr;
97 struct i2c_adapter *adapter;
98 struct pci_dev *dev;
99 unsigned int id;
100 unsigned int TS_Size;
101 unsigned char revision;
102 unsigned int irq;
103 unsigned long bt878_adr;
104 volatile void __iomem *bt878_mem; /* function 1 */
105
106 volatile u32 finished_block;
107 volatile u32 last_block;
108 u32 block_count;
109 u32 block_bytes;
110 u32 line_bytes;
111 u32 line_count;
112
113 u32 buf_size;
114 u8 *buf_cpu;
115 dma_addr_t buf_dma;
116
117 u32 risc_size;
118 u32 *risc_cpu;
119 dma_addr_t risc_dma;
120 u32 risc_pos;
121
122 struct tasklet_struct tasklet;
123 int shutdown;
124};
125
126extern struct bt878 bt878[BT878_MAX];
127
128void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
129 u32 irq_err_ignore);
130void bt878_stop(struct bt878 *bt);
131
132#if defined(__powerpc__) /* big-endian */
133extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
134{
135 __asm__ __volatile__("stwbrx %1,0,%2":"=m"(*addr):"r"(val),
136 "r"(addr));
137 __asm__ __volatile__("eieio":::"memory");
138}
139
140#define bmtwrite(dat,adr) io_st_le32((adr),(dat))
141#define bmtread(adr) ld_le32((adr))
142#else
143#define bmtwrite(dat,adr) writel((dat), (adr))
144#define bmtread(adr) readl(adr)
145#endif
146
147#endif
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
new file mode 100644
index 000000000000..eac83768dfd0
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -0,0 +1,1089 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/vmalloc.h>
29#include <linux/delay.h>
30#include <asm/div64.h>
31
32#include "dvb_frontend.h"
33#include "dst_priv.h"
34#include "dst.h"
35
36struct dst_state {
37
38 struct i2c_adapter* i2c;
39
40 struct bt878* bt;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct dst_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* private demodulator data */
50 u8 tx_tuna[10];
51 u8 rx_tuna[10];
52 u8 rxbuffer[10];
53 u8 diseq_flags;
54 u8 dst_type;
55 u32 type_flags;
56 u32 frequency; /* intermediate frequency in kHz for QPSK */
57 fe_spectral_inversion_t inversion;
58 u32 symbol_rate; /* symbol rate in Symbols per second */
59 fe_code_rate_t fec;
60 fe_sec_voltage_t voltage;
61 fe_sec_tone_mode_t tone;
62 u32 decode_freq;
63 u8 decode_lock;
64 u16 decode_strength;
65 u16 decode_snr;
66 unsigned long cur_jiff;
67 u8 k22;
68 fe_bandwidth_t bandwidth;
69};
70
71static unsigned int dst_verbose = 0;
72module_param(dst_verbose, int, 0644);
73MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)");
74static unsigned int dst_debug = 0;
75module_param(dst_debug, int, 0644);
76MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
77
78#define dprintk if (dst_debug) printk
79
80#define DST_TYPE_IS_SAT 0
81#define DST_TYPE_IS_TERR 1
82#define DST_TYPE_IS_CABLE 2
83
84#define DST_TYPE_HAS_NEWTUNE 1
85#define DST_TYPE_HAS_TS204 2
86#define DST_TYPE_HAS_SYMDIV 4
87
88#define HAS_LOCK 1
89#define ATTEMPT_TUNE 2
90#define HAS_POWER 4
91
92static void dst_packsize(struct dst_state* state, int psize)
93{
94 union dst_gpio_packet bits;
95
96 bits.psize = psize;
97 bt878_device_control(state->bt, DST_IG_TS, &bits);
98}
99
100static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh)
101{
102 union dst_gpio_packet enb;
103 union dst_gpio_packet bits;
104 int err;
105
106 enb.enb.mask = mask;
107 enb.enb.enable = enbb;
108 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
109 dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb);
110 return -EREMOTEIO;
111 }
112
113 /* because complete disabling means no output, no need to do output packet */
114 if (enbb == 0)
115 return 0;
116
117 bits.outp.mask = enbb;
118 bits.outp.highvals = outhigh;
119
120 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
121 dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh);
122 return -EREMOTEIO;
123 }
124 return 0;
125}
126
127static int dst_gpio_inb(struct dst_state *state, u8 * result)
128{
129 union dst_gpio_packet rd_packet;
130 int err;
131
132 *result = 0;
133
134 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
135 dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
136 return -EREMOTEIO;
137 }
138
139 *result = (u8) rd_packet.rd.value;
140 return 0;
141}
142
143#define DST_I2C_ENABLE 1
144#define DST_8820 2
145
146static int dst_reset8820(struct dst_state *state)
147{
148 int retval;
149 /* pull 8820 gpio pin low, wait, high, wait, then low */
150 // dprintk ("%s: reset 8820\n", __FUNCTION__);
151 retval = dst_gpio_outb(state, DST_8820, DST_8820, 0);
152 if (retval < 0)
153 return retval;
154 msleep(10);
155 retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820);
156 if (retval < 0)
157 return retval;
158 /* wait for more feedback on what works here *
159 msleep(10);
160 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
161 if (retval < 0)
162 return retval;
163 */
164 return 0;
165}
166
167static int dst_i2c_enable(struct dst_state *state)
168{
169 int retval;
170 /* pull I2C enable gpio pin low, wait */
171 // dprintk ("%s: i2c enable\n", __FUNCTION__);
172 retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0);
173 if (retval < 0)
174 return retval;
175 // dprintk ("%s: i2c enable delay\n", __FUNCTION__);
176 msleep(33);
177 return 0;
178}
179
180static int dst_i2c_disable(struct dst_state *state)
181{
182 int retval;
183 /* release I2C enable gpio pin, wait */
184 // dprintk ("%s: i2c disable\n", __FUNCTION__);
185 retval = dst_gpio_outb(state, ~0, 0, 0);
186 if (retval < 0)
187 return retval;
188 // dprintk ("%s: i2c disable delay\n", __FUNCTION__);
189 msleep(33);
190 return 0;
191}
192
193static int dst_wait_dst_ready(struct dst_state *state)
194{
195 u8 reply;
196 int retval;
197 int i;
198 for (i = 0; i < 200; i++) {
199 retval = dst_gpio_inb(state, &reply);
200 if (retval < 0)
201 return retval;
202 if ((reply & DST_I2C_ENABLE) == 0) {
203 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
204 return 1;
205 }
206 msleep(10);
207 }
208 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
209 return 0;
210}
211
212static int write_dst(struct dst_state *state, u8 * data, u8 len)
213{
214 struct i2c_msg msg = {
215 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
216 };
217 int err;
218 int cnt;
219
220 if (dst_debug && dst_verbose) {
221 u8 i;
222 dprintk("%s writing", __FUNCTION__);
223 for (i = 0; i < len; i++) {
224 dprintk(" 0x%02x", data[i]);
225 }
226 dprintk("\n");
227 }
228 msleep(30);
229 for (cnt = 0; cnt < 4; cnt++) {
230 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
231 dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
232 dst_i2c_disable(state);
233 msleep(500);
234 dst_i2c_enable(state);
235 msleep(500);
236 continue;
237 } else
238 break;
239 }
240 if (cnt >= 4)
241 return -EREMOTEIO;
242 return 0;
243}
244
245static int read_dst(struct dst_state *state, u8 * ret, u8 len)
246{
247 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
248 int err;
249 int cnt;
250
251 for (cnt = 0; cnt < 4; cnt++) {
252 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
253 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
254 dst_i2c_disable(state);
255 dst_i2c_enable(state);
256 continue;
257 } else
258 break;
259 }
260 if (cnt >= 4)
261 return -EREMOTEIO;
262 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
263 if (dst_debug && dst_verbose) {
264 for (err = 1; err < len; err++)
265 dprintk(" 0x%x", ret[err]);
266 if (err > 1)
267 dprintk("\n");
268 }
269 return 0;
270}
271
272static int dst_set_freq(struct dst_state *state, u32 freq)
273{
274 u8 *val;
275
276 state->frequency = freq;
277
278 // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
279 if (state->dst_type == DST_TYPE_IS_SAT) {
280 freq = freq / 1000;
281 if (freq < 950 || freq > 2150)
282 return -EINVAL;
283 val = &state->tx_tuna[0];
284 val[2] = (freq >> 8) & 0x7f;
285 val[3] = (u8) freq;
286 val[4] = 1;
287 val[8] &= ~4;
288 if (freq < 1531)
289 val[8] |= 4;
290 } else if (state->dst_type == DST_TYPE_IS_TERR) {
291 freq = freq / 1000;
292 if (freq < 137000 || freq > 858000)
293 return -EINVAL;
294 val = &state->tx_tuna[0];
295 val[2] = (freq >> 16) & 0xff;
296 val[3] = (freq >> 8) & 0xff;
297 val[4] = (u8) freq;
298 val[5] = 0;
299 switch (state->bandwidth) {
300 case BANDWIDTH_6_MHZ:
301 val[6] = 6;
302 break;
303
304 case BANDWIDTH_7_MHZ:
305 case BANDWIDTH_AUTO:
306 val[6] = 7;
307 break;
308
309 case BANDWIDTH_8_MHZ:
310 val[6] = 8;
311 break;
312 }
313
314 val[7] = 0;
315 val[8] = 0;
316 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
317 /* guess till will get one */
318 freq = freq / 1000;
319 val = &state->tx_tuna[0];
320 val[2] = (freq >> 16) & 0xff;
321 val[3] = (freq >> 8) & 0xff;
322 val[4] = (u8) freq;
323 } else
324 return -EINVAL;
325 return 0;
326}
327
328static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
329{
330 u8 *val;
331
332 state->bandwidth = bandwidth;
333
334 if (state->dst_type != DST_TYPE_IS_TERR)
335 return 0;
336
337 val = &state->tx_tuna[0];
338 switch (bandwidth) {
339 case BANDWIDTH_6_MHZ:
340 val[6] = 6;
341 break;
342
343 case BANDWIDTH_7_MHZ:
344 val[6] = 7;
345 break;
346
347 case BANDWIDTH_8_MHZ:
348 val[6] = 8;
349 break;
350
351 default:
352 return -EINVAL;
353 }
354 return 0;
355}
356
357static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
358{
359 u8 *val;
360
361 state->inversion = inversion;
362
363 val = &state->tx_tuna[0];
364
365 val[8] &= ~0x80;
366
367 switch (inversion) {
368 case INVERSION_OFF:
369 break;
370 case INVERSION_ON:
371 val[8] |= 0x80;
372 break;
373 default:
374 return -EINVAL;
375 }
376 return 0;
377}
378
379static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec)
380{
381 state->fec = fec;
382 return 0;
383}
384
385static fe_code_rate_t dst_get_fec(struct dst_state* state)
386{
387 return state->fec;
388}
389
390static int dst_set_symbolrate(struct dst_state* state, u32 srate)
391{
392 u8 *val;
393 u32 symcalc;
394 u64 sval;
395
396 state->symbol_rate = srate;
397
398 if (state->dst_type == DST_TYPE_IS_TERR) {
399 return 0;
400 }
401 // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
402 srate /= 1000;
403 val = &state->tx_tuna[0];
404
405 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
406 sval = srate;
407 sval <<= 20;
408 do_div(sval, 88000);
409 symcalc = (u32) sval;
410 // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
411 val[5] = (u8) (symcalc >> 12);
412 val[6] = (u8) (symcalc >> 4);
413 val[7] = (u8) (symcalc << 4);
414 } else {
415 val[5] = (u8) (srate >> 16) & 0x7f;
416 val[6] = (u8) (srate >> 8);
417 val[7] = (u8) srate;
418 }
419 val[8] &= ~0x20;
420 if (srate > 8000)
421 val[8] |= 0x20;
422 return 0;
423}
424
425static u8 dst_check_sum(u8 * buf, u32 len)
426{
427 u32 i;
428 u8 val = 0;
429 if (!len)
430 return 0;
431 for (i = 0; i < len; i++) {
432 val += buf[i];
433 }
434 return ((~val) + 1);
435}
436
437struct dst_types {
438 char *mstr;
439 int offs;
440 u8 dst_type;
441 u32 type_flags;
442};
443
444static struct dst_types dst_tlist[] = {
445 {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
446 {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
447 {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204},
448 {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
449 {"DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
450 {"DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
451 {"DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
452 {"DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE},
453 {"DCT-CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204},
454 {"DTTDIG", 1, DST_TYPE_IS_TERR, 0}
455};
456
457/* DCTNEW and DCT-CI are guesses */
458
459static void dst_type_flags_print(u32 type_flags)
460{
461 printk("DST type flags :");
462 if (type_flags & DST_TYPE_HAS_NEWTUNE)
463 printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
464 if (type_flags & DST_TYPE_HAS_TS204)
465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
466 if (type_flags & DST_TYPE_HAS_SYMDIV)
467 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
468 printk("\n");
469}
470
471static int dst_type_print(u8 type)
472{
473 char *otype;
474 switch (type) {
475 case DST_TYPE_IS_SAT:
476 otype = "satellite";
477 break;
478 case DST_TYPE_IS_TERR:
479 otype = "terrestrial";
480 break;
481 case DST_TYPE_IS_CABLE:
482 otype = "cable";
483 break;
484 default:
485 printk("%s: invalid dst type %d\n", __FUNCTION__, type);
486 return -EINVAL;
487 }
488 printk("DST type : %s\n", otype);
489 return 0;
490}
491
492static int dst_check_ci(struct dst_state *state)
493{
494 u8 txbuf[8];
495 u8 rxbuf[8];
496 int retval;
497 int i;
498 struct dst_types *dsp;
499 u8 use_dst_type;
500 u32 use_type_flags;
501
502 memset(txbuf, 0, sizeof(txbuf));
503 txbuf[1] = 6;
504 txbuf[7] = dst_check_sum(txbuf, 7);
505
506 dst_i2c_enable(state);
507 dst_reset8820(state);
508 retval = write_dst(state, txbuf, 8);
509 if (retval < 0) {
510 dst_i2c_disable(state);
511 dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__);
512 return retval;
513 }
514 msleep(3);
515 retval = read_dst(state, rxbuf, 1);
516 dst_i2c_disable(state);
517 if (retval < 0) {
518 dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__);
519 return retval;
520 }
521 if (rxbuf[0] != 0xff) {
522 dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
523 return retval;
524 }
525 if (!dst_wait_dst_ready(state))
526 return 0;
527 // dst_i2c_enable(i2c); Dimitri
528 retval = read_dst(state, rxbuf, 8);
529 dst_i2c_disable(state);
530 if (retval < 0) {
531 dprintk("%s: read not successful\n", __FUNCTION__);
532 return retval;
533 }
534 if (rxbuf[7] != dst_check_sum(rxbuf, 7)) {
535 dprintk("%s: checksum failure\n", __FUNCTION__);
536 return retval;
537 }
538 rxbuf[7] = '\0';
539 for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) {
540 if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) {
541 use_type_flags = dsp->type_flags;
542 use_dst_type = dsp->dst_type;
543 printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);
544 break;
545 }
546 }
547 if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {
548 printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);
549 printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
550 use_dst_type = DST_TYPE_IS_SAT;
551 use_type_flags = DST_TYPE_HAS_SYMDIV;
552 }
553 dst_type_print(use_dst_type);
554
555 state->type_flags = use_type_flags;
556 state->dst_type = use_dst_type;
557 dst_type_flags_print(state->type_flags);
558
559 if (state->type_flags & DST_TYPE_HAS_TS204) {
560 dst_packsize(state, 204);
561 }
562 return 0;
563}
564
565static int dst_command(struct dst_state* state, u8 * data, u8 len)
566{
567 int retval;
568 u8 reply;
569
570 dst_i2c_enable(state);
571 dst_reset8820(state);
572 retval = write_dst(state, data, len);
573 if (retval < 0) {
574 dst_i2c_disable(state);
575 dprintk("%s: write not successful\n", __FUNCTION__);
576 return retval;
577 }
578 msleep(33);
579 retval = read_dst(state, &reply, 1);
580 dst_i2c_disable(state);
581 if (retval < 0) {
582 dprintk("%s: read verify not successful\n", __FUNCTION__);
583 return retval;
584 }
585 if (reply != 0xff) {
586 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
587 return 0;
588 }
589 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
590 return 0;
591 if (!dst_wait_dst_ready(state))
592 return 0;
593 // dst_i2c_enable(i2c); Per dimitri
594 retval = read_dst(state, state->rxbuffer, 8);
595 dst_i2c_disable(state);
596 if (retval < 0) {
597 dprintk("%s: read not successful\n", __FUNCTION__);
598 return 0;
599 }
600 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
601 dprintk("%s: checksum failure\n", __FUNCTION__);
602 return 0;
603 }
604 return 0;
605}
606
607static int dst_get_signal(struct dst_state* state)
608{
609 int retval;
610 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
611
612 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
613 state->decode_lock = state->decode_strength = state->decode_snr = 0;
614 return 0;
615 }
616 if (0 == (state->diseq_flags & HAS_LOCK)) {
617 state->decode_lock = state->decode_strength = state->decode_snr = 0;
618 return 0;
619 }
620 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
621 retval = dst_command(state, get_signal, 8);
622 if (retval < 0)
623 return retval;
624 if (state->dst_type == DST_TYPE_IS_SAT) {
625 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
626 state->decode_strength = state->rxbuffer[5] << 8;
627 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
628 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
629 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
630 state->decode_strength = state->rxbuffer[4] << 8;
631 state->decode_snr = state->rxbuffer[3] << 8;
632 }
633 state->cur_jiff = jiffies;
634 }
635 return 0;
636}
637
638static int dst_tone_power_cmd(struct dst_state* state)
639{
640 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
641
642 if (state->dst_type == DST_TYPE_IS_TERR)
643 return 0;
644
645 if (state->voltage == SEC_VOLTAGE_OFF)
646 paket[4] = 0;
647 else
648 paket[4] = 1;
649 if (state->tone == SEC_TONE_ON)
650 paket[2] = state->k22;
651 else
652 paket[2] = 0;
653 paket[7] = dst_check_sum(&paket[0], 7);
654 dst_command(state, paket, 8);
655 return 0;
656}
657
658static int dst_get_tuna(struct dst_state* state)
659{
660 int retval;
661 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
662 return 0;
663 state->diseq_flags &= ~(HAS_LOCK);
664 if (!dst_wait_dst_ready(state))
665 return 0;
666 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
667 /* how to get variable length reply ???? */
668 retval = read_dst(state, state->rx_tuna, 10);
669 } else {
670 retval = read_dst(state, &state->rx_tuna[2], 8);
671 }
672 if (retval < 0) {
673 dprintk("%s: read not successful\n", __FUNCTION__);
674 return 0;
675 }
676 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
677 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
678 dprintk("%s: checksum failure?\n", __FUNCTION__);
679 return 0;
680 }
681 } else {
682 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
683 dprintk("%s: checksum failure?\n", __FUNCTION__);
684 return 0;
685 }
686 }
687 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
688 return 0;
689 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
690
691 state->decode_lock = 1;
692 /*
693 dst->decode_n1 = (dst->rx_tuna[4] << 8) +
694 (dst->rx_tuna[5]);
695
696 dst->decode_n2 = (dst->rx_tuna[8] << 8) +
697 (dst->rx_tuna[7]);
698 */
699 state->diseq_flags |= HAS_LOCK;
700 /* dst->cur_jiff = jiffies; */
701 return 1;
702}
703
704static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
705
706static int dst_write_tuna(struct dvb_frontend* fe)
707{
708 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
709 int retval;
710 u8 reply;
711
712 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
713 state->decode_freq = 0;
714 state->decode_lock = state->decode_strength = state->decode_snr = 0;
715 if (state->dst_type == DST_TYPE_IS_SAT) {
716 if (!(state->diseq_flags & HAS_POWER))
717 dst_set_voltage(fe, SEC_VOLTAGE_13);
718 }
719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
720 dst_i2c_enable(state);
721 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
722 dst_reset8820(state);
723 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
724 retval = write_dst(state, &state->tx_tuna[0], 10);
725 } else {
726 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
727 retval = write_dst(state, &state->tx_tuna[2], 8);
728 }
729 if (retval < 0) {
730 dst_i2c_disable(state);
731 dprintk("%s: write not successful\n", __FUNCTION__);
732 return retval;
733 }
734 msleep(3);
735 retval = read_dst(state, &reply, 1);
736 dst_i2c_disable(state);
737 if (retval < 0) {
738 dprintk("%s: read verify not successful\n", __FUNCTION__);
739 return retval;
740 }
741 if (reply != 0xff) {
742 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
743 return 0;
744 }
745 state->diseq_flags |= ATTEMPT_TUNE;
746 return dst_get_tuna(state);
747}
748
749/*
750 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
751 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
752 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
753 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
754 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
755 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
756 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
757 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
758 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
759 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
760 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
761 */
762
763static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
764{
765 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
766 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
767
768 if (state->dst_type == DST_TYPE_IS_TERR)
769 return 0;
770
771 if (cmd->msg_len == 0 || cmd->msg_len > 4)
772 return -EINVAL;
773 memcpy(&paket[3], cmd->msg, cmd->msg_len);
774 paket[7] = dst_check_sum(&paket[0], 7);
775 dst_command(state, paket, 8);
776 return 0;
777}
778
779static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
780{
781 u8 *val;
782 int need_cmd;
783 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
784
785 state->voltage = voltage;
786
787 if (state->dst_type == DST_TYPE_IS_TERR)
788 return 0;
789
790 need_cmd = 0;
791 val = &state->tx_tuna[0];
792 val[8] &= ~0x40;
793 switch (voltage) {
794 case SEC_VOLTAGE_13:
795 if ((state->diseq_flags & HAS_POWER) == 0)
796 need_cmd = 1;
797 state->diseq_flags |= HAS_POWER;
798 break;
799 case SEC_VOLTAGE_18:
800 if ((state->diseq_flags & HAS_POWER) == 0)
801 need_cmd = 1;
802 state->diseq_flags |= HAS_POWER;
803 val[8] |= 0x40;
804 break;
805 case SEC_VOLTAGE_OFF:
806 need_cmd = 1;
807 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
808 break;
809 default:
810 return -EINVAL;
811 }
812 if (need_cmd) {
813 dst_tone_power_cmd(state);
814 }
815 return 0;
816}
817
818static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
819{
820 u8 *val;
821 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
822
823 state->tone = tone;
824
825 if (state->dst_type == DST_TYPE_IS_TERR)
826 return 0;
827
828 val = &state->tx_tuna[0];
829
830 val[8] &= ~0x1;
831
832 switch (tone) {
833 case SEC_TONE_OFF:
834 break;
835 case SEC_TONE_ON:
836 val[8] |= 1;
837 break;
838 default:
839 return -EINVAL;
840 }
841 dst_tone_power_cmd(state);
842 return 0;
843}
844
845static int dst_init(struct dvb_frontend* fe)
846{
847 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
848 static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
849 static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
850 static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
851 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
852 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
853 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
854 state->inversion = INVERSION_ON;
855 state->voltage = SEC_VOLTAGE_13;
856 state->tone = SEC_TONE_OFF;
857 state->symbol_rate = 29473000;
858 state->fec = FEC_AUTO;
859 state->diseq_flags = 0;
860 state->k22 = 0x02;
861 state->bandwidth = BANDWIDTH_7_MHZ;
862 state->cur_jiff = jiffies;
863 if (state->dst_type == DST_TYPE_IS_SAT) {
864 state->frequency = 950000;
865 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna));
866 } else if (state->dst_type == DST_TYPE_IS_TERR) {
867 state->frequency = 137000000;
868 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna));
869 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
870 state->frequency = 51000000;
871 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
872 }
873
874 return 0;
875}
876
877static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
878{
879 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
880
881 *status = 0;
882 if (state->diseq_flags & HAS_LOCK) {
883 dst_get_signal(state);
884 if (state->decode_lock)
885 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
886 }
887
888 return 0;
889}
890
891static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
892{
893 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
894
895 dst_get_signal(state);
896 *strength = state->decode_strength;
897
898 return 0;
899}
900
901static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
902{
903 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
904
905 dst_get_signal(state);
906 *snr = state->decode_snr;
907
908 return 0;
909}
910
911static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
912{
913 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
914
915 dst_set_freq(state, p->frequency);
916 dst_set_inversion(state, p->inversion);
917 if (state->dst_type == DST_TYPE_IS_SAT) {
918 dst_set_fec(state, p->u.qpsk.fec_inner);
919 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
920 } else if (state->dst_type == DST_TYPE_IS_TERR) {
921 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
922 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
923 dst_set_fec(state, p->u.qam.fec_inner);
924 dst_set_symbolrate(state, p->u.qam.symbol_rate);
925 }
926 dst_write_tuna(fe);
927
928 return 0;
929}
930
931static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
932{
933 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
934
935 p->frequency = state->decode_freq;
936 p->inversion = state->inversion;
937 if (state->dst_type == DST_TYPE_IS_SAT) {
938 p->u.qpsk.symbol_rate = state->symbol_rate;
939 p->u.qpsk.fec_inner = dst_get_fec(state);
940 } else if (state->dst_type == DST_TYPE_IS_TERR) {
941 p->u.ofdm.bandwidth = state->bandwidth;
942 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
943 p->u.qam.symbol_rate = state->symbol_rate;
944 p->u.qam.fec_inner = dst_get_fec(state);
945 p->u.qam.modulation = QAM_AUTO;
946 }
947
948 return 0;
949}
950
951static void dst_release(struct dvb_frontend* fe)
952{
953 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
954 kfree(state);
955}
956
957static struct dvb_frontend_ops dst_dvbt_ops;
958static struct dvb_frontend_ops dst_dvbs_ops;
959static struct dvb_frontend_ops dst_dvbc_ops;
960
961struct dvb_frontend* dst_attach(const struct dst_config* config,
962 struct i2c_adapter* i2c,
963 struct bt878 *bt)
964{
965 struct dst_state* state = NULL;
966
967 /* allocate memory for the internal state */
968 state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL);
969 if (state == NULL) goto error;
970
971 /* setup the state */
972 state->config = config;
973 state->i2c = i2c;
974 state->bt = bt;
975
976 /* check if the demod is there */
977 if (dst_check_ci(state) < 0) goto error;
978
979 /* determine settings based on type */
980 switch (state->dst_type) {
981 case DST_TYPE_IS_TERR:
982 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
983 break;
984 case DST_TYPE_IS_CABLE:
985 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
986 break;
987 case DST_TYPE_IS_SAT:
988 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
989 break;
990 default:
991 printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n");
992 goto error;
993 }
994
995 /* create dvb_frontend */
996 state->frontend.ops = &state->ops;
997 state->frontend.demodulator_priv = state;
998 return &state->frontend;
999
1000error:
1001 kfree(state);
1002 return NULL;
1003}
1004
1005static struct dvb_frontend_ops dst_dvbt_ops = {
1006
1007 .info = {
1008 .name = "DST DVB-T",
1009 .type = FE_OFDM,
1010 .frequency_min = 137000000,
1011 .frequency_max = 858000000,
1012 .frequency_stepsize = 166667,
1013 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1014 },
1015
1016 .release = dst_release,
1017
1018 .init = dst_init,
1019
1020 .set_frontend = dst_set_frontend,
1021 .get_frontend = dst_get_frontend,
1022
1023 .read_status = dst_read_status,
1024 .read_signal_strength = dst_read_signal_strength,
1025 .read_snr = dst_read_snr,
1026};
1027
1028static struct dvb_frontend_ops dst_dvbs_ops = {
1029
1030 .info = {
1031 .name = "DST DVB-S",
1032 .type = FE_QPSK,
1033 .frequency_min = 950000,
1034 .frequency_max = 2150000,
1035 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
1036 .frequency_tolerance = 29500,
1037 .symbol_rate_min = 1000000,
1038 .symbol_rate_max = 45000000,
1039 /* . symbol_rate_tolerance = ???,*/
1040 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1041 },
1042
1043 .release = dst_release,
1044
1045 .init = dst_init,
1046
1047 .set_frontend = dst_set_frontend,
1048 .get_frontend = dst_get_frontend,
1049
1050 .read_status = dst_read_status,
1051 .read_signal_strength = dst_read_signal_strength,
1052 .read_snr = dst_read_snr,
1053
1054 .diseqc_send_master_cmd = dst_set_diseqc,
1055 .set_voltage = dst_set_voltage,
1056 .set_tone = dst_set_tone,
1057};
1058
1059static struct dvb_frontend_ops dst_dvbc_ops = {
1060
1061 .info = {
1062 .name = "DST DVB-C",
1063 .type = FE_QAM,
1064 .frequency_stepsize = 62500,
1065 .frequency_min = 51000000,
1066 .frequency_max = 858000000,
1067 .symbol_rate_min = 1000000,
1068 .symbol_rate_max = 45000000,
1069 /* . symbol_rate_tolerance = ???,*/
1070 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
1071 },
1072
1073 .release = dst_release,
1074
1075 .init = dst_init,
1076
1077 .set_frontend = dst_set_frontend,
1078 .get_frontend = dst_get_frontend,
1079
1080 .read_status = dst_read_status,
1081 .read_signal_strength = dst_read_signal_strength,
1082 .read_snr = dst_read_snr,
1083};
1084
1085MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1086MODULE_AUTHOR("Jamie Honan");
1087MODULE_LICENSE("GPL");
1088
1089EXPORT_SYMBOL(dst_attach);
diff --git a/drivers/media/dvb/bt8xx/dst.h b/drivers/media/dvb/bt8xx/dst.h
new file mode 100644
index 000000000000..bcb418c5c121
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst.h
@@ -0,0 +1,40 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef DST_H
24#define DST_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/device.h>
28#include "bt878.h"
29
30struct dst_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34};
35
36extern struct dvb_frontend* dst_attach(const struct dst_config* config,
37 struct i2c_adapter* i2c,
38 struct bt878 *bt);
39
40#endif // DST_H
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
new file mode 100644
index 000000000000..80488aa628b4
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_priv.h
@@ -0,0 +1,36 @@
1/*
2 * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
3 *
4 * Copyright (C) 2003 Jamie Honan
5 */
6
7struct dst_gpio_enable {
8 u32 mask;
9 u32 enable;
10};
11
12struct dst_gpio_output {
13 u32 mask;
14 u32 highvals;
15};
16
17struct dst_gpio_read {
18 unsigned long value;
19};
20
21union dst_gpio_packet {
22 struct dst_gpio_enable enb;
23 struct dst_gpio_output outp;
24 struct dst_gpio_read rd;
25 int psize;
26};
27
28#define DST_IG_ENABLE 0
29#define DST_IG_WRITE 1
30#define DST_IG_READ 2
31#define DST_IG_TS 3
32
33struct bt878;
34
35int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
36
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
new file mode 100644
index 000000000000..b735397f59aa
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -0,0 +1,797 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
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 */
21
22#include <linux/bitops.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/i2c.h>
30
31#include "dmxdev.h"
32#include "dvbdev.h"
33#include "dvb_demux.h"
34#include "dvb_frontend.h"
35
36#include "dvb-bt8xx.h"
37
38#include "bt878.h"
39
40static int debug;
41
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45#define dprintk( args... ) \
46 do { \
47 if (debug) printk(KERN_DEBUG args); \
48 } while (0)
49
50static void dvb_bt8xx_task(unsigned long data)
51{
52 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
53
54 //printk("%d ", card->bt->finished_block);
55
56 while (card->bt->last_block != card->bt->finished_block) {
57 (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
58 (&card->demux,
59 &card->bt->buf_cpu[card->bt->last_block *
60 card->bt->block_bytes],
61 card->bt->block_bytes);
62 card->bt->last_block = (card->bt->last_block + 1) %
63 card->bt->block_count;
64 }
65}
66
67static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
68{
69 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
70 struct dvb_bt8xx_card *card = dvbdmx->priv;
71 int rc;
72
73 dprintk("dvb_bt8xx: start_feed\n");
74
75 if (!dvbdmx->dmx.frontend)
76 return -EINVAL;
77
78 down(&card->lock);
79 card->nfeeds++;
80 rc = card->nfeeds;
81 if (card->nfeeds == 1)
82 bt878_start(card->bt, card->gpio_mode,
83 card->op_sync_orin, card->irq_err_ignore);
84 up(&card->lock);
85 return rc;
86}
87
88static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
89{
90 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
91 struct dvb_bt8xx_card *card = dvbdmx->priv;
92
93 dprintk("dvb_bt8xx: stop_feed\n");
94
95 if (!dvbdmx->dmx.frontend)
96 return -EINVAL;
97
98 down(&card->lock);
99 card->nfeeds--;
100 if (card->nfeeds == 0)
101 bt878_stop(card->bt);
102 up(&card->lock);
103
104 return 0;
105}
106
107static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
108{
109 if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
110 (adev->subsystem_device == bdev->subsystem_device) &&
111 (adev->bus->number == bdev->bus->number) &&
112 (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
113 return 1;
114 return 0;
115}
116
117static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
118{
119 unsigned int card_nr;
120
121 /* Hmm, n squared. Hope n is small */
122 for (card_nr = 0; card_nr < bt878_num; card_nr++) {
123 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
124 return &bt878[card_nr];
125 }
126 return NULL;
127}
128
129
130static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
131{
132 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
133 static u8 mt352_reset [] = { 0x50, 0x80 };
134 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
135 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
136 static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
137 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
138
139 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
140 udelay(2000);
141 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
143
144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
145 mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
147
148 return 0;
149}
150
151static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
152{
153 u32 div;
154 unsigned char bs = 0;
155 unsigned char cp = 0;
156
157 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
158 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
159
160 if (params->frequency < 542000000) cp = 0xb4;
161 else if (params->frequency < 771000000) cp = 0xbc;
162 else cp = 0xf4;
163
164 if (params->frequency == 0) bs = 0x03;
165 else if (params->frequency < 443250000) bs = 0x02;
166 else bs = 0x08;
167
168 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
169 pllbuf[1] = div >> 8;
170 pllbuf[2] = div & 0xff;
171 pllbuf[3] = cp;
172 pllbuf[4] = bs;
173
174 return 0;
175}
176
177static struct mt352_config thomson_dtt7579_config = {
178
179 .demod_address = 0x0f,
180 .demod_init = thomson_dtt7579_demod_init,
181 .pll_set = thomson_dtt7579_pll_set,
182};
183
184static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
185{
186 u32 freq = params->frequency;
187
188 int i, a, n, pump;
189 u32 band, pll;
190
191
192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
193 1576000,1718000,1856000,2036000,2150000};
194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
195 0x00102000,0x00104000,0x00108000,0x00110000,
196 0x00120000,0x00140000};
197
198#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
199 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
200
201 /* This is really the bit driving the tuner chip cx24108 */
202
203 if(freq<950000) freq=950000; /* kHz */
204 if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
205
206 /* decide which VCO to use for the input frequency */
207 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
208 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
209 band=bandsel[i];
210 /* the gain values must be set by SetSymbolrate */
211 /* compute the pll divider needed, from Conexant data sheet,
212 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
213 depending on the divider bit. It is set to /4 on the 2 lowest
214 bands */
215 n=((i<=2?2:1)*freq*10L)/(XTAL/100);
216 a=n%32; n/=32; if(a==0) n--;
217 pump=(freq<(osci[i-1]+osci[i])/2);
218 pll=0xf8000000|
219 ((pump?1:2)<<(14+11))|
220 ((n&0x1ff)<<(5+11))|
221 ((a&0x1f)<<11);
222 /* everything is shifted left 11 bits to left-align the bits in the
223 32bit word. Output to the tuner goes MSB-aligned, after all */
224 printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
225 cx24110_pll_write(fe,band);
226 /* set vga and vca to their widest-band settings, as a precaution.
227 SetSymbolrate might not be called to set this up */
228 cx24110_pll_write(fe,0x500c0000);
229 cx24110_pll_write(fe,0x83f1f800);
230 cx24110_pll_write(fe,pll);
231/* writereg(client,0x56,0x7f);*/
232
233 return 0;
234}
235
236static int pinnsat_pll_init(struct dvb_frontend* fe)
237{
238 return 0;
239}
240
241
242static struct cx24110_config pctvsat_config = {
243
244 .demod_address = 0x55,
245 .pll_init = pinnsat_pll_init,
246 .pll_set = cx24108_pll_set,
247};
248
249
250static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
251{
252 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
253 u8 cfg, cpump, band_select;
254 u8 data[4];
255 u32 div;
256 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
257
258 div = (36000000 + params->frequency + 83333) / 166666;
259 cfg = 0x88;
260
261 if (params->frequency < 175000000) cpump = 2;
262 else if (params->frequency < 390000000) cpump = 1;
263 else if (params->frequency < 470000000) cpump = 2;
264 else if (params->frequency < 750000000) cpump = 2;
265 else cpump = 3;
266
267 if (params->frequency < 175000000) band_select = 0x0e;
268 else if (params->frequency < 470000000) band_select = 0x05;
269 else band_select = 0x03;
270
271 data[0] = (div >> 8) & 0x7f;
272 data[1] = div & 0xff;
273 data[2] = ((div >> 10) & 0x60) | cfg;
274 data[3] = cpump | band_select;
275
276 i2c_transfer(card->i2c_adapter, &msg, 1);
277 return (div * 166666 - 36000000);
278}
279
280static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
281{
282 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
283
284 return request_firmware(fw, name, &bt->bt->dev->dev);
285}
286
287static struct sp887x_config microtune_mt7202dtf_config = {
288
289 .demod_address = 0x70,
290 .pll_set = microtune_mt7202dtf_pll_set,
291 .request_firmware = microtune_mt7202dtf_request_firmware,
292};
293
294
295
296static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
297{
298 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
299 static u8 mt352_reset [] = { 0x50, 0x80 };
300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
302 0x00, 0xFF, 0x00, 0x40, 0x40 };
303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
305
306
307 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
308 udelay(2000);
309 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
310 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
311
312 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
313 udelay(2000);
314 mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
315 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
316
317 return 0;
318}
319
320static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
321{
322 u32 div;
323 unsigned char bs = 0;
324 unsigned char cp = 0;
325
326 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
327 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
328
329 if (params->frequency < 150000000) cp = 0xB4;
330 else if (params->frequency < 173000000) cp = 0xBC;
331 else if (params->frequency < 250000000) cp = 0xB4;
332 else if (params->frequency < 400000000) cp = 0xBC;
333 else if (params->frequency < 420000000) cp = 0xF4;
334 else if (params->frequency < 470000000) cp = 0xFC;
335 else if (params->frequency < 600000000) cp = 0xBC;
336 else if (params->frequency < 730000000) cp = 0xF4;
337 else cp = 0xFC;
338
339 if (params->frequency < 150000000) bs = 0x01;
340 else if (params->frequency < 173000000) bs = 0x01;
341 else if (params->frequency < 250000000) bs = 0x02;
342 else if (params->frequency < 400000000) bs = 0x02;
343 else if (params->frequency < 420000000) bs = 0x02;
344 else if (params->frequency < 470000000) bs = 0x02;
345 else if (params->frequency < 600000000) bs = 0x08;
346 else if (params->frequency < 730000000) bs = 0x08;
347 else bs = 0x08;
348
349 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
350 pllbuf[1] = div >> 8;
351 pllbuf[2] = div & 0xff;
352 pllbuf[3] = cp;
353 pllbuf[4] = bs;
354
355 return 0;
356}
357
358static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
359
360 .demod_address = 0x0f,
361 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
362 .pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
363};
364
365
366static struct dst_config dst_config = {
367
368 .demod_address = 0x55,
369};
370
371
372static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
373{
374 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
375
376 return request_firmware(fw, name, &bt->bt->dev->dev);
377}
378
379static void or51211_setmode(struct dvb_frontend * fe, int mode)
380{
381 struct dvb_bt8xx_card *bt = fe->dvb->priv;
382 bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */
383 msleep(20);
384}
385
386static void or51211_reset(struct dvb_frontend * fe)
387{
388 struct dvb_bt8xx_card *bt = fe->dvb->priv;
389
390 /* RESET DEVICE
391 * reset is controled by GPIO-0
392 * when set to 0 causes reset and when to 1 for normal op
393 * must remain reset for 128 clock cycles on a 50Mhz clock
394 * also PRM1 PRM2 & PRM4 are controled by GPIO-1,GPIO-2 & GPIO-4
395 * We assume that the reset has be held low long enough or we
396 * have been reset by a power on. When the driver is unloaded
397 * reset set to 0 so if reloaded we have been reset.
398 */
399 /* reset & PRM1,2&4 are outputs */
400 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
401 if (ret != 0) {
402 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
403 "(%i)\n", ret);
404 }
405 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
406 msleep(20);
407 /* Now set for normal operation */
408 bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
409 /* wait for operation to begin */
410 msleep(500);
411}
412
413static void or51211_sleep(struct dvb_frontend * fe)
414{
415 struct dvb_bt8xx_card *bt = fe->dvb->priv;
416 bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
417}
418
419static struct or51211_config or51211_config = {
420
421 .demod_address = 0x15,
422 .request_firmware = or51211_request_firmware,
423 .setmode = or51211_setmode,
424 .reset = or51211_reset,
425 .sleep = or51211_sleep,
426};
427
428
429static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
430{
431 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
432 u8 buf[4];
433 u32 div;
434 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
435
436 div = (params->frequency + 36166667) / 166667;
437
438 buf[0] = (div >> 8) & 0x7F;
439 buf[1] = div & 0xFF;
440 buf[2] = 0x85;
441 if ((params->frequency >= 47000000) && (params->frequency < 153000000))
442 buf[3] = 0x01;
443 else if ((params->frequency >= 153000000) && (params->frequency < 430000000))
444 buf[3] = 0x02;
445 else if ((params->frequency >= 430000000) && (params->frequency < 824000000))
446 buf[3] = 0x0C;
447 else if ((params->frequency >= 824000000) && (params->frequency < 863000000))
448 buf[3] = 0x8C;
449 else
450 return -EINVAL;
451
452 i2c_transfer(card->i2c_adapter, &msg, 1);
453 return 0;
454}
455
456static struct nxt6000_config vp3021_alps_tded4_config = {
457
458 .demod_address = 0x0a,
459 .clock_inversion = 1,
460 .pll_set = vp3021_alps_tded4_pll_set,
461};
462
463
464static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
465{
466 switch(type) {
467#ifdef BTTV_DVICO_DVBT_LITE
468 case BTTV_DVICO_DVBT_LITE:
469 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
470 if (card->fe != NULL) {
471 card->fe->ops->info.frequency_min = 174000000;
472 card->fe->ops->info.frequency_max = 862000000;
473 break;
474 }
475 break;
476#endif
477
478#ifdef BTTV_TWINHAN_VP3021
479 case BTTV_TWINHAN_VP3021:
480#else
481 case BTTV_NEBULA_DIGITV:
482#endif
483 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
484 if (card->fe != NULL) {
485 break;
486 }
487 break;
488
489 case BTTV_AVDVBT_761:
490 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
491 if (card->fe != NULL) {
492 break;
493 }
494 break;
495
496 case BTTV_AVDVBT_771:
497 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
498 if (card->fe != NULL) {
499 card->fe->ops->info.frequency_min = 174000000;
500 card->fe->ops->info.frequency_max = 862000000;
501 break;
502 }
503 break;
504
505 case BTTV_TWINHAN_DST:
506 card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt);
507 if (card->fe != NULL) {
508 break;
509 }
510 break;
511
512 case BTTV_PINNACLESAT:
513 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
514 if (card->fe != NULL) {
515 break;
516 }
517 break;
518
519 case BTTV_PC_HDTV:
520 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
521 if (card->fe != NULL) {
522 break;
523 }
524 break;
525 }
526
527 if (card->fe == NULL) {
528 printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
529 card->bt->dev->vendor,
530 card->bt->dev->device,
531 card->bt->dev->subsystem_vendor,
532 card->bt->dev->subsystem_device);
533 } else {
534 if (dvb_register_frontend(card->dvb_adapter, card->fe)) {
535 printk("dvb-bt8xx: Frontend registration failed!\n");
536 if (card->fe->ops->release)
537 card->fe->ops->release(card->fe);
538 card->fe = NULL;
539 }
540 }
541}
542
543static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
544{
545 int result;
546
547 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
548 THIS_MODULE)) < 0) {
549 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
550 return result;
551
552 }
553 card->dvb_adapter->priv = card;
554
555 card->bt->adapter = card->i2c_adapter;
556
557 memset(&card->demux, 0, sizeof(struct dvb_demux));
558
559 card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
560
561 card->demux.priv = card;
562 card->demux.filternum = 256;
563 card->demux.feednum = 256;
564 card->demux.start_feed = dvb_bt8xx_start_feed;
565 card->demux.stop_feed = dvb_bt8xx_stop_feed;
566 card->demux.write_to_decoder = NULL;
567
568 if ((result = dvb_dmx_init(&card->demux)) < 0) {
569 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
570
571 dvb_unregister_adapter(card->dvb_adapter);
572 return result;
573 }
574
575 card->dmxdev.filternum = 256;
576 card->dmxdev.demux = &card->demux.dmx;
577 card->dmxdev.capabilities = 0;
578
579 if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) {
580 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
581
582 dvb_dmx_release(&card->demux);
583 dvb_unregister_adapter(card->dvb_adapter);
584 return result;
585 }
586
587 card->fe_hw.source = DMX_FRONTEND_0;
588
589 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
590 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
591
592 dvb_dmxdev_release(&card->dmxdev);
593 dvb_dmx_release(&card->demux);
594 dvb_unregister_adapter(card->dvb_adapter);
595 return result;
596 }
597
598 card->fe_mem.source = DMX_MEMORY_FE;
599
600 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) {
601 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
602
603 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
604 dvb_dmxdev_release(&card->dmxdev);
605 dvb_dmx_release(&card->demux);
606 dvb_unregister_adapter(card->dvb_adapter);
607 return result;
608 }
609
610 if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
611 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
612
613 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
614 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
615 dvb_dmxdev_release(&card->dmxdev);
616 dvb_dmx_release(&card->demux);
617 dvb_unregister_adapter(card->dvb_adapter);
618 return result;
619 }
620
621 dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
622
623 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
624
625 frontend_init(card, type);
626
627 return 0;
628}
629
630static int dvb_bt8xx_probe(struct device *dev)
631{
632 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
633 struct dvb_bt8xx_card *card;
634 struct pci_dev* bttv_pci_dev;
635 int ret;
636
637 if (!(card = kmalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
638 return -ENOMEM;
639
640 memset(card, 0, sizeof(*card));
641 init_MUTEX(&card->lock);
642 card->bttv_nr = sub->core->nr;
643 strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
644 card->i2c_adapter = &sub->core->i2c_adap;
645
646 switch(sub->core->type)
647 {
648 case BTTV_PINNACLESAT:
649 card->gpio_mode = 0x0400c060;
650 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
651 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
652 card->op_sync_orin = 0;
653 card->irq_err_ignore = 0;
654 break;
655
656#ifdef BTTV_DVICO_DVBT_LITE
657 case BTTV_DVICO_DVBT_LITE:
658#endif
659 card->gpio_mode = 0x0400C060;
660 card->op_sync_orin = 0;
661 card->irq_err_ignore = 0;
662 /* 26, 15, 14, 6, 5
663 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA
664 * DA_APP(parallel) */
665 break;
666
667#ifdef BTTV_TWINHAN_VP3021
668 case BTTV_TWINHAN_VP3021:
669#else
670 case BTTV_NEBULA_DIGITV:
671#endif
672 case BTTV_AVDVBT_761:
673 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
674 card->op_sync_orin = 0;
675 card->irq_err_ignore = 0;
676 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
677 break;
678
679 case BTTV_AVDVBT_771: //case 0x07711461:
680 card->gpio_mode = 0x0400402B;
681 card->op_sync_orin = BT878_RISC_SYNC_MASK;
682 card->irq_err_ignore = 0;
683 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
684 break;
685
686 case BTTV_TWINHAN_DST:
687 card->gpio_mode = 0x2204f2c;
688 card->op_sync_orin = BT878_RISC_SYNC_MASK;
689 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
690 BT878_APPERR | BT878_AFBUS;
691 /* 25,21,14,11,10,9,8,3,2 then
692 * 0x33 = 5,4,1,0
693 * A_SEL=SML, DA_MLB, DA_SBR,
694 * DA_SDR=f, fifo trigger = 32 DWORDS
695 * IOM = 0 == audio A/D
696 * DPM = 0 == digital audio mode
697 * == async data parallel port
698 * then 0x33 (13 is set by start_capture)
699 * DA_APP = async data parallel port,
700 * ACAP_EN = 1,
701 * RISC+FIFO ENABLE */
702 break;
703
704 case BTTV_PC_HDTV:
705 card->gpio_mode = 0x0100EC7B;
706 card->op_sync_orin = 0;
707 card->irq_err_ignore = 0;
708 break;
709
710 default:
711 printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n",
712 sub->core->type);
713 kfree(card);
714 return -ENODEV;
715 }
716
717 dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
718
719 if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
720 printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr);
721 kfree(card);
722 return -EFAULT;
723 }
724
725 if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
726 printk("dvb_bt8xx: unable to determine DMA core of card %d,\n",
727 card->bttv_nr);
728 printk("dvb_bt8xx: if you have the ALSA bt87x audio driver "
729 "installed, try removing it.\n");
730
731 kfree(card);
732 return -EFAULT;
733
734 }
735
736 init_MUTEX(&card->bt->gpio_lock);
737 card->bt->bttv_nr = sub->core->nr;
738
739 if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
740 kfree(card);
741 return ret;
742 }
743
744 dev_set_drvdata(dev, card);
745 return 0;
746}
747
748static int dvb_bt8xx_remove(struct device *dev)
749{
750 struct dvb_bt8xx_card *card = dev_get_drvdata(dev);
751
752 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
753
754 bt878_stop(card->bt);
755 tasklet_kill(&card->bt->tasklet);
756 dvb_net_release(&card->dvbnet);
757 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
758 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
759 dvb_dmxdev_release(&card->dmxdev);
760 dvb_dmx_release(&card->demux);
761 if (card->fe) dvb_unregister_frontend(card->fe);
762 dvb_unregister_adapter(card->dvb_adapter);
763
764 kfree(card);
765
766 return 0;
767}
768
769static struct bttv_sub_driver driver = {
770 .drv = {
771 .name = "dvb-bt8xx",
772 .probe = dvb_bt8xx_probe,
773 .remove = dvb_bt8xx_remove,
774 /* FIXME:
775 * .shutdown = dvb_bt8xx_shutdown,
776 * .suspend = dvb_bt8xx_suspend,
777 * .resume = dvb_bt8xx_resume,
778 */
779 },
780};
781
782static int __init dvb_bt8xx_init(void)
783{
784 return bttv_sub_register(&driver, "dvb");
785}
786
787static void __exit dvb_bt8xx_exit(void)
788{
789 bttv_sub_unregister(&driver);
790}
791
792module_init(dvb_bt8xx_init);
793module_exit(dvb_bt8xx_exit);
794
795MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
796MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
797MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
new file mode 100644
index 000000000000..80ef189f930f
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -0,0 +1,59 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
5 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
6 * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
7 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.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
25#ifndef DVB_BT8XX_H
26#define DVB_BT8XX_H
27
28#include <linux/i2c.h>
29#include "dvbdev.h"
30#include "dvb_net.h"
31#include "bttv.h"
32#include "mt352.h"
33#include "sp887x.h"
34#include "dst.h"
35#include "nxt6000.h"
36#include "cx24110.h"
37#include "or51211.h"
38
39struct dvb_bt8xx_card {
40 struct semaphore lock;
41 int nfeeds;
42 char card_name[32];
43 struct dvb_adapter *dvb_adapter;
44 struct bt878 *bt;
45 unsigned int bttv_nr;
46 struct dvb_demux demux;
47 struct dmxdev dmxdev;
48 struct dmx_frontend fe_hw;
49 struct dmx_frontend fe_mem;
50 u32 gpio_mode;
51 u32 op_sync_orin;
52 u32 irq_err_ignore;
53 struct i2c_adapter *i2c_adapter;
54 struct dvb_net dvbnet;
55
56 struct dvb_frontend* fe;
57};
58
59#endif /* DVB_BT8XX_H */
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
new file mode 100644
index 000000000000..226714085f58
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -0,0 +1,85 @@
1config DVB_CINERGYT2
2 tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
3 depends on DVB_CORE && USB
4 help
5 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
6
7 Say Y if you own such a device and want to use it.
8
9
10config DVB_CINERGYT2_TUNING
11 bool "sophisticated fine-tuning for CinergyT2 cards"
12 depends on DVB_CINERGYT2
13 help
14 Here you can fine-tune some parameters of the CinergyT2 driver.
15
16 Normally you don't need to touch this, but in exotic setups you
17 may fine-tune your setup and adjust e.g. DMA buffer sizes for
18 a particular application.
19
20
21config DVB_CINERGYT2_STREAM_URB_COUNT
22 int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
23 depends on DVB_CINERGYT2_TUNING
24 default "32"
25 help
26 USB Request Blocks for Highspeed Stream transfers are scheduled in
27 a queue for the Host Controller.
28
29 Usually the default value is a safe choice.
30
31 You may increase this number if you are using this device in a
32 Server Environment with many high-traffic USB Highspeed devices
33 sharing the same USB bus.
34
35
36config DVB_CINERGYT2_STREAM_BUF_SIZE
37 int "Size of URB Stream Buffers for Highspeed Transfers"
38 depends on DVB_CINERGYT2_TUNING
39 default "512"
40 help
41 Should be a multiple of native buffer size of 512 bytes.
42 Default value is a safe choice.
43
44 You may increase this number if you are using this device in a
45 Server Environment with many high-traffic USB Highspeed devices
46 sharing the same USB bus.
47
48
49config DVB_CINERGYT2_QUERY_INTERVAL
50 int "Status update interval [milliseconds]"
51 depends on DVB_CINERGYT2_TUNING
52 default "250"
53 help
54 This is the interval for status readouts from the demodulator.
55 You may try lower values if you need more responsive signal quality
56 measurements.
57
58 Please keep in mind that these updates cause traffic on the tuner
59 control bus and thus may or may not affect receiption sensitivity.
60
61 The default value should be a safe choice for common applications.
62
63
64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
65 bool "Register the onboard IR Remote Control Receiver as Input Device"
66 depends on DVB_CINERGYT2_TUNING
67 default "yes"
68 help
69 Enable this option if you want to use the onboard Infrared Remote
70 Control Receiver as Linux-Input device.
71
72 Right now only the keycode table for the default Remote Control
73 delivered with the device is supported, please see the driver
74 source code to find out how to add support for other controls.
75
76
77config DVB_CINERGYT2_RC_QUERY_INTERVAL
78 int "Infrared Remote Controller update interval [milliseconds]"
79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
80 default "100"
81 help
82 If you have a very fast-repeating remote control you can try lower
83 values, for normal consumer receivers the default value should be
84 a safe choice.
85
diff --git a/drivers/media/dvb/cinergyT2/Makefile b/drivers/media/dvb/cinergyT2/Makefile
new file mode 100644
index 000000000000..c51aece20f9f
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
new file mode 100644
index 000000000000..f1f539761371
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -0,0 +1,965 @@
1/*
2 * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
5 * Holger Waechtler <holger@qanu.de>
6 *
7 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
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
25#include <linux/config.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/pci.h>
32#include <linux/input.h>
33#include <linux/dvb/frontend.h>
34
35#include "dmxdev.h"
36#include "dvb_demux.h"
37#include "dvb_net.h"
38
39
40#ifdef CONFIG_DVB_CINERGYT2_TUNING
41 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
42 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
43 #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL)
44 #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
45 #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL)
46 #define ENABLE_RC (1)
47 #endif
48#else
49 #define STREAM_URB_COUNT (32)
50 #define STREAM_BUF_SIZE (512) /* bytes */
51 #define ENABLE_RC (1)
52 #define RC_QUERY_INTERVAL (100) /* milliseconds */
53 #define QUERY_INTERVAL (333) /* milliseconds */
54#endif
55
56#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
57
58static int debug;
59module_param_named(debug, debug, int, 0644);
60MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
61
62#define dprintk(level, args...) \
63do { \
64 if ((debug & level)) { \
65 printk("%s: %s(): ", __stringify(KBUILD_MODNAME), \
66 __FUNCTION__); \
67 printk(args); } \
68} while (0)
69
70enum cinergyt2_ep1_cmd {
71 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
72 CINERGYT2_EP1_PID_SETUP = 0x02,
73 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
74 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
75 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
76 CINERGYT2_EP1_START_SCAN = 0x06,
77 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
78 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
79 CINERGYT2_EP1_SLEEP_MODE = 0x09
80};
81
82struct dvbt_set_parameters_msg {
83 uint8_t cmd;
84 uint32_t freq;
85 uint8_t bandwidth;
86 uint16_t tps;
87 uint8_t flags;
88} __attribute__((packed));
89
90struct dvbt_get_status_msg {
91 uint32_t freq;
92 uint8_t bandwidth;
93 uint16_t tps;
94 uint8_t flags;
95 uint16_t gain;
96 uint8_t snr;
97 uint32_t viterbi_error_rate;
98 uint32_t rs_error_rate;
99 uint32_t uncorrected_block_count;
100 uint8_t lock_bits;
101 uint8_t prev_lock_bits;
102} __attribute__((packed));
103
104static struct dvb_frontend_info cinergyt2_fe_info = {
105 .name = DRIVER_NAME,
106 .type = FE_OFDM,
107 .frequency_min = 174000000,
108 .frequency_max = 862000000,
109 .frequency_stepsize = 166667,
110 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
111 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
112 FE_CAN_FEC_AUTO |
113 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
114 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
115 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS
116};
117
118struct cinergyt2 {
119 struct dvb_demux demux;
120 struct usb_device *udev;
121 struct semaphore sem;
122 struct dvb_adapter *adapter;
123 struct dvb_device *fedev;
124 struct dmxdev dmxdev;
125 struct dvb_net dvbnet;
126
127 int streaming;
128 int sleeping;
129
130 struct dvbt_set_parameters_msg param;
131 struct dvbt_get_status_msg status;
132 struct work_struct query_work;
133
134 wait_queue_head_t poll_wq;
135 int pending_fe_events;
136
137 void *streambuf;
138 dma_addr_t streambuf_dmahandle;
139 struct urb *stream_urb [STREAM_URB_COUNT];
140
141#ifdef ENABLE_RC
142 struct input_dev rc_input_dev;
143 struct work_struct rc_query_work;
144 int rc_input_event;
145#endif
146};
147
148enum {
149 CINERGYT2_RC_EVENT_TYPE_NONE = 0x00,
150 CINERGYT2_RC_EVENT_TYPE_NEC = 0x01,
151 CINERGYT2_RC_EVENT_TYPE_RC5 = 0x02
152};
153
154struct cinergyt2_rc_event {
155 char type;
156 uint32_t value;
157} __attribute__((packed));
158
159static const uint32_t rc_keys [] = {
160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
162 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
163 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfb04eb04, KEY_3,
164 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfa05eb04, KEY_4,
165 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf906eb04, KEY_5,
166 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf807eb04, KEY_6,
167 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf708eb04, KEY_7,
168 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf609eb04, KEY_8,
169 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf50aeb04, KEY_9,
170 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf30ceb04, KEY_0,
171 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf40beb04, KEY_VIDEO,
172 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf20deb04, KEY_REFRESH,
173 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf10eeb04, KEY_SELECT,
174 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf00feb04, KEY_EPG,
175 CINERGYT2_RC_EVENT_TYPE_NEC, 0xef10eb04, KEY_UP,
176 CINERGYT2_RC_EVENT_TYPE_NEC, 0xeb14eb04, KEY_DOWN,
177 CINERGYT2_RC_EVENT_TYPE_NEC, 0xee11eb04, KEY_LEFT,
178 CINERGYT2_RC_EVENT_TYPE_NEC, 0xec13eb04, KEY_RIGHT,
179 CINERGYT2_RC_EVENT_TYPE_NEC, 0xed12eb04, KEY_OK,
180 CINERGYT2_RC_EVENT_TYPE_NEC, 0xea15eb04, KEY_TEXT,
181 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe916eb04, KEY_INFO,
182 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe817eb04, KEY_RED,
183 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe718eb04, KEY_GREEN,
184 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe619eb04, KEY_YELLOW,
185 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe51aeb04, KEY_BLUE,
186 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe31ceb04, KEY_VOLUMEUP,
187 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe11eeb04, KEY_VOLUMEDOWN,
188 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe21deb04, KEY_MUTE,
189 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe41beb04, KEY_CHANNELUP,
190 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe01feb04, KEY_CHANNELDOWN,
191 CINERGYT2_RC_EVENT_TYPE_NEC, 0xbf40eb04, KEY_PAUSE,
192 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb34ceb04, KEY_PLAY,
193 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa758eb04, KEY_RECORD,
194 CINERGYT2_RC_EVENT_TYPE_NEC, 0xab54eb04, KEY_PREVIOUS,
195 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb748eb04, KEY_STOP,
196 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa35ceb04, KEY_NEXT
197};
198
199static int cinergyt2_command (struct cinergyt2 *cinergyt2,
200 char *send_buf, int send_buf_len,
201 char *recv_buf, int recv_buf_len)
202{
203 int actual_len;
204 char dummy;
205 int ret;
206
207 ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1),
208 send_buf, send_buf_len, &actual_len, 1000);
209
210 if (ret)
211 dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret);
212
213 if (!recv_buf)
214 recv_buf = &dummy;
215
216 ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1),
217 recv_buf, recv_buf_len, &actual_len, 1000);
218
219 if (ret)
220 dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret);
221
222 return ret ? ret : actual_len;
223}
224
225static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable)
226{
227 char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
228 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
229}
230
231static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep)
232{
233 char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 };
234 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
235 cinergyt2->sleeping = sleep;
236}
237
238static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs);
239
240static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
241{
242 int err;
243
244 usb_fill_bulk_urb(urb,
245 cinergyt2->udev,
246 usb_rcvbulkpipe(cinergyt2->udev, 0x2),
247 urb->transfer_buffer,
248 STREAM_BUF_SIZE,
249 cinergyt2_stream_irq,
250 cinergyt2);
251
252 if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
253 dprintk(1, "urb submission failed (err = %i)!\n", err);
254
255 return err;
256}
257
258static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs)
259{
260 struct cinergyt2 *cinergyt2 = urb->context;
261
262 if (urb->actual_length > 0)
263 dvb_dmx_swfilter(&cinergyt2->demux,
264 urb->transfer_buffer, urb->actual_length);
265
266 if (cinergyt2->streaming)
267 cinergyt2_submit_stream_urb(cinergyt2, urb);
268}
269
270static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
271{
272 int i;
273
274 for (i=0; i<STREAM_URB_COUNT; i++)
275 if (cinergyt2->stream_urb[i])
276 usb_free_urb(cinergyt2->stream_urb[i]);
277
278 pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE,
279 cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
280}
281
282static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
283{
284 int i;
285
286 cinergyt2->streambuf = pci_alloc_consistent(NULL,
287 STREAM_URB_COUNT*STREAM_BUF_SIZE,
288 &cinergyt2->streambuf_dmahandle);
289 if (!cinergyt2->streambuf) {
290 dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
291 return -ENOMEM;
292 }
293
294 memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE);
295
296 for (i=0; i<STREAM_URB_COUNT; i++) {
297 struct urb *urb;
298
299 if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
300 dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
301 cinergyt2_free_stream_urbs(cinergyt2);
302 return -ENOMEM;
303 }
304
305 urb->transfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE;
306 urb->transfer_buffer_length = STREAM_BUF_SIZE;
307
308 cinergyt2->stream_urb[i] = urb;
309 }
310
311 return 0;
312}
313
314static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
315{
316 int i;
317
318 cinergyt2_control_stream_transfer(cinergyt2, 0);
319
320 for (i=0; i<STREAM_URB_COUNT; i++)
321 if (cinergyt2->stream_urb[i])
322 usb_kill_urb(cinergyt2->stream_urb[i]);
323}
324
325static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)
326{
327 int i, err;
328
329 for (i=0; i<STREAM_URB_COUNT; i++) {
330 if ((err = cinergyt2_submit_stream_urb(cinergyt2, cinergyt2->stream_urb[i]))) {
331 cinergyt2_stop_stream_xfer(cinergyt2);
332 dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err);
333 return err;
334 }
335 }
336
337 cinergyt2_control_stream_transfer(cinergyt2, 1);
338 return 0;
339}
340
341static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
342{
343 struct dvb_demux *demux = dvbdmxfeed->demux;
344 struct cinergyt2 *cinergyt2 = demux->priv;
345
346 if (down_interruptible(&cinergyt2->sem))
347 return -ERESTARTSYS;
348
349 if (cinergyt2->streaming == 0)
350 cinergyt2_start_stream_xfer(cinergyt2);
351
352 cinergyt2->streaming++;
353 up(&cinergyt2->sem);
354 return 0;
355}
356
357static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
358{
359 struct dvb_demux *demux = dvbdmxfeed->demux;
360 struct cinergyt2 *cinergyt2 = demux->priv;
361
362 if (down_interruptible(&cinergyt2->sem))
363 return -ERESTARTSYS;
364
365 if (--cinergyt2->streaming == 0)
366 cinergyt2_stop_stream_xfer(cinergyt2);
367
368 up(&cinergyt2->sem);
369 return 0;
370}
371
372/**
373 * convert linux-dvb frontend parameter set into TPS.
374 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
375 *
376 * This function is probably reusable and may better get placed in a support
377 * library.
378 *
379 * We replace errornous fields by default TPS fields (the ones with value 0).
380 */
381static uint16_t compute_tps (struct dvb_frontend_parameters *p)
382{
383 struct dvb_ofdm_parameters *op = &p->u.ofdm;
384 uint16_t tps = 0;
385
386 switch (op->code_rate_HP) {
387 case FEC_2_3:
388 tps |= (1 << 7);
389 break;
390 case FEC_3_4:
391 tps |= (2 << 7);
392 break;
393 case FEC_5_6:
394 tps |= (3 << 7);
395 break;
396 case FEC_7_8:
397 tps |= (4 << 7);
398 break;
399 case FEC_1_2:
400 case FEC_AUTO:
401 default:
402 /* tps |= (0 << 7) */;
403 }
404
405 switch (op->code_rate_LP) {
406 case FEC_2_3:
407 tps |= (1 << 4);
408 break;
409 case FEC_3_4:
410 tps |= (2 << 4);
411 break;
412 case FEC_5_6:
413 tps |= (3 << 4);
414 break;
415 case FEC_7_8:
416 tps |= (4 << 4);
417 break;
418 case FEC_1_2:
419 case FEC_AUTO:
420 default:
421 /* tps |= (0 << 4) */;
422 }
423
424 switch (op->constellation) {
425 case QAM_16:
426 tps |= (1 << 13);
427 break;
428 case QAM_64:
429 tps |= (2 << 13);
430 break;
431 case QPSK:
432 default:
433 /* tps |= (0 << 13) */;
434 }
435
436 switch (op->transmission_mode) {
437 case TRANSMISSION_MODE_8K:
438 tps |= (1 << 0);
439 break;
440 case TRANSMISSION_MODE_2K:
441 default:
442 /* tps |= (0 << 0) */;
443 }
444
445 switch (op->guard_interval) {
446 case GUARD_INTERVAL_1_16:
447 tps |= (1 << 2);
448 break;
449 case GUARD_INTERVAL_1_8:
450 tps |= (2 << 2);
451 break;
452 case GUARD_INTERVAL_1_4:
453 tps |= (3 << 2);
454 break;
455 case GUARD_INTERVAL_1_32:
456 default:
457 /* tps |= (0 << 2) */;
458 }
459
460 switch (op->hierarchy_information) {
461 case HIERARCHY_1:
462 tps |= (1 << 10);
463 break;
464 case HIERARCHY_2:
465 tps |= (2 << 10);
466 break;
467 case HIERARCHY_4:
468 tps |= (3 << 10);
469 break;
470 case HIERARCHY_NONE:
471 default:
472 /* tps |= (0 << 10) */;
473 }
474
475 return tps;
476}
477
478static int cinergyt2_open (struct inode *inode, struct file *file)
479{
480 struct dvb_device *dvbdev = file->private_data;
481 struct cinergyt2 *cinergyt2 = dvbdev->priv;
482 int err;
483
484 if ((err = dvb_generic_open(inode, file)))
485 return err;
486
487 if (down_interruptible(&cinergyt2->sem))
488 return -ERESTARTSYS;
489
490 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
491 cinergyt2_sleep(cinergyt2, 0);
492 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
493 }
494
495 up(&cinergyt2->sem);
496 return 0;
497}
498
499static int cinergyt2_release (struct inode *inode, struct file *file)
500{
501 struct dvb_device *dvbdev = file->private_data;
502 struct cinergyt2 *cinergyt2 = dvbdev->priv;
503
504 if (down_interruptible(&cinergyt2->sem))
505 return -ERESTARTSYS;
506
507 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
508 cancel_delayed_work(&cinergyt2->query_work);
509 flush_scheduled_work();
510 cinergyt2_sleep(cinergyt2, 1);
511 }
512
513 up(&cinergyt2->sem);
514
515 return dvb_generic_release(inode, file);
516}
517
518static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct *wait)
519{
520 struct dvb_device *dvbdev = file->private_data;
521 struct cinergyt2 *cinergyt2 = dvbdev->priv;
522 poll_wait(file, &cinergyt2->poll_wq, wait);
523 return (POLLIN | POLLRDNORM | POLLPRI);
524}
525
526
527static int cinergyt2_ioctl (struct inode *inode, struct file *file,
528 unsigned cmd, unsigned long arg)
529{
530 struct dvb_device *dvbdev = file->private_data;
531 struct cinergyt2 *cinergyt2 = dvbdev->priv;
532 struct dvbt_get_status_msg *stat = &cinergyt2->status;
533 fe_status_t status = 0;
534
535 switch (cmd) {
536 case FE_GET_INFO:
537 return copy_to_user((void __user*) arg, &cinergyt2_fe_info,
538 sizeof(struct dvb_frontend_info));
539
540 case FE_READ_STATUS:
541 if (0xffff - le16_to_cpu(stat->gain) > 30)
542 status |= FE_HAS_SIGNAL;
543 if (stat->lock_bits & (1 << 6))
544 status |= FE_HAS_LOCK;
545 if (stat->lock_bits & (1 << 5))
546 status |= FE_HAS_SYNC;
547 if (stat->lock_bits & (1 << 4))
548 status |= FE_HAS_CARRIER;
549 if (stat->lock_bits & (1 << 1))
550 status |= FE_HAS_VITERBI;
551
552 return copy_to_user((void __user*) arg, &status, sizeof(status));
553
554 case FE_READ_BER:
555 return put_user(le32_to_cpu(stat->viterbi_error_rate),
556 (__u32 __user *) arg);
557
558 case FE_READ_SIGNAL_STRENGTH:
559 return put_user(0xffff - le16_to_cpu(stat->gain),
560 (__u16 __user *) arg);
561
562 case FE_READ_SNR:
563 return put_user((stat->snr << 8) | stat->snr,
564 (__u16 __user *) arg);
565
566 case FE_READ_UNCORRECTED_BLOCKS:
567 /* UNC are already converted to host byte order... */
568 return put_user(stat->uncorrected_block_count,
569 (__u32 __user *) arg);
570
571 case FE_SET_FRONTEND:
572 {
573 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
574 struct dvb_frontend_parameters p;
575 int err;
576
577 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
578 return -EPERM;
579
580 if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
581 return -EFAULT;
582
583 if (down_interruptible(&cinergyt2->sem))
584 return -ERESTARTSYS;
585
586 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
587 param->tps = cpu_to_le16(compute_tps(&p));
588 param->freq = cpu_to_le32(p.frequency / 1000);
589 param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
590
591 stat->lock_bits = 0;
592 cinergyt2->pending_fe_events++;
593 wake_up_interruptible(&cinergyt2->poll_wq);
594
595 err = cinergyt2_command(cinergyt2,
596 (char *) param, sizeof(*param),
597 NULL, 0);
598
599 up(&cinergyt2->sem);
600
601 return (err < 0) ? err : 0;
602 }
603
604 case FE_GET_FRONTEND:
605 /**
606 * trivial to implement (see struct dvbt_get_status_msg).
607 * equivalent to FE_READ ioctls, but needs
608 * TPS -> linux-dvb parameter set conversion. Feel free
609 * to implement this and send us a patch if you need this
610 * functionality.
611 */
612 break;
613
614 case FE_GET_EVENT:
615 {
616 /**
617 * for now we only fill the status field. the parameters
618 * are trivial to fill as soon FE_GET_FRONTEND is done.
619 */
620 struct dvb_frontend_event __user *e = (void __user *) arg;
621 if (cinergyt2->pending_fe_events == 0) {
622 if (file->f_flags & O_NONBLOCK)
623 return -EWOULDBLOCK;
624 wait_event_interruptible(cinergyt2->poll_wq,
625 cinergyt2->pending_fe_events > 0);
626 }
627 cinergyt2->pending_fe_events = 0;
628 return cinergyt2_ioctl(inode, file, FE_READ_STATUS,
629 (unsigned long) &e->status);
630 }
631
632 default:
633 ;
634 }
635
636 return -EINVAL;
637}
638
639static int cinergyt2_mmap(struct file *file, struct vm_area_struct *vma)
640{
641 struct dvb_device *dvbdev = file->private_data;
642 struct cinergyt2 *cinergyt2 = dvbdev->priv;
643 int ret = 0;
644
645 lock_kernel();
646
647 if (vma->vm_flags & (VM_WRITE | VM_EXEC)) {
648 ret = -EPERM;
649 goto bailout;
650 }
651
652 if (vma->vm_end > vma->vm_start + STREAM_URB_COUNT * STREAM_BUF_SIZE) {
653 ret = -EINVAL;
654 goto bailout;
655 }
656
657 vma->vm_flags |= (VM_IO | VM_DONTCOPY);
658 vma->vm_file = file;
659
660 ret = remap_pfn_range(vma, vma->vm_start,
661 virt_to_phys(cinergyt2->streambuf) >> PAGE_SHIFT,
662 vma->vm_end - vma->vm_start,
663 vma->vm_page_prot) ? -EAGAIN : 0;
664bailout:
665 unlock_kernel();
666 return ret;
667}
668
669static struct file_operations cinergyt2_fops = {
670 .owner = THIS_MODULE,
671 .ioctl = cinergyt2_ioctl,
672 .poll = cinergyt2_poll,
673 .open = cinergyt2_open,
674 .release = cinergyt2_release,
675 .mmap = cinergyt2_mmap
676};
677
678static struct dvb_device cinergyt2_fe_template = {
679 .users = ~0,
680 .writers = 1,
681 .readers = (~0)-1,
682 .fops = &cinergyt2_fops
683};
684
685#ifdef ENABLE_RC
686static void cinergyt2_query_rc (void *data)
687{
688 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
689 char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
690 struct cinergyt2_rc_event rc_events[12];
691 int n, len;
692
693 if (down_interruptible(&cinergyt2->sem))
694 return;
695
696 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
697 (char *) rc_events, sizeof(rc_events));
698
699 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
700 int i;
701
702 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
703 rc_events[n].value == ~0)
704 {
705 /**
706 * keyrepeat bit. If we would handle this properly
707 * we would need to emit down events as long the
708 * keyrepeat goes, a up event if no further
709 * repeat bits occur. Would need a timer to implement
710 * and no other driver does this, so we simply
711 * emit the last key up/down sequence again.
712 */
713 } else {
714 cinergyt2->rc_input_event = KEY_MAX;
715 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
716 if (rc_keys[i+0] == rc_events[n].type &&
717 rc_keys[i+1] == rc_events[n].value)
718 {
719 cinergyt2->rc_input_event = rc_keys[i+2];
720 break;
721 }
722 }
723 }
724
725 if (cinergyt2->rc_input_event != KEY_MAX) {
726 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
727 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
728 input_sync(&cinergyt2->rc_input_dev);
729 }
730 }
731
732 schedule_delayed_work(&cinergyt2->rc_query_work,
733 msecs_to_jiffies(RC_QUERY_INTERVAL));
734
735 up(&cinergyt2->sem);
736}
737#endif
738
739static void cinergyt2_query (void *data)
740{
741 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
742 char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS };
743 struct dvbt_get_status_msg *s = &cinergyt2->status;
744 uint8_t lock_bits;
745 uint32_t unc;
746
747 if (down_interruptible(&cinergyt2->sem))
748 return;
749
750 unc = s->uncorrected_block_count;
751 lock_bits = s->lock_bits;
752
753 cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s));
754
755 unc += le32_to_cpu(s->uncorrected_block_count);
756 s->uncorrected_block_count = unc;
757
758 if (lock_bits != s->lock_bits) {
759 wake_up_interruptible(&cinergyt2->poll_wq);
760 cinergyt2->pending_fe_events++;
761 }
762
763 schedule_delayed_work(&cinergyt2->query_work,
764 msecs_to_jiffies(QUERY_INTERVAL));
765
766 up(&cinergyt2->sem);
767}
768
769static int cinergyt2_probe (struct usb_interface *intf,
770 const struct usb_device_id *id)
771{
772 struct cinergyt2 *cinergyt2;
773 int i, err;
774
775 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
776 dprintk(1, "out of memory?!?\n");
777 return -ENOMEM;
778 }
779
780 memset (cinergyt2, 0, sizeof (struct cinergyt2));
781 usb_set_intfdata (intf, (void *) cinergyt2);
782
783 init_MUTEX(&cinergyt2->sem);
784 init_waitqueue_head (&cinergyt2->poll_wq);
785 INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
786
787 cinergyt2->udev = interface_to_usbdev(intf);
788 cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
789
790 if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) {
791 dprintk(1, "unable to allocate stream urbs\n");
792 kfree(cinergyt2);
793 return -ENOMEM;
794 }
795
796 dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
797
798 cinergyt2->demux.priv = cinergyt2;
799 cinergyt2->demux.filternum = 256;
800 cinergyt2->demux.feednum = 256;
801 cinergyt2->demux.start_feed = cinergyt2_start_feed;
802 cinergyt2->demux.stop_feed = cinergyt2_stop_feed;
803 cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING |
804 DMX_SECTION_FILTERING |
805 DMX_MEMORY_BASED_FILTERING;
806
807 if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) {
808 dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err);
809 goto bailout;
810 }
811
812 cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum;
813 cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
814 cinergyt2->dmxdev.capabilities = 0;
815
816 if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) {
817 dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
818 goto bailout;
819 }
820
821 if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
822 dprintk(1, "dvb_net_init() failed!\n");
823
824 dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev,
825 &cinergyt2_fe_template, cinergyt2,
826 DVB_DEVICE_FRONTEND);
827
828#ifdef ENABLE_RC
829 init_input_dev(&cinergyt2->rc_input_dev);
830
831 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
832 cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
833 cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
834 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
835
836 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
837 set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
838
839 input_register_device(&cinergyt2->rc_input_dev);
840
841 cinergyt2->rc_input_event = KEY_MAX;
842
843 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
844 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
845#endif
846 return 0;
847
848bailout:
849 dvb_dmxdev_release(&cinergyt2->dmxdev);
850 dvb_dmx_release(&cinergyt2->demux);
851 dvb_unregister_adapter (cinergyt2->adapter);
852 cinergyt2_free_stream_urbs (cinergyt2);
853 kfree(cinergyt2);
854 return -ENOMEM;
855}
856
857static void cinergyt2_disconnect (struct usb_interface *intf)
858{
859 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
860
861 if (down_interruptible(&cinergyt2->sem))
862 return;
863
864#ifdef ENABLE_RC
865 cancel_delayed_work(&cinergyt2->rc_query_work);
866 flush_scheduled_work();
867 input_unregister_device(&cinergyt2->rc_input_dev);
868#endif
869
870 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
871 dvb_net_release(&cinergyt2->dvbnet);
872 dvb_dmxdev_release(&cinergyt2->dmxdev);
873 dvb_dmx_release(&cinergyt2->demux);
874 dvb_unregister_device(cinergyt2->fedev);
875 dvb_unregister_adapter(cinergyt2->adapter);
876
877 cinergyt2_free_stream_urbs(cinergyt2);
878 up(&cinergyt2->sem);
879 kfree(cinergyt2);
880}
881
882static int cinergyt2_suspend (struct usb_interface *intf, u32 state)
883{
884 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
885
886 if (down_interruptible(&cinergyt2->sem))
887 return -ERESTARTSYS;
888
889 if (state > 0) { /* state 0 seems to mean DEVICE_PM_ON */
890 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
891#ifdef ENABLE_RC
892 cancel_delayed_work(&cinergyt2->rc_query_work);
893#endif
894 cancel_delayed_work(&cinergyt2->query_work);
895 if (cinergyt2->streaming)
896 cinergyt2_stop_stream_xfer(cinergyt2);
897 flush_scheduled_work();
898 cinergyt2_sleep(cinergyt2, 1);
899 }
900
901 up(&cinergyt2->sem);
902 return 0;
903}
904
905static int cinergyt2_resume (struct usb_interface *intf)
906{
907 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
908 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
909
910 if (down_interruptible(&cinergyt2->sem))
911 return -ERESTARTSYS;
912
913 if (!cinergyt2->sleeping) {
914 cinergyt2_sleep(cinergyt2, 0);
915 cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
916 if (cinergyt2->streaming)
917 cinergyt2_start_stream_xfer(cinergyt2);
918 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
919 }
920
921#ifdef ENABLE_RC
922 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
923#endif
924 up(&cinergyt2->sem);
925 return 0;
926}
927
928static const struct usb_device_id cinergyt2_table [] __devinitdata = {
929 { USB_DEVICE(0x0ccd, 0x0038) },
930 { 0 }
931};
932
933MODULE_DEVICE_TABLE(usb, cinergyt2_table);
934
935static struct usb_driver cinergyt2_driver = {
936 .owner = THIS_MODULE,
937 .name = "cinergyT2",
938 .probe = cinergyt2_probe,
939 .disconnect = cinergyt2_disconnect,
940 .suspend = cinergyt2_suspend,
941 .resume = cinergyt2_resume,
942 .id_table = cinergyt2_table
943};
944
945static int __init cinergyt2_init (void)
946{
947 int err;
948
949 if ((err = usb_register(&cinergyt2_driver)) < 0)
950 dprintk(1, "usb_register() failed! (err %i)\n", err);
951
952 return err;
953}
954
955static void __exit cinergyt2_exit (void)
956{
957 usb_deregister(&cinergyt2_driver);
958}
959
960module_init (cinergyt2_init);
961module_exit (cinergyt2_exit);
962
963MODULE_LICENSE("GPL");
964MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
965
diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
new file mode 100644
index 000000000000..74dfc73ae5b0
--- /dev/null
+++ b/drivers/media/dvb/dibusb/Kconfig
@@ -0,0 +1,62 @@
1config DVB_DIBUSB
2 tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 select DVB_DIB3000MB
6 select DVB_DIB3000MC
7 select DVB_MT352
8 help
9 Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
10 DiBcom (http://www.dibcom.fr) and C&E.
11
12 Devices supported by this driver:
13
14 TwinhanDTV USB-Ter (VP7041)
15 TwinhanDTV Magic Box (VP7041e)
16 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
17 Hama DVB-T USB-Box
18 DiBcom reference devices (non-public)
19 Ultima Electronic/Artec T1 USB TVBOX
20 Compro Videomate DVB-U2000 - DVB-T USB
21 Grandtec DVB-T USB
22 Avermedia AverTV DVBT USB
23 Artec T1 USB1.1 and USB2.0 boxes
24 Yakumo/Typhoon DVB-T USB2.0
25 Hanftek UMT-010 USB2.0
26 Hauppauge WinTV NOVA-T USB2
27
28 The VP7041 seems to be identical to "CTS Portable" (Chinese
29 Television System).
30
31 These devices can be understood as budget ones, they "only" deliver
32 (a part of) the MPEG2 transport stream.
33
34 A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
35 details.
36
37 Say Y if you own such a device and want to use it. You should build it as
38 a module.
39
40config DVB_DIBUSB_MISDESIGNED_DEVICES
41 bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs"
42 depends on DVB_DIBUSB
43 help
44 Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their
45 USB1.1/USB2.0 devices.
46 So comes that they identify with the default Vendor and Product ID of the Cypress
47 CY7C64613 (AN2235) or Cypress FX2.
48
49 Affected device IDs:
50 0x0574:0x2235 (Artec T1 USB1.1, cold)
51 0x04b4:0x8613 (Artec T1 USB2.0, cold)
52 0x0574:0x1002 (Artec T1 USB2.0, warm)
53 0x0574:0x2131 (aged DiBcom USB1.1 test device)
54
55 Say Y if your device has one of the mentioned IDs.
56
57config DVB_DIBCOM_DEBUG
58 bool "Enable extended debug support for DiBcom USB device"
59 depends on DVB_DIBUSB
60 help
61 Say Y if you want to enable debuging. See modinfo dvb-dibusb for
62 debug levels.
diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
new file mode 100644
index 000000000000..e941c508624e
--- /dev/null
+++ b/drivers/media/dvb/dibusb/Makefile
@@ -0,0 +1,11 @@
1dvb-dibusb-objs = dvb-dibusb-core.o \
2 dvb-dibusb-dvb.o \
3 dvb-dibusb-fe-i2c.o \
4 dvb-dibusb-firmware.o \
5 dvb-dibusb-remote.o \
6 dvb-dibusb-usb.o \
7 dvb-fe-dtt200u.o
8
9obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
10
11EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
new file mode 100644
index 000000000000..26235f9247e4
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
@@ -0,0 +1,558 @@
1/*
2 * Driver for mobile USB Budget DVB-T devices based on reference
3 * design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * dvb-dibusb-core.c
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DiBcom, which has
10 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
11 *
12 * Remote control code added by David Matthews (dm@prolingua.co.uk)
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2.
17 *
18 * Acknowledgements
19 *
20 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
21 * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
22 *
23 * see Documentation/dvb/README.dibusb for more information
24 */
25#include "dvb-dibusb.h"
26
27#include <linux/moduleparam.h>
28
29/* debug */
30int dvb_dibusb_debug;
31module_param_named(debug, dvb_dibusb_debug, int, 0644);
32
33#ifdef CONFIG_DVB_DIBCOM_DEBUG
34#define DBSTATUS ""
35#else
36#define DBSTATUS " (debugging is not enabled)"
37#endif
38MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
39#undef DBSTATUS
40
41static int pid_parse;
42module_param(pid_parse, int, 0644);
43MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
44
45static int rc_query_interval = 100;
46module_param(rc_query_interval, int, 0644);
47MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
48
49static int rc_key_repeat_count = 2;
50module_param(rc_key_repeat_count, int, 0644);
51MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
52
53/* Vendor IDs */
54#define USB_VID_ADSTECH 0x06e1
55#define USB_VID_ANCHOR 0x0547
56#define USB_VID_AVERMEDIA 0x14aa
57#define USB_VID_COMPRO 0x185b
58#define USB_VID_COMPRO_UNK 0x145f
59#define USB_VID_CYPRESS 0x04b4
60#define USB_VID_DIBCOM 0x10b8
61#define USB_VID_EMPIA 0xeb1a
62#define USB_VID_GRANDTEC 0x5032
63#define USB_VID_HANFTEK 0x15f4
64#define USB_VID_HAUPPAUGE 0x2040
65#define USB_VID_HYPER_PALTEK 0x1025
66#define USB_VID_IMC_NETWORKS 0x13d3
67#define USB_VID_TWINHAN 0x1822
68#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
69
70/* Product IDs */
71#define USB_PID_ADSTECH_USB2_COLD 0xa333
72#define USB_PID_ADSTECH_USB2_WARM 0xa334
73#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
74#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
75#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
76#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
77#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
78#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
79#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
80#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
81#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
82#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
83#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
84#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
85#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
86#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
87#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
88#define USB_PID_TWINHAN_VP7041_COLD 0x3201
89#define USB_PID_TWINHAN_VP7041_WARM 0x3202
90#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
91#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
92#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
93#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
94#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
95#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
96#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
97#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
98#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
99#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
100#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
101#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
102#define USB_PID_YAKUMO_DTT200U_COLD 0x0201
103#define USB_PID_YAKUMO_DTT200U_WARM 0x0301
104#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
105#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
106
107/* USB Driver stuff
108 * table of devices that this driver is working with
109 *
110 * ATTENTION: Never ever change the order of this table, the particular
111 * devices depend on this order
112 *
113 * Each entry is used as a reference in the device_struct. Currently this is
114 * the only non-redundant way of assigning USB ids to actual devices I'm aware
115 * of, because there is only one place in the code where the assignment of
116 * vendor and product id is done, here.
117 */
118static struct usb_device_id dib_table [] = {
119/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
120/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
121/* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
122/* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
123
124/* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
125/* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
126/* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
127/* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
128/* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
129/* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
130/* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
131/* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
132/* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
133/* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
134/* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
135/* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
136/* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
137/* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
138/* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
139/* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
140/* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
141/* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
142/* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
143/* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
144/* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
145/* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
146/* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
147/* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
148
149/* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
150/* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
151
152/* 30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
153/* 31 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154/* 32 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
155/* 33 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
156/*
157 * activate the following define when you have one of the devices and want to
158 * build it from build-2.6 in dvb-kernel
159 */
160// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
161#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
162/* 34 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
163/* 35 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
164/* 36 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
165/* 37 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) },
166#endif
167 { } /* Terminating entry */
168};
169
170MODULE_DEVICE_TABLE (usb, dib_table);
171
172static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
173 { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
174 { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
175 { .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
176};
177
178struct dibusb_tuner dibusb_tuner[] = {
179 { DIBUSB_TUNER_CABLE_THOMSON,
180 0x61
181 },
182 { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
183 0x60
184 },
185 { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
186 0x61
187 },
188 { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
189 0x60
190 },
191};
192
193static struct dibusb_demod dibusb_demod[] = {
194 { DIBUSB_DIB3000MB,
195 16,
196 { 0x8, 0 },
197 },
198 { DIBUSB_DIB3000MC,
199 32,
200 { 0x9, 0xa, 0xb, 0xc },
201 },
202 { DIBUSB_MT352,
203 254,
204 { 0xf, 0 },
205 },
206 { DTT200U_FE,
207 8,
208 { 0xff,0 }, /* there is no i2c bus in this device */
209 }
210};
211
212static struct dibusb_device_class dibusb_device_classes[] = {
213 { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
214 .firmware = "dvb-dibusb-5.0.0.11.fw",
215 .pipe_cmd = 0x01, .pipe_data = 0x02,
216 .urb_count = 7, .urb_buffer_size = 4096,
217 DIBUSB_RC_NEC_PROTOCOL,
218 &dibusb_demod[DIBUSB_DIB3000MB],
219 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
220 },
221 { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
222 "dvb-dibusb-an2235-1.fw",
223 0x01, 0x02,
224 7, 4096,
225 DIBUSB_RC_NEC_PROTOCOL,
226 &dibusb_demod[DIBUSB_DIB3000MB],
227 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
228 },
229 { DIBUSB2_0,&dibusb_usb_ctrl[2],
230 "dvb-dibusb-6.0.0.5.fw",
231 0x01, 0x06,
232 7, 4096,
233 DIBUSB_RC_NEC_PROTOCOL,
234 &dibusb_demod[DIBUSB_DIB3000MC],
235 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
236 },
237 { UMT2_0, &dibusb_usb_ctrl[2],
238 "dvb-dibusb-umt-2.fw",
239 0x01, 0x06,
240 20, 512,
241 DIBUSB_RC_NO,
242 &dibusb_demod[DIBUSB_MT352],
243 &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
244 },
245 { DIBUSB2_0B,&dibusb_usb_ctrl[2],
246 "dvb-dibusb-adstech-usb2-1.fw",
247 0x01, 0x06,
248 7, 4096,
249 DIBUSB_RC_NEC_PROTOCOL,
250 &dibusb_demod[DIBUSB_DIB3000MB],
251 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
252 },
253 { NOVAT_USB2,&dibusb_usb_ctrl[2],
254 "dvb-dibusb-nova-t-1.fw",
255 0x01, 0x06,
256 7, 4096,
257 DIBUSB_RC_HAUPPAUGE_PROTO,
258 &dibusb_demod[DIBUSB_DIB3000MC],
259 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
260 },
261 { DTT200U,&dibusb_usb_ctrl[2],
262 "dvb-dtt200u-1.fw",
263 0x01, 0x02,
264 7, 4096,
265 DIBUSB_RC_NO,
266 &dibusb_demod[DTT200U_FE],
267 NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
268 },
269};
270
271static struct dibusb_usb_device dibusb_devices[] = {
272 { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
273 &dibusb_device_classes[DIBUSB1_1],
274 { &dib_table[19], &dib_table[21], NULL},
275 { &dib_table[20], &dib_table[22], NULL},
276 },
277 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
278 &dibusb_device_classes[DIBUSB1_1],
279 { &dib_table[11], NULL },
280 { &dib_table[12], NULL },
281 },
282 { "Grandtec USB1.1 DVB-T",
283 &dibusb_device_classes[DIBUSB1_1],
284 { &dib_table[13], &dib_table[15], NULL },
285 { &dib_table[14], &dib_table[16], NULL },
286 },
287 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
288 &dibusb_device_classes[DIBUSB1_1],
289 { &dib_table[7], NULL },
290 { &dib_table[8], NULL },
291 },
292 { "Artec T1 USB1.1 TVBOX with AN2135",
293 &dibusb_device_classes[DIBUSB1_1],
294 { &dib_table[23], NULL },
295 { &dib_table[24], NULL },
296 },
297 { "Artec T1 USB1.1 TVBOX with AN2235",
298 &dibusb_device_classes[DIBUSB1_1_AN2235],
299 { &dib_table[25], NULL },
300 { &dib_table[26], NULL },
301 },
302 { "Avermedia AverTV DVBT USB1.1",
303 &dibusb_device_classes[DIBUSB1_1],
304 { &dib_table[0], NULL },
305 { &dib_table[1], NULL },
306 },
307 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
308 &dibusb_device_classes[DIBUSB1_1],
309 { &dib_table[4], &dib_table[6], NULL},
310 { &dib_table[5], NULL },
311 },
312 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
313 &dibusb_device_classes[DIBUSB1_1],
314 { &dib_table[17], NULL },
315 { &dib_table[18], NULL },
316 },
317 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
318 &dibusb_device_classes[DIBUSB2_0],
319 { &dib_table[9], NULL },
320 { &dib_table[10], NULL },
321 },
322 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
323 &dibusb_device_classes[DIBUSB2_0],
324 { &dib_table[27], NULL },
325 { NULL },
326 },
327 { "Hauppauge WinTV NOVA-T USB2",
328 &dibusb_device_classes[NOVAT_USB2],
329 { &dib_table[30], NULL },
330 { &dib_table[31], NULL },
331 },
332 { "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
333 &dibusb_device_classes[DTT200U],
334 { &dib_table[2], NULL },
335 { &dib_table[3], NULL },
336 },
337 { "Hanftek UMT-010 DVB-T USB2.0",
338 &dibusb_device_classes[UMT2_0],
339 { &dib_table[28], NULL },
340 { &dib_table[29], NULL },
341 },
342 { "KWorld/ADSTech Instant DVB-T USB 2.0",
343 &dibusb_device_classes[DIBUSB2_0B],
344 { &dib_table[32], NULL },
345 { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
346 },
347#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
348 { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
349 &dibusb_device_classes[DIBUSB1_1_AN2235],
350 { &dib_table[34], NULL },
351 { NULL },
352 },
353 { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
354 &dibusb_device_classes[DTT200U],
355 { &dib_table[35], NULL },
356 { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
357 },
358 { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
359 &dibusb_device_classes[DIBUSB1_1],
360 { &dib_table[37], NULL },
361 { NULL },
362 },
363#endif
364};
365
366static int dibusb_exit(struct usb_dibusb *dib)
367{
368 deb_info("init_state before exiting everything: %x\n",dib->init_state);
369 dibusb_remote_exit(dib);
370 dibusb_fe_exit(dib);
371 dibusb_i2c_exit(dib);
372 dibusb_dvb_exit(dib);
373 dibusb_urb_exit(dib);
374 deb_info("init_state should be zero now: %x\n",dib->init_state);
375 dib->init_state = DIBUSB_STATE_INIT;
376 kfree(dib);
377 return 0;
378}
379
380static int dibusb_init(struct usb_dibusb *dib)
381{
382 int ret = 0;
383 sema_init(&dib->usb_sem, 1);
384 sema_init(&dib->i2c_sem, 1);
385
386 dib->init_state = DIBUSB_STATE_INIT;
387
388 if ((ret = dibusb_urb_init(dib)) ||
389 (ret = dibusb_dvb_init(dib)) ||
390 (ret = dibusb_i2c_init(dib))) {
391 dibusb_exit(dib);
392 return ret;
393 }
394
395 if ((ret = dibusb_fe_init(dib)))
396 err("could not initialize a frontend.");
397
398 if ((ret = dibusb_remote_init(dib)))
399 err("could not initialize remote control.");
400
401 return 0;
402}
403
404static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
405{
406 int i;
407
408 /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
409 * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
410 * idea and make this quirk necessary.
411 */
412 if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
413 info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
414 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
415 if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
416 dev = &dibusb_devices[i];
417 break;
418 }
419 }
420 }
421
422 return dev;
423}
424
425static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
426{
427 int i,j;
428 struct dibusb_usb_device *dev = NULL;
429 *cold = -1;
430
431 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
432 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
433 deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
434 if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
435 dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
436 *cold = 1;
437 dev = &dibusb_devices[i];
438 break;
439 }
440 }
441
442 if (dev != NULL)
443 break;
444
445 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
446 deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
447 if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
448 dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
449 *cold = 0;
450 dev = &dibusb_devices[i];
451 break;
452 }
453 }
454 }
455
456 if (dev != NULL)
457 dev = dibusb_device_class_quirk(udev,dev);
458
459 return dev;
460}
461
462/*
463 * USB
464 */
465static int dibusb_probe(struct usb_interface *intf,
466 const struct usb_device_id *id)
467{
468 struct usb_device *udev = interface_to_usbdev(intf);
469 struct usb_dibusb *dib = NULL;
470 struct dibusb_usb_device *dibdev = NULL;
471
472 int ret = -ENOMEM,cold=0;
473
474 if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
475 err("something went very wrong, "
476 "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
477 return -ENODEV;
478 }
479
480 if (cold == 1) {
481 info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
482 ret = dibusb_loadfirmware(udev,dibdev);
483 } else {
484 info("found a '%s' in warm state.",dibdev->name);
485 dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
486 if (dib == NULL) {
487 err("no memory");
488 return ret;
489 }
490 memset(dib,0,sizeof(struct usb_dibusb));
491
492 dib->udev = udev;
493 dib->dibdev = dibdev;
494
495 /* store parameters to structures */
496 dib->rc_query_interval = rc_query_interval;
497 dib->pid_parse = pid_parse;
498 dib->rc_key_repeat_count = rc_key_repeat_count;
499
500 usb_set_intfdata(intf, dib);
501
502 ret = dibusb_init(dib);
503 }
504
505 if (ret == 0)
506 info("%s successfully initialized and connected.",dibdev->name);
507 else
508 info("%s error while loading driver (%d)",dibdev->name,ret);
509 return ret;
510}
511
512static void dibusb_disconnect(struct usb_interface *intf)
513{
514 struct usb_dibusb *dib = usb_get_intfdata(intf);
515 const char *name = DRIVER_DESC;
516
517 usb_set_intfdata(intf,NULL);
518 if (dib != NULL && dib->dibdev != NULL) {
519 name = dib->dibdev->name;
520 dibusb_exit(dib);
521 }
522 info("%s successfully deinitialized and disconnected.",name);
523
524}
525
526/* usb specific object needed to register this driver with the usb subsystem */
527static struct usb_driver dibusb_driver = {
528 .owner = THIS_MODULE,
529 .name = DRIVER_DESC,
530 .probe = dibusb_probe,
531 .disconnect = dibusb_disconnect,
532 .id_table = dib_table,
533};
534
535/* module stuff */
536static int __init usb_dibusb_init(void)
537{
538 int result;
539 if ((result = usb_register(&dibusb_driver))) {
540 err("usb_register failed. Error number %d",result);
541 return result;
542 }
543
544 return 0;
545}
546
547static void __exit usb_dibusb_exit(void)
548{
549 /* deregister this driver from the USB subsystem */
550 usb_deregister(&dibusb_driver);
551}
552
553module_init (usb_dibusb_init);
554module_exit (usb_dibusb_exit);
555
556MODULE_AUTHOR(DRIVER_AUTHOR);
557MODULE_DESCRIPTION(DRIVER_DESC);
558MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
new file mode 100644
index 000000000000..04e54ec093f0
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
@@ -0,0 +1,185 @@
1/*
2 * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * linux-dvb API.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/usb.h>
15#include <linux/version.h>
16
17static u32 urb_compl_count;
18
19/*
20 * MPEG2 TS DVB stuff
21 */
22void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
23{
24 struct usb_dibusb *dib = urb->context;
25
26 deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
27 urb->actual_length);
28
29 urb_compl_count++;
30 if (urb_compl_count % 1000 == 0)
31 deb_info("%d urbs completed so far.\n",urb_compl_count);
32
33 switch (urb->status) {
34 case 0: /* success */
35 case -ETIMEDOUT: /* NAK */
36 break;
37 case -ECONNRESET: /* kill */
38 case -ENOENT:
39 case -ESHUTDOWN:
40 return;
41 default: /* error */
42 deb_ts("urb completition error %d.", urb->status);
43 break;
44 }
45
46 if (dib->feedcount > 0 && urb->actual_length > 0) {
47 if (dib->init_state & DIBUSB_STATE_DVB)
48 dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
49 } else
50 deb_ts("URB dropped because of feedcount.\n");
51
52 usb_submit_urb(urb,GFP_ATOMIC);
53}
54
55static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
56{
57 struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
58 int newfeedcount;
59
60 if (dib == NULL)
61 return -ENODEV;
62
63 newfeedcount = dib->feedcount + (onoff ? 1 : -1);
64
65 /*
66 * stop feed before setting a new pid if there will be no pid anymore
67 */
68 if (newfeedcount == 0) {
69 deb_ts("stop feeding\n");
70 if (dib->xfer_ops.fifo_ctrl != NULL) {
71 if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
72 err("error while inhibiting fifo.");
73 return -ENODEV;
74 }
75 }
76 dibusb_streaming(dib,0);
77 }
78
79 dib->feedcount = newfeedcount;
80
81 /* activate the pid on the device specific pid_filter */
82 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
83 if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL)
84 dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
85
86 /*
87 * start the feed if this was the first pid to set and there is still a pid
88 * for reception.
89 */
90 if (dib->feedcount == onoff && dib->feedcount > 0) {
91
92 deb_ts("controlling pid parser\n");
93 if (dib->xfer_ops.pid_parse != NULL) {
94 if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
95 err("could not handle pid_parser");
96 }
97 }
98
99 deb_ts("start feeding\n");
100 if (dib->xfer_ops.fifo_ctrl != NULL) {
101 if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
102 err("error while enabling fifo.");
103 return -ENODEV;
104 }
105 }
106 dibusb_streaming(dib,1);
107 }
108 return 0;
109}
110
111static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
112{
113 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
114 return dibusb_ctrl_feed(dvbdmxfeed,1);
115}
116
117static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
118{
119 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
120 return dibusb_ctrl_feed(dvbdmxfeed,0);
121}
122
123int dibusb_dvb_init(struct usb_dibusb *dib)
124{
125 int ret;
126
127 urb_compl_count = 0;
128
129 if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC,
130 THIS_MODULE)) < 0) {
131 deb_info("dvb_register_adapter failed: error %d", ret);
132 goto err;
133 }
134 dib->adapter->priv = dib;
135
136/* i2c is done in dibusb_i2c_init */
137
138 dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
139
140 dib->demux.priv = (void *)dib;
141 /* get pidcount from demod */
142 dib->demux.feednum = dib->demux.filternum = 255;
143 dib->demux.start_feed = dibusb_start_feed;
144 dib->demux.stop_feed = dibusb_stop_feed;
145 dib->demux.write_to_decoder = NULL;
146 if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
147 err("dvb_dmx_init failed: error %d",ret);
148 goto err_dmx;
149 }
150
151 dib->dmxdev.filternum = dib->demux.filternum;
152 dib->dmxdev.demux = &dib->demux.dmx;
153 dib->dmxdev.capabilities = 0;
154 if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) {
155 err("dvb_dmxdev_init failed: error %d",ret);
156 goto err_dmx_dev;
157 }
158
159 dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx);
160
161 goto success;
162err_dmx_dev:
163 dvb_dmx_release(&dib->demux);
164err_dmx:
165 dvb_unregister_adapter(dib->adapter);
166err:
167 return ret;
168success:
169 dib->init_state |= DIBUSB_STATE_DVB;
170 return 0;
171}
172
173int dibusb_dvb_exit(struct usb_dibusb *dib)
174{
175 if (dib->init_state & DIBUSB_STATE_DVB) {
176 dib->init_state &= ~DIBUSB_STATE_DVB;
177 deb_info("unregistering DVB part\n");
178 dvb_net_release(&dib->dvb_net);
179 dib->demux.dmx.close(&dib->demux.dmx);
180 dvb_dmxdev_release(&dib->dmxdev);
181 dvb_dmx_release(&dib->demux);
182 dvb_unregister_adapter(dib->adapter);
183 }
184 return 0;
185}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
new file mode 100644
index 000000000000..2ed89488c7c4
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
@@ -0,0 +1,582 @@
1/*
2 * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for attaching, initializing of an appropriate
10 * demodulator/frontend. I2C-stuff is also located here.
11 *
12 */
13#include "dvb-dibusb.h"
14
15#include <linux/usb.h>
16
17static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
18 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
19{
20 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
21 /* write only ? */
22 int wo = (rbuf == NULL || rlen == 0),
23 len = 2 + wlen + (wo ? 0 : 2);
24
25 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
26 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
27
28 memcpy(&sndbuf[2],wbuf,wlen);
29
30 if (!wo) {
31 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
32 sndbuf[wlen+3] = rlen & 0xff;
33 }
34
35 return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
36}
37
38/*
39 * I2C master xfer function
40 */
41static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
42{
43 struct usb_dibusb *dib = i2c_get_adapdata(adap);
44 int i;
45
46 if (down_interruptible(&dib->i2c_sem) < 0)
47 return -EAGAIN;
48
49 if (num > 2)
50 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
51
52 for (i = 0; i < num; i++) {
53 /* write/read request */
54 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
55 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
56 msg[i+1].buf,msg[i+1].len) < 0)
57 break;
58 i++;
59 } else
60 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
61 break;
62 }
63
64 up(&dib->i2c_sem);
65 return i;
66}
67
68static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
69{
70 return I2C_FUNC_I2C;
71}
72
73static struct i2c_algorithm dibusb_algo = {
74 .name = "DiBcom USB i2c algorithm",
75 .id = I2C_ALGO_BIT,
76 .master_xfer = dibusb_i2c_xfer,
77 .functionality = dibusb_i2c_func,
78};
79
80static int dibusb_general_demod_init(struct dvb_frontend *fe);
81static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
82static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
83static int dibusb_general_pll_set(struct dvb_frontend *fe,
84 struct dvb_frontend_parameters* params, u8 pll_buf[5]);
85
86static struct mt352_config mt352_hanftek_umt_010_config = {
87 .demod_address = 0x1e,
88 .demod_init = dibusb_general_demod_init,
89 .pll_set = dibusb_general_pll_set,
90};
91
92static int dibusb_tuner_quirk(struct usb_dibusb *dib)
93{
94 switch (dib->dibdev->dev_cl->id) {
95 case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
96 case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
97 struct dibusb_tuner *t;
98 u8 b[2] = { 0,0 } ,b2[1];
99 struct i2c_msg msg[2] = {
100 { .flags = 0, .buf = b, .len = 2 },
101 { .flags = I2C_M_RD, .buf = b2, .len = 1},
102 };
103
104 t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
105
106 msg[0].addr = msg[1].addr = t->pll_addr;
107
108 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
109 dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
110 dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
111 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
112 dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
113
114 if (b2[0] == 0xfe)
115 info("this device has the Thomson Cable onboard. Which is default.");
116 else {
117 dib->tuner = t;
118 info("this device has the Panasonic ENV77H11D5 onboard.");
119 }
120 break;
121 }
122 default:
123 break;
124 }
125 return 0;
126}
127
128int dibusb_fe_init(struct usb_dibusb* dib)
129{
130 struct dib3000_config demod_cfg;
131 int i;
132
133 if (dib->init_state & DIBUSB_STATE_I2C) {
134 for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) &&
135 dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
136
137 demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
138 demod_cfg.pll_addr = dibusb_general_pll_addr;
139 demod_cfg.pll_set = dibusb_general_pll_set;
140 demod_cfg.pll_init = dibusb_general_pll_init;
141
142 deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE);
143
144 switch (dib->dibdev->dev_cl->demod->id) {
145 case DIBUSB_DIB3000MB:
146 dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
147 break;
148 case DIBUSB_DIB3000MC:
149 dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
150 break;
151 case DIBUSB_MT352:
152 mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
153 dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
154 break;
155 case DTT200U_FE:
156 dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops);
157 break;
158 }
159 if (dib->fe != NULL) {
160 info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
161 break;
162 }
163 }
164 /* if a frontend was found */
165 if (dib->fe != NULL) {
166 if (dib->fe->ops->sleep != NULL)
167 dib->fe_sleep = dib->fe->ops->sleep;
168 dib->fe->ops->sleep = dibusb_hw_sleep;
169
170 if (dib->fe->ops->init != NULL )
171 dib->fe_init = dib->fe->ops->init;
172 dib->fe->ops->init = dibusb_hw_wakeup;
173
174 /* setting the default tuner */
175 dib->tuner = dib->dibdev->dev_cl->tuner;
176
177 /* check which tuner is mounted on this device, in case this is unsure */
178 dibusb_tuner_quirk(dib);
179 }
180 }
181 if (dib->fe == NULL) {
182 err("A frontend driver was not found for device '%s'.",
183 dib->dibdev->name);
184 return -ENODEV;
185 } else {
186 if (dvb_register_frontend(dib->adapter, dib->fe)) {
187 err("Frontend registration failed.");
188 if (dib->fe->ops->release)
189 dib->fe->ops->release(dib->fe);
190 dib->fe = NULL;
191 return -ENODEV;
192 }
193 }
194
195 return 0;
196}
197
198int dibusb_fe_exit(struct usb_dibusb *dib)
199{
200 if (dib->fe != NULL)
201 dvb_unregister_frontend(dib->fe);
202 return 0;
203}
204
205int dibusb_i2c_init(struct usb_dibusb *dib)
206{
207 int ret = 0;
208
209 dib->adapter->priv = dib;
210
211 strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
212#ifdef I2C_ADAP_CLASS_TV_DIGITAL
213 dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
214#else
215 dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
216#endif
217 dib->i2c_adap.algo = &dibusb_algo;
218 dib->i2c_adap.algo_data = NULL;
219 dib->i2c_adap.id = I2C_ALGO_BIT;
220
221 i2c_set_adapdata(&dib->i2c_adap, dib);
222
223 if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
224 err("could not add i2c adapter");
225
226 dib->init_state |= DIBUSB_STATE_I2C;
227
228 return ret;
229}
230
231int dibusb_i2c_exit(struct usb_dibusb *dib)
232{
233 if (dib->init_state & DIBUSB_STATE_I2C)
234 i2c_del_adapter(&dib->i2c_adap);
235 dib->init_state &= ~DIBUSB_STATE_I2C;
236 return 0;
237}
238
239
240/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
241static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
242{
243 u32 tfreq = (fep->frequency + 36125000) / 62500;
244 int vu,p0,p1,p2;
245
246 if (fep->frequency > 403250000)
247 vu = 1, p2 = 1, p1 = 0, p0 = 1;
248 else if (fep->frequency > 115750000)
249 vu = 0, p2 = 1, p1 = 1, p0 = 0;
250 else if (fep->frequency > 44250000)
251 vu = 0, p2 = 0, p1 = 1, p0 = 1;
252 else
253 return -EINVAL;
254
255 pllbuf[0] = (tfreq >> 8) & 0x7f;
256 pllbuf[1] = tfreq & 0xff;
257 pllbuf[2] = 0x8e;
258 pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
259 return 0;
260}
261
262static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
263{
264 u32 freq_khz = fep->frequency / 1000;
265 u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000;
266 u8 TA, T210, R210, ctrl1, cp210, p4321;
267 if (freq_khz > 858000) {
268 err("frequency cannot be larger than 858 MHz.");
269 return -EINVAL;
270 }
271
272 // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
273 TA = 1;
274 T210 = 0;
275 R210 = 0x2;
276 ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
277
278// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES *****************
279 if (freq_khz < 470000)
280 cp210 = 2; // VHF Low and High band ch E12 to E4 to E12
281 else if (freq_khz < 526000)
282 cp210 = 4; // UHF band Ch E21 to E27
283 else // if (freq < 862000000)
284 cp210 = 5; // UHF band ch E28 to E69
285
286//********************* BW select *******************************
287 if (freq_khz < 153000)
288 p4321 = 1; // BW selected for VHF low
289 else if (freq_khz < 470000)
290 p4321 = 2; // BW selected for VHF high E5 to E12
291 else // if (freq < 862000000)
292 p4321 = 4; // BW selection for UHF E21 to E69
293
294 pllbuf[0] = (tfreq >> 8) & 0xff;
295 pllbuf[1] = (tfreq >> 0) & 0xff;
296 pllbuf[2] = 0xff & ctrl1;
297 pllbuf[3] = (cp210 << 5) | (p4321);
298
299 return 0;
300}
301
302/*
303 * 7 6 5 4 3 2 1 0
304 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
305 *
306 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
307 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
308 *
309 * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0
310 * 1 T/A=0 0 0 ATC AL2 AL1 AL0
311 *
312 * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1
313 *
314 * MA0/1 = programmable address bits
315 * R/~W = read/write bit (0 for writing)
316 * N14-0 = programmable LO frequency
317 *
318 * T/A = test AGC bit (0 = next 6 bits AGC setting,
319 * 1 = next 6 bits test and reference divider ratio settings)
320 * T2-0 = test bits
321 * R2-0 = reference divider ratio and programmable frequency step
322 * ATC = AGC current setting and time constant
323 * ATC = 0: AGC current = 220nA, AGC time constant = 2s
324 * ATC = 1: AGC current = 9uA, AGC time constant = 50ms
325 * AL2-0 = AGC take-over point bits
326 * CP2-0 = charge pump current
327 * BS5-1 = PMOS ports control bits;
328 * BSn = 0 corresponding port is off, high-impedance state (at power-on)
329 * BSn = 1 corresponding port is on
330 */
331static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
332{
333 pllbuf[0] = 0x0b;
334 pllbuf[1] = 0xf5;
335 pllbuf[2] = 0x85;
336 pllbuf[3] = 0xab;
337 return 0;
338}
339
340static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
341{
342 int tuner_frequency = 0;
343 u8 band, cp, filter;
344
345 // determine charge pump
346 tuner_frequency = fep->frequency + 36166000;
347 if (tuner_frequency < 87000000)
348 return -EINVAL;
349 else if (tuner_frequency < 130000000)
350 cp = 3;
351 else if (tuner_frequency < 160000000)
352 cp = 5;
353 else if (tuner_frequency < 200000000)
354 cp = 6;
355 else if (tuner_frequency < 290000000)
356 cp = 3;
357 else if (tuner_frequency < 420000000)
358 cp = 5;
359 else if (tuner_frequency < 480000000)
360 cp = 6;
361 else if (tuner_frequency < 620000000)
362 cp = 3;
363 else if (tuner_frequency < 830000000)
364 cp = 5;
365 else if (tuner_frequency < 895000000)
366 cp = 7;
367 else
368 return -EINVAL;
369
370 // determine band
371 if (fep->frequency < 49000000)
372 return -EINVAL;
373 else if (fep->frequency < 161000000)
374 band = 1;
375 else if (fep->frequency < 444000000)
376 band = 2;
377 else if (fep->frequency < 861000000)
378 band = 4;
379 else
380 return -EINVAL;
381
382 // setup PLL filter
383 switch (fep->u.ofdm.bandwidth) {
384 case BANDWIDTH_6_MHZ:
385 case BANDWIDTH_7_MHZ:
386 filter = 0;
387 break;
388 case BANDWIDTH_8_MHZ:
389 filter = 1;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 // calculate divisor
396 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
397 tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
398
399 // setup tuner buffer
400 pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
401 pllbuf[1] = tuner_frequency & 0xff;
402 pllbuf[2] = 0xca;
403 pllbuf[3] = (cp << 5) | (filter << 3) | band;
404 return 0;
405}
406
407/*
408 * 7 6 5 4 3 2 1 0
409 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
410 *
411 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
412 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
413 *
414 * Control byte 1 CP T2 T1 T0 RSA RSB OS
415 *
416 * Band Switch byte X X X P4 P3 P2 P1 P0
417 *
418 * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0
419 *
420 * Address: MA1 MA0 Address
421 * 0 0 c0
422 * 0 1 c2 (always valid)
423 * 1 0 c4
424 * 1 1 c6
425 */
426static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4])
427{
428 u32 div;
429 u8 p210, p3;
430
431#define TUNER_MUL 62500
432
433 div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
434// div = ((fep->frequency/1000 + 36166) * 6) / 1000;
435
436 if (fep->frequency < 174500000)
437 p210 = 1; // not supported by the tdtp_e102p
438 else if (fep->frequency < 230000000) // VHF
439 p210 = 2;
440 else
441 p210 = 4;
442
443 if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
444 p3 = 0;
445 else
446 p3 = 1;
447
448 pllbuf[0] = (div >> 8) & 0x7f;
449 pllbuf[1] = div & 0xff;
450 pllbuf[2] = 0xce;
451// pllbuf[2] = 0xcc;
452 pllbuf[3] = (p3 << 3) | p210;
453
454 return 0;
455}
456
457static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
458{
459 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
460 static u8 mt352_reset[] = { 0x50, 0x80 };
461 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
462 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
463 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
464
465 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
466 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
467 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
468 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
469 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
470
471 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
472 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
473
474 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
475 udelay(2000);
476 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
477 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
478
479 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
480 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
481
482 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
483 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
484 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
485 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
486 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
487
488 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
489 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
490
491 return 0;
492}
493
494static int dibusb_general_demod_init(struct dvb_frontend *fe)
495{
496 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
497 switch (dib->dibdev->dev_cl->id) {
498 case UMT2_0:
499 return lg_tdtp_e102p_mt352_demod_init(fe);
500 default: /* other device classes do not have device specific demod inits */
501 break;
502 }
503 return 0;
504}
505
506static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
507{
508 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
509 return dib->tuner->pll_addr;
510}
511
512static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
513{
514 if (pll_buf == NULL) {
515 struct i2c_msg msg = {
516 .addr = dib->tuner->pll_addr,
517 .flags = 0,
518 .buf = buf,
519 .len = sizeof(buf)
520 };
521 if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
522 return -EIO;
523 msleep(1);
524 } else {
525 pll_buf[0] = dib->tuner->pll_addr << 1;
526 memcpy(&pll_buf[1],buf,4);
527 }
528
529 return 0;
530}
531
532static int dibusb_general_pll_init(struct dvb_frontend *fe,
533 u8 pll_buf[5])
534{
535 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
536 u8 buf[4];
537 int ret=0;
538 switch (dib->tuner->id) {
539 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
540 ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
541 break;
542 default:
543 break;
544 }
545
546 if (ret)
547 return ret;
548
549 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
550}
551
552static int dibusb_general_pll_set(struct dvb_frontend *fe,
553 struct dvb_frontend_parameters *fep, u8 pll_buf[5])
554{
555 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
556 u8 buf[4];
557 int ret=0;
558
559 switch (dib->tuner->id) {
560 case DIBUSB_TUNER_CABLE_THOMSON:
561 ret = thomson_cable_eu_pll_set(fep, buf);
562 break;
563 case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
564 ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
565 break;
566 case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
567 ret = lg_tdtp_e102p_tua6034(fep, buf);
568 break;
569 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
570 ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
571 break;
572 default:
573 warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
574 ret = -ENODEV;
575 break;
576 }
577
578 if (ret)
579 return ret;
580
581 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
582}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
new file mode 100644
index 000000000000..504ba47afdf3
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
@@ -0,0 +1,87 @@
1/*
2 * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for downloading the firmware to the device.
10 */
11#include "dvb-dibusb.h"
12
13#include <linux/firmware.h>
14#include <linux/usb.h>
15
16/*
17 * load a firmware packet to the device
18 */
19static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
20{
21 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
22 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
23}
24
25int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
26{
27 const struct firmware *fw = NULL;
28 u16 addr;
29 u8 *b,*p;
30 int ret = 0,i;
31
32 if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
33 err("did not find the firmware file. (%s) "
34 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
35 dibdev->dev_cl->firmware);
36 return ret;
37 }
38
39 info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware);
40
41 p = kmalloc(fw->size,GFP_KERNEL);
42 if (p != NULL) {
43 u8 reset;
44 /*
45 * you cannot use the fw->data as buffer for
46 * usb_control_msg, a new buffer has to be
47 * created
48 */
49 memcpy(p,fw->data,fw->size);
50
51 /* stop the CPU */
52 reset = 1;
53 if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1)
54 err("could not stop the USB controller CPU.");
55 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
56 b = (u8 *) &p[i];
57 addr = *((u16 *) &b[1]);
58
59 ret = dibusb_writemem(udev,addr,&b[4],b[0]);
60
61 if (ret != b[0]) {
62 err("error while transferring firmware "
63 "(transferred size: %d, block size: %d)",
64 ret,b[0]);
65 ret = -EINVAL;
66 break;
67 }
68 i += 5 + b[0];
69 }
70 /* length in ret */
71 if (ret > 0)
72 ret = 0;
73 /* restart the CPU */
74 reset = 0;
75 if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
76 err("could not restart the USB controller CPU.");
77 ret = -EINVAL;
78 }
79
80 kfree(p);
81 } else {
82 ret = -ENOMEM;
83 }
84 release_firmware(fw);
85
86 return ret;
87}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
new file mode 100644
index 000000000000..9dc8b15517b7
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
@@ -0,0 +1,316 @@
1/*
2 * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for handling the event device on the software
10 * side and the remote control on the hardware side.
11 */
12#include "dvb-dibusb.h"
13
14/* Table to map raw key codes to key events. This should not be hard-wired
15 into the kernel. */
16static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
17{
18 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
19 { 0x00, 0xff, 0x16, KEY_POWER },
20 { 0x00, 0xff, 0x10, KEY_MUTE },
21 { 0x00, 0xff, 0x03, KEY_1 },
22 { 0x00, 0xff, 0x01, KEY_2 },
23 { 0x00, 0xff, 0x06, KEY_3 },
24 { 0x00, 0xff, 0x09, KEY_4 },
25 { 0x00, 0xff, 0x1d, KEY_5 },
26 { 0x00, 0xff, 0x1f, KEY_6 },
27 { 0x00, 0xff, 0x0d, KEY_7 },
28 { 0x00, 0xff, 0x19, KEY_8 },
29 { 0x00, 0xff, 0x1b, KEY_9 },
30 { 0x00, 0xff, 0x15, KEY_0 },
31 { 0x00, 0xff, 0x05, KEY_CHANNELUP },
32 { 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
33 { 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
34 { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
35 { 0x00, 0xff, 0x11, KEY_RECORD },
36 { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
37 { 0x00, 0xff, 0x14, KEY_PLAY },
38 { 0x00, 0xff, 0x1a, KEY_STOP },
39 { 0x00, 0xff, 0x40, KEY_REWIND },
40 { 0x00, 0xff, 0x12, KEY_FASTFORWARD },
41 { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
42 { 0x00, 0xff, 0x4c, KEY_PAUSE },
43 { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
44 { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
45 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
46 { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
47 { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
48 { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
49 { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
50 { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
51 { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
52 /* Key codes for the KWorld/ADSTech/JetWay remote. */
53 { 0x86, 0x6b, 0x12, KEY_POWER },
54 { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
55 { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
56 { 0x86, 0x6b, 0x0b, KEY_EPG },
57 { 0x86, 0x6b, 0x10, KEY_MUTE },
58 { 0x86, 0x6b, 0x01, KEY_1 },
59 { 0x86, 0x6b, 0x02, KEY_2 },
60 { 0x86, 0x6b, 0x03, KEY_3 },
61 { 0x86, 0x6b, 0x04, KEY_4 },
62 { 0x86, 0x6b, 0x05, KEY_5 },
63 { 0x86, 0x6b, 0x06, KEY_6 },
64 { 0x86, 0x6b, 0x07, KEY_7 },
65 { 0x86, 0x6b, 0x08, KEY_8 },
66 { 0x86, 0x6b, 0x09, KEY_9 },
67 { 0x86, 0x6b, 0x0a, KEY_0 },
68 { 0x86, 0x6b, 0x18, KEY_ZOOM },
69 { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
70 { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
71 { 0x86, 0x6b, 0x00, KEY_UNDO },
72 { 0x86, 0x6b, 0x1d, KEY_RECORD },
73 { 0x86, 0x6b, 0x0d, KEY_STOP },
74 { 0x86, 0x6b, 0x0e, KEY_PAUSE },
75 { 0x86, 0x6b, 0x16, KEY_PLAY },
76 { 0x86, 0x6b, 0x11, KEY_BACK },
77 { 0x86, 0x6b, 0x19, KEY_FORWARD },
78 { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
79 { 0x86, 0x6b, 0x15, KEY_ESC },
80 { 0x86, 0x6b, 0x1a, KEY_UP },
81 { 0x86, 0x6b, 0x1e, KEY_DOWN },
82 { 0x86, 0x6b, 0x1f, KEY_LEFT },
83 { 0x86, 0x6b, 0x1b, KEY_RIGHT },
84};
85
86/* Hauppauge NOVA-T USB2 keys */
87static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
88 { 0xddf, KEY_GOTO },
89 { 0xdef, KEY_POWER },
90 { 0xce7, KEY_TV },
91 { 0xcc7, KEY_VIDEO },
92 { 0xccf, KEY_AUDIO },
93 { 0xcd7, KEY_MEDIA },
94 { 0xcdf, KEY_EPG },
95 { 0xca7, KEY_UP },
96 { 0xc67, KEY_RADIO },
97 { 0xcb7, KEY_LEFT },
98 { 0xd2f, KEY_OK },
99 { 0xcbf, KEY_RIGHT },
100 { 0xcff, KEY_BACK },
101 { 0xcaf, KEY_DOWN },
102 { 0xc6f, KEY_MENU },
103 { 0xc87, KEY_VOLUMEUP },
104 { 0xc8f, KEY_VOLUMEDOWN },
105 { 0xc97, KEY_CHANNEL },
106 { 0xc7f, KEY_MUTE },
107 { 0xd07, KEY_CHANNELUP },
108 { 0xd0f, KEY_CHANNELDOWN },
109 { 0xdbf, KEY_RECORD },
110 { 0xdb7, KEY_STOP },
111 { 0xd97, KEY_REWIND },
112 { 0xdaf, KEY_PLAY },
113 { 0xda7, KEY_FASTFORWARD },
114 { 0xd27, KEY_LAST }, /* Skip backwards */
115 { 0xd87, KEY_PAUSE },
116 { 0xcf7, KEY_NEXT },
117 { 0xc07, KEY_0 },
118 { 0xc0f, KEY_1 },
119 { 0xc17, KEY_2 },
120 { 0xc1f, KEY_3 },
121 { 0xc27, KEY_4 },
122 { 0xc2f, KEY_5 },
123 { 0xc37, KEY_6 },
124 { 0xc3f, KEY_7 },
125 { 0xc47, KEY_8 },
126 { 0xc4f, KEY_9 },
127 { 0xc57, KEY_KPASTERISK },
128 { 0xc77, KEY_GRAVE }, /* # */
129 { 0xc5f, KEY_RED },
130 { 0xd77, KEY_GREEN },
131 { 0xdc7, KEY_YELLOW },
132 { 0xd4f, KEY_BLUE},
133};
134
135static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
136{
137 int i;
138 switch (rb[0]) {
139 case DIBUSB_RC_NEC_KEY_PRESSED:
140 /* rb[1-3] is the actual key, rb[4] is a checksum */
141 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
142 rb[1], rb[2], rb[3], rb[4]);
143
144 if ((0xff - rb[3]) != rb[4]) {
145 deb_rc("remote control checksum failed.\n");
146 break;
147 }
148
149 /* See if we can match the raw key code. */
150 for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
151 if (nec_rc_keys[i].c0 == rb[1] &&
152 nec_rc_keys[i].c1 == rb[2] &&
153 nec_rc_keys[i].c2 == rb[3]) {
154
155 dib->last_event = nec_rc_keys[i].key;
156 return 1;
157 }
158 }
159 break;
160 case DIBUSB_RC_NEC_KEY_REPEATED:
161 /* rb[1]..rb[4] are always zero.*/
162 /* Repeats often seem to occur so for the moment just ignore this. */
163 return 0;
164 case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
165 default:
166 break;
167 }
168 return -1;
169}
170
171static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
172{
173 u16 raw;
174 int i,state;
175 switch (rb[0]) {
176 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
177 raw = ((rb[1] & 0x0f) << 8) | rb[2];
178
179 state = !!(rb[1] & 0x40);
180
181 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
182 for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
183 if (haupp_rc_keys[i].raw == raw) {
184 if (dib->last_event == haupp_rc_keys[i].key &&
185 dib->last_state == state) {
186 deb_rc("key repeat\n");
187 return 0;
188 } else {
189 dib->last_event = haupp_rc_keys[i].key;
190 dib->last_state = state;
191 return 1;
192 }
193 }
194 }
195
196 break;
197 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
198 default:
199 break;
200 }
201 return -1;
202}
203
204/*
205 * Read the remote control and feed the appropriate event.
206 * NEC protocol is used for remote controls
207 */
208static int dibusb_read_remote_control(struct usb_dibusb *dib)
209{
210 u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
211 int ret,event = 0;
212
213 if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
214 return ret;
215
216 switch (dib->dibdev->dev_cl->remote_type) {
217 case DIBUSB_RC_NEC_PROTOCOL:
218 event = dibusb_key2event_nec(dib,rb);
219 break;
220 case DIBUSB_RC_HAUPPAUGE_PROTO:
221 event = dibusb_key2event_hauppauge(dib,rb);
222 default:
223 break;
224 }
225
226 /* key repeat */
227 if (event == 0)
228 if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
229 deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
230 event = -1; /* skip this key repeat */
231 }
232
233 if (event == 1 || event == 0) {
234 deb_rc("Translated key 0x%04x\n",event);
235
236 /* Signal down and up events for this key. */
237 input_report_key(&dib->rc_input_dev, dib->last_event, 1);
238 input_report_key(&dib->rc_input_dev, dib->last_event, 0);
239 input_sync(&dib->rc_input_dev);
240
241 if (event == 1)
242 dib->repeat_key_count = 0;
243 }
244 return 0;
245}
246
247/* Remote-control poll function - called every dib->rc_query_interval ms to see
248 whether the remote control has received anything. */
249static void dibusb_remote_query(void *data)
250{
251 struct usb_dibusb *dib = (struct usb_dibusb *) data;
252 /* TODO: need a lock here. We can simply skip checking for the remote control
253 if we're busy. */
254 dibusb_read_remote_control(dib);
255 schedule_delayed_work(&dib->rc_query_work,
256 msecs_to_jiffies(dib->rc_query_interval));
257}
258
259int dibusb_remote_init(struct usb_dibusb *dib)
260{
261 int i;
262
263 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
264 return 0;
265
266 /* Initialise the remote-control structures.*/
267 init_input_dev(&dib->rc_input_dev);
268
269 dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
270 dib->rc_input_dev.keycodesize = sizeof(unsigned char);
271 dib->rc_input_dev.keycodemax = KEY_MAX;
272 dib->rc_input_dev.name = DRIVER_DESC " remote control";
273
274 switch (dib->dibdev->dev_cl->remote_type) {
275 case DIBUSB_RC_NEC_PROTOCOL:
276 for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
277 set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
278 break;
279 case DIBUSB_RC_HAUPPAUGE_PROTO:
280 for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
281 set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
282 break;
283 default:
284 break;
285 }
286
287
288 input_register_device(&dib->rc_input_dev);
289
290 INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
291
292 /* Start the remote-control polling. */
293 if (dib->rc_query_interval < 40)
294 dib->rc_query_interval = 100; /* default */
295
296 info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
297 schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
298
299 dib->init_state |= DIBUSB_STATE_REMOTE;
300
301 return 0;
302}
303
304int dibusb_remote_exit(struct usb_dibusb *dib)
305{
306 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
307 return 0;
308
309 if (dib->init_state & DIBUSB_STATE_REMOTE) {
310 cancel_delayed_work(&dib->rc_query_work);
311 flush_scheduled_work();
312 input_unregister_device(&dib->rc_input_dev);
313 }
314 dib->init_state &= ~DIBUSB_STATE_REMOTE;
315 return 0;
316}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
new file mode 100644
index 000000000000..642f0596a5ba
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
@@ -0,0 +1,303 @@
1/*
2 * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * usb specific stuff.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/version.h>
15#include <linux/pci.h>
16
17int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
18 u16 rlen)
19{
20 int actlen,ret = -ENOMEM;
21
22 if (wbuf == NULL || wlen == 0)
23 return -EINVAL;
24
25 if ((ret = down_interruptible(&dib->usb_sem)))
26 return ret;
27
28 debug_dump(wbuf,wlen);
29
30 ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
31 dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
32 DIBUSB_I2C_TIMEOUT);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
42 dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
43 DIBUSB_I2C_TIMEOUT);
44
45 if (ret)
46 err("recv bulk message failed: %d",ret);
47 else {
48 deb_alot("rlen: %d\n",rlen);
49 debug_dump(rbuf,actlen);
50 }
51 }
52
53 up(&dib->usb_sem);
54 return ret;
55}
56
57/*
58 * Cypress controls
59 */
60int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
61{
62 return dibusb_readwrite_usb(dib,buf,len,NULL,0);
63}
64
65#if 0
66/*
67 * #if 0'ing the following functions as they are not in use _now_,
68 * but probably will be sometime.
69 */
70/*
71 * do not use this, just a workaround for a bug,
72 * which will hopefully never occur :).
73 */
74int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
75{
76 u8 b[1] = { DIBUSB_REQ_INTR_READ };
77 return dibusb_write_usb(dib,b,1);
78}
79#endif
80
81/*
82 * ioctl for the firmware
83 */
84static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
85{
86 u8 b[34];
87 int size = plen > 32 ? 32 : plen;
88 memset(b,0,34);
89 b[0] = DIBUSB_REQ_SET_IOCTL;
90 b[1] = cmd;
91
92 if (size > 0)
93 memcpy(&b[2],param,size);
94
95 return dibusb_write_usb(dib,b,34); //2+size);
96}
97
98/*
99 * ioctl for power control
100 */
101int dibusb_hw_wakeup(struct dvb_frontend *fe)
102{
103 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
104 u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
105 deb_info("dibusb-device is getting up.\n");
106
107 switch (dib->dibdev->dev_cl->id) {
108 case DTT200U:
109 break;
110 default:
111 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
112 break;
113 }
114
115 if (dib->fe_init)
116 return dib->fe_init(fe);
117
118 return 0;
119}
120
121int dibusb_hw_sleep(struct dvb_frontend *fe)
122{
123 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
124 u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
125 deb_info("dibusb-device is going to bed.\n");
126 /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
127 switch (dib->dibdev->dev_cl->id) {
128 case DIBUSB1_1:
129 case NOVAT_USB2:
130 case DTT200U:
131 break;
132 default:
133 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
134 break;
135 }
136 if (dib->fe_sleep)
137 return dib->fe_sleep(fe);
138
139 return 0;
140}
141
142int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
143{
144 u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
145 return dibusb_readwrite_usb(dib,b,2,NULL,0);
146}
147
148static int dibusb_urb_kill(struct usb_dibusb *dib)
149{
150 int i;
151deb_info("trying to kill urbs\n");
152 if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
153 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
154 deb_info("killing URB no. %d.\n",i);
155
156 /* stop the URB */
157 usb_kill_urb(dib->urb_list[i]);
158 }
159 } else
160 deb_info(" URBs not killed.\n");
161 dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
162 return 0;
163}
164
165static int dibusb_urb_submit(struct usb_dibusb *dib)
166{
167 int i,ret;
168 if (dib->init_state & DIBUSB_STATE_URB_INIT) {
169 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
170 deb_info("submitting URB no. %d\n",i);
171 if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
172 err("could not submit buffer urb no. %d - get them all back\n",i);
173 dibusb_urb_kill(dib);
174 return ret;
175 }
176 dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
177 }
178 }
179 return 0;
180}
181
182int dibusb_streaming(struct usb_dibusb *dib,int onoff)
183{
184 if (onoff)
185 dibusb_urb_submit(dib);
186 else
187 dibusb_urb_kill(dib);
188
189 switch (dib->dibdev->dev_cl->id) {
190 case DIBUSB2_0:
191 case DIBUSB2_0B:
192 case NOVAT_USB2:
193 case UMT2_0:
194 if (onoff)
195 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
196 else
197 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
198 break;
199 default:
200 break;
201 }
202 return 0;
203}
204
205int dibusb_urb_init(struct usb_dibusb *dib)
206{
207 int i,bufsize,def_pid_parse = 1;
208
209 /*
210 * when reloading the driver w/o replugging the device
211 * a timeout occures, this helps
212 */
213 usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
214 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
215 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
216
217 /* allocate the array for the data transfer URBs */
218 dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
219 if (dib->urb_list == NULL)
220 return -ENOMEM;
221 memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
222
223 dib->init_state |= DIBUSB_STATE_URB_LIST;
224
225 bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
226 deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
227 /* allocate the actual buffer for the URBs */
228 if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
229 deb_info("not enough memory.\n");
230 return -ENOMEM;
231 }
232 deb_info("allocation complete\n");
233 memset(dib->buffer,0,bufsize);
234
235 dib->init_state |= DIBUSB_STATE_URB_BUF;
236
237 /* allocate and submit the URBs */
238 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
239 if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
240 return -ENOMEM;
241 }
242
243 usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
244 usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
245 &dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
246 dib->dibdev->dev_cl->urb_buffer_size,
247 dibusb_urb_complete, dib);
248
249 dib->urb_list[i]->transfer_flags = 0;
250
251 dib->init_state |= DIBUSB_STATE_URB_INIT;
252 }
253
254 /* dib->pid_parse here contains the value of the module parameter */
255 /* decide if pid parsing can be deactivated:
256 * is possible (by device type) and wanted (by user)
257 */
258 switch (dib->dibdev->dev_cl->id) {
259 case DIBUSB2_0:
260 case DIBUSB2_0B:
261 if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
262 def_pid_parse = 0;
263 info("running at HIGH speed, will deliver the complete TS.");
264 } else
265 info("will use pid_parsing.");
266 break;
267 default:
268 break;
269 }
270 /* from here on it contains the device and user decision */
271 dib->pid_parse = def_pid_parse;
272
273 return 0;
274}
275
276int dibusb_urb_exit(struct usb_dibusb *dib)
277{
278 int i;
279
280 dibusb_urb_kill(dib);
281
282 if (dib->init_state & DIBUSB_STATE_URB_LIST) {
283 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
284 if (dib->urb_list[i] != NULL) {
285 deb_info("freeing URB no. %d.\n",i);
286 /* free the URBs */
287 usb_free_urb(dib->urb_list[i]);
288 }
289 }
290 /* free the urb array */
291 kfree(dib->urb_list);
292 dib->init_state &= ~DIBUSB_STATE_URB_LIST;
293 }
294
295 if (dib->init_state & DIBUSB_STATE_URB_BUF)
296 pci_free_consistent(NULL,
297 dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
298 dib->buffer,dib->dma_handle);
299
300 dib->init_state &= ~DIBUSB_STATE_URB_BUF;
301 dib->init_state &= ~DIBUSB_STATE_URB_INIT;
302 return 0;
303}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
new file mode 100644
index 000000000000..52cd35dd9d83
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb.h
@@ -0,0 +1,327 @@
1/*
2 * dvb-dibusb.h
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dvb-dibusb-core.c .
11 */
12#ifndef __DVB_DIBUSB_H__
13#define __DVB_DIBUSB_H__
14
15#include <linux/input.h>
16#include <linux/config.h>
17#include <linux/usb.h>
18
19#include "dvb_frontend.h"
20#include "dvb_demux.h"
21#include "dvb_net.h"
22#include "dmxdev.h"
23
24#include "dib3000.h"
25#include "mt352.h"
26
27/* debug */
28#ifdef CONFIG_DVB_DIBCOM_DEBUG
29#define dprintk(level,args...) \
30 do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0)
31
32#define debug_dump(b,l) {\
33 int i; \
34 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
35 deb_xfer("\n");\
36}
37
38#else
39#define dprintk(args...)
40#define debug_dump(b,l)
41#endif
42
43extern int dvb_dibusb_debug;
44
45/* Version information */
46#define DRIVER_VERSION "0.3"
47#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
48#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
49
50#define deb_info(args...) dprintk(0x01,args)
51#define deb_xfer(args...) dprintk(0x02,args)
52#define deb_alot(args...) dprintk(0x04,args)
53#define deb_ts(args...) dprintk(0x08,args)
54#define deb_err(args...) dprintk(0x10,args)
55#define deb_rc(args...) dprintk(0x20,args)
56
57/* generic log methods - taken from usb.h */
58#undef err
59#define err(format, arg...) printk(KERN_ERR "dvb-dibusb: " format "\n" , ## arg)
60#undef info
61#define info(format, arg...) printk(KERN_INFO "dvb-dibusb: " format "\n" , ## arg)
62#undef warn
63#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg)
64
65struct dibusb_usb_controller {
66 const char *name; /* name of the usb controller */
67 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
68};
69
70typedef enum {
71 DIBUSB1_1 = 0,
72 DIBUSB1_1_AN2235,
73 DIBUSB2_0,
74 UMT2_0,
75 DIBUSB2_0B,
76 NOVAT_USB2,
77 DTT200U,
78} dibusb_class_t;
79
80typedef enum {
81 DIBUSB_TUNER_CABLE_THOMSON = 0,
82 DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
83 DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
84 DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
85} dibusb_tuner_t;
86
87typedef enum {
88 DIBUSB_DIB3000MB = 0,
89 DIBUSB_DIB3000MC,
90 DIBUSB_MT352,
91 DTT200U_FE,
92} dibusb_demodulator_t;
93
94typedef enum {
95 DIBUSB_RC_NO = 0,
96 DIBUSB_RC_NEC_PROTOCOL,
97 DIBUSB_RC_HAUPPAUGE_PROTO,
98} dibusb_remote_t;
99
100struct dibusb_tuner {
101 dibusb_tuner_t id;
102
103 u8 pll_addr; /* tuner i2c address */
104};
105extern struct dibusb_tuner dibusb_tuner[];
106
107#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
108struct dibusb_demod {
109 dibusb_demodulator_t id;
110
111 int pid_filter_count; /* counter of the internal pid_filter */
112 u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
113};
114
115#define DIBUSB_MAX_TUNER_NUM 2
116struct dibusb_device_class {
117 dibusb_class_t id;
118
119 const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
120 const char *firmware; /* valid firmware filenames */
121
122 int pipe_cmd; /* command pipe (read/write) */
123 int pipe_data; /* data pipe */
124
125 int urb_count; /* number of data URBs to be submitted */
126 int urb_buffer_size; /* the size of the buffer for each URB */
127
128 dibusb_remote_t remote_type; /* does this device have a ir-receiver */
129
130 struct dibusb_demod *demod; /* which demodulator is mount */
131 struct dibusb_tuner *tuner; /* which tuner can be found here */
132};
133
134#define DIBUSB_ID_MAX_NUM 15
135struct dibusb_usb_device {
136 const char *name; /* real name of the box */
137 struct dibusb_device_class *dev_cl; /* which dibusb_device_class is this device part of */
138
139 struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
140 struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
141};
142
143/* a PID for the pid_filter list, when in use */
144struct dibusb_pid
145{
146 int index;
147 u16 pid;
148 int active;
149};
150
151struct usb_dibusb {
152 /* usb */
153 struct usb_device * udev;
154
155 struct dibusb_usb_device * dibdev;
156
157#define DIBUSB_STATE_INIT 0x000
158#define DIBUSB_STATE_URB_LIST 0x001
159#define DIBUSB_STATE_URB_BUF 0x002
160#define DIBUSB_STATE_URB_INIT 0x004
161#define DIBUSB_STATE_DVB 0x008
162#define DIBUSB_STATE_I2C 0x010
163#define DIBUSB_STATE_REMOTE 0x020
164#define DIBUSB_STATE_URB_SUBMIT 0x040
165 int init_state;
166
167 int feedcount;
168 struct dib_fe_xfer_ops xfer_ops;
169
170 struct dibusb_tuner *tuner;
171
172 struct urb **urb_list;
173 u8 *buffer;
174 dma_addr_t dma_handle;
175
176 /* I2C */
177 struct i2c_adapter i2c_adap;
178
179 /* locking */
180 struct semaphore usb_sem;
181 struct semaphore i2c_sem;
182
183 /* dvb */
184 struct dvb_adapter *adapter;
185 struct dmxdev dmxdev;
186 struct dvb_demux demux;
187 struct dvb_net dvb_net;
188 struct dvb_frontend* fe;
189
190 int (*fe_sleep) (struct dvb_frontend *);
191 int (*fe_init) (struct dvb_frontend *);
192
193 /* remote control */
194 struct input_dev rc_input_dev;
195 struct work_struct rc_query_work;
196 int last_event;
197 int last_state; /* for Hauppauge RC protocol */
198 int repeat_key_count;
199 int rc_key_repeat_count; /* module parameter */
200
201 /* module parameters */
202 int pid_parse;
203 int rc_query_interval;
204};
205
206/* commonly used functions in the separated files */
207
208/* dvb-dibusb-firmware.c */
209int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
210
211/* dvb-dibusb-remote.c */
212int dibusb_remote_exit(struct usb_dibusb *dib);
213int dibusb_remote_init(struct usb_dibusb *dib);
214
215/* dvb-dibusb-fe-i2c.c */
216int dibusb_fe_init(struct usb_dibusb* dib);
217int dibusb_fe_exit(struct usb_dibusb *dib);
218int dibusb_i2c_init(struct usb_dibusb *dib);
219int dibusb_i2c_exit(struct usb_dibusb *dib);
220
221/* dvb-dibusb-dvb.c */
222void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
223int dibusb_dvb_init(struct usb_dibusb *dib);
224int dibusb_dvb_exit(struct usb_dibusb *dib);
225
226/* dvb-dibusb-usb.c */
227int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
228 u16 rlen);
229int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len);
230
231int dibusb_hw_wakeup(struct dvb_frontend *);
232int dibusb_hw_sleep(struct dvb_frontend *);
233int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
234int dibusb_streaming(struct usb_dibusb *,int);
235
236int dibusb_urb_init(struct usb_dibusb *);
237int dibusb_urb_exit(struct usb_dibusb *);
238
239/* dvb-fe-dtt200u.c */
240struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *);
241
242/* i2c and transfer stuff */
243#define DIBUSB_I2C_TIMEOUT 5000
244
245/*
246 * protocol of all dibusb related devices
247 */
248
249/*
250 * bulk msg to/from endpoint 0x01
251 *
252 * general structure:
253 * request_byte parameter_bytes
254 */
255
256#define DIBUSB_REQ_START_READ 0x00
257#define DIBUSB_REQ_START_DEMOD 0x01
258
259/*
260 * i2c read
261 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
262 * bulk read: byte_buffer (length_word bytes)
263 */
264#define DIBUSB_REQ_I2C_READ 0x02
265
266/*
267 * i2c write
268 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
269 */
270#define DIBUSB_REQ_I2C_WRITE 0x03
271
272/*
273 * polling the value of the remote control
274 * bulk write: 0x04
275 * bulk read: byte_buffer (5 bytes)
276 *
277 * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
278 */
279#define DIBUSB_REQ_POLL_REMOTE 0x04
280
281#define DIBUSB_RC_NEC_EMPTY 0x00
282#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
283#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
284
285/* additional status values for Hauppauge Remote Control Protocol */
286#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
287#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
288
289/* streaming mode:
290 * bulk write: 0x05 mode_byte
291 *
292 * mode_byte is mostly 0x00
293 */
294#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
295
296/* interrupt the internal read loop, when blocking */
297#define DIBUSB_REQ_INTR_READ 0x06
298
299/* io control
300 * 0x07 cmd_byte param_bytes
301 *
302 * param_bytes can be up to 32 bytes
303 *
304 * cmd_byte function parameter name
305 * 0x00 power mode
306 * 0x00 sleep
307 * 0x01 wakeup
308 *
309 * 0x01 enable streaming
310 * 0x02 disable streaming
311 *
312 *
313 */
314#define DIBUSB_REQ_SET_IOCTL 0x07
315
316/* IOCTL commands */
317
318/* change the power mode in firmware */
319#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
320#define DIBUSB_IOCTL_POWER_SLEEP 0x00
321#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
322
323/* modify streaming of the FX2 */
324#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
325#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
326
327#endif
diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
new file mode 100644
index 000000000000..1872aa6d200a
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
@@ -0,0 +1,263 @@
1/*
2 * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the
3 * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
4 * it uses the usb-transfer functions directly (maybe creating a
5 * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * see dvb-dibusb-core.c for copyright details.
10 */
11
12/* guessed protocol description (reverse engineered):
13 * read
14 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
15 * 81 - <TS_LOCK> <current frequency divided by 250000>
16 * 82 - crash - do not touch
17 * 83 - crash - do not touch
18 * 84 - remote control
19 * 85 - crash - do not touch (OK, stop testing here)
20 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
21 * 89 - noise-to-signal
22 * 8a - unkown 1 byte - signal_strength
23 * 8c - ber ???
24 * 8d - ber
25 * 8e - unc
26 *
27 * write
28 * 02 - bandwidth
29 * 03 - frequency (divided by 250000)
30 * 04 - pid table (index pid(7:0) pid(12:8))
31 * 05 - reset the pid table
32 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
33 */
34
35#include "dvb-dibusb.h"
36#include "dvb_frontend.h"
37
38struct dtt200u_fe_state {
39 struct usb_dibusb *dib;
40
41 struct dvb_frontend_parameters fep;
42 struct dvb_frontend frontend;
43};
44
45#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
46
47static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
48{
49 struct dtt200u_fe_state *state = fe->demodulator_priv;
50 u8 bw[1] = { 0x81 };
51 u8 br[3] = { 0 };
52// u8 bdeb[5] = { 0 };
53
54 dibusb_readwrite_usb(state->dib,bw,1,br,3);
55 switch (br[0]) {
56 case 0x01:
57 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
58 break;
59 case 0x00:
60 *stat = 0;
61 break;
62 default:
63 moan("br[0]",0x81);
64 break;
65 }
66
67// bw[0] = 0x88;
68// dibusb_readwrite_usb(state->dib,bw,1,bdeb,5);
69
70// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
71
72 return 0;
73}
74static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
75{
76 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw[1] = { 0x8d };
78 *ber = 0;
79 dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3);
80 return 0;
81}
82
83static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
84{
85 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 bw[1] = { 0x8c };
87 *unc = 0;
88 dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3);
89 return 0;
90}
91
92static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
93{
94 struct dtt200u_fe_state *state = fe->demodulator_priv;
95 u8 bw[1] = { 0x8a };
96 u8 b;
97 dibusb_readwrite_usb(state->dib,bw,1,&b, 1);
98 *strength = (b << 8) | b;
99 return 0;
100}
101
102static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
103{
104 struct dtt200u_fe_state *state = fe->demodulator_priv;
105 u8 bw[1] = { 0x89 };
106 u8 br[1] = { 0 };
107 dibusb_readwrite_usb(state->dib,bw,1,br,1);
108 *snr = ((0xff - br[0]) << 8) | (0xff - br[0]);
109 return 0;
110}
111
112static int dtt200u_fe_init(struct dvb_frontend* fe)
113{
114 struct dtt200u_fe_state *state = fe->demodulator_priv;
115 u8 b[] = { 0x01 };
116 return dibusb_write_usb(state->dib,b,1);
117}
118
119static int dtt200u_fe_sleep(struct dvb_frontend* fe)
120{
121 return dtt200u_fe_init(fe);
122}
123
124static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
125{
126 tune->min_delay_ms = 1500;
127 tune->step_size = 166667;
128 tune->max_drift = 166667 * 2;
129 return 0;
130}
131
132static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
133 struct dvb_frontend_parameters *fep)
134{
135 struct dtt200u_fe_state *state = fe->demodulator_priv;
136 u16 freq = fep->frequency / 250000;
137 u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 };
138
139 switch (fep->u.ofdm.bandwidth) {
140 case BANDWIDTH_8_MHZ: bw = 8; break;
141 case BANDWIDTH_7_MHZ: bw = 7; break;
142 case BANDWIDTH_6_MHZ: bw = 6; break;
143 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
144 default:
145 return -EINVAL;
146 }
147 deb_info("set_frontend\n");
148
149 bwbuf[1] = bw;
150 dibusb_write_usb(state->dib,bwbuf,2);
151
152 freqbuf[1] = freq & 0xff;
153 freqbuf[2] = (freq >> 8) & 0xff;
154 dibusb_write_usb(state->dib,freqbuf,3);
155
156 memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
157
158 return 0;
159}
160
161static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
162 struct dvb_frontend_parameters *fep)
163{
164 struct dtt200u_fe_state *state = fe->demodulator_priv;
165 memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
166 return 0;
167}
168
169static void dtt200u_fe_release(struct dvb_frontend* fe)
170{
171 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
172 kfree(state);
173}
174
175static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
176{
177 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
178 u8 b_pid[4];
179 pid = onoff ? pid : 0;
180
181 b_pid[0] = 0x04;
182 b_pid[1] = index;
183 b_pid[2] = pid & 0xff;
184 b_pid[3] = (pid >> 8) & 0xff;
185
186 dibusb_write_usb(state->dib,b_pid,4);
187 return 0;
188}
189
190static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff)
191{
192 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
193 u8 b_streaming[2] = { 0x08, onoff };
194 u8 b_rst_pid[1] = { 0x05 };
195
196 dibusb_write_usb(state->dib,b_streaming,2);
197
198 if (!onoff)
199 dibusb_write_usb(state->dib,b_rst_pid,1);
200 return 0;
201}
202
203static struct dvb_frontend_ops dtt200u_fe_ops;
204
205struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops)
206{
207 struct dtt200u_fe_state* state = NULL;
208
209 /* allocate memory for the internal state */
210 state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
211 if (state == NULL)
212 goto error;
213 memset(state,0,sizeof(struct dtt200u_fe_state));
214
215 deb_info("attaching frontend dtt200u\n");
216
217 state->dib = dib;
218
219 state->frontend.ops = &dtt200u_fe_ops;
220 state->frontend.demodulator_priv = state;
221
222 xfer_ops->fifo_ctrl = dtt200u_fifo_control;
223 xfer_ops->pid_ctrl = dtt200u_pid_control;
224
225 goto success;
226error:
227 return NULL;
228success:
229 return &state->frontend;
230}
231
232static struct dvb_frontend_ops dtt200u_fe_ops = {
233 .info = {
234 .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
235 .type = FE_OFDM,
236 .frequency_min = 44250000,
237 .frequency_max = 867250000,
238 .frequency_stepsize = 250000,
239 .caps = FE_CAN_INVERSION_AUTO |
240 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
241 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
242 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
243 FE_CAN_TRANSMISSION_MODE_AUTO |
244 FE_CAN_GUARD_INTERVAL_AUTO |
245 FE_CAN_RECOVER |
246 FE_CAN_HIERARCHY_AUTO,
247 },
248
249 .release = dtt200u_fe_release,
250
251 .init = dtt200u_fe_init,
252 .sleep = dtt200u_fe_sleep,
253
254 .set_frontend = dtt200u_fe_set_frontend,
255 .get_frontend = dtt200u_fe_get_frontend,
256 .get_tune_settings = dtt200u_fe_get_tune_settings,
257
258 .read_status = dtt200u_fe_read_status,
259 .read_ber = dtt200u_fe_read_ber,
260 .read_signal_strength = dtt200u_fe_read_signal_strength,
261 .read_snr = dtt200u_fe_read_snr,
262 .read_ucblocks = dtt200u_fe_read_unc_blocks,
263};
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
new file mode 100644
index 000000000000..a9a7b3421048
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -0,0 +1,11 @@
1config DVB_CORE
2 tristate "DVB Core Support"
3 depends on DVB
4 select CRC32
5 help
6 DVB core utility functions for device handling, software fallbacks etc.
7 Say Y when you have a DVB card and want to use it. Say Y if your want
8 to build your drivers outside the kernel, but need the DVB core. All
9 in-kernel drivers will select this automatically if needed.
10 If unsure say N.
11
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
new file mode 100644
index 000000000000..c6baac20f529
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the kernel DVB device drivers.
3#
4
5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
6 dvb_ca_en50221.o dvb_frontend.o \
7 dvb_net.o dvb_ringbuffer.o
8
9obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
new file mode 100644
index 000000000000..fb55eaa5c8e7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -0,0 +1,301 @@
1/*
2 * demux.h
3 *
4 * Copyright (c) 2002 Convergence GmbH
5 *
6 * based on code:
7 * Copyright (c) 2000 Nokia Research Center
8 * Tampere, FINLAND
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (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 Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26#ifndef __DEMUX_H
27#define __DEMUX_H
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/list.h>
32#include <linux/time.h>
33
34/*--------------------------------------------------------------------------*/
35/* Common definitions */
36/*--------------------------------------------------------------------------*/
37
38/*
39 * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
40 */
41
42#ifndef DMX_MAX_FILTER_SIZE
43#define DMX_MAX_FILTER_SIZE 18
44#endif
45
46/*
47 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
48 */
49
50#ifndef DMX_MAX_SECFEED_SIZE
51#define DMX_MAX_SECFEED_SIZE 4096
52#endif
53
54
55/*
56 * enum dmx_success: Success codes for the Demux Callback API.
57 */
58
59enum dmx_success {
60 DMX_OK = 0, /* Received Ok */
61 DMX_LENGTH_ERROR, /* Incorrect length */
62 DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
63 DMX_CRC_ERROR, /* Incorrect CRC */
64 DMX_FRAME_ERROR, /* Frame alignment error */
65 DMX_FIFO_ERROR, /* Receiver FIFO overrun */
66 DMX_MISSED_ERROR /* Receiver missed packet */
67} ;
68
69/*--------------------------------------------------------------------------*/
70/* TS packet reception */
71/*--------------------------------------------------------------------------*/
72
73/* TS filter type for set() */
74
75#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
76#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
77 payload (<=184 bytes per packet) to callback */
78#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
79
80/* PES type for filters which write to built-in decoder */
81/* these should be kept identical to the types in dmx.h */
82
83enum dmx_ts_pes
84{ /* also send packets to decoder (if it exists) */
85 DMX_TS_PES_AUDIO0,
86 DMX_TS_PES_VIDEO0,
87 DMX_TS_PES_TELETEXT0,
88 DMX_TS_PES_SUBTITLE0,
89 DMX_TS_PES_PCR0,
90
91 DMX_TS_PES_AUDIO1,
92 DMX_TS_PES_VIDEO1,
93 DMX_TS_PES_TELETEXT1,
94 DMX_TS_PES_SUBTITLE1,
95 DMX_TS_PES_PCR1,
96
97 DMX_TS_PES_AUDIO2,
98 DMX_TS_PES_VIDEO2,
99 DMX_TS_PES_TELETEXT2,
100 DMX_TS_PES_SUBTITLE2,
101 DMX_TS_PES_PCR2,
102
103 DMX_TS_PES_AUDIO3,
104 DMX_TS_PES_VIDEO3,
105 DMX_TS_PES_TELETEXT3,
106 DMX_TS_PES_SUBTITLE3,
107 DMX_TS_PES_PCR3,
108
109 DMX_TS_PES_OTHER
110};
111
112#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0
113#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0
114#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0
115#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0
116#define DMX_TS_PES_PCR DMX_TS_PES_PCR0
117
118
119struct dmx_ts_feed {
120 int is_filtering; /* Set to non-zero when filtering in progress */
121 struct dmx_demux *parent; /* Back-pointer */
122 void *priv; /* Pointer to private data of the API client */
123 int (*set) (struct dmx_ts_feed *feed,
124 u16 pid,
125 int type,
126 enum dmx_ts_pes pes_type,
127 size_t callback_length,
128 size_t circular_buffer_size,
129 int descramble,
130 struct timespec timeout);
131 int (*start_filtering) (struct dmx_ts_feed* feed);
132 int (*stop_filtering) (struct dmx_ts_feed* feed);
133};
134
135/*--------------------------------------------------------------------------*/
136/* Section reception */
137/*--------------------------------------------------------------------------*/
138
139struct dmx_section_filter {
140 u8 filter_value [DMX_MAX_FILTER_SIZE];
141 u8 filter_mask [DMX_MAX_FILTER_SIZE];
142 u8 filter_mode [DMX_MAX_FILTER_SIZE];
143 struct dmx_section_feed* parent; /* Back-pointer */
144 void* priv; /* Pointer to private data of the API client */
145};
146
147struct dmx_section_feed {
148 int is_filtering; /* Set to non-zero when filtering in progress */
149 struct dmx_demux* parent; /* Back-pointer */
150 void* priv; /* Pointer to private data of the API client */
151
152 int check_crc;
153 u32 crc_val;
154
155 u8 *secbuf;
156 u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
157 u16 secbufp, seclen, tsfeedp;
158
159 int (*set) (struct dmx_section_feed* feed,
160 u16 pid,
161 size_t circular_buffer_size,
162 int descramble,
163 int check_crc);
164 int (*allocate_filter) (struct dmx_section_feed* feed,
165 struct dmx_section_filter** filter);
166 int (*release_filter) (struct dmx_section_feed* feed,
167 struct dmx_section_filter* filter);
168 int (*start_filtering) (struct dmx_section_feed* feed);
169 int (*stop_filtering) (struct dmx_section_feed* feed);
170};
171
172/*--------------------------------------------------------------------------*/
173/* Callback functions */
174/*--------------------------------------------------------------------------*/
175
176typedef int (*dmx_ts_cb) ( const u8 * buffer1,
177 size_t buffer1_length,
178 const u8 * buffer2,
179 size_t buffer2_length,
180 struct dmx_ts_feed* source,
181 enum dmx_success success);
182
183typedef int (*dmx_section_cb) ( const u8 * buffer1,
184 size_t buffer1_len,
185 const u8 * buffer2,
186 size_t buffer2_len,
187 struct dmx_section_filter * source,
188 enum dmx_success success);
189
190/*--------------------------------------------------------------------------*/
191/* DVB Front-End */
192/*--------------------------------------------------------------------------*/
193
194enum dmx_frontend_source {
195 DMX_MEMORY_FE,
196 DMX_FRONTEND_0,
197 DMX_FRONTEND_1,
198 DMX_FRONTEND_2,
199 DMX_FRONTEND_3,
200 DMX_STREAM_0, /* external stream input, e.g. LVDS */
201 DMX_STREAM_1,
202 DMX_STREAM_2,
203 DMX_STREAM_3
204};
205
206struct dmx_frontend {
207 struct list_head connectivity_list; /* List of front-ends that can
208 be connected to a particular
209 demux */
210 void* priv; /* Pointer to private data of the API client */
211 enum dmx_frontend_source source;
212};
213
214/*--------------------------------------------------------------------------*/
215/* MPEG-2 TS Demux */
216/*--------------------------------------------------------------------------*/
217
218/*
219 * Flags OR'ed in the capabilites field of struct dmx_demux.
220 */
221
222#define DMX_TS_FILTERING 1
223#define DMX_PES_FILTERING 2
224#define DMX_SECTION_FILTERING 4
225#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
226#define DMX_CRC_CHECKING 16
227#define DMX_TS_DESCRAMBLING 32
228#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
229#define DMX_MAC_ADDRESS_DESCRAMBLING 128
230
231/*
232 * Demux resource type identifier.
233*/
234
235/*
236 * DMX_FE_ENTRY(): Casts elements in the list of registered
237 * front-ends from the generic type struct list_head
238 * to the type * struct dmx_frontend
239 *.
240*/
241
242#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
243
244struct dmx_demux {
245 u32 capabilities; /* Bitfield of capability flags */
246 struct dmx_frontend* frontend; /* Front-end connected to the demux */
247 struct list_head reg_list; /* List of registered demuxes */
248 void* priv; /* Pointer to private data of the API client */
249 int users; /* Number of users */
250 int (*open) (struct dmx_demux* demux);
251 int (*close) (struct dmx_demux* demux);
252 int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
253 int (*allocate_ts_feed) (struct dmx_demux* demux,
254 struct dmx_ts_feed** feed,
255 dmx_ts_cb callback);
256 int (*release_ts_feed) (struct dmx_demux* demux,
257 struct dmx_ts_feed* feed);
258 int (*allocate_section_feed) (struct dmx_demux* demux,
259 struct dmx_section_feed** feed,
260 dmx_section_cb callback);
261 int (*release_section_feed) (struct dmx_demux* demux,
262 struct dmx_section_feed* feed);
263 int (*descramble_mac_address) (struct dmx_demux* demux,
264 u8* buffer1,
265 size_t buffer1_length,
266 u8* buffer2,
267 size_t buffer2_length,
268 u16 pid);
269 int (*descramble_section_payload) (struct dmx_demux* demux,
270 u8* buffer1,
271 size_t buffer1_length,
272 u8* buffer2, size_t buffer2_length,
273 u16 pid);
274 int (*add_frontend) (struct dmx_demux* demux,
275 struct dmx_frontend* frontend);
276 int (*remove_frontend) (struct dmx_demux* demux,
277 struct dmx_frontend* frontend);
278 struct list_head* (*get_frontends) (struct dmx_demux* demux);
279 int (*connect_frontend) (struct dmx_demux* demux,
280 struct dmx_frontend* frontend);
281 int (*disconnect_frontend) (struct dmx_demux* demux);
282
283 int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
284
285 int (*get_stc) (struct dmx_demux* demux, unsigned int num,
286 u64 *stc, unsigned int *base);
287};
288
289/*--------------------------------------------------------------------------*/
290/* Demux directory */
291/*--------------------------------------------------------------------------*/
292
293/*
294 * DMX_DIR_ENTRY(): Casts elements in the list of registered
295 * demuxes from the generic type struct list_head* to the type struct dmx_demux
296 *.
297 */
298
299#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list)
300
301#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
new file mode 100644
index 000000000000..1863f1dfb00c
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -0,0 +1,1137 @@
1/*
2 * dmxdev.c - DVB demultiplexer device
3 *
4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/sched.h>
30#include <linux/poll.h>
31#include <linux/ioctl.h>
32#include <linux/wait.h>
33#include <asm/uaccess.h>
34#include <asm/system.h>
35
36#include "dmxdev.h"
37
38static int debug;
39
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
42
43#define dprintk if (debug) printk
44
45static inline struct dmxdev_filter *
46dvb_dmxdev_file_to_filter(struct file *file)
47{
48 return (struct dmxdev_filter *) file->private_data;
49}
50
51static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
52{
53 buffer->data=NULL;
54 buffer->size=8192;
55 buffer->pread=0;
56 buffer->pwrite=0;
57 buffer->error=0;
58 init_waitqueue_head(&buffer->queue);
59}
60
61static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len)
62{
63 int split;
64 int free;
65 int todo;
66
67 if (!len)
68 return 0;
69 if (!buf->data)
70 return 0;
71
72 free=buf->pread-buf->pwrite;
73 split=0;
74 if (free<=0) {
75 free+=buf->size;
76 split=buf->size-buf->pwrite;
77 }
78 if (len>=free) {
79 dprintk("dmxdev: buffer overflow\n");
80 return -1;
81 }
82 if (split>=len)
83 split=0;
84 todo=len;
85 if (split) {
86 memcpy(buf->data + buf->pwrite, src, split);
87 todo-=split;
88 buf->pwrite=0;
89 }
90 memcpy(buf->data + buf->pwrite, src+split, todo);
91 buf->pwrite=(buf->pwrite+todo)%buf->size;
92 return len;
93}
94
95static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src,
96 int non_blocking, char __user *buf, size_t count, loff_t *ppos)
97{
98 unsigned long todo=count;
99 int split, avail, error;
100
101 if (!src->data)
102 return 0;
103
104 if ((error=src->error)) {
105 src->pwrite=src->pread;
106 src->error=0;
107 return error;
108 }
109
110 if (non_blocking && (src->pwrite==src->pread))
111 return -EWOULDBLOCK;
112
113 while (todo>0) {
114 if (non_blocking && (src->pwrite==src->pread))
115 return (count-todo) ? (count-todo) : -EWOULDBLOCK;
116
117 if (wait_event_interruptible(src->queue,
118 (src->pread!=src->pwrite) ||
119 (src->error))<0)
120 return count-todo;
121
122 if ((error=src->error)) {
123 src->pwrite=src->pread;
124 src->error=0;
125 return error;
126 }
127
128 split=src->size;
129 avail=src->pwrite - src->pread;
130 if (avail<0) {
131 avail+=src->size;
132 split=src->size - src->pread;
133 }
134 if (avail>todo)
135 avail=todo;
136 if (split<avail) {
137 if (copy_to_user(buf, src->data+src->pread, split))
138 return -EFAULT;
139 buf+=split;
140 src->pread=0;
141 todo-=split;
142 avail-=split;
143 }
144 if (avail) {
145 if (copy_to_user(buf, src->data+src->pread, avail))
146 return -EFAULT;
147 src->pread = (src->pread + avail) % src->size;
148 todo-=avail;
149 buf+=avail;
150 }
151 }
152 return count;
153}
154
155static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type)
156{
157 struct list_head *head, *pos;
158
159 head=demux->get_frontends(demux);
160 if (!head)
161 return NULL;
162 list_for_each(pos, head)
163 if (DMX_FE_ENTRY(pos)->source==type)
164 return DMX_FE_ENTRY(pos);
165
166 return NULL;
167}
168
169static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state)
170{
171 spin_lock_irq(&dmxdevdvr->dev->lock);
172 dmxdevdvr->state=state;
173 spin_unlock_irq(&dmxdevdvr->dev->lock);
174}
175
176static int dvb_dvr_open(struct inode *inode, struct file *file)
177{
178 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
179 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
180 struct dmx_frontend *front;
181
182 dprintk ("function : %s\n", __FUNCTION__);
183
184 if (down_interruptible (&dmxdev->mutex))
185 return -ERESTARTSYS;
186
187 if ((file->f_flags&O_ACCMODE)==O_RDWR) {
188 if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
189 up(&dmxdev->mutex);
190 return -EOPNOTSUPP;
191 }
192 }
193
194 if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
195 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
196 dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
197 dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
198 if (!dmxdev->dvr_buffer.data) {
199 up(&dmxdev->mutex);
200 return -ENOMEM;
201 }
202 }
203
204 if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
205 dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
206
207 if (!dmxdev->demux->write) {
208 up(&dmxdev->mutex);
209 return -EOPNOTSUPP;
210 }
211
212 front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
213
214 if (!front) {
215 up(&dmxdev->mutex);
216 return -EINVAL;
217 }
218 dmxdev->demux->disconnect_frontend(dmxdev->demux);
219 dmxdev->demux->connect_frontend(dmxdev->demux, front);
220 }
221 up(&dmxdev->mutex);
222 return 0;
223}
224
225static int dvb_dvr_release(struct inode *inode, struct file *file)
226{
227 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
228 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
229
230 if (down_interruptible (&dmxdev->mutex))
231 return -ERESTARTSYS;
232
233 if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
234 dmxdev->demux->disconnect_frontend(dmxdev->demux);
235 dmxdev->demux->connect_frontend(dmxdev->demux,
236 dmxdev->dvr_orig_fe);
237 }
238 if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
239 if (dmxdev->dvr_buffer.data) {
240 void *mem=dmxdev->dvr_buffer.data;
241 mb();
242 spin_lock_irq(&dmxdev->lock);
243 dmxdev->dvr_buffer.data=NULL;
244 spin_unlock_irq(&dmxdev->lock);
245 vfree(mem);
246 }
247 }
248 up(&dmxdev->mutex);
249 return 0;
250}
251
252static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
253 size_t count, loff_t *ppos)
254{
255 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
256 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
257 int ret;
258
259 if (!dmxdev->demux->write)
260 return -EOPNOTSUPP;
261 if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
262 return -EINVAL;
263 if (down_interruptible (&dmxdev->mutex))
264 return -ERESTARTSYS;
265 ret=dmxdev->demux->write(dmxdev->demux, buf, count);
266 up(&dmxdev->mutex);
267 return ret;
268}
269
270static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
271 loff_t *ppos)
272{
273 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
274 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
275 int ret;
276
277 //down(&dmxdev->mutex);
278 ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
279 file->f_flags&O_NONBLOCK,
280 buf, count, ppos);
281 //up(&dmxdev->mutex);
282 return ret;
283}
284
285static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state)
286{
287 spin_lock_irq(&dmxdevfilter->dev->lock);
288 dmxdevfilter->state=state;
289 spin_unlock_irq(&dmxdevfilter->dev->lock);
290}
291
292static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size)
293{
294 struct dmxdev_buffer *buf=&dmxdevfilter->buffer;
295 void *mem;
296
297 if (buf->size==size)
298 return 0;
299 if (dmxdevfilter->state>=DMXDEV_STATE_GO)
300 return -EBUSY;
301 spin_lock_irq(&dmxdevfilter->dev->lock);
302 mem=buf->data;
303 buf->data=NULL;
304 buf->size=size;
305 buf->pwrite=buf->pread=0;
306 spin_unlock_irq(&dmxdevfilter->dev->lock);
307 vfree(mem);
308
309 if (buf->size) {
310 mem=vmalloc(dmxdevfilter->buffer.size);
311 if (!mem)
312 return -ENOMEM;
313 spin_lock_irq(&dmxdevfilter->dev->lock);
314 buf->data=mem;
315 spin_unlock_irq(&dmxdevfilter->dev->lock);
316 }
317 return 0;
318}
319
320static void dvb_dmxdev_filter_timeout(unsigned long data)
321{
322 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data;
323
324 dmxdevfilter->buffer.error=-ETIMEDOUT;
325 spin_lock_irq(&dmxdevfilter->dev->lock);
326 dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT;
327 spin_unlock_irq(&dmxdevfilter->dev->lock);
328 wake_up(&dmxdevfilter->buffer.queue);
329}
330
331static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
332{
333 struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec;
334
335 del_timer(&dmxdevfilter->timer);
336 if (para->timeout) {
337 dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout;
338 dmxdevfilter->timer.data=(unsigned long) dmxdevfilter;
339 dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000;
340 add_timer(&dmxdevfilter->timer);
341 }
342}
343
344static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
345 const u8 *buffer2, size_t buffer2_len,
346 struct dmx_section_filter *filter, enum dmx_success success)
347{
348 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) filter->priv;
349 int ret;
350
351 if (dmxdevfilter->buffer.error) {
352 wake_up(&dmxdevfilter->buffer.queue);
353 return 0;
354 }
355 spin_lock(&dmxdevfilter->dev->lock);
356 if (dmxdevfilter->state!=DMXDEV_STATE_GO) {
357 spin_unlock(&dmxdevfilter->dev->lock);
358 return 0;
359 }
360 del_timer(&dmxdevfilter->timer);
361 dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
362 buffer1[0], buffer1[1],
363 buffer1[2], buffer1[3],
364 buffer1[4], buffer1[5]);
365 ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len);
366 if (ret==buffer1_len) {
367 ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len);
368 }
369 if (ret<0) {
370 dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread;
371 dmxdevfilter->buffer.error=-EOVERFLOW;
372 }
373 if (dmxdevfilter->params.sec.flags&DMX_ONESHOT)
374 dmxdevfilter->state=DMXDEV_STATE_DONE;
375 spin_unlock(&dmxdevfilter->dev->lock);
376 wake_up(&dmxdevfilter->buffer.queue);
377 return 0;
378}
379
380static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
381 const u8 *buffer2, size_t buffer2_len,
382 struct dmx_ts_feed *feed, enum dmx_success success)
383{
384 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) feed->priv;
385 struct dmxdev_buffer *buffer;
386 int ret;
387
388 spin_lock(&dmxdevfilter->dev->lock);
389 if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) {
390 spin_unlock(&dmxdevfilter->dev->lock);
391 return 0;
392 }
393
394 if (dmxdevfilter->params.pes.output==DMX_OUT_TAP)
395 buffer=&dmxdevfilter->buffer;
396 else
397 buffer=&dmxdevfilter->dev->dvr_buffer;
398 if (buffer->error) {
399 spin_unlock(&dmxdevfilter->dev->lock);
400 wake_up(&buffer->queue);
401 return 0;
402 }
403 ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
404 if (ret==buffer1_len)
405 ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
406 if (ret<0) {
407 buffer->pwrite=buffer->pread;
408 buffer->error=-EOVERFLOW;
409 }
410 spin_unlock(&dmxdevfilter->dev->lock);
411 wake_up(&buffer->queue);
412 return 0;
413}
414
415
416/* stop feed but only mark the specified filter as stopped (state set) */
417
418static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
419{
420 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
421
422 switch (dmxdevfilter->type) {
423 case DMXDEV_TYPE_SEC:
424 del_timer(&dmxdevfilter->timer);
425 dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
426 break;
427 case DMXDEV_TYPE_PES:
428 dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
429 break;
430 default:
431 return -EINVAL;
432 }
433 return 0;
434}
435
436
437/* start feed associated with the specified filter */
438
439static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
440{
441 dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO);
442
443 switch (filter->type) {
444 case DMXDEV_TYPE_SEC:
445 return filter->feed.sec->start_filtering(filter->feed.sec);
446 break;
447 case DMXDEV_TYPE_PES:
448 return filter->feed.ts->start_filtering(filter->feed.ts);
449 break;
450 default:
451 return -EINVAL;
452 }
453
454 return 0;
455}
456
457
458/* restart section feed if it has filters left associated with it,
459 otherwise release the feed */
460
461static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
462{
463 int i;
464 struct dmxdev *dmxdev = filter->dev;
465 u16 pid = filter->params.sec.pid;
466
467 for (i=0; i<dmxdev->filternum; i++)
468 if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
469 dmxdev->filter[i].type==DMXDEV_TYPE_SEC &&
470 dmxdev->filter[i].pid==pid) {
471 dvb_dmxdev_feed_start(&dmxdev->filter[i]);
472 return 0;
473 }
474
475 filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec);
476
477 return 0;
478}
479
480static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
481{
482 if (dmxdevfilter->state<DMXDEV_STATE_GO)
483 return 0;
484
485 switch (dmxdevfilter->type) {
486 case DMXDEV_TYPE_SEC:
487 if (!dmxdevfilter->feed.sec)
488 break;
489 dvb_dmxdev_feed_stop(dmxdevfilter);
490 if (dmxdevfilter->filter.sec)
491 dmxdevfilter->feed.sec->
492 release_filter(dmxdevfilter->feed.sec,
493 dmxdevfilter->filter.sec);
494 dvb_dmxdev_feed_restart(dmxdevfilter);
495 dmxdevfilter->feed.sec=NULL;
496 break;
497 case DMXDEV_TYPE_PES:
498 if (!dmxdevfilter->feed.ts)
499 break;
500 dvb_dmxdev_feed_stop(dmxdevfilter);
501 dmxdevfilter->dev->demux->
502 release_ts_feed(dmxdevfilter->dev->demux,
503 dmxdevfilter->feed.ts);
504 dmxdevfilter->feed.ts=NULL;
505 break;
506 default:
507 if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED)
508 return 0;
509 return -EINVAL;
510 }
511 dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0;
512 return 0;
513}
514
515static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
516{
517 if (dmxdevfilter->state<DMXDEV_STATE_SET)
518 return 0;
519
520 dmxdevfilter->type=DMXDEV_TYPE_NONE;
521 dmxdevfilter->pid=0xffff;
522 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
523 return 0;
524}
525
526static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
527{
528 struct dmxdev *dmxdev = filter->dev;
529 void *mem;
530 int ret, i;
531
532 if (filter->state < DMXDEV_STATE_SET)
533 return -EINVAL;
534
535 if (filter->state >= DMXDEV_STATE_GO)
536 dvb_dmxdev_filter_stop(filter);
537
538 if (!(mem = filter->buffer.data)) {
539 mem = vmalloc(filter->buffer.size);
540 spin_lock_irq(&filter->dev->lock);
541 filter->buffer.data=mem;
542 spin_unlock_irq(&filter->dev->lock);
543 if (!filter->buffer.data)
544 return -ENOMEM;
545 }
546
547 filter->buffer.pwrite = filter->buffer.pread = 0;
548
549 switch (filter->type) {
550 case DMXDEV_TYPE_SEC:
551 {
552 struct dmx_sct_filter_params *para=&filter->params.sec;
553 struct dmx_section_filter **secfilter=&filter->filter.sec;
554 struct dmx_section_feed **secfeed=&filter->feed.sec;
555
556 *secfilter=NULL;
557 *secfeed=NULL;
558
559 /* find active filter/feed with same PID */
560 for (i=0; i<dmxdev->filternum; i++) {
561 if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
562 dmxdev->filter[i].pid == para->pid &&
563 dmxdev->filter[i].type == DMXDEV_TYPE_SEC) {
564 *secfeed = dmxdev->filter[i].feed.sec;
565 break;
566 }
567 }
568
569 /* if no feed found, try to allocate new one */
570 if (!*secfeed) {
571 ret=dmxdev->demux->allocate_section_feed(dmxdev->demux,
572 secfeed,
573 dvb_dmxdev_section_callback);
574 if (ret<0) {
575 printk ("DVB (%s): could not alloc feed\n",
576 __FUNCTION__);
577 return ret;
578 }
579
580 ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0,
581 (para->flags & DMX_CHECK_CRC) ? 1 : 0);
582
583 if (ret<0) {
584 printk ("DVB (%s): could not set feed\n",
585 __FUNCTION__);
586 dvb_dmxdev_feed_restart(filter);
587 return ret;
588 }
589 } else {
590 dvb_dmxdev_feed_stop(filter);
591 }
592
593 ret=(*secfeed)->allocate_filter(*secfeed, secfilter);
594
595 if (ret < 0) {
596 dvb_dmxdev_feed_restart(filter);
597 filter->feed.sec->start_filtering(*secfeed);
598 dprintk ("could not get filter\n");
599 return ret;
600 }
601
602 (*secfilter)->priv = filter;
603
604 memcpy(&((*secfilter)->filter_value[3]),
605 &(para->filter.filter[1]), DMX_FILTER_SIZE-1);
606 memcpy(&(*secfilter)->filter_mask[3],
607 &para->filter.mask[1], DMX_FILTER_SIZE-1);
608 memcpy(&(*secfilter)->filter_mode[3],
609 &para->filter.mode[1], DMX_FILTER_SIZE-1);
610
611 (*secfilter)->filter_value[0]=para->filter.filter[0];
612 (*secfilter)->filter_mask[0]=para->filter.mask[0];
613 (*secfilter)->filter_mode[0]=para->filter.mode[0];
614 (*secfilter)->filter_mask[1]=0;
615 (*secfilter)->filter_mask[2]=0;
616
617 filter->todo = 0;
618
619 ret = filter->feed.sec->start_filtering (filter->feed.sec);
620
621 if (ret < 0)
622 return ret;
623
624 dvb_dmxdev_filter_timer(filter);
625 break;
626 }
627
628 case DMXDEV_TYPE_PES:
629 {
630 struct timespec timeout = { 0 };
631 struct dmx_pes_filter_params *para = &filter->params.pes;
632 dmx_output_t otype;
633 int ret;
634 int ts_type;
635 enum dmx_ts_pes ts_pes;
636 struct dmx_ts_feed **tsfeed = &filter->feed.ts;
637
638 filter->feed.ts = NULL;
639 otype=para->output;
640
641 ts_pes=(enum dmx_ts_pes) para->pes_type;
642
643 if (ts_pes<DMX_PES_OTHER)
644 ts_type=TS_DECODER;
645 else
646 ts_type=0;
647
648 if (otype == DMX_OUT_TS_TAP)
649 ts_type |= TS_PACKET;
650
651 if (otype == DMX_OUT_TAP)
652 ts_type |= TS_PAYLOAD_ONLY|TS_PACKET;
653
654 ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux,
655 tsfeed,
656 dvb_dmxdev_ts_callback);
657 if (ret<0)
658 return ret;
659
660 (*tsfeed)->priv = (void *) filter;
661
662 ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
663 188, 32768, 0, timeout);
664
665 if (ret < 0) {
666 dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
667 return ret;
668 }
669
670 ret = filter->feed.ts->start_filtering(filter->feed.ts);
671
672 if (ret < 0)
673 return ret;
674
675 break;
676 }
677 default:
678 return -EINVAL;
679 }
680
681 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
682 return 0;
683}
684
685static int dvb_demux_open(struct inode *inode, struct file *file)
686{
687 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
688 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
689 int i;
690 struct dmxdev_filter *dmxdevfilter;
691
692 if (!dmxdev->filter)
693 return -EINVAL;
694
695 if (down_interruptible(&dmxdev->mutex))
696 return -ERESTARTSYS;
697
698 for (i=0; i<dmxdev->filternum; i++)
699 if (dmxdev->filter[i].state==DMXDEV_STATE_FREE)
700 break;
701
702 if (i==dmxdev->filternum) {
703 up(&dmxdev->mutex);
704 return -EMFILE;
705 }
706
707 dmxdevfilter=&dmxdev->filter[i];
708 sema_init(&dmxdevfilter->mutex, 1);
709 dmxdevfilter->dvbdev=dmxdev->dvbdev;
710 file->private_data=dmxdevfilter;
711
712 dvb_dmxdev_buffer_init(&dmxdevfilter->buffer);
713 dmxdevfilter->type=DMXDEV_TYPE_NONE;
714 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
715 dmxdevfilter->feed.ts=NULL;
716 init_timer(&dmxdevfilter->timer);
717
718 up(&dmxdev->mutex);
719 return 0;
720}
721
722
723static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter)
724{
725 if (down_interruptible(&dmxdev->mutex))
726 return -ERESTARTSYS;
727
728 if (down_interruptible(&dmxdevfilter->mutex)) {
729 up(&dmxdev->mutex);
730 return -ERESTARTSYS;
731 }
732
733 dvb_dmxdev_filter_stop(dmxdevfilter);
734 dvb_dmxdev_filter_reset(dmxdevfilter);
735
736 if (dmxdevfilter->buffer.data) {
737 void *mem=dmxdevfilter->buffer.data;
738
739 spin_lock_irq(&dmxdev->lock);
740 dmxdevfilter->buffer.data=NULL;
741 spin_unlock_irq(&dmxdev->lock);
742 vfree(mem);
743 }
744
745 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
746 wake_up(&dmxdevfilter->buffer.queue);
747 up(&dmxdevfilter->mutex);
748 up(&dmxdev->mutex);
749 return 0;
750}
751
752static inline void invert_mode(dmx_filter_t *filter)
753{
754 int i;
755
756 for (i=0; i<DMX_FILTER_SIZE; i++)
757 filter->mode[i]^=0xff;
758}
759
760
761static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
762 struct dmxdev_filter *dmxdevfilter,
763 struct dmx_sct_filter_params *params)
764{
765 dprintk ("function : %s\n", __FUNCTION__);
766
767 dvb_dmxdev_filter_stop(dmxdevfilter);
768
769 dmxdevfilter->type=DMXDEV_TYPE_SEC;
770 dmxdevfilter->pid=params->pid;
771 memcpy(&dmxdevfilter->params.sec,
772 params, sizeof(struct dmx_sct_filter_params));
773 invert_mode(&dmxdevfilter->params.sec.filter);
774 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
775
776 if (params->flags&DMX_IMMEDIATE_START)
777 return dvb_dmxdev_filter_start(dmxdevfilter);
778
779 return 0;
780}
781
782static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
783 struct dmxdev_filter *dmxdevfilter,
784 struct dmx_pes_filter_params *params)
785{
786 dvb_dmxdev_filter_stop(dmxdevfilter);
787
788 if (params->pes_type>DMX_PES_OTHER || params->pes_type<0)
789 return -EINVAL;
790
791 dmxdevfilter->type=DMXDEV_TYPE_PES;
792 dmxdevfilter->pid=params->pid;
793 memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params));
794
795 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
796
797 if (params->flags&DMX_IMMEDIATE_START)
798 return dvb_dmxdev_filter_start(dmxdevfilter);
799
800 return 0;
801}
802
803static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
804 struct file *file, char __user *buf, size_t count, loff_t *ppos)
805{
806 int result, hcount;
807 int done=0;
808
809 if (dfil->todo<=0) {
810 hcount=3+dfil->todo;
811 if (hcount>count)
812 hcount=count;
813 result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
814 buf, hcount, ppos);
815 if (result<0) {
816 dfil->todo=0;
817 return result;
818 }
819 if (copy_from_user(dfil->secheader-dfil->todo, buf, result))
820 return -EFAULT;
821 buf+=result;
822 done=result;
823 count-=result;
824 dfil->todo-=result;
825 if (dfil->todo>-3)
826 return done;
827 dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff;
828 if (!count)
829 return done;
830 }
831 if (count>dfil->todo)
832 count=dfil->todo;
833 result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
834 buf, count, ppos);
835 if (result<0)
836 return result;
837 dfil->todo-=result;
838 return (result+done);
839}
840
841
842static ssize_t
843dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
844{
845 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
846 int ret=0;
847
848 if (down_interruptible(&dmxdevfilter->mutex))
849 return -ERESTARTSYS;
850
851 if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
852 ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
853 else
854 ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
855 file->f_flags&O_NONBLOCK,
856 buf, count, ppos);
857
858 up(&dmxdevfilter->mutex);
859 return ret;
860}
861
862
863static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
864 unsigned int cmd, void *parg)
865{
866 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
867 struct dmxdev *dmxdev=dmxdevfilter->dev;
868 unsigned long arg=(unsigned long) parg;
869 int ret=0;
870
871 if (down_interruptible (&dmxdev->mutex))
872 return -ERESTARTSYS;
873
874 switch (cmd) {
875 case DMX_START:
876 if (down_interruptible(&dmxdevfilter->mutex)) {
877 up(&dmxdev->mutex);
878 return -ERESTARTSYS;
879 }
880 if (dmxdevfilter->state<DMXDEV_STATE_SET)
881 ret = -EINVAL;
882 else
883 ret = dvb_dmxdev_filter_start(dmxdevfilter);
884 up(&dmxdevfilter->mutex);
885 break;
886
887 case DMX_STOP:
888 if (down_interruptible(&dmxdevfilter->mutex)) {
889 up(&dmxdev->mutex);
890 return -ERESTARTSYS;
891 }
892 ret=dvb_dmxdev_filter_stop(dmxdevfilter);
893 up(&dmxdevfilter->mutex);
894 break;
895
896 case DMX_SET_FILTER:
897 if (down_interruptible(&dmxdevfilter->mutex)) {
898 up(&dmxdev->mutex);
899 return -ERESTARTSYS;
900 }
901 ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
902 (struct dmx_sct_filter_params *)parg);
903 up(&dmxdevfilter->mutex);
904 break;
905
906 case DMX_SET_PES_FILTER:
907 if (down_interruptible(&dmxdevfilter->mutex)) {
908 up(&dmxdev->mutex);
909 return -ERESTARTSYS;
910 }
911 ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
912 (struct dmx_pes_filter_params *)parg);
913 up(&dmxdevfilter->mutex);
914 break;
915
916 case DMX_SET_BUFFER_SIZE:
917 if (down_interruptible(&dmxdevfilter->mutex)) {
918 up(&dmxdev->mutex);
919 return -ERESTARTSYS;
920 }
921 ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
922 up(&dmxdevfilter->mutex);
923 break;
924
925 case DMX_GET_EVENT:
926 break;
927
928 case DMX_GET_PES_PIDS:
929 if (!dmxdev->demux->get_pes_pids) {
930 ret=-EINVAL;
931 break;
932 }
933 dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
934 break;
935
936 case DMX_GET_STC:
937 if (!dmxdev->demux->get_stc) {
938 ret=-EINVAL;
939 break;
940 }
941 ret = dmxdev->demux->get_stc(dmxdev->demux,
942 ((struct dmx_stc *)parg)->num,
943 &((struct dmx_stc *)parg)->stc,
944 &((struct dmx_stc *)parg)->base);
945 break;
946
947 default:
948 ret=-EINVAL;
949 }
950 up(&dmxdev->mutex);
951 return ret;
952}
953
954static int dvb_demux_ioctl(struct inode *inode, struct file *file,
955 unsigned int cmd, unsigned long arg)
956{
957 return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl);
958}
959
960
961static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
962{
963 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
964 unsigned int mask = 0;
965
966 if (!dmxdevfilter)
967 return -EINVAL;
968
969 poll_wait(file, &dmxdevfilter->buffer.queue, wait);
970
971 if (dmxdevfilter->state != DMXDEV_STATE_GO &&
972 dmxdevfilter->state != DMXDEV_STATE_DONE &&
973 dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT)
974 return 0;
975
976 if (dmxdevfilter->buffer.error)
977 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
978
979 if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite)
980 mask |= (POLLIN | POLLRDNORM | POLLPRI);
981
982 return mask;
983}
984
985
986static int dvb_demux_release(struct inode *inode, struct file *file)
987{
988 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
989 struct dmxdev *dmxdev = dmxdevfilter->dev;
990
991 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
992}
993
994
995static struct file_operations dvb_demux_fops = {
996 .owner = THIS_MODULE,
997 .read = dvb_demux_read,
998 .ioctl = dvb_demux_ioctl,
999 .open = dvb_demux_open,
1000 .release = dvb_demux_release,
1001 .poll = dvb_demux_poll,
1002};
1003
1004
1005static struct dvb_device dvbdev_demux = {
1006 .priv = NULL,
1007 .users = 1,
1008 .writers = 1,
1009 .fops = &dvb_demux_fops
1010};
1011
1012
1013static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
1014 unsigned int cmd, void *parg)
1015{
1016 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
1017 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
1018
1019 int ret=0;
1020
1021 if (down_interruptible (&dmxdev->mutex))
1022 return -ERESTARTSYS;
1023
1024 switch (cmd) {
1025 case DMX_SET_BUFFER_SIZE:
1026 // FIXME: implement
1027 ret=0;
1028 break;
1029
1030 default:
1031 ret=-EINVAL;
1032 }
1033 up(&dmxdev->mutex);
1034 return ret;
1035}
1036
1037
1038static int dvb_dvr_ioctl(struct inode *inode, struct file *file,
1039 unsigned int cmd, unsigned long arg)
1040{
1041 return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl);
1042}
1043
1044
1045static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait)
1046{
1047 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1048 struct dmxdev *dmxdev = (struct dmxdev *) dvbdev->priv;
1049 unsigned int mask = 0;
1050
1051 dprintk ("function : %s\n", __FUNCTION__);
1052
1053 poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
1054
1055 if ((file->f_flags&O_ACCMODE) == O_RDONLY) {
1056 if (dmxdev->dvr_buffer.error)
1057 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1058
1059 if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
1060 mask |= (POLLIN | POLLRDNORM | POLLPRI);
1061 } else
1062 mask |= (POLLOUT | POLLWRNORM | POLLPRI);
1063
1064 return mask;
1065}
1066
1067
1068static struct file_operations dvb_dvr_fops = {
1069 .owner = THIS_MODULE,
1070 .read = dvb_dvr_read,
1071 .write = dvb_dvr_write,
1072 .ioctl = dvb_dvr_ioctl,
1073 .open = dvb_dvr_open,
1074 .release = dvb_dvr_release,
1075 .poll = dvb_dvr_poll,
1076};
1077
1078static struct dvb_device dvbdev_dvr = {
1079 .priv = NULL,
1080 .users = 1,
1081 .writers = 1,
1082 .fops = &dvb_dvr_fops
1083};
1084
1085int
1086dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1087{
1088 int i;
1089
1090 if (dmxdev->demux->open(dmxdev->demux) < 0)
1091 return -EUSERS;
1092
1093 dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter));
1094 if (!dmxdev->filter)
1095 return -ENOMEM;
1096
1097 dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr));
1098 if (!dmxdev->dvr) {
1099 vfree(dmxdev->filter);
1100 dmxdev->filter = NULL;
1101 return -ENOMEM;
1102 }
1103
1104 sema_init(&dmxdev->mutex, 1);
1105 spin_lock_init(&dmxdev->lock);
1106 for (i=0; i<dmxdev->filternum; i++) {
1107 dmxdev->filter[i].dev=dmxdev;
1108 dmxdev->filter[i].buffer.data=NULL;
1109 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1110 dmxdev->dvr[i].dev=dmxdev;
1111 dmxdev->dvr[i].buffer.data=NULL;
1112 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1113 dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
1114 }
1115
1116 dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX);
1117 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR);
1118
1119 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
1120
1121 return 0;
1122}
1123EXPORT_SYMBOL(dvb_dmxdev_init);
1124
1125void
1126dvb_dmxdev_release(struct dmxdev *dmxdev)
1127{
1128 dvb_unregister_device(dmxdev->dvbdev);
1129 dvb_unregister_device(dmxdev->dvr_dvbdev);
1130
1131 vfree(dmxdev->filter);
1132 dmxdev->filter=NULL;
1133 vfree(dmxdev->dvr);
1134 dmxdev->dvr=NULL;
1135 dmxdev->demux->close(dmxdev->demux);
1136}
1137EXPORT_SYMBOL(dvb_dmxdev_release);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
new file mode 100644
index 000000000000..395a9cd75012
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -0,0 +1,128 @@
1/*
2 * dmxdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (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 Lesser 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#ifndef _DMXDEV_H_
24#define _DMXDEV_H_
25
26#include <linux/types.h>
27#include <linux/spinlock.h>
28#include <linux/kernel.h>
29#include <linux/timer.h>
30#include <linux/wait.h>
31#include <linux/fs.h>
32#include <linux/string.h>
33#include <asm/semaphore.h>
34
35#include <linux/dvb/dmx.h>
36
37#include "dvbdev.h"
38#include "demux.h"
39
40enum dmxdevype {
41 DMXDEV_TYPE_NONE,
42 DMXDEV_TYPE_SEC,
43 DMXDEV_TYPE_PES,
44};
45
46enum dmxdev_state {
47 DMXDEV_STATE_FREE,
48 DMXDEV_STATE_ALLOCATED,
49 DMXDEV_STATE_SET,
50 DMXDEV_STATE_GO,
51 DMXDEV_STATE_DONE,
52 DMXDEV_STATE_TIMEDOUT
53};
54
55struct dmxdev_buffer {
56 u8 *data;
57 int size;
58 int pread;
59 int pwrite;
60 wait_queue_head_t queue;
61 int error;
62};
63
64struct dmxdev_filter {
65 struct dvb_device *dvbdev;
66
67 union {
68 struct dmx_section_filter *sec;
69 } filter;
70
71 union {
72 struct dmx_ts_feed *ts;
73 struct dmx_section_feed *sec;
74 } feed;
75
76 union {
77 struct dmx_sct_filter_params sec;
78 struct dmx_pes_filter_params pes;
79 } params;
80
81 int type;
82 enum dmxdev_state state;
83 struct dmxdev *dev;
84 struct dmxdev_buffer buffer;
85
86 struct semaphore mutex;
87
88 /* only for sections */
89 struct timer_list timer;
90 int todo;
91 u8 secheader[3];
92
93 u16 pid;
94};
95
96
97struct dmxdev_dvr {
98 int state;
99 struct dmxdev *dev;
100 struct dmxdev_buffer buffer;
101};
102
103
104struct dmxdev {
105 struct dvb_device *dvbdev;
106 struct dvb_device *dvr_dvbdev;
107
108 struct dmxdev_filter *filter;
109 struct dmxdev_dvr *dvr;
110 struct dmx_demux *demux;
111
112 int filternum;
113 int capabilities;
114#define DMXDEV_CAP_DUPLEX 1
115 struct dmx_frontend *dvr_orig_fe;
116
117 struct dmxdev_buffer dvr_buffer;
118#define DVR_BUFFER_SIZE (10*188*1024)
119
120 struct semaphore mutex;
121 spinlock_t lock;
122};
123
124
125int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
126void dvb_dmxdev_release(struct dmxdev *dmxdev);
127
128#endif /* _DMXDEV_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
new file mode 100644
index 000000000000..c1ea89f2880c
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -0,0 +1,1778 @@
1/*
2 * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * Parts of this file were based on sources as follows:
7 *
8 * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de>
9 *
10 * based on code:
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
29 */
30
31#include <linux/errno.h>
32#include <linux/slab.h>
33#include <linux/list.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/vmalloc.h>
37#include <linux/delay.h>
38#include <linux/rwsem.h>
39
40#include "dvb_ca_en50221.h"
41#include "dvb_ringbuffer.h"
42
43static int dvb_ca_en50221_debug;
44
45module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
46MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
47
48#define dprintk if (dvb_ca_en50221_debug) printk
49
50#define INIT_TIMEOUT_SECS 5
51
52#define HOST_LINK_BUF_SIZE 0x200
53
54#define RX_BUFFER_SIZE 65535
55
56#define MAX_RX_PACKETS_PER_ITERATION 10
57
58#define CTRLIF_DATA 0
59#define CTRLIF_COMMAND 1
60#define CTRLIF_STATUS 1
61#define CTRLIF_SIZE_LOW 2
62#define CTRLIF_SIZE_HIGH 3
63
64#define CMDREG_HC 1 /* Host control */
65#define CMDREG_SW 2 /* Size write */
66#define CMDREG_SR 4 /* Size read */
67#define CMDREG_RS 8 /* Reset interface */
68#define CMDREG_FRIE 0x40 /* Enable FR interrupt */
69#define CMDREG_DAIE 0x80 /* Enable DA interrupt */
70#define IRQEN (CMDREG_DAIE)
71
72#define STATUSREG_RE 1 /* read error */
73#define STATUSREG_WE 2 /* write error */
74#define STATUSREG_FR 0x40 /* module free */
75#define STATUSREG_DA 0x80 /* data available */
76#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */
77
78
79#define DVB_CA_SLOTSTATE_NONE 0
80#define DVB_CA_SLOTSTATE_UNINITIALISED 1
81#define DVB_CA_SLOTSTATE_RUNNING 2
82#define DVB_CA_SLOTSTATE_INVALID 3
83#define DVB_CA_SLOTSTATE_WAITREADY 4
84#define DVB_CA_SLOTSTATE_VALIDATE 5
85#define DVB_CA_SLOTSTATE_WAITFR 6
86#define DVB_CA_SLOTSTATE_LINKINIT 7
87
88
89/* Information on a CA slot */
90struct dvb_ca_slot {
91
92 /* current state of the CAM */
93 int slot_state;
94
95 /* Number of CAMCHANGES that have occurred since last processing */
96 atomic_t camchange_count;
97
98 /* Type of last CAMCHANGE */
99 int camchange_type;
100
101 /* base address of CAM config */
102 u32 config_base;
103
104 /* value to write into Config Control register */
105 u8 config_option;
106
107 /* if 1, the CAM supports DA IRQs */
108 u8 da_irq_supported:1;
109
110 /* size of the buffer to use when talking to the CAM */
111 int link_buf_size;
112
113 /* semaphore for syncing access to slot structure */
114 struct rw_semaphore sem;
115
116 /* buffer for incoming packets */
117 struct dvb_ringbuffer rx_buffer;
118
119 /* timer used during various states of the slot */
120 unsigned long timeout;
121};
122
123/* Private CA-interface information */
124struct dvb_ca_private {
125
126 /* pointer back to the public data structure */
127 struct dvb_ca_en50221 *pub;
128
129 /* the DVB device */
130 struct dvb_device *dvbdev;
131
132 /* Flags describing the interface (DVB_CA_FLAG_*) */
133 u32 flags;
134
135 /* number of slots supported by this CA interface */
136 unsigned int slot_count;
137
138 /* information on each slot */
139 struct dvb_ca_slot *slot_info;
140
141 /* wait queues for read() and write() operations */
142 wait_queue_head_t wait_queue;
143
144 /* PID of the monitoring thread */
145 pid_t thread_pid;
146
147 /* Wait queue used when shutting thread down */
148 wait_queue_head_t thread_queue;
149
150 /* Flag indicating when thread should exit */
151 unsigned int exit:1;
152
153 /* Flag indicating if the CA device is open */
154 unsigned int open:1;
155
156 /* Flag indicating the thread should wake up now */
157 unsigned int wakeup:1;
158
159 /* Delay the main thread should use */
160 unsigned long delay;
161
162 /* Slot to start looking for data to read from in the next user-space read operation */
163 int next_read_slot;
164};
165
166static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
167static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
168static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
169
170
171/**
172 * Safely find needle in haystack.
173 *
174 * @param haystack Buffer to look in.
175 * @param hlen Number of bytes in haystack.
176 * @param needle Buffer to find.
177 * @param nlen Number of bytes in needle.
178 * @return Pointer into haystack needle was found at, or NULL if not found.
179 */
180static u8 *findstr(u8 * haystack, int hlen, u8 * needle, int nlen)
181{
182 int i;
183
184 if (hlen < nlen)
185 return NULL;
186
187 for (i = 0; i <= hlen - nlen; i++) {
188 if (!strncmp(haystack + i, needle, nlen))
189 return haystack + i;
190 }
191
192 return NULL;
193}
194
195
196
197/* ******************************************************************************** */
198/* EN50221 physical interface functions */
199
200
201/**
202 * Check CAM status.
203 */
204static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
205{
206 int slot_status;
207 int cam_present_now;
208 int cam_changed;
209
210 /* IRQ mode */
211 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) {
212 return (atomic_read(&ca->slot_info[slot].camchange_count) != 0);
213 }
214
215 /* poll mode */
216 slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open);
217
218 cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0;
219 cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0;
220 if (!cam_changed) {
221 int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE);
222 cam_changed = (cam_present_now != cam_present_old);
223 }
224
225 if (cam_changed) {
226 if (!cam_present_now) {
227 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
228 } else {
229 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED;
230 }
231 atomic_set(&ca->slot_info[slot].camchange_count, 1);
232 } else {
233 if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) &&
234 (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) {
235 // move to validate state if reset is completed
236 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
237 }
238 }
239
240 return cam_changed;
241}
242
243
244/**
245 * Wait for flags to become set on the STATUS register on a CAM interface,
246 * checking for errors and timeout.
247 *
248 * @param ca CA instance.
249 * @param slot Slot on interface.
250 * @param waitfor Flags to wait for.
251 * @param timeout_ms Timeout in milliseconds.
252 *
253 * @return 0 on success, nonzero on error.
254 */
255static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
256 u8 waitfor, int timeout_hz)
257{
258 unsigned long timeout;
259 unsigned long start;
260
261 dprintk("%s\n", __FUNCTION__);
262
263 /* loop until timeout elapsed */
264 start = jiffies;
265 timeout = jiffies + timeout_hz;
266 while (1) {
267 /* read the status and check for error */
268 int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
269 if (res < 0)
270 return -EIO;
271
272 /* if we got the flags, it was successful! */
273 if (res & waitfor) {
274 dprintk("%s succeeded timeout:%lu\n", __FUNCTION__, jiffies - start);
275 return 0;
276 }
277
278 /* check for timeout */
279 if (time_after(jiffies, timeout)) {
280 break;
281 }
282
283 /* wait for a bit */
284 msleep(1);
285 }
286
287 dprintk("%s failed timeout:%lu\n", __FUNCTION__, jiffies - start);
288
289 /* if we get here, we've timed out */
290 return -ETIMEDOUT;
291}
292
293
294/**
295 * Initialise the link layer connection to a CAM.
296 *
297 * @param ca CA instance.
298 * @param slot Slot id.
299 *
300 * @return 0 on success, nonzero on failure.
301 */
302static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
303{
304 int ret;
305 int buf_size;
306 u8 buf[2];
307
308 dprintk("%s\n", __FUNCTION__);
309
310 /* we'll be determining these during this function */
311 ca->slot_info[slot].da_irq_supported = 0;
312
313 /* set the host link buffer size temporarily. it will be overwritten with the
314 * real negotiated size later. */
315 ca->slot_info[slot].link_buf_size = 2;
316
317 /* read the buffer size from the CAM */
318 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
319 return ret;
320 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
321 return ret;
322 if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
323 return -EIO;
324 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
325 return ret;
326
327 /* store it, and choose the minimum of our buffer and the CAM's buffer size */
328 buf_size = (buf[0] << 8) | buf[1];
329 if (buf_size > HOST_LINK_BUF_SIZE)
330 buf_size = HOST_LINK_BUF_SIZE;
331 ca->slot_info[slot].link_buf_size = buf_size;
332 buf[0] = buf_size >> 8;
333 buf[1] = buf_size & 0xff;
334 dprintk("Chosen link buffer size of %i\n", buf_size);
335
336 /* write the buffer size to the CAM */
337 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0)
338 return ret;
339 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0)
340 return ret;
341 if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
342 return -EIO;
343 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
344 return ret;
345
346 /* success */
347 return 0;
348}
349
350/**
351 * Read a tuple from attribute memory.
352 *
353 * @param ca CA instance.
354 * @param slot Slot id.
355 * @param address Address to read from. Updated.
356 * @param tupleType Tuple id byte. Updated.
357 * @param tupleLength Tuple length. Updated.
358 * @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
359 *
360 * @return 0 on success, nonzero on error.
361 */
362static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
363 int *address, int *tupleType, int *tupleLength, u8 * tuple)
364{
365 int i;
366 int _tupleType;
367 int _tupleLength;
368 int _address = *address;
369
370 /* grab the next tuple length and type */
371 if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0)
372 return _tupleType;
373 if (_tupleType == 0xff) {
374 dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
375 *address += 2;
376 *tupleType = _tupleType;
377 *tupleLength = 0;
378 return 0;
379 }
380 if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0)
381 return _tupleLength;
382 _address += 4;
383
384 dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
385
386 /* read in the whole tuple */
387 for (i = 0; i < _tupleLength; i++) {
388 tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2));
389 dprintk(" 0x%02x: 0x%02x %c\n",
390 i, tuple[i] & 0xff,
391 ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
392 }
393 _address += (_tupleLength * 2);
394
395 // success
396 *tupleType = _tupleType;
397 *tupleLength = _tupleLength;
398 *address = _address;
399 return 0;
400}
401
402
403/**
404 * Parse attribute memory of a CAM module, extracting Config register, and checking
405 * it is a DVB CAM module.
406 *
407 * @param ca CA instance.
408 * @param slot Slot id.
409 *
410 * @return 0 on success, <0 on failure.
411 */
412static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
413{
414 int address = 0;
415 int tupleLength;
416 int tupleType;
417 u8 tuple[257];
418 char *dvb_str;
419 int rasz;
420 int status;
421 int got_cftableentry = 0;
422 int end_chain = 0;
423 int i;
424 u16 manfid = 0;
425 u16 devid = 0;
426
427
428 // CISTPL_DEVICE_0A
429 if ((status =
430 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
431 return status;
432 if (tupleType != 0x1D)
433 return -EINVAL;
434
435
436
437 // CISTPL_DEVICE_0C
438 if ((status =
439 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
440 return status;
441 if (tupleType != 0x1C)
442 return -EINVAL;
443
444
445
446 // CISTPL_VERS_1
447 if ((status =
448 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
449 return status;
450 if (tupleType != 0x15)
451 return -EINVAL;
452
453
454
455 // CISTPL_MANFID
456 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
457 &tupleLength, tuple)) < 0)
458 return status;
459 if (tupleType != 0x20)
460 return -EINVAL;
461 if (tupleLength != 4)
462 return -EINVAL;
463 manfid = (tuple[1] << 8) | tuple[0];
464 devid = (tuple[3] << 8) | tuple[2];
465
466
467
468 // CISTPL_CONFIG
469 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
470 &tupleLength, tuple)) < 0)
471 return status;
472 if (tupleType != 0x1A)
473 return -EINVAL;
474 if (tupleLength < 3)
475 return -EINVAL;
476
477 /* extract the configbase */
478 rasz = tuple[0] & 3;
479 if (tupleLength < (3 + rasz + 14))
480 return -EINVAL;
481 ca->slot_info[slot].config_base = 0;
482 for (i = 0; i < rasz + 1; i++) {
483 ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i));
484 }
485
486 /* check it contains the correct DVB string */
487 dvb_str = findstr(tuple, tupleLength, "DVB_CI_V", 8);
488 if (dvb_str == NULL)
489 return -EINVAL;
490 if (tupleLength < ((dvb_str - (char *) tuple) + 12))
491 return -EINVAL;
492
493 /* is it a version we support? */
494 if (strncmp(dvb_str + 8, "1.00", 4)) {
495 printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
496 ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
497 return -EINVAL;
498 }
499
500 /* process the CFTABLE_ENTRY tuples, and any after those */
501 while ((!end_chain) && (address < 0x1000)) {
502 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
503 &tupleLength, tuple)) < 0)
504 return status;
505 switch (tupleType) {
506 case 0x1B: // CISTPL_CFTABLE_ENTRY
507 if (tupleLength < (2 + 11 + 17))
508 break;
509
510 /* if we've already parsed one, just use it */
511 if (got_cftableentry)
512 break;
513
514 /* get the config option */
515 ca->slot_info[slot].config_option = tuple[0] & 0x3f;
516
517 /* OK, check it contains the correct strings */
518 if ((findstr(tuple, tupleLength, "DVB_HOST", 8) == NULL) ||
519 (findstr(tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL))
520 break;
521
522 got_cftableentry = 1;
523 break;
524
525 case 0x14: // CISTPL_NO_LINK
526 break;
527
528 case 0xFF: // CISTPL_END
529 end_chain = 1;
530 break;
531
532 default: /* Unknown tuple type - just skip this tuple and move to the next one */
533 dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
534 tupleLength);
535 break;
536 }
537 }
538
539 if ((address > 0x1000) || (!got_cftableentry))
540 return -EINVAL;
541
542 dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
543 manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option);
544
545 // success!
546 return 0;
547}
548
549
550/**
551 * Set CAM's configoption correctly.
552 *
553 * @param ca CA instance.
554 * @param slot Slot containing the CAM.
555 */
556static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
557{
558 int configoption;
559
560 dprintk("%s\n", __FUNCTION__);
561
562 /* set the config option */
563 ca->pub->write_attribute_mem(ca->pub, slot,
564 ca->slot_info[slot].config_base,
565 ca->slot_info[slot].config_option);
566
567 /* check it */
568 configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base);
569 dprintk("Set configoption 0x%x, read configoption 0x%x\n",
570 ca->slot_info[slot].config_option, configoption & 0x3f);
571
572 /* fine! */
573 return 0;
574
575}
576
577
578/**
579 * This function talks to an EN50221 CAM control interface. It reads a buffer of
580 * data from the CAM. The data can either be stored in a supplied buffer, or
581 * automatically be added to the slot's rx_buffer.
582 *
583 * @param ca CA instance.
584 * @param slot Slot to read from.
585 * @param ebuf If non-NULL, the data will be written to this buffer. If NULL,
586 * the data will be added into the buffering system as a normal fragment.
587 * @param ecount Size of ebuf. Ignored if ebuf is NULL.
588 *
589 * @return Number of bytes read, or < 0 on error
590 */
591static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount)
592{
593 int bytes_read;
594 int status;
595 u8 buf[HOST_LINK_BUF_SIZE];
596 int i;
597
598 dprintk("%s\n", __FUNCTION__);
599
600 /* check if we have space for a link buf in the rx_buffer */
601 if (ebuf == NULL) {
602 int buf_free;
603
604 down_read(&ca->slot_info[slot].sem);
605 if (ca->slot_info[slot].rx_buffer.data == NULL) {
606 up_read(&ca->slot_info[slot].sem);
607 status = -EIO;
608 goto exit;
609 }
610 buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
611 up_read(&ca->slot_info[slot].sem);
612
613 if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
614 status = -EAGAIN;
615 goto exit;
616 }
617 }
618
619 /* check if there is data available */
620 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
621 goto exit;
622 if (!(status & STATUSREG_DA)) {
623 /* no data */
624 status = 0;
625 goto exit;
626 }
627
628 /* read the amount of data */
629 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
630 goto exit;
631 bytes_read = status << 8;
632 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
633 goto exit;
634 bytes_read |= status;
635
636 /* check it will fit */
637 if (ebuf == NULL) {
638 if (bytes_read > ca->slot_info[slot].link_buf_size) {
639 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
640 ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
641 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
642 status = -EIO;
643 goto exit;
644 }
645 if (bytes_read < 2) {
646 printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
647 ca->dvbdev->adapter->num);
648 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
649 status = -EIO;
650 goto exit;
651 }
652 } else {
653 if (bytes_read > ecount) {
654 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
655 ca->dvbdev->adapter->num);
656 status = -EIO;
657 goto exit;
658 }
659 }
660
661 /* fill the buffer */
662 for (i = 0; i < bytes_read; i++) {
663 /* read byte and check */
664 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
665 goto exit;
666
667 /* OK, store it in the buffer */
668 buf[i] = status;
669 }
670
671 /* check for read error (RE should now be 0) */
672 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
673 goto exit;
674 if (status & STATUSREG_RE) {
675 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
676 status = -EIO;
677 goto exit;
678 }
679
680 /* OK, add it to the receive buffer, or copy into external buffer if supplied */
681 if (ebuf == NULL) {
682 down_read(&ca->slot_info[slot].sem);
683 if (ca->slot_info[slot].rx_buffer.data == NULL) {
684 up_read(&ca->slot_info[slot].sem);
685 status = -EIO;
686 goto exit;
687 }
688 dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
689 up_read(&ca->slot_info[slot].sem);
690 } else {
691 memcpy(ebuf, buf, bytes_read);
692 }
693
694 dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
695 buf[0], (buf[1] & 0x80) == 0, bytes_read);
696
697 /* wake up readers when a last_fragment is received */
698 if ((buf[1] & 0x80) == 0x00) {
699 wake_up_interruptible(&ca->wait_queue);
700 }
701 status = bytes_read;
702
703exit:
704 return status;
705}
706
707
708/**
709 * This function talks to an EN50221 CAM control interface. It writes a buffer of data
710 * to a CAM.
711 *
712 * @param ca CA instance.
713 * @param slot Slot to write to.
714 * @param ebuf The data in this buffer is treated as a complete link-level packet to
715 * be written.
716 * @param count Size of ebuf.
717 *
718 * @return Number of bytes written, or < 0 on error.
719 */
720static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * buf, int bytes_write)
721{
722 int status;
723 int i;
724
725 dprintk("%s\n", __FUNCTION__);
726
727
728 // sanity check
729 if (bytes_write > ca->slot_info[slot].link_buf_size)
730 return -EINVAL;
731
732 /* check if interface is actually waiting for us to read from it, or if a read is in progress */
733 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
734 goto exitnowrite;
735 if (status & (STATUSREG_DA | STATUSREG_RE)) {
736 status = -EAGAIN;
737 goto exitnowrite;
738 }
739
740 /* OK, set HC bit */
741 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
742 IRQEN | CMDREG_HC)) != 0)
743 goto exit;
744
745 /* check if interface is still free */
746 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
747 goto exit;
748 if (!(status & STATUSREG_FR)) {
749 /* it wasn't free => try again later */
750 status = -EAGAIN;
751 goto exit;
752 }
753
754 /* send the amount of data */
755 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
756 goto exit;
757 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
758 bytes_write & 0xff)) != 0)
759 goto exit;
760
761 /* send the buffer */
762 for (i = 0; i < bytes_write; i++) {
763 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0)
764 goto exit;
765 }
766
767 /* check for write error (WE should now be 0) */
768 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
769 goto exit;
770 if (status & STATUSREG_WE) {
771 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
772 status = -EIO;
773 goto exit;
774 }
775 status = bytes_write;
776
777 dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
778 buf[0], (buf[1] & 0x80) == 0, bytes_write);
779
780exit:
781 ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
782
783exitnowrite:
784 return status;
785}
786EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
787
788
789
790/* ******************************************************************************** */
791/* EN50221 higher level functions */
792
793
794/**
795 * A CAM has been removed => shut it down.
796 *
797 * @param ca CA instance.
798 * @param slot Slot to shut down.
799 */
800static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
801{
802 dprintk("%s\n", __FUNCTION__);
803
804 down_write(&ca->slot_info[slot].sem);
805 ca->pub->slot_shutdown(ca->pub, slot);
806 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
807 vfree(ca->slot_info[slot].rx_buffer.data);
808 ca->slot_info[slot].rx_buffer.data = NULL;
809 up_write(&ca->slot_info[slot].sem);
810
811 /* need to wake up all processes to check if they're now
812 trying to write to a defunct CAM */
813 wake_up_interruptible(&ca->wait_queue);
814
815 dprintk("Slot %i shutdown\n", slot);
816
817 /* success */
818 return 0;
819}
820EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
821
822
823/**
824 * A CAMCHANGE IRQ has occurred.
825 *
826 * @param ca CA instance.
827 * @param slot Slot concerned.
828 * @param change_type One of the DVB_CA_CAMCHANGE_* values.
829 */
830void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
831{
832 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
833
834 dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
835
836 switch (change_type) {
837 case DVB_CA_EN50221_CAMCHANGE_REMOVED:
838 case DVB_CA_EN50221_CAMCHANGE_INSERTED:
839 break;
840
841 default:
842 return;
843 }
844
845 ca->slot_info[slot].camchange_type = change_type;
846 atomic_inc(&ca->slot_info[slot].camchange_count);
847 dvb_ca_en50221_thread_wakeup(ca);
848}
849EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
850
851
852/**
853 * A CAMREADY IRQ has occurred.
854 *
855 * @param ca CA instance.
856 * @param slot Slot concerned.
857 */
858void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
859{
860 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
861
862 dprintk("CAMREADY IRQ slot:%i\n", slot);
863
864 if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) {
865 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
866 dvb_ca_en50221_thread_wakeup(ca);
867 }
868}
869
870
871/**
872 * An FR or DA IRQ has occurred.
873 *
874 * @param ca CA instance.
875 * @param slot Slot concerned.
876 */
877void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
878{
879 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
880 int flags;
881
882 dprintk("FR/DA IRQ slot:%i\n", slot);
883
884 switch (ca->slot_info[slot].slot_state) {
885 case DVB_CA_SLOTSTATE_LINKINIT:
886 flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS);
887 if (flags & STATUSREG_DA) {
888 dprintk("CAM supports DA IRQ\n");
889 ca->slot_info[slot].da_irq_supported = 1;
890 }
891 break;
892
893 case DVB_CA_SLOTSTATE_RUNNING:
894 if (ca->open)
895 dvb_ca_en50221_read_data(ca, slot, NULL, 0);
896 break;
897 }
898}
899
900
901
902/* ******************************************************************************** */
903/* EN50221 thread functions */
904
905/**
906 * Wake up the DVB CA thread
907 *
908 * @param ca CA instance.
909 */
910static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
911{
912
913 dprintk("%s\n", __FUNCTION__);
914
915 ca->wakeup = 1;
916 mb();
917 wake_up_interruptible(&ca->thread_queue);
918}
919
920/**
921 * Used by the CA thread to determine if an early wakeup is necessary
922 *
923 * @param ca CA instance.
924 */
925static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
926{
927 if (ca->wakeup) {
928 ca->wakeup = 0;
929 return 1;
930 }
931 if (ca->exit)
932 return 1;
933
934 return 0;
935}
936
937
938/**
939 * Update the delay used by the thread.
940 *
941 * @param ca CA instance.
942 */
943static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
944{
945 int delay;
946 int curdelay = 100000000;
947 int slot;
948
949 for (slot = 0; slot < ca->slot_count; slot++) {
950 switch (ca->slot_info[slot].slot_state) {
951 default:
952 case DVB_CA_SLOTSTATE_NONE:
953 case DVB_CA_SLOTSTATE_INVALID:
954 delay = HZ * 60;
955 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
956 delay = HZ / 10;
957 }
958 break;
959
960 case DVB_CA_SLOTSTATE_UNINITIALISED:
961 case DVB_CA_SLOTSTATE_WAITREADY:
962 case DVB_CA_SLOTSTATE_VALIDATE:
963 case DVB_CA_SLOTSTATE_WAITFR:
964 case DVB_CA_SLOTSTATE_LINKINIT:
965 delay = HZ / 10;
966 break;
967
968 case DVB_CA_SLOTSTATE_RUNNING:
969 delay = HZ * 60;
970 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
971 delay = HZ / 10;
972 }
973 if (ca->open) {
974 if ((!ca->slot_info[slot].da_irq_supported) ||
975 (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
976 delay = HZ / 10;
977 }
978 }
979 break;
980 }
981
982 if (delay < curdelay)
983 curdelay = delay;
984 }
985
986 ca->delay = curdelay;
987}
988
989
990
991/**
992 * Kernel thread which monitors CA slots for CAM changes, and performs data transfers.
993 */
994static int dvb_ca_en50221_thread(void *data)
995{
996 struct dvb_ca_private *ca = (struct dvb_ca_private *) data;
997 char name[15];
998 int slot;
999 int flags;
1000 int status;
1001 int pktcount;
1002 void *rxbuf;
1003
1004 dprintk("%s\n", __FUNCTION__);
1005
1006 /* setup kernel thread */
1007 snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
1008
1009 lock_kernel();
1010 daemonize(name);
1011 sigfillset(&current->blocked);
1012 unlock_kernel();
1013
1014 /* choose the correct initial delay */
1015 dvb_ca_en50221_thread_update_delay(ca);
1016
1017 /* main loop */
1018 while (!ca->exit) {
1019 /* sleep for a bit */
1020 if (!ca->wakeup) {
1021 flags = wait_event_interruptible_timeout(ca->thread_queue,
1022 dvb_ca_en50221_thread_should_wakeup(ca),
1023 ca->delay);
1024 if ((flags == -ERESTARTSYS) || ca->exit) {
1025 /* got signal or quitting */
1026 break;
1027 }
1028 }
1029 ca->wakeup = 0;
1030
1031 /* go through all the slots processing them */
1032 for (slot = 0; slot < ca->slot_count; slot++) {
1033
1034 // check the cam status + deal with CAMCHANGEs
1035 while (dvb_ca_en50221_check_camstatus(ca, slot)) {
1036 /* clear down an old CI slot if necessary */
1037 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE)
1038 dvb_ca_en50221_slot_shutdown(ca, slot);
1039
1040 /* if a CAM is NOW present, initialise it */
1041 if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) {
1042 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
1043 }
1044
1045 /* we've handled one CAMCHANGE */
1046 dvb_ca_en50221_thread_update_delay(ca);
1047 atomic_dec(&ca->slot_info[slot].camchange_count);
1048 }
1049
1050 // CAM state machine
1051 switch (ca->slot_info[slot].slot_state) {
1052 case DVB_CA_SLOTSTATE_NONE:
1053 case DVB_CA_SLOTSTATE_INVALID:
1054 // no action needed
1055 break;
1056
1057 case DVB_CA_SLOTSTATE_UNINITIALISED:
1058 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY;
1059 ca->pub->slot_reset(ca->pub, slot);
1060 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1061 break;
1062
1063 case DVB_CA_SLOTSTATE_WAITREADY:
1064 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1065 printk("dvb_ca adaptor %d: PC card did not respond :(\n",
1066 ca->dvbdev->adapter->num);
1067 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1068 dvb_ca_en50221_thread_update_delay(ca);
1069 break;
1070 }
1071 // no other action needed; will automatically change state when ready
1072 break;
1073
1074 case DVB_CA_SLOTSTATE_VALIDATE:
1075 if (dvb_ca_en50221_parse_attributes(ca, slot)
1076 != 0) {
1077 printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
1078 ca->dvbdev->adapter->num);
1079 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1080 dvb_ca_en50221_thread_update_delay(ca);
1081 break;
1082 }
1083 if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
1084 printk("dvb_ca adapter %d: Unable to initialise CAM :(\n",
1085 ca->dvbdev->adapter->num);
1086 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1087 dvb_ca_en50221_thread_update_delay(ca);
1088 break;
1089 }
1090 if (ca->pub->write_cam_control(ca->pub, slot,
1091 CTRLIF_COMMAND, CMDREG_RS) != 0) {
1092 printk("dvb_ca adapter %d: Unable to reset CAM IF\n",
1093 ca->dvbdev->adapter->num);
1094 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1095 dvb_ca_en50221_thread_update_delay(ca);
1096 break;
1097 }
1098 dprintk("DVB CAM validated successfully\n");
1099
1100 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1101 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR;
1102 ca->wakeup = 1;
1103 break;
1104
1105 case DVB_CA_SLOTSTATE_WAITFR:
1106 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1107 printk("dvb_ca adapter %d: DVB CAM did not respond :(\n",
1108 ca->dvbdev->adapter->num);
1109 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1110 dvb_ca_en50221_thread_update_delay(ca);
1111 break;
1112 }
1113
1114 flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
1115 if (flags & STATUSREG_FR) {
1116 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
1117 ca->wakeup = 1;
1118 }
1119 break;
1120
1121 case DVB_CA_SLOTSTATE_LINKINIT:
1122 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
1123 printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num);
1124 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1125 dvb_ca_en50221_thread_update_delay(ca);
1126 break;
1127 }
1128
1129 rxbuf = vmalloc(RX_BUFFER_SIZE);
1130 if (rxbuf == NULL) {
1131 printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
1132 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1133 dvb_ca_en50221_thread_update_delay(ca);
1134 break;
1135 }
1136 down_write(&ca->slot_info[slot].sem);
1137 dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
1138 up_write(&ca->slot_info[slot].sem);
1139
1140 ca->pub->slot_ts_enable(ca->pub, slot);
1141 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
1142 dvb_ca_en50221_thread_update_delay(ca);
1143 printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num);
1144 break;
1145
1146 case DVB_CA_SLOTSTATE_RUNNING:
1147 if (!ca->open)
1148 continue;
1149
1150 // no need to poll if the CAM supports IRQs
1151 if (ca->slot_info[slot].da_irq_supported)
1152 break;
1153
1154 // poll mode
1155 pktcount = 0;
1156 while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) {
1157 if (!ca->open)
1158 break;
1159
1160 /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */
1161 if (dvb_ca_en50221_check_camstatus(ca, slot)) {
1162 // we dont want to sleep on the next iteration so we can handle the cam change
1163 ca->wakeup = 1;
1164 break;
1165 }
1166
1167 /* check if we've hit our limit this time */
1168 if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) {
1169 // dont sleep; there is likely to be more data to read
1170 ca->wakeup = 1;
1171 break;
1172 }
1173 }
1174 break;
1175 }
1176 }
1177 }
1178
1179 /* completed */
1180 ca->thread_pid = 0;
1181 mb();
1182 wake_up_interruptible(&ca->thread_queue);
1183 return 0;
1184}
1185
1186
1187
1188/* ******************************************************************************** */
1189/* EN50221 IO interface functions */
1190
1191/**
1192 * Real ioctl implementation.
1193 * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
1194 *
1195 * @param inode Inode concerned.
1196 * @param file File concerned.
1197 * @param cmd IOCTL command.
1198 * @param arg Associated argument.
1199 *
1200 * @return 0 on success, <0 on error.
1201 */
1202static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
1203 unsigned int cmd, void *parg)
1204{
1205 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1206 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1207 int err = 0;
1208 int slot;
1209
1210 dprintk("%s\n", __FUNCTION__);
1211
1212 switch (cmd) {
1213 case CA_RESET:
1214 for (slot = 0; slot < ca->slot_count; slot++) {
1215 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
1216 dvb_ca_en50221_slot_shutdown(ca, slot);
1217 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
1218 dvb_ca_en50221_camchange_irq(ca->pub,
1219 slot,
1220 DVB_CA_EN50221_CAMCHANGE_INSERTED);
1221 }
1222 }
1223 ca->next_read_slot = 0;
1224 dvb_ca_en50221_thread_wakeup(ca);
1225 break;
1226
1227 case CA_GET_CAP: {
1228 struct ca_caps *caps = (struct ca_caps *) parg;
1229
1230 caps->slot_num = ca->slot_count;
1231 caps->slot_type = CA_CI_LINK;
1232 caps->descr_num = 0;
1233 caps->descr_type = 0;
1234 break;
1235 }
1236
1237 case CA_GET_SLOT_INFO: {
1238 struct ca_slot_info *info = (struct ca_slot_info *) parg;
1239
1240 if ((info->num > ca->slot_count) || (info->num < 0))
1241 return -EINVAL;
1242
1243 info->type = CA_CI_LINK;
1244 info->flags = 0;
1245 if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
1246 && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) {
1247 info->flags = CA_CI_MODULE_PRESENT;
1248 }
1249 if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1250 info->flags |= CA_CI_MODULE_READY;
1251 }
1252 break;
1253 }
1254
1255 default:
1256 err = -EINVAL;
1257 break;
1258 }
1259
1260 return err;
1261}
1262
1263
1264/**
1265 * Wrapper for ioctl implementation.
1266 *
1267 * @param inode Inode concerned.
1268 * @param file File concerned.
1269 * @param cmd IOCTL command.
1270 * @param arg Associated argument.
1271 *
1272 * @return 0 on success, <0 on error.
1273 */
1274static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file,
1275 unsigned int cmd, unsigned long arg)
1276{
1277 return dvb_usercopy(inode, file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
1278}
1279
1280
1281/**
1282 * Implementation of write() syscall.
1283 *
1284 * @param file File structure.
1285 * @param buf Source buffer.
1286 * @param count Size of source buffer.
1287 * @param ppos Position in file (ignored).
1288 *
1289 * @return Number of bytes read, or <0 on error.
1290 */
1291static ssize_t dvb_ca_en50221_io_write(struct file *file,
1292 const char __user * buf, size_t count, loff_t * ppos)
1293{
1294 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1295 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1296 u8 slot, connection_id;
1297 int status;
1298 char fragbuf[HOST_LINK_BUF_SIZE];
1299 int fragpos = 0;
1300 int fraglen;
1301 unsigned long timeout;
1302 int written;
1303
1304 dprintk("%s\n", __FUNCTION__);
1305
1306 /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1307 if (count < 2)
1308 return -EINVAL;
1309
1310 /* extract slot & connection id */
1311 if (copy_from_user(&slot, buf, 1))
1312 return -EFAULT;
1313 if (copy_from_user(&connection_id, buf + 1, 1))
1314 return -EFAULT;
1315 buf += 2;
1316 count -= 2;
1317
1318 /* check if the slot is actually running */
1319 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1320 return -EINVAL;
1321
1322 /* fragment the packets & store in the buffer */
1323 while (fragpos < count) {
1324 fraglen = ca->slot_info[slot].link_buf_size - 2;
1325 if ((count - fragpos) < fraglen)
1326 fraglen = count - fragpos;
1327
1328 fragbuf[0] = connection_id;
1329 fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
1330 if ((status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen)) != 0)
1331 goto exit;
1332
1333 timeout = jiffies + HZ / 2;
1334 written = 0;
1335 while (!time_after(jiffies, timeout)) {
1336 /* check the CAM hasn't been removed/reset in the meantime */
1337 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) {
1338 status = -EIO;
1339 goto exit;
1340 }
1341
1342 status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
1343 if (status == (fraglen + 2)) {
1344 written = 1;
1345 break;
1346 }
1347 if (status != -EAGAIN)
1348 goto exit;
1349
1350 msleep(1);
1351 }
1352 if (!written) {
1353 status = -EIO;
1354 goto exit;
1355 }
1356
1357 fragpos += fraglen;
1358 }
1359 status = count + 2;
1360
1361exit:
1362 return status;
1363}
1364
1365
1366/**
1367 * Condition for waking up in dvb_ca_en50221_io_read_condition
1368 */
1369static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *result, int *_slot)
1370{
1371 int slot;
1372 int slot_count = 0;
1373 int idx;
1374 int fraglen;
1375 int connection_id = -1;
1376 int found = 0;
1377 u8 hdr[2];
1378
1379 slot = ca->next_read_slot;
1380 while ((slot_count < ca->slot_count) && (!found)) {
1381 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1382 goto nextslot;
1383
1384 down_read(&ca->slot_info[slot].sem);
1385
1386 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1387 up_read(&ca->slot_info[slot].sem);
1388 return 0;
1389 }
1390
1391 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1392 while (idx != -1) {
1393 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
1394 if (connection_id == -1)
1395 connection_id = hdr[0];
1396 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
1397 *_slot = slot;
1398 found = 1;
1399 break;
1400 }
1401
1402 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1403 }
1404
1405 if (!found)
1406 up_read(&ca->slot_info[slot].sem);
1407
1408 nextslot:
1409 slot = (slot + 1) % ca->slot_count;
1410 slot_count++;
1411 }
1412
1413 ca->next_read_slot = slot;
1414 return found;
1415}
1416
1417
1418/**
1419 * Implementation of read() syscall.
1420 *
1421 * @param file File structure.
1422 * @param buf Destination buffer.
1423 * @param count Size of destination buffer.
1424 * @param ppos Position in file (ignored).
1425 *
1426 * @return Number of bytes read, or <0 on error.
1427 */
1428static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
1429 size_t count, loff_t * ppos)
1430{
1431 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1432 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1433 int status;
1434 int result = 0;
1435 u8 hdr[2];
1436 int slot;
1437 int connection_id = -1;
1438 size_t idx, idx2;
1439 int last_fragment = 0;
1440 size_t fraglen;
1441 int pktlen;
1442 int dispose = 0;
1443
1444 dprintk("%s\n", __FUNCTION__);
1445
1446 /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1447 if (count < 2)
1448 return -EINVAL;
1449
1450 /* wait for some data */
1451 if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
1452
1453 /* if we're in nonblocking mode, exit immediately */
1454 if (file->f_flags & O_NONBLOCK)
1455 return -EWOULDBLOCK;
1456
1457 /* wait for some data */
1458 status = wait_event_interruptible(ca->wait_queue,
1459 dvb_ca_en50221_io_read_condition
1460 (ca, &result, &slot));
1461 }
1462 if ((status < 0) || (result < 0)) {
1463 if (result)
1464 return result;
1465 return status;
1466 }
1467
1468 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1469 pktlen = 2;
1470 do {
1471 if (idx == -1) {
1472 printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num);
1473 status = -EIO;
1474 goto exit;
1475 }
1476
1477 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
1478 if (connection_id == -1)
1479 connection_id = hdr[0];
1480 if (hdr[0] == connection_id) {
1481 if (pktlen < count) {
1482 if ((pktlen + fraglen - 2) > count) {
1483 fraglen = count - pktlen;
1484 } else {
1485 fraglen -= 2;
1486 }
1487
1488 if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2,
1489 buf + pktlen, fraglen, 1)) < 0) {
1490 goto exit;
1491 }
1492 pktlen += fraglen;
1493 }
1494
1495 if ((hdr[1] & 0x80) == 0)
1496 last_fragment = 1;
1497 dispose = 1;
1498 }
1499
1500 idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1501 if (dispose)
1502 dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx);
1503 idx = idx2;
1504 dispose = 0;
1505 } while (!last_fragment);
1506
1507 hdr[0] = slot;
1508 hdr[1] = connection_id;
1509 if ((status = copy_to_user(buf, hdr, 2)) != 0)
1510 goto exit;
1511 status = pktlen;
1512
1513 exit:
1514 up_read(&ca->slot_info[slot].sem);
1515 return status;
1516}
1517
1518
1519/**
1520 * Implementation of file open syscall.
1521 *
1522 * @param inode Inode concerned.
1523 * @param file File concerned.
1524 *
1525 * @return 0 on success, <0 on failure.
1526 */
1527static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
1528{
1529 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1530 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1531 int err;
1532 int i;
1533
1534 dprintk("%s\n", __FUNCTION__);
1535
1536 if (!try_module_get(ca->pub->owner))
1537 return -EIO;
1538
1539 err = dvb_generic_open(inode, file);
1540 if (err < 0)
1541 return err;
1542
1543 for (i = 0; i < ca->slot_count; i++) {
1544
1545 if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1546 down_write(&ca->slot_info[i].sem);
1547 if (ca->slot_info[i].rx_buffer.data != NULL) {
1548 dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
1549 }
1550 up_write(&ca->slot_info[i].sem);
1551 }
1552 }
1553
1554 ca->open = 1;
1555 dvb_ca_en50221_thread_update_delay(ca);
1556 dvb_ca_en50221_thread_wakeup(ca);
1557
1558 return 0;
1559}
1560
1561
1562/**
1563 * Implementation of file close syscall.
1564 *
1565 * @param inode Inode concerned.
1566 * @param file File concerned.
1567 *
1568 * @return 0 on success, <0 on failure.
1569 */
1570static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
1571{
1572 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1573 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1574 int err = 0;
1575
1576 dprintk("%s\n", __FUNCTION__);
1577
1578 /* mark the CA device as closed */
1579 ca->open = 0;
1580 dvb_ca_en50221_thread_update_delay(ca);
1581
1582 err = dvb_generic_release(inode, file);
1583
1584 module_put(ca->pub->owner);
1585
1586 return 0;
1587}
1588
1589
1590/**
1591 * Implementation of poll() syscall.
1592 *
1593 * @param file File concerned.
1594 * @param wait poll wait table.
1595 *
1596 * @return Standard poll mask.
1597 */
1598static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
1599{
1600 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1601 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1602 unsigned int mask = 0;
1603 int slot;
1604 int result = 0;
1605
1606 dprintk("%s\n", __FUNCTION__);
1607
1608 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1609 up_read(&ca->slot_info[slot].sem);
1610 mask |= POLLIN;
1611 }
1612
1613 /* if there is something, return now */
1614 if (mask)
1615 return mask;
1616
1617 /* wait for something to happen */
1618 poll_wait(file, &ca->wait_queue, wait);
1619
1620 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1621 up_read(&ca->slot_info[slot].sem);
1622 mask |= POLLIN;
1623 }
1624
1625 return mask;
1626}
1627EXPORT_SYMBOL(dvb_ca_en50221_init);
1628
1629
1630static struct file_operations dvb_ca_fops = {
1631 .owner = THIS_MODULE,
1632 .read = dvb_ca_en50221_io_read,
1633 .write = dvb_ca_en50221_io_write,
1634 .ioctl = dvb_ca_en50221_io_ioctl,
1635 .open = dvb_ca_en50221_io_open,
1636 .release = dvb_ca_en50221_io_release,
1637 .poll = dvb_ca_en50221_io_poll,
1638};
1639
1640static struct dvb_device dvbdev_ca = {
1641 .priv = NULL,
1642 .users = 1,
1643 .readers = 1,
1644 .writers = 1,
1645 .fops = &dvb_ca_fops,
1646};
1647
1648
1649/* ******************************************************************************** */
1650/* Initialisation/shutdown functions */
1651
1652
1653/**
1654 * Initialise a new DVB CA EN50221 interface device.
1655 *
1656 * @param dvb_adapter DVB adapter to attach the new CA device to.
1657 * @param ca The dvb_ca instance.
1658 * @param flags Flags describing the CA device (DVB_CA_FLAG_*).
1659 * @param slot_count Number of slots supported.
1660 *
1661 * @return 0 on success, nonzero on failure
1662 */
1663int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1664 struct dvb_ca_en50221 *pubca, int flags, int slot_count)
1665{
1666 int ret;
1667 struct dvb_ca_private *ca = NULL;
1668 int i;
1669
1670 dprintk("%s\n", __FUNCTION__);
1671
1672 if (slot_count < 1)
1673 return -EINVAL;
1674
1675 /* initialise the system data */
1676 if ((ca =
1677 (struct dvb_ca_private *) kmalloc(sizeof(struct dvb_ca_private),
1678 GFP_KERNEL)) == NULL) {
1679 ret = -ENOMEM;
1680 goto error;
1681 }
1682 memset(ca, 0, sizeof(struct dvb_ca_private));
1683 ca->pub = pubca;
1684 ca->flags = flags;
1685 ca->slot_count = slot_count;
1686 if ((ca->slot_info = kmalloc(sizeof(struct dvb_ca_slot) * slot_count, GFP_KERNEL)) == NULL) {
1687 ret = -ENOMEM;
1688 goto error;
1689 }
1690 memset(ca->slot_info, 0, sizeof(struct dvb_ca_slot) * slot_count);
1691 init_waitqueue_head(&ca->wait_queue);
1692 ca->thread_pid = 0;
1693 init_waitqueue_head(&ca->thread_queue);
1694 ca->exit = 0;
1695 ca->open = 0;
1696 ca->wakeup = 0;
1697 ca->next_read_slot = 0;
1698 pubca->private = ca;
1699
1700 /* register the DVB device */
1701 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
1702 if (ret)
1703 goto error;
1704
1705 /* now initialise each slot */
1706 for (i = 0; i < slot_count; i++) {
1707 memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot));
1708 ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
1709 atomic_set(&ca->slot_info[i].camchange_count, 0);
1710 ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
1711 init_rwsem(&ca->slot_info[i].sem);
1712 }
1713
1714 if (signal_pending(current)) {
1715 ret = -EINTR;
1716 goto error;
1717 }
1718 mb();
1719
1720 /* create a kthread for monitoring this CA device */
1721
1722 ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);
1723
1724 if (ret < 0) {
1725 printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
1726 goto error;
1727 }
1728 ca->thread_pid = ret;
1729 return 0;
1730
1731 error:
1732 if (ca != NULL) {
1733 if (ca->dvbdev != NULL)
1734 dvb_unregister_device(ca->dvbdev);
1735 kfree(ca->slot_info);
1736 kfree(ca);
1737 }
1738 pubca->private = NULL;
1739 return ret;
1740}
1741EXPORT_SYMBOL(dvb_ca_en50221_release);
1742
1743
1744
1745/**
1746 * Release a DVB CA EN50221 interface device.
1747 *
1748 * @param ca_dev The dvb_device_t instance for the CA device.
1749 * @param ca The associated dvb_ca instance.
1750 */
1751void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1752{
1753 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
1754 int i;
1755
1756 dprintk("%s\n", __FUNCTION__);
1757
1758 /* shutdown the thread if there was one */
1759 if (ca->thread_pid) {
1760 if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
1761 printk("dvb_ca_release adapter %d: thread PID %d already died\n",
1762 ca->dvbdev->adapter->num, ca->thread_pid);
1763 } else {
1764 ca->exit = 1;
1765 mb();
1766 dvb_ca_en50221_thread_wakeup(ca);
1767 wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
1768 }
1769 }
1770
1771 for (i = 0; i < ca->slot_count; i++) {
1772 dvb_ca_en50221_slot_shutdown(ca, i);
1773 }
1774 kfree(ca->slot_info);
1775 dvb_unregister_device(ca->dvbdev);
1776 kfree(ca);
1777 pubca->private = NULL;
1778}
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
new file mode 100644
index 000000000000..8467e63ddc0d
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -0,0 +1,134 @@
1/*
2 * dvb_ca.h: generic DVB functions for EN50221 CA interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_CA_EN50221_H_
22#define _DVB_CA_EN50221_H_
23
24#include <linux/list.h>
25#include <linux/dvb/ca.h>
26
27#include "dvbdev.h"
28
29#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
30#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
31#define DVB_CA_EN50221_POLL_CAM_READY 4
32
33#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE 1
34#define DVB_CA_EN50221_FLAG_IRQ_FR 2
35#define DVB_CA_EN50221_FLAG_IRQ_DA 4
36
37#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0
38#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1
39
40
41
42/* Structure describing a CA interface */
43struct dvb_ca_en50221 {
44
45 /* the module owning this structure */
46 struct module* owner;
47
48 /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
49 * they may be called from several threads at once */
50
51 /* functions for accessing attribute memory on the CAM */
52 int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
53 int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value);
54
55 /* functions for accessing the control interface on the CAM */
56 int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address);
57 int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value);
58
59 /* Functions for controlling slots */
60 int (*slot_reset)(struct dvb_ca_en50221* ca, int slot);
61 int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot);
62 int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot);
63
64 /*
65 * Poll slot status.
66 * Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set
67 */
68 int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open);
69
70 /* private data, used by caller */
71 void* data;
72
73 /* Opaque data used by the dvb_ca core. Do not modify! */
74 void* private;
75};
76
77
78
79
80/* ******************************************************************************** */
81/* Functions for reporting IRQ events */
82
83/**
84 * A CAMCHANGE IRQ has occurred.
85 *
86 * @param ca CA instance.
87 * @param slot Slot concerned.
88 * @param change_type One of the DVB_CA_CAMCHANGE_* values
89 */
90void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
91
92/**
93 * A CAMREADY IRQ has occurred.
94 *
95 * @param ca CA instance.
96 * @param slot Slot concerned.
97 */
98void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
99
100/**
101 * An FR or a DA IRQ has occurred.
102 *
103 * @param ca CA instance.
104 * @param slot Slot concerned.
105 */
106void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
107
108
109
110/* ******************************************************************************** */
111/* Initialisation/shutdown functions */
112
113/**
114 * Initialise a new DVB CA device.
115 *
116 * @param dvb_adapter DVB adapter to attach the new CA device to.
117 * @param ca The dvb_ca instance.
118 * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
119 * @param slot_count Number of slots supported.
120 *
121 * @return 0 on success, nonzero on failure
122 */
123extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
124
125/**
126 * Release a DVB CA device.
127 *
128 * @param ca The associated dvb_ca instance.
129 */
130extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);
131
132
133
134#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
new file mode 100644
index 000000000000..ac9889d22288
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -0,0 +1,1294 @@
1/*
2 * dvb_demux.c - DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/module.h>
28#include <linux/poll.h>
29#include <linux/string.h>
30#include <linux/crc32.h>
31#include <asm/uaccess.h>
32
33#include "dvb_demux.h"
34
35#define NOBUFS
36/*
37** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
38*/
39// #define DVB_DEMUX_SECTION_LOSS_LOG
40
41
42static LIST_HEAD(dmx_muxs);
43
44
45static int dmx_register_demux(struct dmx_demux *demux)
46{
47 demux->users = 0;
48 list_add(&demux->reg_list, &dmx_muxs);
49 return 0;
50}
51
52static int dmx_unregister_demux(struct dmx_demux* demux)
53{
54 struct list_head *pos, *n, *head=&dmx_muxs;
55
56 list_for_each_safe (pos, n, head) {
57 if (DMX_DIR_ENTRY(pos) == demux) {
58 if (demux->users>0)
59 return -EINVAL;
60 list_del(pos);
61 return 0;
62 }
63 }
64
65 return -ENODEV;
66}
67
68
69/******************************************************************************
70 * static inlined helper functions
71 ******************************************************************************/
72
73
74static inline u16 section_length(const u8 *buf)
75{
76 return 3+((buf[1]&0x0f)<<8)+buf[2];
77}
78
79
80static inline u16 ts_pid(const u8 *buf)
81{
82 return ((buf[1]&0x1f)<<8)+buf[2];
83}
84
85
86static inline u8 payload(const u8 *tsp)
87{
88 if (!(tsp[3] & 0x10)) // no payload?
89 return 0;
90 if (tsp[3] & 0x20) { // adaptation field?
91 if (tsp[4] > 183) // corrupted data?
92 return 0;
93 else
94 return 184-1-tsp[4];
95 }
96 return 184;
97}
98
99
100static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
101{
102 return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len));
103}
104
105
106static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len)
107{
108 memcpy (d, s, len);
109}
110
111
112/******************************************************************************
113 * Software filter functions
114 ******************************************************************************/
115
116static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf)
117{
118 int count = payload(buf);
119 int p;
120 //int ccok;
121 //u8 cc;
122
123 if (count == 0)
124 return -1;
125
126 p = 188-count;
127
128 /*
129 cc=buf[3]&0x0f;
130 ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
131 dvbdmxfeed->cc=cc;
132 if (!ccok)
133 printk("missed packet!\n");
134 */
135
136 if (buf[1] & 0x40) // PUSI ?
137 feed->peslen = 0xfffa;
138
139 feed->peslen += count;
140
141 return feed->cb.ts (&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
142}
143
144
145static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
146 struct dvb_demux_filter *f)
147{
148 u8 neq = 0;
149 int i;
150
151 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
152 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
153
154 if (f->maskandmode[i] & xor)
155 return 0;
156
157 neq |= f->maskandnotmode[i] & xor;
158 }
159
160 if (f->doneq && !neq)
161 return 0;
162
163 return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen,
164 NULL, 0, &f->filter, DMX_OK);
165}
166
167
168static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
169{
170 struct dvb_demux *demux = feed->demux;
171 struct dvb_demux_filter *f = feed->filter;
172 struct dmx_section_feed *sec = &feed->feed.sec;
173 int section_syntax_indicator;
174
175 if (!sec->is_filtering)
176 return 0;
177
178 if (!f)
179 return 0;
180
181 if (sec->check_crc) {
182 section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
183 if (section_syntax_indicator &&
184 demux->check_crc32(feed, sec->secbuf, sec->seclen))
185 return -1;
186 }
187
188 do {
189 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
190 return -1;
191 } while ((f = f->next) && sec->is_filtering);
192
193 sec->seclen = 0;
194
195 return 0;
196}
197
198
199static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
200{
201 struct dmx_section_feed *sec = &feed->feed.sec;
202
203#ifdef DVB_DEMUX_SECTION_LOSS_LOG
204 if(sec->secbufp < sec->tsfeedp)
205 {
206 int i, n = sec->tsfeedp - sec->secbufp;
207
208 /* section padding is done with 0xff bytes entirely.
209 ** due to speed reasons, we won't check all of them
210 ** but just first and last
211 */
212 if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
213 {
214 printk("dvb_demux.c section ts padding loss: %d/%d\n",
215 n, sec->tsfeedp);
216 printk("dvb_demux.c pad data:");
217 for(i = 0; i < n; i++)
218 printk(" %02x", sec->secbuf[i]);
219 printk("\n");
220 }
221 }
222#endif
223
224 sec->tsfeedp = sec->secbufp = sec->seclen = 0;
225 sec->secbuf = sec->secbuf_base;
226}
227
228/*
229** Losless Section Demux 1.4.1 by Emard
230** Valsecchi Patrick:
231** - middle of section A (no PUSI)
232** - end of section A and start of section B
233** (with PUSI pointing to the start of the second section)
234**
235** In this case, without feed->pusi_seen you'll receive a garbage section
236** consisting of the end of section A. Basically because tsfeedp
237** is incemented and the use=0 condition is not raised
238** when the second packet arrives.
239**
240** Fix:
241** when demux is started, let feed->pusi_seen = 0 to
242** prevent initial feeding of garbage from the end of
243** previous section. When you for the first time see PUSI=1
244** then set feed->pusi_seen = 1
245*/
246static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
247{
248 struct dvb_demux *demux = feed->demux;
249 struct dmx_section_feed *sec = &feed->feed.sec;
250 u16 limit, seclen, n;
251
252 if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
253 return 0;
254
255 if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
256 {
257#ifdef DVB_DEMUX_SECTION_LOSS_LOG
258 printk("dvb_demux.c section buffer full loss: %d/%d\n",
259 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
260#endif
261 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
262 }
263
264 if(len <= 0)
265 return 0;
266
267 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
268 sec->tsfeedp += len;
269
270 /* -----------------------------------------------------
271 ** Dump all the sections we can find in the data (Emard)
272 */
273
274 limit = sec->tsfeedp;
275 if(limit > DMX_MAX_SECFEED_SIZE)
276 return -1; /* internal error should never happen */
277
278 /* to be sure always set secbuf */
279 sec->secbuf = sec->secbuf_base + sec->secbufp;
280
281 for(n = 0; sec->secbufp + 2 < limit; n++)
282 {
283 seclen = section_length(sec->secbuf);
284 if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
285 || seclen + sec->secbufp > limit)
286 return 0;
287 sec->seclen = seclen;
288 sec->crc_val = ~0;
289 /* dump [secbuf .. secbuf+seclen) */
290 if(feed->pusi_seen)
291 dvb_dmx_swfilter_section_feed(feed);
292#ifdef DVB_DEMUX_SECTION_LOSS_LOG
293 else
294 printk("dvb_demux.c pusi not seen, discarding section data\n");
295#endif
296 sec->secbufp += seclen; /* secbufp and secbuf moving together is */
297 sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
298 }
299
300 return 0;
301}
302
303
304static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf)
305{
306 u8 p, count;
307 int ccok, dc_i = 0;
308 u8 cc;
309
310 count = payload(buf);
311
312 if (count == 0) /* count == 0 if no payload or out of range */
313 return -1;
314
315 p = 188 - count; /* payload start */
316
317 cc = buf[3] & 0x0f;
318 ccok = ((feed->cc + 1) & 0x0f) == cc;
319 feed->cc = cc;
320
321 if (buf[3] & 0x20) {
322 /* adaption field present, check for discontinuity_indicator */
323 if ((buf[4] > 0) && (buf[5] & 0x80))
324 dc_i = 1;
325 }
326
327 if (!ccok || dc_i) {
328#ifdef DVB_DEMUX_SECTION_LOSS_LOG
329 printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
330 /* those bytes under sume circumstances will again be reported
331 ** in the following dvb_dmx_swfilter_section_new
332 */
333#endif
334 /* Discontinuity detected. Reset pusi_seen = 0 to
335 ** stop feeding of suspicious data until next PUSI=1 arrives
336 */
337 feed->pusi_seen = 0;
338 dvb_dmx_swfilter_section_new(feed);
339 return 0;
340 }
341
342 if (buf[1] & 0x40) {
343 // PUSI=1 (is set), section boundary is here
344 if (count > 1 && buf[p] < count) {
345 const u8 *before = buf+p+1;
346 u8 before_len = buf[p];
347 const u8 *after = before+before_len;
348 u8 after_len = count-1-before_len;
349
350 dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
351 /* before start of new section, set pusi_seen = 1 */
352 feed->pusi_seen = 1;
353 dvb_dmx_swfilter_section_new(feed);
354 dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
355 }
356#ifdef DVB_DEMUX_SECTION_LOSS_LOG
357 else
358 if (count > 0)
359 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
360#endif
361 } else {
362 // PUSI=0 (is not set), no section boundary
363 const u8 *entire = buf+p;
364 u8 entire_len = count;
365
366 dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
367 }
368 return 0;
369}
370
371
372static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
373{
374 switch(feed->type) {
375 case DMX_TYPE_TS:
376 if (!feed->feed.ts.is_filtering)
377 break;
378 if (feed->ts_type & TS_PACKET) {
379 if (feed->ts_type & TS_PAYLOAD_ONLY)
380 dvb_dmx_swfilter_payload(feed, buf);
381 else
382 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
383 }
384 if (feed->ts_type & TS_DECODER)
385 if (feed->demux->write_to_decoder)
386 feed->demux->write_to_decoder(feed, buf, 188);
387 break;
388
389 case DMX_TYPE_SEC:
390 if (!feed->feed.sec.is_filtering)
391 break;
392 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
393 feed->feed.sec.seclen = feed->feed.sec.secbufp=0;
394 break;
395
396 default:
397 break;
398 }
399}
400
401#define DVR_FEED(f) \
402 (((f)->type == DMX_TYPE_TS) && \
403 ((f)->feed.ts.is_filtering) && \
404 (((f)->ts_type & (TS_PACKET|TS_PAYLOAD_ONLY)) == TS_PACKET))
405
406static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
407{
408 struct dvb_demux_feed *feed;
409 struct list_head *pos, *head=&demux->feed_list;
410 u16 pid = ts_pid(buf);
411 int dvr_done = 0;
412
413 list_for_each(pos, head) {
414 feed = list_entry(pos, struct dvb_demux_feed, list_head);
415
416 if ((feed->pid != pid) && (feed->pid != 0x2000))
417 continue;
418
419 /* copy each packet only once to the dvr device, even
420 * if a PID is in multiple filters (e.g. video + PCR) */
421 if ((DVR_FEED(feed)) && (dvr_done++))
422 continue;
423
424 if (feed->pid == pid) {
425 dvb_dmx_swfilter_packet_type(feed, buf);
426 if (DVR_FEED(feed))
427 continue;
428 }
429
430 if (feed->pid == 0x2000)
431 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
432 }
433}
434
435void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
436{
437 spin_lock(&demux->lock);
438
439 while (count--) {
440 if(buf[0] == 0x47) {
441 dvb_dmx_swfilter_packet(demux, buf);
442 }
443 buf += 188;
444 }
445
446 spin_unlock(&demux->lock);
447}
448EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
449
450
451void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
452{
453 int p = 0, i, j;
454
455 spin_lock(&demux->lock);
456
457 if ((i = demux->tsbufp)) {
458 if (count < (j=188-i)) {
459 memcpy(&demux->tsbuf[i], buf, count);
460 demux->tsbufp += count;
461 goto bailout;
462 }
463 memcpy(&demux->tsbuf[i], buf, j);
464 if (demux->tsbuf[0] == 0x47)
465 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
466 demux->tsbufp = 0;
467 p += j;
468 }
469
470 while (p < count) {
471 if (buf[p] == 0x47) {
472 if (count-p >= 188) {
473 dvb_dmx_swfilter_packet(demux, buf+p);
474 p += 188;
475 } else {
476 i = count-p;
477 memcpy(demux->tsbuf, buf+p, i);
478 demux->tsbufp=i;
479 goto bailout;
480 }
481 } else
482 p++;
483 }
484
485bailout:
486 spin_unlock(&demux->lock);
487}
488EXPORT_SYMBOL(dvb_dmx_swfilter);
489
490void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
491{
492 int p = 0,i, j;
493 u8 tmppack[188];
494 spin_lock(&demux->lock);
495
496 if ((i = demux->tsbufp)) {
497 if (count < (j=204-i)) {
498 memcpy(&demux->tsbuf[i], buf, count);
499 demux->tsbufp += count;
500 goto bailout;
501 }
502 memcpy(&demux->tsbuf[i], buf, j);
503 if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8)) {
504 memcpy(tmppack, demux->tsbuf, 188);
505 if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
506 dvb_dmx_swfilter_packet(demux, tmppack);
507 }
508 demux->tsbufp = 0;
509 p += j;
510 }
511
512 while (p < count) {
513 if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
514 if (count-p >= 204) {
515 memcpy(tmppack, buf+p, 188);
516 if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
517 dvb_dmx_swfilter_packet(demux, tmppack);
518 p += 204;
519 } else {
520 i = count-p;
521 memcpy(demux->tsbuf, buf+p, i);
522 demux->tsbufp=i;
523 goto bailout;
524 }
525 } else {
526 p++;
527 }
528 }
529
530bailout:
531 spin_unlock(&demux->lock);
532}
533EXPORT_SYMBOL(dvb_dmx_swfilter_204);
534
535
536static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
537{
538 int i;
539
540 for (i=0; i<demux->filternum; i++)
541 if (demux->filter[i].state == DMX_STATE_FREE)
542 break;
543
544 if (i == demux->filternum)
545 return NULL;
546
547 demux->filter[i].state = DMX_STATE_ALLOCATED;
548
549 return &demux->filter[i];
550}
551
552static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
553{
554 int i;
555
556 for (i=0; i<demux->feednum; i++)
557 if (demux->feed[i].state == DMX_STATE_FREE)
558 break;
559
560 if (i == demux->feednum)
561 return NULL;
562
563 demux->feed[i].state = DMX_STATE_ALLOCATED;
564
565 return &demux->feed[i];
566}
567
568static int dvb_demux_feed_find(struct dvb_demux_feed *feed)
569{
570 struct dvb_demux_feed *entry;
571
572 list_for_each_entry(entry, &feed->demux->feed_list, list_head)
573 if (entry == feed)
574 return 1;
575
576 return 0;
577}
578
579static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
580{
581 spin_lock_irq(&feed->demux->lock);
582 if (dvb_demux_feed_find(feed)) {
583 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
584 __FUNCTION__, feed->type, feed->state, feed->pid);
585 goto out;
586 }
587
588 list_add(&feed->list_head, &feed->demux->feed_list);
589out:
590 spin_unlock_irq(&feed->demux->lock);
591}
592
593static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
594{
595 spin_lock_irq(&feed->demux->lock);
596 if (!(dvb_demux_feed_find(feed))) {
597 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
598 __FUNCTION__, feed->type, feed->state, feed->pid);
599 goto out;
600 }
601
602 list_del(&feed->list_head);
603out:
604 spin_unlock_irq(&feed->demux->lock);
605}
606
607static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
608 enum dmx_ts_pes pes_type, size_t callback_length,
609 size_t circular_buffer_size, int descramble,
610 struct timespec timeout)
611{
612 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
613 struct dvb_demux *demux = feed->demux;
614
615 if (pid > DMX_MAX_PID)
616 return -EINVAL;
617
618 if (down_interruptible (&demux->mutex))
619 return -ERESTARTSYS;
620
621 if (ts_type & TS_DECODER) {
622 if (pes_type >= DMX_TS_PES_OTHER) {
623 up(&demux->mutex);
624 return -EINVAL;
625 }
626
627 if (demux->pesfilter[pes_type] &&
628 demux->pesfilter[pes_type] != feed) {
629 up(&demux->mutex);
630 return -EINVAL;
631 }
632
633 demux->pesfilter[pes_type] = feed;
634 demux->pids[pes_type] = pid;
635 }
636
637 dvb_demux_feed_add(feed);
638
639 feed->pid = pid;
640 feed->buffer_size = circular_buffer_size;
641 feed->descramble = descramble;
642 feed->timeout = timeout;
643 feed->cb_length = callback_length;
644 feed->ts_type = ts_type;
645 feed->pes_type = pes_type;
646
647 if (feed->descramble) {
648 up(&demux->mutex);
649 return -ENOSYS;
650 }
651
652 if (feed->buffer_size) {
653#ifdef NOBUFS
654 feed->buffer=NULL;
655#else
656 feed->buffer = vmalloc(feed->buffer_size);
657 if (!feed->buffer) {
658 up(&demux->mutex);
659 return -ENOMEM;
660 }
661#endif
662 }
663
664 feed->state = DMX_STATE_READY;
665 up(&demux->mutex);
666
667 return 0;
668}
669
670
671static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
672{
673 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
674 struct dvb_demux *demux = feed->demux;
675 int ret;
676
677 if (down_interruptible (&demux->mutex))
678 return -ERESTARTSYS;
679
680 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
681 up(&demux->mutex);
682 return -EINVAL;
683 }
684
685 if (!demux->start_feed) {
686 up(&demux->mutex);
687 return -ENODEV;
688 }
689
690 if ((ret = demux->start_feed(feed)) < 0) {
691 up(&demux->mutex);
692 return ret;
693 }
694
695 spin_lock_irq(&demux->lock);
696 ts_feed->is_filtering = 1;
697 feed->state = DMX_STATE_GO;
698 spin_unlock_irq(&demux->lock);
699 up(&demux->mutex);
700
701 return 0;
702}
703
704static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
705{
706 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
707 struct dvb_demux *demux = feed->demux;
708 int ret;
709
710 if (down_interruptible (&demux->mutex))
711 return -ERESTARTSYS;
712
713 if (feed->state < DMX_STATE_GO) {
714 up(&demux->mutex);
715 return -EINVAL;
716 }
717
718 if (!demux->stop_feed) {
719 up(&demux->mutex);
720 return -ENODEV;
721 }
722
723 ret = demux->stop_feed(feed);
724
725 spin_lock_irq(&demux->lock);
726 ts_feed->is_filtering = 0;
727 feed->state = DMX_STATE_ALLOCATED;
728 spin_unlock_irq(&demux->lock);
729 up(&demux->mutex);
730
731 return ret;
732}
733
734static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed,
735 dmx_ts_cb callback)
736{
737 struct dvb_demux *demux = (struct dvb_demux *) dmx;
738 struct dvb_demux_feed *feed;
739
740 if (down_interruptible (&demux->mutex))
741 return -ERESTARTSYS;
742
743 if (!(feed = dvb_dmx_feed_alloc(demux))) {
744 up(&demux->mutex);
745 return -EBUSY;
746 }
747
748 feed->type = DMX_TYPE_TS;
749 feed->cb.ts = callback;
750 feed->demux = demux;
751 feed->pid = 0xffff;
752 feed->peslen = 0xfffa;
753 feed->buffer = NULL;
754
755 (*ts_feed) = &feed->feed.ts;
756 (*ts_feed)->parent = dmx;
757 (*ts_feed)->priv = NULL;
758 (*ts_feed)->is_filtering = 0;
759 (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
760 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
761 (*ts_feed)->set = dmx_ts_feed_set;
762
763
764 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
765 feed->state = DMX_STATE_FREE;
766 up(&demux->mutex);
767 return -EBUSY;
768 }
769
770 feed->filter->type = DMX_TYPE_TS;
771 feed->filter->feed = feed;
772 feed->filter->state = DMX_STATE_READY;
773
774 up(&demux->mutex);
775
776 return 0;
777}
778
779static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed)
780{
781 struct dvb_demux *demux = (struct dvb_demux *) dmx;
782 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
783
784 if (down_interruptible (&demux->mutex))
785 return -ERESTARTSYS;
786
787 if (feed->state == DMX_STATE_FREE) {
788 up(&demux->mutex);
789 return -EINVAL;
790 }
791
792#ifndef NOBUFS
793 vfree(feed->buffer);
794 feed->buffer=0;
795#endif
796
797 feed->state = DMX_STATE_FREE;
798 feed->filter->state = DMX_STATE_FREE;
799
800 dvb_demux_feed_del(feed);
801
802 feed->pid = 0xffff;
803
804 if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
805 demux->pesfilter[feed->pes_type] = NULL;
806
807 up(&demux->mutex);
808 return 0;
809}
810
811
812/******************************************************************************
813 * dmx_section_feed API calls
814 ******************************************************************************/
815
816static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
817 struct dmx_section_filter** filter)
818{
819 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
820 struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
821 struct dvb_demux_filter *dvbdmxfilter;
822
823 if (down_interruptible (&dvbdemux->mutex))
824 return -ERESTARTSYS;
825
826 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
827 if (!dvbdmxfilter) {
828 up(&dvbdemux->mutex);
829 return -EBUSY;
830 }
831
832 spin_lock_irq(&dvbdemux->lock);
833 *filter = &dvbdmxfilter->filter;
834 (*filter)->parent = feed;
835 (*filter)->priv = NULL;
836 dvbdmxfilter->feed = dvbdmxfeed;
837 dvbdmxfilter->type = DMX_TYPE_SEC;
838 dvbdmxfilter->state = DMX_STATE_READY;
839 dvbdmxfilter->next = dvbdmxfeed->filter;
840 dvbdmxfeed->filter = dvbdmxfilter;
841 spin_unlock_irq(&dvbdemux->lock);
842
843 up(&dvbdemux->mutex);
844 return 0;
845}
846
847
848static int dmx_section_feed_set(struct dmx_section_feed* feed,
849 u16 pid, size_t circular_buffer_size,
850 int descramble, int check_crc)
851{
852 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
853 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
854
855 if (pid > 0x1fff)
856 return -EINVAL;
857
858 if (down_interruptible (&dvbdmx->mutex))
859 return -ERESTARTSYS;
860
861 dvb_demux_feed_add(dvbdmxfeed);
862
863 dvbdmxfeed->pid = pid;
864 dvbdmxfeed->buffer_size = circular_buffer_size;
865 dvbdmxfeed->descramble = descramble;
866 if (dvbdmxfeed->descramble) {
867 up(&dvbdmx->mutex);
868 return -ENOSYS;
869 }
870
871 dvbdmxfeed->feed.sec.check_crc = check_crc;
872
873#ifdef NOBUFS
874 dvbdmxfeed->buffer = NULL;
875#else
876 dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
877 if (!dvbdmxfeed->buffer) {
878 up(&dvbdmx->mutex);
879 return -ENOMEM;
880 }
881#endif
882
883 dvbdmxfeed->state = DMX_STATE_READY;
884 up(&dvbdmx->mutex);
885 return 0;
886}
887
888
889static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
890{
891 int i;
892 struct dvb_demux_filter *f;
893 struct dmx_section_filter *sf;
894 u8 mask, mode, doneq;
895
896 if (!(f=dvbdmxfeed->filter))
897 return;
898 do {
899 sf = &f->filter;
900 doneq = 0;
901 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
902 mode = sf->filter_mode[i];
903 mask = sf->filter_mask[i];
904 f->maskandmode[i] = mask & mode;
905 doneq |= f->maskandnotmode[i] = mask & ~mode;
906 }
907 f->doneq = doneq ? 1 : 0;
908 } while ((f = f->next));
909}
910
911
912static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
913{
914 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
915 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
916 int ret;
917
918 if (down_interruptible (&dvbdmx->mutex))
919 return -ERESTARTSYS;
920
921 if (feed->is_filtering) {
922 up(&dvbdmx->mutex);
923 return -EBUSY;
924 }
925
926 if (!dvbdmxfeed->filter) {
927 up(&dvbdmx->mutex);
928 return -EINVAL;
929 }
930
931 dvbdmxfeed->feed.sec.tsfeedp = 0;
932 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
933 dvbdmxfeed->feed.sec.secbufp = 0;
934 dvbdmxfeed->feed.sec.seclen = 0;
935
936 if (!dvbdmx->start_feed) {
937 up(&dvbdmx->mutex);
938 return -ENODEV;
939 }
940
941 prepare_secfilters(dvbdmxfeed);
942
943 if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
944 up(&dvbdmx->mutex);
945 return ret;
946 }
947
948 spin_lock_irq(&dvbdmx->lock);
949 feed->is_filtering = 1;
950 dvbdmxfeed->state = DMX_STATE_GO;
951 spin_unlock_irq(&dvbdmx->lock);
952
953 up(&dvbdmx->mutex);
954 return 0;
955}
956
957
958static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
959{
960 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
961 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
962 int ret;
963
964 if (down_interruptible (&dvbdmx->mutex))
965 return -ERESTARTSYS;
966
967 if (!dvbdmx->stop_feed) {
968 up(&dvbdmx->mutex);
969 return -ENODEV;
970 }
971
972 ret = dvbdmx->stop_feed(dvbdmxfeed);
973
974 spin_lock_irq(&dvbdmx->lock);
975 dvbdmxfeed->state = DMX_STATE_READY;
976 feed->is_filtering = 0;
977 spin_unlock_irq(&dvbdmx->lock);
978
979 up(&dvbdmx->mutex);
980 return ret;
981}
982
983
984static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
985 struct dmx_section_filter* filter)
986{
987 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *) filter, *f;
988 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
989 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
990
991 if (down_interruptible (&dvbdmx->mutex))
992 return -ERESTARTSYS;
993
994 if (dvbdmxfilter->feed != dvbdmxfeed) {
995 up(&dvbdmx->mutex);
996 return -EINVAL;
997 }
998
999 if (feed->is_filtering)
1000 feed->stop_filtering(feed);
1001
1002 spin_lock_irq(&dvbdmx->lock);
1003 f = dvbdmxfeed->filter;
1004
1005 if (f == dvbdmxfilter) {
1006 dvbdmxfeed->filter = dvbdmxfilter->next;
1007 } else {
1008 while(f->next != dvbdmxfilter)
1009 f = f->next;
1010 f->next = f->next->next;
1011 }
1012
1013 dvbdmxfilter->state = DMX_STATE_FREE;
1014 spin_unlock_irq(&dvbdmx->lock);
1015 up(&dvbdmx->mutex);
1016 return 0;
1017}
1018
1019static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1020 struct dmx_section_feed **feed,
1021 dmx_section_cb callback)
1022{
1023 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
1024 struct dvb_demux_feed *dvbdmxfeed;
1025
1026 if (down_interruptible (&dvbdmx->mutex))
1027 return -ERESTARTSYS;
1028
1029 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
1030 up(&dvbdmx->mutex);
1031 return -EBUSY;
1032 }
1033
1034 dvbdmxfeed->type = DMX_TYPE_SEC;
1035 dvbdmxfeed->cb.sec = callback;
1036 dvbdmxfeed->demux = dvbdmx;
1037 dvbdmxfeed->pid = 0xffff;
1038 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
1039 dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
1040 dvbdmxfeed->feed.sec.tsfeedp = 0;
1041 dvbdmxfeed->filter = NULL;
1042 dvbdmxfeed->buffer = NULL;
1043
1044 (*feed)=&dvbdmxfeed->feed.sec;
1045 (*feed)->is_filtering = 0;
1046 (*feed)->parent = demux;
1047 (*feed)->priv = NULL;
1048
1049 (*feed)->set = dmx_section_feed_set;
1050 (*feed)->allocate_filter = dmx_section_feed_allocate_filter;
1051 (*feed)->start_filtering = dmx_section_feed_start_filtering;
1052 (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
1053 (*feed)->release_filter = dmx_section_feed_release_filter;
1054
1055 up(&dvbdmx->mutex);
1056 return 0;
1057}
1058
1059static int dvbdmx_release_section_feed(struct dmx_demux *demux,
1060 struct dmx_section_feed *feed)
1061{
1062 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
1063 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
1064
1065 if (down_interruptible (&dvbdmx->mutex))
1066 return -ERESTARTSYS;
1067
1068 if (dvbdmxfeed->state==DMX_STATE_FREE) {
1069 up(&dvbdmx->mutex);
1070 return -EINVAL;
1071 }
1072#ifndef NOBUFS
1073 vfree(dvbdmxfeed->buffer);
1074 dvbdmxfeed->buffer=0;
1075#endif
1076 dvbdmxfeed->state=DMX_STATE_FREE;
1077
1078 dvb_demux_feed_del(dvbdmxfeed);
1079
1080 dvbdmxfeed->pid = 0xffff;
1081
1082 up(&dvbdmx->mutex);
1083 return 0;
1084}
1085
1086
1087/******************************************************************************
1088 * dvb_demux kernel data API calls
1089 ******************************************************************************/
1090
1091static int dvbdmx_open(struct dmx_demux *demux)
1092{
1093 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1094
1095 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
1096 return -EUSERS;
1097
1098 dvbdemux->users++;
1099 return 0;
1100}
1101
1102
1103static int dvbdmx_close(struct dmx_demux *demux)
1104{
1105 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1106
1107 if (dvbdemux->users == 0)
1108 return -ENODEV;
1109
1110 dvbdemux->users--;
1111 //FIXME: release any unneeded resources if users==0
1112 return 0;
1113}
1114
1115
1116static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
1117{
1118 struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1119
1120 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1121 return -EINVAL;
1122
1123 if (down_interruptible (&dvbdemux->mutex))
1124 return -ERESTARTSYS;
1125 dvb_dmx_swfilter(dvbdemux, buf, count);
1126 up(&dvbdemux->mutex);
1127
1128 if (signal_pending(current))
1129 return -EINTR;
1130 return count;
1131}
1132
1133
1134static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1135{
1136 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1137 struct list_head *head = &dvbdemux->frontend_list;
1138
1139 list_add(&(frontend->connectivity_list), head);
1140
1141 return 0;
1142}
1143
1144
1145static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1146{
1147 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1148 struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
1149
1150 list_for_each_safe (pos, n, head) {
1151 if (DMX_FE_ENTRY(pos) == frontend) {
1152 list_del(pos);
1153 return 0;
1154 }
1155 }
1156
1157 return -ENODEV;
1158}
1159
1160
1161static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
1162{
1163 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1164
1165 if (list_empty(&dvbdemux->frontend_list))
1166 return NULL;
1167 return &dvbdemux->frontend_list;
1168}
1169
1170
1171static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1172{
1173 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1174
1175 if (demux->frontend)
1176 return -EINVAL;
1177
1178 if (down_interruptible (&dvbdemux->mutex))
1179 return -ERESTARTSYS;
1180
1181 demux->frontend = frontend;
1182 up(&dvbdemux->mutex);
1183 return 0;
1184}
1185
1186
1187static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1188{
1189 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1190
1191 if (down_interruptible (&dvbdemux->mutex))
1192 return -ERESTARTSYS;
1193
1194 demux->frontend = NULL;
1195 up(&dvbdemux->mutex);
1196 return 0;
1197}
1198
1199
1200static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
1201{
1202 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1203
1204 memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
1205 return 0;
1206}
1207
1208
1209int dvb_dmx_init(struct dvb_demux *dvbdemux)
1210{
1211 int i, err;
1212 struct dmx_demux *dmx = &dvbdemux->dmx;
1213
1214 dvbdemux->users = 0;
1215 dvbdemux->filter = vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
1216
1217 if (!dvbdemux->filter)
1218 return -ENOMEM;
1219
1220 dvbdemux->feed = vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
1221 if (!dvbdemux->feed) {
1222 vfree(dvbdemux->filter);
1223 return -ENOMEM;
1224 }
1225 for (i=0; i<dvbdemux->filternum; i++) {
1226 dvbdemux->filter[i].state = DMX_STATE_FREE;
1227 dvbdemux->filter[i].index = i;
1228 }
1229 for (i=0; i<dvbdemux->feednum; i++) {
1230 dvbdemux->feed[i].state = DMX_STATE_FREE;
1231 dvbdemux->feed[i].index = i;
1232 }
1233 dvbdemux->frontend_list.next=
1234 dvbdemux->frontend_list.prev=
1235 &dvbdemux->frontend_list;
1236 for (i=0; i<DMX_TS_PES_OTHER; i++) {
1237 dvbdemux->pesfilter[i] = NULL;
1238 dvbdemux->pids[i] = 0xffff;
1239 }
1240
1241 INIT_LIST_HEAD(&dvbdemux->feed_list);
1242
1243 dvbdemux->playing = 0;
1244 dvbdemux->recording = 0;
1245 dvbdemux->tsbufp = 0;
1246
1247 if (!dvbdemux->check_crc32)
1248 dvbdemux->check_crc32 = dvb_dmx_crc32;
1249
1250 if (!dvbdemux->memcopy)
1251 dvbdemux->memcopy = dvb_dmx_memcopy;
1252
1253 dmx->frontend = NULL;
1254 dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;
1255 dmx->priv = (void *) dvbdemux;
1256 dmx->open = dvbdmx_open;
1257 dmx->close = dvbdmx_close;
1258 dmx->write = dvbdmx_write;
1259 dmx->allocate_ts_feed = dvbdmx_allocate_ts_feed;
1260 dmx->release_ts_feed = dvbdmx_release_ts_feed;
1261 dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
1262 dmx->release_section_feed = dvbdmx_release_section_feed;
1263
1264 dmx->descramble_mac_address = NULL;
1265 dmx->descramble_section_payload = NULL;
1266
1267 dmx->add_frontend = dvbdmx_add_frontend;
1268 dmx->remove_frontend = dvbdmx_remove_frontend;
1269 dmx->get_frontends = dvbdmx_get_frontends;
1270 dmx->connect_frontend = dvbdmx_connect_frontend;
1271 dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
1272 dmx->get_pes_pids = dvbdmx_get_pes_pids;
1273
1274 sema_init(&dvbdemux->mutex, 1);
1275 spin_lock_init(&dvbdemux->lock);
1276
1277 if ((err = dmx_register_demux(dmx)) < 0)
1278 return err;
1279
1280 return 0;
1281}
1282EXPORT_SYMBOL(dvb_dmx_init);
1283
1284
1285int dvb_dmx_release(struct dvb_demux *dvbdemux)
1286{
1287 struct dmx_demux *dmx = &dvbdemux->dmx;
1288
1289 dmx_unregister_demux(dmx);
1290 vfree(dvbdemux->filter);
1291 vfree(dvbdemux->feed);
1292 return 0;
1293}
1294EXPORT_SYMBOL(dvb_dmx_release);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
new file mode 100644
index 000000000000..c09beb391622
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -0,0 +1,146 @@
1/*
2 * dvb_demux.h: DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (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 Lesser 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
24#ifndef _DVB_DEMUX_H_
25#define _DVB_DEMUX_H_
26
27#include <linux/time.h>
28#include <linux/timer.h>
29#include <linux/spinlock.h>
30#include <asm/semaphore.h>
31
32#include "demux.h"
33
34#define DMX_TYPE_TS 0
35#define DMX_TYPE_SEC 1
36#define DMX_TYPE_PES 2
37
38#define DMX_STATE_FREE 0
39#define DMX_STATE_ALLOCATED 1
40#define DMX_STATE_SET 2
41#define DMX_STATE_READY 3
42#define DMX_STATE_GO 4
43
44#define DVB_DEMUX_MASK_MAX 18
45
46struct dvb_demux_filter {
47 struct dmx_section_filter filter;
48 u8 maskandmode [DMX_MAX_FILTER_SIZE];
49 u8 maskandnotmode [DMX_MAX_FILTER_SIZE];
50 int doneq;
51
52 struct dvb_demux_filter *next;
53 struct dvb_demux_feed *feed;
54 int index;
55 int state;
56 int type;
57 int pesto;
58
59 u16 handle;
60 u16 hw_handle;
61 struct timer_list timer;
62 int ts_state;
63};
64
65
66#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
67
68struct dvb_demux_feed {
69 union {
70 struct dmx_ts_feed ts;
71 struct dmx_section_feed sec;
72 } feed;
73
74 union {
75 dmx_ts_cb ts;
76 dmx_section_cb sec;
77 } cb;
78
79 struct dvb_demux *demux;
80 void *priv;
81 int type;
82 int state;
83 u16 pid;
84 u8 *buffer;
85 int buffer_size;
86 int descramble;
87
88 struct timespec timeout;
89 struct dvb_demux_filter *filter;
90 int cb_length;
91
92 int ts_type;
93 enum dmx_ts_pes pes_type;
94
95 int cc;
96 int pusi_seen; /* prevents feeding of garbage from previous section */
97
98 u16 peslen;
99
100 struct list_head list_head;
101 int index; /* a unique index for each feed (can be used as hardware pid filter index) */
102};
103
104struct dvb_demux {
105 struct dmx_demux dmx;
106 void *priv;
107 int filternum;
108 int feednum;
109 int (*start_feed) (struct dvb_demux_feed *feed);
110 int (*stop_feed) (struct dvb_demux_feed *feed);
111 int (*write_to_decoder) (struct dvb_demux_feed *feed,
112 const u8 *buf, size_t len);
113 u32 (*check_crc32) (struct dvb_demux_feed *feed,
114 const u8 *buf, size_t len);
115 void (*memcopy) (struct dvb_demux_feed *feed, u8 *dst,
116 const u8 *src, size_t len);
117
118 int users;
119#define MAX_DVB_DEMUX_USERS 10
120 struct dvb_demux_filter *filter;
121 struct dvb_demux_feed *feed;
122
123 struct list_head frontend_list;
124
125 struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
126 u16 pids[DMX_TS_PES_OTHER];
127 int playing;
128 int recording;
129
130#define DMX_MAX_PID 0x2000
131 struct list_head feed_list;
132 u8 tsbuf[204];
133 int tsbufp;
134
135 struct semaphore mutex;
136 spinlock_t lock;
137};
138
139
140int dvb_dmx_init(struct dvb_demux *dvbdemux);
141int dvb_dmx_release(struct dvb_demux *dvbdemux);
142void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count);
143void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
144void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count);
145
146#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
new file mode 100644
index 000000000000..bd5143906084
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -0,0 +1,603 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/string.h>
4#include "dvb_filter.h"
5
6#if 0
7static unsigned int bitrates[3][16] =
8{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
9 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
10 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
11#endif
12
13static u32 freq[4] = {480, 441, 320, 0};
14
15static unsigned int ac3_bitrates[32] =
16 {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
17 0,0,0,0,0,0,0,0,0,0,0,0,0};
18
19static u32 ac3_frames[3][32] =
20 {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
21 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
22 {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
23 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
24 {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
25 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
26
27
28
29#if 0
30static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
31 void (*pes_write)(u8 *buf, int count, void *data),
32 void *priv)
33{
34 dvb_filter_ipack_init(pa, IPACKS, pes_write);
35 dvb_filter_ipack_init(pv, IPACKS, pes_write);
36 pa->pid = pida;
37 pv->pid = pidv;
38 pa->data = priv;
39 pv->data = priv;
40}
41#endif
42
43#if 0
44static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
45{
46 u8 off = 0;
47
48 if (!buf || !p ){
49 printk("NULL POINTER IDIOT\n");
50 return;
51 }
52 if (buf[1]&PAY_START) {
53 if (p->plength == MMAX_PLENGTH-6 && p->found>6){
54 p->plength = p->found-6;
55 p->found = 0;
56 send_ipack(p);
57 dvb_filter_ipack_reset(p);
58 }
59 }
60 if (buf[3] & ADAPT_FIELD) { // adaptation field?
61 off = buf[4] + 1;
62 if (off+4 > 187) return;
63 }
64 dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
65}
66#endif
67
68#if 0
69/* needs 5 byte input, returns picture coding type*/
70static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
71{
72 u8 pct;
73
74 if (pr) printk( "Pic header: ");
75 pic->temporal_reference[field] = (( headr[0] << 2 ) |
76 (headr[1] & 0x03) )& 0x03ff;
77 if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
78
79 pct = ( headr[1] >> 2 ) & 0x07;
80 pic->picture_coding_type[field] = pct;
81 if (pr) {
82 switch(pct){
83 case I_FRAME:
84 printk( " I-FRAME");
85 break;
86 case B_FRAME:
87 printk( " B-FRAME");
88 break;
89 case P_FRAME:
90 printk( " P-FRAME");
91 break;
92 }
93 }
94
95
96 pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
97 ( (headr[3] & 0x1F) << 11) ) & 0xffff;
98
99 if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
100
101 pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
102 ((headr[4] & 0x80) >> 3);
103
104 if ( pct == B_FRAME ){
105 pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
106 }
107 if (pr) printk( " pic head param: 0x%x",
108 pic->picture_header_parameter);
109
110 return pct;
111}
112#endif
113
114#if 0
115/* needs 4 byte input */
116static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
117{
118 if (pr) printk("GOP header: ");
119
120 pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
121 ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
122
123 if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
124 ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
125 ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
126
127 if ( ( headr[3] & 0x40 ) != 0 ){
128 pic->closed_gop = 1;
129 } else {
130 pic->closed_gop = 0;
131 }
132 if (pr) printk("closed: %d", pic->closed_gop);
133
134 if ( ( headr[3] & 0x20 ) != 0 ){
135 pic->broken_link = 1;
136 } else {
137 pic->broken_link = 0;
138 }
139 if (pr) printk(" broken: %d\n", pic->broken_link);
140
141 return 0;
142}
143#endif
144
145#if 0
146/* needs 8 byte input */
147static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
148{
149 int sw;
150 int form = -1;
151
152 if (pr) printk("Reading sequence header\n");
153
154 vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
155 vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
156
157 sw = (int)((headr[3]&0xF0) >> 4) ;
158
159 switch( sw ){
160 case 1:
161 if (pr)
162 printk("Videostream: ASPECT: 1:1");
163 vi->aspect_ratio = 100;
164 break;
165 case 2:
166 if (pr)
167 printk("Videostream: ASPECT: 4:3");
168 vi->aspect_ratio = 133;
169 break;
170 case 3:
171 if (pr)
172 printk("Videostream: ASPECT: 16:9");
173 vi->aspect_ratio = 177;
174 break;
175 case 4:
176 if (pr)
177 printk("Videostream: ASPECT: 2.21:1");
178 vi->aspect_ratio = 221;
179 break;
180
181 case 5 ... 15:
182 if (pr)
183 printk("Videostream: ASPECT: reserved");
184 vi->aspect_ratio = 0;
185 break;
186
187 default:
188 vi->aspect_ratio = 0;
189 return -1;
190 }
191
192 if (pr)
193 printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
194
195 sw = (int)(headr[3]&0x0F);
196
197 switch ( sw ) {
198 case 1:
199 if (pr)
200 printk(" FRate: 23.976 fps");
201 vi->framerate = 23976;
202 form = -1;
203 break;
204 case 2:
205 if (pr)
206 printk(" FRate: 24 fps");
207 vi->framerate = 24000;
208 form = -1;
209 break;
210 case 3:
211 if (pr)
212 printk(" FRate: 25 fps");
213 vi->framerate = 25000;
214 form = VIDEO_MODE_PAL;
215 break;
216 case 4:
217 if (pr)
218 printk(" FRate: 29.97 fps");
219 vi->framerate = 29970;
220 form = VIDEO_MODE_NTSC;
221 break;
222 case 5:
223 if (pr)
224 printk(" FRate: 30 fps");
225 vi->framerate = 30000;
226 form = VIDEO_MODE_NTSC;
227 break;
228 case 6:
229 if (pr)
230 printk(" FRate: 50 fps");
231 vi->framerate = 50000;
232 form = VIDEO_MODE_PAL;
233 break;
234 case 7:
235 if (pr)
236 printk(" FRate: 60 fps");
237 vi->framerate = 60000;
238 form = VIDEO_MODE_NTSC;
239 break;
240 }
241
242 vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
243
244 vi->vbv_buffer_size
245 = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
246
247 if (pr){
248 printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
249 printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
250 printk("\n");
251 }
252
253 vi->video_format = form;
254
255 return 0;
256}
257#endif
258
259
260#if 0
261static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
262{
263 u8 *headr;
264 int found = 0;
265 int c = 0;
266
267 while (found < 4 && c+4 < count){
268 u8 *b;
269
270 b = mbuf+c;
271 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
272 && b[3] == 0xb3) found = 4;
273 else {
274 c++;
275 }
276 }
277
278 if (! found) return -1;
279 c += 4;
280 if (c+12 >= count) return -1;
281 headr = mbuf+c;
282 if (read_sequence_header(headr, vi, pr) < 0) return -1;
283 vi->off = c-4;
284 return 0;
285}
286#endif
287
288
289#if 0
290static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
291{
292 u8 *headr;
293 int found = 0;
294 int c = 0;
295 int fr = 0;
296
297 while (found < 2 && c < count){
298 u8 b[2];
299 memcpy( b, mbuf+c, 2);
300
301 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
302 found = 2;
303 else {
304 c++;
305 }
306 }
307
308 if (!found) return -1;
309
310 if (c+3 >= count) return -1;
311 headr = mbuf+c;
312
313 ai->layer = (headr[1] & 0x06) >> 1;
314
315 if (pr)
316 printk("Audiostream: Layer: %d", 4-ai->layer);
317
318
319 ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
320
321 if (pr){
322 if (ai->bit_rate == 0)
323 printk(" Bit rate: free");
324 else if (ai->bit_rate == 0xf)
325 printk(" BRate: reserved");
326 else
327 printk(" BRate: %d kb/s", ai->bit_rate/1000);
328 }
329
330 fr = (headr[2] & 0x0c ) >> 2;
331 ai->frequency = freq[fr]*100;
332 if (pr){
333 if (ai->frequency == 3)
334 printk(" Freq: reserved\n");
335 else
336 printk(" Freq: %d kHz\n",ai->frequency);
337
338 }
339 ai->off = c;
340 return 0;
341}
342#endif
343
344
345int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
346{
347 u8 *headr;
348 int found = 0;
349 int c = 0;
350 u8 frame = 0;
351 int fr = 0;
352
353 while ( !found && c < count){
354 u8 *b = mbuf+c;
355
356 if ( b[0] == 0x0b && b[1] == 0x77 )
357 found = 1;
358 else {
359 c++;
360 }
361 }
362
363 if (!found) return -1;
364 if (pr)
365 printk("Audiostream: AC3");
366
367 ai->off = c;
368 if (c+5 >= count) return -1;
369
370 ai->layer = 0; // 0 for AC3
371 headr = mbuf+c+2;
372
373 frame = (headr[2]&0x3f);
374 ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
375
376 if (pr)
377 printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
378
379 ai->frequency = (headr[2] & 0xc0 ) >> 6;
380 fr = (headr[2] & 0xc0 ) >> 6;
381 ai->frequency = freq[fr]*100;
382 if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
383
384
385 ai->framesize = ac3_frames[fr][frame >> 1];
386 if ((frame & 1) && (fr == 1)) ai->framesize++;
387 ai->framesize = ai->framesize << 1;
388 if (pr) printk (" Framesize %d\n",(int) ai->framesize);
389
390
391 return 0;
392}
393EXPORT_SYMBOL(dvb_filter_get_ac3info);
394
395
396#if 0
397static u8 *skip_pes_header(u8 **bufp)
398{
399 u8 *inbuf = *bufp;
400 u8 *buf = inbuf;
401 u8 *pts = NULL;
402 int skip = 0;
403
404 static const int mpeg1_skip_table[16] = {
405 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
406 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
407 };
408
409
410 if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
411 if (buf[7] & PTS_ONLY)
412 pts = buf+9;
413 else pts = NULL;
414 buf = inbuf + 9 + inbuf[8];
415 } else { /* mpeg1 */
416 for (buf = inbuf + 6; *buf == 0xff; buf++)
417 if (buf == inbuf + 6 + 16) {
418 break;
419 }
420 if ((*buf & 0xc0) == 0x40)
421 buf += 2;
422 skip = mpeg1_skip_table [*buf >> 4];
423 if (skip == 5 || skip == 10) pts = buf;
424 else pts = NULL;
425
426 buf += mpeg1_skip_table [*buf >> 4];
427 }
428
429 *bufp = buf;
430 return pts;
431}
432#endif
433
434#if 0
435static void initialize_quant_matrix( u32 *matrix )
436{
437 int i;
438
439 matrix[0] = 0x08101013;
440 matrix[1] = 0x10131616;
441 matrix[2] = 0x16161616;
442 matrix[3] = 0x1a181a1b;
443 matrix[4] = 0x1b1b1a1a;
444 matrix[5] = 0x1a1a1b1b;
445 matrix[6] = 0x1b1d1d1d;
446 matrix[7] = 0x2222221d;
447 matrix[8] = 0x1d1d1b1b;
448 matrix[9] = 0x1d1d2020;
449 matrix[10] = 0x22222526;
450 matrix[11] = 0x25232322;
451 matrix[12] = 0x23262628;
452 matrix[13] = 0x28283030;
453 matrix[14] = 0x2e2e3838;
454 matrix[15] = 0x3a454553;
455
456 for ( i = 16 ; i < 32 ; i++ )
457 matrix[i] = 0x10101010;
458}
459#endif
460
461#if 0
462static void initialize_mpg_picture(struct mpg_picture *pic)
463{
464 int i;
465
466 /* set MPEG1 */
467 pic->mpeg1_flag = 1;
468 pic->profile_and_level = 0x4A ; /* MP@LL */
469 pic->progressive_sequence = 1;
470 pic->low_delay = 0;
471
472 pic->sequence_display_extension_flag = 0;
473 for ( i = 0 ; i < 4 ; i++ ){
474 pic->frame_centre_horizontal_offset[i] = 0;
475 pic->frame_centre_vertical_offset[i] = 0;
476 }
477 pic->last_frame_centre_horizontal_offset = 0;
478 pic->last_frame_centre_vertical_offset = 0;
479
480 pic->picture_display_extension_flag[0] = 0;
481 pic->picture_display_extension_flag[1] = 0;
482 pic->sequence_header_flag = 0;
483 pic->gop_flag = 0;
484 pic->sequence_end_flag = 0;
485}
486#endif
487
488#if 0
489static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
490{
491 int16_t last_h_offset;
492 int16_t last_v_offset;
493
494 int16_t *p_h_offset;
495 int16_t *p_v_offset;
496
497 if ( pic->mpeg1_flag ){
498 pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
499 pic->top_field_first = 0;
500 pic->repeat_first_field = 0;
501 pic->progressive_frame = 1;
502 pic->picture_coding_parameter = 0x000010;
503 }
504
505 /* Reset flag */
506 pic->picture_display_extension_flag[field_type] = 0;
507
508 last_h_offset = pic->last_frame_centre_horizontal_offset;
509 last_v_offset = pic->last_frame_centre_vertical_offset;
510 if ( field_type == FIRST_FIELD ){
511 p_h_offset = pic->frame_centre_horizontal_offset;
512 p_v_offset = pic->frame_centre_vertical_offset;
513 *p_h_offset = last_h_offset;
514 *(p_h_offset + 1) = last_h_offset;
515 *(p_h_offset + 2) = last_h_offset;
516 *p_v_offset = last_v_offset;
517 *(p_v_offset + 1) = last_v_offset;
518 *(p_v_offset + 2) = last_v_offset;
519 } else {
520 pic->frame_centre_horizontal_offset[3] = last_h_offset;
521 pic->frame_centre_vertical_offset[3] = last_v_offset;
522 }
523}
524#endif
525
526#if 0
527static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
528{
529 pic->picture_header = 0;
530 pic->sequence_header_data
531 = ( INIT_HORIZONTAL_SIZE << 20 )
532 | ( INIT_VERTICAL_SIZE << 8 )
533 | ( INIT_ASPECT_RATIO << 4 )
534 | ( INIT_FRAME_RATE );
535 pic->mpeg1_flag = 0;
536 pic->vinfo.horizontal_size
537 = INIT_DISP_HORIZONTAL_SIZE;
538 pic->vinfo.vertical_size
539 = INIT_DISP_VERTICAL_SIZE;
540 pic->picture_display_extension_flag[field_type]
541 = 0;
542 pic->pts_flag[field_type] = 0;
543
544 pic->sequence_gop_header = 0;
545 pic->picture_header = 0;
546 pic->sequence_header_flag = 0;
547 pic->gop_flag = 0;
548 pic->sequence_end_flag = 0;
549 pic->sequence_display_extension_flag = 0;
550 pic->last_frame_centre_horizontal_offset = 0;
551 pic->last_frame_centre_vertical_offset = 0;
552 pic->channel = chan;
553}
554#endif
555
556void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
557 dvb_filter_pes2ts_cb_t *cb, void *priv)
558{
559 unsigned char *buf=p2ts->buf;
560
561 buf[0]=0x47;
562 buf[1]=(pid>>8);
563 buf[2]=pid&0xff;
564 p2ts->cc=0;
565 p2ts->cb=cb;
566 p2ts->priv=priv;
567}
568EXPORT_SYMBOL(dvb_filter_pes2ts_init);
569
570int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
571 int len, int payload_start)
572{
573 unsigned char *buf=p2ts->buf;
574 int ret=0, rest;
575
576 //len=6+((pes[4]<<8)|pes[5]);
577
578 if (payload_start)
579 buf[1]|=0x40;
580 else
581 buf[1]&=~0x40;
582 while (len>=184) {
583 buf[3]=0x10|((p2ts->cc++)&0x0f);
584 memcpy(buf+4, pes, 184);
585 if ((ret=p2ts->cb(p2ts->priv, buf)))
586 return ret;
587 len-=184; pes+=184;
588 buf[1]&=~0x40;
589 }
590 if (!len)
591 return 0;
592 buf[3]=0x30|((p2ts->cc++)&0x0f);
593 rest=183-len;
594 if (rest) {
595 buf[5]=0x00;
596 if (rest-1)
597 memset(buf+6, 0xff, rest-1);
598 }
599 buf[4]=rest;
600 memcpy(buf+5+rest, pes, len);
601 return p2ts->cb(p2ts->priv, buf);
602}
603EXPORT_SYMBOL(dvb_filter_pes2ts);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h
new file mode 100644
index 000000000000..b0848f7836b7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.h
@@ -0,0 +1,246 @@
1/*
2 * dvb_filter.h
3 *
4 * Copyright (C) 2003 Convergence GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_FILTER_H_
22#define _DVB_FILTER_H_
23
24#include <linux/slab.h>
25
26#include "demux.h"
27
28typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
29
30struct dvb_filter_pes2ts {
31 unsigned char buf[188];
32 unsigned char cc;
33 dvb_filter_pes2ts_cb_t *cb;
34 void *priv;
35};
36
37void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
38 dvb_filter_pes2ts_cb_t *cb, void *priv);
39
40int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
41 int len, int payload_start);
42
43
44#define PROG_STREAM_MAP 0xBC
45#define PRIVATE_STREAM1 0xBD
46#define PADDING_STREAM 0xBE
47#define PRIVATE_STREAM2 0xBF
48#define AUDIO_STREAM_S 0xC0
49#define AUDIO_STREAM_E 0xDF
50#define VIDEO_STREAM_S 0xE0
51#define VIDEO_STREAM_E 0xEF
52#define ECM_STREAM 0xF0
53#define EMM_STREAM 0xF1
54#define DSM_CC_STREAM 0xF2
55#define ISO13522_STREAM 0xF3
56#define PROG_STREAM_DIR 0xFF
57
58#define DVB_PICTURE_START 0x00
59#define DVB_USER_START 0xb2
60#define DVB_SEQUENCE_HEADER 0xb3
61#define DVB_SEQUENCE_ERROR 0xb4
62#define DVB_EXTENSION_START 0xb5
63#define DVB_SEQUENCE_END 0xb7
64#define DVB_GOP_START 0xb8
65#define DVB_EXCEPT_SLICE 0xb0
66
67#define SEQUENCE_EXTENSION 0x01
68#define SEQUENCE_DISPLAY_EXTENSION 0x02
69#define PICTURE_CODING_EXTENSION 0x08
70#define QUANT_MATRIX_EXTENSION 0x03
71#define PICTURE_DISPLAY_EXTENSION 0x07
72
73#define I_FRAME 0x01
74#define B_FRAME 0x02
75#define P_FRAME 0x03
76
77/* Initialize sequence_data */
78#define INIT_HORIZONTAL_SIZE 720
79#define INIT_VERTICAL_SIZE 576
80#define INIT_ASPECT_RATIO 0x02
81#define INIT_FRAME_RATE 0x03
82#define INIT_DISP_HORIZONTAL_SIZE 540
83#define INIT_DISP_VERTICAL_SIZE 576
84
85
86//flags2
87#define PTS_DTS_FLAGS 0xC0
88#define ESCR_FLAG 0x20
89#define ES_RATE_FLAG 0x10
90#define DSM_TRICK_FLAG 0x08
91#define ADD_CPY_FLAG 0x04
92#define PES_CRC_FLAG 0x02
93#define PES_EXT_FLAG 0x01
94
95//pts_dts flags
96#define PTS_ONLY 0x80
97#define PTS_DTS 0xC0
98
99#define TS_SIZE 188
100#define TRANS_ERROR 0x80
101#define PAY_START 0x40
102#define TRANS_PRIO 0x20
103#define PID_MASK_HI 0x1F
104//flags
105#define TRANS_SCRMBL1 0x80
106#define TRANS_SCRMBL2 0x40
107#define ADAPT_FIELD 0x20
108#define PAYLOAD 0x10
109#define COUNT_MASK 0x0F
110
111// adaptation flags
112#define DISCON_IND 0x80
113#define RAND_ACC_IND 0x40
114#define ES_PRI_IND 0x20
115#define PCR_FLAG 0x10
116#define OPCR_FLAG 0x08
117#define SPLICE_FLAG 0x04
118#define TRANS_PRIV 0x02
119#define ADAP_EXT_FLAG 0x01
120
121// adaptation extension flags
122#define LTW_FLAG 0x80
123#define PIECE_RATE 0x40
124#define SEAM_SPLICE 0x20
125
126
127#define MAX_PLENGTH 0xFFFF
128#define MMAX_PLENGTH (256*MAX_PLENGTH)
129
130#ifndef IPACKS
131#define IPACKS 2048
132#endif
133
134struct ipack {
135 int size;
136 int found;
137 u8 *buf;
138 u8 cid;
139 u32 plength;
140 u8 plen[2];
141 u8 flag1;
142 u8 flag2;
143 u8 hlength;
144 u8 pts[5];
145 u16 *pid;
146 int mpeg;
147 u8 check;
148 int which;
149 int done;
150 void *data;
151 void (*func)(u8 *buf, int size, void *priv);
152 int count;
153 int repack_subids;
154};
155
156struct dvb_video_info {
157 u32 horizontal_size;
158 u32 vertical_size;
159 u32 aspect_ratio;
160 u32 framerate;
161 u32 video_format;
162 u32 bit_rate;
163 u32 comp_bit_rate;
164 u32 vbv_buffer_size;
165 s16 vbv_delay;
166 u32 CSPF;
167 u32 off;
168};
169
170#define OFF_SIZE 4
171#define FIRST_FIELD 0
172#define SECOND_FIELD 1
173#define VIDEO_FRAME_PICTURE 0x03
174
175struct mpg_picture {
176 int channel;
177 struct dvb_video_info vinfo;
178 u32 *sequence_gop_header;
179 u32 *picture_header;
180 s32 time_code;
181 int low_delay;
182 int closed_gop;
183 int broken_link;
184 int sequence_header_flag;
185 int gop_flag;
186 int sequence_end_flag;
187
188 u8 profile_and_level;
189 s32 picture_coding_parameter;
190 u32 matrix[32];
191 s8 matrix_change_flag;
192
193 u8 picture_header_parameter;
194 /* bit 0 - 2: bwd f code
195 bit 3 : fpb vector
196 bit 4 - 6: fwd f code
197 bit 7 : fpf vector */
198
199 int mpeg1_flag;
200 int progressive_sequence;
201 int sequence_display_extension_flag;
202 u32 sequence_header_data;
203 s16 last_frame_centre_horizontal_offset;
204 s16 last_frame_centre_vertical_offset;
205
206 u32 pts[2]; /* [0] 1st field, [1] 2nd field */
207 int top_field_first;
208 int repeat_first_field;
209 int progressive_frame;
210 int bank;
211 int forward_bank;
212 int backward_bank;
213 int compress;
214 s16 frame_centre_horizontal_offset[OFF_SIZE];
215 /* [0-2] 1st field, [3] 2nd field */
216 s16 frame_centre_vertical_offset[OFF_SIZE];
217 /* [0-2] 1st field, [3] 2nd field */
218 s16 temporal_reference[2];
219 /* [0] 1st field, [1] 2nd field */
220
221 s8 picture_coding_type[2];
222 /* [0] 1st field, [1] 2nd field */
223 s8 picture_structure[2];
224 /* [0] 1st field, [1] 2nd field */
225 s8 picture_display_extension_flag[2];
226 /* [0] 1st field, [1] 2nd field */
227 /* picture_display_extenion() 0:no 1:exit*/
228 s8 pts_flag[2];
229 /* [0] 1st field, [1] 2nd field */
230};
231
232struct dvb_audio_info {
233 int layer;
234 u32 bit_rate;
235 u32 frequency;
236 u32 mode;
237 u32 mode_extension ;
238 u32 emphasis;
239 u32 framesize;
240 u32 off;
241};
242
243int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
244
245
246#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
new file mode 100644
index 000000000000..59a9adfae1eb
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -0,0 +1,915 @@
1/*
2 * dvb_frontend.c: DVB frontend tuning interface/thread
3 *
4 *
5 * Copyright (C) 1999-2001 Ralph Metzler
6 * Marcus Metzler
7 * Holger Waechtler
8 * for convergence integrated media GmbH
9 *
10 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup)
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 */
27
28#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/wait.h>
32#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/list.h>
37#include <linux/suspend.h>
38#include <asm/processor.h>
39#include <asm/semaphore.h>
40
41#include "dvb_frontend.h"
42#include "dvbdev.h"
43
44static int dvb_frontend_debug;
45static int dvb_shutdown_timeout = 5;
46static int dvb_force_auto_inversion;
47static int dvb_override_tune_delay;
48static int dvb_powerdown_on_sleep = 1;
49
50module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
51MODULE_PARM_DESC(dvb_frontend_debug, "Turn on/off frontend core debugging (default:off).");
52module_param(dvb_shutdown_timeout, int, 0444);
53MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
54module_param(dvb_force_auto_inversion, int, 0444);
55MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
56module_param(dvb_override_tune_delay, int, 0444);
57MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
58module_param(dvb_powerdown_on_sleep, int, 0444);
59MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)");
60
61#define dprintk if (dvb_frontend_debug) printk
62
63#define FESTATE_IDLE 1
64#define FESTATE_RETUNE 2
65#define FESTATE_TUNING_FAST 4
66#define FESTATE_TUNING_SLOW 8
67#define FESTATE_TUNED 16
68#define FESTATE_ZIGZAG_FAST 32
69#define FESTATE_ZIGZAG_SLOW 64
70#define FESTATE_DISEQC 128
71#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
72#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
73#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
74#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
75/*
76 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
77 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.
78 * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress.
79 * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower.
80 * FESTATE_TUNED. The frontend has successfully locked on.
81 * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it.
82 * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower.
83 * FESTATE_DISEQC. A DISEQC command has just been issued.
84 * FESTATE_WAITFORLOCK. When we're waiting for a lock.
85 * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan.
86 * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan.
87 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
88 */
89
90static DECLARE_MUTEX(frontend_mutex);
91
92struct dvb_frontend_private {
93
94 struct dvb_device *dvbdev;
95 struct dvb_frontend_parameters parameters;
96 struct dvb_fe_events events;
97 struct semaphore sem;
98 struct list_head list_head;
99 wait_queue_head_t wait_queue;
100 pid_t thread_pid;
101 unsigned long release_jiffies;
102 int state;
103 int bending;
104 int lnb_drift;
105 int inversion;
106 int auto_step;
107 int auto_sub_step;
108 int started_auto_step;
109 int min_delay;
110 int max_drift;
111 int step_size;
112 int exit;
113 int wakeup;
114 fe_status_t status;
115};
116
117
118static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
119{
120 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
121 struct dvb_fe_events *events = &fepriv->events;
122 struct dvb_frontend_event *e;
123 int wp;
124
125 dprintk ("%s\n", __FUNCTION__);
126
127 if (down_interruptible (&events->sem))
128 return;
129
130 wp = (events->eventw + 1) % MAX_EVENT;
131
132 if (wp == events->eventr) {
133 events->overflow = 1;
134 events->eventr = (events->eventr + 1) % MAX_EVENT;
135 }
136
137 e = &events->events[events->eventw];
138
139 memcpy (&e->parameters, &fepriv->parameters,
140 sizeof (struct dvb_frontend_parameters));
141
142 if (status & FE_HAS_LOCK)
143 if (fe->ops->get_frontend)
144 fe->ops->get_frontend(fe, &e->parameters);
145
146 events->eventw = wp;
147
148 up (&events->sem);
149
150 e->status = status;
151
152 wake_up_interruptible (&events->wait_queue);
153}
154
155static int dvb_frontend_get_event(struct dvb_frontend *fe,
156 struct dvb_frontend_event *event, int flags)
157{
158 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
159 struct dvb_fe_events *events = &fepriv->events;
160
161 dprintk ("%s\n", __FUNCTION__);
162
163 if (events->overflow) {
164 events->overflow = 0;
165 return -EOVERFLOW;
166 }
167
168 if (events->eventw == events->eventr) {
169 int ret;
170
171 if (flags & O_NONBLOCK)
172 return -EWOULDBLOCK;
173
174 up(&fepriv->sem);
175
176 ret = wait_event_interruptible (events->wait_queue,
177 events->eventw != events->eventr);
178
179 if (down_interruptible (&fepriv->sem))
180 return -ERESTARTSYS;
181
182 if (ret < 0)
183 return ret;
184 }
185
186 if (down_interruptible (&events->sem))
187 return -ERESTARTSYS;
188
189 memcpy (event, &events->events[events->eventr],
190 sizeof(struct dvb_frontend_event));
191
192 events->eventr = (events->eventr + 1) % MAX_EVENT;
193
194 up (&events->sem);
195
196 return 0;
197}
198
199static void dvb_frontend_init(struct dvb_frontend *fe)
200{
201 dprintk ("DVB: initialising frontend %i (%s)...\n",
202 fe->dvb->num,
203 fe->ops->info.name);
204
205 if (fe->ops->init)
206 fe->ops->init(fe);
207}
208
209static void update_delay(int *quality, int *delay, int min_delay, int locked)
210{
211 int q2;
212
213 dprintk ("%s\n", __FUNCTION__);
214
215 if (locked)
216 (*quality) = (*quality * 220 + 36*256) / 256;
217 else
218 (*quality) = (*quality * 220 + 0) / 256;
219
220 q2 = *quality - 128;
221 q2 *= q2;
222
223 *delay = min_delay + q2 * HZ / (128*128);
224}
225
226/**
227 * Performs automatic twiddling of frontend parameters.
228 *
229 * @param fe The frontend concerned.
230 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
231 * @returns Number of complete iterations that have been performed.
232 */
233static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
234{
235 int autoinversion;
236 int ready = 0;
237 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
238 int original_inversion = fepriv->parameters.inversion;
239 u32 original_frequency = fepriv->parameters.frequency;
240
241 /* are we using autoinversion? */
242 autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
243 (fepriv->parameters.inversion == INVERSION_AUTO));
244
245 /* setup parameters correctly */
246 while(!ready) {
247 /* calculate the lnb_drift */
248 fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size;
249
250 /* wrap the auto_step if we've exceeded the maximum drift */
251 if (fepriv->lnb_drift > fepriv->max_drift) {
252 fepriv->auto_step = 0;
253 fepriv->auto_sub_step = 0;
254 fepriv->lnb_drift = 0;
255 }
256
257 /* perform inversion and +/- zigzag */
258 switch(fepriv->auto_sub_step) {
259 case 0:
260 /* try with the current inversion and current drift setting */
261 ready = 1;
262 break;
263
264 case 1:
265 if (!autoinversion) break;
266
267 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
268 ready = 1;
269 break;
270
271 case 2:
272 if (fepriv->lnb_drift == 0) break;
273
274 fepriv->lnb_drift = -fepriv->lnb_drift;
275 ready = 1;
276 break;
277
278 case 3:
279 if (fepriv->lnb_drift == 0) break;
280 if (!autoinversion) break;
281
282 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
283 fepriv->lnb_drift = -fepriv->lnb_drift;
284 ready = 1;
285 break;
286
287 default:
288 fepriv->auto_step++;
289 fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
290 break;
291 }
292
293 if (!ready) fepriv->auto_sub_step++;
294 }
295
296 /* if this attempt would hit where we started, indicate a complete
297 * iteration has occurred */
298 if ((fepriv->auto_step == fepriv->started_auto_step) &&
299 (fepriv->auto_sub_step == 0) && check_wrapped) {
300 return 1;
301 }
302
303 dprintk("%s: drift:%i inversion:%i auto_step:%i "
304 "auto_sub_step:%i started_auto_step:%i\n",
305 __FUNCTION__, fepriv->lnb_drift, fepriv->inversion,
306 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
307
308 /* set the frontend itself */
309 fepriv->parameters.frequency += fepriv->lnb_drift;
310 if (autoinversion)
311 fepriv->parameters.inversion = fepriv->inversion;
312 if (fe->ops->set_frontend)
313 fe->ops->set_frontend(fe, &fepriv->parameters);
314
315 fepriv->parameters.frequency = original_frequency;
316 fepriv->parameters.inversion = original_inversion;
317
318 fepriv->auto_sub_step++;
319 return 0;
320}
321
322static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
323{
324 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
325
326 if (fepriv->exit)
327 return 1;
328
329 if (fepriv->dvbdev->writers == 1)
330 if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ)
331 return 1;
332
333 return 0;
334}
335
336static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
337{
338 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
339
340 if (fepriv->wakeup) {
341 fepriv->wakeup = 0;
342 return 1;
343 }
344 return dvb_frontend_is_exiting(fe);
345}
346
347static void dvb_frontend_wakeup(struct dvb_frontend *fe)
348{
349 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
350
351 fepriv->wakeup = 1;
352 wake_up_interruptible(&fepriv->wait_queue);
353}
354
355/*
356 * FIXME: use linux/kthread.h
357 */
358static int dvb_frontend_thread(void *data)
359{
360 struct dvb_frontend *fe = (struct dvb_frontend *) data;
361 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
362 unsigned long timeout;
363 char name [15];
364 int quality = 0, delay = 3*HZ;
365 fe_status_t s;
366 int check_wrapped = 0;
367
368 dprintk("%s\n", __FUNCTION__);
369
370 snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);
371
372 lock_kernel();
373 daemonize(name);
374 sigfillset(&current->blocked);
375 unlock_kernel();
376
377 fepriv->status = 0;
378 dvb_frontend_init(fe);
379 fepriv->wakeup = 0;
380
381 while (1) {
382 up(&fepriv->sem); /* is locked when we enter the thread... */
383
384 timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
385 dvb_frontend_should_wakeup(fe),
386 delay);
387 if (0 != dvb_frontend_is_exiting(fe)) {
388 /* got signal or quitting */
389 break;
390 }
391
392 if (current->flags & PF_FREEZE)
393 refrigerator(PF_FREEZE);
394
395 if (down_interruptible(&fepriv->sem))
396 break;
397
398 /* if we've got no parameters, just keep idling */
399 if (fepriv->state & FESTATE_IDLE) {
400 delay = 3*HZ;
401 quality = 0;
402 continue;
403 }
404
405 /* get the frontend status */
406 if (fepriv->state & FESTATE_RETUNE) {
407 s = 0;
408 } else {
409 if (fe->ops->read_status)
410 fe->ops->read_status(fe, &s);
411 if (s != fepriv->status) {
412 dvb_frontend_add_event(fe, s);
413 fepriv->status = s;
414 }
415 }
416 /* if we're not tuned, and we have a lock, move to the TUNED state */
417 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
418 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
419 fepriv->state = FESTATE_TUNED;
420
421 /* if we're tuned, then we have determined the correct inversion */
422 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
423 (fepriv->parameters.inversion == INVERSION_AUTO)) {
424 fepriv->parameters.inversion = fepriv->inversion;
425 }
426 continue;
427 }
428
429 /* if we are tuned already, check we're still locked */
430 if (fepriv->state & FESTATE_TUNED) {
431 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
432
433 /* we're tuned, and the lock is still good... */
434 if (s & FE_HAS_LOCK)
435 continue;
436 else {
437 /* if we _WERE_ tuned, but now don't have a lock,
438 * need to zigzag */
439 fepriv->state = FESTATE_ZIGZAG_FAST;
440 fepriv->started_auto_step = fepriv->auto_step;
441 check_wrapped = 0;
442 }
443 }
444
445 /* don't actually do anything if we're in the LOSTLOCK state,
446 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
447 if ((fepriv->state & FESTATE_LOSTLOCK) &&
448 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
449 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
450 continue;
451 }
452
453 /* don't do anything if we're in the DISEQC state, since this
454 * might be someone with a motorized dish controlled by DISEQC.
455 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */
456 if (fepriv->state & FESTATE_DISEQC) {
457 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
458 continue;
459 }
460
461 /* if we're in the RETUNE state, set everything up for a brand
462 * new scan, keeping the current inversion setting, as the next
463 * tune is _very_ likely to require the same */
464 if (fepriv->state & FESTATE_RETUNE) {
465 fepriv->lnb_drift = 0;
466 fepriv->auto_step = 0;
467 fepriv->auto_sub_step = 0;
468 fepriv->started_auto_step = 0;
469 check_wrapped = 0;
470 }
471
472 /* fast zigzag. */
473 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
474 delay = fepriv->min_delay;
475
476 /* peform a tune */
477 if (dvb_frontend_autotune(fe, check_wrapped)) {
478 /* OK, if we've run out of trials at the fast speed.
479 * Drop back to slow for the _next_ attempt */
480 fepriv->state = FESTATE_SEARCHING_SLOW;
481 fepriv->started_auto_step = fepriv->auto_step;
482 continue;
483 }
484 check_wrapped = 1;
485
486 /* if we've just retuned, enter the ZIGZAG_FAST state.
487 * This ensures we cannot return from an
488 * FE_SET_FRONTEND ioctl before the first frontend tune
489 * occurs */
490 if (fepriv->state & FESTATE_RETUNE) {
491 fepriv->state = FESTATE_TUNING_FAST;
492 }
493 }
494
495 /* slow zigzag */
496 if (fepriv->state & FESTATE_SEARCHING_SLOW) {
497 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
498
499 /* Note: don't bother checking for wrapping; we stay in this
500 * state until we get a lock */
501 dvb_frontend_autotune(fe, 0);
502 }
503 }
504
505 if (dvb_shutdown_timeout) {
506 if (dvb_powerdown_on_sleep)
507 if (fe->ops->set_voltage)
508 fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF);
509 if (fe->ops->sleep)
510 fe->ops->sleep(fe);
511 }
512
513 fepriv->thread_pid = 0;
514 mb();
515
516 dvb_frontend_wakeup(fe);
517 return 0;
518}
519
520static void dvb_frontend_stop(struct dvb_frontend *fe)
521{
522 unsigned long ret;
523 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
524
525 dprintk ("%s\n", __FUNCTION__);
526
527 fepriv->exit = 1;
528 mb();
529
530 if (!fepriv->thread_pid)
531 return;
532
533 /* check if the thread is really alive */
534 if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) {
535 printk("dvb_frontend_stop: thread PID %d already died\n",
536 fepriv->thread_pid);
537 /* make sure the mutex was not held by the thread */
538 init_MUTEX (&fepriv->sem);
539 return;
540 }
541
542 /* wake up the frontend thread, so it notices that fe->exit == 1 */
543 dvb_frontend_wakeup(fe);
544
545 /* wait until the frontend thread has exited */
546 ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid);
547 if (-ERESTARTSYS != ret) {
548 fepriv->state = FESTATE_IDLE;
549 return;
550 }
551 fepriv->state = FESTATE_IDLE;
552
553 /* paranoia check in case a signal arrived */
554 if (fepriv->thread_pid)
555 printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
556 fepriv->thread_pid);
557}
558
559static int dvb_frontend_start(struct dvb_frontend *fe)
560{
561 int ret;
562 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
563
564 dprintk ("%s\n", __FUNCTION__);
565
566 if (fepriv->thread_pid) {
567 if (!fepriv->exit)
568 return 0;
569 else
570 dvb_frontend_stop (fe);
571 }
572
573 if (signal_pending(current))
574 return -EINTR;
575 if (down_interruptible (&fepriv->sem))
576 return -EINTR;
577
578 fepriv->state = FESTATE_IDLE;
579 fepriv->exit = 0;
580 fepriv->thread_pid = 0;
581 mb();
582
583 ret = kernel_thread (dvb_frontend_thread, fe, 0);
584
585 if (ret < 0) {
586 printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);
587 up(&fepriv->sem);
588 return ret;
589 }
590 fepriv->thread_pid = ret;
591
592 return 0;
593}
594
595static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
596 unsigned int cmd, void *parg)
597{
598 struct dvb_device *dvbdev = file->private_data;
599 struct dvb_frontend *fe = dvbdev->priv;
600 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
601 int err = -EOPNOTSUPP;
602
603 dprintk ("%s\n", __FUNCTION__);
604
605 if (!fe || fepriv->exit)
606 return -ENODEV;
607
608 if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
609 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
610 cmd == FE_DISEQC_RECV_SLAVE_REPLY))
611 return -EPERM;
612
613 if (down_interruptible (&fepriv->sem))
614 return -ERESTARTSYS;
615
616 switch (cmd) {
617 case FE_GET_INFO: {
618 struct dvb_frontend_info* info = (struct dvb_frontend_info*) parg;
619 memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info));
620
621 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
622 * do it, it is done for it. */
623 info->caps |= FE_CAN_INVERSION_AUTO;
624 err = 0;
625 break;
626 }
627
628 case FE_READ_STATUS:
629 if (fe->ops->read_status)
630 err = fe->ops->read_status(fe, (fe_status_t*) parg);
631 break;
632
633 case FE_READ_BER:
634 if (fe->ops->read_ber)
635 err = fe->ops->read_ber(fe, (__u32*) parg);
636 break;
637
638 case FE_READ_SIGNAL_STRENGTH:
639 if (fe->ops->read_signal_strength)
640 err = fe->ops->read_signal_strength(fe, (__u16*) parg);
641 break;
642
643 case FE_READ_SNR:
644 if (fe->ops->read_snr)
645 err = fe->ops->read_snr(fe, (__u16*) parg);
646 break;
647
648 case FE_READ_UNCORRECTED_BLOCKS:
649 if (fe->ops->read_ucblocks)
650 err = fe->ops->read_ucblocks(fe, (__u32*) parg);
651 break;
652
653
654 case FE_DISEQC_RESET_OVERLOAD:
655 if (fe->ops->diseqc_reset_overload) {
656 err = fe->ops->diseqc_reset_overload(fe);
657 fepriv->state = FESTATE_DISEQC;
658 fepriv->status = 0;
659 }
660 break;
661
662 case FE_DISEQC_SEND_MASTER_CMD:
663 if (fe->ops->diseqc_send_master_cmd) {
664 err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
665 fepriv->state = FESTATE_DISEQC;
666 fepriv->status = 0;
667 }
668 break;
669
670 case FE_DISEQC_SEND_BURST:
671 if (fe->ops->diseqc_send_burst) {
672 err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
673 fepriv->state = FESTATE_DISEQC;
674 fepriv->status = 0;
675 }
676 break;
677
678 case FE_SET_TONE:
679 if (fe->ops->set_tone) {
680 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
681 fepriv->state = FESTATE_DISEQC;
682 fepriv->status = 0;
683 }
684 break;
685
686 case FE_SET_VOLTAGE:
687 if (fe->ops->set_voltage) {
688 err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
689 fepriv->state = FESTATE_DISEQC;
690 fepriv->status = 0;
691 }
692 break;
693
694 case FE_DISHNETWORK_SEND_LEGACY_CMD:
695 if (fe->ops->dishnetwork_send_legacy_command) {
696 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
697 fepriv->state = FESTATE_DISEQC;
698 fepriv->status = 0;
699 }
700 break;
701
702 case FE_DISEQC_RECV_SLAVE_REPLY:
703 if (fe->ops->diseqc_recv_slave_reply)
704 err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
705 break;
706
707 case FE_ENABLE_HIGH_LNB_VOLTAGE:
708 if (fe->ops->enable_high_lnb_voltage)
709 err = fe->ops->enable_high_lnb_voltage(fe, (int) parg);
710 break;
711
712 case FE_SET_FRONTEND: {
713 struct dvb_frontend_tune_settings fetunesettings;
714
715 memcpy (&fepriv->parameters, parg,
716 sizeof (struct dvb_frontend_parameters));
717
718 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
719 memcpy(&fetunesettings.parameters, parg,
720 sizeof (struct dvb_frontend_parameters));
721
722 /* force auto frequency inversion if requested */
723 if (dvb_force_auto_inversion) {
724 fepriv->parameters.inversion = INVERSION_AUTO;
725 fetunesettings.parameters.inversion = INVERSION_AUTO;
726 }
727 if (fe->ops->info.type == FE_OFDM) {
728 /* without hierachical coding code_rate_LP is irrelevant,
729 * so we tolerate the otherwise invalid FEC_NONE setting */
730 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
731 fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
732 fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
733 }
734
735 /* get frontend-specific tuning settings */
736 if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) {
737 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
738 fepriv->max_drift = fetunesettings.max_drift;
739 fepriv->step_size = fetunesettings.step_size;
740 } else {
741 /* default values */
742 switch(fe->ops->info.type) {
743 case FE_QPSK:
744 fepriv->min_delay = HZ/20;
745 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
746 fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000;
747 break;
748
749 case FE_QAM:
750 fepriv->min_delay = HZ/20;
751 fepriv->step_size = 0; /* no zigzag */
752 fepriv->max_drift = 0;
753 break;
754
755 case FE_OFDM:
756 fepriv->min_delay = HZ/20;
757 fepriv->step_size = fe->ops->info.frequency_stepsize * 2;
758 fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1;
759 break;
760 case FE_ATSC:
761 printk("dvb-core: FE_ATSC not handled yet.\n");
762 break;
763 }
764 }
765 if (dvb_override_tune_delay > 0)
766 fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
767
768 fepriv->state = FESTATE_RETUNE;
769 dvb_frontend_wakeup(fe);
770 dvb_frontend_add_event(fe, 0);
771 fepriv->status = 0;
772 err = 0;
773 break;
774 }
775
776 case FE_GET_EVENT:
777 err = dvb_frontend_get_event (fe, parg, file->f_flags);
778 break;
779
780 case FE_GET_FRONTEND:
781 if (fe->ops->get_frontend) {
782 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
783 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg);
784 }
785 break;
786 };
787
788 up (&fepriv->sem);
789 return err;
790}
791
792static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
793{
794 struct dvb_device *dvbdev = file->private_data;
795 struct dvb_frontend *fe = dvbdev->priv;
796 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
797
798 dprintk ("%s\n", __FUNCTION__);
799
800 poll_wait (file, &fepriv->events.wait_queue, wait);
801
802 if (fepriv->events.eventw != fepriv->events.eventr)
803 return (POLLIN | POLLRDNORM | POLLPRI);
804
805 return 0;
806}
807
808static int dvb_frontend_open(struct inode *inode, struct file *file)
809{
810 struct dvb_device *dvbdev = file->private_data;
811 struct dvb_frontend *fe = dvbdev->priv;
812 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
813 int ret;
814
815 dprintk ("%s\n", __FUNCTION__);
816
817 if ((ret = dvb_generic_open (inode, file)) < 0)
818 return ret;
819
820 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
821 ret = dvb_frontend_start (fe);
822 if (ret)
823 dvb_generic_release (inode, file);
824
825 /* empty event queue */
826 fepriv->events.eventr = fepriv->events.eventw = 0;
827 }
828
829 return ret;
830}
831
832static int dvb_frontend_release(struct inode *inode, struct file *file)
833{
834 struct dvb_device *dvbdev = file->private_data;
835 struct dvb_frontend *fe = dvbdev->priv;
836 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
837
838 dprintk ("%s\n", __FUNCTION__);
839
840 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
841 fepriv->release_jiffies = jiffies;
842
843 return dvb_generic_release (inode, file);
844}
845
846static struct file_operations dvb_frontend_fops = {
847 .owner = THIS_MODULE,
848 .ioctl = dvb_generic_ioctl,
849 .poll = dvb_frontend_poll,
850 .open = dvb_frontend_open,
851 .release = dvb_frontend_release
852};
853
854int dvb_register_frontend(struct dvb_adapter* dvb,
855 struct dvb_frontend* fe)
856{
857 struct dvb_frontend_private *fepriv;
858 static const struct dvb_device dvbdev_template = {
859 .users = ~0,
860 .writers = 1,
861 .readers = (~0)-1,
862 .fops = &dvb_frontend_fops,
863 .kernel_ioctl = dvb_frontend_ioctl
864 };
865
866 dprintk ("%s\n", __FUNCTION__);
867
868 if (down_interruptible (&frontend_mutex))
869 return -ERESTARTSYS;
870
871 fe->frontend_priv = kmalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
872 if (fe->frontend_priv == NULL) {
873 up(&frontend_mutex);
874 return -ENOMEM;
875 }
876 fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
877 memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private));
878
879 init_MUTEX (&fepriv->sem);
880 init_waitqueue_head (&fepriv->wait_queue);
881 init_waitqueue_head (&fepriv->events.wait_queue);
882 init_MUTEX (&fepriv->events.sem);
883 fe->dvb = dvb;
884 fepriv->inversion = INVERSION_OFF;
885
886 printk ("DVB: registering frontend %i (%s)...\n",
887 fe->dvb->num,
888 fe->ops->info.name);
889
890 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
891 fe, DVB_DEVICE_FRONTEND);
892
893 up (&frontend_mutex);
894 return 0;
895}
896EXPORT_SYMBOL(dvb_register_frontend);
897
898int dvb_unregister_frontend(struct dvb_frontend* fe)
899{
900 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
901 dprintk ("%s\n", __FUNCTION__);
902
903 down (&frontend_mutex);
904 dvb_unregister_device (fepriv->dvbdev);
905 dvb_frontend_stop (fe);
906 if (fe->ops->release)
907 fe->ops->release(fe);
908 else
909 printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
910 /* fe is invalid now */
911 kfree(fepriv);
912 up (&frontend_mutex);
913 return 0;
914}
915EXPORT_SYMBOL(dvb_unregister_frontend);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
new file mode 100644
index 000000000000..d2b021792791
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -0,0 +1,126 @@
1/*
2 * dvb_frontend.h
3 *
4 * Copyright (C) 2001 convergence integrated media GmbH
5 * Copyright (C) 2004 convergence GmbH
6 *
7 * Written by Ralph Metzler
8 * Overhauled by Holger Waechtler
9 * Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 *
26 */
27
28#ifndef _DVB_FRONTEND_H_
29#define _DVB_FRONTEND_H_
30
31#include <linux/types.h>
32#include <linux/sched.h>
33#include <linux/ioctl.h>
34#include <linux/i2c.h>
35#include <linux/module.h>
36#include <linux/errno.h>
37#include <linux/delay.h>
38
39#include <linux/dvb/frontend.h>
40
41#include "dvbdev.h"
42
43/* FIXME: Move to i2c-id.h */
44#define I2C_DRIVERID_DVBFE_SP8870 I2C_DRIVERID_EXP2
45#define I2C_DRIVERID_DVBFE_CX22700 I2C_DRIVERID_EXP2
46#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2
47#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2
48#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2
49#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2
50#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2
51#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2
52#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
53#define I2C_DRIVERID_DVBFE_MT312 I2C_DRIVERID_EXP2
54#define I2C_DRIVERID_DVBFE_MT352 I2C_DRIVERID_EXP2
55#define I2C_DRIVERID_DVBFE_NXT6000 I2C_DRIVERID_EXP2
56#define I2C_DRIVERID_DVBFE_SP887X I2C_DRIVERID_EXP2
57#define I2C_DRIVERID_DVBFE_STV0299 I2C_DRIVERID_EXP2
58#define I2C_DRIVERID_DVBFE_TDA1004X I2C_DRIVERID_EXP2
59#define I2C_DRIVERID_DVBFE_TDA8083 I2C_DRIVERID_EXP2
60#define I2C_DRIVERID_DVBFE_VES1820 I2C_DRIVERID_EXP2
61#define I2C_DRIVERID_DVBFE_VES1X93 I2C_DRIVERID_EXP2
62#define I2C_DRIVERID_DVBFE_TDA80XX I2C_DRIVERID_EXP2
63
64
65struct dvb_frontend_tune_settings {
66 int min_delay_ms;
67 int step_size;
68 int max_drift;
69 struct dvb_frontend_parameters parameters;
70};
71
72struct dvb_frontend;
73
74struct dvb_frontend_ops {
75
76 struct dvb_frontend_info info;
77
78 void (*release)(struct dvb_frontend* fe);
79
80 int (*init)(struct dvb_frontend* fe);
81 int (*sleep)(struct dvb_frontend* fe);
82
83 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
84 int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
85 int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
86
87 int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
88 int (*read_ber)(struct dvb_frontend* fe, u32* ber);
89 int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
90 int (*read_snr)(struct dvb_frontend* fe, u16* snr);
91 int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks);
92
93 int (*diseqc_reset_overload)(struct dvb_frontend* fe);
94 int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
95 int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
96 int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
97 int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
98 int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
99 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg);
100 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
101};
102
103#define MAX_EVENT 8
104
105struct dvb_fe_events {
106 struct dvb_frontend_event events[MAX_EVENT];
107 int eventw;
108 int eventr;
109 int overflow;
110 wait_queue_head_t wait_queue;
111 struct semaphore sem;
112};
113
114struct dvb_frontend {
115 struct dvb_frontend_ops* ops;
116 struct dvb_adapter *dvb;
117 void* demodulator_priv;
118 void* frontend_priv;
119};
120
121extern int dvb_register_frontend(struct dvb_adapter* dvb,
122 struct dvb_frontend* fe);
123
124extern int dvb_unregister_frontend(struct dvb_frontend* fe);
125
126#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
new file mode 100644
index 000000000000..44892e7abd3d
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -0,0 +1,1381 @@
1/*
2 * dvb_net.c
3 *
4 * Copyright (C) 2001 Convergence integrated media GmbH
5 * Ralph Metzler <ralph@convergence.de>
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * ULE Decapsulation code:
9 * Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH.
10 * and Department of Scientific Computing
11 * Paris Lodron University of Salzburg.
12 * Hilmar Linder <hlinder@cosy.sbg.ac.at>
13 * and Wolfram Stering <wstering@cosy.sbg.ac.at>
14 *
15 * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31 */
32
33/*
34 * ULE ChangeLog:
35 * Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt
36 *
37 * Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt:
38 * ULE Extension header handling.
39 * Bugreports by Moritz Vieth and Hanno Tersteegen,
40 * Fraunhofer Institute for Open Communication Systems
41 * Competence Center for Advanced Satellite Communications.
42 * Bugfixes and robustness improvements.
43 * Filtering on dest MAC addresses, if present (D-Bit = 0)
44 * ULE_DEBUG compile-time option.
45 */
46
47/*
48 * FIXME / TODO (dvb_net.c):
49 *
50 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
51 *
52 * TS_FEED callback is called once for every single TS cell although it is
53 * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()).
54 *
55 */
56
57#include <linux/module.h>
58#include <linux/kernel.h>
59#include <linux/netdevice.h>
60#include <linux/etherdevice.h>
61#include <linux/dvb/net.h>
62#include <linux/uio.h>
63#include <asm/uaccess.h>
64#include <linux/crc32.h>
65#include <linux/version.h>
66
67#include "dvb_demux.h"
68#include "dvb_net.h"
69
70static int dvb_net_debug;
71module_param(dvb_net_debug, int, 0444);
72MODULE_PARM_DESC(dvb_net_debug, "enable debug messages");
73
74#define dprintk(x...) do { if (dvb_net_debug) printk(x); } while (0)
75
76
77static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
78{
79 unsigned int j;
80 for (j = 0; j < cnt; j++)
81 c = crc32_be( c, iov[j].iov_base, iov[j].iov_len );
82 return c;
83}
84
85
86#define DVB_NET_MULTICAST_MAX 10
87
88#undef ULE_DEBUG
89
90#ifdef ULE_DEBUG
91
92#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
93
94static void hexdump( const unsigned char *buf, unsigned short len )
95{
96 char str[80], octet[10];
97 int ofs, i, l;
98
99 for (ofs = 0; ofs < len; ofs += 16) {
100 sprintf( str, "%03d: ", ofs );
101
102 for (i = 0; i < 16; i++) {
103 if ((i + ofs) < len)
104 sprintf( octet, "%02x ", buf[ofs + i] );
105 else
106 strcpy( octet, " " );
107
108 strcat( str, octet );
109 }
110 strcat( str, " " );
111 l = strlen( str );
112
113 for (i = 0; (i < 16) && ((i + ofs) < len); i++)
114 str[l++] = isprint( buf[ofs + i] ) ? buf[ofs + i] : '.';
115
116 str[l] = '\0';
117 printk( KERN_WARNING "%s\n", str );
118 }
119}
120
121#endif
122
123struct dvb_net_priv {
124 int in_use;
125 struct net_device_stats stats;
126 u16 pid;
127 struct dvb_net *host;
128 struct dmx_demux *demux;
129 struct dmx_section_feed *secfeed;
130 struct dmx_section_filter *secfilter;
131 struct dmx_ts_feed *tsfeed;
132 int multi_num;
133 struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
134 unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
135 int rx_mode;
136#define RX_MODE_UNI 0
137#define RX_MODE_MULTI 1
138#define RX_MODE_ALL_MULTI 2
139#define RX_MODE_PROMISC 3
140 struct work_struct set_multicast_list_wq;
141 struct work_struct restart_net_feed_wq;
142 unsigned char feedtype; /* Either FEED_TYPE_ or FEED_TYPE_ULE */
143 int need_pusi; /* Set to 1, if synchronization on PUSI required. */
144 unsigned char tscc; /* TS continuity counter after sync on PUSI. */
145 struct sk_buff *ule_skb; /* ULE SNDU decodes into this buffer. */
146 unsigned char *ule_next_hdr; /* Pointer into skb to next ULE extension header. */
147 unsigned short ule_sndu_len; /* ULE SNDU length in bytes, w/o D-Bit. */
148 unsigned short ule_sndu_type; /* ULE SNDU type field, complete. */
149 unsigned char ule_sndu_type_1; /* ULE SNDU type field, if split across 2 TS cells. */
150 unsigned char ule_dbit; /* Whether the DestMAC address present
151 * or not (bit is set). */
152 unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */
153 int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */
154 unsigned long ts_count; /* Current ts cell counter. */
155};
156
157
158/**
159 * Determine the packet's protocol ID. The rule here is that we
160 * assume 802.3 if the type field is short enough to be a length.
161 * This is normal practice and works for any 'now in use' protocol.
162 *
163 * stolen from eth.c out of the linux kernel, hacked for dvb-device
164 * by Michael Holzt <kju@debian.org>
165 */
166static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
167 struct net_device *dev)
168{
169 struct ethhdr *eth;
170 unsigned char *rawp;
171
172 skb->mac.raw=skb->data;
173 skb_pull(skb,dev->hard_header_len);
174#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
175 eth = skb->mac.ethernet;
176#else
177 eth = eth_hdr(skb);
178#endif
179
180 if (*eth->h_dest & 1) {
181 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
182 skb->pkt_type=PACKET_BROADCAST;
183 else
184 skb->pkt_type=PACKET_MULTICAST;
185 }
186
187 if (ntohs(eth->h_proto) >= 1536)
188 return eth->h_proto;
189
190 rawp = skb->data;
191
192 /**
193 * This is a magic hack to spot IPX packets. Older Novell breaks
194 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
195 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
196 * won't work for fault tolerant netware but does for the rest.
197 */
198 if (*(unsigned short *)rawp == 0xFFFF)
199 return htons(ETH_P_802_3);
200
201 /**
202 * Real 802.2 LLC
203 */
204 return htons(ETH_P_802_2);
205}
206
207#define TS_SZ 188
208#define TS_SYNC 0x47
209#define TS_TEI 0x80
210#define TS_SC 0xC0
211#define TS_PUSI 0x40
212#define TS_AF_A 0x20
213#define TS_AF_D 0x10
214
215/* ULE Extension Header handlers. */
216
217#define ULE_TEST 0
218#define ULE_BRIDGED 1
219
220static int ule_test_sndu( struct dvb_net_priv *p )
221{
222 return -1;
223}
224
225static int ule_bridged_sndu( struct dvb_net_priv *p )
226{
227 /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt.
228 * This has to be the last extension header, otherwise it won't work.
229 * Blame the authors!
230 */
231 p->ule_bridged = 1;
232 return 0;
233}
234
235
236/** Handle ULE extension headers.
237 * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
238 * Returns: >= 0: nr. of bytes consumed by next extension header
239 * -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
240 */
241static int handle_one_ule_extension( struct dvb_net_priv *p )
242{
243 /* Table of mandatory extension header handlers. The header type is the index. */
244 static int (*ule_mandatory_ext_handlers[255])( struct dvb_net_priv *p ) =
245 { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, };
246
247 /* Table of optional extension header handlers. The header type is the index. */
248 static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, };
249
250 int ext_len = 0;
251 unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8;
252 unsigned char htype = p->ule_sndu_type & 0x00FF;
253
254 /* Discriminate mandatory and optional extension headers. */
255 if (hlen == 0) {
256 /* Mandatory extension header */
257 if (ule_mandatory_ext_handlers[htype]) {
258 ext_len = ule_mandatory_ext_handlers[htype]( p );
259 p->ule_next_hdr += ext_len;
260 if (! p->ule_bridged) {
261 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr );
262 p->ule_next_hdr += 2;
263 } else {
264 p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) );
265 /* This assures the extension handling loop will terminate. */
266 }
267 } else
268 ext_len = -1; /* SNDU has to be discarded. */
269 } else {
270 /* Optional extension header. Calculate the length. */
271 ext_len = hlen << 2;
272 /* Process the optional extension header according to its type. */
273 if (ule_optional_ext_handlers[htype])
274 (void)ule_optional_ext_handlers[htype]( p );
275 p->ule_next_hdr += ext_len;
276 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr );
277 p->ule_next_hdr += 2;
278 }
279
280 return ext_len;
281}
282
283static int handle_ule_extensions( struct dvb_net_priv *p )
284{
285 int total_ext_len = 0, l;
286
287 p->ule_next_hdr = p->ule_skb->data;
288 do {
289 l = handle_one_ule_extension( p );
290 if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */
291 total_ext_len += l;
292
293 } while (p->ule_sndu_type < 1536);
294
295 return total_ext_len;
296}
297
298
299/** Prepare for a new ULE SNDU: reset the decoder state. */
300static inline void reset_ule( struct dvb_net_priv *p )
301{
302 p->ule_skb = NULL;
303 p->ule_next_hdr = NULL;
304 p->ule_sndu_len = 0;
305 p->ule_sndu_type = 0;
306 p->ule_sndu_type_1 = 0;
307 p->ule_sndu_remain = 0;
308 p->ule_dbit = 0xFF;
309 p->ule_bridged = 0;
310}
311
312/**
313 * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
314 * TS cells of a single PID.
315 */
316static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
317{
318 struct dvb_net_priv *priv = (struct dvb_net_priv *)dev->priv;
319 unsigned long skipped = 0L;
320 u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1;
321 struct ethhdr *ethh = NULL;
322
323#ifdef ULE_DEBUG
324 /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
325 static unsigned char ule_hist[100*TS_SZ];
326 static unsigned char *ule_where = ule_hist, ule_dump = 0;
327#endif
328
329 if (dev == NULL) {
330 printk( KERN_ERR "NO netdev struct!\n" );
331 return;
332 }
333
334 /* For all TS cells in current buffer.
335 * Appearently, we are called for every single TS cell.
336 */
337 for (ts = (char *)buf, ts_end = (char *)buf + buf_len; ts < ts_end; /* no default incr. */ ) {
338
339 if (new_ts) {
340 /* We are about to process a new TS cell. */
341
342#ifdef ULE_DEBUG
343 if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist;
344 memcpy( ule_where, ts, TS_SZ );
345 if (ule_dump) {
346 hexdump( ule_where, TS_SZ );
347 ule_dump = 0;
348 }
349 ule_where += TS_SZ;
350#endif
351
352 /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */
353 if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) {
354 printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
355 priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6);
356
357 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
358 if (priv->ule_skb) {
359 dev_kfree_skb( priv->ule_skb );
360 /* Prepare for next SNDU. */
361 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
362 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
363 }
364 reset_ule(priv);
365 priv->need_pusi = 1;
366
367 /* Continue with next TS cell. */
368 ts += TS_SZ;
369 priv->ts_count++;
370 continue;
371 }
372
373 ts_remain = 184;
374 from_where = ts + 4;
375 }
376 /* Synchronize on PUSI, if required. */
377 if (priv->need_pusi) {
378 if (ts[1] & TS_PUSI) {
379 /* Find beginning of first ULE SNDU in current TS cell. */
380 /* Synchronize continuity counter. */
381 priv->tscc = ts[3] & 0x0F;
382 /* There is a pointer field here. */
383 if (ts[4] > ts_remain) {
384 printk(KERN_ERR "%lu: Invalid ULE packet "
385 "(pointer field %d)\n", priv->ts_count, ts[4]);
386 ts += TS_SZ;
387 priv->ts_count++;
388 continue;
389 }
390 /* Skip to destination of pointer field. */
391 from_where = &ts[5] + ts[4];
392 ts_remain -= 1 + ts[4];
393 skipped = 0;
394 } else {
395 skipped++;
396 ts += TS_SZ;
397 priv->ts_count++;
398 continue;
399 }
400 }
401
402 /* Check continuity counter. */
403 if (new_ts) {
404 if ((ts[3] & 0x0F) == priv->tscc)
405 priv->tscc = (priv->tscc + 1) & 0x0F;
406 else {
407 /* TS discontinuity handling: */
408 printk(KERN_WARNING "%lu: TS discontinuity: got %#x, "
409 "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc);
410 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
411 if (priv->ule_skb) {
412 dev_kfree_skb( priv->ule_skb );
413 /* Prepare for next SNDU. */
414 // reset_ule(priv); moved to below.
415 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
416 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
417 }
418 reset_ule(priv);
419 /* skip to next PUSI. */
420 priv->need_pusi = 1;
421 ts += TS_SZ;
422 priv->ts_count++;
423 continue;
424 }
425 /* If we still have an incomplete payload, but PUSI is
426 * set; some TS cells are missing.
427 * This is only possible here, if we missed exactly 16 TS
428 * cells (continuity counter wrap). */
429 if (ts[1] & TS_PUSI) {
430 if (! priv->need_pusi) {
431 if (*from_where > 181) {
432 /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */
433 printk(KERN_WARNING "%lu: Invalid pointer "
434 "field: %u.\n", priv->ts_count, *from_where);
435
436 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
437 if (priv->ule_skb) {
438 dev_kfree_skb( priv->ule_skb );
439 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
440 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
441 }
442 reset_ule(priv);
443 priv->need_pusi = 1;
444 ts += TS_SZ;
445 priv->ts_count++;
446 continue;
447 }
448 /* Skip pointer field (we're processing a
449 * packed payload). */
450 from_where += 1;
451 ts_remain -= 1;
452 } else
453 priv->need_pusi = 0;
454
455 if (priv->ule_sndu_remain > 183) {
456 /* Current SNDU lacks more data than there could be available in the
457 * current TS cell. */
458 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
459 ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++;
460 printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
461 "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n",
462 priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
463 dev_kfree_skb(priv->ule_skb);
464 /* Prepare for next SNDU. */
465 reset_ule(priv);
466 /* Resync: go to where pointer field points to: start of next ULE SNDU. */
467 from_where += ts[4];
468 ts_remain -= ts[4];
469 }
470 }
471 }
472
473 /* Check if new payload needs to be started. */
474 if (priv->ule_skb == NULL) {
475 /* Start a new payload with skb.
476 * Find ULE header. It is only guaranteed that the
477 * length field (2 bytes) is contained in the current
478 * TS.
479 * Check ts_remain has to be >= 2 here. */
480 if (ts_remain < 2) {
481 printk(KERN_WARNING "Invalid payload packing: only %d "
482 "bytes left in TS. Resyncing.\n", ts_remain);
483 priv->ule_sndu_len = 0;
484 priv->need_pusi = 1;
485 continue;
486 }
487
488 if (! priv->ule_sndu_len) {
489 /* Got at least two bytes, thus extrace the SNDU length. */
490 priv->ule_sndu_len = from_where[0] << 8 | from_where[1];
491 if (priv->ule_sndu_len & 0x8000) {
492 /* D-Bit is set: no dest mac present. */
493 priv->ule_sndu_len &= 0x7FFF;
494 priv->ule_dbit = 1;
495 } else
496 priv->ule_dbit = 0;
497
498 if (priv->ule_sndu_len > 32763) {
499 printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
500 "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
501 priv->ule_sndu_len = 0;
502 priv->need_pusi = 1;
503 new_ts = 1;
504 ts += TS_SZ;
505 priv->ts_count++;
506 continue;
507 }
508 ts_remain -= 2; /* consume the 2 bytes SNDU length. */
509 from_where += 2;
510 }
511
512 /*
513 * State of current TS:
514 * ts_remain (remaining bytes in the current TS cell)
515 * 0 ule_type is not available now, we need the next TS cell
516 * 1 the first byte of the ule_type is present
517 * >=2 full ULE header present, maybe some payload data as well.
518 */
519 switch (ts_remain) {
520 case 1:
521 priv->ule_sndu_type = from_where[0] << 8;
522 priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
523 ts_remain -= 1; from_where += 1;
524 /* Continue w/ next TS. */
525 case 0:
526 new_ts = 1;
527 ts += TS_SZ;
528 priv->ts_count++;
529 continue;
530
531 default: /* complete ULE header is present in current TS. */
532 /* Extract ULE type field. */
533 if (priv->ule_sndu_type_1) {
534 priv->ule_sndu_type |= from_where[0];
535 from_where += 1; /* points to payload start. */
536 ts_remain -= 1;
537 } else {
538 /* Complete type is present in new TS. */
539 priv->ule_sndu_type = from_where[0] << 8 | from_where[1];
540 from_where += 2; /* points to payload start. */
541 ts_remain -= 2;
542 }
543 break;
544 }
545
546 /* Allocate the skb (decoder target buffer) with the correct size, as follows:
547 * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */
548 priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN );
549 if (priv->ule_skb == NULL) {
550 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
551 dev->name);
552 ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++;
553 return;
554 }
555
556 /* This includes the CRC32 _and_ dest mac, if !dbit. */
557 priv->ule_sndu_remain = priv->ule_sndu_len;
558 priv->ule_skb->dev = dev;
559 /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */
560 skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN );
561 }
562
563 /* Copy data into our current skb. */
564 how_much = min(priv->ule_sndu_remain, (int)ts_remain);
565 memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much);
566 priv->ule_sndu_remain -= how_much;
567 ts_remain -= how_much;
568 from_where += how_much;
569
570 /* Check for complete payload. */
571 if (priv->ule_sndu_remain <= 0) {
572 /* Check CRC32, we've got it in our skb already. */
573 unsigned short ulen = htons(priv->ule_sndu_len);
574 unsigned short utype = htons(priv->ule_sndu_type);
575 struct kvec iov[3] = {
576 { &ulen, sizeof ulen },
577 { &utype, sizeof utype },
578 { priv->ule_skb->data, priv->ule_skb->len - 4 }
579 };
580 unsigned long ule_crc = ~0L, expected_crc;
581 if (priv->ule_dbit) {
582 /* Set D-bit for CRC32 verification,
583 * if it was set originally. */
584 ulen |= 0x0080;
585 }
586
587 ule_crc = iov_crc32(ule_crc, iov, 3);
588 expected_crc = *((u8 *)priv->ule_skb->tail - 4) << 24 |
589 *((u8 *)priv->ule_skb->tail - 3) << 16 |
590 *((u8 *)priv->ule_skb->tail - 2) << 8 |
591 *((u8 *)priv->ule_skb->tail - 1);
592 if (ule_crc != expected_crc) {
593 printk(KERN_WARNING "%lu: CRC32 check FAILED: %#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
594 priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
595
596#ifdef ULE_DEBUG
597 hexdump( iov[0].iov_base, iov[0].iov_len );
598 hexdump( iov[1].iov_base, iov[1].iov_len );
599 hexdump( iov[2].iov_base, iov[2].iov_len );
600
601 if (ule_where == ule_hist) {
602 hexdump( &ule_hist[98*TS_SZ], TS_SZ );
603 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
604 } else if (ule_where == &ule_hist[TS_SZ]) {
605 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
606 hexdump( ule_hist, TS_SZ );
607 } else {
608 hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ );
609 hexdump( ule_where - TS_SZ, TS_SZ );
610 }
611 ule_dump = 1;
612#endif
613
614 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
615 ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++;
616 dev_kfree_skb(priv->ule_skb);
617 } else {
618 /* CRC32 verified OK. */
619 /* Handle ULE Extension Headers. */
620 if (priv->ule_sndu_type < 1536) {
621 /* There is an extension header. Handle it accordingly. */
622 int l = handle_ule_extensions( priv );
623 if (l < 0) {
624 /* Mandatory extension header unknown or TEST SNDU. Drop it. */
625 // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" );
626 dev_kfree_skb( priv->ule_skb );
627 goto sndu_done;
628 }
629 skb_pull( priv->ule_skb, l );
630 }
631
632 /* CRC32 was OK. Remove it from skb. */
633 priv->ule_skb->tail -= 4;
634 priv->ule_skb->len -= 4;
635
636 /* Filter on receiver's destination MAC address, if present. */
637 if (!priv->ule_dbit) {
638 /* The destination MAC address is the next data in the skb. */
639 if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) {
640 /* MAC addresses don't match. Drop SNDU. */
641 // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" );
642 dev_kfree_skb( priv->ule_skb );
643 goto sndu_done;
644 }
645 if (! priv->ule_bridged) {
646 skb_push( priv->ule_skb, ETH_ALEN + 2 );
647 ethh = (struct ethhdr *)priv->ule_skb->data;
648 memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN );
649 memset( ethh->h_source, 0, ETH_ALEN );
650 ethh->h_proto = htons( priv->ule_sndu_type );
651 } else {
652 /* Skip the Receiver destination MAC address. */
653 skb_pull( priv->ule_skb, ETH_ALEN );
654 }
655 } else {
656 if (! priv->ule_bridged) {
657 skb_push( priv->ule_skb, ETH_HLEN );
658 ethh = (struct ethhdr *)priv->ule_skb->data;
659 memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN );
660 memset( ethh->h_source, 0, ETH_ALEN );
661 ethh->h_proto = htons( priv->ule_sndu_type );
662 } else {
663 /* skb is in correct state; nothing to do. */
664 }
665 }
666 priv->ule_bridged = 0;
667
668 /* Stuff into kernel's protocol stack. */
669 priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev);
670 /* If D-bit is set (i.e. destination MAC address not present),
671 * receive the packet anyhow. */
672 /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
673 priv->ule_skb->pkt_type = PACKET_HOST; */
674 ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++;
675 ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len;
676 netif_rx(priv->ule_skb);
677 }
678 sndu_done:
679 /* Prepare for next SNDU. */
680 reset_ule(priv);
681 }
682
683 /* More data in current TS (look at the bytes following the CRC32)? */
684 if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) {
685 /* Next ULE SNDU starts right there. */
686 new_ts = 0;
687 priv->ule_skb = NULL;
688 priv->ule_sndu_type_1 = 0;
689 priv->ule_sndu_len = 0;
690 // printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n",
691 // *(from_where + 0), *(from_where + 1),
692 // *(from_where + 2), *(from_where + 3));
693 // printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0);
694 // hexdump(ts, 188);
695 } else {
696 new_ts = 1;
697 ts += TS_SZ;
698 priv->ts_count++;
699 if (priv->ule_skb == NULL) {
700 priv->need_pusi = 1;
701 priv->ule_sndu_type_1 = 0;
702 priv->ule_sndu_len = 0;
703 }
704 }
705 } /* for all available TS cells */
706}
707
708static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
709 const u8 *buffer2, size_t buffer2_len,
710 struct dmx_ts_feed *feed, enum dmx_success success)
711{
712 struct net_device *dev = (struct net_device *)feed->priv;
713
714 if (buffer2 != 0)
715 printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2);
716 if (buffer1_len > 32768)
717 printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
718 /* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
719 buffer1_len, buffer1_len / TS_SZ, buffer1); */
720 dvb_net_ule(dev, buffer1, buffer1_len);
721 return 0;
722}
723
724
725static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
726{
727 u8 *eth;
728 struct sk_buff *skb;
729 struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
730
731 /* note: pkt_len includes a 32bit checksum */
732 if (pkt_len < 16) {
733 printk("%s: IP/MPE packet length = %d too small.\n",
734 dev->name, pkt_len);
735 stats->rx_errors++;
736 stats->rx_length_errors++;
737 return;
738 }
739/* it seems some ISPs manage to screw up here, so we have to
740 * relax the error checks... */
741#if 0
742 if ((pkt[5] & 0xfd) != 0xc1) {
743 /* drop scrambled or broken packets */
744#else
745 if ((pkt[5] & 0x3c) != 0x00) {
746 /* drop scrambled */
747#endif
748 stats->rx_errors++;
749 stats->rx_crc_errors++;
750 return;
751 }
752 if (pkt[5] & 0x02) {
753 //FIXME: handle LLC/SNAP
754 stats->rx_dropped++;
755 return;
756 }
757 if (pkt[7]) {
758 /* FIXME: assemble datagram from multiple sections */
759 stats->rx_errors++;
760 stats->rx_frame_errors++;
761 return;
762 }
763
764 /* we have 14 byte ethernet header (ip header follows);
765 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment
766 */
767 if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) {
768 //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
769 stats->rx_dropped++;
770 return;
771 }
772 skb_reserve(skb, 2); /* longword align L3 header */
773 skb->dev = dev;
774
775 /* copy L3 payload */
776 eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14);
777 memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4);
778
779 /* create ethernet header: */
780 eth[0]=pkt[0x0b];
781 eth[1]=pkt[0x0a];
782 eth[2]=pkt[0x09];
783 eth[3]=pkt[0x08];
784 eth[4]=pkt[0x04];
785 eth[5]=pkt[0x03];
786
787 eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
788
789 eth[12] = 0x08; /* ETH_P_IP */
790 eth[13] = 0x00;
791
792 skb->protocol = dvb_net_eth_type_trans(skb, dev);
793
794 stats->rx_packets++;
795 stats->rx_bytes+=skb->len;
796 netif_rx(skb);
797}
798
799static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
800 const u8 *buffer2, size_t buffer2_len,
801 struct dmx_section_filter *filter,
802 enum dmx_success success)
803{
804 struct net_device *dev=(struct net_device *) filter->priv;
805
806 /**
807 * we rely on the DVB API definition where exactly one complete
808 * section is delivered in buffer1
809 */
810 dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
811 return 0;
812}
813
814static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
815{
816 dev_kfree_skb(skb);
817 return 0;
818}
819
820static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
821static u8 mask_allmulti[6]={0xff, 0xff, 0xff, 0x00, 0x00, 0x00};
822static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
823static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
824
825static int dvb_net_filter_sec_set(struct net_device *dev,
826 struct dmx_section_filter **secfilter,
827 u8 *mac, u8 *mac_mask)
828{
829 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
830 int ret;
831
832 *secfilter=NULL;
833 ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
834 if (ret<0) {
835 printk("%s: could not get filter\n", dev->name);
836 return ret;
837 }
838
839 (*secfilter)->priv=(void *) dev;
840
841 memset((*secfilter)->filter_value, 0x00, DMX_MAX_FILTER_SIZE);
842 memset((*secfilter)->filter_mask, 0x00, DMX_MAX_FILTER_SIZE);
843 memset((*secfilter)->filter_mode, 0xff, DMX_MAX_FILTER_SIZE);
844
845 (*secfilter)->filter_value[0]=0x3e;
846 (*secfilter)->filter_value[3]=mac[5];
847 (*secfilter)->filter_value[4]=mac[4];
848 (*secfilter)->filter_value[8]=mac[3];
849 (*secfilter)->filter_value[9]=mac[2];
850 (*secfilter)->filter_value[10]=mac[1];
851 (*secfilter)->filter_value[11]=mac[0];
852
853 (*secfilter)->filter_mask[0] = 0xff;
854 (*secfilter)->filter_mask[3] = mac_mask[5];
855 (*secfilter)->filter_mask[4] = mac_mask[4];
856 (*secfilter)->filter_mask[8] = mac_mask[3];
857 (*secfilter)->filter_mask[9] = mac_mask[2];
858 (*secfilter)->filter_mask[10] = mac_mask[1];
859 (*secfilter)->filter_mask[11]=mac_mask[0];
860
861 dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
862 dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
863 dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
864 dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
865 mac_mask[3], mac_mask[4], mac_mask[5]);
866
867 return 0;
868}
869
870static int dvb_net_feed_start(struct net_device *dev)
871{
872 int ret, i;
873 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
874 struct dmx_demux *demux = priv->demux;
875 unsigned char *mac = (unsigned char *) dev->dev_addr;
876
877 dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
878 if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
879 printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
880
881 priv->secfeed=NULL;
882 priv->secfilter=NULL;
883 priv->tsfeed = NULL;
884
885 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
886 dprintk("%s: alloc secfeed\n", __FUNCTION__);
887 ret=demux->allocate_section_feed(demux, &priv->secfeed,
888 dvb_net_sec_callback);
889 if (ret<0) {
890 printk("%s: could not allocate section feed\n", dev->name);
891 return ret;
892 }
893
894 ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
895
896 if (ret<0) {
897 printk("%s: could not set section feed\n", dev->name);
898 priv->demux->release_section_feed(priv->demux, priv->secfeed);
899 priv->secfeed=NULL;
900 return ret;
901 }
902
903 if (priv->rx_mode != RX_MODE_PROMISC) {
904 dprintk("%s: set secfilter\n", __FUNCTION__);
905 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal);
906 }
907
908 switch (priv->rx_mode) {
909 case RX_MODE_MULTI:
910 for (i = 0; i < priv->multi_num; i++) {
911 dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i);
912 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i],
913 priv->multi_macs[i], mask_normal);
914 }
915 break;
916 case RX_MODE_ALL_MULTI:
917 priv->multi_num=1;
918 dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__);
919 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0],
920 mac_allmulti, mask_allmulti);
921 break;
922 case RX_MODE_PROMISC:
923 priv->multi_num=0;
924 dprintk("%s: set secfilter\n", __FUNCTION__);
925 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc);
926 break;
927 }
928
929 dprintk("%s: start filtering\n", __FUNCTION__);
930 priv->secfeed->start_filtering(priv->secfeed);
931 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
932 struct timespec timeout = { 0, 30000000 }; // 30 msec
933
934 /* we have payloads encapsulated in TS */
935 dprintk("%s: alloc tsfeed\n", __FUNCTION__);
936 ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
937 if (ret < 0) {
938 printk("%s: could not allocate ts feed\n", dev->name);
939 return ret;
940 }
941
942 /* Set netdevice pointer for ts decaps callback. */
943 priv->tsfeed->priv = (void *)dev;
944 ret = priv->tsfeed->set(priv->tsfeed, priv->pid,
945 TS_PACKET, DMX_TS_PES_OTHER,
946 188 * 100, /* nr. of bytes delivered per callback */
947 32768, /* circular buffer size */
948 0, /* descramble */
949 timeout);
950
951 if (ret < 0) {
952 printk("%s: could not set ts feed\n", dev->name);
953 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
954 priv->tsfeed = NULL;
955 return ret;
956 }
957
958 dprintk("%s: start filtering\n", __FUNCTION__);
959 priv->tsfeed->start_filtering(priv->tsfeed);
960 } else
961 return -EINVAL;
962
963 return 0;
964}
965
966static int dvb_net_feed_stop(struct net_device *dev)
967{
968 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
969 int i;
970
971 dprintk("%s\n", __FUNCTION__);
972 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
973 if (priv->secfeed) {
974 if (priv->secfeed->is_filtering) {
975 dprintk("%s: stop secfeed\n", __FUNCTION__);
976 priv->secfeed->stop_filtering(priv->secfeed);
977 }
978
979 if (priv->secfilter) {
980 dprintk("%s: release secfilter\n", __FUNCTION__);
981 priv->secfeed->release_filter(priv->secfeed,
982 priv->secfilter);
983 priv->secfilter=NULL;
984 }
985
986 for (i=0; i<priv->multi_num; i++) {
987 if (priv->multi_secfilter[i]) {
988 dprintk("%s: release multi_filter[%d]\n",
989 __FUNCTION__, i);
990 priv->secfeed->release_filter(priv->secfeed,
991 priv->multi_secfilter[i]);
992 priv->multi_secfilter[i] = NULL;
993 }
994 }
995
996 priv->demux->release_section_feed(priv->demux, priv->secfeed);
997 priv->secfeed = NULL;
998 } else
999 printk("%s: no feed to stop\n", dev->name);
1000 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
1001 if (priv->tsfeed) {
1002 if (priv->tsfeed->is_filtering) {
1003 dprintk("%s: stop tsfeed\n", __FUNCTION__);
1004 priv->tsfeed->stop_filtering(priv->tsfeed);
1005 }
1006 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
1007 priv->tsfeed = NULL;
1008 }
1009 else
1010 printk("%s: no ts feed to stop\n", dev->name);
1011 } else
1012 return -EINVAL;
1013 return 0;
1014}
1015
1016
1017static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
1018{
1019 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1020
1021 if (priv->multi_num == DVB_NET_MULTICAST_MAX)
1022 return -ENOMEM;
1023
1024 memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
1025
1026 priv->multi_num++;
1027 return 0;
1028}
1029
1030
1031static void wq_set_multicast_list (void *data)
1032{
1033 struct net_device *dev = data;
1034 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1035
1036 dvb_net_feed_stop(dev);
1037
1038 priv->rx_mode = RX_MODE_UNI;
1039
1040 if (dev->flags & IFF_PROMISC) {
1041 dprintk("%s: promiscuous mode\n", dev->name);
1042 priv->rx_mode = RX_MODE_PROMISC;
1043 } else if ((dev->flags & IFF_ALLMULTI)) {
1044 dprintk("%s: allmulti mode\n", dev->name);
1045 priv->rx_mode = RX_MODE_ALL_MULTI;
1046 } else if (dev->mc_count) {
1047 int mci;
1048 struct dev_mc_list *mc;
1049
1050 dprintk("%s: set_mc_list, %d entries\n",
1051 dev->name, dev->mc_count);
1052
1053 priv->rx_mode = RX_MODE_MULTI;
1054 priv->multi_num = 0;
1055
1056 for (mci = 0, mc=dev->mc_list;
1057 mci < dev->mc_count;
1058 mc = mc->next, mci++) {
1059 dvb_set_mc_filter(dev, mc);
1060 }
1061 }
1062
1063 dvb_net_feed_start(dev);
1064}
1065
1066
1067static void dvb_net_set_multicast_list (struct net_device *dev)
1068{
1069 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1070 schedule_work(&priv->set_multicast_list_wq);
1071}
1072
1073
1074static void wq_restart_net_feed (void *data)
1075{
1076 struct net_device *dev = data;
1077
1078 if (netif_running(dev)) {
1079 dvb_net_feed_stop(dev);
1080 dvb_net_feed_start(dev);
1081 }
1082}
1083
1084
1085static int dvb_net_set_mac (struct net_device *dev, void *p)
1086{
1087 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1088 struct sockaddr *addr=p;
1089
1090 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1091
1092 if (netif_running(dev))
1093 schedule_work(&priv->restart_net_feed_wq);
1094
1095 return 0;
1096}
1097
1098
1099static int dvb_net_open(struct net_device *dev)
1100{
1101 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1102
1103 priv->in_use++;
1104 dvb_net_feed_start(dev);
1105 return 0;
1106}
1107
1108
1109static int dvb_net_stop(struct net_device *dev)
1110{
1111 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1112
1113 priv->in_use--;
1114 return dvb_net_feed_stop(dev);
1115}
1116
1117static struct net_device_stats * dvb_net_get_stats(struct net_device *dev)
1118{
1119 return &((struct dvb_net_priv*) dev->priv)->stats;
1120}
1121
1122static void dvb_net_setup(struct net_device *dev)
1123{
1124 ether_setup(dev);
1125
1126 dev->open = dvb_net_open;
1127 dev->stop = dvb_net_stop;
1128 dev->hard_start_xmit = dvb_net_tx;
1129 dev->get_stats = dvb_net_get_stats;
1130 dev->set_multicast_list = dvb_net_set_multicast_list;
1131 dev->set_mac_address = dvb_net_set_mac;
1132 dev->mtu = 4096;
1133 dev->mc_count = 0;
1134 dev->hard_header_cache = NULL;
1135 dev->flags |= IFF_NOARP;
1136}
1137
1138static int get_if(struct dvb_net *dvbnet)
1139{
1140 int i;
1141
1142 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1143 if (!dvbnet->state[i])
1144 break;
1145
1146 if (i == DVB_NET_DEVICES_MAX)
1147 return -1;
1148
1149 dvbnet->state[i]=1;
1150 return i;
1151}
1152
1153static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
1154{
1155 struct net_device *net;
1156 struct dvb_net_priv *priv;
1157 int result;
1158 int if_num;
1159
1160 if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE)
1161 return -EINVAL;
1162 if ((if_num = get_if(dvbnet)) < 0)
1163 return -EINVAL;
1164
1165 net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
1166 if (!net)
1167 return -ENOMEM;
1168
1169 if (dvbnet->dvbdev->id)
1170 snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
1171 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
1172 else
1173 /* compatibility fix to keep dvb0_0 format */
1174 snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
1175 dvbnet->dvbdev->adapter->num, if_num);
1176
1177 net->addr_len = 6;
1178 memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
1179
1180 dvbnet->device[if_num] = net;
1181
1182 priv = net->priv;
1183 priv->demux = dvbnet->demux;
1184 priv->pid = pid;
1185 priv->rx_mode = RX_MODE_UNI;
1186 priv->need_pusi = 1;
1187 priv->tscc = 0;
1188 priv->feedtype = feedtype;
1189 reset_ule(priv);
1190
1191 INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
1192 INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
1193
1194 net->base_addr = pid;
1195
1196 if ((result = register_netdev(net)) < 0) {
1197 dvbnet->device[if_num] = NULL;
1198 free_netdev(net);
1199 return result;
1200 }
1201 printk("dvb_net: created network interface %s\n", net->name);
1202
1203 return if_num;
1204}
1205
1206static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num)
1207{
1208 struct net_device *net = dvbnet->device[num];
1209 struct dvb_net_priv *priv;
1210
1211 if (!dvbnet->state[num])
1212 return -EINVAL;
1213 priv = net->priv;
1214 if (priv->in_use)
1215 return -EBUSY;
1216
1217 dvb_net_stop(net);
1218 flush_scheduled_work();
1219 printk("dvb_net: removed network interface %s\n", net->name);
1220 unregister_netdev(net);
1221 dvbnet->state[num]=0;
1222 dvbnet->device[num] = NULL;
1223 free_netdev(net);
1224
1225 return 0;
1226}
1227
1228static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
1229 unsigned int cmd, void *parg)
1230{
1231 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1232 struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv;
1233
1234 if (((file->f_flags&O_ACCMODE)==O_RDONLY))
1235 return -EPERM;
1236
1237 switch (cmd) {
1238 case NET_ADD_IF:
1239 {
1240 struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
1241 int result;
1242
1243 if (!capable(CAP_SYS_ADMIN))
1244 return -EPERM;
1245
1246 if (!try_module_get(dvbdev->adapter->module))
1247 return -EPERM;
1248
1249 result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype);
1250 if (result<0) {
1251 module_put(dvbdev->adapter->module);
1252 return result;
1253 }
1254 dvbnetif->if_num=result;
1255 break;
1256 }
1257 case NET_GET_IF:
1258 {
1259 struct net_device *netdev;
1260 struct dvb_net_priv *priv_data;
1261 struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
1262
1263 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1264 !dvbnet->state[dvbnetif->if_num])
1265 return -EINVAL;
1266
1267 netdev = dvbnet->device[dvbnetif->if_num];
1268
1269 priv_data=(struct dvb_net_priv*)netdev->priv;
1270 dvbnetif->pid=priv_data->pid;
1271 dvbnetif->feedtype=priv_data->feedtype;
1272 break;
1273 }
1274 case NET_REMOVE_IF:
1275 {
1276 int ret;
1277
1278 if (!capable(CAP_SYS_ADMIN))
1279 return -EPERM;
1280 if ((unsigned int) parg >= DVB_NET_DEVICES_MAX)
1281 return -EINVAL;
1282 ret = dvb_net_remove_if(dvbnet, (unsigned int) parg);
1283 if (!ret)
1284 module_put(dvbdev->adapter->module);
1285 return ret;
1286 }
1287
1288 /* binary compatiblity cruft */
1289 case __NET_ADD_IF_OLD:
1290 {
1291 struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
1292 int result;
1293
1294 if (!capable(CAP_SYS_ADMIN))
1295 return -EPERM;
1296
1297 if (!try_module_get(dvbdev->adapter->module))
1298 return -EPERM;
1299
1300 result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE);
1301 if (result<0) {
1302 module_put(dvbdev->adapter->module);
1303 return result;
1304 }
1305 dvbnetif->if_num=result;
1306 break;
1307 }
1308 case __NET_GET_IF_OLD:
1309 {
1310 struct net_device *netdev;
1311 struct dvb_net_priv *priv_data;
1312 struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
1313
1314 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1315 !dvbnet->state[dvbnetif->if_num])
1316 return -EINVAL;
1317
1318 netdev = dvbnet->device[dvbnetif->if_num];
1319
1320 priv_data=(struct dvb_net_priv*)netdev->priv;
1321 dvbnetif->pid=priv_data->pid;
1322 break;
1323 }
1324 default:
1325 return -ENOTTY;
1326 }
1327 return 0;
1328}
1329
1330static int dvb_net_ioctl(struct inode *inode, struct file *file,
1331 unsigned int cmd, unsigned long arg)
1332{
1333 return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
1334}
1335
1336static struct file_operations dvb_net_fops = {
1337 .owner = THIS_MODULE,
1338 .ioctl = dvb_net_ioctl,
1339 .open = dvb_generic_open,
1340 .release = dvb_generic_release,
1341};
1342
1343static struct dvb_device dvbdev_net = {
1344 .priv = NULL,
1345 .users = 1,
1346 .writers = 1,
1347 .fops = &dvb_net_fops,
1348};
1349
1350
1351void dvb_net_release (struct dvb_net *dvbnet)
1352{
1353 int i;
1354
1355 dvb_unregister_device(dvbnet->dvbdev);
1356
1357 for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
1358 if (!dvbnet->state[i])
1359 continue;
1360 dvb_net_remove_if(dvbnet, i);
1361 }
1362}
1363EXPORT_SYMBOL(dvb_net_release);
1364
1365
1366int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
1367 struct dmx_demux *dmx)
1368{
1369 int i;
1370
1371 dvbnet->demux = dmx;
1372
1373 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1374 dvbnet->state[i] = 0;
1375
1376 dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
1377 dvbnet, DVB_DEVICE_NET);
1378
1379 return 0;
1380}
1381EXPORT_SYMBOL(dvb_net_init);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
new file mode 100644
index 000000000000..f14e4ca38570
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.h
@@ -0,0 +1,46 @@
1/*
2 * dvb_net.h
3 *
4 * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _DVB_NET_H_
23#define _DVB_NET_H_
24
25#include <linux/module.h>
26#include <linux/netdevice.h>
27#include <linux/inetdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30
31#include "dvbdev.h"
32
33#define DVB_NET_DEVICES_MAX 10
34
35struct dvb_net {
36 struct dvb_device *dvbdev;
37 struct net_device *device[DVB_NET_DEVICES_MAX];
38 int state[DVB_NET_DEVICES_MAX];
39 struct dmx_demux *demux;
40};
41
42
43void dvb_net_release(struct dvb_net *);
44int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
45
46#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
new file mode 100644
index 000000000000..fb6d94a69d71
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -0,0 +1,270 @@
1/*
2 *
3 * dvb_ringbuffer.c: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler
10 * & Marcus Metzler for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27
28
29#define __KERNEL_SYSCALLS__
30#include <linux/errno.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/sched.h>
34#include <linux/string.h>
35#include <asm/uaccess.h>
36
37#include "dvb_ringbuffer.h"
38
39#define PKT_READY 0
40#define PKT_DISPOSED 1
41
42
43void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
44{
45 rbuf->pread=rbuf->pwrite=0;
46 rbuf->data=data;
47 rbuf->size=len;
48
49 init_waitqueue_head(&rbuf->queue);
50
51 spin_lock_init(&(rbuf->lock));
52}
53
54
55
56int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
57{
58 return (rbuf->pread==rbuf->pwrite);
59}
60
61
62
63ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
64{
65 ssize_t free;
66
67 free = rbuf->pread - rbuf->pwrite;
68 if (free <= 0)
69 free += rbuf->size;
70 return free-1;
71}
72
73
74
75ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
76{
77 ssize_t avail;
78
79 avail = rbuf->pwrite - rbuf->pread;
80 if (avail < 0)
81 avail += rbuf->size;
82 return avail;
83}
84
85
86
87void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
88{
89 rbuf->pread = rbuf->pwrite;
90}
91
92
93
94void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
95{
96 unsigned long flags;
97
98 spin_lock_irqsave(&rbuf->lock, flags);
99 dvb_ringbuffer_flush(rbuf);
100 spin_unlock_irqrestore(&rbuf->lock, flags);
101
102 wake_up(&rbuf->queue);
103}
104
105
106
107ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
108{
109 size_t todo = len;
110 size_t split;
111
112 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
113 if (split > 0) {
114 if (!usermem)
115 memcpy(buf, rbuf->data+rbuf->pread, split);
116 else
117 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
118 return -EFAULT;
119 buf += split;
120 todo -= split;
121 rbuf->pread = 0;
122 }
123 if (!usermem)
124 memcpy(buf, rbuf->data+rbuf->pread, todo);
125 else
126 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
127 return -EFAULT;
128
129 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
130
131 return len;
132}
133
134
135
136ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
137{
138 size_t todo = len;
139 size_t split;
140
141 split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
142
143 if (split > 0) {
144 memcpy(rbuf->data+rbuf->pwrite, buf, split);
145 buf += split;
146 todo -= split;
147 rbuf->pwrite = 0;
148 }
149 memcpy(rbuf->data+rbuf->pwrite, buf, todo);
150 rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
151
152 return len;
153}
154
155ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
156{
157 int status;
158 ssize_t oldpwrite = rbuf->pwrite;
159
160 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
161 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
162 DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
163 status = dvb_ringbuffer_write(rbuf, buf, len);
164
165 if (status < 0) rbuf->pwrite = oldpwrite;
166 return status;
167}
168
169ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
170 int offset, u8* buf, size_t len, int usermem)
171{
172 size_t todo;
173 size_t split;
174 size_t pktlen;
175
176 pktlen = rbuf->data[idx] << 8;
177 pktlen |= rbuf->data[(idx + 1) % rbuf->size];
178 if (offset > pktlen) return -EINVAL;
179 if ((offset + len) > pktlen) len = pktlen - offset;
180
181 idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
182 todo = len;
183 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
184 if (split > 0) {
185 if (!usermem)
186 memcpy(buf, rbuf->data+idx, split);
187 else
188 if (copy_to_user(buf, rbuf->data+idx, split))
189 return -EFAULT;
190 buf += split;
191 todo -= split;
192 idx = 0;
193 }
194 if (!usermem)
195 memcpy(buf, rbuf->data+idx, todo);
196 else
197 if (copy_to_user(buf, rbuf->data+idx, todo))
198 return -EFAULT;
199
200 return len;
201}
202
203void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
204{
205 size_t pktlen;
206
207 rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
208
209 // clean up disposed packets
210 while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
211 if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
212 pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
213 pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
214 DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
215 } else {
216 // first packet is not disposed, so we stop cleaning now
217 break;
218 }
219 }
220}
221
222ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
223{
224 int consumed;
225 int curpktlen;
226 int curpktstatus;
227
228 if (idx == -1) {
229 idx = rbuf->pread;
230 } else {
231 curpktlen = rbuf->data[idx] << 8;
232 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
233 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
234 }
235
236 consumed = (idx - rbuf->pread) % rbuf->size;
237
238 while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
239
240 curpktlen = rbuf->data[idx] << 8;
241 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
242 curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
243
244 if (curpktstatus == PKT_READY) {
245 *pktlen = curpktlen;
246 return idx;
247 }
248
249 consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
250 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
251 }
252
253 // no packets available
254 return -1;
255}
256
257
258
259EXPORT_SYMBOL(dvb_ringbuffer_init);
260EXPORT_SYMBOL(dvb_ringbuffer_empty);
261EXPORT_SYMBOL(dvb_ringbuffer_free);
262EXPORT_SYMBOL(dvb_ringbuffer_avail);
263EXPORT_SYMBOL(dvb_ringbuffer_flush);
264EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
265EXPORT_SYMBOL(dvb_ringbuffer_read);
266EXPORT_SYMBOL(dvb_ringbuffer_write);
267EXPORT_SYMBOL(dvb_ringbuffer_pkt_write);
268EXPORT_SYMBOL(dvb_ringbuffer_pkt_read);
269EXPORT_SYMBOL(dvb_ringbuffer_pkt_dispose);
270EXPORT_SYMBOL(dvb_ringbuffer_pkt_next);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
new file mode 100644
index 000000000000..d18e9c4ba9ea
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -0,0 +1,173 @@
1/*
2 *
3 * dvb_ringbuffer.h: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
10 * for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27#ifndef _DVB_RINGBUFFER_H_
28#define _DVB_RINGBUFFER_H_
29
30#include <linux/spinlock.h>
31#include <linux/wait.h>
32
33struct dvb_ringbuffer {
34 u8 *data;
35 ssize_t size;
36 ssize_t pread;
37 ssize_t pwrite;
38
39 wait_queue_head_t queue;
40 spinlock_t lock;
41};
42
43#define DVB_RINGBUFFER_PKTHDRSIZE 3
44
45
46/*
47** Notes:
48** ------
49** (1) For performance reasons read and write routines don't check buffer sizes
50** and/or number of bytes free/available. This has to be done before these
51** routines are called. For example:
52**
53** *** write <buflen> bytes ***
54** free = dvb_ringbuffer_free(rbuf);
55** if (free >= buflen)
56** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
57** else
58** ...
59**
60** *** read min. 1000, max. <bufsize> bytes ***
61** avail = dvb_ringbuffer_avail(rbuf);
62** if (avail >= 1000)
63** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0);
64** else
65** ...
66**
67** (2) If there is exactly one reader and one writer, there is no need
68** to lock read or write operations.
69** Two or more readers must be locked against each other.
70** Flushing the buffer counts as a read operation.
71** Two or more writers must be locked against each other.
72*/
73
74/* initialize ring buffer, lock and queue */
75extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
76
77/* test whether buffer is empty */
78extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
79
80/* return the number of free bytes in the buffer */
81extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
82
83/* return the number of bytes waiting in the buffer */
84extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
85
86
87/* read routines & macros */
88/* ---------------------- */
89/* flush buffer */
90extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
91
92/* flush buffer protected by spinlock and wake-up waiting task(s) */
93extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
94
95/* peek at byte <offs> in the buffer */
96#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
97 (rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
98
99/* advance read ptr by <num> bytes */
100#define DVB_RINGBUFFER_SKIP(rbuf,num) \
101 (rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
102
103/*
104** read <len> bytes from ring buffer into <buf>
105** <usermem> specifies whether <buf> resides in user space
106** returns number of bytes transferred or -EFAULT
107*/
108extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
109 size_t len, int usermem);
110
111
112/* write routines & macros */
113/* ----------------------- */
114/* write single byte to ring buffer */
115#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte) \
116 { (rbuf)->data[(rbuf)->pwrite]=(byte); \
117 (rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
118/*
119** write <len> bytes to ring buffer
120** <usermem> specifies whether <buf> resides in user space
121** returns number of bytes transferred or -EFAULT
122*/
123extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
124 size_t len);
125
126
127/**
128 * Write a packet into the ringbuffer.
129 *
130 * <rbuf> Ringbuffer to write to.
131 * <buf> Buffer to write.
132 * <len> Length of buffer (currently limited to 65535 bytes max).
133 * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
134 */
135extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
136 size_t len);
137
138/**
139 * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
140 * does NOT update the read pointer in the ringbuffer. You must use
141 * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
142 *
143 * <rbuf> Ringbuffer concerned.
144 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
145 * <offset> Offset into packet to read from.
146 * <buf> Destination buffer for data.
147 * <len> Size of destination buffer.
148 * <usermem> Set to 1 if <buf> is in userspace.
149 * returns Number of bytes read, or -EFAULT.
150 */
151extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
152 int offset, u8* buf, size_t len, int usermem);
153
154/**
155 * Dispose of a packet in the ring buffer.
156 *
157 * <rbuf> Ring buffer concerned.
158 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
159 */
160extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
161
162/**
163 * Get the index of the next packet in a ringbuffer.
164 *
165 * <rbuf> Ringbuffer concerned.
166 * <idx> Previous packet index, or -1 to return the first packet index.
167 * <pktlen> On success, will be updated to contain the length of the packet in bytes.
168 * returns Packet index (if >=0), or -1 if no packets available.
169 */
170extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);
171
172
173#endif /* _DVB_RINGBUFFER_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
new file mode 100644
index 000000000000..cf4ffe38fda3
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -0,0 +1,449 @@
1/*
2 * dvbdev.c
3 *
4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/types.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/device.h>
34#include <linux/fs.h>
35#include <linux/cdev.h>
36
37#include "dvbdev.h"
38
39static int dvbdev_debug;
40
41module_param(dvbdev_debug, int, 0644);
42MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
43
44#define dprintk if (dvbdev_debug) printk
45
46static LIST_HEAD(dvb_adapter_list);
47static DECLARE_MUTEX(dvbdev_register_lock);
48
49static const char * const dnames[] = {
50 "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
51 "net", "osd"
52};
53
54#define DVB_MAX_ADAPTERS 8
55#define DVB_MAX_IDS 4
56#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
57#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
58
59struct class_simple *dvb_class;
60EXPORT_SYMBOL(dvb_class);
61
62static struct dvb_device* dvbdev_find_device (int minor)
63{
64 struct list_head *entry;
65
66 list_for_each (entry, &dvb_adapter_list) {
67 struct list_head *entry0;
68 struct dvb_adapter *adap;
69 adap = list_entry (entry, struct dvb_adapter, list_head);
70 list_for_each (entry0, &adap->device_list) {
71 struct dvb_device *dev;
72 dev = list_entry (entry0, struct dvb_device, list_head);
73 if (nums2minor(adap->num, dev->type, dev->id) == minor)
74 return dev;
75 }
76 }
77
78 return NULL;
79}
80
81
82static int dvb_device_open(struct inode *inode, struct file *file)
83{
84 struct dvb_device *dvbdev;
85
86 dvbdev = dvbdev_find_device (iminor(inode));
87
88 if (dvbdev && dvbdev->fops) {
89 int err = 0;
90 struct file_operations *old_fops;
91
92 file->private_data = dvbdev;
93 old_fops = file->f_op;
94 file->f_op = fops_get(dvbdev->fops);
95 if(file->f_op->open)
96 err = file->f_op->open(inode,file);
97 if (err) {
98 fops_put(file->f_op);
99 file->f_op = fops_get(old_fops);
100 }
101 fops_put(old_fops);
102 return err;
103 }
104 return -ENODEV;
105}
106
107
108static struct file_operations dvb_device_fops =
109{
110 .owner = THIS_MODULE,
111 .open = dvb_device_open,
112};
113
114static struct cdev dvb_device_cdev = {
115 .kobj = {.name = "dvb", },
116 .owner = THIS_MODULE,
117};
118
119int dvb_generic_open(struct inode *inode, struct file *file)
120{
121 struct dvb_device *dvbdev = file->private_data;
122
123 if (!dvbdev)
124 return -ENODEV;
125
126 if (!dvbdev->users)
127 return -EBUSY;
128
129 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
130 if (!dvbdev->readers)
131 return -EBUSY;
132 dvbdev->readers--;
133 } else {
134 if (!dvbdev->writers)
135 return -EBUSY;
136 dvbdev->writers--;
137 }
138
139 dvbdev->users--;
140 return 0;
141}
142EXPORT_SYMBOL(dvb_generic_open);
143
144
145int dvb_generic_release(struct inode *inode, struct file *file)
146{
147 struct dvb_device *dvbdev = file->private_data;
148
149 if (!dvbdev)
150 return -ENODEV;
151
152 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
153 dvbdev->readers++;
154 } else {
155 dvbdev->writers++;
156 }
157
158 dvbdev->users++;
159 return 0;
160}
161EXPORT_SYMBOL(dvb_generic_release);
162
163
164int dvb_generic_ioctl(struct inode *inode, struct file *file,
165 unsigned int cmd, unsigned long arg)
166{
167 struct dvb_device *dvbdev = file->private_data;
168
169 if (!dvbdev)
170 return -ENODEV;
171
172 if (!dvbdev->kernel_ioctl)
173 return -EINVAL;
174
175 return dvb_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl);
176}
177EXPORT_SYMBOL(dvb_generic_ioctl);
178
179
180static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
181{
182 u32 id = 0;
183
184 while (id < DVB_MAX_IDS) {
185 struct list_head *entry;
186 list_for_each (entry, &adap->device_list) {
187 struct dvb_device *dev;
188 dev = list_entry (entry, struct dvb_device, list_head);
189 if (dev->type == type && dev->id == id)
190 goto skip;
191 }
192 return id;
193skip:
194 id++;
195 }
196 return -ENFILE;
197}
198
199
200int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
201 const struct dvb_device *template, void *priv, int type)
202{
203 struct dvb_device *dvbdev;
204 int id;
205
206 if (down_interruptible (&dvbdev_register_lock))
207 return -ERESTARTSYS;
208
209 if ((id = dvbdev_get_free_id (adap, type)) < 0) {
210 up (&dvbdev_register_lock);
211 *pdvbdev = NULL;
212 printk ("%s: could get find free device id...\n", __FUNCTION__);
213 return -ENFILE;
214 }
215
216 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
217
218 if (!dvbdev) {
219 up(&dvbdev_register_lock);
220 return -ENOMEM;
221 }
222
223 up (&dvbdev_register_lock);
224
225 memcpy(dvbdev, template, sizeof(struct dvb_device));
226 dvbdev->type = type;
227 dvbdev->id = id;
228 dvbdev->adapter = adap;
229 dvbdev->priv = priv;
230
231 dvbdev->fops->owner = adap->module;
232
233 list_add_tail (&dvbdev->list_head, &adap->device_list);
234
235 devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
236 S_IFCHR | S_IRUSR | S_IWUSR,
237 "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
238
239 class_simple_device_add(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
240 NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
241
242 dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
243 adap->num, dnames[type], id, nums2minor(adap->num, type, id),
244 nums2minor(adap->num, type, id));
245
246 return 0;
247}
248EXPORT_SYMBOL(dvb_register_device);
249
250
251void dvb_unregister_device(struct dvb_device *dvbdev)
252{
253 if (!dvbdev)
254 return;
255
256 devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
257 dnames[dvbdev->type], dvbdev->id);
258
259 class_simple_device_remove(MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
260 dvbdev->type, dvbdev->id)));
261
262 list_del (&dvbdev->list_head);
263 kfree (dvbdev);
264}
265EXPORT_SYMBOL(dvb_unregister_device);
266
267
268static int dvbdev_get_free_adapter_num (void)
269{
270 int num = 0;
271
272 while (num < DVB_MAX_ADAPTERS) {
273 struct list_head *entry;
274 list_for_each (entry, &dvb_adapter_list) {
275 struct dvb_adapter *adap;
276 adap = list_entry (entry, struct dvb_adapter, list_head);
277 if (adap->num == num)
278 goto skip;
279 }
280 return num;
281skip:
282 num++;
283 }
284
285 return -ENFILE;
286}
287
288
289int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module)
290{
291 struct dvb_adapter *adap;
292 int num;
293
294 if (down_interruptible (&dvbdev_register_lock))
295 return -ERESTARTSYS;
296
297 if ((num = dvbdev_get_free_adapter_num ()) < 0) {
298 up (&dvbdev_register_lock);
299 return -ENFILE;
300 }
301
302 if (!(*padap = adap = kmalloc(sizeof(struct dvb_adapter), GFP_KERNEL))) {
303 up(&dvbdev_register_lock);
304 return -ENOMEM;
305 }
306
307 memset (adap, 0, sizeof(struct dvb_adapter));
308 INIT_LIST_HEAD (&adap->device_list);
309
310 printk ("DVB: registering new adapter (%s).\n", name);
311
312 devfs_mk_dir("dvb/adapter%d", num);
313 adap->num = num;
314 adap->name = name;
315 adap->module = module;
316
317 list_add_tail (&adap->list_head, &dvb_adapter_list);
318
319 up (&dvbdev_register_lock);
320
321 return num;
322}
323EXPORT_SYMBOL(dvb_register_adapter);
324
325
326int dvb_unregister_adapter(struct dvb_adapter *adap)
327{
328 devfs_remove("dvb/adapter%d", adap->num);
329
330 if (down_interruptible (&dvbdev_register_lock))
331 return -ERESTARTSYS;
332 list_del (&adap->list_head);
333 up (&dvbdev_register_lock);
334 kfree (adap);
335 return 0;
336}
337EXPORT_SYMBOL(dvb_unregister_adapter);
338
339/* if the miracle happens and "generic_usercopy()" is included into
340 the kernel, then this can vanish. please don't make the mistake and
341 define this as video_usercopy(). this will introduce a dependecy
342 to the v4l "videodev.o" module, which is unnecessary for some
343 cards (ie. the budget dvb-cards don't need the v4l module...) */
344int dvb_usercopy(struct inode *inode, struct file *file,
345 unsigned int cmd, unsigned long arg,
346 int (*func)(struct inode *inode, struct file *file,
347 unsigned int cmd, void *arg))
348{
349 char sbuf[128];
350 void *mbuf = NULL;
351 void *parg = NULL;
352 int err = -EINVAL;
353
354 /* Copy arguments into temp kernel buffer */
355 switch (_IOC_DIR(cmd)) {
356 case _IOC_NONE:
357 /*
358 * For this command, the pointer is actually an integer
359 * argument.
360 */
361 parg = (void *) arg;
362 break;
363 case _IOC_READ: /* some v4l ioctls are marked wrong ... */
364 case _IOC_WRITE:
365 case (_IOC_WRITE | _IOC_READ):
366 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
367 parg = sbuf;
368 } else {
369 /* too big to allocate from stack */
370 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
371 if (NULL == mbuf)
372 return -ENOMEM;
373 parg = mbuf;
374 }
375
376 err = -EFAULT;
377 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
378 goto out;
379 break;
380 }
381
382 /* call driver */
383 if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
384 err = -EINVAL;
385
386 if (err < 0)
387 goto out;
388
389 /* Copy results into user buffer */
390 switch (_IOC_DIR(cmd))
391 {
392 case _IOC_READ:
393 case (_IOC_WRITE | _IOC_READ):
394 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
395 err = -EFAULT;
396 break;
397 }
398
399out:
400 kfree(mbuf);
401 return err;
402}
403
404static int __init init_dvbdev(void)
405{
406 int retval;
407 dev_t dev = MKDEV(DVB_MAJOR, 0);
408
409 if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
410 printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
411 return retval;
412 }
413
414 cdev_init(&dvb_device_cdev, &dvb_device_fops);
415 if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
416 printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
417 goto error;
418 }
419
420 devfs_mk_dir("dvb");
421
422 dvb_class = class_simple_create(THIS_MODULE, "dvb");
423 if (IS_ERR(dvb_class)) {
424 retval = PTR_ERR(dvb_class);
425 goto error;
426 }
427 return 0;
428
429error:
430 cdev_del(&dvb_device_cdev);
431 unregister_chrdev_region(dev, MAX_DVB_MINORS);
432 return retval;
433}
434
435
436static void __exit exit_dvbdev(void)
437{
438 devfs_remove("dvb");
439 class_simple_destroy(dvb_class);
440 cdev_del(&dvb_device_cdev);
441 unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
442}
443
444module_init(init_dvbdev);
445module_exit(exit_dvbdev);
446
447MODULE_DESCRIPTION("DVB Core Driver");
448MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
449MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
new file mode 100644
index 000000000000..184edba3caa7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -0,0 +1,104 @@
1/*
2 * dvbdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Lesser Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (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 Lesser 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#ifndef _DVBDEV_H_
24#define _DVBDEV_H_
25
26#include <linux/types.h>
27#include <linux/poll.h>
28#include <linux/fs.h>
29#include <linux/list.h>
30#include <linux/devfs_fs_kernel.h>
31#include <linux/smp_lock.h>
32
33#define DVB_MAJOR 212
34
35#define DVB_DEVICE_VIDEO 0
36#define DVB_DEVICE_AUDIO 1
37#define DVB_DEVICE_SEC 2
38#define DVB_DEVICE_FRONTEND 3
39#define DVB_DEVICE_DEMUX 4
40#define DVB_DEVICE_DVR 5
41#define DVB_DEVICE_CA 6
42#define DVB_DEVICE_NET 7
43#define DVB_DEVICE_OSD 8
44
45
46struct dvb_adapter {
47 int num;
48 struct list_head list_head;
49 struct list_head device_list;
50 const char *name;
51 u8 proposed_mac [6];
52 void* priv;
53
54 struct module *module;
55};
56
57
58struct dvb_device {
59 struct list_head list_head;
60 struct file_operations *fops;
61 struct dvb_adapter *adapter;
62 int type;
63 u32 id;
64
65 /* in theory, 'users' can vanish now,
66 but I don't want to change too much now... */
67 int readers;
68 int writers;
69 int users;
70
71 /* don't really need those !? -- FIXME: use video_usercopy */
72 int (*kernel_ioctl)(struct inode *inode, struct file *file,
73 unsigned int cmd, void *arg);
74
75 void *priv;
76};
77
78
79extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module);
80extern int dvb_unregister_adapter (struct dvb_adapter *adap);
81
82extern int dvb_register_device (struct dvb_adapter *adap,
83 struct dvb_device **pdvbdev,
84 const struct dvb_device *template,
85 void *priv,
86 int type);
87
88extern void dvb_unregister_device (struct dvb_device *dvbdev);
89
90extern int dvb_generic_open (struct inode *inode, struct file *file);
91extern int dvb_generic_release (struct inode *inode, struct file *file);
92extern int dvb_generic_ioctl (struct inode *inode, struct file *file,
93 unsigned int cmd, unsigned long arg);
94
95/* we don't mess with video_usercopy() any more,
96we simply define out own dvb_usercopy(), which will hopefully become
97generic_usercopy() someday... */
98
99extern int dvb_usercopy(struct inode *inode, struct file *file,
100 unsigned int cmd, unsigned long arg,
101 int (*func)(struct inode *inode, struct file *file,
102 unsigned int cmd, void *arg));
103
104#endif /* #ifndef _DVBDEV_H_ */
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
new file mode 100644
index 000000000000..0bfd4df17d08
--- /dev/null
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -0,0 +1,172 @@
1menu "Customise DVB Frontends"
2 depends on DVB_CORE
3
4comment "DVB-S (satellite) frontends"
5 depends on DVB_CORE
6
7config DVB_STV0299
8 tristate "ST STV0299 based"
9 depends on DVB_CORE
10 help
11 A DVB-S tuner module. Say Y when you want to support this frontend.
12
13config DVB_CX24110
14 tristate "Conexant CX24110 based"
15 depends on DVB_CORE
16 help
17 A DVB-S tuner module. Say Y when you want to support this frontend.
18
19config DVB_TDA8083
20 tristate "Philips TDA8083 based"
21 depends on DVB_CORE
22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend.
24
25config DVB_TDA80XX
26 tristate "Philips TDA8044 or TDA8083 based"
27 depends on DVB_CORE
28 help
29 A DVB-S tuner module. Say Y when you want to support this frontend.
30
31config DVB_MT312
32 tristate "Zarlink MT312 based"
33 depends on DVB_CORE
34 help
35 A DVB-S tuner module. Say Y when you want to support this frontend.
36
37config DVB_VES1X93
38 tristate "VLSI VES1893 or VES1993 based"
39 depends on DVB_CORE
40 help
41 A DVB-S tuner module. Say Y when you want to support this frontend.
42
43comment "DVB-T (terrestrial) frontends"
44 depends on DVB_CORE
45
46config DVB_SP8870
47 tristate "Spase sp8870 based"
48 depends on DVB_CORE
49 select FW_LOADER
50 help
51 A DVB-T tuner module. Say Y when you want to support this frontend.
52
53 This driver needs external firmware. Please use the command
54 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
55 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
56
57config DVB_SP887X
58 tristate "Spase sp887x based"
59 depends on DVB_CORE
60 select FW_LOADER
61 help
62 A DVB-T tuner module. Say Y when you want to support this frontend.
63
64 This driver needs external firmware. Please use the command
65 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
66 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
67
68config DVB_CX22700
69 tristate "Conexant CX22700 based"
70 depends on DVB_CORE
71 help
72 A DVB-T tuner module. Say Y when you want to support this frontend.
73
74config DVB_CX22702
75 tristate "Conexant cx22702 demodulator (OFDM)"
76 depends on DVB_CORE
77 help
78 A DVB-T tuner module. Say Y when you want to support this frontend.
79
80config DVB_L64781
81 tristate "LSI L64781"
82 depends on DVB_CORE
83 help
84 A DVB-T tuner module. Say Y when you want to support this frontend.
85
86config DVB_TDA1004X
87 tristate "Philips TDA10045H/TDA10046H based"
88 depends on DVB_CORE
89 select FW_LOADER
90 help
91 A DVB-T tuner module. Say Y when you want to support this frontend.
92
93 This driver needs external firmware. Please use the commands
94 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
95 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
96 download/extract them, and then copy them to /usr/lib/hotplug/firmware.
97
98config DVB_NXT6000
99 tristate "NxtWave Communications NXT6000 based"
100 depends on DVB_CORE
101 help
102 A DVB-T tuner module. Say Y when you want to support this frontend.
103
104config DVB_MT352
105 tristate "Zarlink MT352 based"
106 depends on DVB_CORE
107 help
108 A DVB-T tuner module. Say Y when you want to support this frontend.
109
110config DVB_DIB3000MB
111 tristate "DiBcom 3000M-B"
112 depends on DVB_CORE
113 help
114 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
115 to support this frontend.
116
117config DVB_DIB3000MC
118 tristate "DiBcom 3000P/M-C"
119 depends on DVB_CORE
120 help
121 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
122 to support this frontend.
123
124comment "DVB-C (cable) frontends"
125 depends on DVB_CORE
126
127config DVB_ATMEL_AT76C651
128 tristate "Atmel AT76C651 based"
129 depends on DVB_CORE
130 help
131 A DVB-C tuner module. Say Y when you want to support this frontend.
132
133config DVB_VES1820
134 tristate "VLSI VES1820 based"
135 depends on DVB_CORE
136 help
137 A DVB-C tuner module. Say Y when you want to support this frontend.
138
139config DVB_TDA10021
140 tristate "Philips TDA10021 based"
141 depends on DVB_CORE
142 help
143 A DVB-C tuner module. Say Y when you want to support this frontend.
144
145config DVB_STV0297
146 tristate "ST STV0297 based"
147 depends on DVB_CORE
148 help
149 A DVB-C tuner module. Say Y when you want to support this frontend.
150
151comment "ATSC (North American/Korean Terresterial DTV) frontends"
152 depends on DVB_CORE
153
154config DVB_NXT2002
155 tristate "Nxt2002 based"
156 depends on DVB_CORE
157 select FW_LOADER
158 help
159 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
160
161config DVB_OR51132
162 tristate "OR51132 based (pcHDTV)"
163 depends on DVB_CORE
164
165config DVB_OR51211
166 tristate "or51211 based (pcHDTV HD2000 card)"
167 depends on DVB_CORE
168 select FW_LOADER
169 help
170 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
171
172endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
new file mode 100644
index 000000000000..7f8784870eab
--- /dev/null
+++ b/drivers/media/dvb/frontends/Makefile
@@ -0,0 +1,30 @@
1#
2# Makefile for the kernel DVB frontend device drivers.
3#
4
5EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
6
7obj-$(CONFIG_DVB_CORE) += dvb-pll.o
8obj-$(CONFIG_DVB_STV0299) += stv0299.o
9obj-$(CONFIG_DVB_SP8870) += sp8870.o
10obj-$(CONFIG_DVB_CX22700) += cx22700.o
11obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
12obj-$(CONFIG_DVB_CX24110) += cx24110.o
13obj-$(CONFIG_DVB_TDA8083) += tda8083.o
14obj-$(CONFIG_DVB_L64781) += l64781.o
15obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o
16obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o
17obj-$(CONFIG_DVB_MT312) += mt312.o
18obj-$(CONFIG_DVB_VES1820) += ves1820.o
19obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
20obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
21obj-$(CONFIG_DVB_SP887X) += sp887x.o
22obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
23obj-$(CONFIG_DVB_MT352) += mt352.o
24obj-$(CONFIG_DVB_CX22702) += cx22702.o
25obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
new file mode 100644
index 000000000000..ce2eaa1640e8
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.c
@@ -0,0 +1,450 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.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 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kernel.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35#include <linux/bitops.h>
36#include "dvb_frontend.h"
37#include "at76c651.h"
38
39
40struct at76c651_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct at76c651_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* revision of the chip */
51 u8 revision;
52
53 /* last QAM value set */
54 u8 qam;
55};
56
57static int debug;
58#define dprintk(args...) \
59 do { \
60 if (debug) printk(KERN_DEBUG "at76c651: " args); \
61 } while (0)
62
63
64#if ! defined(__powerpc__)
65static __inline__ int __ilog2(unsigned long x)
66{
67 int i;
68
69 if (x == 0)
70 return -1;
71
72 for (i = 0; x != 0; i++)
73 x >>= 1;
74
75 return i - 1;
76}
77#endif
78
79static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf[] = { reg, data };
83 struct i2c_msg msg =
84 { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
85
86 ret = i2c_transfer(state->i2c, &msg, 1);
87
88 if (ret != 1)
89 dprintk("%s: writereg error "
90 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
91 __FUNCTION__, reg, data, ret);
92
93 msleep(10);
94
95 return (ret != 1) ? -EREMOTEIO : 0;
96}
97
98static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
99{
100 int ret;
101 u8 val;
102 struct i2c_msg msg[] = {
103 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
104 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
105 };
106
107 ret = i2c_transfer(state->i2c, msg, 2);
108
109 if (ret != 2)
110 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
111
112 return val;
113}
114
115static int at76c651_reset(struct at76c651_state* state)
116{
117 return at76c651_writereg(state, 0x07, 0x01);
118}
119
120static void at76c651_disable_interrupts(struct at76c651_state* state)
121{
122 at76c651_writereg(state, 0x0b, 0x00);
123}
124
125static int at76c651_set_auto_config(struct at76c651_state *state)
126{
127 /*
128 * Autoconfig
129 */
130
131 at76c651_writereg(state, 0x06, 0x01);
132
133 /*
134 * Performance optimizations, should be done after autoconfig
135 */
136
137 at76c651_writereg(state, 0x10, 0x06);
138 at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
139 at76c651_writereg(state, 0x15, 0x28);
140 at76c651_writereg(state, 0x20, 0x09);
141 at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
142 at76c651_writereg(state, 0x30, 0x90);
143 if (state->qam == 5)
144 at76c651_writereg(state, 0x35, 0x2A);
145
146 /*
147 * Initialize A/D-converter
148 */
149
150 if (state->revision == 0x11) {
151 at76c651_writereg(state, 0x2E, 0x38);
152 at76c651_writereg(state, 0x2F, 0x13);
153 }
154
155 at76c651_disable_interrupts(state);
156
157 /*
158 * Restart operation
159 */
160
161 at76c651_reset(state);
162
163 return 0;
164}
165
166static void at76c651_set_bbfreq(struct at76c651_state* state)
167{
168 at76c651_writereg(state, 0x04, 0x3f);
169 at76c651_writereg(state, 0x05, 0xee);
170}
171
172static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
173{
174 u8 exponent;
175 u32 mantissa;
176
177 if (symbol_rate > 9360000)
178 return -EINVAL;
179
180 /*
181 * FREF = 57800 kHz
182 * exponent = 10 + floor (log2(symbol_rate / FREF))
183 * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
184 */
185
186 exponent = __ilog2((symbol_rate << 4) / 903125);
187 mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
188
189 at76c651_writereg(state, 0x00, mantissa >> 13);
190 at76c651_writereg(state, 0x01, mantissa >> 5);
191 at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
192
193 return 0;
194}
195
196static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
197{
198 switch (qam) {
199 case QPSK:
200 state->qam = 0x02;
201 break;
202 case QAM_16:
203 state->qam = 0x04;
204 break;
205 case QAM_32:
206 state->qam = 0x05;
207 break;
208 case QAM_64:
209 state->qam = 0x06;
210 break;
211 case QAM_128:
212 state->qam = 0x07;
213 break;
214 case QAM_256:
215 state->qam = 0x08;
216 break;
217#if 0
218 case QAM_512:
219 state->qam = 0x09;
220 break;
221 case QAM_1024:
222 state->qam = 0x0A;
223 break;
224#endif
225 default:
226 return -EINVAL;
227
228 }
229
230 return at76c651_writereg(state, 0x03, state->qam);
231}
232
233static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
234{
235 u8 feciqinv = at76c651_readreg(state, 0x60);
236
237 switch (inversion) {
238 case INVERSION_OFF:
239 feciqinv |= 0x02;
240 feciqinv &= 0xFE;
241 break;
242
243 case INVERSION_ON:
244 feciqinv |= 0x03;
245 break;
246
247 case INVERSION_AUTO:
248 feciqinv &= 0xFC;
249 break;
250
251 default:
252 return -EINVAL;
253 }
254
255 return at76c651_writereg(state, 0x60, feciqinv);
256}
257
258static int at76c651_set_parameters(struct dvb_frontend* fe,
259 struct dvb_frontend_parameters *p)
260{
261 int ret;
262 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
263
264 at76c651_writereg(state, 0x0c, 0xc3);
265 state->config->pll_set(fe, p);
266 at76c651_writereg(state, 0x0c, 0xc2);
267
268 if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
269 return ret;
270
271 if ((ret = at76c651_set_inversion(state, p->inversion)))
272 return ret;
273
274 return at76c651_set_auto_config(state);
275}
276
277static int at76c651_set_defaults(struct dvb_frontend* fe)
278{
279 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
280
281 at76c651_set_symbol_rate(state, 6900000);
282 at76c651_set_qam(state, QAM_64);
283 at76c651_set_bbfreq(state);
284 at76c651_set_auto_config(state);
285
286 if (state->config->pll_init) {
287 at76c651_writereg(state, 0x0c, 0xc3);
288 state->config->pll_init(fe);
289 at76c651_writereg(state, 0x0c, 0xc2);
290 }
291
292 return 0;
293}
294
295static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
296{
297 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
298 u8 sync;
299
300 /*
301 * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
302 */
303 sync = at76c651_readreg(state, 0x80);
304 *status = 0;
305
306 if (sync & (0x04 | 0x10)) /* AGC1 || TIM */
307 *status |= FE_HAS_SIGNAL;
308 if (sync & 0x10) /* TIM */
309 *status |= FE_HAS_CARRIER;
310 if (sync & 0x80) /* FEC */
311 *status |= FE_HAS_VITERBI;
312 if (sync & 0x40) /* CAR */
313 *status |= FE_HAS_SYNC;
314 if ((sync & 0xF0) == 0xF0) /* TIM && EQU && CAR && FEC */
315 *status |= FE_HAS_LOCK;
316
317 return 0;
318}
319
320static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
321{
322 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
323
324 *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
325 *ber |= at76c651_readreg(state, 0x82) << 8;
326 *ber |= at76c651_readreg(state, 0x83);
327 *ber *= 10;
328
329 return 0;
330}
331
332static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
333{
334 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
335
336 u8 gain = ~at76c651_readreg(state, 0x91);
337 *strength = (gain << 8) | gain;
338
339 return 0;
340}
341
342static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
343{
344 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
345
346 *snr = 0xFFFF -
347 ((at76c651_readreg(state, 0x8F) << 8) |
348 at76c651_readreg(state, 0x90));
349
350 return 0;
351}
352
353static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
354{
355 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
356
357 *ucblocks = at76c651_readreg(state, 0x82);
358
359 return 0;
360}
361
362static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 50;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370static void at76c651_release(struct dvb_frontend* fe)
371{
372 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
373 kfree(state);
374}
375
376static struct dvb_frontend_ops at76c651_ops;
377
378struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
379 struct i2c_adapter* i2c)
380{
381 struct at76c651_state* state = NULL;
382
383 /* allocate memory for the internal state */
384 state = (struct at76c651_state*) kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
385 if (state == NULL) goto error;
386
387 /* setup the state */
388 state->config = config;
389 state->qam = 0;
390
391 /* check if the demod is there */
392 if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
393
394 /* finalise state setup */
395 state->i2c = i2c;
396 state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
397 memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
398
399 /* create dvb_frontend */
400 state->frontend.ops = &state->ops;
401 state->frontend.demodulator_priv = state;
402 return &state->frontend;
403
404error:
405 kfree(state);
406 return NULL;
407}
408
409static struct dvb_frontend_ops at76c651_ops = {
410
411 .info = {
412 .name = "Atmel AT76C651B DVB-C",
413 .type = FE_QAM,
414 .frequency_min = 48250000,
415 .frequency_max = 863250000,
416 .frequency_stepsize = 62500,
417 /*.frequency_tolerance = */ /* FIXME: 12% of SR */
418 .symbol_rate_min = 0, /* FIXME */
419 .symbol_rate_max = 9360000, /* FIXME */
420 .symbol_rate_tolerance = 4000,
421 .caps = FE_CAN_INVERSION_AUTO |
422 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
423 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
424 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
425 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
426 FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
427 },
428
429 .release = at76c651_release,
430
431 .init = at76c651_set_defaults,
432
433 .set_frontend = at76c651_set_parameters,
434 .get_tune_settings = at76c651_get_tune_settings,
435
436 .read_status = at76c651_read_status,
437 .read_ber = at76c651_read_ber,
438 .read_signal_strength = at76c651_read_signal_strength,
439 .read_snr = at76c651_read_snr,
440 .read_ucblocks = at76c651_read_ucblocks,
441};
442
443module_param(debug, int, 0644);
444MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
445
446MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
447MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
new file mode 100644
index 000000000000..34054df93608
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.h
@@ -0,0 +1,47 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.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 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#ifndef AT76C651_H
30#define AT76C651_H
31
32#include <linux/dvb/frontend.h>
33
34struct at76c651_config
35{
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* PLL maintenance */
40 int (*pll_init)(struct dvb_frontend* fe);
41 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
42};
43
44extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // AT76C651_H
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
new file mode 100644
index 000000000000..a212279042b8
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -0,0 +1,435 @@
1/*
2 Conexant cx22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
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/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "cx22700.h"
31
32
33struct cx22700_state {
34
35 struct i2c_adapter* i2c;
36
37 struct dvb_frontend_ops ops;
38
39 const struct cx22700_config* config;
40
41 struct dvb_frontend frontend;
42};
43
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "cx22700: " args); \
49 } while (0)
50
51static u8 init_tab [] = {
52 0x04, 0x10,
53 0x05, 0x09,
54 0x06, 0x00,
55 0x08, 0x04,
56 0x09, 0x00,
57 0x0a, 0x01,
58 0x15, 0x40,
59 0x16, 0x10,
60 0x17, 0x87,
61 0x18, 0x17,
62 0x1a, 0x10,
63 0x25, 0x04,
64 0x2e, 0x00,
65 0x39, 0x00,
66 0x3a, 0x04,
67 0x45, 0x08,
68 0x46, 0x02,
69 0x47, 0x05,
70};
71
72
73static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
74{
75 int ret;
76 u8 buf [] = { reg, data };
77 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
78
79 dprintk ("%s\n", __FUNCTION__);
80
81 ret = i2c_transfer (state->i2c, &msg, 1);
82
83 if (ret != 1)
84 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
85 __FUNCTION__, reg, data, ret);
86
87 return (ret != 1) ? -1 : 0;
88}
89
90static int cx22700_readreg (struct cx22700_state* state, u8 reg)
91{
92 int ret;
93 u8 b0 [] = { reg };
94 u8 b1 [] = { 0 };
95 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
96 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
97
98 dprintk ("%s\n", __FUNCTION__);
99
100 ret = i2c_transfer (state->i2c, msg, 2);
101
102 if (ret != 2) return -EIO;
103
104 return b1[0];
105}
106
107static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
108{
109 u8 val;
110
111 dprintk ("%s\n", __FUNCTION__);
112
113 switch (inversion) {
114 case INVERSION_AUTO:
115 return -EOPNOTSUPP;
116 case INVERSION_ON:
117 val = cx22700_readreg (state, 0x09);
118 return cx22700_writereg (state, 0x09, val | 0x01);
119 case INVERSION_OFF:
120 val = cx22700_readreg (state, 0x09);
121 return cx22700_writereg (state, 0x09, val & 0xfe);
122 default:
123 return -EINVAL;
124 }
125}
126
127static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p)
128{
129 static const u8 qam_tab [4] = { 0, 1, 0, 2 };
130 static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
131 u8 val;
132
133 dprintk ("%s\n", __FUNCTION__);
134
135 if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
136 return -EINVAL;
137
138 if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
139
140 if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
141 return -EINVAL;
142
143 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
144 p->guard_interval > GUARD_INTERVAL_1_4)
145 return -EINVAL;
146
147 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
148 p->transmission_mode != TRANSMISSION_MODE_8K)
149 return -EINVAL;
150
151 if (p->constellation != QPSK &&
152 p->constellation != QAM_16 &&
153 p->constellation != QAM_64)
154 return -EINVAL;
155
156 if (p->hierarchy_information < HIERARCHY_NONE ||
157 p->hierarchy_information > HIERARCHY_4)
158 return -EINVAL;
159
160 if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
161 return -EINVAL;
162
163 if (p->bandwidth == BANDWIDTH_7_MHZ)
164 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
165 else
166 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
167
168 val = qam_tab[p->constellation - QPSK];
169 val |= p->hierarchy_information - HIERARCHY_NONE;
170
171 cx22700_writereg (state, 0x04, val);
172
173 val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
174 val |= fec_tab[p->code_rate_LP - FEC_1_2];
175
176 cx22700_writereg (state, 0x05, val);
177
178 val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
179 val |= p->transmission_mode - TRANSMISSION_MODE_2K;
180
181 cx22700_writereg (state, 0x06, val);
182
183 cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */
184 cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */
185
186 return 0;
187}
188
189static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p)
190{
191 static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
192 static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
193 FEC_5_6, FEC_7_8 };
194 u8 val;
195
196 dprintk ("%s\n", __FUNCTION__);
197
198 if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */
199 return -EAGAIN;
200
201 val = cx22700_readreg (state, 0x01);
202
203 if ((val & 0x7) > 4)
204 p->hierarchy_information = HIERARCHY_AUTO;
205 else
206 p->hierarchy_information = HIERARCHY_NONE + (val & 0x7);
207
208 if (((val >> 3) & 0x3) > 2)
209 p->constellation = QAM_AUTO;
210 else
211 p->constellation = qam_tab[(val >> 3) & 0x3];
212
213 val = cx22700_readreg (state, 0x02);
214
215 if (((val >> 3) & 0x07) > 4)
216 p->code_rate_HP = FEC_AUTO;
217 else
218 p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
219
220 if ((val & 0x07) > 4)
221 p->code_rate_LP = FEC_AUTO;
222 else
223 p->code_rate_LP = fec_tab[val & 0x07];
224
225 val = cx22700_readreg (state, 0x03);
226
227 p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
228 p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
229
230 return 0;
231}
232
233static int cx22700_init (struct dvb_frontend* fe)
234
235{ struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
236 int i;
237
238 dprintk("cx22700_init: init chip\n");
239
240 cx22700_writereg (state, 0x00, 0x02); /* soft reset */
241 cx22700_writereg (state, 0x00, 0x00);
242
243 msleep(10);
244
245 for (i=0; i<sizeof(init_tab); i+=2)
246 cx22700_writereg (state, init_tab[i], init_tab[i+1]);
247
248 cx22700_writereg (state, 0x00, 0x01);
249
250 if (state->config->pll_init) {
251 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
252 state->config->pll_init(fe);
253 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
254 }
255
256 return 0;
257}
258
259static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
260{
261 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
262
263 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
264 | (cx22700_readreg (state, 0x0e) << 1);
265 u8 sync = cx22700_readreg (state, 0x07);
266
267 *status = 0;
268
269 if (rs_ber < 0xff00)
270 *status |= FE_HAS_SIGNAL;
271
272 if (sync & 0x20)
273 *status |= FE_HAS_CARRIER;
274
275 if (sync & 0x10)
276 *status |= FE_HAS_VITERBI;
277
278 if (sync & 0x10)
279 *status |= FE_HAS_SYNC;
280
281 if (*status == 0x0f)
282 *status |= FE_HAS_LOCK;
283
284 return 0;
285}
286
287static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
288{
289 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
290
291 *ber = cx22700_readreg (state, 0x0c) & 0x7f;
292 cx22700_writereg (state, 0x0c, 0x00);
293
294 return 0;
295}
296
297static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
298{
299 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
300
301 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
302 | (cx22700_readreg (state, 0x0e) << 1);
303 *signal_strength = ~rs_ber;
304
305 return 0;
306}
307
308static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
309{
310 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
311
312 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
313 | (cx22700_readreg (state, 0x0e) << 1);
314 *snr = ~rs_ber;
315
316 return 0;
317}
318
319static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
320{
321 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
322
323 *ucblocks = cx22700_readreg (state, 0x0f);
324 cx22700_writereg (state, 0x0f, 0x00);
325
326 return 0;
327}
328
329static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
330{
331 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
332
333 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
334 cx22700_writereg (state, 0x00, 0x00);
335
336 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
337 state->config->pll_set(fe, p);
338 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
339 cx22700_set_inversion (state, p->inversion);
340 cx22700_set_tps (state, &p->u.ofdm);
341 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */
342 cx22700_writereg (state, 0x00, 0x01); /* restart acquire */
343
344 return 0;
345}
346
347static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
348{
349 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
350 u8 reg09 = cx22700_readreg (state, 0x09);
351
352 p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
353 return cx22700_get_tps (state, &p->u.ofdm);
354}
355
356static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358 fesettings->min_delay_ms = 150;
359 fesettings->step_size = 166667;
360 fesettings->max_drift = 166667*2;
361 return 0;
362}
363
364static void cx22700_release(struct dvb_frontend* fe)
365{
366 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
367 kfree(state);
368}
369
370static struct dvb_frontend_ops cx22700_ops;
371
372struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
373 struct i2c_adapter* i2c)
374{
375 struct cx22700_state* state = NULL;
376
377 /* allocate memory for the internal state */
378 state = (struct cx22700_state*) kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
379 if (state == NULL) goto error;
380
381 /* setup the state */
382 state->config = config;
383 state->i2c = i2c;
384 memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
385
386 /* check if the demod is there */
387 if (cx22700_readreg(state, 0x07) < 0) goto error;
388
389 /* create dvb_frontend */
390 state->frontend.ops = &state->ops;
391 state->frontend.demodulator_priv = state;
392 return &state->frontend;
393
394error:
395 kfree(state);
396 return NULL;
397}
398
399static struct dvb_frontend_ops cx22700_ops = {
400
401 .info = {
402 .name = "Conexant CX22700 DVB-T",
403 .type = FE_OFDM,
404 .frequency_min = 470000000,
405 .frequency_max = 860000000,
406 .frequency_stepsize = 166667,
407 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
408 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
409 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
410 FE_CAN_RECOVER
411 },
412
413 .release = cx22700_release,
414
415 .init = cx22700_init,
416
417 .set_frontend = cx22700_set_frontend,
418 .get_frontend = cx22700_get_frontend,
419 .get_tune_settings = cx22700_get_tune_settings,
420
421 .read_status = cx22700_read_status,
422 .read_ber = cx22700_read_ber,
423 .read_signal_strength = cx22700_read_signal_strength,
424 .read_snr = cx22700_read_snr,
425 .read_ucblocks = cx22700_read_ucblocks,
426};
427
428module_param(debug, int, 0644);
429MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
430
431MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
432MODULE_AUTHOR("Holger Waechtler");
433MODULE_LICENSE("GPL");
434
435EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
new file mode 100644
index 000000000000..c9145b45874b
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -0,0 +1,41 @@
1/*
2 Conexant CX22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
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#ifndef CX22700_H
24#define CX22700_H
25
26#include <linux/dvb/frontend.h>
27
28struct cx22700_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
new file mode 100644
index 000000000000..1930b513eefa
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -0,0 +1,519 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include "dvb_frontend.h"
35#include "cx22702.h"
36
37
38struct cx22702_state {
39
40 struct i2c_adapter* i2c;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct cx22702_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* previous uncorrected block counter */
50 u8 prevUCBlocks;
51};
52
53static int debug = 0;
54#define dprintk if (debug) printk
55
56/* Register values to initialise the demod */
57static u8 init_tab [] = {
58 0x00, 0x00, /* Stop aquisition */
59 0x0B, 0x06,
60 0x09, 0x01,
61 0x0D, 0x41,
62 0x16, 0x32,
63 0x20, 0x0A,
64 0x21, 0x17,
65 0x24, 0x3e,
66 0x26, 0xff,
67 0x27, 0x10,
68 0x28, 0x00,
69 0x29, 0x00,
70 0x2a, 0x10,
71 0x2b, 0x00,
72 0x2c, 0x10,
73 0x2d, 0x00,
74 0x48, 0xd4,
75 0x49, 0x56,
76 0x6b, 0x1e,
77 0xc8, 0x02,
78 0xf8, 0x02,
79 0xf9, 0x00,
80 0xfa, 0x00,
81 0xfb, 0x00,
82 0xfc, 0x00,
83 0xfd, 0x00,
84};
85
86static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
87{
88 int ret;
89 u8 buf [] = { reg, data };
90 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
91
92 ret = i2c_transfer(state->i2c, &msg, 1);
93
94 if (ret != 1)
95 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
96 __FUNCTION__, reg, data, ret);
97
98 return (ret != 1) ? -1 : 0;
99}
100
101static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106
107 struct i2c_msg msg [] = {
108 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
109 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
110
111 ret = i2c_transfer(state->i2c, msg, 2);
112
113 if (ret != 2)
114 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
115
116 return b1[0];
117}
118
119static int cx22702_set_inversion (struct cx22702_state *state, int inversion)
120{
121 u8 val;
122
123 switch (inversion) {
124
125 case INVERSION_AUTO:
126 return -EOPNOTSUPP;
127
128 case INVERSION_ON:
129 val = cx22702_readreg (state, 0x0C);
130 return cx22702_writereg (state, 0x0C, val | 0x01);
131
132 case INVERSION_OFF:
133 val = cx22702_readreg (state, 0x0C);
134 return cx22702_writereg (state, 0x0C, val & 0xfe);
135
136 default:
137 return -EINVAL;
138
139 }
140
141}
142
143/* Retrieve the demod settings */
144static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p)
145{
146 u8 val;
147
148 /* Make sure the TPS regs are valid */
149 if (!(cx22702_readreg(state, 0x0A) & 0x20))
150 return -EAGAIN;
151
152 val = cx22702_readreg (state, 0x01);
153 switch( (val&0x18)>>3) {
154 case 0: p->constellation = QPSK; break;
155 case 1: p->constellation = QAM_16; break;
156 case 2: p->constellation = QAM_64; break;
157 }
158 switch( val&0x07 ) {
159 case 0: p->hierarchy_information = HIERARCHY_NONE; break;
160 case 1: p->hierarchy_information = HIERARCHY_1; break;
161 case 2: p->hierarchy_information = HIERARCHY_2; break;
162 case 3: p->hierarchy_information = HIERARCHY_4; break;
163 }
164
165
166 val = cx22702_readreg (state, 0x02);
167 switch( (val&0x38)>>3 ) {
168 case 0: p->code_rate_HP = FEC_1_2; break;
169 case 1: p->code_rate_HP = FEC_2_3; break;
170 case 2: p->code_rate_HP = FEC_3_4; break;
171 case 3: p->code_rate_HP = FEC_5_6; break;
172 case 4: p->code_rate_HP = FEC_7_8; break;
173 }
174 switch( val&0x07 ) {
175 case 0: p->code_rate_LP = FEC_1_2; break;
176 case 1: p->code_rate_LP = FEC_2_3; break;
177 case 2: p->code_rate_LP = FEC_3_4; break;
178 case 3: p->code_rate_LP = FEC_5_6; break;
179 case 4: p->code_rate_LP = FEC_7_8; break;
180 }
181
182
183 val = cx22702_readreg (state, 0x03);
184 switch( (val&0x0c)>>2 ) {
185 case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
186 case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
187 case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
188 case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
189 }
190 switch( val&0x03 ) {
191 case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
192 case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
193 }
194
195 return 0;
196}
197
198/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
199static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
200{
201 u8 val;
202 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
203
204 /* set PLL */
205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
206 state->config->pll_set(fe, p);
207 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
208
209 /* set inversion */
210 cx22702_set_inversion (state, p->inversion);
211
212 /* set bandwidth */
213 switch(p->u.ofdm.bandwidth) {
214 case BANDWIDTH_6_MHZ:
215 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 );
216 break;
217 case BANDWIDTH_7_MHZ:
218 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 );
219 break;
220 case BANDWIDTH_8_MHZ:
221 cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
222 break;
223 default:
224 dprintk ("%s: invalid bandwidth\n",__FUNCTION__);
225 return -EINVAL;
226 }
227
228
229 p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working
230
231 /* use auto configuration? */
232 if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) ||
233 (p->u.ofdm.constellation==QAM_AUTO) ||
234 (p->u.ofdm.code_rate_HP==FEC_AUTO) ||
235 (p->u.ofdm.code_rate_LP==FEC_AUTO) ||
236 (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) ||
237 (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) {
238
239 /* TPS Source - use hardware driven values */
240 cx22702_writereg(state, 0x06, 0x10);
241 cx22702_writereg(state, 0x07, 0x9);
242 cx22702_writereg(state, 0x08, 0xC1);
243 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
244 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
245 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
246 printk("%s: Autodetecting\n",__FUNCTION__);
247 return 0;
248 }
249
250 /* manually programmed values */
251 val=0;
252 switch(p->u.ofdm.constellation) {
253 case QPSK: val = (val&0xe7); break;
254 case QAM_16: val = (val&0xe7)|0x08; break;
255 case QAM_64: val = (val&0xe7)|0x10; break;
256 default:
257 dprintk ("%s: invalid constellation\n",__FUNCTION__);
258 return -EINVAL;
259 }
260 switch(p->u.ofdm.hierarchy_information) {
261 case HIERARCHY_NONE: val = (val&0xf8); break;
262 case HIERARCHY_1: val = (val&0xf8)|1; break;
263 case HIERARCHY_2: val = (val&0xf8)|2; break;
264 case HIERARCHY_4: val = (val&0xf8)|3; break;
265 default:
266 dprintk ("%s: invalid hierarchy\n",__FUNCTION__);
267 return -EINVAL;
268 }
269 cx22702_writereg (state, 0x06, val);
270
271 val=0;
272 switch(p->u.ofdm.code_rate_HP) {
273 case FEC_NONE:
274 case FEC_1_2: val = (val&0xc7); break;
275 case FEC_2_3: val = (val&0xc7)|0x08; break;
276 case FEC_3_4: val = (val&0xc7)|0x10; break;
277 case FEC_5_6: val = (val&0xc7)|0x18; break;
278 case FEC_7_8: val = (val&0xc7)|0x20; break;
279 default:
280 dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__);
281 return -EINVAL;
282 }
283 switch(p->u.ofdm.code_rate_LP) {
284 case FEC_NONE:
285 case FEC_1_2: val = (val&0xf8); break;
286 case FEC_2_3: val = (val&0xf8)|1; break;
287 case FEC_3_4: val = (val&0xf8)|2; break;
288 case FEC_5_6: val = (val&0xf8)|3; break;
289 case FEC_7_8: val = (val&0xf8)|4; break;
290 default:
291 dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__);
292 return -EINVAL;
293 }
294 cx22702_writereg (state, 0x07, val);
295
296 val=0;
297 switch(p->u.ofdm.guard_interval) {
298 case GUARD_INTERVAL_1_32: val = (val&0xf3); break;
299 case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break;
300 case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
301 case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
302 default:
303 dprintk ("%s: invalid guard_interval\n",__FUNCTION__);
304 return -EINVAL;
305 }
306 switch(p->u.ofdm.transmission_mode) {
307 case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
308 case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
309 default:
310 dprintk ("%s: invalid transmission_mode\n",__FUNCTION__);
311 return -EINVAL;
312 }
313 cx22702_writereg(state, 0x08, val);
314 cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 );
315 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
316
317 /* Begin channel aquisition */
318 cx22702_writereg(state, 0x00, 0x01);
319
320 return 0;
321}
322
323/* Reset the demod hardware and reset all of the configuration registers
324 to a default state. */
325static int cx22702_init (struct dvb_frontend* fe)
326{
327 int i;
328 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
329
330 cx22702_writereg (state, 0x00, 0x02);
331
332 msleep(10);
333
334 for (i=0; i<sizeof(init_tab); i+=2)
335 cx22702_writereg (state, init_tab[i], init_tab[i+1]);
336
337
338 /* init PLL */
339 if (state->config->pll_init) {
340 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
341 state->config->pll_init(fe);
342 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
343 }
344
345 return 0;
346}
347
348static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
349{
350 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
351 u8 reg0A;
352 u8 reg23;
353
354 *status = 0;
355
356 reg0A = cx22702_readreg (state, 0x0A);
357 reg23 = cx22702_readreg (state, 0x23);
358
359 dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
360 ,__FUNCTION__,reg0A,reg23);
361
362 if(reg0A & 0x10) {
363 *status |= FE_HAS_LOCK;
364 *status |= FE_HAS_VITERBI;
365 *status |= FE_HAS_SYNC;
366 }
367
368 if(reg0A & 0x20)
369 *status |= FE_HAS_CARRIER;
370
371 if(reg23 < 0xf0)
372 *status |= FE_HAS_SIGNAL;
373
374 return 0;
375}
376
377static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
378{
379 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
380
381 if(cx22702_readreg (state, 0xE4) & 0x02) {
382 /* Realtime statistics */
383 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
384 | (cx22702_readreg (state, 0xDF)&0x7F);
385 } else {
386 /* Averagtine statistics */
387 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
388 | cx22702_readreg (state, 0xDF);
389 }
390
391 return 0;
392}
393
394static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
397
398 *signal_strength = cx22702_readreg (state, 0x23);
399
400 return 0;
401}
402
403static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
404{
405 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
406
407 u16 rs_ber=0;
408 if(cx22702_readreg (state, 0xE4) & 0x02) {
409 /* Realtime statistics */
410 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
411 | (cx22702_readreg (state, 0xDF)& 0x7F);
412 } else {
413 /* Averagine statistics */
414 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8
415 | cx22702_readreg (state, 0xDF);
416 }
417 *snr = ~rs_ber;
418
419 return 0;
420}
421
422static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
423{
424 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
425
426 u8 _ucblocks;
427
428 /* RS Uncorrectable Packet Count then reset */
429 _ucblocks = cx22702_readreg (state, 0xE3);
430 if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks);
431 else *ucblocks = state->prevUCBlocks - _ucblocks;
432 state->prevUCBlocks = _ucblocks;
433
434 return 0;
435}
436
437static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
438{
439 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
440
441 u8 reg0C = cx22702_readreg (state, 0x0C);
442
443 p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
444 return cx22702_get_tps (state, &p->u.ofdm);
445}
446
447static void cx22702_release(struct dvb_frontend* fe)
448{
449 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
450 kfree(state);
451}
452
453static struct dvb_frontend_ops cx22702_ops;
454
455struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
456 struct i2c_adapter* i2c)
457{
458 struct cx22702_state* state = NULL;
459
460 /* allocate memory for the internal state */
461 state = (struct cx22702_state*) kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
462 if (state == NULL) goto error;
463
464 /* setup the state */
465 state->config = config;
466 state->i2c = i2c;
467 memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
468 state->prevUCBlocks = 0;
469
470 /* check if the demod is there */
471 if (cx22702_readreg(state, 0x1f) != 0x3) goto error;
472
473 /* create dvb_frontend */
474 state->frontend.ops = &state->ops;
475 state->frontend.demodulator_priv = state;
476 return &state->frontend;
477
478error:
479 kfree(state);
480 return NULL;
481}
482
483static struct dvb_frontend_ops cx22702_ops = {
484
485 .info = {
486 .name = "Conexant CX22702 DVB-T",
487 .type = FE_OFDM,
488 .frequency_min = 177000000,
489 .frequency_max = 858000000,
490 .frequency_stepsize = 166666,
491 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
492 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
493 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
494 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
495 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
496 },
497
498 .release = cx22702_release,
499
500 .init = cx22702_init,
501
502 .set_frontend = cx22702_set_tps,
503 .get_frontend = cx22702_get_frontend,
504
505 .read_status = cx22702_read_status,
506 .read_ber = cx22702_read_ber,
507 .read_signal_strength = cx22702_read_signal_strength,
508 .read_snr = cx22702_read_snr,
509 .read_ucblocks = cx22702_read_ucblocks,
510};
511
512module_param(debug, int, 0644);
513MODULE_PARM_DESC(debug, "Enable verbose debug messages");
514
515MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
516MODULE_AUTHOR("Steven Toth");
517MODULE_LICENSE("GPL");
518
519EXPORT_SYMBOL(cx22702_attach);
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
new file mode 100644
index 000000000000..6e34f997aba2
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -0,0 +1,46 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#ifndef CX22702_H
29#define CX22702_H
30
31#include <linux/dvb/frontend.h>
32
33struct cx22702_config
34{
35 /* the demodulator's i2c address */
36 u8 demod_address;
37
38 /* PLL maintenance */
39 int (*pll_init)(struct dvb_frontend* fe);
40 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
41};
42
43extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
44 struct i2c_adapter* i2c);
45
46#endif // CX22702_H
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
new file mode 100644
index 000000000000..ae16112a0653
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -0,0 +1,657 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
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
25#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30
31#include "dvb_frontend.h"
32#include "cx24110.h"
33
34
35struct cx24110_state {
36
37 struct i2c_adapter* i2c;
38
39 struct dvb_frontend_ops ops;
40
41 const struct cx24110_config* config;
42
43 struct dvb_frontend frontend;
44
45 u32 lastber;
46 u32 lastbler;
47 u32 lastesn0;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "cx24110: " args); \
54 } while (0)
55
56static struct {u8 reg; u8 data;} cx24110_regdata[]=
57 /* Comments beginning with @ denote this value should
58 be the default */
59 {{0x09,0x01}, /* SoftResetAll */
60 {0x09,0x00}, /* release reset */
61 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
62 {0x02,0x17}, /* middle byte " */
63 {0x03,0x29}, /* LSB " */
64 {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
65 {0x06,0xa5}, /* @ PLL 60MHz */
66 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
67 {0x0a,0x00}, /* @ partial chip disables, do not set */
68 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
69 active for first byte */
70 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
71 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
72 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
73 to avoid starting the BER counter. Reset the
74 CRC test bit. Finite counting selected */
75 {0x15,0xff}, /* @ size of the limited time window for RS BER
76 estimation. It is <value>*256 RS blocks, this
77 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
78 {0x16,0x00}, /* @ enable all RS output ports */
79 {0x17,0x04}, /* @ time window allowed for the RS to sync */
80 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
81 for automatically */
82 /* leave the current code rate and normalization
83 registers as they are after reset... */
84 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
85 only once */
86 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
87 estimation. It is <value>*65536 channel bits, i.e.
88 approx. 38ms at 27.5MS/s, rate 3/4 */
89 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
90 /* leave front-end AGC parameters at default values */
91 /* leave decimation AGC parameters at default values */
92 {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
93 {0x36,0xff}, /* clear all interrupt pending flags */
94 {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
95 {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
96 /* leave the equalizer parameters on their default values */
97 /* leave the final AGC parameters on their default values */
98 {0x41,0x00}, /* @ MSB of front-end derotator frequency */
99 {0x42,0x00}, /* @ middle bytes " */
100 {0x43,0x00}, /* @ LSB " */
101 /* leave the carrier tracking loop parameters on default */
102 /* leave the bit timing loop parameters at gefault */
103 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
104 /* the cx24108 data sheet for symbol rates above 15MS/s */
105 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
106 {0x61,0x95}, /* GPIO pins 1-4 have special function */
107 {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
108 {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
109 {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
110 {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
111 {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
112 {0x73,0x00}, /* @ disable several demod bypasses */
113 {0x74,0x00}, /* @ " */
114 {0x75,0x00} /* @ " */
115 /* the remaining registers are for SEC */
116 };
117
118
119static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
120{
121 u8 buf [] = { reg, data };
122 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
123 int err;
124
125 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
126 dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
127 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
128 return -EREMOTEIO;
129 }
130
131 return 0;
132}
133
134static int cx24110_readreg (struct cx24110_state* state, u8 reg)
135{
136 int ret;
137 u8 b0 [] = { reg };
138 u8 b1 [] = { 0 };
139 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
140 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
141
142 ret = i2c_transfer(state->i2c, msg, 2);
143
144 if (ret != 2) return ret;
145
146 return b1[0];
147}
148
149static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
150{
151/* fixme (low): error handling */
152
153 switch (inversion) {
154 case INVERSION_OFF:
155 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
156 /* AcqSpectrInvDis on. No idea why someone should want this */
157 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
158 /* Initial value 0 at start of acq */
159 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
160 /* current value 0 */
161 /* The cx24110 manual tells us this reg is read-only.
162 But what the heck... set it ayways */
163 break;
164 case INVERSION_ON:
165 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
166 /* AcqSpectrInvDis on. No idea why someone should want this */
167 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
168 /* Initial value 1 at start of acq */
169 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
170 /* current value 1 */
171 break;
172 case INVERSION_AUTO:
173 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
174 /* AcqSpectrInvDis off. Leave initial & current states as is */
175 break;
176 default:
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
184{
185/* fixme (low): error handling */
186
187 static const int rate[]={-1,1,2,3,5,7,-1};
188 static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
189 static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
190
191 /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
192 searches all enabled viterbi rates, and can handle non-standard
193 rates as well. */
194
195 if (fec>FEC_AUTO)
196 fec=FEC_AUTO;
197
198 if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
199 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
200 /* clear AcqVitDis bit */
201 cx24110_writereg(state,0x18,0xae);
202 /* allow all DVB standard code rates */
203 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
204 /* set nominal Viterbi rate 3/4 */
205 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
206 /* set current Viterbi rate 3/4 */
207 cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
208 /* set the puncture registers for code rate 3/4 */
209 return 0;
210 } else {
211 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
212 /* set AcqVitDis bit */
213 if(rate[fec]>0) {
214 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
215 /* set nominal Viterbi rate */
216 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
217 /* set current Viterbi rate */
218 cx24110_writereg(state,0x1a,g1[fec]);
219 cx24110_writereg(state,0x1b,g2[fec]);
220 /* not sure if this is the right way: I always used AutoAcq mode */
221 } else
222 return -EOPNOTSUPP;
223/* fixme (low): which is the correct return code? */
224 };
225 return 0;
226}
227
228static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
229{
230 int i;
231
232 i=cx24110_readreg(state,0x22)&0x0f;
233 if(!(i&0x08)) {
234 return FEC_1_2 + i - 1;
235 } else {
236/* fixme (low): a special code rate has been selected. In theory, we need to
237 return a denominator value, a numerator value, and a pair of puncture
238 maps to correctly describe this mode. But this should never happen in
239 practice, because it cannot be set by cx24110_get_fec. */
240 return FEC_NONE;
241 }
242}
243
244static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
245{
246/* fixme (low): add error handling */
247 u32 ratio;
248 u32 tmp, fclk, BDRI;
249
250 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
251 int i;
252
253dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
254 if (srate>90999000UL/2)
255 srate=90999000UL/2;
256 if (srate<500000)
257 srate=500000;
258
259 for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++)
260 ;
261 /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
262 and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
263 R06[3:0] PLLphaseDetGain */
264 tmp=cx24110_readreg(state,0x07)&0xfc;
265 if(srate<90999000UL/4) { /* sample rate 45MHz*/
266 cx24110_writereg(state,0x07,tmp);
267 cx24110_writereg(state,0x06,0x78);
268 fclk=90999000UL/2;
269 } else if(srate<60666000UL/2) { /* sample rate 60MHz */
270 cx24110_writereg(state,0x07,tmp|0x1);
271 cx24110_writereg(state,0x06,0xa5);
272 fclk=60666000UL;
273 } else if(srate<80888000UL/2) { /* sample rate 80MHz */
274 cx24110_writereg(state,0x07,tmp|0x2);
275 cx24110_writereg(state,0x06,0x87);
276 fclk=80888000UL;
277 } else { /* sample rate 90MHz */
278 cx24110_writereg(state,0x07,tmp|0x3);
279 cx24110_writereg(state,0x06,0x78);
280 fclk=90999000UL;
281 };
282 dprintk("cx24110 debug: fclk %d Hz\n",fclk);
283 /* we need to divide two integers with approx. 27 bits in 32 bit
284 arithmetic giving a 25 bit result */
285 /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
286 also the most complex divisor. Hence, the dividend has,
287 assuming 32bit unsigned arithmetic, 6 clear bits on top, the
288 divisor 2 unused bits at the bottom. Also, the quotient is
289 always less than 1/2. Borrowed from VES1893.c, of course */
290
291 tmp=srate<<6;
292 BDRI=fclk>>2;
293 ratio=(tmp/BDRI);
294
295 tmp=(tmp%BDRI)<<8;
296 ratio=(ratio<<8)+(tmp/BDRI);
297
298 tmp=(tmp%BDRI)<<8;
299 ratio=(ratio<<8)+(tmp/BDRI);
300
301 tmp=(tmp%BDRI)<<1;
302 ratio=(ratio<<1)+(tmp/BDRI);
303
304 dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
305 dprintk("fclk = %d\n", fclk);
306 dprintk("ratio= %08x\n", ratio);
307
308 cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
309 cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
310 cx24110_writereg(state, 0x3, (ratio)&0xff);
311
312 return 0;
313
314}
315
316int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
317{
318 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
319
320/* tuner data is 21 bits long, must be left-aligned in data */
321/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
322/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
323
324 dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
325
326 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
327 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
328
329 /* if the auto tuner writer is still busy, clear it out */
330 while (cx24110_readreg(state,0x6d)&0x80)
331 cx24110_writereg(state,0x72,0);
332
333 /* write the topmost 8 bits */
334 cx24110_writereg(state,0x72,(data>>24)&0xff);
335
336 /* wait for the send to be completed */
337 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
338 ;
339
340 /* send another 8 bytes */
341 cx24110_writereg(state,0x72,(data>>16)&0xff);
342 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
343 ;
344
345 /* and the topmost 5 bits of this byte */
346 cx24110_writereg(state,0x72,(data>>8)&0xff);
347 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
348 ;
349
350 /* now strobe the enable line once */
351 cx24110_writereg(state,0x6d,0x32);
352 cx24110_writereg(state,0x6d,0x30);
353
354 return 0;
355}
356
357static int cx24110_initfe(struct dvb_frontend* fe)
358{
359 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
360/* fixme (low): error handling */
361 int i;
362
363 dprintk("%s: init chip\n", __FUNCTION__);
364
365 for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) {
366 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
367 };
368
369 if (state->config->pll_init) state->config->pll_init(fe);
370
371 return 0;
372}
373
374static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
375{
376 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
377
378 switch (voltage) {
379 case SEC_VOLTAGE_13:
380 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
381 case SEC_VOLTAGE_18:
382 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe,
389 fe_sec_mini_cmd_t burst)
390{
391 int rv, bit, i;
392 struct cx24110_state *state = fe->demodulator_priv;
393
394 if (burst == SEC_MINI_A)
395 bit = 0x00;
396 else if (burst == SEC_MINI_B)
397 bit = 0x08;
398 else
399 return -EINVAL;
400
401 rv = cx24110_readreg(state, 0x77);
402 cx24110_writereg(state, 0x77, rv|0x04);
403
404 rv = cx24110_readreg(state, 0x76);
405 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
406 for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
407 ; /* wait for LNB ready */
408
409 return 0;
410}
411
412static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
413 struct dvb_diseqc_master_cmd *cmd)
414{
415 int i, rv;
416 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
417
418 for (i = 0; i < cmd->msg_len; i++)
419 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
420
421 rv = cx24110_readreg(state, 0x77);
422 cx24110_writereg(state, 0x77, rv|0x04);
423
424 rv = cx24110_readreg(state, 0x76);
425
426 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
427 for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);)
428 ; /* wait for LNB ready */
429
430 return 0;
431}
432
433static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
434{
435 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
436
437 int sync = cx24110_readreg (state, 0x55);
438
439 *status = 0;
440
441 if (sync & 0x10)
442 *status |= FE_HAS_SIGNAL;
443
444 if (sync & 0x08)
445 *status |= FE_HAS_CARRIER;
446
447 sync = cx24110_readreg (state, 0x08);
448
449 if (sync & 0x40)
450 *status |= FE_HAS_VITERBI;
451
452 if (sync & 0x20)
453 *status |= FE_HAS_SYNC;
454
455 if ((sync & 0x60) == 0x60)
456 *status |= FE_HAS_LOCK;
457
458 return 0;
459}
460
461static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
462{
463 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
464
465 /* fixme (maybe): value range is 16 bit. Scale? */
466 if(cx24110_readreg(state,0x24)&0x10) {
467 /* the Viterbi error counter has finished one counting window */
468 cx24110_writereg(state,0x24,0x04); /* select the ber reg */
469 state->lastber=cx24110_readreg(state,0x25)|
470 (cx24110_readreg(state,0x26)<<8);
471 cx24110_writereg(state,0x24,0x04); /* start new count window */
472 cx24110_writereg(state,0x24,0x14);
473 }
474 *ber = state->lastber;
475
476 return 0;
477}
478
479static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
480{
481 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
482
483/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
484 u8 signal = cx24110_readreg (state, 0x27)+128;
485 *signal_strength = (signal << 8) | signal;
486
487 return 0;
488}
489
490static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
491{
492 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
493
494 /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
495 if(cx24110_readreg(state,0x6a)&0x80) {
496 /* the Es/N0 error counter has finished one counting window */
497 state->lastesn0=cx24110_readreg(state,0x69)|
498 (cx24110_readreg(state,0x68)<<8);
499 cx24110_writereg(state,0x6a,0x84); /* start new count window */
500 }
501 *snr = state->lastesn0;
502
503 return 0;
504}
505
506static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
507{
508 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
509 u32 lastbyer;
510
511 if(cx24110_readreg(state,0x10)&0x40) {
512 /* the RS error counter has finished one counting window */
513 cx24110_writereg(state,0x10,0x60); /* select the byer reg */
514 lastbyer=cx24110_readreg(state,0x12)|
515 (cx24110_readreg(state,0x13)<<8)|
516 (cx24110_readreg(state,0x14)<<16);
517 cx24110_writereg(state,0x10,0x70); /* select the bler reg */
518 state->lastbler=cx24110_readreg(state,0x12)|
519 (cx24110_readreg(state,0x13)<<8)|
520 (cx24110_readreg(state,0x14)<<16);
521 cx24110_writereg(state,0x10,0x20); /* start new count window */
522 }
523 *ucblocks = state->lastbler;
524
525 return 0;
526}
527
528static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
529{
530 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
531
532 state->config->pll_set(fe, p);
533 cx24110_set_inversion (state, p->inversion);
534 cx24110_set_fec (state, p->u.qpsk.fec_inner);
535 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate);
536 cx24110_writereg(state,0x04,0x05); /* start aquisition */
537
538 return 0;
539}
540
541static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
542{
543 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
544 s32 afc; unsigned sclk;
545
546/* cannot read back tuner settings (freq). Need to have some private storage */
547
548 sclk = cx24110_readreg (state, 0x07) & 0x03;
549/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
550 * Need 64 bit arithmetic. Is thiss possible in the kernel? */
551 if (sclk==0) sclk=90999000L/2L;
552 else if (sclk==1) sclk=60666000L;
553 else if (sclk==2) sclk=80888000L;
554 else sclk=90999000L;
555 sclk>>=8;
556 afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
557 ((sclk*cx24110_readreg (state, 0x45))>>8)+
558 ((sclk*cx24110_readreg (state, 0x46))>>16);
559
560 p->frequency += afc;
561 p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
562 INVERSION_ON : INVERSION_OFF;
563 p->u.qpsk.fec_inner = cx24110_get_fec (state);
564
565 return 0;
566}
567
568static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
569{
570 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
571
572 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
573}
574
575static void cx24110_release(struct dvb_frontend* fe)
576{
577 struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv;
578 kfree(state);
579}
580
581static struct dvb_frontend_ops cx24110_ops;
582
583struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
584 struct i2c_adapter* i2c)
585{
586 struct cx24110_state* state = NULL;
587 int ret;
588
589 /* allocate memory for the internal state */
590 state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
591 if (state == NULL) goto error;
592
593 /* setup the state */
594 state->config = config;
595 state->i2c = i2c;
596 memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
597 state->lastber = 0;
598 state->lastbler = 0;
599 state->lastesn0 = 0;
600
601 /* check if the demod is there */
602 ret = cx24110_readreg(state, 0x00);
603 if ((ret != 0x5a) && (ret != 0x69)) goto error;
604
605 /* create dvb_frontend */
606 state->frontend.ops = &state->ops;
607 state->frontend.demodulator_priv = state;
608 return &state->frontend;
609
610error:
611 kfree(state);
612 return NULL;
613}
614
615static struct dvb_frontend_ops cx24110_ops = {
616
617 .info = {
618 .name = "Conexant CX24110 DVB-S",
619 .type = FE_QPSK,
620 .frequency_min = 950000,
621 .frequency_max = 2150000,
622 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
623 .frequency_tolerance = 29500,
624 .symbol_rate_min = 1000000,
625 .symbol_rate_max = 45000000,
626 .caps = FE_CAN_INVERSION_AUTO |
627 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
628 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
629 FE_CAN_QPSK | FE_CAN_RECOVER
630 },
631
632 .release = cx24110_release,
633
634 .init = cx24110_initfe,
635 .set_frontend = cx24110_set_frontend,
636 .get_frontend = cx24110_get_frontend,
637 .read_status = cx24110_read_status,
638 .read_ber = cx24110_read_ber,
639 .read_signal_strength = cx24110_read_signal_strength,
640 .read_snr = cx24110_read_snr,
641 .read_ucblocks = cx24110_read_ucblocks,
642
643 .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
644 .set_tone = cx24110_set_tone,
645 .set_voltage = cx24110_set_voltage,
646 .diseqc_send_burst = cx24110_diseqc_send_burst,
647};
648
649module_param(debug, int, 0644);
650MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
651
652MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
653MODULE_AUTHOR("Peter Hettkamp");
654MODULE_LICENSE("GPL");
655
656EXPORT_SYMBOL(cx24110_attach);
657EXPORT_SYMBOL(cx24110_pll_write);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
new file mode 100644
index 000000000000..6b663f4744e0
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -0,0 +1,45 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
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
25#ifndef CX24110_H
26#define CX24110_H
27
28#include <linux/dvb/frontend.h>
29
30struct cx24110_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
41 struct i2c_adapter* i2c);
42
43extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data);
44
45#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
new file mode 100644
index 000000000000..47ab02e133d1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -0,0 +1,83 @@
1#include "dib3000-common.h"
2
3#ifdef CONFIG_DVB_DIBCOM_DEBUG
4static int debug;
5module_param(debug, int, 0644);
6MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
7#endif
8#define deb_info(args...) dprintk(0x01,args)
9#define deb_i2c(args...) dprintk(0x02,args)
10#define deb_srch(args...) dprintk(0x04,args)
11
12
13int dib3000_read_reg(struct dib3000_state *state, u16 reg)
14{
15 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
16 u8 rb[2];
17 struct i2c_msg msg[] = {
18 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
19 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
20 };
21
22 if (i2c_transfer(state->i2c, msg, 2) != 2)
23 deb_i2c("i2c read error\n");
24
25 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
26 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
27
28 return (rb[0] << 8) | rb[1];
29}
30
31int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
32{
33 u8 b[] = {
34 (reg >> 8) & 0xff, reg & 0xff,
35 (val >> 8) & 0xff, val & 0xff,
36 };
37 struct i2c_msg msg[] = {
38 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
39 };
40 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
41
42 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
43}
44
45int dib3000_search_status(u16 irq,u16 lock)
46{
47 if (irq & 0x02) {
48 if (lock & 0x01) {
49 deb_srch("auto search succeeded\n");
50 return 1; // auto search succeeded
51 } else {
52 deb_srch("auto search not successful\n");
53 return 0; // auto search failed
54 }
55 } else if (irq & 0x01) {
56 deb_srch("auto search failed\n");
57 return 0; // auto search failed
58 }
59 return -1; // try again
60}
61
62/* for auto search */
63u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
64 { /* fft */
65 { /* gua */
66 { 0, 1 }, /* 0 0 { 0,1 } */
67 { 3, 9 }, /* 0 1 { 0,1 } */
68 },
69 {
70 { 2, 5 }, /* 1 0 { 0,1 } */
71 { 6, 11 }, /* 1 1 { 0,1 } */
72 }
73 };
74
75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers");
77MODULE_LICENSE("GPL");
78
79EXPORT_SYMBOL(dib3000_seq);
80
81EXPORT_SYMBOL(dib3000_read_reg);
82EXPORT_SYMBOL(dib3000_write_reg);
83EXPORT_SYMBOL(dib3000_search_status);
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
new file mode 100644
index 000000000000..c31d6df15472
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.h
@@ -0,0 +1,137 @@
1/*
2 * .h-files for the common use of the frontend drivers made by DiBcom
3 * DiBcom 3000M-B/C, 3000P
4 *
5 * DiBcom (http://www.dibcom.fr/)
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DibCom, which has
10 *
11 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 * Acknowledgements
18 *
19 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
20 * sources, on which this driver (and the dvb-dibusb) are based.
21 *
22 * see Documentation/dvb/README.dibusb for more information
23 *
24 */
25
26#ifndef DIB3000_COMMON_H
27#define DIB3000_COMMON_H
28
29#include "dvb_frontend.h"
30#include "dib3000.h"
31
32/* info and err, taken from usb.h, if there is anything available like by default. */
33#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
34#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
35#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
36
37/* frontend state */
38struct dib3000_state {
39 struct i2c_adapter* i2c;
40
41 struct dvb_frontend_ops ops;
42
43/* configuration settings */
44 struct dib3000_config config;
45
46 struct dvb_frontend frontend;
47 int timing_offset;
48 int timing_offset_comp_done;
49
50 fe_bandwidth_t last_tuned_bw;
51 u32 last_tuned_freq;
52};
53
54/* commonly used methods by the dib3000mb/mc/p frontend */
55extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
56extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
57
58extern int dib3000_search_status(u16 irq,u16 lock);
59
60/* handy shortcuts */
61#define rd(reg) dib3000_read_reg(state,reg)
62
63#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
64 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
65
66#define wr_foreach(a,v) { int i; \
67 if (sizeof(a) != sizeof(v)) \
68 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
69 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
70 wr(a[i],v[i]); \
71 }
72
73#define set_or(reg,val) wr(reg,rd(reg) | val)
74
75#define set_and(reg,val) wr(reg,rd(reg) & val)
76
77
78/* debug */
79
80#ifdef CONFIG_DVB_DIBCOM_DEBUG
81#define dprintk(level,args...) \
82 do { if ((debug & level)) { printk(args); } } while (0)
83#else
84#define dprintk(args...) do { } while (0)
85#endif
86
87/* mask for enabling a specific pid for the pid_filter */
88#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
89
90/* common values for tuning */
91#define DIB3000_ALPHA_0 ( 0)
92#define DIB3000_ALPHA_1 ( 1)
93#define DIB3000_ALPHA_2 ( 2)
94#define DIB3000_ALPHA_4 ( 4)
95
96#define DIB3000_CONSTELLATION_QPSK ( 0)
97#define DIB3000_CONSTELLATION_16QAM ( 1)
98#define DIB3000_CONSTELLATION_64QAM ( 2)
99
100#define DIB3000_GUARD_TIME_1_32 ( 0)
101#define DIB3000_GUARD_TIME_1_16 ( 1)
102#define DIB3000_GUARD_TIME_1_8 ( 2)
103#define DIB3000_GUARD_TIME_1_4 ( 3)
104
105#define DIB3000_TRANSMISSION_MODE_2K ( 0)
106#define DIB3000_TRANSMISSION_MODE_8K ( 1)
107
108#define DIB3000_SELECT_LP ( 0)
109#define DIB3000_SELECT_HP ( 1)
110
111#define DIB3000_FEC_1_2 ( 1)
112#define DIB3000_FEC_2_3 ( 2)
113#define DIB3000_FEC_3_4 ( 3)
114#define DIB3000_FEC_5_6 ( 5)
115#define DIB3000_FEC_7_8 ( 7)
116
117#define DIB3000_HRCH_OFF ( 0)
118#define DIB3000_HRCH_ON ( 1)
119
120#define DIB3000_DDS_INVERSION_OFF ( 0)
121#define DIB3000_DDS_INVERSION_ON ( 1)
122
123#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
124#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
125
126/* for auto search */
127extern u16 dib3000_seq[2][2][2];
128
129#define DIB3000_REG_MANUFACTOR_ID ( 1025)
130#define DIB3000_I2C_ID_DIBCOM (0x01b3)
131
132#define DIB3000_REG_DEVICE_ID ( 1026)
133#define DIB3000MB_DEVICE_ID (0x3000)
134#define DIB3000MC_DEVICE_ID (0x3001)
135#define DIB3000P_DEVICE_ID (0x3002)
136
137#endif // DIB3000_COMMON_H
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
new file mode 100644
index 000000000000..80687c130836
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -0,0 +1,54 @@
1/*
2 * public header file of the frontend drivers for mobile DVB-T demodulators
3 * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#ifndef DIB3000_H
25#define DIB3000_H
26
27#include <linux/dvb/frontend.h>
28
29struct dib3000_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance and the i2c address of the PLL */
35 u8 (*pll_addr)(struct dvb_frontend *fe);
36 int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
37 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
38};
39
40struct dib_fe_xfer_ops
41{
42 /* pid and transfer handling is done in the demodulator */
43 int (*pid_parse)(struct dvb_frontend *fe, int onoff);
44 int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
45 int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
46 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
47};
48
49extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
50 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
51
52extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
53 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
54#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
new file mode 100644
index 000000000000..a853d12a26f1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -0,0 +1,784 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#include <linux/config.h>
25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "dib3000-common.h"
33#include "dib3000mb_priv.h"
34#include "dib3000.h"
35
36/* Version information */
37#define DRIVER_VERSION "0.1"
38#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
39#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
40
41#ifdef CONFIG_DVB_DIBCOM_DEBUG
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
45#endif
46#define deb_info(args...) dprintk(0x01,args)
47#define deb_xfer(args...) dprintk(0x02,args)
48#define deb_setf(args...) dprintk(0x04,args)
49#define deb_getf(args...) dprintk(0x08,args)
50
51static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mb_get_frontend(struct dvb_frontend* fe,
54 struct dvb_frontend_parameters *fep);
55
56static int dib3000mb_set_frontend(struct dvb_frontend* fe,
57 struct dvb_frontend_parameters *fep, int tuner)
58{
59 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
60 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
61 fe_code_rate_t fe_cr = FEC_NONE;
62 int search_state, seq;
63
64 if (tuner) {
65 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
66 state->config.pll_set(fe, fep, NULL);
67 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
68
69 deb_setf("bandwidth: ");
70 switch (ofdm->bandwidth) {
71 case BANDWIDTH_8_MHZ:
72 deb_setf("8 MHz\n");
73 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
74 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
75 break;
76 case BANDWIDTH_7_MHZ:
77 deb_setf("7 MHz\n");
78 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
79 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
80 break;
81 case BANDWIDTH_6_MHZ:
82 deb_setf("6 MHz\n");
83 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
84 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
85 break;
86 case BANDWIDTH_AUTO:
87 return -EOPNOTSUPP;
88 default:
89 err("unkown bandwidth value.");
90 return -EINVAL;
91 }
92 }
93 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
94
95 deb_setf("transmission mode: ");
96 switch (ofdm->transmission_mode) {
97 case TRANSMISSION_MODE_2K:
98 deb_setf("2k\n");
99 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
100 break;
101 case TRANSMISSION_MODE_8K:
102 deb_setf("8k\n");
103 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
104 break;
105 case TRANSMISSION_MODE_AUTO:
106 deb_setf("auto\n");
107 break;
108 default:
109 return -EINVAL;
110 }
111
112 deb_setf("guard: ");
113 switch (ofdm->guard_interval) {
114 case GUARD_INTERVAL_1_32:
115 deb_setf("1_32\n");
116 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
117 break;
118 case GUARD_INTERVAL_1_16:
119 deb_setf("1_16\n");
120 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
121 break;
122 case GUARD_INTERVAL_1_8:
123 deb_setf("1_8\n");
124 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
125 break;
126 case GUARD_INTERVAL_1_4:
127 deb_setf("1_4\n");
128 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
129 break;
130 case GUARD_INTERVAL_AUTO:
131 deb_setf("auto\n");
132 break;
133 default:
134 return -EINVAL;
135 }
136
137 deb_setf("inversion: ");
138 switch (fep->inversion) {
139 case INVERSION_OFF:
140 deb_setf("off\n");
141 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
142 break;
143 case INVERSION_AUTO:
144 deb_setf("auto ");
145 break;
146 case INVERSION_ON:
147 deb_setf("on\n");
148 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
149 break;
150 default:
151 return -EINVAL;
152 }
153
154 deb_setf("constellation: ");
155 switch (ofdm->constellation) {
156 case QPSK:
157 deb_setf("qpsk\n");
158 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
159 break;
160 case QAM_16:
161 deb_setf("qam16\n");
162 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
163 break;
164 case QAM_64:
165 deb_setf("qam64\n");
166 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
167 break;
168 case QAM_AUTO:
169 break;
170 default:
171 return -EINVAL;
172 }
173 deb_setf("hierachy: ");
174 switch (ofdm->hierarchy_information) {
175 case HIERARCHY_NONE:
176 deb_setf("none ");
177 /* fall through */
178 case HIERARCHY_1:
179 deb_setf("alpha=1\n");
180 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
181 break;
182 case HIERARCHY_2:
183 deb_setf("alpha=2\n");
184 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
185 break;
186 case HIERARCHY_4:
187 deb_setf("alpha=4\n");
188 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
189 break;
190 case HIERARCHY_AUTO:
191 deb_setf("alpha=auto\n");
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 deb_setf("hierarchy: ");
198 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
199 deb_setf("none\n");
200 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
201 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
202 fe_cr = ofdm->code_rate_HP;
203 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
204 deb_setf("on\n");
205 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
206 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
207 fe_cr = ofdm->code_rate_LP;
208 }
209 deb_setf("fec: ");
210 switch (fe_cr) {
211 case FEC_1_2:
212 deb_setf("1_2\n");
213 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
214 break;
215 case FEC_2_3:
216 deb_setf("2_3\n");
217 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
218 break;
219 case FEC_3_4:
220 deb_setf("3_4\n");
221 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
222 break;
223 case FEC_5_6:
224 deb_setf("5_6\n");
225 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
226 break;
227 case FEC_7_8:
228 deb_setf("7_8\n");
229 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
230 break;
231 case FEC_NONE:
232 deb_setf("none ");
233 break;
234 case FEC_AUTO:
235 deb_setf("auto\n");
236 break;
237 default:
238 return -EINVAL;
239 }
240
241 seq = dib3000_seq
242 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
243 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
244 [fep->inversion == INVERSION_AUTO];
245
246 deb_setf("seq? %d\n", seq);
247
248 wr(DIB3000MB_REG_SEQ, seq);
249
250 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
251
252 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
253 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
254 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
255 } else {
256 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
257 }
258
259 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
260 } else {
261 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
262 }
263
264 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
265 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
266 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
267
268 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
269
270 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
271
272 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
273 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
274
275 /* wait for AGC lock */
276 msleep(70);
277
278 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
279
280 /* something has to be auto searched */
281 if (ofdm->constellation == QAM_AUTO ||
282 ofdm->hierarchy_information == HIERARCHY_AUTO ||
283 fe_cr == FEC_AUTO ||
284 fep->inversion == INVERSION_AUTO) {
285 int as_count=0;
286
287 deb_setf("autosearch enabled.\n");
288
289 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
290
291 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
292 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
293
294 while ((search_state =
295 dib3000_search_status(
296 rd(DIB3000MB_REG_AS_IRQ_PENDING),
297 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
298 msleep(1);
299
300 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
301
302 if (search_state == 1) {
303 struct dvb_frontend_parameters feps;
304 if (dib3000mb_get_frontend(fe, &feps) == 0) {
305 deb_setf("reading tuning data from frontend succeeded.\n");
306 return dib3000mb_set_frontend(fe, &feps, 0);
307 }
308 }
309
310 } else {
311 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
312 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
313 }
314
315 return 0;
316}
317
318static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
319{
320 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
321
322 deb_info("dib3000mb is getting up.\n");
323 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
324
325 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
326
327 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
328 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
329
330 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
331
332 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
333
334 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
335 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
336
337 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
338
339 wr_foreach(dib3000mb_reg_impulse_noise,
340 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
341
342 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
343
344 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
345
346 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
347
348 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
349
350 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
351
352 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
353 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
354 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
355 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
356
357 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
358
359 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
360 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
361 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
362 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
363 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
364 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
365 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
366 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
367 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
368 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
369 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
370 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
371 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
372 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
373 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
374
375 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
376
377 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
378 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
379 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
380
381 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
382
383 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
384 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
385 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
386 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
387 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
388 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
389
390 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
391
392 if (state->config.pll_init) {
393 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
394 state->config.pll_init(fe,NULL);
395 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
396 }
397
398 return 0;
399}
400
401static int dib3000mb_get_frontend(struct dvb_frontend* fe,
402 struct dvb_frontend_parameters *fep)
403{
404 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
405 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
406 fe_code_rate_t *cr;
407 u16 tps_val;
408 int inv_test1,inv_test2;
409 u32 dds_val, threshold = 0x800000;
410
411 if (!rd(DIB3000MB_REG_TPS_LOCK))
412 return 0;
413
414 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
415 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
416 if (dds_val < threshold)
417 inv_test1 = 0;
418 else if (dds_val == threshold)
419 inv_test1 = 1;
420 else
421 inv_test1 = 2;
422
423 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
424 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
425 if (dds_val < threshold)
426 inv_test2 = 0;
427 else if (dds_val == threshold)
428 inv_test2 = 1;
429 else
430 inv_test2 = 2;
431
432 fep->inversion =
433 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
434 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
435 INVERSION_ON : INVERSION_OFF;
436
437 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
438
439 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
440 case DIB3000_CONSTELLATION_QPSK:
441 deb_getf("QPSK ");
442 ofdm->constellation = QPSK;
443 break;
444 case DIB3000_CONSTELLATION_16QAM:
445 deb_getf("QAM16 ");
446 ofdm->constellation = QAM_16;
447 break;
448 case DIB3000_CONSTELLATION_64QAM:
449 deb_getf("QAM64 ");
450 ofdm->constellation = QAM_64;
451 break;
452 default:
453 err("Unexpected constellation returned by TPS (%d)", tps_val);
454 break;
455 }
456 deb_getf("TPS: %d\n", tps_val);
457
458 if (rd(DIB3000MB_REG_TPS_HRCH)) {
459 deb_getf("HRCH ON\n");
460 cr = &ofdm->code_rate_LP;
461 ofdm->code_rate_HP = FEC_NONE;
462 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
463 case DIB3000_ALPHA_0:
464 deb_getf("HIERARCHY_NONE ");
465 ofdm->hierarchy_information = HIERARCHY_NONE;
466 break;
467 case DIB3000_ALPHA_1:
468 deb_getf("HIERARCHY_1 ");
469 ofdm->hierarchy_information = HIERARCHY_1;
470 break;
471 case DIB3000_ALPHA_2:
472 deb_getf("HIERARCHY_2 ");
473 ofdm->hierarchy_information = HIERARCHY_2;
474 break;
475 case DIB3000_ALPHA_4:
476 deb_getf("HIERARCHY_4 ");
477 ofdm->hierarchy_information = HIERARCHY_4;
478 break;
479 default:
480 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
481 break;
482 }
483 deb_getf("TPS: %d\n", tps_val);
484
485 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
486 } else {
487 deb_getf("HRCH OFF\n");
488 cr = &ofdm->code_rate_HP;
489 ofdm->code_rate_LP = FEC_NONE;
490 ofdm->hierarchy_information = HIERARCHY_NONE;
491
492 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
493 }
494
495 switch (tps_val) {
496 case DIB3000_FEC_1_2:
497 deb_getf("FEC_1_2 ");
498 *cr = FEC_1_2;
499 break;
500 case DIB3000_FEC_2_3:
501 deb_getf("FEC_2_3 ");
502 *cr = FEC_2_3;
503 break;
504 case DIB3000_FEC_3_4:
505 deb_getf("FEC_3_4 ");
506 *cr = FEC_3_4;
507 break;
508 case DIB3000_FEC_5_6:
509 deb_getf("FEC_5_6 ");
510 *cr = FEC_4_5;
511 break;
512 case DIB3000_FEC_7_8:
513 deb_getf("FEC_7_8 ");
514 *cr = FEC_7_8;
515 break;
516 default:
517 err("Unexpected FEC returned by TPS (%d)", tps_val);
518 break;
519 }
520 deb_getf("TPS: %d\n",tps_val);
521
522 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
523 case DIB3000_GUARD_TIME_1_32:
524 deb_getf("GUARD_INTERVAL_1_32 ");
525 ofdm->guard_interval = GUARD_INTERVAL_1_32;
526 break;
527 case DIB3000_GUARD_TIME_1_16:
528 deb_getf("GUARD_INTERVAL_1_16 ");
529 ofdm->guard_interval = GUARD_INTERVAL_1_16;
530 break;
531 case DIB3000_GUARD_TIME_1_8:
532 deb_getf("GUARD_INTERVAL_1_8 ");
533 ofdm->guard_interval = GUARD_INTERVAL_1_8;
534 break;
535 case DIB3000_GUARD_TIME_1_4:
536 deb_getf("GUARD_INTERVAL_1_4 ");
537 ofdm->guard_interval = GUARD_INTERVAL_1_4;
538 break;
539 default:
540 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
541 break;
542 }
543 deb_getf("TPS: %d\n", tps_val);
544
545 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
546 case DIB3000_TRANSMISSION_MODE_2K:
547 deb_getf("TRANSMISSION_MODE_2K ");
548 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
549 break;
550 case DIB3000_TRANSMISSION_MODE_8K:
551 deb_getf("TRANSMISSION_MODE_8K ");
552 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
553 break;
554 default:
555 err("unexpected transmission mode return by TPS (%d)", tps_val);
556 break;
557 }
558 deb_getf("TPS: %d\n", tps_val);
559
560 return 0;
561}
562
563static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
564{
565 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
566
567 *stat = 0;
568
569 if (rd(DIB3000MB_REG_AGC_LOCK))
570 *stat |= FE_HAS_SIGNAL;
571 if (rd(DIB3000MB_REG_CARRIER_LOCK))
572 *stat |= FE_HAS_CARRIER;
573 if (rd(DIB3000MB_REG_VIT_LCK))
574 *stat |= FE_HAS_VITERBI;
575 if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
576 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
577
578 deb_getf("actual status is %2x\n",*stat);
579
580 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
581 rd(DIB3000MB_REG_TPS_LOCK),
582 rd(DIB3000MB_REG_TPS_QAM),
583 rd(DIB3000MB_REG_TPS_HRCH),
584 rd(DIB3000MB_REG_TPS_VIT_ALPHA),
585 rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
586 rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
587 rd(DIB3000MB_REG_TPS_GUARD_TIME),
588 rd(DIB3000MB_REG_TPS_FFT),
589 rd(DIB3000MB_REG_TPS_CELL_ID));
590
591 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
592 return 0;
593}
594
595static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
596{
597 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
598
599 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
600 return 0;
601}
602
603/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
604static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
605{
606 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
607
608 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
609 return 0;
610}
611
612static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
613{
614 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
615 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
616 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
617 rd(DIB3000MB_REG_NOISE_POWER_LSB);
618 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
619 return 0;
620}
621
622static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
623{
624 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
625
626 *unc = rd(DIB3000MB_REG_UNC);
627 return 0;
628}
629
630static int dib3000mb_sleep(struct dvb_frontend* fe)
631{
632 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
633 deb_info("dib3000mb is going to bed.\n");
634 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
635 return 0;
636}
637
638static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
639{
640 tune->min_delay_ms = 800;
641 tune->step_size = 166667;
642 tune->max_drift = 166667 * 2;
643
644 return 0;
645}
646
647static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
648{
649 return dib3000mb_fe_init(fe, 0);
650}
651
652static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
653{
654 return dib3000mb_set_frontend(fe, fep, 1);
655}
656
657static void dib3000mb_release(struct dvb_frontend* fe)
658{
659 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
660 kfree(state);
661}
662
663/* pid filter and transfer stuff */
664static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
665{
666 struct dib3000_state *state = fe->demodulator_priv;
667 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
668 wr(index+DIB3000MB_REG_FIRST_PID,pid);
669 return 0;
670}
671
672static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
673{
674 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
675
676 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
677 if (onoff) {
678 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
679 } else {
680 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
681 }
682 return 0;
683}
684
685static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
686{
687 struct dib3000_state *state = fe->demodulator_priv;
688 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
689 wr(DIB3000MB_REG_PID_PARSE,onoff);
690 return 0;
691}
692
693static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
694{
695 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
696 if (onoff) {
697 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
698 } else {
699 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
700 }
701 return 0;
702}
703
704static struct dvb_frontend_ops dib3000mb_ops;
705
706struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
707 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
708{
709 struct dib3000_state* state = NULL;
710
711 /* allocate memory for the internal state */
712 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
713 if (state == NULL)
714 goto error;
715 memset(state,0,sizeof(struct dib3000_state));
716
717 /* setup the state */
718 state->i2c = i2c;
719 memcpy(&state->config,config,sizeof(struct dib3000_config));
720 memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
721
722 /* check for the correct demod */
723 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
724 goto error;
725
726 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
727 goto error;
728
729 /* create dvb_frontend */
730 state->frontend.ops = &state->ops;
731 state->frontend.demodulator_priv = state;
732
733 /* set the xfer operations */
734 xfer_ops->pid_parse = dib3000mb_pid_parse;
735 xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
736 xfer_ops->pid_ctrl = dib3000mb_pid_control;
737 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
738
739 return &state->frontend;
740
741error:
742 kfree(state);
743 return NULL;
744}
745
746static struct dvb_frontend_ops dib3000mb_ops = {
747
748 .info = {
749 .name = "DiBcom 3000M-B DVB-T",
750 .type = FE_OFDM,
751 .frequency_min = 44250000,
752 .frequency_max = 867250000,
753 .frequency_stepsize = 62500,
754 .caps = FE_CAN_INVERSION_AUTO |
755 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
756 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
757 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
758 FE_CAN_TRANSMISSION_MODE_AUTO |
759 FE_CAN_GUARD_INTERVAL_AUTO |
760 FE_CAN_RECOVER |
761 FE_CAN_HIERARCHY_AUTO,
762 },
763
764 .release = dib3000mb_release,
765
766 .init = dib3000mb_fe_init_nonmobile,
767 .sleep = dib3000mb_sleep,
768
769 .set_frontend = dib3000mb_set_frontend_and_tuner,
770 .get_frontend = dib3000mb_get_frontend,
771 .get_tune_settings = dib3000mb_fe_get_tune_settings,
772
773 .read_status = dib3000mb_read_status,
774 .read_ber = dib3000mb_read_ber,
775 .read_signal_strength = dib3000mb_read_signal_strength,
776 .read_snr = dib3000mb_read_snr,
777 .read_ucblocks = dib3000mb_read_unc_blocks,
778};
779
780MODULE_AUTHOR(DRIVER_AUTHOR);
781MODULE_DESCRIPTION(DRIVER_DESC);
782MODULE_LICENSE("GPL");
783
784EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
new file mode 100644
index 000000000000..57e61aa5b07b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -0,0 +1,467 @@
1/*
2 * dib3000mb_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mb.c .
11 */
12
13#ifndef __DIB3000MB_PRIV_H_INCLUDED__
14#define __DIB3000MB_PRIV_H_INCLUDED__
15
16/* register addresses and some of their default values */
17
18/* restart subsystems */
19#define DIB3000MB_REG_RESTART ( 0)
20
21#define DIB3000MB_RESTART_OFF ( 0)
22#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1)
23#define DIB3000MB_RESTART_CTRL (1 << 2)
24#define DIB3000MB_RESTART_AGC (1 << 3)
25
26/* FFT size */
27#define DIB3000MB_REG_FFT ( 1)
28
29/* Guard time */
30#define DIB3000MB_REG_GUARD_TIME ( 2)
31
32/* QAM */
33#define DIB3000MB_REG_QAM ( 3)
34
35/* Alpha coefficient high priority Viterbi algorithm */
36#define DIB3000MB_REG_VIT_ALPHA ( 4)
37
38/* spectrum inversion */
39#define DIB3000MB_REG_DDS_INV ( 5)
40
41/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
42#define DIB3000MB_REG_DDS_FREQ_MSB ( 6)
43#define DIB3000MB_REG_DDS_FREQ_LSB ( 7)
44#define DIB3000MB_DDS_FREQ_MSB ( 178)
45#define DIB3000MB_DDS_FREQ_LSB ( 8990)
46
47/* timing frequency (carrier spacing) */
48static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
49static u16 dib3000mb_timing_freq[][2] = {
50 { 126 , 48873 }, /* 6 MHz */
51 { 147 , 57019 }, /* 7 MHz */
52 { 168 , 65164 }, /* 8 MHz */
53};
54
55/* impulse noise parameter */
56/* 36 ??? */
57
58static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
59
60enum dib3000mb_impulse_noise_type {
61 DIB3000MB_IMPNOISE_OFF,
62 DIB3000MB_IMPNOISE_MOBILE,
63 DIB3000MB_IMPNOISE_FIXED,
64 DIB3000MB_IMPNOISE_DEFAULT
65};
66
67static u16 dib3000mb_impulse_noise_values[][5] = {
68 { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
69 { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
70 { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
71 { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
72};
73
74/*
75 * Dual Automatic-Gain-Control
76 * - gains RF in tuner (AGC1)
77 * - gains IF after filtering (AGC2)
78 */
79
80/* also from 16 to 18 */
81static u16 dib3000mb_reg_agc_gain[] = {
82 19,20,21,22,23,24,25,26,27,28,29,30,31,32
83};
84
85static u16 dib3000mb_default_agc_gain[] =
86 { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */
87 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */
88
89/* phase noise */
90/* 36 is set when setting the impulse noise */
91static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
92
93static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
94
95/* lock duration */
96static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
97static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
98
99/* AGC loop bandwidth */
100static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
101
102static u16 dib3000mb_agc_bandwidth_low[] =
103 { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
104static u16 dib3000mb_agc_bandwidth_high[] =
105 { 2349, 5, 2349, 5, 2586, 2, 2586, 2 };
106
107/*
108 * lock0 definition (coff_lock)
109 */
110#define DIB3000MB_REG_LOCK0_MASK ( 51)
111#define DIB3000MB_LOCK0_DEFAULT ( 4)
112
113/*
114 * lock1 definition (cpil_lock)
115 * for auto search
116 * which values hide behind the lock masks
117 */
118#define DIB3000MB_REG_LOCK1_MASK ( 52)
119#define DIB3000MB_LOCK1_SEARCH_4 (0x0004)
120#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800)
121#define DIB3000MB_LOCK1_DEFAULT (0x0001)
122
123/*
124 * lock2 definition (fec_lock) */
125#define DIB3000MB_REG_LOCK2_MASK ( 53)
126#define DIB3000MB_LOCK2_DEFAULT (0x0080)
127
128/*
129 * SEQ ? what was that again ... :)
130 * changes when, inversion, guard time and fft is
131 * either automatically detected or not
132 */
133#define DIB3000MB_REG_SEQ ( 54)
134
135/* bandwidth */
136static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
137static u16 dib3000mb_bandwidth_6mhz[] =
138 { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
139
140static u16 dib3000mb_bandwidth_7mhz[] =
141 { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 };
142
143static u16 dib3000mb_bandwidth_8mhz[] =
144 { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
145
146#define DIB3000MB_REG_UNK_68 ( 68)
147#define DIB3000MB_UNK_68 ( 0)
148
149#define DIB3000MB_REG_UNK_69 ( 69)
150#define DIB3000MB_UNK_69 ( 0)
151
152#define DIB3000MB_REG_UNK_71 ( 71)
153#define DIB3000MB_UNK_71 ( 0)
154
155#define DIB3000MB_REG_UNK_77 ( 77)
156#define DIB3000MB_UNK_77 ( 6)
157
158#define DIB3000MB_REG_UNK_78 ( 78)
159#define DIB3000MB_UNK_78 (0x0080)
160
161/* isi */
162#define DIB3000MB_REG_ISI ( 79)
163#define DIB3000MB_ISI_ACTIVATE ( 0)
164#define DIB3000MB_ISI_INHIBIT ( 1)
165
166/* sync impovement */
167#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84)
168#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3)
169#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0)
170
171/* phase noise compensation inhibition */
172#define DIB3000MB_REG_PHASE_NOISE ( 87)
173#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0)
174
175#define DIB3000MB_REG_UNK_92 ( 92)
176#define DIB3000MB_UNK_92 (0x0080)
177
178#define DIB3000MB_REG_UNK_96 ( 96)
179#define DIB3000MB_UNK_96 (0x0010)
180
181#define DIB3000MB_REG_UNK_97 ( 97)
182#define DIB3000MB_UNK_97 (0x0009)
183
184/* mobile mode ??? */
185#define DIB3000MB_REG_MOBILE_MODE ( 101)
186#define DIB3000MB_MOBILE_MODE_ON ( 1)
187#define DIB3000MB_MOBILE_MODE_OFF ( 0)
188
189#define DIB3000MB_REG_UNK_106 ( 106)
190#define DIB3000MB_UNK_106 (0x0080)
191
192#define DIB3000MB_REG_UNK_107 ( 107)
193#define DIB3000MB_UNK_107 (0x0080)
194
195#define DIB3000MB_REG_UNK_108 ( 108)
196#define DIB3000MB_UNK_108 (0x0080)
197
198/* fft */
199#define DIB3000MB_REG_UNK_121 ( 121)
200#define DIB3000MB_UNK_121_2K ( 7)
201#define DIB3000MB_UNK_121_DEFAULT ( 5)
202
203#define DIB3000MB_REG_UNK_122 ( 122)
204#define DIB3000MB_UNK_122 ( 2867)
205
206/* QAM for mobile mode */
207#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126)
208#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3)
209#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1)
210#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0)
211
212/*
213 * data diversity when having more than one chip on-board
214 * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
215 */
216#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127)
217#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0)
218#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2)
219
220/* vit hrch */
221#define DIB3000MB_REG_VIT_HRCH ( 128)
222
223/* vit code rate */
224#define DIB3000MB_REG_VIT_CODE_RATE ( 129)
225
226/* vit select hp */
227#define DIB3000MB_REG_VIT_HP ( 130)
228
229/* time frame for Bit-Error-Rate calculation */
230#define DIB3000MB_REG_BERLEN ( 135)
231#define DIB3000MB_BERLEN_LONG ( 0)
232#define DIB3000MB_BERLEN_DEFAULT ( 1)
233#define DIB3000MB_BERLEN_MEDIUM ( 2)
234#define DIB3000MB_BERLEN_SHORT ( 3)
235
236/* 142 - 152 FIFO parameters
237 * which is what ?
238 */
239
240#define DIB3000MB_REG_FIFO_142 ( 142)
241#define DIB3000MB_FIFO_142 ( 0)
242
243/* MPEG2 TS output mode */
244#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143)
245#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0)
246#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1)
247
248#define DIB3000MB_REG_PID_PARSE ( 144)
249#define DIB3000MB_PID_PARSE_INHIBIT ( 0)
250#define DIB3000MB_PID_PARSE_ACTIVATE ( 1)
251
252#define DIB3000MB_REG_FIFO ( 145)
253#define DIB3000MB_FIFO_INHIBIT ( 1)
254#define DIB3000MB_FIFO_ACTIVATE ( 0)
255
256#define DIB3000MB_REG_FIFO_146 ( 146)
257#define DIB3000MB_FIFO_146 ( 3)
258
259#define DIB3000MB_REG_FIFO_147 ( 147)
260#define DIB3000MB_FIFO_147 (0x0100)
261
262/*
263 * pidfilter
264 * it is not a hardware pidfilter but a filter which drops all pids
265 * except the ones set. Necessary because of the limited USB1.1 bandwidth.
266 * regs 153-168
267 */
268
269#define DIB3000MB_REG_FIRST_PID ( 153)
270#define DIB3000MB_NUM_PIDS ( 16)
271
272/*
273 * output mode
274 * USB devices have to use 'slave'-mode
275 * see also DIB3000MB_REG_ELECT_OUT_MODE
276 */
277#define DIB3000MB_REG_OUTPUT_MODE ( 169)
278#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0)
279#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1)
280#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2)
281#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5)
282#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6)
283
284/* irq event mask */
285#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170)
286#define DIB3000MB_IRQ_EVENT_MASK ( 0)
287
288/* filter coefficients */
289static u16 dib3000mb_reg_filter_coeffs[] = {
290 171, 172, 173, 174, 175, 176, 177, 178,
291 179, 180, 181, 182, 183, 184, 185, 186,
292 188, 189, 190, 191, 192, 194
293};
294
295static u16 dib3000mb_filter_coeffs[] = {
296 226, 160, 29,
297 979, 998, 19,
298 22, 1019, 1006,
299 1022, 12, 6,
300 1017, 1017, 3,
301 6, 1019,
302 1021, 2, 3,
303 1, 0,
304};
305
306/*
307 * mobile algorithm (when you are moving with your device)
308 * but not faster than 90 km/h
309 */
310#define DIB3000MB_REG_MOBILE_ALGO ( 195)
311#define DIB3000MB_MOBILE_ALGO_ON ( 0)
312#define DIB3000MB_MOBILE_ALGO_OFF ( 1)
313
314/* multiple demodulators algorithm */
315#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206)
316#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207)
317
318/* terminator, no more demods */
319#define DIB3000MB_MULTI_DEMOD_MSB ( 32767)
320#define DIB3000MB_MULTI_DEMOD_LSB ( 4095)
321
322/* bring the device into a known */
323#define DIB3000MB_REG_RESET_DEVICE ( 1024)
324#define DIB3000MB_RESET_DEVICE (0x812c)
325#define DIB3000MB_RESET_DEVICE_RST ( 0)
326
327/* hardware clock configuration */
328#define DIB3000MB_REG_CLOCK ( 1027)
329#define DIB3000MB_CLOCK_DEFAULT (0x9000)
330#define DIB3000MB_CLOCK_DIVERSITY (0x92b0)
331
332/* power down config */
333#define DIB3000MB_REG_POWER_CONTROL ( 1028)
334#define DIB3000MB_POWER_DOWN ( 1)
335#define DIB3000MB_POWER_UP ( 0)
336
337/* electrical output mode */
338#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029)
339#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0)
340#define DIB3000MB_ELECT_OUT_MODE_ON ( 1)
341
342/* set the tuner i2c address */
343#define DIB3000MB_REG_TUNER ( 1089)
344
345/* monitoring registers (read only) */
346
347/* agc loop locked (size: 1) */
348#define DIB3000MB_REG_AGC_LOCK ( 324)
349
350/* agc power (size: 16) */
351#define DIB3000MB_REG_AGC_POWER ( 325)
352
353/* agc1 value (16) */
354#define DIB3000MB_REG_AGC1_VALUE ( 326)
355
356/* agc2 value (16) */
357#define DIB3000MB_REG_AGC2_VALUE ( 327)
358
359/* total RF power (16), can be used for signal strength */
360#define DIB3000MB_REG_RF_POWER ( 328)
361
362/* dds_frequency with offset (24) */
363#define DIB3000MB_REG_DDS_VALUE_MSB ( 339)
364#define DIB3000MB_REG_DDS_VALUE_LSB ( 340)
365
366/* timing offset signed (24) */
367#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341)
368#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342)
369
370/* fft start position (13) */
371#define DIB3000MB_REG_FFT_WINDOW_POS ( 353)
372
373/* carriers locked (1) */
374#define DIB3000MB_REG_CARRIER_LOCK ( 355)
375
376/* noise power (24) */
377#define DIB3000MB_REG_NOISE_POWER_MSB ( 372)
378#define DIB3000MB_REG_NOISE_POWER_LSB ( 373)
379
380#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374)
381#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375)
382
383/*
384 * signal power (16), this and the above can be
385 * used to calculate the signal/noise - ratio
386 */
387#define DIB3000MB_REG_SIGNAL_POWER ( 380)
388
389/* mer (24) */
390#define DIB3000MB_REG_MER_MSB ( 381)
391#define DIB3000MB_REG_MER_LSB ( 382)
392
393/*
394 * Transmission Parameter Signalling (TPS)
395 * the following registers can be used to get TPS-information.
396 * The values are according to the DVB-T standard.
397 */
398
399/* TPS locked (1) */
400#define DIB3000MB_REG_TPS_LOCK ( 394)
401
402/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
403#define DIB3000MB_REG_TPS_QAM ( 398)
404
405/* hierarchy from TPS (1) */
406#define DIB3000MB_REG_TPS_HRCH ( 399)
407
408/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
409#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400)
410
411/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
412#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401)
413
414/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
415#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402)
416
417/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
418#define DIB3000MB_REG_TPS_GUARD_TIME ( 403)
419
420/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
421#define DIB3000MB_REG_TPS_FFT ( 404)
422
423/* cell id from TPS (16) */
424#define DIB3000MB_REG_TPS_CELL_ID ( 406)
425
426/* TPS (68) */
427#define DIB3000MB_REG_TPS_1 ( 408)
428#define DIB3000MB_REG_TPS_2 ( 409)
429#define DIB3000MB_REG_TPS_3 ( 410)
430#define DIB3000MB_REG_TPS_4 ( 411)
431#define DIB3000MB_REG_TPS_5 ( 412)
432
433/* bit error rate (before RS correction) (21) */
434#define DIB3000MB_REG_BER_MSB ( 414)
435#define DIB3000MB_REG_BER_LSB ( 415)
436
437/* packet error rate (uncorrected TS packets) (16) */
438#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)
439
440/* uncorrected packet count (16) */
441#define DIB3000MB_REG_UNC ( 420)
442
443/* viterbi locked (1) */
444#define DIB3000MB_REG_VIT_LCK ( 421)
445
446/* viterbi inidcator (16) */
447#define DIB3000MB_REG_VIT_INDICATOR ( 422)
448
449/* transport stream sync lock (1) */
450#define DIB3000MB_REG_TS_SYNC_LOCK ( 423)
451
452/* transport stream RS lock (1) */
453#define DIB3000MB_REG_TS_RS_LOCK ( 424)
454
455/* lock mask 0 value (1) */
456#define DIB3000MB_REG_LOCK0_VALUE ( 425)
457
458/* lock mask 1 value (1) */
459#define DIB3000MB_REG_LOCK1_VALUE ( 426)
460
461/* lock mask 2 value (1) */
462#define DIB3000MB_REG_LOCK2_VALUE ( 427)
463
464/* interrupt pending for auto search */
465#define DIB3000MB_REG_AS_IRQ_PENDING ( 434)
466
467#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
new file mode 100644
index 000000000000..4a31c05eaecd
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -0,0 +1,931 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DiBCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/version.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30
31#include "dib3000-common.h"
32#include "dib3000mc_priv.h"
33#include "dib3000.h"
34
35/* Version information */
36#define DRIVER_VERSION "0.1"
37#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
38#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able)).");
44#endif
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_xfer(args...) dprintk(0x02,args)
47#define deb_setf(args...) dprintk(0x04,args)
48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args)
50
51static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
54 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
55{
56 switch (transmission_mode) {
57 case TRANSMISSION_MODE_2K:
58 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
59 break;
60 case TRANSMISSION_MODE_8K:
61 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
62 break;
63 default:
64 break;
65 }
66
67 switch (bandwidth) {
68/* case BANDWIDTH_5_MHZ:
69 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]);
70 break; */
71 case BANDWIDTH_6_MHZ:
72 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]);
73 break;
74 case BANDWIDTH_7_MHZ:
75 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]);
76 break;
77 case BANDWIDTH_8_MHZ:
78 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]);
79 break;
80 default:
81 break;
82 }
83
84 switch (mode) {
85 case 0: /* no impulse */ /* fall through */
86 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]);
87 break;
88 case 1: /* new algo */
89 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
90 set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
91 break;
92 default: /* old algo */
93 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
94 break;
95 }
96 return 0;
97}
98
99static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
100 fe_transmit_mode_t fft, fe_bandwidth_t bw)
101{
102 u16 timf_msb,timf_lsb;
103 s32 tim_offset,tim_sgn;
104 u64 comp1,comp2,comp=0;
105
106 switch (bw) {
107 case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break;
108 case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break;
109 case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break;
110 default: err("unknown bandwidth (%d)",bw); break;
111 }
112 timf_msb = (comp >> 16) & 0xff;
113 timf_lsb = (comp & 0xffff);
114
115 // Update the timing offset ;
116 if (upd_offset > 0) {
117 if (!state->timing_offset_comp_done) {
118 msleep(200);
119 state->timing_offset_comp_done = 1;
120 }
121 tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB);
122 if ((tim_offset & 0x2000) == 0x2000)
123 tim_offset |= 0xC000;
124 if (fft == TRANSMISSION_MODE_2K)
125 tim_offset <<= 2;
126 state->timing_offset += tim_offset;
127 }
128
129 tim_offset = state->timing_offset;
130 if (tim_offset < 0) {
131 tim_sgn = 1;
132 tim_offset = -tim_offset;
133 } else
134 tim_sgn = 0;
135
136 comp1 = (u32)tim_offset * (u32)timf_lsb ;
137 comp2 = (u32)tim_offset * (u32)timf_msb ;
138 comp = ((comp1 >> 16) + comp2) >> 7;
139
140 if (tim_sgn == 0)
141 comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp;
142 else
143 comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ;
144
145 timf_msb = (comp >> 16) & 0xff;
146 timf_lsb = comp & 0xffff;
147
148 wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
149 wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
150 return 0;
151}
152
153static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
154{
155 if (boost) {
156 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON);
157 } else {
158 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF);
159 }
160 switch (bw) {
161 case BANDWIDTH_8_MHZ:
162 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
163 break;
164 case BANDWIDTH_7_MHZ:
165 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
166 break;
167 case BANDWIDTH_6_MHZ:
168 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
169 break;
170/* case BANDWIDTH_5_MHZ:
171 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
172 break;*/
173 case BANDWIDTH_AUTO:
174 return -EOPNOTSUPP;
175 default:
176 err("unknown bandwidth value (%d).",bw);
177 return -EINVAL;
178 }
179 if (boost) {
180 u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
181 rd(DIB3000MC_REG_BW_TIMOUT_LSB);
182 timeout *= 85; timeout >>= 7;
183 wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
184 wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
185 }
186 return 0;
187}
188
189static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
190{
191 switch (con) {
192 case QAM_64:
193 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
194 break;
195 case QAM_16:
196 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
197 break;
198 case QPSK:
199 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
200 break;
201 case QAM_AUTO:
202 break;
203 default:
204 warn("unkown constellation.");
205 break;
206 }
207 return 0;
208}
209
210static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
211{
212 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
213 fe_code_rate_t fe_cr = FEC_NONE;
214 u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0;
215 int seq;
216
217 switch (ofdm->transmission_mode) {
218 case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break;
219 case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break;
220 case TRANSMISSION_MODE_AUTO: break;
221 default: return -EINVAL;
222 }
223 switch (ofdm->guard_interval) {
224 case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
225 case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
226 case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
227 case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
228 case GUARD_INTERVAL_AUTO: break;
229 default: return -EINVAL;
230 }
231 switch (ofdm->constellation) {
232 case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
233 case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
234 case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
235 case QAM_AUTO: break;
236 default: return -EINVAL;
237 }
238 switch (ofdm->hierarchy_information) {
239 case HIERARCHY_NONE: /* fall through */
240 case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
241 case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
242 case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
243 case HIERARCHY_AUTO: break;
244 default: return -EINVAL;
245 }
246 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
247 hrch = DIB3000_HRCH_OFF;
248 sel_hp = DIB3000_SELECT_HP;
249 fe_cr = ofdm->code_rate_HP;
250 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
251 hrch = DIB3000_HRCH_ON;
252 sel_hp = DIB3000_SELECT_LP;
253 fe_cr = ofdm->code_rate_LP;
254 }
255 switch (fe_cr) {
256 case FEC_1_2: cr = DIB3000_FEC_1_2; break;
257 case FEC_2_3: cr = DIB3000_FEC_2_3; break;
258 case FEC_3_4: cr = DIB3000_FEC_3_4; break;
259 case FEC_5_6: cr = DIB3000_FEC_5_6; break;
260 case FEC_7_8: cr = DIB3000_FEC_7_8; break;
261 case FEC_NONE: break;
262 case FEC_AUTO: break;
263 default: return -EINVAL;
264 }
265
266 wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft));
267 wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch));
268
269 switch (fep->inversion) {
270 case INVERSION_OFF:
271 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
272 break;
273 case INVERSION_AUTO: /* fall through */
274 case INVERSION_ON:
275 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 seq = dib3000_seq
282 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
283 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
284 [fep->inversion == INVERSION_AUTO];
285
286 deb_setf("seq? %d\n", seq);
287 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1));
288 *auto_val = ofdm->constellation == QAM_AUTO ||
289 ofdm->hierarchy_information == HIERARCHY_AUTO ||
290 ofdm->guard_interval == GUARD_INTERVAL_AUTO ||
291 ofdm->transmission_mode == TRANSMISSION_MODE_AUTO ||
292 fe_cr == FEC_AUTO ||
293 fep->inversion == INVERSION_AUTO;
294 return 0;
295}
296
297static int dib3000mc_get_frontend(struct dvb_frontend* fe,
298 struct dvb_frontend_parameters *fep)
299{
300 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
301 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
302 fe_code_rate_t *cr;
303 u16 tps_val,cr_val;
304 int inv_test1,inv_test2;
305 u32 dds_val, threshold = 0x1000000;
306
307 if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
308 return 0;
309
310 dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
311 deb_getf("DDS_FREQ: %6x\n",dds_val);
312 if (dds_val < threshold)
313 inv_test1 = 0;
314 else if (dds_val == threshold)
315 inv_test1 = 1;
316 else
317 inv_test1 = 2;
318
319 dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
320 deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
321 if (dds_val < threshold)
322 inv_test2 = 0;
323 else if (dds_val == threshold)
324 inv_test2 = 1;
325 else
326 inv_test2 = 2;
327
328 fep->inversion =
329 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
330 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
331 INVERSION_ON : INVERSION_OFF;
332
333 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
334
335 fep->frequency = state->last_tuned_freq;
336 fep->u.ofdm.bandwidth= state->last_tuned_bw;
337
338 tps_val = rd(DIB3000MC_REG_TUNING_PARM);
339
340 switch (DIB3000MC_TP_QAM(tps_val)) {
341 case DIB3000_CONSTELLATION_QPSK:
342 deb_getf("QPSK ");
343 ofdm->constellation = QPSK;
344 break;
345 case DIB3000_CONSTELLATION_16QAM:
346 deb_getf("QAM16 ");
347 ofdm->constellation = QAM_16;
348 break;
349 case DIB3000_CONSTELLATION_64QAM:
350 deb_getf("QAM64 ");
351 ofdm->constellation = QAM_64;
352 break;
353 default:
354 err("Unexpected constellation returned by TPS (%d)", tps_val);
355 break;
356 }
357
358 if (DIB3000MC_TP_HRCH(tps_val)) {
359 deb_getf("HRCH ON ");
360 cr = &ofdm->code_rate_LP;
361 ofdm->code_rate_HP = FEC_NONE;
362 switch (DIB3000MC_TP_ALPHA(tps_val)) {
363 case DIB3000_ALPHA_0:
364 deb_getf("HIERARCHY_NONE ");
365 ofdm->hierarchy_information = HIERARCHY_NONE;
366 break;
367 case DIB3000_ALPHA_1:
368 deb_getf("HIERARCHY_1 ");
369 ofdm->hierarchy_information = HIERARCHY_1;
370 break;
371 case DIB3000_ALPHA_2:
372 deb_getf("HIERARCHY_2 ");
373 ofdm->hierarchy_information = HIERARCHY_2;
374 break;
375 case DIB3000_ALPHA_4:
376 deb_getf("HIERARCHY_4 ");
377 ofdm->hierarchy_information = HIERARCHY_4;
378 break;
379 default:
380 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
381 break;
382 }
383 cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
384 } else {
385 deb_getf("HRCH OFF ");
386 cr = &ofdm->code_rate_HP;
387 ofdm->code_rate_LP = FEC_NONE;
388 ofdm->hierarchy_information = HIERARCHY_NONE;
389 cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
390 }
391
392 switch (cr_val) {
393 case DIB3000_FEC_1_2:
394 deb_getf("FEC_1_2 ");
395 *cr = FEC_1_2;
396 break;
397 case DIB3000_FEC_2_3:
398 deb_getf("FEC_2_3 ");
399 *cr = FEC_2_3;
400 break;
401 case DIB3000_FEC_3_4:
402 deb_getf("FEC_3_4 ");
403 *cr = FEC_3_4;
404 break;
405 case DIB3000_FEC_5_6:
406 deb_getf("FEC_5_6 ");
407 *cr = FEC_4_5;
408 break;
409 case DIB3000_FEC_7_8:
410 deb_getf("FEC_7_8 ");
411 *cr = FEC_7_8;
412 break;
413 default:
414 err("Unexpected FEC returned by TPS (%d)", tps_val);
415 break;
416 }
417
418 switch (DIB3000MC_TP_GUARD(tps_val)) {
419 case DIB3000_GUARD_TIME_1_32:
420 deb_getf("GUARD_INTERVAL_1_32 ");
421 ofdm->guard_interval = GUARD_INTERVAL_1_32;
422 break;
423 case DIB3000_GUARD_TIME_1_16:
424 deb_getf("GUARD_INTERVAL_1_16 ");
425 ofdm->guard_interval = GUARD_INTERVAL_1_16;
426 break;
427 case DIB3000_GUARD_TIME_1_8:
428 deb_getf("GUARD_INTERVAL_1_8 ");
429 ofdm->guard_interval = GUARD_INTERVAL_1_8;
430 break;
431 case DIB3000_GUARD_TIME_1_4:
432 deb_getf("GUARD_INTERVAL_1_4 ");
433 ofdm->guard_interval = GUARD_INTERVAL_1_4;
434 break;
435 default:
436 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
437 break;
438 }
439
440 switch (DIB3000MC_TP_FFT(tps_val)) {
441 case DIB3000_TRANSMISSION_MODE_2K:
442 deb_getf("TRANSMISSION_MODE_2K ");
443 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
444 break;
445 case DIB3000_TRANSMISSION_MODE_8K:
446 deb_getf("TRANSMISSION_MODE_8K ");
447 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
448 break;
449 default:
450 err("unexpected transmission mode return by TPS (%d)", tps_val);
451 break;
452 }
453 deb_getf("\n");
454
455 return 0;
456}
457
458static int dib3000mc_set_frontend(struct dvb_frontend* fe,
459 struct dvb_frontend_parameters *fep, int tuner)
460{
461 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
462 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
463 int search_state,auto_val;
464 u16 val;
465
466 if (tuner) { /* initial call from dvb */
467 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
468 state->config.pll_set(fe,fep,NULL);
469 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
470
471 state->last_tuned_freq = fep->frequency;
472 // if (!scanboost) {
473 dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
474 dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
475 state->last_tuned_bw = ofdm->bandwidth;
476
477 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
478 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
479 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
480
481 /* Default cfg isi offset adp */
482 wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
483
484 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
485 dib3000mc_set_adp_cfg(state,ofdm->constellation);
486 wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
487
488 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
489 /* power smoothing */
490 if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
491 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
492 } else {
493 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
494 }
495 auto_val = 0;
496 dib3000mc_set_general_cfg(state,fep,&auto_val);
497 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
498
499 val = rd(DIB3000MC_REG_DEMOD_PARM);
500 wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
501 wr(DIB3000MC_REG_DEMOD_PARM,val);
502 // }
503 msleep(70);
504
505 /* something has to be auto searched */
506 if (auto_val) {
507 int as_count=0;
508
509 deb_setf("autosearch enabled.\n");
510
511 val = rd(DIB3000MC_REG_DEMOD_PARM);
512 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
513 wr(DIB3000MC_REG_DEMOD_PARM,val);
514
515 while ((search_state = dib3000_search_status(
516 rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
517 msleep(10);
518
519 deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
520
521 if (search_state == 1) {
522 struct dvb_frontend_parameters feps;
523 if (dib3000mc_get_frontend(fe, &feps) == 0) {
524 deb_setf("reading tuning data from frontend succeeded.\n");
525 return dib3000mc_set_frontend(fe, &feps, 0);
526 }
527 }
528 } else {
529 dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
530 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
531 dib3000mc_set_adp_cfg(state,ofdm->constellation);
532
533 /* set_offset_cfg */
534 wr_foreach(dib3000mc_reg_offset,
535 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
536 }
537 } else { /* second call, after autosearch (fka: set_WithKnownParams) */
538// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
539
540 auto_val = 0;
541 dib3000mc_set_general_cfg(state,fep,&auto_val);
542 if (auto_val)
543 deb_info("auto_val is true, even though an auto search was already performed.\n");
544
545 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
546
547 val = rd(DIB3000MC_REG_DEMOD_PARM);
548 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
549 wr(DIB3000MC_REG_DEMOD_PARM,val);
550
551 msleep(30);
552
553 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
554 dib3000mc_set_adp_cfg(state,ofdm->constellation);
555 wr_foreach(dib3000mc_reg_offset,
556 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
557
558
559 }
560 return 0;
561}
562
563static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
564{
565 struct dib3000_state *state;
566
567 deb_info("init start\n");
568
569 state = fe->demodulator_priv;
570 state->timing_offset = 0;
571 state->timing_offset_comp_done = 0;
572
573 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
574 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
575 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
576 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
577 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
578 wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
579
580 wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
581 wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
582
583 wr(33,5);
584 wr(36,81);
585 wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
586
587 wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
588 wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
589
590 /* mobile mode - portable reception */
591 wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]);
592
593/* TUNER_PANASONIC_ENV57H12D5: */
594 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
595 wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
596 wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
597
598 wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
599 wr(26,0x6680);
600 wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
601 wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
602 wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
603 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
604
605 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
606 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
607
608 wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
609
610 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
611 wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
612
613 dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
614// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
615
616 wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
617 wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
618 wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
619
620 wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
621
622 dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
623
624/* output mode control, just the MPEG2_SLAVE */
625// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
626 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
627 wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
628 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
629 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
630
631/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
632 wr(DIB3000MC_REG_OUTMODE,
633 DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
634 rd(DIB3000MC_REG_OUTMODE)));
635
636 wr(DIB3000MC_REG_SMO_MODE,
637 DIB3000MC_SMO_MODE_DEFAULT |
638 DIB3000MC_SMO_MODE_188);
639
640 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
641 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
642*/
643
644/* diversity */
645 wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
646 wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
647
648 set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
649
650 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
651
652/* if (state->config->pll_init) {
653 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
654 state->config->pll_init(fe,NULL);
655 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
656 }*/
657 deb_info("init end\n");
658 return 0;
659}
660static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
661{
662 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
663 u16 lock = rd(DIB3000MC_REG_LOCKING);
664
665 *stat = 0;
666 if (DIB3000MC_AGC_LOCK(lock))
667 *stat |= FE_HAS_SIGNAL;
668 if (DIB3000MC_CARRIER_LOCK(lock))
669 *stat |= FE_HAS_CARRIER;
670 if (DIB3000MC_TPS_LOCK(lock))
671 *stat |= FE_HAS_VITERBI;
672 if (DIB3000MC_MPEG_SYNC_LOCK(lock))
673 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
674
675 deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040));
676
677 return 0;
678}
679
680static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber)
681{
682 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
683 *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB));
684 return 0;
685}
686
687static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
688{
689 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
690
691 *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
692 return 0;
693}
694
695/* see dib3000mb.c for calculation comments */
696static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
697{
698 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
699 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
700 *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
701
702 deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
703 return 0;
704}
705
706/* see dib3000mb.c for calculation comments */
707static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
708{
709 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
710 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
711 val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
712 u16 sig,noise;
713
714 sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
715 noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3);
716 if (noise == 0)
717 *snr = 0xffff;
718 else
719 *snr = (u16) sig/noise;
720
721 deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
722 deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
723 deb_stat("snr: %d\n",*snr);
724 return 0;
725}
726
727static int dib3000mc_sleep(struct dvb_frontend* fe)
728{
729 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
730
731 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN);
732 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN);
733 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN);
734 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN);
735 return 0;
736}
737
738static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
739{
740 tune->min_delay_ms = 2000;
741 tune->step_size = 166667;
742 tune->max_drift = 166667 * 2;
743
744 return 0;
745}
746
747static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe)
748{
749 return dib3000mc_fe_init(fe, 0);
750}
751
752static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
753{
754 return dib3000mc_set_frontend(fe, fep, 1);
755}
756
757static void dib3000mc_release(struct dvb_frontend* fe)
758{
759 struct dib3000_state *state = (struct dib3000_state *) fe->demodulator_priv;
760 kfree(state);
761}
762
763/* pid filter and transfer stuff */
764static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
765{
766 struct dib3000_state *state = fe->demodulator_priv;
767 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
768 wr(index+DIB3000MC_REG_FIRST_PID,pid);
769 return 0;
770}
771
772static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff)
773{
774 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
775 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
776
777 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
778
779 if (onoff) {
780 deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
781 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
782 } else {
783 deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
784 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
785 }
786 return 0;
787}
788
789static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
790{
791 struct dib3000_state *state = fe->demodulator_priv;
792 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
793
794 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
795
796 if (onoff) {
797 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
798 } else {
799 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
800 }
801 return 0;
802}
803
804static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
805{
806 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
807 if (onoff) {
808 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
809 } else {
810 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
811 }
812 return 0;
813}
814
815static int dib3000mc_demod_init(struct dib3000_state *state)
816{
817 u16 default_addr = 0x0a;
818 /* first init */
819 if (state->config.demod_address != default_addr) {
820 deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr);
821 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
822 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
823
824 wr(DIB3000MC_REG_RST_I2C_ADDR,
825 DIB3000MC_DEMOD_ADDR(default_addr) |
826 DIB3000MC_DEMOD_ADDR_ON);
827
828 state->config.demod_address = default_addr;
829
830 wr(DIB3000MC_REG_RST_I2C_ADDR,
831 DIB3000MC_DEMOD_ADDR(default_addr));
832 } else
833 deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
834 return 0;
835}
836
837
838static struct dvb_frontend_ops dib3000mc_ops;
839
840struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
841 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
842{
843 struct dib3000_state* state = NULL;
844 u16 devid;
845
846 /* allocate memory for the internal state */
847 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
848 if (state == NULL)
849 goto error;
850 memset(state,0,sizeof(struct dib3000_state));
851
852 /* setup the state */
853 state->i2c = i2c;
854 memcpy(&state->config,config,sizeof(struct dib3000_config));
855 memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
856
857 /* check for the correct demod */
858 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
859 goto error;
860
861 devid = rd(DIB3000_REG_DEVICE_ID);
862 if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID)
863 goto error;
864
865 switch (devid) {
866 case DIB3000MC_DEVICE_ID:
867 info("Found a DiBcom 3000M-C, interesting...");
868 break;
869 case DIB3000P_DEVICE_ID:
870 info("Found a DiBcom 3000P.");
871 break;
872 }
873
874 /* create dvb_frontend */
875 state->frontend.ops = &state->ops;
876 state->frontend.demodulator_priv = state;
877
878 /* set the xfer operations */
879 xfer_ops->pid_parse = dib3000mc_pid_parse;
880 xfer_ops->fifo_ctrl = dib3000mc_fifo_control;
881 xfer_ops->pid_ctrl = dib3000mc_pid_control;
882 xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl;
883
884 dib3000mc_demod_init(state);
885
886 return &state->frontend;
887
888error:
889 kfree(state);
890 return NULL;
891}
892
893static struct dvb_frontend_ops dib3000mc_ops = {
894
895 .info = {
896 .name = "DiBcom 3000P/M-C DVB-T",
897 .type = FE_OFDM,
898 .frequency_min = 44250000,
899 .frequency_max = 867250000,
900 .frequency_stepsize = 62500,
901 .caps = FE_CAN_INVERSION_AUTO |
902 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
903 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
904 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
905 FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_RECOVER |
908 FE_CAN_HIERARCHY_AUTO,
909 },
910
911 .release = dib3000mc_release,
912
913 .init = dib3000mc_fe_init_nonmobile,
914 .sleep = dib3000mc_sleep,
915
916 .set_frontend = dib3000mc_set_frontend_and_tuner,
917 .get_frontend = dib3000mc_get_frontend,
918 .get_tune_settings = dib3000mc_fe_get_tune_settings,
919
920 .read_status = dib3000mc_read_status,
921 .read_ber = dib3000mc_read_ber,
922 .read_signal_strength = dib3000mc_read_signal_strength,
923 .read_snr = dib3000mc_read_snr,
924 .read_ucblocks = dib3000mc_read_unc_blocks,
925};
926
927MODULE_AUTHOR(DRIVER_AUTHOR);
928MODULE_DESCRIPTION(DRIVER_DESC);
929MODULE_LICENSE("GPL");
930
931EXPORT_SYMBOL(dib3000mc_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
new file mode 100644
index 000000000000..2930aac7591b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc_priv.h
@@ -0,0 +1,428 @@
1/*
2 * dib3000mc_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mc.c .
11 */
12
13#ifndef __DIB3000MC_PRIV_H__
14#define __DIB3000MC_PRIV_H__
15
16/*
17 * Demodulator parameters
18 * reg: 0 1 1 1 11 11 111
19 * | | | | | |
20 * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4)
21 * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM)
22 * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4)
23 * | | +----------- transmission mode (0=2k, 1=8k)
24 * | |
25 * | +-------------- restart autosearch for parameters
26 * +---------------- restart the demodulator
27 * reg: 181 1 111 1
28 * | | |
29 * | | +- FEC applies for HP or LP (0=LP, 1=HP)
30 * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8)
31 * +------- hierarchy on (0=no, 1=yes)
32 */
33
34/* demodulator tuning parameter and restart options */
35#define DIB3000MC_REG_DEMOD_PARM ( 0)
36#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \
37 (0x7 & a) | \
38 ((0x3 & c) << 3) | \
39 ((0x3 & g) << 5) | \
40 ((0x1 & t) << 7) )
41#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8)
42#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8)
43#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9)
44#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9)
45
46/* register for hierarchy parameters */
47#define DIB3000MC_REG_HRCH_PARM ( 181)
48#define DIB3000MC_HRCH_PARM(s,f,h) ( \
49 (0x1 & s) | \
50 ((0x7 & f) << 1) | \
51 ((0x1 & h) << 4) )
52
53/* timeout ??? */
54#define DIB3000MC_REG_UNK_1 ( 1)
55#define DIB3000MC_UNK_1 ( 0x04)
56
57/* timeout ??? */
58#define DIB3000MC_REG_UNK_2 ( 2)
59#define DIB3000MC_UNK_2 ( 0x04)
60
61/* timeout ??? */
62#define DIB3000MC_REG_UNK_3 ( 3)
63#define DIB3000MC_UNK_3 (0x1000)
64
65#define DIB3000MC_REG_UNK_4 ( 4)
66#define DIB3000MC_UNK_4 (0x0814)
67
68/* timeout ??? */
69#define DIB3000MC_REG_SEQ_TPS ( 5)
70#define DIB3000MC_SEQ_TPS_DEFAULT ( 1)
71#define DIB3000MC_SEQ_TPS(s,t) ( \
72 ((s & 0x0f) << 4) | \
73 ((t & 0x01) << 8) )
74#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1)
75#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf)
76
77/* parameters for the bandwidth */
78#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6)
79#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7)
80
81static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 };
82
83/*static u16 dib3000mc_bandwidth_5mhz[] =
84 { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/
85
86static u16 dib3000mc_bandwidth_6mhz[] =
87 { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 };
88
89static u16 dib3000mc_bandwidth_7mhz[] =
90 { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
91
92static u16 dib3000mc_bandwidth_8mhz[] =
93 { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
94
95static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
96static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
97
98/* lock mask */
99#define DIB3000MC_REG_LOCK_MASK ( 15)
100#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800)
101
102/* reset the uncorrected packet count (??? do it 5 times) */
103#define DIB3000MC_REG_RST_UNC ( 18)
104#define DIB3000MC_RST_UNC_ON ( 1)
105#define DIB3000MC_RST_UNC_OFF ( 0)
106
107#define DIB3000MC_REG_UNK_19 ( 19)
108#define DIB3000MC_UNK_19 ( 0)
109
110/* DDS frequency value (IF position) and inversion bit */
111#define DIB3000MC_REG_INVERSION ( 21)
112#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21)
113#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164)
114#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364)
115
116#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22)
117#define DIB3000MC_DDS_FREQ_LSB (0x463d)
118
119/* timing frequencies setting */
120#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23)
121#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24)
122#define DIB3000MC_CLOCK_REF (0x151fd1)
123
124//static u16 dib3000mc_reg_timing_freq[] = { 23,24 };
125
126//static u16 dib3000mc_timing_freq[][2] = {
127// { 0x69, 0x9f18 }, /* 5 MHz */
128// { 0x7e ,0xbee9 }, /* 6 MHz */
129// { 0x93 ,0xdebb }, /* 7 MHz */
130// { 0xa8 ,0xfe8c }, /* 8 MHz */
131//};
132
133/* timeout ??? */
134static u16 dib3000mc_reg_offset[] = { 26,33 };
135
136static u16 dib3000mc_offset[][2] = {
137 { 26240, 5 }, /* default */
138 { 30336, 6 }, /* 8K */
139 { 38528, 8 }, /* 2K */
140};
141
142#define DIB3000MC_REG_ISI ( 29)
143#define DIB3000MC_ISI_DEFAULT (0x1073)
144#define DIB3000MC_ISI_ACTIVATE (0x0000)
145#define DIB3000MC_ISI_INHIBIT (0x0200)
146
147/* impulse noise control */
148static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
149
150static u16 dib3000mc_imp_noise_ctl[][2] = {
151 { 0x1294, 0x1ff8 }, /* mode 0 */
152 { 0x1294, 0x1ff8 }, /* mode 1 */
153 { 0x1294, 0x1ff8 }, /* mode 2 */
154 { 0x1294, 0x1ff8 }, /* mode 3 */
155 { 0x1294, 0x1ff8 }, /* mode 4 */
156};
157
158/* AGC registers */
159static u16 dib3000mc_reg_agc[] = {
160 36,37,38,39,42,43,44,45,46,47,48,49
161};
162
163static u16 dib3000mc_agc_tuner[][12] = {
164 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666,
165 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019
166 }, /* TUNER_PANASONIC_ENV77H04D5, */
167
168 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a,
169 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e
170 }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */
171
172 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff,
173 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040
174 }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */
175
176 { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29,
177 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537
178 }, /* TUNER_PROVIDER_X */
179 /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */
180};
181
182/* AGC loop bandwidth */
183static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 };
184static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 };
185
186static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 };
187static u16 dib3000mc_agc_bandwidth_general[] =
188 { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 };
189
190#define DIB3000MC_REG_IMP_NOISE_55 ( 55)
191#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10))
192
193/* Impulse noise params */
194static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 };
195static u16 dib3000mc_impluse_noise[][3] = {
196 { 0x489, 0x89, 0x72 }, /* 5 MHz */
197 { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */
198 { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */
199 { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */
200};
201
202static u16 dib3000mc_reg_fft[] = {
203 58,59,60,61,62,63,64,65,66,67,68,69,
204 70,71,72,73,74,75,76,77,78,79,80,81,
205 82,83,84,85,86
206};
207
208static u16 dib3000mc_fft_modes[][29] = {
209 { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
210 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
211 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
212 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
213 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd
214 }, /* fft mode 0 */
215 { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
216 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
217 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
218 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
219 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd
220 }, /* fft mode 1 */
221};
222
223#define DIB3000MC_REG_UNK_88 ( 88)
224#define DIB3000MC_UNK_88 (0x0410)
225
226static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 };
227static u16 dib3000mc_bw[][6] = {
228 { 0,0,0,0,0,0 }, /* 5 MHz */
229 { 0,0,0,0,0,0 }, /* 6 MHz */
230 { 0,0,0,0,0,0 }, /* 7 MHz */
231 { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */
232};
233
234
235/* phase noise control */
236#define DIB3000MC_REG_UNK_99 ( 99)
237#define DIB3000MC_UNK_99 (0x0220)
238
239#define DIB3000MC_REG_SCAN_BOOST ( 100)
240#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6)
241#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9)
242
243/* timeout ??? */
244#define DIB3000MC_REG_UNK_110 ( 110)
245#define DIB3000MC_UNK_110 ( 3277)
246
247#define DIB3000MC_REG_UNK_111 ( 111)
248#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0)
249#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1)
250
251/* superious rm config */
252#define DIB3000MC_REG_UNK_120 ( 120)
253#define DIB3000MC_UNK_120 ( 8207)
254
255#define DIB3000MC_REG_UNK_133 ( 133)
256#define DIB3000MC_UNK_133 ( 15564)
257
258#define DIB3000MC_REG_UNK_134 ( 134)
259#define DIB3000MC_UNK_134 ( 0)
260
261/* adapter config for constellation */
262static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 };
263
264static u16 dib3000mc_adp_cfg[][4] = {
265 { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */
266 { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */
267 { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */
268};
269
270static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 };
271
272static u16 dib3000mc_mobile_mode[][5] = {
273 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */
274 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */
275 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */
276 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */
277};
278
279#define DIB3000MC_REG_DIVERSITY1 ( 177)
280#define DIB3000MC_DIVERSITY1_DEFAULT ( 1)
281
282#define DIB3000MC_REG_DIVERSITY2 ( 178)
283#define DIB3000MC_DIVERSITY2_DEFAULT ( 1)
284
285#define DIB3000MC_REG_DIVERSITY3 ( 180)
286#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0)
287#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6)
288
289#define DIB3000MC_REG_FEC_CFG ( 195)
290#define DIB3000MC_FEC_CFG ( 0x10)
291
292/*
293 * reg 206, output mode
294 * 1111 1111
295 * |||| ||||
296 * |||| |||+- unk
297 * |||| ||+-- unk
298 * |||| |+--- unk (on by default)
299 * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
300 * |||+------ pid_parse (1 = enabled, 0 = disabled)
301 * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204)
302 * |+-------- unk
303 * +--------- unk
304 */
305
306#define DIB3000MC_REG_SMO_MODE ( 206)
307#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2)
308#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3)
309#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7)
310#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4)
311#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef)
312#define DIB3000MC_SMO_MODE_188 (1 << 5)
313#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \
314 DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
315
316#define DIB3000MC_REG_FIFO_THRESHOLD ( 207)
317#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792)
318#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512)
319/*
320 * pidfilter
321 * it is not a hardware pidfilter but a filter which drops all pids
322 * except the ones set. When connected to USB1.1 bandwidth this is important.
323 * DiB3000P/M-C can filter up to 32 PIDs
324 */
325#define DIB3000MC_REG_FIRST_PID ( 212)
326#define DIB3000MC_NUM_PIDS ( 32)
327
328#define DIB3000MC_REG_OUTMODE ( 244)
329#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0)
330#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11)
331#define DIB3000MC_OM_SERIAL (2 << 11)
332#define DIB3000MC_OM_DIVOUT_ON (4 << 11)
333#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK)
334
335#define DIB3000MC_REG_RF_POWER ( 392)
336
337#define DIB3000MC_REG_FFT_POSITION ( 407)
338
339#define DIB3000MC_REG_DDS_FREQ_MSB ( 414)
340#define DIB3000MC_REG_DDS_FREQ_LSB ( 415)
341
342#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416)
343#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417)
344
345#define DIB3000MC_REG_TUNING_PARM ( 458)
346#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03)
347#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01)
348#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07)
349#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01)
350#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07)
351#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07)
352#define DIB3000MC_TP_GUARD(v) (v & 0x03)
353
354#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483)
355#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484)
356
357#define DIB3000MC_REG_MER ( 485)
358
359#define DIB3000MC_REG_BER_MSB ( 500)
360#define DIB3000MC_REG_BER_LSB ( 501)
361
362#define DIB3000MC_REG_PACKET_ERRORS ( 503)
363
364#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506)
365
366#define DIB3000MC_REG_LOCK_507 ( 507)
367#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ?
368
369#define DIB3000MC_REG_LOCKING ( 509)
370#define DIB3000MC_AGC_LOCK(v) (v & 0x8000)
371#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000)
372#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080)
373#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040)
374#define DIB3000MC_TPS_LOCK(v) (v & 0x0004)
375
376#define DIB3000MC_REG_AS_IRQ ( 511)
377#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1)
378#define DIB3000MC_AS_IRQ_FAIL ( 1)
379
380#define DIB3000MC_REG_TUNER ( 769)
381
382#define DIB3000MC_REG_RST_I2C_ADDR ( 1024)
383#define DIB3000MC_DEMOD_ADDR_ON ( 1)
384#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0)
385
386#define DIB3000MC_REG_RESTART ( 1027)
387#define DIB3000MC_RESTART_OFF (0x0000)
388#define DIB3000MC_RESTART_AGC (0x0800)
389#define DIB3000MC_RESTART_CONFIG (0x8000)
390
391#define DIB3000MC_REG_RESTART_VIT ( 1028)
392#define DIB3000MC_RESTART_VIT_OFF ( 0)
393#define DIB3000MC_RESTART_VIT_ON ( 1)
394
395#define DIB3000MC_REG_CLK_CFG_1 ( 1031)
396#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0)
397#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff)
398
399#define DIB3000MC_REG_CLK_CFG_2 ( 1032)
400#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c)
401#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104)
402#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000)
403#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff)
404
405#define DIB3000MC_REG_CLK_CFG_3 ( 1033)
406#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0)
407#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5)
408
409#define DIB3000MC_REG_CLK_CFG_7 ( 1037)
410#define DIB3000MC_CLK_CFG_7_INIT ( 12592)
411#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003)
412#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003)
413#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8)
414
415/* was commented out ??? */
416#define DIB3000MC_REG_CLK_CFG_8 ( 1038)
417#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c)
418
419#define DIB3000MC_REG_CLK_CFG_9 ( 1039)
420#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0)
421
422/* also clock ??? */
423#define DIB3000MC_REG_ELEC_OUT ( 1040)
424#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0)
425#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1)
426#define DIB3000MC_ELEC_OUT_SLAVE ( 3)
427
428#endif
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
new file mode 100644
index 000000000000..2a3c2ce7b2aa
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -0,0 +1,168 @@
1/*
2 * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
3 *
4 * descriptions + helper functions for simple dvb plls.
5 *
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "dvb-pll.h"
28
29/* ----------------------------------------------------------- */
30/* descriptions */
31
32struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
33 .name = "Thomson dtt7579",
34 .min = 177000000,
35 .max = 858000000,
36 .count = 5,
37 .entries = {
38 { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */
39 { 443250000, 36166667, 166666, 0xb4, 0x02 },
40 { 542000000, 36166667, 166666, 0xb4, 0x08 },
41 { 771000000, 36166667, 166666, 0xbc, 0x08 },
42 { 999999999, 36166667, 166666, 0xf4, 0x08 },
43 },
44};
45EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
46
47struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
48 .name = "Thomson dtt7610",
49 .min = 44000000,
50 .max = 958000000,
51 .count = 3,
52 .entries = {
53 { 157250000, 44000000, 62500, 0x8e, 0x39 },
54 { 454000000, 44000000, 62500, 0x8e, 0x3a },
55 { 999999999, 44000000, 62500, 0x8e, 0x3c },
56 },
57};
58EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
59
60static void thomson_dtt759x_bw(u8 *buf, int bandwidth)
61{
62 if (BANDWIDTH_7_MHZ == bandwidth)
63 buf[3] |= 0x10;
64}
65
66struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
67 .name = "Thomson dtt759x",
68 .min = 177000000,
69 .max = 896000000,
70 .setbw = thomson_dtt759x_bw,
71 .count = 6,
72 .entries = {
73 { 0, 36166667, 166666, 0x84, 0x03 },
74 { 264000000, 36166667, 166666, 0xb4, 0x02 },
75 { 470000000, 36166667, 166666, 0xbc, 0x02 },
76 { 735000000, 36166667, 166666, 0xbc, 0x08 },
77 { 835000000, 36166667, 166666, 0xf4, 0x08 },
78 { 999999999, 36166667, 166666, 0xfc, 0x08 },
79 },
80};
81EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
82
83struct dvb_pll_desc dvb_pll_lg_z201 = {
84 .name = "LG z201",
85 .min = 174000000,
86 .max = 862000000,
87 .count = 5,
88 .entries = {
89 { 0, 36166667, 166666, 0xbc, 0x03 },
90 { 443250000, 36166667, 166666, 0xbc, 0x01 },
91 { 542000000, 36166667, 166666, 0xbc, 0x02 },
92 { 830000000, 36166667, 166666, 0xf4, 0x02 },
93 { 999999999, 36166667, 166666, 0xfc, 0x02 },
94 },
95};
96EXPORT_SYMBOL(dvb_pll_lg_z201);
97
98struct dvb_pll_desc dvb_pll_unknown_1 = {
99 .name = "unknown 1", /* used by dntv live dvb-t */
100 .min = 174000000,
101 .max = 862000000,
102 .count = 9,
103 .entries = {
104 { 150000000, 36166667, 166666, 0xb4, 0x01 },
105 { 173000000, 36166667, 166666, 0xbc, 0x01 },
106 { 250000000, 36166667, 166666, 0xb4, 0x02 },
107 { 400000000, 36166667, 166666, 0xbc, 0x02 },
108 { 420000000, 36166667, 166666, 0xf4, 0x02 },
109 { 470000000, 36166667, 166666, 0xfc, 0x02 },
110 { 600000000, 36166667, 166666, 0xbc, 0x08 },
111 { 730000000, 36166667, 166666, 0xf4, 0x08 },
112 { 999999999, 36166667, 166666, 0xfc, 0x08 },
113 },
114};
115EXPORT_SYMBOL(dvb_pll_unknown_1);
116
117/* ----------------------------------------------------------- */
118/* code */
119
120static int debug = 0;
121module_param(debug, int, 0644);
122MODULE_PARM_DESC(debug, "enable verbose debug messages");
123
124int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
125 u32 freq, int bandwidth)
126{
127 u32 div;
128 int i;
129
130 if (freq != 0 && (freq < desc->min || freq > desc->max))
131 return -EINVAL;
132
133 for (i = 0; i < desc->count; i++) {
134 if (freq > desc->entries[i].limit)
135 continue;
136 break;
137 }
138 if (debug)
139 printk("pll: %s: freq=%d bw=%d | i=%d/%d\n",
140 desc->name, freq, bandwidth, i, desc->count);
141 BUG_ON(i == desc->count);
142
143 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
144 buf[0] = div >> 8;
145 buf[1] = div & 0xff;
146 buf[2] = desc->entries[i].cb1;
147 buf[3] = desc->entries[i].cb2;
148
149 if (desc->setbw)
150 desc->setbw(buf, bandwidth);
151
152 if (debug)
153 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
154 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
155
156 return 0;
157}
158EXPORT_SYMBOL(dvb_pll_configure);
159
160MODULE_DESCRIPTION("dvb pll library");
161MODULE_AUTHOR("Gerd Knorr");
162MODULE_LICENSE("GPL");
163
164/*
165 * Local variables:
166 * c-basic-offset: 8
167 * End:
168 */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
new file mode 100644
index 000000000000..016c794a5677
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -0,0 +1,34 @@
1/*
2 * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
3 */
4
5struct dvb_pll_desc {
6 char *name;
7 u32 min;
8 u32 max;
9 void (*setbw)(u8 *buf, int bandwidth);
10 int count;
11 struct {
12 u32 limit;
13 u32 offset;
14 u32 stepsize;
15 u8 cb1;
16 u8 cb2;
17 } entries[9];
18};
19
20extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
21extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
22extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
23extern struct dvb_pll_desc dvb_pll_lg_z201;
24extern struct dvb_pll_desc dvb_pll_unknown_1;
25
26int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
27 u32 freq, int bandwidth);
28
29/*
30 * Local variables:
31 * c-basic-offset: 8
32 * compile-command: "make DVB=1"
33 * End:
34 */
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
new file mode 100644
index 000000000000..c05a9b05600c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -0,0 +1,279 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25
26#include "dvb_frontend.h"
27#include "dvb_dummy_fe.h"
28
29
30struct dvb_dummy_fe_state {
31 struct dvb_frontend_ops ops;
32 struct dvb_frontend frontend;
33};
34
35
36static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
37{
38 *status = FE_HAS_SIGNAL
39 | FE_HAS_CARRIER
40 | FE_HAS_VITERBI
41 | FE_HAS_SYNC
42 | FE_HAS_LOCK;
43
44 return 0;
45}
46
47static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
48{
49 *ber = 0;
50 return 0;
51}
52
53static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
54{
55 *strength = 0;
56 return 0;
57}
58
59static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
60{
61 *snr = 0;
62 return 0;
63}
64
65static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
66{
67 *ucblocks = 0;
68 return 0;
69}
70
71static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
72{
73 return 0;
74}
75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{
78 return 0;
79}
80
81static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
82{
83 return 0;
84}
85
86static int dvb_dummy_fe_init(struct dvb_frontend* fe)
87{
88 return 0;
89}
90
91static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
92{
93 return 0;
94}
95
96static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
97{
98 return 0;
99}
100
101static void dvb_dummy_fe_release(struct dvb_frontend* fe)
102{
103 struct dvb_dummy_fe_state* state = (struct dvb_dummy_fe_state*) fe->demodulator_priv;
104 kfree(state);
105}
106
107static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
108
109struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
110{
111 struct dvb_dummy_fe_state* state = NULL;
112
113 /* allocate memory for the internal state */
114 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
115 if (state == NULL) goto error;
116
117 /* setup the state */
118 memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
119
120 /* create dvb_frontend */
121 state->frontend.ops = &state->ops;
122 state->frontend.demodulator_priv = state;
123 return &state->frontend;
124
125error:
126 kfree(state);
127 return NULL;
128}
129
130static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
131
132struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
133{
134 struct dvb_dummy_fe_state* state = NULL;
135
136 /* allocate memory for the internal state */
137 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
138 if (state == NULL) goto error;
139
140 /* setup the state */
141 memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
142
143 /* create dvb_frontend */
144 state->frontend.ops = &state->ops;
145 state->frontend.demodulator_priv = state;
146 return &state->frontend;
147
148error:
149 if (state) kfree(state);
150 return NULL;
151}
152
153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
154
155struct dvb_frontend* dvb_dummy_fe_qam_attach()
156{
157 struct dvb_dummy_fe_state* state = NULL;
158
159 /* allocate memory for the internal state */
160 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
161 if (state == NULL) goto error;
162
163 /* setup the state */
164 memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
165
166 /* create dvb_frontend */
167 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state;
169 return &state->frontend;
170
171error:
172 if (state) kfree(state);
173 return NULL;
174}
175
176static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
177
178 .info = {
179 .name = "Dummy DVB-T",
180 .type = FE_OFDM,
181 .frequency_min = 0,
182 .frequency_max = 863250000,
183 .frequency_stepsize = 62500,
184 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
185 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
186 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
187 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
188 FE_CAN_TRANSMISSION_MODE_AUTO |
189 FE_CAN_GUARD_INTERVAL_AUTO |
190 FE_CAN_HIERARCHY_AUTO,
191 },
192
193 .release = dvb_dummy_fe_release,
194
195 .init = dvb_dummy_fe_init,
196 .sleep = dvb_dummy_fe_sleep,
197
198 .set_frontend = dvb_dummy_fe_set_frontend,
199 .get_frontend = dvb_dummy_fe_get_frontend,
200
201 .read_status = dvb_dummy_fe_read_status,
202 .read_ber = dvb_dummy_fe_read_ber,
203 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
204 .read_snr = dvb_dummy_fe_read_snr,
205 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
206};
207
208static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
209
210 .info = {
211 .name = "Dummy DVB-C",
212 .type = FE_QAM,
213 .frequency_stepsize = 62500,
214 .frequency_min = 51000000,
215 .frequency_max = 858000000,
216 .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */
217 .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */
218 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
219 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
220 FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
221 },
222
223 .release = dvb_dummy_fe_release,
224
225 .init = dvb_dummy_fe_init,
226 .sleep = dvb_dummy_fe_sleep,
227
228 .set_frontend = dvb_dummy_fe_set_frontend,
229 .get_frontend = dvb_dummy_fe_get_frontend,
230
231 .read_status = dvb_dummy_fe_read_status,
232 .read_ber = dvb_dummy_fe_read_ber,
233 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
234 .read_snr = dvb_dummy_fe_read_snr,
235 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
236};
237
238static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
239
240 .info = {
241 .name = "Dummy DVB-S",
242 .type = FE_QPSK,
243 .frequency_min = 950000,
244 .frequency_max = 2150000,
245 .frequency_stepsize = 250, /* kHz for QPSK frontends */
246 .frequency_tolerance = 29500,
247 .symbol_rate_min = 1000000,
248 .symbol_rate_max = 45000000,
249 .caps = FE_CAN_INVERSION_AUTO |
250 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
251 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
252 FE_CAN_QPSK
253 },
254
255 .release = dvb_dummy_fe_release,
256
257 .init = dvb_dummy_fe_init,
258 .sleep = dvb_dummy_fe_sleep,
259
260 .set_frontend = dvb_dummy_fe_set_frontend,
261 .get_frontend = dvb_dummy_fe_get_frontend,
262
263 .read_status = dvb_dummy_fe_read_status,
264 .read_ber = dvb_dummy_fe_read_ber,
265 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
266 .read_snr = dvb_dummy_fe_read_snr,
267 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
268
269 .set_voltage = dvb_dummy_fe_set_voltage,
270 .set_tone = dvb_dummy_fe_set_tone,
271};
272
273MODULE_DESCRIPTION("DVB DUMMY Frontend");
274MODULE_AUTHOR("Emard");
275MODULE_LICENSE("GPL");
276
277EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
278EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
279EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
new file mode 100644
index 000000000000..8210f19d56ce
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -0,0 +1,32 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef DVB_DUMMY_FE_H
23#define DVB_DUMMY_FE_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
29extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
30extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
31
32#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
new file mode 100644
index 000000000000..9ac95de9834d
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -0,0 +1,602 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
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/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "l64781.h"
31
32
33struct l64781_state {
34 struct i2c_adapter* i2c;
35 struct dvb_frontend_ops ops;
36 const struct l64781_config* config;
37 struct dvb_frontend frontend;
38
39 /* private demodulator data */
40 int first:1;
41};
42
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "l64781: " args); \
46 } while (0)
47
48static int debug;
49
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
52
53
54static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
55{
56 int ret;
57 u8 buf [] = { reg, data };
58 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
59
60 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
61 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
62 __FUNCTION__, reg, ret);
63
64 return (ret != 1) ? -1 : 0;
65}
66
67static int l64781_readreg (struct l64781_state* state, u8 reg)
68{
69 int ret;
70 u8 b0 [] = { reg };
71 u8 b1 [] = { 0 };
72 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
73 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) return ret;
78
79 return b1[0];
80}
81
82static void apply_tps (struct l64781_state* state)
83{
84 l64781_writereg (state, 0x2a, 0x00);
85 l64781_writereg (state, 0x2a, 0x01);
86
87 /* This here is a little bit questionable because it enables
88 the automatic update of TPS registers. I think we'd need to
89 handle the IRQ from FE to update some other registers as
90 well, or at least implement some magic to tuning to correct
91 to the TPS received from transmission. */
92 l64781_writereg (state, 0x2a, 0x02);
93}
94
95
96static void reset_afc (struct l64781_state* state)
97{
98 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
99 timing offset */
100 l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
101 l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */
102 l64781_writereg (state, 0x09, 0);
103 l64781_writereg (state, 0x0a, 0);
104 l64781_writereg (state, 0x07, 0x8e);
105 l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */
106 l64781_writereg (state, 0x11, 0x80); /* stall TIM */
107 l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */
108 l64781_writereg (state, 0x12, 0);
109 l64781_writereg (state, 0x13, 0);
110 l64781_writereg (state, 0x11, 0x00);
111}
112
113static int reset_and_configure (struct l64781_state* state)
114{
115 u8 buf [] = { 0x06 };
116 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
117 // NOTE: this is correct in writing to address 0x00
118
119 return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
120}
121
122static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
123{
124 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
125 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
126 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
127 /* QPSK, QAM_16, QAM_64 */
128 static const u8 qam_tab [] = { 2, 4, 0, 6 };
129 static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */
130 static const u8 guard_tab [] = { 1, 2, 4, 8 };
131 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
132 static const u32 ppm = 8000;
133 struct dvb_ofdm_parameters *p = &param->u.ofdm;
134 u32 ddfs_offset_fixed;
135/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
136/* bw_tab[p->bandWidth]<<10)/15625; */
137 u32 init_freq;
138 u32 spi_bias;
139 u8 val0x04;
140 u8 val0x05;
141 u8 val0x06;
142 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
143
144 state->config->pll_set(fe, param);
145
146 if (param->inversion != INVERSION_ON &&
147 param->inversion != INVERSION_OFF)
148 return -EINVAL;
149
150 if (bw < 0 || bw > 2)
151 return -EINVAL;
152
153 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
154 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
155 p->code_rate_HP != FEC_7_8)
156 return -EINVAL;
157
158 if (p->hierarchy_information != HIERARCHY_NONE &&
159 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
160 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
161 p->code_rate_LP != FEC_7_8))
162 return -EINVAL;
163
164 if (p->constellation != QPSK && p->constellation != QAM_16 &&
165 p->constellation != QAM_64)
166 return -EINVAL;
167
168 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
169 p->transmission_mode != TRANSMISSION_MODE_8K)
170 return -EINVAL;
171
172 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
173 p->guard_interval > GUARD_INTERVAL_1_4)
174 return -EINVAL;
175
176 if (p->hierarchy_information < HIERARCHY_NONE ||
177 p->hierarchy_information > HIERARCHY_4)
178 return -EINVAL;
179
180 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000;
181
182 /* This works up to 20000 ppm, it overflows if too large ppm! */
183 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
184 bw_tab[p->bandwidth] & 0xFFFFFF);
185
186 /* SPI bias calculation is slightly modified to fit in 32bit */
187 /* will work for high ppm only... */
188 spi_bias = 378 * (1 << 10);
189 spi_bias *= 16;
190 spi_bias *= bw_tab[p->bandwidth];
191 spi_bias *= qam_tab[p->constellation];
192 spi_bias /= p->code_rate_HP + 1;
193 spi_bias /= (guard_tab[p->guard_interval] + 32);
194 spi_bias *= 1000ULL;
195 spi_bias /= 1000ULL + ppm/1000;
196 spi_bias *= p->code_rate_HP;
197
198 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
199 val0x05 = fec_tab[p->code_rate_HP];
200
201 if (p->hierarchy_information != HIERARCHY_NONE)
202 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
203
204 val0x06 = (p->hierarchy_information << 2) | p->constellation;
205
206 l64781_writereg (state, 0x04, val0x04);
207 l64781_writereg (state, 0x05, val0x05);
208 l64781_writereg (state, 0x06, val0x06);
209
210 reset_afc (state);
211
212 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
213 l64781_writereg (state, 0x15,
214 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
215 l64781_writereg (state, 0x16, init_freq & 0xff);
216 l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
217 l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
218
219 l64781_writereg (state, 0x1b, spi_bias & 0xff);
220 l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
221 l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
222 (param->inversion == INVERSION_ON ? 0x80 : 0x00));
223
224 l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
225 l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
226
227 l64781_readreg (state, 0x00); /* clear interrupt registers... */
228 l64781_readreg (state, 0x01); /* dto. */
229
230 apply_tps (state);
231
232 return 0;
233}
234
235static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param)
236{
237 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
238 int tmp;
239
240
241 tmp = l64781_readreg(state, 0x04);
242 switch(tmp & 3) {
243 case 0:
244 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
245 break;
246 case 1:
247 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
248 break;
249 case 2:
250 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
251 break;
252 case 3:
253 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
254 break;
255 }
256 switch((tmp >> 2) & 3) {
257 case 0:
258 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
259 break;
260 case 1:
261 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
262 break;
263 default:
264 printk("Unexpected value for transmission_mode\n");
265 }
266
267
268
269 tmp = l64781_readreg(state, 0x05);
270 switch(tmp & 7) {
271 case 0:
272 param->u.ofdm.code_rate_HP = FEC_1_2;
273 break;
274 case 1:
275 param->u.ofdm.code_rate_HP = FEC_2_3;
276 break;
277 case 2:
278 param->u.ofdm.code_rate_HP = FEC_3_4;
279 break;
280 case 3:
281 param->u.ofdm.code_rate_HP = FEC_5_6;
282 break;
283 case 4:
284 param->u.ofdm.code_rate_HP = FEC_7_8;
285 break;
286 default:
287 printk("Unexpected value for code_rate_HP\n");
288 }
289 switch((tmp >> 3) & 7) {
290 case 0:
291 param->u.ofdm.code_rate_LP = FEC_1_2;
292 break;
293 case 1:
294 param->u.ofdm.code_rate_LP = FEC_2_3;
295 break;
296 case 2:
297 param->u.ofdm.code_rate_LP = FEC_3_4;
298 break;
299 case 3:
300 param->u.ofdm.code_rate_LP = FEC_5_6;
301 break;
302 case 4:
303 param->u.ofdm.code_rate_LP = FEC_7_8;
304 break;
305 default:
306 printk("Unexpected value for code_rate_LP\n");
307 }
308
309
310 tmp = l64781_readreg(state, 0x06);
311 switch(tmp & 3) {
312 case 0:
313 param->u.ofdm.constellation = QPSK;
314 break;
315 case 1:
316 param->u.ofdm.constellation = QAM_16;
317 break;
318 case 2:
319 param->u.ofdm.constellation = QAM_64;
320 break;
321 default:
322 printk("Unexpected value for constellation\n");
323 }
324 switch((tmp >> 2) & 7) {
325 case 0:
326 param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
327 break;
328 case 1:
329 param->u.ofdm.hierarchy_information = HIERARCHY_1;
330 break;
331 case 2:
332 param->u.ofdm.hierarchy_information = HIERARCHY_2;
333 break;
334 case 3:
335 param->u.ofdm.hierarchy_information = HIERARCHY_4;
336 break;
337 default:
338 printk("Unexpected value for hierarchy\n");
339 }
340
341
342 tmp = l64781_readreg (state, 0x1d);
343 param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
344
345 tmp = (int) (l64781_readreg (state, 0x08) |
346 (l64781_readreg (state, 0x09) << 8) |
347 (l64781_readreg (state, 0x0a) << 16));
348 param->frequency += tmp;
349
350 return 0;
351}
352
353static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
354{
355 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
356 int sync = l64781_readreg (state, 0x32);
357 int gain = l64781_readreg (state, 0x0e);
358
359 l64781_readreg (state, 0x00); /* clear interrupt registers... */
360 l64781_readreg (state, 0x01); /* dto. */
361
362 *status = 0;
363
364 if (gain > 5)
365 *status |= FE_HAS_SIGNAL;
366
367 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
368 *status |= FE_HAS_CARRIER;
369
370 if (sync & 0x20)
371 *status |= FE_HAS_VITERBI;
372
373 if (sync & 0x40)
374 *status |= FE_HAS_SYNC;
375
376 if (sync == 0x7f)
377 *status |= FE_HAS_LOCK;
378
379 return 0;
380}
381
382static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
383{
384 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
385
386 /* XXX FIXME: set up counting period (reg 0x26...0x28)
387 */
388 *ber = l64781_readreg (state, 0x39)
389 | (l64781_readreg (state, 0x3a) << 8);
390
391 return 0;
392}
393
394static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
397
398 u8 gain = l64781_readreg (state, 0x0e);
399 *signal_strength = (gain << 8) | gain;
400
401 return 0;
402}
403
404static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
405{
406 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
407
408 u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
409 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
410
411 return 0;
412}
413
414static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
415{
416 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
417
418 *ucblocks = l64781_readreg (state, 0x37)
419 | (l64781_readreg (state, 0x38) << 8);
420
421 return 0;
422}
423
424static int l64781_sleep(struct dvb_frontend* fe)
425{
426 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
427
428 /* Power down */
429 return l64781_writereg (state, 0x3e, 0x5a);
430}
431
432static int l64781_init(struct dvb_frontend* fe)
433{
434 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
435
436 reset_and_configure (state);
437
438 /* Power up */
439 l64781_writereg (state, 0x3e, 0xa5);
440
441 /* Reset hard */
442 l64781_writereg (state, 0x2a, 0x04);
443 l64781_writereg (state, 0x2a, 0x00);
444
445 /* Set tuner specific things */
446 /* AFC_POL, set also in reset_afc */
447 l64781_writereg (state, 0x07, 0x8e);
448
449 /* Use internal ADC */
450 l64781_writereg (state, 0x0b, 0x81);
451
452 /* AGC loop gain, and polarity is positive */
453 l64781_writereg (state, 0x0c, 0x84);
454
455 /* Internal ADC outputs two's complement */
456 l64781_writereg (state, 0x0d, 0x8c);
457
458 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
459 value of 2 with all possible bandwidths and guard
460 intervals, which is the initial value anyway. */
461 /*l64781_writereg (state, 0x19, 0x92);*/
462
463 /* Everything is two's complement, soft bit and CSI_OUT too */
464 l64781_writereg (state, 0x1e, 0x09);
465
466 if (state->config->pll_init) state->config->pll_init(fe);
467
468 /* delay a bit after first init attempt */
469 if (state->first) {
470 state->first = 0;
471 msleep(200);
472 }
473
474 return 0;
475}
476
477static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
478{
479 fesettings->min_delay_ms = 200;
480 fesettings->step_size = 166667;
481 fesettings->max_drift = 166667*2;
482 return 0;
483}
484
485static void l64781_release(struct dvb_frontend* fe)
486{
487 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
488 kfree(state);
489}
490
491static struct dvb_frontend_ops l64781_ops;
492
493struct dvb_frontend* l64781_attach(const struct l64781_config* config,
494 struct i2c_adapter* i2c)
495{
496 struct l64781_state* state = NULL;
497 int reg0x3e = -1;
498 u8 b0 [] = { 0x1a };
499 u8 b1 [] = { 0x00 };
500 struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
501 { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
502
503 /* allocate memory for the internal state */
504 state = (struct l64781_state*) kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
505 if (state == NULL) goto error;
506
507 /* setup the state */
508 state->config = config;
509 state->i2c = i2c;
510 memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
511 state->first = 1;
512
513 /**
514 * the L64781 won't show up before we send the reset_and_configure()
515 * broadcast. If nothing responds there is no L64781 on the bus...
516 */
517 if (reset_and_configure(state) < 0) {
518 dprintk("No response to reset and configure broadcast...\n");
519 goto error;
520 }
521
522 /* The chip always responds to reads */
523 if (i2c_transfer(state->i2c, msg, 2) != 2) {
524 dprintk("No response to read on I2C bus\n");
525 goto error;
526 }
527
528 /* Save current register contents for bailout */
529 reg0x3e = l64781_readreg(state, 0x3e);
530
531 /* Reading the POWER_DOWN register always returns 0 */
532 if (reg0x3e != 0) {
533 dprintk("Device doesn't look like L64781\n");
534 goto error;
535 }
536
537 /* Turn the chip off */
538 l64781_writereg (state, 0x3e, 0x5a);
539
540 /* Responds to all reads with 0 */
541 if (l64781_readreg(state, 0x1a) != 0) {
542 dprintk("Read 1 returned unexpcted value\n");
543 goto error;
544 }
545
546 /* Turn the chip on */
547 l64781_writereg (state, 0x3e, 0xa5);
548
549 /* Responds with register default value */
550 if (l64781_readreg(state, 0x1a) != 0xa1) {
551 dprintk("Read 2 returned unexpcted value\n");
552 goto error;
553 }
554
555 /* create dvb_frontend */
556 state->frontend.ops = &state->ops;
557 state->frontend.demodulator_priv = state;
558 return &state->frontend;
559
560error:
561 if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
562 kfree(state);
563 return NULL;
564}
565
566static struct dvb_frontend_ops l64781_ops = {
567
568 .info = {
569 .name = "LSI L64781 DVB-T",
570 .type = FE_OFDM,
571 /* .frequency_min = ???,*/
572 /* .frequency_max = ???,*/
573 .frequency_stepsize = 166666,
574 /* .frequency_tolerance = ???,*/
575 /* .symbol_rate_tolerance = ???,*/
576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
577 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
578 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
579 FE_CAN_MUTE_TS
580 },
581
582 .release = l64781_release,
583
584 .init = l64781_init,
585 .sleep = l64781_sleep,
586
587 .set_frontend = apply_frontend_param,
588 .get_frontend = get_frontend,
589 .get_tune_settings = l64781_get_tune_settings,
590
591 .read_status = l64781_read_status,
592 .read_ber = l64781_read_ber,
593 .read_signal_strength = l64781_read_signal_strength,
594 .read_snr = l64781_read_snr,
595 .read_ucblocks = l64781_read_ucblocks,
596};
597
598MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
new file mode 100644
index 000000000000..7e30fb0fdfa7
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -0,0 +1,42 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
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#ifndef L64781_H
24#define L64781_H
25
26#include <linux/dvb/frontend.h>
27
28struct l64781_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38
39extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
new file mode 100644
index 000000000000..176a22e3441b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -0,0 +1,729 @@
1/*
2 Driver for Zarlink VP310/MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32
33#include "dvb_frontend.h"
34#include "mt312_priv.h"
35#include "mt312.h"
36
37
38struct mt312_state {
39 struct i2c_adapter* i2c;
40 struct dvb_frontend_ops ops;
41 /* configuration settings */
42 const struct mt312_config* config;
43 struct dvb_frontend frontend;
44
45 u8 id;
46 u8 frequency;
47};
48
49static int debug;
50#define dprintk(args...) \
51 do { \
52 if (debug) printk(KERN_DEBUG "mt312: " args); \
53 } while (0)
54
55#define MT312_SYS_CLK 90000000UL /* 90 MHz */
56#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
57#define MT312_PLL_CLK 10000000UL /* 10 MHz */
58
59static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
60 void *buf, const size_t count)
61{
62 int ret;
63 struct i2c_msg msg[2];
64 u8 regbuf[1] = { reg };
65
66 msg[0].addr = state->config->demod_address;
67 msg[0].flags = 0;
68 msg[0].buf = regbuf;
69 msg[0].len = 1;
70 msg[1].addr = state->config->demod_address;
71 msg[1].flags = I2C_M_RD;
72 msg[1].buf = buf;
73 msg[1].len = count;
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) {
78 printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
79 return -EREMOTEIO;
80 }
81
82 if(debug) {
83 int i;
84 dprintk("R(%d):", reg & 0x7f);
85 for (i = 0; i < count; i++)
86 printk(" %02x", ((const u8 *) buf)[i]);
87 printk("\n");
88 }
89
90 return 0;
91}
92
93static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg,
94 const void *src, const size_t count)
95{
96 int ret;
97 u8 buf[count + 1];
98 struct i2c_msg msg;
99
100 if(debug) {
101 int i;
102 dprintk("W(%d):", reg & 0x7f);
103 for (i = 0; i < count; i++)
104 printk(" %02x", ((const u8 *) src)[i]);
105 printk("\n");
106 }
107
108 buf[0] = reg;
109 memcpy(&buf[1], src, count);
110
111 msg.addr = state->config->demod_address;
112 msg.flags = 0;
113 msg.buf = buf;
114 msg.len = count + 1;
115
116 ret = i2c_transfer(state->i2c, &msg, 1);
117
118 if (ret != 1) {
119 dprintk("%s: ret == %d\n", __FUNCTION__, ret);
120 return -EREMOTEIO;
121 }
122
123 return 0;
124}
125
126static inline int mt312_readreg(struct mt312_state* state,
127 const enum mt312_reg_addr reg, u8 *val)
128{
129 return mt312_read(state, reg, val, 1);
130}
131
132static inline int mt312_writereg(struct mt312_state* state,
133 const enum mt312_reg_addr reg, const u8 val)
134{
135 return mt312_write(state, reg, &val, 1);
136}
137
138static inline u32 mt312_div(u32 a, u32 b)
139{
140 return (a + (b / 2)) / b;
141}
142
143static int mt312_reset(struct mt312_state* state, const u8 full)
144{
145 return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
146}
147
148static int mt312_get_inversion(struct mt312_state* state,
149 fe_spectral_inversion_t *i)
150{
151 int ret;
152 u8 vit_mode;
153
154 if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 0)
155 return ret;
156
157 if (vit_mode & 0x80) /* auto inversion was used */
158 *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
159
160 return 0;
161}
162
163static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
164{
165 int ret;
166 u8 sym_rate_h;
167 u8 dec_ratio;
168 u16 sym_rat_op;
169 u16 monitor;
170 u8 buf[2];
171
172 if ((ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h)) < 0)
173 return ret;
174
175 if (sym_rate_h & 0x80) { /* symbol rate search was used */
176 if ((ret = mt312_writereg(state, MON_CTRL, 0x03)) < 0)
177 return ret;
178
179 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
180 return ret;
181
182 monitor = (buf[0] << 8) | buf[1];
183
184 dprintk(KERN_DEBUG "sr(auto) = %u\n",
185 mt312_div(monitor * 15625, 4));
186 } else {
187 if ((ret = mt312_writereg(state, MON_CTRL, 0x05)) < 0)
188 return ret;
189
190 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
191 return ret;
192
193 dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
194
195 if ((ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf))) < 0)
196 return ret;
197
198 sym_rat_op = (buf[0] << 8) | buf[1];
199
200 dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
201 sym_rat_op, dec_ratio);
202 dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
203 (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
204 2) - dec_ratio);
205 }
206
207 return 0;
208}
209
210static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
211{
212 const fe_code_rate_t fec_tab[8] =
213 { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
214 FEC_AUTO, FEC_AUTO };
215
216 int ret;
217 u8 fec_status;
218
219 if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 0)
220 return ret;
221
222 *cr = fec_tab[(fec_status >> 4) & 0x07];
223
224 return 0;
225}
226
227static int mt312_initfe(struct dvb_frontend* fe)
228{
229 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
230 int ret;
231 u8 buf[2];
232
233 /* wake up */
234 if ((ret = mt312_writereg(state, CONFIG, (state->frequency == 60 ? 0x88 : 0x8c))) < 0)
235 return ret;
236
237 /* wait at least 150 usec */
238 udelay(150);
239
240 /* full reset */
241 if ((ret = mt312_reset(state, 1)) < 0)
242 return ret;
243
244// Per datasheet, write correct values. 09/28/03 ACCJr.
245// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
246 {
247 u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
248
249 if ((ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
250 return ret;
251 }
252
253 /* SYS_CLK */
254 buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
255
256 /* DISEQC_RATIO */
257 buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
258
259 if ((ret = mt312_write(state, SYS_CLK, buf, sizeof(buf))) < 0)
260 return ret;
261
262 if ((ret = mt312_writereg(state, SNR_THS_HIGH, 0x32)) < 0)
263 return ret;
264
265 if ((ret = mt312_writereg(state, OP_CTRL, 0x53)) < 0)
266 return ret;
267
268 /* TS_SW_LIM */
269 buf[0] = 0x8c;
270 buf[1] = 0x98;
271
272 if ((ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf))) < 0)
273 return ret;
274
275 if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0)
276 return ret;
277
278 if (state->config->pll_init) {
279 mt312_writereg(state, GPP_CTRL, 0x40);
280 state->config->pll_init(fe);
281 mt312_writereg(state, GPP_CTRL, 0x00);
282 }
283
284 return 0;
285}
286
287static int mt312_send_master_cmd(struct dvb_frontend* fe,
288 struct dvb_diseqc_master_cmd *c)
289{
290 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
291 int ret;
292 u8 diseqc_mode;
293
294 if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
295 return -EINVAL;
296
297 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
298 return ret;
299
300 if ((ret =
301 mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0)
302 return ret;
303
304 if ((ret =
305 mt312_writereg(state, DISEQC_MODE,
306 (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
307 | 0x04)) < 0)
308 return ret;
309
310 /* set DISEQC_MODE[2:0] to zero if a return message is expected */
311 if (c->msg[0] & 0x02)
312 if ((ret =
313 mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40))) < 0)
314 return ret;
315
316 return 0;
317}
318
319static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
320{
321 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
322 const u8 mini_tab[2] = { 0x02, 0x03 };
323
324 int ret;
325 u8 diseqc_mode;
326
327 if (c > SEC_MINI_B)
328 return -EINVAL;
329
330 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
331 return ret;
332
333 if ((ret =
334 mt312_writereg(state, DISEQC_MODE,
335 (diseqc_mode & 0x40) | mini_tab[c])) < 0)
336 return ret;
337
338 return 0;
339}
340
341static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
342{
343 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
344 const u8 tone_tab[2] = { 0x01, 0x00 };
345
346 int ret;
347 u8 diseqc_mode;
348
349 if (t > SEC_TONE_OFF)
350 return -EINVAL;
351
352 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
353 return ret;
354
355 if ((ret =
356 mt312_writereg(state, DISEQC_MODE,
357 (diseqc_mode & 0x40) | tone_tab[t])) < 0)
358 return ret;
359
360 return 0;
361}
362
363static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
364{
365 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
366 const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
367
368 if (v > SEC_VOLTAGE_OFF)
369 return -EINVAL;
370
371 return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
372}
373
374static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
375{
376 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
377 int ret;
378 u8 status[3];
379
380 *s = 0;
381
382 if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0)
383 return ret;
384
385 dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
386
387 if (status[0] & 0xc0)
388 *s |= FE_HAS_SIGNAL; /* signal noise ratio */
389 if (status[0] & 0x04)
390 *s |= FE_HAS_CARRIER; /* qpsk carrier lock */
391 if (status[2] & 0x02)
392 *s |= FE_HAS_VITERBI; /* viterbi lock */
393 if (status[2] & 0x04)
394 *s |= FE_HAS_SYNC; /* byte align lock */
395 if (status[0] & 0x01)
396 *s |= FE_HAS_LOCK; /* qpsk lock */
397
398 return 0;
399}
400
401static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
402{
403 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
404 int ret;
405 u8 buf[3];
406
407 if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 0)
408 return ret;
409
410 *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
411
412 return 0;
413}
414
415static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength)
416{
417 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
418 int ret;
419 u8 buf[3];
420 u16 agc;
421 s16 err_db;
422
423 if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 0)
424 return ret;
425
426 agc = (buf[0] << 6) | (buf[1] >> 2);
427 err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
428
429 *signal_strength = agc;
430
431 dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
432
433 return 0;
434}
435
436static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
437{
438 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
439 int ret;
440 u8 buf[2];
441
442 if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 0)
443 return ret;
444
445 *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
446
447 return 0;
448}
449
450static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
451{
452 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
453 int ret;
454 u8 buf[2];
455
456 if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 0)
457 return ret;
458
459 *ubc = (buf[0] << 8) | buf[1];
460
461 return 0;
462}
463
464static int mt312_set_frontend(struct dvb_frontend* fe,
465 struct dvb_frontend_parameters *p)
466{
467 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
468 int ret;
469 u8 buf[5], config_val;
470 u16 sr;
471
472 const u8 fec_tab[10] =
473 { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
474 const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
475
476 dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
477
478 if ((p->frequency < fe->ops->info.frequency_min)
479 || (p->frequency > fe->ops->info.frequency_max))
480 return -EINVAL;
481
482 if ((p->inversion < INVERSION_OFF)
483 || (p->inversion > INVERSION_ON))
484 return -EINVAL;
485
486 if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min)
487 || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max))
488 return -EINVAL;
489
490 if ((p->u.qpsk.fec_inner < FEC_NONE)
491 || (p->u.qpsk.fec_inner > FEC_AUTO))
492 return -EINVAL;
493
494 if ((p->u.qpsk.fec_inner == FEC_4_5)
495 || (p->u.qpsk.fec_inner == FEC_8_9))
496 return -EINVAL;
497
498 switch (state->id) {
499 case ID_VP310:
500 // For now we will do this only for the VP310.
501 // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
502 if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0))
503 return ret;
504 if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
505 {
506 if ((config_val & 0x0c) == 0x08) { //We are running 60MHz
507 state->frequency = 90;
508 if ((ret = mt312_initfe(fe)) < 0)
509 return ret;
510 }
511 }
512 else
513 {
514 if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz
515 state->frequency = 60;
516 if ((ret = mt312_initfe(fe)) < 0)
517 return ret;
518 }
519 }
520 break;
521
522 case ID_MT312:
523 break;
524
525 default:
526 return -EINVAL;
527 }
528
529 mt312_writereg(state, GPP_CTRL, 0x40);
530 state->config->pll_set(fe, p);
531 mt312_writereg(state, GPP_CTRL, 0x00);
532
533 /* sr = (u16)(sr * 256.0 / 1000000.0) */
534 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
535
536 /* SYM_RATE */
537 buf[0] = (sr >> 8) & 0x3f;
538 buf[1] = (sr >> 0) & 0xff;
539
540 /* VIT_MODE */
541 buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];
542
543 /* QPSK_CTRL */
544 buf[3] = 0x40; /* swap I and Q before QPSK demodulation */
545
546 if (p->u.qpsk.symbol_rate < 10000000)
547 buf[3] |= 0x04; /* use afc mode */
548
549 /* GO */
550 buf[4] = 0x01;
551
552 if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
553 return ret;
554
555 mt312_reset(state, 0);
556
557 return 0;
558}
559
560static int mt312_get_frontend(struct dvb_frontend* fe,
561 struct dvb_frontend_parameters *p)
562{
563 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
564 int ret;
565
566 if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
567 return ret;
568
569 if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)
570 return ret;
571
572 if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)
573 return ret;
574
575 return 0;
576}
577
578static int mt312_sleep(struct dvb_frontend* fe)
579{
580 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
581 int ret;
582 u8 config;
583
584 /* reset all registers to defaults */
585 if ((ret = mt312_reset(state, 1)) < 0)
586 return ret;
587
588 if ((ret = mt312_readreg(state, CONFIG, &config)) < 0)
589 return ret;
590
591 /* enter standby */
592 if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 0)
593 return ret;
594
595 return 0;
596}
597
598static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
599{
600 fesettings->min_delay_ms = 50;
601 fesettings->step_size = 0;
602 fesettings->max_drift = 0;
603 return 0;
604}
605
606static void mt312_release(struct dvb_frontend* fe)
607{
608 struct mt312_state* state = (struct mt312_state*) fe->demodulator_priv;
609 kfree(state);
610}
611
612static struct dvb_frontend_ops vp310_mt312_ops;
613
614struct dvb_frontend* vp310_attach(const struct mt312_config* config,
615 struct i2c_adapter* i2c)
616{
617 struct mt312_state* state = NULL;
618
619 /* allocate memory for the internal state */
620 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
621 if (state == NULL)
622 goto error;
623
624 /* setup the state */
625 state->config = config;
626 state->i2c = i2c;
627 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
628 strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
629
630 /* check if the demod is there */
631 if (mt312_readreg(state, ID, &state->id) < 0)
632 goto error;
633 if (state->id != ID_VP310) {
634 goto error;
635 }
636
637 /* create dvb_frontend */
638 state->frequency = 90;
639 state->frontend.ops = &state->ops;
640 state->frontend.demodulator_priv = state;
641 return &state->frontend;
642
643error:
644 kfree(state);
645 return NULL;
646}
647
648struct dvb_frontend* mt312_attach(const struct mt312_config* config,
649 struct i2c_adapter* i2c)
650{
651 struct mt312_state* state = NULL;
652
653 /* allocate memory for the internal state */
654 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
655 if (state == NULL)
656 goto error;
657
658 /* setup the state */
659 state->config = config;
660 state->i2c = i2c;
661 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
662 strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
663
664 /* check if the demod is there */
665 if (mt312_readreg(state, ID, &state->id) < 0)
666 goto error;
667 if (state->id != ID_MT312) {
668 goto error;
669 }
670
671 /* create dvb_frontend */
672 state->frequency = 60;
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 if (state)
679 kfree(state);
680 return NULL;
681}
682
683static struct dvb_frontend_ops vp310_mt312_ops = {
684
685 .info = {
686 .name = "Zarlink ???? DVB-S",
687 .type = FE_QPSK,
688 .frequency_min = 950000,
689 .frequency_max = 2150000,
690 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
691 .symbol_rate_min = MT312_SYS_CLK / 128,
692 .symbol_rate_max = MT312_SYS_CLK / 2,
693 .caps =
694 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
695 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
697 FE_CAN_RECOVER
698 },
699
700 .release = mt312_release,
701
702 .init = mt312_initfe,
703 .sleep = mt312_sleep,
704
705 .set_frontend = mt312_set_frontend,
706 .get_frontend = mt312_get_frontend,
707 .get_tune_settings = mt312_get_tune_settings,
708
709 .read_status = mt312_read_status,
710 .read_ber = mt312_read_ber,
711 .read_signal_strength = mt312_read_signal_strength,
712 .read_snr = mt312_read_snr,
713 .read_ucblocks = mt312_read_ucblocks,
714
715 .diseqc_send_master_cmd = mt312_send_master_cmd,
716 .diseqc_send_burst = mt312_send_burst,
717 .set_tone = mt312_set_tone,
718 .set_voltage = mt312_set_voltage,
719};
720
721module_param(debug, int, 0644);
722MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
723
724MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
725MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
726MODULE_LICENSE("GPL");
727
728EXPORT_SYMBOL(mt312_attach);
729EXPORT_SYMBOL(vp310_attach);
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
new file mode 100644
index 000000000000..b3a53a73a117
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -0,0 +1,47 @@
1/*
2 Driver for Zarlink MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#ifndef MT312_H
27#define MT312_H
28
29#include <linux/dvb/frontend.h>
30
31struct mt312_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* PLL maintenance */
37 int (*pll_init)(struct dvb_frontend* fe);
38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
39};
40
41extern struct dvb_frontend* mt312_attach(const struct mt312_config* config,
42 struct i2c_adapter* i2c);
43
44extern struct dvb_frontend* vp310_attach(const struct mt312_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h
new file mode 100644
index 000000000000..5e0b95b5337b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312_priv.h
@@ -0,0 +1,162 @@
1/*
2 Driver for Zarlink MT312 QPSK Frontend
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef _DVB_FRONTENDS_MT312_PRIV
24#define _DVB_FRONTENDS_MT312_PRIV
25
26enum mt312_reg_addr {
27 QPSK_INT_H = 0,
28 QPSK_INT_M = 1,
29 QPSK_INT_L = 2,
30 FEC_INT = 3,
31 QPSK_STAT_H = 4,
32 QPSK_STAT_L = 5,
33 FEC_STATUS = 6,
34 LNB_FREQ_H = 7,
35 LNB_FREQ_L = 8,
36 M_SNR_H = 9,
37 M_SNR_L = 10,
38 VIT_ERRCNT_H = 11,
39 VIT_ERRCNT_M = 12,
40 VIT_ERRCNT_L = 13,
41 RS_BERCNT_H = 14,
42 RS_BERCNT_M = 15,
43 RS_BERCNT_L = 16,
44 RS_UBC_H = 17,
45 RS_UBC_L = 18,
46 SIG_LEVEL = 19,
47 GPP_CTRL = 20,
48 RESET = 21,
49 DISEQC_MODE = 22,
50 SYM_RATE_H = 23,
51 SYM_RATE_L = 24,
52 VIT_MODE = 25,
53 QPSK_CTRL = 26,
54 GO = 27,
55 IE_QPSK_H = 28,
56 IE_QPSK_M = 29,
57 IE_QPSK_L = 30,
58 IE_FEC = 31,
59 QPSK_STAT_EN = 32,
60 FEC_STAT_EN = 33,
61 SYS_CLK = 34,
62 DISEQC_RATIO = 35,
63 DISEQC_INSTR = 36,
64 FR_LIM = 37,
65 FR_OFF = 38,
66 AGC_CTRL = 39,
67 AGC_INIT = 40,
68 AGC_REF = 41,
69 AGC_MAX = 42,
70 AGC_MIN = 43,
71 AGC_LK_TH = 44,
72 TS_AGC_LK_TH = 45,
73 AGC_PWR_SET = 46,
74 QPSK_MISC = 47,
75 SNR_THS_LOW = 48,
76 SNR_THS_HIGH = 49,
77 TS_SW_RATE = 50,
78 TS_SW_LIM_L = 51,
79 TS_SW_LIM_H = 52,
80 CS_SW_RATE_1 = 53,
81 CS_SW_RATE_2 = 54,
82 CS_SW_RATE_3 = 55,
83 CS_SW_RATE_4 = 56,
84 CS_SW_LIM = 57,
85 TS_LPK = 58,
86 TS_LPK_M = 59,
87 TS_LPK_L = 60,
88 CS_KPROP_H = 61,
89 CS_KPROP_L = 62,
90 CS_KINT_H = 63,
91 CS_KINT_L = 64,
92 QPSK_SCALE = 65,
93 TLD_OUTCLK_TH = 66,
94 TLD_INCLK_TH = 67,
95 FLD_TH = 68,
96 PLD_OUTLK3 = 69,
97 PLD_OUTLK2 = 70,
98 PLD_OUTLK1 = 71,
99 PLD_OUTLK0 = 72,
100 PLD_INLK3 = 73,
101 PLD_INLK2 = 74,
102 PLD_INLK1 = 75,
103 PLD_INLK0 = 76,
104 PLD_ACC_TIME = 77,
105 SWEEP_PAR = 78,
106 STARTUP_TIME = 79,
107 LOSSLOCK_TH = 80,
108 FEC_LOCK_TM = 81,
109 LOSSLOCK_TM = 82,
110 VIT_ERRPER_H = 83,
111 VIT_ERRPER_M = 84,
112 VIT_ERRPER_L = 85,
113 VIT_SETUP = 86,
114 VIT_REF0 = 87,
115 VIT_REF1 = 88,
116 VIT_REF2 = 89,
117 VIT_REF3 = 90,
118 VIT_REF4 = 91,
119 VIT_REF5 = 92,
120 VIT_REF6 = 93,
121 VIT_MAXERR = 94,
122 BA_SETUPT = 95,
123 OP_CTRL = 96,
124 FEC_SETUP = 97,
125 PROG_SYNC = 98,
126 AFC_SEAR_TH = 99,
127 CSACC_DIF_TH = 100,
128 QPSK_LK_CT = 101,
129 QPSK_ST_CT = 102,
130 MON_CTRL = 103,
131 QPSK_RESET = 104,
132 QPSK_TST_CT = 105,
133 QPSK_TST_ST = 106,
134 TEST_R = 107,
135 AGC_H = 108,
136 AGC_M = 109,
137 AGC_L = 110,
138 FREQ_ERR1_H = 111,
139 FREQ_ERR1_M = 112,
140 FREQ_ERR1_L = 113,
141 FREQ_ERR2_H = 114,
142 FREQ_ERR2_L = 115,
143 SYM_RAT_OP_H = 116,
144 SYM_RAT_OP_L = 117,
145 DESEQC2_INT = 118,
146 DISEQC2_STAT = 119,
147 DISEQC2_FIFO = 120,
148 DISEQC2_CTRL1 = 121,
149 DISEQC2_CTRL2 = 122,
150 MONITOR_H = 123,
151 MONITOR_L = 124,
152 TEST_MODE = 125,
153 ID = 126,
154 CONFIG = 127
155};
156
157enum mt312_model_id {
158 ID_VP310 = 1,
159 ID_MT312 = 3
160};
161
162#endif /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
new file mode 100644
index 000000000000..50326c7248fa
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -0,0 +1,610 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/init.h>
37#include <linux/delay.h>
38
39#include "dvb_frontend.h"
40#include "mt352_priv.h"
41#include "mt352.h"
42
43struct mt352_state {
44 struct i2c_adapter* i2c;
45 struct dvb_frontend frontend;
46 struct dvb_frontend_ops ops;
47
48 /* configuration settings */
49 const struct mt352_config* config;
50};
51
52static int debug;
53#define dprintk(args...) \
54 do { \
55 if (debug) printk(KERN_DEBUG "mt352: " args); \
56 } while (0)
57
58static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 struct mt352_state* state = fe->demodulator_priv;
61 u8 buf[2] = { reg, val };
62 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
63 .buf = buf, .len = 2 };
64 int err = i2c_transfer(state->i2c, &msg, 1);
65 if (err != 1) {
66 printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
67 return err;
68 }
69 return 0;
70}
71
72int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
73{
74 int err,i;
75 for (i=0; i < ilen-1; i++)
76 if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
77 return err;
78
79 return 0;
80}
81
82static int mt352_read_register(struct mt352_state* state, u8 reg)
83{
84 int ret;
85 u8 b0 [] = { reg };
86 u8 b1 [] = { 0 };
87 struct i2c_msg msg [] = { { .addr = state->config->demod_address,
88 .flags = 0,
89 .buf = b0, .len = 1 },
90 { .addr = state->config->demod_address,
91 .flags = I2C_M_RD,
92 .buf = b1, .len = 1 } };
93
94 ret = i2c_transfer(state->i2c, msg, 2);
95
96 if (ret != 2) {
97 printk("%s: readreg error (reg=%d, ret==%i)\n",
98 __FUNCTION__, reg, ret);
99 return ret;
100 }
101
102 return b1[0];
103}
104
105int mt352_read(struct dvb_frontend *fe, u8 reg)
106{
107 return mt352_read_register(fe->demodulator_priv,reg);
108}
109
110static int mt352_sleep(struct dvb_frontend* fe)
111{
112 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
113
114 mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
115 return 0;
116}
117
118static void mt352_calc_nominal_rate(struct mt352_state* state,
119 enum fe_bandwidth bandwidth,
120 unsigned char *buf)
121{
122 u32 adc_clock = 20480; /* 20.340 MHz */
123 u32 bw,value;
124
125 switch (bandwidth) {
126 case BANDWIDTH_6_MHZ:
127 bw = 6;
128 break;
129 case BANDWIDTH_7_MHZ:
130 bw = 7;
131 break;
132 case BANDWIDTH_8_MHZ:
133 default:
134 bw = 8;
135 break;
136 }
137 if (state->config->adc_clock)
138 adc_clock = state->config->adc_clock;
139
140 value = 64 * bw * (1<<16) / (7 * 8);
141 value = value * 1000 / adc_clock;
142 dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
143 __FUNCTION__, bw, adc_clock, value);
144 buf[0] = msb(value);
145 buf[1] = lsb(value);
146}
147
148static void mt352_calc_input_freq(struct mt352_state* state,
149 unsigned char *buf)
150{
151 int adc_clock = 20480; /* 20.480000 MHz */
152 int if2 = 36167; /* 36.166667 MHz */
153 int ife,value;
154
155 if (state->config->adc_clock)
156 adc_clock = state->config->adc_clock;
157 if (state->config->if2)
158 if2 = state->config->if2;
159
160 ife = (2*adc_clock - if2);
161 value = -16374 * ife / adc_clock;
162 dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
163 __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff);
164 buf[0] = msb(value);
165 buf[1] = lsb(value);
166}
167
168static int mt352_set_parameters(struct dvb_frontend* fe,
169 struct dvb_frontend_parameters *param)
170{
171 struct mt352_state* state = fe->demodulator_priv;
172 unsigned char buf[13];
173 static unsigned char tuner_go[] = { 0x5d, 0x01 };
174 static unsigned char fsm_go[] = { 0x5e, 0x01 };
175 unsigned int tps = 0;
176 struct dvb_ofdm_parameters *op = &param->u.ofdm;
177
178 switch (op->code_rate_HP) {
179 case FEC_2_3:
180 tps |= (1 << 7);
181 break;
182 case FEC_3_4:
183 tps |= (2 << 7);
184 break;
185 case FEC_5_6:
186 tps |= (3 << 7);
187 break;
188 case FEC_7_8:
189 tps |= (4 << 7);
190 break;
191 case FEC_1_2:
192 case FEC_AUTO:
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 switch (op->code_rate_LP) {
199 case FEC_2_3:
200 tps |= (1 << 4);
201 break;
202 case FEC_3_4:
203 tps |= (2 << 4);
204 break;
205 case FEC_5_6:
206 tps |= (3 << 4);
207 break;
208 case FEC_7_8:
209 tps |= (4 << 4);
210 break;
211 case FEC_1_2:
212 case FEC_AUTO:
213 break;
214 case FEC_NONE:
215 if (op->hierarchy_information == HIERARCHY_AUTO ||
216 op->hierarchy_information == HIERARCHY_NONE)
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 switch (op->constellation) {
223 case QPSK:
224 break;
225 case QAM_AUTO:
226 case QAM_16:
227 tps |= (1 << 13);
228 break;
229 case QAM_64:
230 tps |= (2 << 13);
231 break;
232 default:
233 return -EINVAL;
234 }
235
236 switch (op->transmission_mode) {
237 case TRANSMISSION_MODE_2K:
238 case TRANSMISSION_MODE_AUTO:
239 break;
240 case TRANSMISSION_MODE_8K:
241 tps |= (1 << 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 switch (op->guard_interval) {
248 case GUARD_INTERVAL_1_32:
249 case GUARD_INTERVAL_AUTO:
250 break;
251 case GUARD_INTERVAL_1_16:
252 tps |= (1 << 2);
253 break;
254 case GUARD_INTERVAL_1_8:
255 tps |= (2 << 2);
256 break;
257 case GUARD_INTERVAL_1_4:
258 tps |= (3 << 2);
259 break;
260 default:
261 return -EINVAL;
262 }
263
264 switch (op->hierarchy_information) {
265 case HIERARCHY_AUTO:
266 case HIERARCHY_NONE:
267 break;
268 case HIERARCHY_1:
269 tps |= (1 << 10);
270 break;
271 case HIERARCHY_2:
272 tps |= (2 << 10);
273 break;
274 case HIERARCHY_4:
275 tps |= (3 << 10);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281
282 buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
283
284 buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */
285 buf[2] = lsb(tps);
286
287 buf[3] = 0x50; // old
288// buf[3] = 0xf4; // pinnacle
289
290 mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
291 mt352_calc_input_freq(state, buf+6);
292 state->config->pll_set(fe, param, buf+8);
293
294 mt352_write(fe, buf, sizeof(buf));
295 if (state->config->no_tuner) {
296 /* start decoding */
297 mt352_write(fe, fsm_go, 2);
298 } else {
299 /* start tuning */
300 mt352_write(fe, tuner_go, 2);
301 }
302 return 0;
303}
304
305static int mt352_get_parameters(struct dvb_frontend* fe,
306 struct dvb_frontend_parameters *param)
307{
308 struct mt352_state* state = fe->demodulator_priv;
309 u16 tps;
310 u16 div;
311 u8 trl;
312 struct dvb_ofdm_parameters *op = &param->u.ofdm;
313 static const u8 tps_fec_to_api[8] =
314 {
315 FEC_1_2,
316 FEC_2_3,
317 FEC_3_4,
318 FEC_5_6,
319 FEC_7_8,
320 FEC_AUTO,
321 FEC_AUTO,
322 FEC_AUTO
323 };
324
325 if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
326 return -EINVAL;
327
328 /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
329 * the mt352 sometimes works with the wrong parameters
330 */
331 tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
332 div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
333 trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
334
335 op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
336 op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
337
338 switch ( (tps >> 13) & 3)
339 {
340 case 0:
341 op->constellation = QPSK;
342 break;
343 case 1:
344 op->constellation = QAM_16;
345 break;
346 case 2:
347 op->constellation = QAM_64;
348 break;
349 default:
350 op->constellation = QAM_AUTO;
351 break;
352 }
353
354 op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
355
356 switch ( (tps >> 2) & 3)
357 {
358 case 0:
359 op->guard_interval = GUARD_INTERVAL_1_32;
360 break;
361 case 1:
362 op->guard_interval = GUARD_INTERVAL_1_16;
363 break;
364 case 2:
365 op->guard_interval = GUARD_INTERVAL_1_8;
366 break;
367 case 3:
368 op->guard_interval = GUARD_INTERVAL_1_4;
369 break;
370 default:
371 op->guard_interval = GUARD_INTERVAL_AUTO;
372 break;
373 }
374
375 switch ( (tps >> 10) & 7)
376 {
377 case 0:
378 op->hierarchy_information = HIERARCHY_NONE;
379 break;
380 case 1:
381 op->hierarchy_information = HIERARCHY_1;
382 break;
383 case 2:
384 op->hierarchy_information = HIERARCHY_2;
385 break;
386 case 3:
387 op->hierarchy_information = HIERARCHY_4;
388 break;
389 default:
390 op->hierarchy_information = HIERARCHY_AUTO;
391 break;
392 }
393
394 param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;
395
396 if (trl == 0x72)
397 op->bandwidth = BANDWIDTH_8_MHZ;
398 else if (trl == 0x64)
399 op->bandwidth = BANDWIDTH_7_MHZ;
400 else
401 op->bandwidth = BANDWIDTH_6_MHZ;
402
403
404 if (mt352_read_register(state, STATUS_2) & 0x02)
405 param->inversion = INVERSION_OFF;
406 else
407 param->inversion = INVERSION_ON;
408
409 return 0;
410}
411
412static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
413{
414 struct mt352_state* state = fe->demodulator_priv;
415 int s0, s1, s3;
416
417 /* FIXME:
418 *
419 * The MT352 design manual from Zarlink states (page 46-47):
420 *
421 * Notes about the TUNER_GO register:
422 *
423 * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
424 * byte is copied from the tuner to the STATUS_3 register and
425 * completion of the read operation is indicated by bit-5 of the
426 * INTERRUPT_3 register.
427 */
428
429 if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
430 return -EREMOTEIO;
431 if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
432 return -EREMOTEIO;
433 if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
434 return -EREMOTEIO;
435
436 *status = 0;
437 if (s0 & (1 << 4))
438 *status |= FE_HAS_CARRIER;
439 if (s0 & (1 << 1))
440 *status |= FE_HAS_VITERBI;
441 if (s0 & (1 << 5))
442 *status |= FE_HAS_LOCK;
443 if (s1 & (1 << 1))
444 *status |= FE_HAS_SYNC;
445 if (s3 & (1 << 6))
446 *status |= FE_HAS_SIGNAL;
447
448 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
449 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
450 *status &= ~FE_HAS_LOCK;
451
452 return 0;
453}
454
455static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
456{
457 struct mt352_state* state = fe->demodulator_priv;
458
459 *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
460 (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
461 (mt352_read_register (state, RS_ERR_CNT_0));
462
463 return 0;
464}
465
466static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
467{
468 struct mt352_state* state = fe->demodulator_priv;
469
470 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
471 (mt352_read_register(state, AGC_GAIN_0));
472
473 *strength = ~signal;
474 return 0;
475}
476
477static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
478{
479 struct mt352_state* state = fe->demodulator_priv;
480
481 u8 _snr = mt352_read_register (state, SNR);
482 *snr = (_snr << 8) | _snr;
483
484 return 0;
485}
486
487static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
488{
489 struct mt352_state* state = fe->demodulator_priv;
490
491 *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) |
492 (mt352_read_register (state, RS_UBC_0));
493
494 return 0;
495}
496
497static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
498{
499 fe_tune_settings->min_delay_ms = 800;
500 fe_tune_settings->step_size = 0;
501 fe_tune_settings->max_drift = 0;
502
503 return 0;
504}
505
506static int mt352_init(struct dvb_frontend* fe)
507{
508 struct mt352_state* state = fe->demodulator_priv;
509
510 static u8 mt352_reset_attach [] = { RESET, 0xC0 };
511
512 dprintk("%s: hello\n",__FUNCTION__);
513
514 if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
515 (mt352_read_register(state, CONFIG) & 0x20) == 0) {
516
517 /* Do a "hard" reset */
518 mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
519 return state->config->demod_init(fe);
520 }
521
522 return 0;
523}
524
525static void mt352_release(struct dvb_frontend* fe)
526{
527 struct mt352_state* state = fe->demodulator_priv;
528 kfree(state);
529}
530
531static struct dvb_frontend_ops mt352_ops;
532
533struct dvb_frontend* mt352_attach(const struct mt352_config* config,
534 struct i2c_adapter* i2c)
535{
536 struct mt352_state* state = NULL;
537
538 /* allocate memory for the internal state */
539 state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL);
540 if (state == NULL) goto error;
541 memset(state,0,sizeof(*state));
542
543 /* setup the state */
544 state->config = config;
545 state->i2c = i2c;
546 memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
547
548 /* check if the demod is there */
549 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
550
551 /* create dvb_frontend */
552 state->frontend.ops = &state->ops;
553 state->frontend.demodulator_priv = state;
554 return &state->frontend;
555
556error:
557 kfree(state);
558 return NULL;
559}
560
561static struct dvb_frontend_ops mt352_ops = {
562
563 .info = {
564 .name = "Zarlink MT352 DVB-T",
565 .type = FE_OFDM,
566 .frequency_min = 174000000,
567 .frequency_max = 862000000,
568 .frequency_stepsize = 166667,
569 .frequency_tolerance = 0,
570 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
571 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
572 FE_CAN_FEC_AUTO |
573 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
574 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
575 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
576 FE_CAN_MUTE_TS
577 },
578
579 .release = mt352_release,
580
581 .init = mt352_init,
582 .sleep = mt352_sleep,
583
584 .set_frontend = mt352_set_parameters,
585 .get_frontend = mt352_get_parameters,
586 .get_tune_settings = mt352_get_tune_settings,
587
588 .read_status = mt352_read_status,
589 .read_ber = mt352_read_ber,
590 .read_signal_strength = mt352_read_signal_strength,
591 .read_snr = mt352_read_snr,
592 .read_ucblocks = mt352_read_ucblocks,
593};
594
595module_param(debug, int, 0644);
596MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
597
598MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(mt352_attach);
603EXPORT_SYMBOL(mt352_write);
604EXPORT_SYMBOL(mt352_read);
605/*
606 * Local variables:
607 * c-basic-offset: 8
608 * compile-command: "make DVB=1"
609 * End:
610 */
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
new file mode 100644
index 000000000000..f5d8a5aed8a9
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -0,0 +1,72 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef MT352_H
34#define MT352_H
35
36#include <linux/dvb/frontend.h>
37
38struct mt352_config
39{
40 /* the demodulator's i2c address */
41 u8 demod_address;
42
43 /* frequencies in kHz */
44 int adc_clock; // default: 20480
45 int if2; // default: 36166
46
47 /* set if no pll is connected to the secondary i2c bus */
48 int no_tuner;
49
50 /* Initialise the demodulator and PLL. Cannot be NULL */
51 int (*demod_init)(struct dvb_frontend* fe);
52
53 /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings.
54 * byte0: Set to pll i2c address (nonlinux; left shifted by 1)
55 * byte1-4: PLL configuration.
56 */
57 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf);
58};
59
60extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
61 struct i2c_adapter* i2c);
62
63extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
64extern int mt352_read(struct dvb_frontend *fe, u8 reg);
65
66#endif // MT352_H
67
68/*
69 * Local variables:
70 * c-basic-offset: 8
71 * End:
72 */
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h
new file mode 100644
index 000000000000..44ad0d4c8f12
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352_priv.h
@@ -0,0 +1,127 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef _MT352_PRIV_
34#define _MT352_PRIV_
35
36#define ID_MT352 0x13
37
38#define msb(x) (((x) >> 8) & 0xff)
39#define lsb(x) ((x) & 0xff)
40
41enum mt352_reg_addr {
42 STATUS_0 = 0x00,
43 STATUS_1 = 0x01,
44 STATUS_2 = 0x02,
45 STATUS_3 = 0x03,
46 STATUS_4 = 0x04,
47 INTERRUPT_0 = 0x05,
48 INTERRUPT_1 = 0x06,
49 INTERRUPT_2 = 0x07,
50 INTERRUPT_3 = 0x08,
51 SNR = 0x09,
52 VIT_ERR_CNT_2 = 0x0A,
53 VIT_ERR_CNT_1 = 0x0B,
54 VIT_ERR_CNT_0 = 0x0C,
55 RS_ERR_CNT_2 = 0x0D,
56 RS_ERR_CNT_1 = 0x0E,
57 RS_ERR_CNT_0 = 0x0F,
58 RS_UBC_1 = 0x10,
59 RS_UBC_0 = 0x11,
60 AGC_GAIN_3 = 0x12,
61 AGC_GAIN_2 = 0x13,
62 AGC_GAIN_1 = 0x14,
63 AGC_GAIN_0 = 0x15,
64 FREQ_OFFSET_2 = 0x17,
65 FREQ_OFFSET_1 = 0x18,
66 FREQ_OFFSET_0 = 0x19,
67 TIMING_OFFSET_1 = 0x1A,
68 TIMING_OFFSET_0 = 0x1B,
69 CHAN_FREQ_1 = 0x1C,
70 CHAN_FREQ_0 = 0x1D,
71 TPS_RECEIVED_1 = 0x1E,
72 TPS_RECEIVED_0 = 0x1F,
73 TPS_CURRENT_1 = 0x20,
74 TPS_CURRENT_0 = 0x21,
75 TPS_CELL_ID_1 = 0x22,
76 TPS_CELL_ID_0 = 0x23,
77 TPS_MISC_DATA_2 = 0x24,
78 TPS_MISC_DATA_1 = 0x25,
79 TPS_MISC_DATA_0 = 0x26,
80 RESET = 0x50,
81 TPS_GIVEN_1 = 0x51,
82 TPS_GIVEN_0 = 0x52,
83 ACQ_CTL = 0x53,
84 TRL_NOMINAL_RATE_1 = 0x54,
85 TRL_NOMINAL_RATE_0 = 0x55,
86 INPUT_FREQ_1 = 0x56,
87 INPUT_FREQ_0 = 0x57,
88 TUNER_ADDR = 0x58,
89 CHAN_START_1 = 0x59,
90 CHAN_START_0 = 0x5A,
91 CONT_1 = 0x5B,
92 CONT_0 = 0x5C,
93 TUNER_GO = 0x5D,
94 STATUS_EN_0 = 0x5F,
95 STATUS_EN_1 = 0x60,
96 INTERRUPT_EN_0 = 0x61,
97 INTERRUPT_EN_1 = 0x62,
98 INTERRUPT_EN_2 = 0x63,
99 INTERRUPT_EN_3 = 0x64,
100 AGC_TARGET = 0x67,
101 AGC_CTL = 0x68,
102 CAPT_RANGE = 0x75,
103 SNR_SELECT_1 = 0x79,
104 SNR_SELECT_0 = 0x7A,
105 RS_ERR_PER_1 = 0x7C,
106 RS_ERR_PER_0 = 0x7D,
107 CHIP_ID = 0x7F,
108 CHAN_STOP_1 = 0x80,
109 CHAN_STOP_0 = 0x81,
110 CHAN_STEP_1 = 0x82,
111 CHAN_STEP_0 = 0x83,
112 FEC_LOCK_TIME = 0x85,
113 OFDM_LOCK_TIME = 0x86,
114 ACQ_DELAY = 0x87,
115 SCAN_CTL = 0x88,
116 CLOCK_CTL = 0x89,
117 CONFIG = 0x8A,
118 MCLK_RATIO = 0x8B,
119 GPP_CTL = 0x8C,
120 ADC_CTL_1 = 0x8E,
121 ADC_CTL_0 = 0x8F
122};
123
124/* here we assume 1/6MHz == 166.66kHz stepsize */
125#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
126
127#endif /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
new file mode 100644
index 000000000000..4743aa17406e
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -0,0 +1,705 @@
1/*
2 Support for B2C2/BBTI Technisat Air2PC - ATSC
3
4 Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
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*/
21
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
28#define CRC_CCIT_MASK 0x1021
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/device.h>
34#include <linux/firmware.h>
35
36#include "dvb_frontend.h"
37#include "nxt2002.h"
38
39struct nxt2002_state {
40
41 struct i2c_adapter* i2c;
42 struct dvb_frontend_ops ops;
43 const struct nxt2002_config* config;
44 struct dvb_frontend frontend;
45
46 /* demodulator private data */
47 u8 initialised:1;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "nxt2002: " args); \
54 } while (0)
55
56static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
57{
58 /* probbably a much better way or doing this */
59 u8 buf2 [256],x;
60 int err;
61 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
62
63 buf2[0] = reg;
64 for (x = 0 ; x < len ; x++)
65 buf2[x+1] = buf[x];
66
67 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
68 printk ("%s: i2c write error (addr %02x, err == %i)\n",
69 __FUNCTION__, state->config->demod_address, err);
70 return -EREMOTEIO;
71 }
72
73 return 0;
74}
75
76static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
77{
78 u8 reg2 [] = { reg };
79
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
82
83 int err;
84
85 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
86 printk ("%s: i2c read error (addr %02x, err == %i)\n",
87 __FUNCTION__, state->config->demod_address, err);
88 return -EREMOTEIO;
89 }
90
91 return 0;
92}
93
94static u16 nxt2002_crc(u16 crc, u8 c)
95{
96
97 u8 i;
98 u16 input = (u16) c & 0xFF;
99
100 input<<=8;
101 for(i=0 ;i<8 ;i++) {
102 if((crc ^ input) & 0x8000)
103 crc=(crc<<1)^CRC_CCIT_MASK;
104 else
105 crc<<=1;
106 input<<=1;
107 }
108 return crc;
109}
110
111static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
112{
113 u8 buf;
114 dprintk("%s\n", __FUNCTION__);
115
116 /* set multi register length */
117 i2c_writebytes(state,0x34,&len,1);
118
119 /* set mutli register register */
120 i2c_writebytes(state,0x35,&reg,1);
121
122 /* send the actual data */
123 i2c_writebytes(state,0x36,data,len);
124
125 /* toggle the multireg write bit*/
126 buf = 0x02;
127 i2c_writebytes(state,0x21,&buf,1);
128
129 i2c_readbytes(state,0x21,&buf,1);
130
131 if ((buf & 0x02) == 0)
132 return 0;
133
134 dprintk("Error writing multireg register %02X\n",reg);
135
136 return 0;
137}
138
139static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
140{
141 u8 len2;
142 dprintk("%s\n", __FUNCTION__);
143
144 /* set multi register length */
145 len2 = len & 0x80;
146 i2c_writebytes(state,0x34,&len2,1);
147
148 /* set mutli register register */
149 i2c_writebytes(state,0x35,&reg,1);
150
151 /* send the actual data */
152 i2c_readbytes(state,reg,data,len);
153
154 return 0;
155}
156
157static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
158{
159 u8 buf[2],counter = 0;
160 dprintk("%s\n", __FUNCTION__);
161
162 buf[0] = 0x80;
163 i2c_writebytes(state,0x22,buf,1);
164
165 while (counter < 20) {
166 i2c_readbytes(state,0x31,buf,1);
167 if (buf[0] & 0x40)
168 return;
169 msleep(10);
170 counter++;
171 }
172
173 dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
174 return;
175}
176
177static void nxt2002_microcontroller_start (struct nxt2002_state* state)
178{
179 u8 buf;
180 dprintk("%s\n", __FUNCTION__);
181
182 buf = 0x00;
183 i2c_writebytes(state,0x22,&buf,1);
184}
185
186static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
187{
188 u8 buf,count = 0;
189
190 dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
191
192 dprintk("%s\n", __FUNCTION__);
193 /* stop the micro first */
194 nxt2002_microcontroller_stop(state);
195
196 /* set the i2c transfer speed to the tuner */
197 buf = 0x03;
198 i2c_writebytes(state,0x20,&buf,1);
199
200 /* setup to transfer 4 bytes via i2c */
201 buf = 0x04;
202 i2c_writebytes(state,0x34,&buf,1);
203
204 /* write actual tuner bytes */
205 i2c_writebytes(state,0x36,data,4);
206
207 /* set tuner i2c address */
208 buf = 0xC2;
209 i2c_writebytes(state,0x35,&buf,1);
210
211 /* write UC Opmode to begin transfer */
212 buf = 0x80;
213 i2c_writebytes(state,0x21,&buf,1);
214
215 while (count < 20) {
216 i2c_readbytes(state,0x21,&buf,1);
217 if ((buf & 0x80)== 0x00)
218 return 0;
219 msleep(100);
220 count++;
221 }
222
223 printk("nxt2002: timeout error writing tuner\n");
224 return 0;
225}
226
227static void nxt2002_agc_reset(struct nxt2002_state* state)
228{
229 u8 buf;
230 dprintk("%s\n", __FUNCTION__);
231
232 buf = 0x08;
233 i2c_writebytes(state,0x08,&buf,1);
234
235 buf = 0x00;
236 i2c_writebytes(state,0x08,&buf,1);
237
238 return;
239}
240
241static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
242{
243
244 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
245 u8 buf[256],written = 0,chunkpos = 0;
246 u16 rambase,position,crc = 0;
247
248 dprintk("%s\n", __FUNCTION__);
249 dprintk("Firmware is %zu bytes\n",fw->size);
250
251 /* Get the RAM base for this nxt2002 */
252 i2c_readbytes(state,0x10,buf,1);
253
254 if (buf[0] & 0x10)
255 rambase = 0x1000;
256 else
257 rambase = 0x0000;
258
259 dprintk("rambase on this nxt2002 is %04X\n",rambase);
260
261 /* Hold the micro in reset while loading firmware */
262 buf[0] = 0x80;
263 i2c_writebytes(state,0x2B,buf,1);
264
265 for (position = 0; position < fw->size ; position++) {
266 if (written == 0) {
267 crc = 0;
268 chunkpos = 0x28;
269 buf[0] = ((rambase + position) >> 8);
270 buf[1] = (rambase + position) & 0xFF;
271 buf[2] = 0x81;
272 /* write starting address */
273 i2c_writebytes(state,0x29,buf,3);
274 }
275 written++;
276 chunkpos++;
277
278 if ((written % 4) == 0)
279 i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
280
281 crc = nxt2002_crc(crc,fw->data[position]);
282
283 if ((written == 255) || (position+1 == fw->size)) {
284 /* write remaining bytes of firmware */
285 i2c_writebytes(state, chunkpos+4-(written %4),
286 &fw->data[position-(written %4) + 1],
287 written %4);
288 buf[0] = crc << 8;
289 buf[1] = crc & 0xFF;
290
291 /* write crc */
292 i2c_writebytes(state,0x2C,buf,2);
293
294 /* do a read to stop things */
295 i2c_readbytes(state,0x2A,buf,1);
296
297 /* set transfer mode to complete */
298 buf[0] = 0x80;
299 i2c_writebytes(state,0x2B,buf,1);
300
301 written = 0;
302 }
303 }
304
305 printk ("done.\n");
306 return 0;
307};
308
309static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
310 struct dvb_frontend_parameters *p)
311{
312 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
313 u32 freq = 0;
314 u16 tunerfreq = 0;
315 u8 buf[4];
316
317 freq = 44000 + ( p->frequency / 1000 );
318
319 dprintk("freq = %d p->frequency = %d\n",freq,p->frequency);
320
321 tunerfreq = freq * 24/4000;
322
323 buf[0] = (tunerfreq >> 8) & 0x7F;
324 buf[1] = (tunerfreq & 0xFF);
325
326 if (p->frequency <= 214000000) {
327 buf[2] = 0x84 + (0x06 << 3);
328 buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
329 } else if (p->frequency <= 721000000) {
330 buf[2] = 0x84 + (0x07 << 3);
331 buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
332 } else if (p->frequency <= 841000000) {
333 buf[2] = 0x84 + (0x0E << 3);
334 buf[3] = 0x08;
335 } else {
336 buf[2] = 0x84 + (0x0F << 3);
337 buf[3] = 0x02;
338 }
339
340 /* write frequency information */
341 nxt2002_writetuner(state,buf);
342
343 /* reset the agc now that tuning has been completed */
344 nxt2002_agc_reset(state);
345
346
347
348 /* set target power level */
349 switch (p->u.vsb.modulation) {
350 case QAM_64:
351 case QAM_256:
352 buf[0] = 0x74;
353 break;
354 case VSB_8:
355 buf[0] = 0x70;
356 break;
357 default:
358 return -EINVAL;
359 break;
360 }
361 i2c_writebytes(state,0x42,buf,1);
362
363 /* configure sdm */
364 buf[0] = 0x87;
365 i2c_writebytes(state,0x57,buf,1);
366
367 /* write sdm1 input */
368 buf[0] = 0x10;
369 buf[1] = 0x00;
370 nxt2002_writereg_multibyte(state,0x58,buf,2);
371
372 /* write sdmx input */
373 switch (p->u.vsb.modulation) {
374 case QAM_64:
375 buf[0] = 0x68;
376 break;
377 case QAM_256:
378 buf[0] = 0x64;
379 break;
380 case VSB_8:
381 buf[0] = 0x60;
382 break;
383 default:
384 return -EINVAL;
385 break;
386 }
387 buf[1] = 0x00;
388 nxt2002_writereg_multibyte(state,0x5C,buf,2);
389
390 /* write adc power lpf fc */
391 buf[0] = 0x05;
392 i2c_writebytes(state,0x43,buf,1);
393
394 /* write adc power lpf fc */
395 buf[0] = 0x05;
396 i2c_writebytes(state,0x43,buf,1);
397
398 /* write accumulator2 input */
399 buf[0] = 0x80;
400 buf[1] = 0x00;
401 nxt2002_writereg_multibyte(state,0x4B,buf,2);
402
403 /* write kg1 */
404 buf[0] = 0x00;
405 i2c_writebytes(state,0x4D,buf,1);
406
407 /* write sdm12 lpf fc */
408 buf[0] = 0x44;
409 i2c_writebytes(state,0x55,buf,1);
410
411 /* write agc control reg */
412 buf[0] = 0x04;
413 i2c_writebytes(state,0x41,buf,1);
414
415 /* write agc ucgp0 */
416 switch (p->u.vsb.modulation) {
417 case QAM_64:
418 buf[0] = 0x02;
419 break;
420 case QAM_256:
421 buf[0] = 0x03;
422 break;
423 case VSB_8:
424 buf[0] = 0x00;
425 break;
426 default:
427 return -EINVAL;
428 break;
429 }
430 i2c_writebytes(state,0x30,buf,1);
431
432 /* write agc control reg */
433 buf[0] = 0x00;
434 i2c_writebytes(state,0x41,buf,1);
435
436 /* write accumulator2 input */
437 buf[0] = 0x80;
438 buf[1] = 0x00;
439 nxt2002_writereg_multibyte(state,0x49,buf,2);
440 nxt2002_writereg_multibyte(state,0x4B,buf,2);
441
442 /* write agc control reg */
443 buf[0] = 0x04;
444 i2c_writebytes(state,0x41,buf,1);
445
446 nxt2002_microcontroller_start(state);
447
448 /* adjacent channel detection should be done here, but I don't
449 have any stations with this need so I cannot test it */
450
451 return 0;
452}
453
454static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
455{
456 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
457 u8 lock;
458 i2c_readbytes(state,0x31,&lock,1);
459
460 *status = 0;
461 if (lock & 0x20) {
462 *status |= FE_HAS_SIGNAL;
463 *status |= FE_HAS_CARRIER;
464 *status |= FE_HAS_VITERBI;
465 *status |= FE_HAS_SYNC;
466 *status |= FE_HAS_LOCK;
467 }
468 return 0;
469}
470
471static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
472{
473 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
474 u8 b[3];
475
476 nxt2002_readreg_multibyte(state,0xE6,b,3);
477
478 *ber = ((b[0] << 8) + b[1]) * 8;
479
480 return 0;
481}
482
483static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
484{
485 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
486 u8 b[2];
487 u16 temp = 0;
488
489 /* setup to read cluster variance */
490 b[0] = 0x00;
491 i2c_writebytes(state,0xA1,b,1);
492
493 /* get multreg val */
494 nxt2002_readreg_multibyte(state,0xA6,b,2);
495
496 temp = (b[0] << 8) | b[1];
497 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
498
499 return 0;
500}
501
502static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
503{
504
505 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
506 u8 b[2];
507 u16 temp = 0, temp2;
508 u32 snrdb = 0;
509
510 /* setup to read cluster variance */
511 b[0] = 0x00;
512 i2c_writebytes(state,0xA1,b,1);
513
514 /* get multreg val from 0xA6 */
515 nxt2002_readreg_multibyte(state,0xA6,b,2);
516
517 temp = (b[0] << 8) | b[1];
518 temp2 = 0x7FFF - temp;
519
520 /* snr will be in db */
521 if (temp2 > 0x7F00)
522 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
523 else if (temp2 > 0x7EC0)
524 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
525 else if (temp2 > 0x7C00)
526 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
527 else
528 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
529
530 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
531
532 *snr = snrdb * (0xFFFF/32000);
533
534 return 0;
535}
536
537static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
538{
539 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
540 u8 b[3];
541
542 nxt2002_readreg_multibyte(state,0xE6,b,3);
543 *ucblocks = b[2];
544
545 return 0;
546}
547
548static int nxt2002_sleep(struct dvb_frontend* fe)
549{
550 return 0;
551}
552
553static int nxt2002_init(struct dvb_frontend* fe)
554{
555 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
556 const struct firmware *fw;
557 int ret;
558 u8 buf[2];
559
560 if (!state->initialised) {
561 /* request the firmware, this will block until someone uploads it */
562 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
563 ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
564 printk("nxt2002: Waiting for firmware upload(2)...\n");
565 if (ret) {
566 printk("nxt2002: no firmware upload (timeout or file not found?)\n");
567 return ret;
568 }
569
570 ret = nxt2002_load_firmware(fe, fw);
571 if (ret) {
572 printk("nxt2002: writing firmware to device failed\n");
573 release_firmware(fw);
574 return ret;
575 }
576 printk("nxt2002: firmware upload complete\n");
577
578 /* Put the micro into reset */
579 nxt2002_microcontroller_stop(state);
580
581 /* ensure transfer is complete */
582 buf[0]=0;
583 i2c_writebytes(state,0x2B,buf,1);
584
585 /* Put the micro into reset for real this time */
586 nxt2002_microcontroller_stop(state);
587
588 /* soft reset everything (agc,frontend,eq,fec)*/
589 buf[0] = 0x0F;
590 i2c_writebytes(state,0x08,buf,1);
591 buf[0] = 0x00;
592 i2c_writebytes(state,0x08,buf,1);
593
594 /* write agc sdm configure */
595 buf[0] = 0xF1;
596 i2c_writebytes(state,0x57,buf,1);
597
598 /* write mod output format */
599 buf[0] = 0x20;
600 i2c_writebytes(state,0x09,buf,1);
601
602 /* write fec mpeg mode */
603 buf[0] = 0x7E;
604 buf[1] = 0x00;
605 i2c_writebytes(state,0xE9,buf,2);
606
607 /* write mux selection */
608 buf[0] = 0x00;
609 i2c_writebytes(state,0xCC,buf,1);
610
611 state->initialised = 1;
612 }
613
614 return 0;
615}
616
617static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
618{
619 fesettings->min_delay_ms = 500;
620 fesettings->step_size = 0;
621 fesettings->max_drift = 0;
622 return 0;
623}
624
625static void nxt2002_release(struct dvb_frontend* fe)
626{
627 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
628 kfree(state);
629}
630
631static struct dvb_frontend_ops nxt2002_ops;
632
633struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct nxt2002_state* state = NULL;
637 u8 buf [] = {0,0,0,0,0};
638
639 /* allocate memory for the internal state */
640 state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
647 state->initialised = 0;
648
649 /* Check the first 5 registers to ensure this a revision we can handle */
650
651 i2c_readbytes(state, 0x00, buf, 5);
652 if (buf[0] != 0x04) goto error; /* device id */
653 if (buf[1] != 0x02) goto error; /* fab id */
654 if (buf[2] != 0x11) goto error; /* month */
655 if (buf[3] != 0x20) goto error; /* year msb */
656 if (buf[4] != 0x00) goto error; /* year lsb */
657
658 /* create dvb_frontend */
659 state->frontend.ops = &state->ops;
660 state->frontend.demodulator_priv = state;
661 return &state->frontend;
662
663error:
664 kfree(state);
665 return NULL;
666}
667
668static struct dvb_frontend_ops nxt2002_ops = {
669
670 .info = {
671 .name = "Nextwave nxt2002 VSB/QAM frontend",
672 .type = FE_ATSC,
673 .frequency_min = 54000000,
674 .frequency_max = 860000000,
675 /* stepsize is just a guess */
676 .frequency_stepsize = 166666,
677 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
678 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
679 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
680 },
681
682 .release = nxt2002_release,
683
684 .init = nxt2002_init,
685 .sleep = nxt2002_sleep,
686
687 .set_frontend = nxt2002_setup_frontend_parameters,
688 .get_tune_settings = nxt2002_get_tune_settings,
689
690 .read_status = nxt2002_read_status,
691 .read_ber = nxt2002_read_ber,
692 .read_signal_strength = nxt2002_read_signal_strength,
693 .read_snr = nxt2002_read_snr,
694 .read_ucblocks = nxt2002_read_ucblocks,
695
696};
697
698module_param(debug, int, 0644);
699MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
700
701MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
702MODULE_AUTHOR("Taylor Jacob");
703MODULE_LICENSE("GPL");
704
705EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
new file mode 100644
index 000000000000..462301f577ee
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.h
@@ -0,0 +1,23 @@
1/*
2 Driver for the Nxt2002 demodulator
3*/
4
5#ifndef NXT2002_H
6#define NXT2002_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct nxt2002_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* request firmware for device */
17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
18};
19
20extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
21 struct i2c_adapter* i2c);
22
23#endif // NXT2002_H
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
new file mode 100644
index 000000000000..a41f7da8b842
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -0,0 +1,554 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29#include "nxt6000_priv.h"
30#include "nxt6000.h"
31
32
33
34struct nxt6000_state {
35 struct i2c_adapter* i2c;
36 struct dvb_frontend_ops ops;
37 /* configuration settings */
38 const struct nxt6000_config* config;
39 struct dvb_frontend frontend;
40};
41
42static int debug = 0;
43#define dprintk if (debug) printk
44
45static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
46{
47 u8 buf[] = { reg, data };
48 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
49 int ret;
50
51 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
52 dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
53
54 return (ret != 1) ? -EFAULT : 0;
55}
56
57static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
58{
59 int ret;
60 u8 b0[] = { reg };
61 u8 b1[] = { 0 };
62 struct i2c_msg msgs[] = {
63 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
64 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
65 };
66
67 ret = i2c_transfer(state->i2c, msgs, 2);
68
69 if (ret != 2)
70 dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
71
72 return b1[0];
73}
74
75static void nxt6000_reset(struct nxt6000_state* state)
76{
77 u8 val;
78
79 val = nxt6000_readreg(state, OFDM_COR_CTL);
80
81 nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
82 nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
83}
84
85static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth)
86{
87 u16 nominal_rate;
88 int result;
89
90 switch (bandwidth) {
91
92 case BANDWIDTH_6_MHZ:
93 nominal_rate = 0x55B7;
94 break;
95
96 case BANDWIDTH_7_MHZ:
97 nominal_rate = 0x6400;
98 break;
99
100 case BANDWIDTH_8_MHZ:
101 nominal_rate = 0x7249;
102 break;
103
104 default:
105 return -EINVAL;
106 }
107
108 if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
109 return result;
110
111 return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
112}
113
114static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
115{
116 switch (guard_interval) {
117
118 case GUARD_INTERVAL_1_32:
119 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
120
121 case GUARD_INTERVAL_1_16:
122 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
123
124 case GUARD_INTERVAL_AUTO:
125 case GUARD_INTERVAL_1_8:
126 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
127
128 case GUARD_INTERVAL_1_4:
129 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
130
131 default:
132 return -EINVAL;
133 }
134}
135
136static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
137{
138 switch (inversion) {
139
140 case INVERSION_OFF:
141 return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
142
143 case INVERSION_ON:
144 return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
145
146 default:
147 return -EINVAL;
148
149 }
150}
151
152static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
153{
154 int result;
155
156 switch (transmission_mode) {
157
158 case TRANSMISSION_MODE_2K:
159 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
160 return result;
161
162 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
163
164 case TRANSMISSION_MODE_8K:
165 case TRANSMISSION_MODE_AUTO:
166 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
167 return result;
168
169 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
170
171 default:
172 return -EINVAL;
173
174 }
175}
176
177static void nxt6000_setup(struct dvb_frontend* fe)
178{
179 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
180
181 nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
182 nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
183 nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC);
184 nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
185 nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
186 nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
187 nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
188 nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
189 nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
190 nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */
191 nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
192 nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
193 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
194 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
195 nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
196 nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
197 nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
198
199 if (state->config->clock_inversion)
200 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
201 else
202 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
203
204 nxt6000_writereg(state, TS_FORMAT, 0);
205
206 if (state->config->pll_init) {
207 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
208 state->config->pll_init(fe);
209 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
210 }
211}
212
213static void nxt6000_dump_status(struct nxt6000_state *state)
214{
215 u8 val;
216
217/*
218 printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
219 printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
220 printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
221 printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
222 printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
223 printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
224 printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
225 printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
226 printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
227 printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
228*/
229 printk("NXT6000 status:");
230
231 val = nxt6000_readreg(state, RS_COR_STAT);
232
233 printk(" DATA DESCR LOCK: %d,", val & 0x01);
234 printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
235
236 val = nxt6000_readreg(state, VIT_SYNC_STATUS);
237
238 printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
239
240 switch ((val >> 4) & 0x07) {
241
242 case 0x00:
243 printk(" VITERBI CODERATE: 1/2,");
244 break;
245
246 case 0x01:
247 printk(" VITERBI CODERATE: 2/3,");
248 break;
249
250 case 0x02:
251 printk(" VITERBI CODERATE: 3/4,");
252 break;
253
254 case 0x03:
255 printk(" VITERBI CODERATE: 5/6,");
256 break;
257
258 case 0x04:
259 printk(" VITERBI CODERATE: 7/8,");
260 break;
261
262 default:
263 printk(" VITERBI CODERATE: Reserved,");
264
265 }
266
267 val = nxt6000_readreg(state, OFDM_COR_STAT);
268
269 printk(" CHCTrack: %d,", (val >> 7) & 0x01);
270 printk(" TPSLock: %d,", (val >> 6) & 0x01);
271 printk(" SYRLock: %d,", (val >> 5) & 0x01);
272 printk(" AGCLock: %d,", (val >> 4) & 0x01);
273
274 switch (val & 0x0F) {
275
276 case 0x00:
277 printk(" CoreState: IDLE,");
278 break;
279
280 case 0x02:
281 printk(" CoreState: WAIT_AGC,");
282 break;
283
284 case 0x03:
285 printk(" CoreState: WAIT_SYR,");
286 break;
287
288 case 0x04:
289 printk(" CoreState: WAIT_PPM,");
290 break;
291
292 case 0x01:
293 printk(" CoreState: WAIT_TRL,");
294 break;
295
296 case 0x05:
297 printk(" CoreState: WAIT_TPS,");
298 break;
299
300 case 0x06:
301 printk(" CoreState: MONITOR_TPS,");
302 break;
303
304 default:
305 printk(" CoreState: Reserved,");
306
307 }
308
309 val = nxt6000_readreg(state, OFDM_SYR_STAT);
310
311 printk(" SYRLock: %d,", (val >> 4) & 0x01);
312 printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
313
314 switch ((val >> 4) & 0x03) {
315
316 case 0x00:
317 printk(" SYRGuard: 1/32,");
318 break;
319
320 case 0x01:
321 printk(" SYRGuard: 1/16,");
322 break;
323
324 case 0x02:
325 printk(" SYRGuard: 1/8,");
326 break;
327
328 case 0x03:
329 printk(" SYRGuard: 1/4,");
330 break;
331 }
332
333 val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
334
335 switch ((val >> 4) & 0x07) {
336
337 case 0x00:
338 printk(" TPSLP: 1/2,");
339 break;
340
341 case 0x01:
342 printk(" TPSLP: 2/3,");
343 break;
344
345 case 0x02:
346 printk(" TPSLP: 3/4,");
347 break;
348
349 case 0x03:
350 printk(" TPSLP: 5/6,");
351 break;
352
353 case 0x04:
354 printk(" TPSLP: 7/8,");
355 break;
356
357 default:
358 printk(" TPSLP: Reserved,");
359
360 }
361
362 switch (val & 0x07) {
363
364 case 0x00:
365 printk(" TPSHP: 1/2,");
366 break;
367
368 case 0x01:
369 printk(" TPSHP: 2/3,");
370 break;
371
372 case 0x02:
373 printk(" TPSHP: 3/4,");
374 break;
375
376 case 0x03:
377 printk(" TPSHP: 5/6,");
378 break;
379
380 case 0x04:
381 printk(" TPSHP: 7/8,");
382 break;
383
384 default:
385 printk(" TPSHP: Reserved,");
386
387 }
388
389 val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
390
391 printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
392
393 switch ((val >> 4) & 0x03) {
394
395 case 0x00:
396 printk(" TPSGuard: 1/32,");
397 break;
398
399 case 0x01:
400 printk(" TPSGuard: 1/16,");
401 break;
402
403 case 0x02:
404 printk(" TPSGuard: 1/8,");
405 break;
406
407 case 0x03:
408 printk(" TPSGuard: 1/4,");
409 break;
410
411 }
412
413 /* Strange magic required to gain access to RF_AGC_STATUS */
414 nxt6000_readreg(state, RF_AGC_VAL_1);
415 val = nxt6000_readreg(state, RF_AGC_STATUS);
416 val = nxt6000_readreg(state, RF_AGC_STATUS);
417
418 printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
419 printk("\n");
420}
421
422static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
423{
424 u8 core_status;
425 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
426
427 *status = 0;
428
429 core_status = nxt6000_readreg(state, OFDM_COR_STAT);
430
431 if (core_status & AGCLOCKED)
432 *status |= FE_HAS_SIGNAL;
433
434 if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
435 *status |= FE_HAS_CARRIER;
436
437 if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
438 *status |= FE_HAS_VITERBI;
439
440 if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
441 *status |= FE_HAS_SYNC;
442
443 if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
444 *status |= FE_HAS_LOCK;
445
446 if (debug)
447 nxt6000_dump_status(state);
448
449 return 0;
450}
451
452static int nxt6000_init(struct dvb_frontend* fe)
453{
454 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
455
456 nxt6000_reset(state);
457 nxt6000_setup(fe);
458
459 return 0;
460}
461
462static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
463{
464 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
465 int result;
466
467 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
468 state->config->pll_set(fe, param);
469 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
470
471 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
472 return result;
473 if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0)
474 return result;
475 if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0)
476 return result;
477 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
478 return result;
479
480 return 0;
481}
482
483static void nxt6000_release(struct dvb_frontend* fe)
484{
485 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
486 kfree(state);
487}
488
489static struct dvb_frontend_ops nxt6000_ops;
490
491struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
492 struct i2c_adapter* i2c)
493{
494 struct nxt6000_state* state = NULL;
495
496 /* allocate memory for the internal state */
497 state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
498 if (state == NULL) goto error;
499
500 /* setup the state */
501 state->config = config;
502 state->i2c = i2c;
503 memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
504
505 /* check if the demod is there */
506 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
507
508 /* create dvb_frontend */
509 state->frontend.ops = &state->ops;
510 state->frontend.demodulator_priv = state;
511 return &state->frontend;
512
513error:
514 kfree(state);
515 return NULL;
516}
517
518static struct dvb_frontend_ops nxt6000_ops = {
519
520 .info = {
521 .name = "NxtWave NXT6000 DVB-T",
522 .type = FE_OFDM,
523 .frequency_min = 0,
524 .frequency_max = 863250000,
525 .frequency_stepsize = 62500,
526 /*.frequency_tolerance = *//* FIXME: 12% of SR */
527 .symbol_rate_min = 0, /* FIXME */
528 .symbol_rate_max = 9360000, /* FIXME */
529 .symbol_rate_tolerance = 4000,
530 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
531 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
532 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
533 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
534 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
535 FE_CAN_HIERARCHY_AUTO,
536 },
537
538 .release = nxt6000_release,
539
540 .init = nxt6000_init,
541
542 .set_frontend = nxt6000_set_frontend,
543
544 .read_status = nxt6000_read_status,
545};
546
547module_param(debug, int, 0644);
548MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
549
550MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
551MODULE_AUTHOR("Florian Schirmer");
552MODULE_LICENSE("GPL");
553
554EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
new file mode 100644
index 000000000000..b7d9bead3002
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -0,0 +1,43 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef NXT6000_H
23#define NXT6000_H
24
25#include <linux/dvb/frontend.h>
26
27struct nxt6000_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* should clock inversion be used? */
33 u8 clock_inversion:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
new file mode 100644
index 000000000000..64b1a89b2a22
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000_priv.h
@@ -0,0 +1,265 @@
1/*
2 * Public Include File for DRV6000 users
3 * (ie. NxtWave Communications - NXT6000 demodulator driver)
4 *
5 * Copyright (C) 2001 NxtWave Communications, Inc.
6 *
7 */
8
9/* Nxt6000 Register Addresses and Bit Masks */
10
11/* Maximum Register Number */
12#define MAXNXT6000REG (0x9A)
13
14/* 0x1B A_VIT_BER_0 aka 0x3A */
15#define A_VIT_BER_0 (0x1B)
16
17/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
18#define A_VIT_BER_TIMER_0 (0x1D)
19
20/* 0x21 RS_COR_STAT */
21#define RS_COR_STAT (0x21)
22#define RSCORESTATUS (0x03)
23
24/* 0x22 RS_COR_INTEN */
25#define RS_COR_INTEN (0x22)
26
27/* 0x23 RS_COR_INSTAT */
28#define RS_COR_INSTAT (0x23)
29#define INSTAT_ERROR (0x04)
30#define LOCK_LOSS_BITS (0x03)
31
32/* 0x24 RS_COR_SYNC_PARAM */
33#define RS_COR_SYNC_PARAM (0x24)
34#define SYNC_PARAM (0x03)
35
36/* 0x25 BER_CTRL */
37#define BER_CTRL (0x25)
38#define BER_ENABLE (0x02)
39#define BER_RESET (0x01)
40
41/* 0x26 BER_PAY */
42#define BER_PAY (0x26)
43
44/* 0x27 BER_PKT_L */
45#define BER_PKT_L (0x27)
46#define BER_PKTOVERFLOW (0x80)
47
48/* 0x30 VIT_COR_CTL */
49#define VIT_COR_CTL (0x30)
50#define BER_CONTROL (0x02)
51#define VIT_COR_MASK (0x82)
52#define VIT_COR_RESYNC (0x80)
53
54
55/* 0x32 VIT_SYNC_STATUS */
56#define VIT_SYNC_STATUS (0x32)
57#define VITINSYNC (0x80)
58
59/* 0x33 VIT_COR_INTEN */
60#define VIT_COR_INTEN (0x33)
61#define GLOBAL_ENABLE (0x80)
62
63/* 0x34 VIT_COR_INTSTAT */
64#define VIT_COR_INTSTAT (0x34)
65#define BER_DONE (0x08)
66#define BER_OVERFLOW (0x10)
67
68 /* 0x38 OFDM_BERTimer *//* Use the alias registers */
69#define A_VIT_BER_TIMER_0 (0x1D)
70
71 /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
72#define A_VIT_BER_0 (0x1B)
73
74/* 0x40 OFDM_COR_CTL */
75#define OFDM_COR_CTL (0x40)
76#define COREACT (0x20)
77#define HOLDSM (0x10)
78#define WAIT_AGC (0x02)
79#define WAIT_SYR (0x03)
80
81/* 0x41 OFDM_COR_STAT */
82#define OFDM_COR_STAT (0x41)
83#define COR_STATUS (0x0F)
84#define MONITOR_TPS (0x06)
85#define TPSLOCKED (0x40)
86#define AGCLOCKED (0x10)
87
88/* 0x42 OFDM_COR_INTEN */
89#define OFDM_COR_INTEN (0x42)
90#define TPSRCVBAD (0x04)
91#define TPSRCVCHANGED (0x02)
92#define TPSRCVUPDATE (0x01)
93
94/* 0x43 OFDM_COR_INSTAT */
95#define OFDM_COR_INSTAT (0x43)
96
97/* 0x44 OFDM_COR_MODEGUARD */
98#define OFDM_COR_MODEGUARD (0x44)
99#define FORCEMODE (0x08)
100#define FORCEMODE8K (0x04)
101
102/* 0x45 OFDM_AGC_CTL */
103#define OFDM_AGC_CTL (0x45)
104#define INITIAL_AGC_BW (0x08)
105#define AGCNEG (0x02)
106#define AGCLAST (0x10)
107
108/* 0x48 OFDM_AGC_TARGET */
109#define OFDM_AGC_TARGET (0x48)
110#define OFDM_AGC_TARGET_DEFAULT (0x28)
111#define OFDM_AGC_TARGET_IMPULSE (0x38)
112
113/* 0x49 OFDM_AGC_GAIN_1 */
114#define OFDM_AGC_GAIN_1 (0x49)
115
116/* 0x4B OFDM_ITB_CTL */
117#define OFDM_ITB_CTL (0x4B)
118#define ITBINV (0x01)
119
120/* 0x4C OFDM_ITB_FREQ_1 */
121#define OFDM_ITB_FREQ_1 (0x4C)
122
123/* 0x4D OFDM_ITB_FREQ_2 */
124#define OFDM_ITB_FREQ_2 (0x4D)
125
126/* 0x4E OFDM_CAS_CTL */
127#define OFDM_CAS_CTL (0x4E)
128#define ACSDIS (0x40)
129#define CCSEN (0x80)
130
131/* 0x4F CAS_FREQ */
132#define CAS_FREQ (0x4F)
133
134/* 0x51 OFDM_SYR_CTL */
135#define OFDM_SYR_CTL (0x51)
136#define SIXTH_ENABLE (0x80)
137#define SYR_TRACKING_DISABLE (0x01)
138
139/* 0x52 OFDM_SYR_STAT */
140#define OFDM_SYR_STAT (0x52)
141#define GI14_2K_SYR_LOCK (0x13)
142#define GI14_8K_SYR_LOCK (0x17)
143#define GI14_SYR_LOCK (0x10)
144
145/* 0x55 OFDM_SYR_OFFSET_1 */
146#define OFDM_SYR_OFFSET_1 (0x55)
147
148/* 0x56 OFDM_SYR_OFFSET_2 */
149#define OFDM_SYR_OFFSET_2 (0x56)
150
151/* 0x58 OFDM_SCR_CTL */
152#define OFDM_SCR_CTL (0x58)
153#define SYR_ADJ_DECAY_MASK (0x70)
154#define SYR_ADJ_DECAY (0x30)
155
156/* 0x59 OFDM_PPM_CTL_1 */
157#define OFDM_PPM_CTL_1 (0x59)
158#define PPMMAX_MASK (0x30)
159#define PPM256 (0x30)
160
161/* 0x5B OFDM_TRL_NOMINALRATE_1 */
162#define OFDM_TRL_NOMINALRATE_1 (0x5B)
163
164/* 0x5C OFDM_TRL_NOMINALRATE_2 */
165#define OFDM_TRL_NOMINALRATE_2 (0x5C)
166
167/* 0x5D OFDM_TRL_TIME_1 */
168#define OFDM_TRL_TIME_1 (0x5D)
169
170/* 0x60 OFDM_CRL_FREQ_1 */
171#define OFDM_CRL_FREQ_1 (0x60)
172
173/* 0x63 OFDM_CHC_CTL_1 */
174#define OFDM_CHC_CTL_1 (0x63)
175#define MANMEAN1 (0xF0);
176#define CHCFIR (0x01)
177
178/* 0x64 OFDM_CHC_SNR */
179#define OFDM_CHC_SNR (0x64)
180
181/* 0x65 OFDM_BDI_CTL */
182#define OFDM_BDI_CTL (0x65)
183#define LP_SELECT (0x02)
184
185/* 0x67 OFDM_TPS_RCVD_1 */
186#define OFDM_TPS_RCVD_1 (0x67)
187#define TPSFRAME (0x03)
188
189/* 0x68 OFDM_TPS_RCVD_2 */
190#define OFDM_TPS_RCVD_2 (0x68)
191
192/* 0x69 OFDM_TPS_RCVD_3 */
193#define OFDM_TPS_RCVD_3 (0x69)
194
195/* 0x6A OFDM_TPS_RCVD_4 */
196#define OFDM_TPS_RCVD_4 (0x6A)
197
198/* 0x6B OFDM_TPS_RESERVED_1 */
199#define OFDM_TPS_RESERVED_1 (0x6B)
200
201/* 0x6C OFDM_TPS_RESERVED_2 */
202#define OFDM_TPS_RESERVED_2 (0x6C)
203
204/* 0x73 OFDM_MSC_REV */
205#define OFDM_MSC_REV (0x73)
206
207/* 0x76 OFDM_SNR_CARRIER_2 */
208#define OFDM_SNR_CARRIER_2 (0x76)
209#define MEAN_MASK (0x80)
210#define MEANBIT (0x80)
211
212/* 0x80 ANALOG_CONTROL_0 */
213#define ANALOG_CONTROL_0 (0x80)
214#define POWER_DOWN_ADC (0x40)
215
216/* 0x81 ENABLE_TUNER_IIC */
217#define ENABLE_TUNER_IIC (0x81)
218#define ENABLE_TUNER_BIT (0x01)
219
220/* 0x82 EN_DMD_RACQ */
221#define EN_DMD_RACQ (0x82)
222#define EN_DMD_RACQ_REG_VAL (0x81)
223#define EN_DMD_RACQ_REG_VAL_14 (0x01)
224
225/* 0x84 SNR_COMMAND */
226#define SNR_COMMAND (0x84)
227#define SNRStat (0x80)
228
229/* 0x85 SNRCARRIERNUMBER_LSB */
230#define SNRCARRIERNUMBER_LSB (0x85)
231
232/* 0x87 SNRMINTHRESHOLD_LSB */
233#define SNRMINTHRESHOLD_LSB (0x87)
234
235/* 0x89 SNR_PER_CARRIER_LSB */
236#define SNR_PER_CARRIER_LSB (0x89)
237
238/* 0x8B SNRBELOWTHRESHOLD_LSB */
239#define SNRBELOWTHRESHOLD_LSB (0x8B)
240
241/* 0x91 RF_AGC_VAL_1 */
242#define RF_AGC_VAL_1 (0x91)
243
244/* 0x92 RF_AGC_STATUS */
245#define RF_AGC_STATUS (0x92)
246
247/* 0x98 DIAG_CONFIG */
248#define DIAG_CONFIG (0x98)
249#define DIAG_MASK (0x70)
250#define TB_SET (0x10)
251#define TRAN_SELECT (0x07)
252#define SERIAL_SELECT (0x01)
253
254/* 0x99 SUB_DIAG_MODE_SEL */
255#define SUB_DIAG_MODE_SEL (0x99)
256#define CLKINVERSION (0x01)
257
258/* 0x9A TS_FORMAT */
259#define TS_FORMAT (0x9A)
260#define ERROR_SENSE (0x08)
261#define VALID_SENSE (0x04)
262#define SYNC_SENSE (0x02)
263#define GATED_CLOCK (0x01)
264
265#define NXT6000ASICDEVICE (0x0b)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
new file mode 100644
index 000000000000..df5dee7760a3
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -0,0 +1,628 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
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
25/*
26 * This driver needs two external firmware files. Please copy
27 * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
28 * /usr/lib/hotplug/firmware/ or /lib/firmware/
29 * (depending on configuration of firmware hotplug).
30 */
31#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
32#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <asm/byteorder.h>
40
41#include "dvb_frontend.h"
42#include "dvb-pll.h"
43#include "or51132.h"
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "or51132: " args); \
49 } while (0)
50
51
52struct or51132_state
53{
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56
57 /* Configuration settings */
58 const struct or51132_config* config;
59
60 struct dvb_frontend frontend;
61
62 /* Demodulator private data */
63 fe_modulation_t current_modulation;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len)
70{
71 int err;
72 struct i2c_msg msg;
73 msg.addr = reg;
74 msg.flags = 0;
75 msg.len = len;
76 msg.buf = buf;
77
78 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
79 printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err);
80 return -EREMOTEIO;
81 }
82
83 return 0;
84}
85
86static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len)
87{
88 int err;
89 struct i2c_msg msg;
90 msg.addr = reg;
91 msg.flags = I2C_M_RD;
92 msg.len = len;
93 msg.buf = buf;
94
95 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
96 printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err);
97 return -EREMOTEIO;
98 }
99
100 return 0;
101}
102
103static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
104{
105 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
106 static u8 run_buf[] = {0x7F,0x01};
107 static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
108 u8 rec_buf[14];
109 u8 cmd_buf[14];
110 u32 firmwareAsize, firmwareBsize;
111 int i,ret;
112
113 dprintk("Firmware is %Zd bytes\n",fw->size);
114
115 /* Get size of firmware A and B */
116 firmwareAsize = le32_to_cpu(*((u32*)fw->data));
117 dprintk("FirmwareA is %i bytes\n",firmwareAsize);
118 firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4)));
119 dprintk("FirmwareB is %i bytes\n",firmwareBsize);
120
121 /* Upload firmware */
122 if ((ret = i2c_writebytes(state,state->config->demod_address,
123 &fw->data[8],firmwareAsize))) {
124 printk(KERN_WARNING "or51132: load_firmware error 1\n");
125 return ret;
126 }
127 msleep(1); /* 1ms */
128 if ((ret = i2c_writebytes(state,state->config->demod_address,
129 &fw->data[8+firmwareAsize],firmwareBsize))) {
130 printk(KERN_WARNING "or51132: load_firmware error 2\n");
131 return ret;
132 }
133 msleep(1); /* 1ms */
134
135 if ((ret = i2c_writebytes(state,state->config->demod_address,
136 run_buf,2))) {
137 printk(KERN_WARNING "or51132: load_firmware error 3\n");
138 return ret;
139 }
140
141 /* Wait at least 5 msec */
142 msleep(20); /* 10ms */
143
144 if ((ret = i2c_writebytes(state,state->config->demod_address,
145 run_buf,2))) {
146 printk(KERN_WARNING "or51132: load_firmware error 4\n");
147 return ret;
148 }
149
150 /* 50ms for operation to begin */
151 msleep(50);
152
153 /* Read back ucode version to besure we loaded correctly and are really up and running */
154 /* Get uCode version */
155 cmd_buf[0] = 0x10;
156 cmd_buf[1] = 0x10;
157 cmd_buf[2] = 0x00;
158 cmd_buf[3] = 0x00;
159 msleep(20); /* 20ms */
160 if ((ret = i2c_writebytes(state,state->config->demod_address,
161 cmd_buf,3))) {
162 printk(KERN_WARNING "or51132: load_firmware error a\n");
163 return ret;
164 }
165
166 cmd_buf[0] = 0x04;
167 cmd_buf[1] = 0x17;
168 cmd_buf[2] = 0x00;
169 cmd_buf[3] = 0x00;
170 msleep(20); /* 20ms */
171 if ((ret = i2c_writebytes(state,state->config->demod_address,
172 cmd_buf,2))) {
173 printk(KERN_WARNING "or51132: load_firmware error b\n");
174 return ret;
175 }
176
177 cmd_buf[0] = 0x00;
178 cmd_buf[1] = 0x00;
179 cmd_buf[2] = 0x00;
180 cmd_buf[3] = 0x00;
181 msleep(20); /* 20ms */
182 if ((ret = i2c_writebytes(state,state->config->demod_address,
183 cmd_buf,2))) {
184 printk(KERN_WARNING "or51132: load_firmware error c\n");
185 return ret;
186 }
187
188 for(i=0;i<4;i++) {
189 msleep(20); /* 20ms */
190 get_ver_buf[4] = i+1;
191 if ((ret = i2c_readbytes(state,state->config->demod_address,
192 &rec_buf[i*2],2))) {
193 printk(KERN_WARNING
194 "or51132: load_firmware error d - %d\n",i);
195 return ret;
196 }
197 }
198
199 printk(KERN_WARNING
200 "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
201 rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
202 rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
203 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
204 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
205
206 cmd_buf[0] = 0x10;
207 cmd_buf[1] = 0x00;
208 cmd_buf[2] = 0x00;
209 cmd_buf[3] = 0x00;
210 msleep(20); /* 20ms */
211 if ((ret = i2c_writebytes(state,state->config->demod_address,
212 cmd_buf,3))) {
213 printk(KERN_WARNING "or51132: load_firmware error e\n");
214 return ret;
215 }
216 return 0;
217};
218
219static int or51132_init(struct dvb_frontend* fe)
220{
221 return 0;
222}
223
224static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
225{
226 *ber = 0;
227 return 0;
228}
229
230static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
231{
232 *ucblocks = 0;
233 return 0;
234}
235
236static int or51132_sleep(struct dvb_frontend* fe)
237{
238 return 0;
239}
240
241static int or51132_setmode(struct dvb_frontend* fe)
242{
243 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
244 unsigned char cmd_buf[4];
245
246 dprintk("setmode %d\n",(int)state->current_modulation);
247 /* set operation mode in Receiver 1 register; */
248 cmd_buf[0] = 0x04;
249 cmd_buf[1] = 0x01;
250 switch (state->current_modulation) {
251 case QAM_256:
252 case QAM_64:
253 case QAM_AUTO:
254 /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/
255 cmd_buf[2] = 0x5F;
256 break;
257 case VSB_8:
258 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/
259 cmd_buf[2] = 0x50;
260 break;
261 default:
262 printk("setmode:Modulation set to unsupported value\n");
263 };
264 cmd_buf[3] = 0x00;
265 if (i2c_writebytes(state,state->config->demod_address,
266 cmd_buf,3)) {
267 printk(KERN_WARNING "or51132: set_mode error 1\n");
268 return -1;
269 }
270 dprintk("or51132: set #1 to %02x\n", cmd_buf[2]);
271
272 /* Set operation mode in Receiver 6 register */
273 cmd_buf[0] = 0x1C;
274 switch (state->current_modulation) {
275 case QAM_AUTO:
276 /* REC MODE Normal Carrier Lock */
277 cmd_buf[1] = 0x00;
278 /* Channel MODE Auto QAM64/256 */
279 cmd_buf[2] = 0x4f;
280 break;
281 case QAM_256:
282 /* REC MODE Normal Carrier Lock */
283 cmd_buf[1] = 0x00;
284 /* Channel MODE QAM256 */
285 cmd_buf[2] = 0x45;
286 break;
287 case QAM_64:
288 /* REC MODE Normal Carrier Lock */
289 cmd_buf[1] = 0x00;
290 /* Channel MODE QAM64 */
291 cmd_buf[2] = 0x43;
292 break;
293 case VSB_8:
294 /* REC MODE inv IF spectrum, Normal */
295 cmd_buf[1] = 0x03;
296 /* Channel MODE ATSC/VSB8 */
297 cmd_buf[2] = 0x06;
298 break;
299 default:
300 printk("setmode: Modulation set to unsupported value\n");
301 };
302 cmd_buf[3] = 0x00;
303 msleep(20); /* 20ms */
304 if (i2c_writebytes(state,state->config->demod_address,
305 cmd_buf,3)) {
306 printk(KERN_WARNING "or51132: set_mode error 2\n");
307 return -1;
308 }
309 dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]);
310
311 return 0;
312}
313
314static int or51132_set_parameters(struct dvb_frontend* fe,
315 struct dvb_frontend_parameters *param)
316{
317 int ret;
318 u8 buf[4];
319 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
320 const struct firmware *fw;
321
322 /* Change only if we are actually changing the modulation */
323 if (state->current_modulation != param->u.vsb.modulation) {
324 switch(param->u.vsb.modulation) {
325 case VSB_8:
326 dprintk("set_parameters VSB MODE\n");
327 printk("or51132: Waiting for firmware upload(%s)...\n",
328 OR51132_VSB_FIRMWARE);
329 ret = request_firmware(&fw, OR51132_VSB_FIRMWARE,
330 &state->i2c->dev);
331 if (ret){
332 printk(KERN_WARNING "or51132: No firmware up"
333 "loaded(timeout or file not found?)\n");
334 return ret;
335 }
336 /* Set non-punctured clock for VSB */
337 state->config->set_ts_params(fe, 0);
338 break;
339 case QAM_AUTO:
340 case QAM_64:
341 case QAM_256:
342 dprintk("set_parameters QAM MODE\n");
343 printk("or51132: Waiting for firmware upload(%s)...\n",
344 OR51132_QAM_FIRMWARE);
345 ret = request_firmware(&fw, OR51132_QAM_FIRMWARE,
346 &state->i2c->dev);
347 if (ret){
348 printk(KERN_WARNING "or51132: No firmware up"
349 "loaded(timeout or file not found?)\n");
350 return ret;
351 }
352 /* Set punctured clock for QAM */
353 state->config->set_ts_params(fe, 1);
354 break;
355 default:
356 printk("or51132:Modulation type(%d) UNSUPPORTED\n",
357 param->u.vsb.modulation);
358 return -1;
359 };
360 ret = or51132_load_firmware(fe, fw);
361 release_firmware(fw);
362 if (ret) {
363 printk(KERN_WARNING "or51132: Writing firmware to "
364 "device failed!\n");
365 return ret;
366 }
367 printk("or51132: Firmware upload complete.\n");
368
369 state->current_modulation = param->u.vsb.modulation;
370 or51132_setmode(fe);
371 }
372
373 /* Change only if we are actually changing the channel */
374 if (state->current_frequency != param->frequency) {
375 dvb_pll_configure(state->config->pll_desc, buf,
376 param->frequency, 0);
377 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
378 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
379 if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
380 printk(KERN_WARNING "or51132: set_parameters error "
381 "writing to tuner\n");
382
383 /* Set to current mode */
384 or51132_setmode(fe);
385
386 /* Update current frequency */
387 state->current_frequency = param->frequency;
388 }
389 return 0;
390}
391
392static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
393{
394 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
395 unsigned char rec_buf[2];
396 unsigned char snd_buf[2];
397 *status = 0;
398
399 /* Receiver Status */
400 snd_buf[0]=0x04;
401 snd_buf[1]=0x00;
402 msleep(30); /* 30ms */
403 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
404 printk(KERN_WARNING "or51132: read_status write error\n");
405 return -1;
406 }
407 msleep(30); /* 30ms */
408 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
409 printk(KERN_WARNING "or51132: read_status read error\n");
410 return -1;
411 }
412 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
413
414 if (rec_buf[1] & 0x01) { /* Receiver Lock */
415 *status |= FE_HAS_SIGNAL;
416 *status |= FE_HAS_CARRIER;
417 *status |= FE_HAS_VITERBI;
418 *status |= FE_HAS_SYNC;
419 *status |= FE_HAS_LOCK;
420 }
421 return 0;
422}
423
424/* log10-1 table at .5 increments from 1 to 100.5 */
425static unsigned int i100x20log10[] = {
426 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
427 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
428 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
429 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
430 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
431 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
432 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
433 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
434 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
435 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
436 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
437 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
438 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
439 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
440 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
441 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
442 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
443 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
444 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
445 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
446};
447
448static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
449
450static unsigned int i20Log10(unsigned short val)
451{
452 unsigned int rntval = 100;
453 unsigned int tmp = val;
454 unsigned int exp = 1;
455
456 while(tmp > 100) {tmp /= 100; exp++;}
457
458 val = (2 * val)/denom[exp];
459 if (exp > 1) rntval = 2000*exp;
460
461 rntval += i100x20log10[val];
462 return rntval;
463}
464
465static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
466{
467 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
468 unsigned char rec_buf[2];
469 unsigned char snd_buf[2];
470 u8 rcvr_stat;
471 u16 snr_equ;
472 int usK;
473
474 snd_buf[0]=0x04;
475 snd_buf[1]=0x02; /* SNR after Equalizer */
476 msleep(30); /* 30ms */
477 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
478 printk(KERN_WARNING "or51132: read_status write error\n");
479 return -1;
480 }
481 msleep(30); /* 30ms */
482 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
483 printk(KERN_WARNING "or51132: read_status read error\n");
484 return -1;
485 }
486 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
487 dprintk("read_signal_strength snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
488
489 /* Receiver Status */
490 snd_buf[0]=0x04;
491 snd_buf[1]=0x00;
492 msleep(30); /* 30ms */
493 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
494 printk(KERN_WARNING "or51132: read_signal_strength read_status write error\n");
495 return -1;
496 }
497 msleep(30); /* 30ms */
498 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
499 printk(KERN_WARNING "or51132: read_signal_strength read_status read error\n");
500 return -1;
501 }
502 dprintk("read_signal_strength read_status %x %x\n",rec_buf[0],rec_buf[1]);
503 rcvr_stat = rec_buf[1];
504 usK = (rcvr_stat & 0x10) ? 3 : 0;
505
506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
507 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 dprintk("read_signal_strength %i\n",*strength);
509
510 return 0;
511}
512
513static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
514{
515 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
516 unsigned char rec_buf[2];
517 unsigned char snd_buf[2];
518 u16 snr_equ;
519
520 snd_buf[0]=0x04;
521 snd_buf[1]=0x02; /* SNR after Equalizer */
522 msleep(30); /* 30ms */
523 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
524 printk(KERN_WARNING "or51132: read_snr write error\n");
525 return -1;
526 }
527 msleep(30); /* 30ms */
528 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
529 printk(KERN_WARNING "or51132: read_snr dvr read error\n");
530 return -1;
531 }
532 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
533 dprintk("read_snr snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
534
535 *snr = 0xFFFF - snr_equ;
536 dprintk("read_snr %i\n",*snr);
537
538 return 0;
539}
540
541static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
542{
543 fe_tune_settings->min_delay_ms = 500;
544 fe_tune_settings->step_size = 0;
545 fe_tune_settings->max_drift = 0;
546
547 return 0;
548}
549
550static void or51132_release(struct dvb_frontend* fe)
551{
552 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
553 kfree(state);
554}
555
556static struct dvb_frontend_ops or51132_ops;
557
558struct dvb_frontend* or51132_attach(const struct or51132_config* config,
559 struct i2c_adapter* i2c)
560{
561 struct or51132_state* state = NULL;
562
563 /* Allocate memory for the internal state */
564 state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
565 if (state == NULL)
566 goto error;
567
568 /* Setup the state */
569 state->config = config;
570 state->i2c = i2c;
571 memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
572 state->current_frequency = -1;
573 state->current_modulation = -1;
574
575 /* Create dvb_frontend */
576 state->frontend.ops = &state->ops;
577 state->frontend.demodulator_priv = state;
578 return &state->frontend;
579
580error:
581 if (state)
582 kfree(state);
583 return NULL;
584}
585
586static struct dvb_frontend_ops or51132_ops = {
587
588 .info = {
589 .name = "Oren OR51132 VSB/QAM Frontend",
590 .type = FE_ATSC,
591 .frequency_min = 44000000,
592 .frequency_max = 958000000,
593 .frequency_stepsize = 166666,
594 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
595 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
596 FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
597 FE_CAN_8VSB
598 },
599
600 .release = or51132_release,
601
602 .init = or51132_init,
603 .sleep = or51132_sleep,
604
605 .set_frontend = or51132_set_parameters,
606 .get_tune_settings = or51132_get_tune_settings,
607
608 .read_status = or51132_read_status,
609 .read_ber = or51132_read_ber,
610 .read_signal_strength = or51132_read_signal_strength,
611 .read_snr = or51132_read_snr,
612 .read_ucblocks = or51132_read_ucblocks,
613};
614
615module_param(debug, int, 0644);
616MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
617
618MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
619MODULE_AUTHOR("Kirk Lapray");
620MODULE_LICENSE("GPL");
621
622EXPORT_SYMBOL(or51132_attach);
623
624/*
625 * Local variables:
626 * c-basic-offset: 8
627 * End:
628 */
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
new file mode 100644
index 000000000000..622cdd18381b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -0,0 +1,48 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 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*/
21
22#ifndef OR51132_H
23#define OR51132_H
24
25#include <linux/firmware.h>
26#include <linux/dvb/frontend.h>
27
28struct or51132_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32 u8 pll_address;
33 struct dvb_pll_desc *pll_desc;
34
35 /* Need to set device param for start_dma */
36 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
37};
38
39extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // OR51132_H
43
44/*
45 * Local variables:
46 * c-basic-offset: 8
47 * End:
48 */
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
new file mode 100644
index 000000000000..ad56a9958404
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -0,0 +1,631 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
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
25/*
26 * This driver needs external firmware. Please use the command
27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
29 */
30#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/device.h>
36#include <linux/firmware.h>
37#include <asm/byteorder.h>
38
39#include "dvb_frontend.h"
40#include "or51211.h"
41
42static int debug;
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "or51211: " args); \
46 } while (0)
47
48static u8 run_buf[] = {0x7f,0x01};
49static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
50
51struct or51211_state {
52
53 struct i2c_adapter* i2c;
54 struct dvb_frontend_ops ops;
55
56 /* Configuration settings */
57 const struct or51211_config* config;
58
59 struct dvb_frontend frontend;
60 struct bt878* bt;
61
62 /* Demodulator private data */
63 u8 initialized:1;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
70 int len)
71{
72 int err;
73 struct i2c_msg msg;
74 msg.addr = reg;
75 msg.flags = 0;
76 msg.len = len;
77 msg.buf = buf;
78
79 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
80 printk(KERN_WARNING "or51211: i2c_writebytes error "
81 "(addr %02x, err == %i)\n", reg, err);
82 return -EREMOTEIO;
83 }
84
85 return 0;
86}
87
88static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len)
89{
90 int err;
91 struct i2c_msg msg;
92 msg.addr = reg;
93 msg.flags = I2C_M_RD;
94 msg.len = len;
95 msg.buf = buf;
96
97 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "or51211: i2c_readbytes error "
99 "(addr %02x, err == %i)\n", reg, err);
100 return -EREMOTEIO;
101 }
102
103 return 0;
104}
105
106static int or51211_load_firmware (struct dvb_frontend* fe,
107 const struct firmware *fw)
108{
109 struct or51211_state* state = fe->demodulator_priv;
110 u8 tudata[585];
111 int i;
112
113 dprintk("Firmware is %d bytes\n",fw->size);
114
115 /* Get eprom data */
116 tudata[0] = 17;
117 if (i2c_writebytes(state,0x50,tudata,1)) {
118 printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
119 return -1;
120 }
121 if (i2c_readbytes(state,0x50,&tudata[145],192)) {
122 printk(KERN_WARNING "or51211: load_firmware error eprom\n");
123 return -1;
124 }
125
126 /* Create firmware buffer */
127 for (i = 0; i < 145; i++)
128 tudata[i] = fw->data[i];
129
130 for (i = 0; i < 248; i++)
131 tudata[i+337] = fw->data[145+i];
132
133 state->config->reset(fe);
134
135 if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
136 printk(KERN_WARNING "or51211: load_firmware error 1\n");
137 return -1;
138 }
139 msleep(1);
140
141 if (i2c_writebytes(state,state->config->demod_address,
142 &fw->data[393],8125)) {
143 printk(KERN_WARNING "or51211: load_firmware error 2\n");
144 return -1;
145 }
146 msleep(1);
147
148 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
149 printk(KERN_WARNING "or51211: load_firmware error 3\n");
150 return -1;
151 }
152
153 /* Wait at least 5 msec */
154 msleep(10);
155 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
156 printk(KERN_WARNING "or51211: load_firmware error 4\n");
157 return -1;
158 }
159 msleep(10);
160
161 printk("or51211: Done.\n");
162 return 0;
163};
164
165static int or51211_setmode(struct dvb_frontend* fe, int mode)
166{
167 struct or51211_state* state = fe->demodulator_priv;
168 u8 rec_buf[14];
169
170 state->config->setmode(fe, mode);
171
172 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
173 printk(KERN_WARNING "or51211: setmode error 1\n");
174 return -1;
175 }
176
177 /* Wait at least 5 msec */
178 msleep(10);
179 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
180 printk(KERN_WARNING "or51211: setmode error 2\n");
181 return -1;
182 }
183
184 msleep(10);
185
186 /* Set operation mode in Receiver 1 register;
187 * type 1:
188 * data 0x50h Automatic sets receiver channel conditions
189 * Automatic NTSC rejection filter
190 * Enable MPEG serial data output
191 * MPEG2tr
192 * High tuner phase noise
193 * normal +/-150kHz Carrier acquisition range
194 */
195 if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
196 printk(KERN_WARNING "or51211: setmode error 3\n");
197 return -1;
198 }
199
200 rec_buf[0] = 0x04;
201 rec_buf[1] = 0x00;
202 rec_buf[2] = 0x03;
203 rec_buf[3] = 0x00;
204 msleep(20);
205 if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
206 printk(KERN_WARNING "or51211: setmode error 5\n");
207 }
208 msleep(3);
209 if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
210 printk(KERN_WARNING "or51211: setmode error 6");
211 return -1;
212 }
213 dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
214
215 return 0;
216}
217
218static int or51211_set_parameters(struct dvb_frontend* fe,
219 struct dvb_frontend_parameters *param)
220{
221 struct or51211_state* state = fe->demodulator_priv;
222 u32 freq = 0;
223 u16 tunerfreq = 0;
224 u8 buf[4];
225
226 /* Change only if we are actually changing the channel */
227 if (state->current_frequency != param->frequency) {
228 freq = 44000 + (param->frequency/1000);
229 tunerfreq = freq * 16/1000;
230
231 dprintk("set_parameters frequency = %d (tunerfreq = %d)\n",
232 param->frequency,tunerfreq);
233
234 buf[0] = (tunerfreq >> 8) & 0x7F;
235 buf[1] = (tunerfreq & 0xFF);
236 buf[2] = 0x8E;
237
238 if (param->frequency < 157250000) {
239 buf[3] = 0xA0;
240 dprintk("set_parameters VHF low range\n");
241 } else if (param->frequency < 454000000) {
242 buf[3] = 0x90;
243 dprintk("set_parameters VHF high range\n");
244 } else {
245 buf[3] = 0x30;
246 dprintk("set_parameters UHF range\n");
247 }
248 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
249 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
250
251 if (i2c_writebytes(state,0xC2>>1,buf,4))
252 printk(KERN_WARNING "or51211:set_parameters error "
253 "writing to tuner\n");
254
255 /* Set to ATSC mode */
256 or51211_setmode(fe,0);
257
258 /* Update current frequency */
259 state->current_frequency = param->frequency;
260 }
261 return 0;
262}
263
264static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
265{
266 struct or51211_state* state = fe->demodulator_priv;
267 unsigned char rec_buf[2];
268 unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
269 *status = 0;
270
271 /* Receiver Status */
272 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
273 printk(KERN_WARNING "or51132: read_status write error\n");
274 return -1;
275 }
276 msleep(3);
277 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
278 printk(KERN_WARNING "or51132: read_status read error\n");
279 return -1;
280 }
281 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
282
283 if (rec_buf[0] & 0x01) { /* Receiver Lock */
284 *status |= FE_HAS_SIGNAL;
285 *status |= FE_HAS_CARRIER;
286 *status |= FE_HAS_VITERBI;
287 *status |= FE_HAS_SYNC;
288 *status |= FE_HAS_LOCK;
289 }
290 return 0;
291}
292
293/* log10-1 table at .5 increments from 1 to 100.5 */
294static unsigned int i100x20log10[] = {
295 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
296 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
297 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
298 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
299 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
300 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
301 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
302 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
303 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
304 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
305 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
306 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
307 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
308 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
309 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
310 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
311 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
312 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
313 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
314 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
315};
316
317static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
318
319static unsigned int i20Log10(unsigned short val)
320{
321 unsigned int rntval = 100;
322 unsigned int tmp = val;
323 unsigned int exp = 1;
324
325 while(tmp > 100) {tmp /= 100; exp++;}
326
327 val = (2 * val)/denom[exp];
328 if (exp > 1) rntval = 2000*exp;
329
330 rntval += i100x20log10[val];
331 return rntval;
332}
333
334static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
335{
336 struct or51211_state* state = fe->demodulator_priv;
337 u8 rec_buf[2];
338 u8 snd_buf[4];
339 u8 snr_equ;
340
341 /* SNR after Equalizer */
342 snd_buf[0] = 0x04;
343 snd_buf[1] = 0x00;
344 snd_buf[2] = 0x04;
345 snd_buf[3] = 0x00;
346
347 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
348 printk(KERN_WARNING "or51211: read_status write error\n");
349 return -1;
350 }
351 msleep(3);
352 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
353 printk(KERN_WARNING "or51211: read_status read error\n");
354 return -1;
355 }
356 snr_equ = rec_buf[0] & 0xff;
357
358 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
359 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
360
361 dprintk("read_signal_strength %i\n",*strength);
362
363 return 0;
364}
365
366static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
367{
368 struct or51211_state* state = fe->demodulator_priv;
369 u8 rec_buf[2];
370 u8 snd_buf[4];
371
372 /* SNR after Equalizer */
373 snd_buf[0] = 0x04;
374 snd_buf[1] = 0x00;
375 snd_buf[2] = 0x04;
376 snd_buf[3] = 0x00;
377
378 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
379 printk(KERN_WARNING "or51211: read_status write error\n");
380 return -1;
381 }
382 msleep(3);
383 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
384 printk(KERN_WARNING "or51211: read_status read error\n");
385 return -1;
386 }
387 *snr = rec_buf[0] & 0xff;
388
389 dprintk("read_snr %i\n",*snr);
390
391 return 0;
392}
393
394static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
395{
396 *ber = -ENOSYS;
397 return 0;
398}
399
400static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
401{
402 *ucblocks = -ENOSYS;
403 return 0;
404}
405
406static int or51211_sleep(struct dvb_frontend* fe)
407{
408 return 0;
409}
410
411static int or51211_init(struct dvb_frontend* fe)
412{
413 struct or51211_state* state = fe->demodulator_priv;
414 const struct or51211_config* config = state->config;
415 const struct firmware* fw;
416 unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
417 unsigned char rec_buf[14];
418 int ret,i;
419
420 if (!state->initialized) {
421 /* Request the firmware, this will block until it uploads */
422 printk(KERN_INFO "or51211: Waiting for firmware upload "
423 "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
424 ret = config->request_firmware(fe, &fw,
425 OR51211_DEFAULT_FIRMWARE);
426 printk(KERN_INFO "or51211:Got Hotplug firmware\n");
427 if (ret) {
428 printk(KERN_WARNING "or51211: No firmware uploaded "
429 "(timeout or file not found?)\n");
430 return ret;
431 }
432
433 ret = or51211_load_firmware(fe, fw);
434 if (ret) {
435 printk(KERN_WARNING "or51211: Writing firmware to "
436 "device failed!\n");
437 release_firmware(fw);
438 return ret;
439 }
440 printk(KERN_INFO "or51211: Firmware upload complete.\n");
441
442 /* Set operation mode in Receiver 1 register;
443 * type 1:
444 * data 0x50h Automatic sets receiver channel conditions
445 * Automatic NTSC rejection filter
446 * Enable MPEG serial data output
447 * MPEG2tr
448 * High tuner phase noise
449 * normal +/-150kHz Carrier acquisition range
450 */
451 if (i2c_writebytes(state,state->config->demod_address,
452 cmd_buf,3)) {
453 printk(KERN_WARNING "or51211: Load DVR Error 5\n");
454 return -1;
455 }
456
457 /* Read back ucode version to besure we loaded correctly */
458 /* and are really up and running */
459 rec_buf[0] = 0x04;
460 rec_buf[1] = 0x00;
461 rec_buf[2] = 0x03;
462 rec_buf[3] = 0x00;
463 msleep(30);
464 if (i2c_writebytes(state,state->config->demod_address,
465 rec_buf,3)) {
466 printk(KERN_WARNING "or51211: Load DVR Error A\n");
467 return -1;
468 }
469 msleep(3);
470 if (i2c_readbytes(state,state->config->demod_address,
471 &rec_buf[10],2)) {
472 printk(KERN_WARNING "or51211: Load DVR Error B\n");
473 return -1;
474 }
475
476 rec_buf[0] = 0x04;
477 rec_buf[1] = 0x00;
478 rec_buf[2] = 0x01;
479 rec_buf[3] = 0x00;
480 msleep(20);
481 if (i2c_writebytes(state,state->config->demod_address,
482 rec_buf,3)) {
483 printk(KERN_WARNING "or51211: Load DVR Error C\n");
484 return -1;
485 }
486 msleep(3);
487 if (i2c_readbytes(state,state->config->demod_address,
488 &rec_buf[12],2)) {
489 printk(KERN_WARNING "or51211: Load DVR Error D\n");
490 return -1;
491 }
492
493 for (i = 0; i < 8; i++)
494 rec_buf[i]=0xed;
495
496 for (i = 0; i < 5; i++) {
497 msleep(30);
498 get_ver_buf[4] = i+1;
499 if (i2c_writebytes(state,state->config->demod_address,
500 get_ver_buf,5)) {
501 printk(KERN_WARNING "or51211:Load DVR Error 6"
502 " - %d\n",i);
503 return -1;
504 }
505 msleep(3);
506
507 if (i2c_readbytes(state,state->config->demod_address,
508 &rec_buf[i*2],2)) {
509 printk(KERN_WARNING "or51211:Load DVR Error 7"
510 " - %d\n",i);
511 return -1;
512 }
513 /* If we didn't receive the right index, try again */
514 if ((int)rec_buf[i*2+1]!=i+1){
515 i--;
516 }
517 }
518 dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
519 rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
520 rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
521 rec_buf[8], rec_buf[9]);
522
523 printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
524 " Status %02x\n",
525 rec_buf[2], rec_buf[4],rec_buf[6],
526 rec_buf[12],rec_buf[10]);
527
528 rec_buf[0] = 0x04;
529 rec_buf[1] = 0x00;
530 rec_buf[2] = 0x03;
531 rec_buf[3] = 0x00;
532 msleep(20);
533 if (i2c_writebytes(state,state->config->demod_address,
534 rec_buf,3)) {
535 printk(KERN_WARNING "or51211: Load DVR Error 8\n");
536 return -1;
537 }
538 msleep(20);
539 if (i2c_readbytes(state,state->config->demod_address,
540 &rec_buf[8],2)) {
541 printk(KERN_WARNING "or51211: Load DVR Error 9\n");
542 return -1;
543 }
544 state->initialized = 1;
545 }
546
547 return 0;
548}
549
550static int or51211_get_tune_settings(struct dvb_frontend* fe,
551 struct dvb_frontend_tune_settings* fesettings)
552{
553 fesettings->min_delay_ms = 500;
554 fesettings->step_size = 0;
555 fesettings->max_drift = 0;
556 return 0;
557}
558
559static void or51211_release(struct dvb_frontend* fe)
560{
561 struct or51211_state* state = fe->demodulator_priv;
562 state->config->sleep(fe);
563 kfree(state);
564}
565
566static struct dvb_frontend_ops or51211_ops;
567
568struct dvb_frontend* or51211_attach(const struct or51211_config* config,
569 struct i2c_adapter* i2c)
570{
571 struct or51211_state* state = NULL;
572
573 /* Allocate memory for the internal state */
574 state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
575 if (state == NULL)
576 goto error;
577
578 /* Setup the state */
579 state->config = config;
580 state->i2c = i2c;
581 memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
582 state->initialized = 0;
583 state->current_frequency = 0;
584
585 /* Create dvb_frontend */
586 state->frontend.ops = &state->ops;
587 state->frontend.demodulator_priv = state;
588 return &state->frontend;
589
590error:
591 kfree(state);
592 return NULL;
593}
594
595static struct dvb_frontend_ops or51211_ops = {
596
597 .info = {
598 .name = "Oren OR51211 VSB Frontend",
599 .type = FE_ATSC,
600 .frequency_min = 44000000,
601 .frequency_max = 958000000,
602 .frequency_stepsize = 166666,
603 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
604 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
605 FE_CAN_8VSB
606 },
607
608 .release = or51211_release,
609
610 .init = or51211_init,
611 .sleep = or51211_sleep,
612
613 .set_frontend = or51211_set_parameters,
614 .get_tune_settings = or51211_get_tune_settings,
615
616 .read_status = or51211_read_status,
617 .read_ber = or51211_read_ber,
618 .read_signal_strength = or51211_read_signal_strength,
619 .read_snr = or51211_read_snr,
620 .read_ucblocks = or51211_read_ucblocks,
621};
622
623module_param(debug, int, 0644);
624MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
625
626MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
627MODULE_AUTHOR("Kirk Lapray");
628MODULE_LICENSE("GPL");
629
630EXPORT_SYMBOL(or51211_attach);
631
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
new file mode 100644
index 000000000000..13a5a3afbf8b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -0,0 +1,44 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 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*/
21
22#ifndef OR51211_H
23#define OR51211_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct or51211_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32
33 /* Request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35 void (*setmode)(struct dvb_frontend * fe, int mode);
36 void (*reset)(struct dvb_frontend * fe);
37 void (*sleep)(struct dvb_frontend * fe);
38};
39
40extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // OR51211_H
44
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
new file mode 100644
index 000000000000..58ad34ef0a00
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -0,0 +1,614 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34#include <linux/delay.h>
35
36#include "dvb_frontend.h"
37#include "sp8870.h"
38
39
40struct sp8870_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct sp8870_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* demodulator private data */
51 u8 initialised:1;
52};
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "sp8870: " args); \
58 } while (0)
59
60/* firmware size for sp8870 */
61#define SP8870_FIRMWARE_SIZE 16382
62
63/* starting point for firmware in file 'Sc_main.mc' */
64#define SP8870_FIRMWARE_OFFSET 0x0A
65
66static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
67{
68 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
69 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
70 int err;
71
72 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
73 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
74 return -EREMOTEIO;
75 }
76
77 return 0;
78}
79
80static int sp8870_readreg (struct sp8870_state* state, u16 reg)
81{
82 int ret;
83 u8 b0 [] = { reg >> 8 , reg & 0xff };
84 u8 b1 [] = { 0, 0 };
85 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
86 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
87
88 ret = i2c_transfer (state->i2c, msg, 2);
89
90 if (ret != 2) {
91 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
92 return -1;
93 }
94
95 return (b1[0] << 8 | b1[1]);
96}
97
98static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
99{
100 struct i2c_msg msg;
101 char *fw_buf = fw->data;
102 int fw_pos;
103 u8 tx_buf[255];
104 int tx_len;
105 int err = 0;
106
107 dprintk ("%s: ...\n", __FUNCTION__);
108
109 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
110 return -EINVAL;
111
112 // system controller stop
113 sp8870_writereg(state, 0x0F00, 0x0000);
114
115 // instruction RAM register hiword
116 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
117
118 // instruction RAM MWR
119 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
120
121 // do firmware upload
122 fw_pos = SP8870_FIRMWARE_OFFSET;
123 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
124 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
125 // write register 0xCF0A
126 tx_buf[0] = 0xCF;
127 tx_buf[1] = 0x0A;
128 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
129 msg.addr = state->config->demod_address;
130 msg.flags = 0;
131 msg.buf = tx_buf;
132 msg.len = tx_len + 2;
133 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
134 printk("%s: firmware upload failed!\n", __FUNCTION__);
135 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
136 return err;
137 }
138 fw_pos += tx_len;
139 }
140
141 dprintk ("%s: done!\n", __FUNCTION__);
142 return 0;
143};
144
145static void sp8870_microcontroller_stop (struct sp8870_state* state)
146{
147 sp8870_writereg(state, 0x0F08, 0x000);
148 sp8870_writereg(state, 0x0F09, 0x000);
149
150 // microcontroller STOP
151 sp8870_writereg(state, 0x0F00, 0x000);
152}
153
154static void sp8870_microcontroller_start (struct sp8870_state* state)
155{
156 sp8870_writereg(state, 0x0F08, 0x000);
157 sp8870_writereg(state, 0x0F09, 0x000);
158
159 // microcontroller START
160 sp8870_writereg(state, 0x0F00, 0x001);
161 // not documented but if we don't read 0x0D01 out here
162 // we don't get a correct data valid signal
163 sp8870_readreg(state, 0x0D01);
164}
165
166static int sp8870_read_data_valid_signal(struct sp8870_state* state)
167{
168 return (sp8870_readreg(state, 0x0D02) > 0);
169}
170
171static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
172{
173 int known_parameters = 1;
174
175 *reg0xc05 = 0x000;
176
177 switch (p->u.ofdm.constellation) {
178 case QPSK:
179 break;
180 case QAM_16:
181 *reg0xc05 |= (1 << 10);
182 break;
183 case QAM_64:
184 *reg0xc05 |= (2 << 10);
185 break;
186 case QAM_AUTO:
187 known_parameters = 0;
188 break;
189 default:
190 return -EINVAL;
191 };
192
193 switch (p->u.ofdm.hierarchy_information) {
194 case HIERARCHY_NONE:
195 break;
196 case HIERARCHY_1:
197 *reg0xc05 |= (1 << 7);
198 break;
199 case HIERARCHY_2:
200 *reg0xc05 |= (2 << 7);
201 break;
202 case HIERARCHY_4:
203 *reg0xc05 |= (3 << 7);
204 break;
205 case HIERARCHY_AUTO:
206 known_parameters = 0;
207 break;
208 default:
209 return -EINVAL;
210 };
211
212 switch (p->u.ofdm.code_rate_HP) {
213 case FEC_1_2:
214 break;
215 case FEC_2_3:
216 *reg0xc05 |= (1 << 3);
217 break;
218 case FEC_3_4:
219 *reg0xc05 |= (2 << 3);
220 break;
221 case FEC_5_6:
222 *reg0xc05 |= (3 << 3);
223 break;
224 case FEC_7_8:
225 *reg0xc05 |= (4 << 3);
226 break;
227 case FEC_AUTO:
228 known_parameters = 0;
229 break;
230 default:
231 return -EINVAL;
232 };
233
234 if (known_parameters)
235 *reg0xc05 |= (2 << 1); /* use specified parameters */
236 else
237 *reg0xc05 |= (1 << 1); /* enable autoprobing */
238
239 return 0;
240}
241
242static int sp8870_wake_up(struct sp8870_state* state)
243{
244 // enable TS output and interface pins
245 return sp8870_writereg(state, 0xC18, 0x00D);
246}
247
248static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
249 struct dvb_frontend_parameters *p)
250{
251 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
252 int err;
253 u16 reg0xc05;
254
255 if ((err = configure_reg0xc05(p, &reg0xc05)))
256 return err;
257
258 // system controller stop
259 sp8870_microcontroller_stop(state);
260
261 // set tuner parameters
262 sp8870_writereg(state, 0x206, 0x001);
263 state->config->pll_set(fe, p);
264 sp8870_writereg(state, 0x206, 0x000);
265
266 // sample rate correction bit [23..17]
267 sp8870_writereg(state, 0x0319, 0x000A);
268
269 // sample rate correction bit [16..0]
270 sp8870_writereg(state, 0x031A, 0x0AAB);
271
272 // integer carrier offset
273 sp8870_writereg(state, 0x0309, 0x0400);
274
275 // fractional carrier offset
276 sp8870_writereg(state, 0x030A, 0x0000);
277
278 // filter for 6/7/8 Mhz channel
279 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
280 sp8870_writereg(state, 0x0311, 0x0002);
281 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
282 sp8870_writereg(state, 0x0311, 0x0001);
283 else
284 sp8870_writereg(state, 0x0311, 0x0000);
285
286 // scan order: 2k first = 0x0000, 8k first = 0x0001
287 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
288 sp8870_writereg(state, 0x0338, 0x0000);
289 else
290 sp8870_writereg(state, 0x0338, 0x0001);
291
292 sp8870_writereg(state, 0xc05, reg0xc05);
293
294 // read status reg in order to clear pending irqs
295 sp8870_readreg(state, 0x200);
296
297 // system controller start
298 sp8870_microcontroller_start(state);
299
300 return 0;
301}
302
303static int sp8870_init (struct dvb_frontend* fe)
304{
305 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
306 const struct firmware *fw = NULL;
307
308 sp8870_wake_up(state);
309 if (state->initialised) return 0;
310 state->initialised = 1;
311
312 dprintk ("%s\n", __FUNCTION__);
313
314
315 /* request the firmware, this will block until someone uploads it */
316 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
317 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
318 printk("sp8870: no firmware upload (timeout or file not found?)\n");
319 release_firmware(fw);
320 return -EIO;
321 }
322
323 if (sp8870_firmware_upload(state, fw)) {
324 printk("sp8870: writing firmware to device failed\n");
325 release_firmware(fw);
326 return -EIO;
327 }
328 printk("sp8870: firmware upload complete\n");
329
330 /* enable TS output and interface pins */
331 sp8870_writereg(state, 0xc18, 0x00d);
332
333 // system controller stop
334 sp8870_microcontroller_stop(state);
335
336 // ADC mode
337 sp8870_writereg(state, 0x0301, 0x0003);
338
339 // Reed Solomon parity bytes passed to output
340 sp8870_writereg(state, 0x0C13, 0x0001);
341
342 // MPEG clock is suppressed if no valid data
343 sp8870_writereg(state, 0x0C14, 0x0001);
344
345 /* bit 0x010: enable data valid signal */
346 sp8870_writereg(state, 0x0D00, 0x010);
347 sp8870_writereg(state, 0x0D01, 0x000);
348
349 /* setup PLL */
350 if (state->config->pll_init) {
351 sp8870_writereg(state, 0x206, 0x001);
352 state->config->pll_init(fe);
353 sp8870_writereg(state, 0x206, 0x000);
354 }
355
356 return 0;
357}
358
359static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
360{
361 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
362 int status;
363 int signal;
364
365 *fe_status = 0;
366
367 status = sp8870_readreg (state, 0x0200);
368 if (status < 0)
369 return -EIO;
370
371 signal = sp8870_readreg (state, 0x0303);
372 if (signal < 0)
373 return -EIO;
374
375 if (signal > 0x0F)
376 *fe_status |= FE_HAS_SIGNAL;
377 if (status & 0x08)
378 *fe_status |= FE_HAS_SYNC;
379 if (status & 0x04)
380 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
381
382 return 0;
383}
384
385static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
386{
387 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
388 int ret;
389 u32 tmp;
390
391 *ber = 0;
392
393 ret = sp8870_readreg(state, 0xC08);
394 if (ret < 0)
395 return -EIO;
396
397 tmp = ret & 0x3F;
398
399 ret = sp8870_readreg(state, 0xC07);
400 if (ret < 0)
401 return -EIO;
402
403 tmp = ret << 6;
404
405 if (tmp >= 0x3FFF0)
406 tmp = ~0;
407
408 *ber = tmp;
409
410 return 0;
411}
412
413static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
414{
415 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
416 int ret;
417 u16 tmp;
418
419 *signal = 0;
420
421 ret = sp8870_readreg (state, 0x306);
422 if (ret < 0)
423 return -EIO;
424
425 tmp = ret << 8;
426
427 ret = sp8870_readreg (state, 0x303);
428 if (ret < 0)
429 return -EIO;
430
431 tmp |= ret;
432
433 if (tmp)
434 *signal = 0xFFFF - tmp;
435
436 return 0;
437}
438
439static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
440{
441 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
442 int ret;
443
444 *ublocks = 0;
445
446 ret = sp8870_readreg(state, 0xC0C);
447 if (ret < 0)
448 return -EIO;
449
450 if (ret == 0xFFFF)
451 ret = ~0;
452
453 *ublocks = ret;
454
455 return 0;
456}
457
458// number of trials to recover from lockup
459#define MAXTRIALS 5
460// maximum checks for data valid signal
461#define MAXCHECKS 100
462
463// only for debugging: counter for detected lockups
464static int lockups = 0;
465// only for debugging: counter for channel switches
466static int switches = 0;
467
468static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
469{
470 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
471
472 /*
473 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
474 We try to detect this by checking the data valid signal.
475 If it is not set after MAXCHECKS we try to recover the lockup by setting
476 the frontend parameters again.
477 */
478
479 int err = 0;
480 int valid = 0;
481 int trials = 0;
482 int check_count = 0;
483
484 dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency);
485
486 for (trials = 1; trials <= MAXTRIALS; trials++) {
487
488 if ((err = sp8870_set_frontend_parameters(fe, p)))
489 return err;
490
491 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
492// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
493 valid = sp8870_read_data_valid_signal(state);
494 if (valid) {
495 dprintk("%s: delay = %i usec\n",
496 __FUNCTION__, check_count * 10);
497 break;
498 }
499 udelay(10);
500 }
501 if (valid)
502 break;
503 }
504
505 if (!valid) {
506 printk("%s: firmware crash!!!!!!\n", __FUNCTION__);
507 return -EIO;
508 }
509
510 if (debug) {
511 if (valid) {
512 if (trials > 1) {
513 printk("%s: firmware lockup!!!\n", __FUNCTION__);
514 printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1);
515 lockups++;
516 }
517 }
518 switches++;
519 printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups);
520 }
521
522 return 0;
523}
524
525static int sp8870_sleep(struct dvb_frontend* fe)
526{
527 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
528
529 // tristate TS output and disable interface pins
530 return sp8870_writereg(state, 0xC18, 0x000);
531}
532
533static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
534{
535 fesettings->min_delay_ms = 350;
536 fesettings->step_size = 0;
537 fesettings->max_drift = 0;
538 return 0;
539}
540
541static void sp8870_release(struct dvb_frontend* fe)
542{
543 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
544 kfree(state);
545}
546
547static struct dvb_frontend_ops sp8870_ops;
548
549struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
550 struct i2c_adapter* i2c)
551{
552 struct sp8870_state* state = NULL;
553
554 /* allocate memory for the internal state */
555 state = (struct sp8870_state*) kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
556 if (state == NULL) goto error;
557
558 /* setup the state */
559 state->config = config;
560 state->i2c = i2c;
561 memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
562 state->initialised = 0;
563
564 /* check if the demod is there */
565 if (sp8870_readreg(state, 0x0200) < 0) goto error;
566
567 /* create dvb_frontend */
568 state->frontend.ops = &state->ops;
569 state->frontend.demodulator_priv = state;
570 return &state->frontend;
571
572error:
573 kfree(state);
574 return NULL;
575}
576
577static struct dvb_frontend_ops sp8870_ops = {
578
579 .info = {
580 .name = "Spase SP8870 DVB-T",
581 .type = FE_OFDM,
582 .frequency_min = 470000000,
583 .frequency_max = 860000000,
584 .frequency_stepsize = 166666,
585 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
586 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
587 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
588 FE_CAN_QPSK | FE_CAN_QAM_16 |
589 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
590 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
591 },
592
593 .release = sp8870_release,
594
595 .init = sp8870_init,
596 .sleep = sp8870_sleep,
597
598 .set_frontend = sp8870_set_frontend,
599 .get_tune_settings = sp8870_get_tune_settings,
600
601 .read_status = sp8870_read_status,
602 .read_ber = sp8870_read_ber,
603 .read_signal_strength = sp8870_read_signal_strength,
604 .read_ucblocks = sp8870_read_uncorrected_blocks,
605};
606
607module_param(debug, int, 0644);
608MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
609
610MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
611MODULE_AUTHOR("Juergen Peitz");
612MODULE_LICENSE("GPL");
613
614EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
new file mode 100644
index 000000000000..f3b555dbc960
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef SP8870_H
24#define SP8870_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct sp8870_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37
38 /* request firmware for device */
39 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
40};
41
42extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
new file mode 100644
index 000000000000..7eae833ece49
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -0,0 +1,606 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5/*
6 * This driver needs external firmware. Please use the command
7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
9 */
10#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/firmware.h>
17
18#include "dvb_frontend.h"
19#include "sp887x.h"
20
21
22struct sp887x_state {
23 struct i2c_adapter* i2c;
24 struct dvb_frontend_ops ops;
25 const struct sp887x_config* config;
26 struct dvb_frontend frontend;
27
28 /* demodulator private data */
29 u8 initialised:1;
30};
31
32static int debug;
33#define dprintk(args...) \
34 do { \
35 if (debug) printk(KERN_DEBUG "sp887x: " args); \
36 } while (0)
37
38static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
39{
40 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
41 int err;
42
43 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
44 printk ("%s: i2c write error (addr %02x, err == %i)\n",
45 __FUNCTION__, state->config->demod_address, err);
46 return -EREMOTEIO;
47 }
48
49 return 0;
50}
51
52static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
53{
54 u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
55 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
56 int ret;
57
58 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
59 /**
60 * in case of soft reset we ignore ACK errors...
61 */
62 if (!(reg == 0xf1a && data == 0x000 &&
63 (ret == -EREMOTEIO || ret == -EFAULT)))
64 {
65 printk("%s: writereg error "
66 "(reg %03x, data %03x, ret == %i)\n",
67 __FUNCTION__, reg & 0xffff, data & 0xffff, ret);
68 return ret;
69 }
70 }
71
72 return 0;
73}
74
75static int sp887x_readreg (struct sp887x_state* state, u16 reg)
76{
77 u8 b0 [] = { reg >> 8 , reg & 0xff };
78 u8 b1 [2];
79 int ret;
80 struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
82
83 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
84 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
85 return -1;
86 }
87
88 return (((b1[0] << 8) | b1[1]) & 0xfff);
89}
90
91static void sp887x_microcontroller_stop (struct sp887x_state* state)
92{
93 dprintk("%s\n", __FUNCTION__);
94 sp887x_writereg(state, 0xf08, 0x000);
95 sp887x_writereg(state, 0xf09, 0x000);
96
97 /* microcontroller STOP */
98 sp887x_writereg(state, 0xf00, 0x000);
99}
100
101static void sp887x_microcontroller_start (struct sp887x_state* state)
102{
103 dprintk("%s\n", __FUNCTION__);
104 sp887x_writereg(state, 0xf08, 0x000);
105 sp887x_writereg(state, 0xf09, 0x000);
106
107 /* microcontroller START */
108 sp887x_writereg(state, 0xf00, 0x001);
109}
110
111static void sp887x_setup_agc (struct sp887x_state* state)
112{
113 /* setup AGC parameters */
114 dprintk("%s\n", __FUNCTION__);
115 sp887x_writereg(state, 0x33c, 0x054);
116 sp887x_writereg(state, 0x33b, 0x04c);
117 sp887x_writereg(state, 0x328, 0x000);
118 sp887x_writereg(state, 0x327, 0x005);
119 sp887x_writereg(state, 0x326, 0x001);
120 sp887x_writereg(state, 0x325, 0x001);
121 sp887x_writereg(state, 0x324, 0x001);
122 sp887x_writereg(state, 0x318, 0x050);
123 sp887x_writereg(state, 0x317, 0x3fe);
124 sp887x_writereg(state, 0x316, 0x001);
125 sp887x_writereg(state, 0x313, 0x005);
126 sp887x_writereg(state, 0x312, 0x002);
127 sp887x_writereg(state, 0x306, 0x000);
128 sp887x_writereg(state, 0x303, 0x000);
129}
130
131#define BLOCKSIZE 30
132#define FW_SIZE 0x4000
133/**
134 * load firmware and setup MPEG interface...
135 */
136static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
137{
138 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
139 u8 buf [BLOCKSIZE+2];
140 int i;
141 int fw_size = fw->size;
142 unsigned char *mem = fw->data;
143
144 dprintk("%s\n", __FUNCTION__);
145
146 /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
147 if (fw_size < FW_SIZE+10)
148 return -ENODEV;
149
150 mem = fw->data + 10;
151
152 /* soft reset */
153 sp887x_writereg(state, 0xf1a, 0x000);
154
155 sp887x_microcontroller_stop (state);
156
157 printk ("%s: firmware upload... ", __FUNCTION__);
158
159 /* setup write pointer to -1 (end of memory) */
160 /* bit 0x8000 in address is set to enable 13bit mode */
161 sp887x_writereg(state, 0x8f08, 0x1fff);
162
163 /* dummy write (wrap around to start of memory) */
164 sp887x_writereg(state, 0x8f0a, 0x0000);
165
166 for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
167 int c = BLOCKSIZE;
168 int err;
169
170 if (i+c > FW_SIZE)
171 c = FW_SIZE - i;
172
173 /* bit 0x8000 in address is set to enable 13bit mode */
174 /* bit 0x4000 enables multibyte read/write transfers */
175 /* write register is 0xf0a */
176 buf[0] = 0xcf;
177 buf[1] = 0x0a;
178
179 memcpy(&buf[2], mem + i, c);
180
181 if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
182 printk ("failed.\n");
183 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
184 return err;
185 }
186 }
187
188 /* don't write RS bytes between packets */
189 sp887x_writereg(state, 0xc13, 0x001);
190
191 /* suppress clock if (!data_valid) */
192 sp887x_writereg(state, 0xc14, 0x000);
193
194 /* setup MPEG interface... */
195 sp887x_writereg(state, 0xc1a, 0x872);
196 sp887x_writereg(state, 0xc1b, 0x001);
197 sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
198 sp887x_writereg(state, 0xc1a, 0x871);
199
200 /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
201 sp887x_writereg(state, 0x301, 0x002);
202
203 sp887x_setup_agc(state);
204
205 /* bit 0x010: enable data valid signal */
206 sp887x_writereg(state, 0xd00, 0x010);
207 sp887x_writereg(state, 0x0d1, 0x000);
208
209 /* setup the PLL */
210 if (state->config->pll_init) {
211 sp887x_writereg(state, 0x206, 0x001);
212 state->config->pll_init(fe);
213 sp887x_writereg(state, 0x206, 0x000);
214 }
215
216 printk ("done.\n");
217 return 0;
218};
219
220static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
221{
222 int known_parameters = 1;
223
224 *reg0xc05 = 0x000;
225
226 switch (p->u.ofdm.constellation) {
227 case QPSK:
228 break;
229 case QAM_16:
230 *reg0xc05 |= (1 << 10);
231 break;
232 case QAM_64:
233 *reg0xc05 |= (2 << 10);
234 break;
235 case QAM_AUTO:
236 known_parameters = 0;
237 break;
238 default:
239 return -EINVAL;
240 };
241
242 switch (p->u.ofdm.hierarchy_information) {
243 case HIERARCHY_NONE:
244 break;
245 case HIERARCHY_1:
246 *reg0xc05 |= (1 << 7);
247 break;
248 case HIERARCHY_2:
249 *reg0xc05 |= (2 << 7);
250 break;
251 case HIERARCHY_4:
252 *reg0xc05 |= (3 << 7);
253 break;
254 case HIERARCHY_AUTO:
255 known_parameters = 0;
256 break;
257 default:
258 return -EINVAL;
259 };
260
261 switch (p->u.ofdm.code_rate_HP) {
262 case FEC_1_2:
263 break;
264 case FEC_2_3:
265 *reg0xc05 |= (1 << 3);
266 break;
267 case FEC_3_4:
268 *reg0xc05 |= (2 << 3);
269 break;
270 case FEC_5_6:
271 *reg0xc05 |= (3 << 3);
272 break;
273 case FEC_7_8:
274 *reg0xc05 |= (4 << 3);
275 break;
276 case FEC_AUTO:
277 known_parameters = 0;
278 break;
279 default:
280 return -EINVAL;
281 };
282
283 if (known_parameters)
284 *reg0xc05 |= (2 << 1); /* use specified parameters */
285 else
286 *reg0xc05 |= (1 << 1); /* enable autoprobing */
287
288 return 0;
289}
290
291/**
292 * estimates division of two 24bit numbers,
293 * derived from the ves1820/stv0299 driver code
294 */
295static void divide (int n, int d, int *quotient_i, int *quotient_f)
296{
297 unsigned int q, r;
298
299 r = (n % d) << 8;
300 q = (r / d);
301
302 if (quotient_i)
303 *quotient_i = q;
304
305 if (quotient_f) {
306 r = (r % d) << 8;
307 q = (q << 8) | (r / d);
308 r = (r % d) << 8;
309 *quotient_f = (q << 8) | (r / d);
310 }
311}
312
313static void sp887x_correct_offsets (struct sp887x_state* state,
314 struct dvb_frontend_parameters *p,
315 int actual_freq)
316{
317 static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
318 int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
319 int freq_offset = actual_freq - p->frequency;
320 int sysclock = 61003; //[kHz]
321 int ifreq = 36000000;
322 int freq;
323 int frequency_shift;
324
325 if (p->inversion == INVERSION_ON)
326 freq = ifreq - freq_offset;
327 else
328 freq = ifreq + freq_offset;
329
330 divide(freq / 333, sysclock, NULL, &frequency_shift);
331
332 if (p->inversion == INVERSION_ON)
333 frequency_shift = -frequency_shift;
334
335 /* sample rate correction */
336 sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
337 sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
338
339 /* carrier offset correction */
340 sp887x_writereg(state, 0x309, frequency_shift >> 12);
341 sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
342}
343
344static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
345 struct dvb_frontend_parameters *p)
346{
347 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
348 int actual_freq, err;
349 u16 val, reg0xc05;
350
351 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
352 p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ &&
353 p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ)
354 return -EINVAL;
355
356 if ((err = configure_reg0xc05(p, &reg0xc05)))
357 return err;
358
359 sp887x_microcontroller_stop(state);
360
361 /* setup the PLL */
362 sp887x_writereg(state, 0x206, 0x001);
363 actual_freq = state->config->pll_set(fe, p);
364 sp887x_writereg(state, 0x206, 0x000);
365
366 /* read status reg in order to clear <pending irqs */
367 sp887x_readreg(state, 0x200);
368
369 sp887x_correct_offsets(state, p, actual_freq);
370
371 /* filter for 6/7/8 Mhz channel */
372 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
373 val = 2;
374 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
375 val = 1;
376 else
377 val = 0;
378
379 sp887x_writereg(state, 0x311, val);
380
381 /* scan order: 2k first = 0, 8k first = 1 */
382 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
383 sp887x_writereg(state, 0x338, 0x000);
384 else
385 sp887x_writereg(state, 0x338, 0x001);
386
387 sp887x_writereg(state, 0xc05, reg0xc05);
388
389 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
390 val = 2 << 3;
391 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
392 val = 3 << 3;
393 else
394 val = 0 << 3;
395
396 /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
397 * optimize algorithm for given bandwidth...
398 */
399 sp887x_writereg(state, 0xf14, 0x160 | val);
400 sp887x_writereg(state, 0xf15, 0x000);
401
402 sp887x_microcontroller_start(state);
403 return 0;
404}
405
406static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
407{
408 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
409 u16 snr12 = sp887x_readreg(state, 0xf16);
410 u16 sync0x200 = sp887x_readreg(state, 0x200);
411 u16 sync0xf17 = sp887x_readreg(state, 0xf17);
412
413 *status = 0;
414
415 if (snr12 > 0x00f)
416 *status |= FE_HAS_SIGNAL;
417
418 //if (sync0x200 & 0x004)
419 // *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
420
421 //if (sync0x200 & 0x008)
422 // *status |= FE_HAS_VITERBI;
423
424 if ((sync0xf17 & 0x00f) == 0x002) {
425 *status |= FE_HAS_LOCK;
426 *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
427 }
428
429 if (sync0x200 & 0x001) { /* tuner adjustment requested...*/
430 int steps = (sync0x200 >> 4) & 0x00f;
431 if (steps & 0x008)
432 steps = -steps;
433 dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
434 steps);
435 }
436
437 return 0;
438}
439
440static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
441{
442 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
443
444 *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
445 (sp887x_readreg(state, 0xc07) << 6);
446 sp887x_writereg(state, 0xc08, 0x000);
447 sp887x_writereg(state, 0xc07, 0x000);
448 if (*ber >= 0x3fff0)
449 *ber = ~0;
450
451 return 0;
452}
453
454static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
455{
456 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
457
458 u16 snr12 = sp887x_readreg(state, 0xf16);
459 u32 signal = 3 * (snr12 << 4);
460 *strength = (signal < 0xffff) ? signal : 0xffff;
461
462 return 0;
463}
464
465static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
466{
467 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
468
469 u16 snr12 = sp887x_readreg(state, 0xf16);
470 *snr = (snr12 << 4) | (snr12 >> 8);
471
472 return 0;
473}
474
475static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
476{
477 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
478
479 *ucblocks = sp887x_readreg(state, 0xc0c);
480 if (*ucblocks == 0xfff)
481 *ucblocks = ~0;
482
483 return 0;
484}
485
486static int sp887x_sleep(struct dvb_frontend* fe)
487{
488 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
489
490 /* tristate TS output and disable interface pins */
491 sp887x_writereg(state, 0xc18, 0x000);
492
493 return 0;
494}
495
496static int sp887x_init(struct dvb_frontend* fe)
497{
498 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
499 const struct firmware *fw = NULL;
500 int ret;
501
502 if (!state->initialised) {
503 /* request the firmware, this will block until someone uploads it */
504 printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
505 ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
506 if (ret) {
507 printk("sp887x: no firmware upload (timeout or file not found?)\n");
508 return ret;
509 }
510
511 ret = sp887x_initial_setup(fe, fw);
512 if (ret) {
513 printk("sp887x: writing firmware to device failed\n");
514 release_firmware(fw);
515 return ret;
516 }
517 printk("sp887x: firmware upload complete\n");
518 state->initialised = 1;
519 }
520
521 /* enable TS output and interface pins */
522 sp887x_writereg(state, 0xc18, 0x00d);
523
524 return 0;
525}
526
527static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
528{
529 fesettings->min_delay_ms = 350;
530 fesettings->step_size = 166666*2;
531 fesettings->max_drift = (166666*2)+1;
532 return 0;
533}
534
535static void sp887x_release(struct dvb_frontend* fe)
536{
537 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
538 kfree(state);
539}
540
541static struct dvb_frontend_ops sp887x_ops;
542
543struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
544 struct i2c_adapter* i2c)
545{
546 struct sp887x_state* state = NULL;
547
548 /* allocate memory for the internal state */
549 state = (struct sp887x_state*) kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
550 if (state == NULL) goto error;
551
552 /* setup the state */
553 state->config = config;
554 state->i2c = i2c;
555 memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
556 state->initialised = 0;
557
558 /* check if the demod is there */
559 if (sp887x_readreg(state, 0x0200) < 0) goto error;
560
561 /* create dvb_frontend */
562 state->frontend.ops = &state->ops;
563 state->frontend.demodulator_priv = state;
564 return &state->frontend;
565
566error:
567 kfree(state);
568 return NULL;
569}
570
571static struct dvb_frontend_ops sp887x_ops = {
572
573 .info = {
574 .name = "Spase SP887x DVB-T",
575 .type = FE_OFDM,
576 .frequency_min = 50500000,
577 .frequency_max = 858000000,
578 .frequency_stepsize = 166666,
579 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
580 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
581 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
582 FE_CAN_RECOVER
583 },
584
585 .release = sp887x_release,
586
587 .init = sp887x_init,
588 .sleep = sp887x_sleep,
589
590 .set_frontend = sp887x_setup_frontend_parameters,
591 .get_tune_settings = sp887x_get_tune_settings,
592
593 .read_status = sp887x_read_status,
594 .read_ber = sp887x_read_ber,
595 .read_signal_strength = sp887x_read_signal_strength,
596 .read_snr = sp887x_read_snr,
597 .read_ucblocks = sp887x_read_ucblocks,
598};
599
600module_param(debug, int, 0644);
601MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
602
603MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
604MODULE_LICENSE("GPL");
605
606EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
new file mode 100644
index 000000000000..6a05d8f8e8cc
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -0,0 +1,29 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5#ifndef SP887X_H
6#define SP887X_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct sp887x_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* PLL maintenance */
17 int (*pll_init)(struct dvb_frontend* fe);
18
19 /* this should return the actual frequency tuned to */
20 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
21
22 /* request firmware for device */
23 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
24};
25
26extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
27 struct i2c_adapter* i2c);
28
29#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
new file mode 100644
index 000000000000..502c6403dfc6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -0,0 +1,798 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
5 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27
28#include "dvb_frontend.h"
29#include "stv0297.h"
30
31struct stv0297_state {
32 struct i2c_adapter *i2c;
33 struct dvb_frontend_ops ops;
34 const struct stv0297_config *config;
35 struct dvb_frontend frontend;
36
37 unsigned long base_freq;
38 u8 pwm;
39};
40
41#if 1
42#define dprintk(x...) printk(x)
43#else
44#define dprintk(x...)
45#endif
46
47#define STV0297_CLOCK_KHZ 28900
48
49static u8 init_tab[] = {
50 0x00, 0x09,
51 0x01, 0x69,
52 0x03, 0x00,
53 0x04, 0x00,
54 0x07, 0x00,
55 0x08, 0x00,
56 0x20, 0x00,
57 0x21, 0x40,
58 0x22, 0x00,
59 0x23, 0x00,
60 0x24, 0x40,
61 0x25, 0x88,
62 0x30, 0xff,
63 0x31, 0x00,
64 0x32, 0xff,
65 0x33, 0x00,
66 0x34, 0x50,
67 0x35, 0x7f,
68 0x36, 0x00,
69 0x37, 0x20,
70 0x38, 0x00,
71 0x40, 0x1c,
72 0x41, 0xff,
73 0x42, 0x29,
74 0x43, 0x00,
75 0x44, 0xff,
76 0x45, 0x00,
77 0x46, 0x00,
78 0x49, 0x04,
79 0x4a, 0xff,
80 0x4b, 0x7f,
81 0x52, 0x30,
82 0x55, 0xae,
83 0x56, 0x47,
84 0x57, 0xe1,
85 0x58, 0x3a,
86 0x5a, 0x1e,
87 0x5b, 0x34,
88 0x60, 0x00,
89 0x63, 0x00,
90 0x64, 0x00,
91 0x65, 0x00,
92 0x66, 0x00,
93 0x67, 0x00,
94 0x68, 0x00,
95 0x69, 0x00,
96 0x6a, 0x02,
97 0x6b, 0x00,
98 0x70, 0xff,
99 0x71, 0x00,
100 0x72, 0x00,
101 0x73, 0x00,
102 0x74, 0x0c,
103 0x80, 0x00,
104 0x81, 0x00,
105 0x82, 0x00,
106 0x83, 0x00,
107 0x84, 0x04,
108 0x85, 0x80,
109 0x86, 0x24,
110 0x87, 0x78,
111 0x88, 0x00,
112 0x89, 0x00,
113 0x90, 0x01,
114 0x91, 0x01,
115 0xa0, 0x00,
116 0xa1, 0x00,
117 0xa2, 0x00,
118 0xb0, 0x91,
119 0xb1, 0x0b,
120 0xc0, 0x53,
121 0xc1, 0x70,
122 0xc2, 0x12,
123 0xd0, 0x00,
124 0xd1, 0x00,
125 0xd2, 0x00,
126 0xd3, 0x00,
127 0xd4, 0x00,
128 0xd5, 0x00,
129 0xde, 0x00,
130 0xdf, 0x00,
131 0x61, 0x49,
132 0x62, 0x0b,
133 0x53, 0x08,
134 0x59, 0x08,
135};
136
137
138static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
143
144 ret = i2c_transfer(state->i2c, &msg, 1);
145
146 if (ret != 1)
147 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
148 "ret == %i)\n", __FUNCTION__, reg, data, ret);
149
150 return (ret != 1) ? -1 : 0;
151}
152
153static int stv0297_readreg(struct stv0297_state *state, u8 reg)
154{
155 int ret;
156 u8 b0[] = { reg };
157 u8 b1[] = { 0 };
158 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
159 1},
160 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
161 };
162
163 // this device needs a STOP between the register and data
164 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
165 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
166 return -1;
167 }
168 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
169 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
170 return -1;
171 }
172
173 return b1[0];
174}
175
176static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
177{
178 int val;
179
180 val = stv0297_readreg(state, reg);
181 val &= ~mask;
182 val |= (data & mask);
183 stv0297_writereg(state, reg, val);
184
185 return 0;
186}
187
188static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
189{
190 int ret;
191 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
192 &reg1,.len = 1},
193 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
194 };
195
196 // this device needs a STOP between the register and data
197 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
198 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
199 return -1;
200 }
201 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
202 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
203 return -1;
204 }
205
206 return 0;
207}
208
209static u32 stv0297_get_symbolrate(struct stv0297_state *state)
210{
211 u64 tmp;
212
213 tmp = stv0297_readreg(state, 0x55);
214 tmp |= stv0297_readreg(state, 0x56) << 8;
215 tmp |= stv0297_readreg(state, 0x57) << 16;
216 tmp |= stv0297_readreg(state, 0x58) << 24;
217
218 tmp *= STV0297_CLOCK_KHZ;
219 tmp >>= 32;
220
221 return (u32) tmp;
222}
223
224static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
225{
226 long tmp;
227
228 tmp = 131072L * srate; /* 131072 = 2^17 */
229 tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */
230 tmp = tmp * 8192L; /* 8192 = 2^13 */
231
232 stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
233 stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
234 stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
235 stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
236}
237
238static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
239{
240 long tmp;
241
242 tmp = (long) fshift *262144L; /* 262144 = 2*18 */
243 tmp /= symrate;
244 tmp *= 1024; /* 1024 = 2*10 */
245
246 // adjust
247 if (tmp >= 0) {
248 tmp += 500000;
249 } else {
250 tmp -= 500000;
251 }
252 tmp /= 1000000;
253
254 stv0297_writereg(state, 0x60, tmp & 0xFF);
255 stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
256}
257
258static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
259{
260 long tmp;
261
262 /* symrate is hardcoded to 10000 */
263 tmp = offset * 26844L; /* (2**28)/10000 */
264 if (tmp < 0)
265 tmp += 0x10000000;
266 tmp &= 0x0FFFFFFF;
267
268 stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
269 stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
270 stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
271 stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
272}
273
274/*
275static long stv0297_get_carrieroffset(struct stv0297_state *state)
276{
277 s64 tmp;
278
279 stv0297_writereg(state, 0x6B, 0x00);
280
281 tmp = stv0297_readreg(state, 0x66);
282 tmp |= (stv0297_readreg(state, 0x67) << 8);
283 tmp |= (stv0297_readreg(state, 0x68) << 16);
284 tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
285
286 tmp *= stv0297_get_symbolrate(state);
287 tmp >>= 28;
288
289 return (s32) tmp;
290}
291*/
292
293static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
294{
295 s32 tmp;
296
297 if (freq > 10000)
298 freq -= STV0297_CLOCK_KHZ;
299
300 tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
301 tmp = (freq * 1000) / tmp;
302 if (tmp > 0xffff)
303 tmp = 0xffff;
304
305 stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
306 stv0297_writereg(state, 0x21, tmp >> 8);
307 stv0297_writereg(state, 0x20, tmp);
308}
309
310static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
311{
312 int val = 0;
313
314 switch (modulation) {
315 case QAM_16:
316 val = 0;
317 break;
318
319 case QAM_32:
320 val = 1;
321 break;
322
323 case QAM_64:
324 val = 4;
325 break;
326
327 case QAM_128:
328 val = 2;
329 break;
330
331 case QAM_256:
332 val = 3;
333 break;
334
335 default:
336 return -EINVAL;
337 }
338
339 stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
340
341 return 0;
342}
343
344static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
345{
346 int val = 0;
347
348 switch (inversion) {
349 case INVERSION_OFF:
350 val = 0;
351 break;
352
353 case INVERSION_ON:
354 val = 1;
355 break;
356
357 default:
358 return -EINVAL;
359 }
360
361 stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
362
363 return 0;
364}
365
366int stv0297_enable_plli2c(struct dvb_frontend *fe)
367{
368 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
369
370 stv0297_writereg(state, 0x87, 0x78);
371 stv0297_writereg(state, 0x86, 0xc8);
372
373 return 0;
374}
375
376static int stv0297_init(struct dvb_frontend *fe)
377{
378 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
379 int i;
380
381 /* soft reset */
382 stv0297_writereg_mask(state, 0x80, 1, 1);
383 stv0297_writereg_mask(state, 0x80, 1, 0);
384
385 /* reset deinterleaver */
386 stv0297_writereg_mask(state, 0x81, 1, 1);
387 stv0297_writereg_mask(state, 0x81, 1, 0);
388
389 /* load init table */
390 for (i = 0; i < sizeof(init_tab); i += 2) {
391 stv0297_writereg(state, init_tab[i], init_tab[i + 1]);
392 }
393
394 /* set a dummy symbol rate */
395 stv0297_set_symbolrate(state, 6900);
396
397 /* invert AGC1 polarity */
398 stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
399
400 /* setup bit error counting */
401 stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
402 stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
403 stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
404 stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
405
406 /* min + max PWM */
407 stv0297_writereg(state, 0x4a, 0x00);
408 stv0297_writereg(state, 0x4b, state->pwm);
409 msleep(200);
410
411 if (state->config->pll_init)
412 state->config->pll_init(fe);
413
414 return 0;
415}
416
417static int stv0297_sleep(struct dvb_frontend *fe)
418{
419 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
420
421 stv0297_writereg_mask(state, 0x80, 1, 1);
422
423 return 0;
424}
425
426static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
427{
428 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
429
430 u8 sync = stv0297_readreg(state, 0xDF);
431
432 *status = 0;
433 if (sync & 0x80)
434 *status |=
435 FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
436 return 0;
437}
438
439static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
440{
441 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
442 u8 BER[3];
443
444 stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes
445 mdelay(25); // Hopefully got 4096 Bytes
446 stv0297_readregs(state, 0xA0, BER, 3);
447 mdelay(25);
448 *ber = (BER[2] << 8 | BER[1]) / (8 * 4096);
449
450 return 0;
451}
452
453
454static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
455{
456 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
457 u8 STRENGTH[2];
458
459 stv0297_readregs(state, 0x41, STRENGTH, 2);
460 *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
461
462 return 0;
463}
464
465static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
466{
467 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
468 u8 SNR[2];
469
470 stv0297_readregs(state, 0x07, SNR, 2);
471 *snr = SNR[1] << 8 | SNR[0];
472
473 return 0;
474}
475
476static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
477{
478 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
479
480 *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
481 | stv0297_readreg(state, 0xD4);
482
483 return 0;
484}
485
486static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
487{
488 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
489 int u_threshold;
490 int initial_u;
491 int blind_u;
492 int delay;
493 int sweeprate;
494 int carrieroffset;
495 unsigned long starttime;
496 unsigned long timeout;
497 fe_spectral_inversion_t inversion;
498
499 switch (p->u.qam.modulation) {
500 case QAM_16:
501 case QAM_32:
502 case QAM_64:
503 delay = 100;
504 sweeprate = 1500;
505 break;
506
507 case QAM_128:
508 delay = 150;
509 sweeprate = 1000;
510 break;
511
512 case QAM_256:
513 delay = 200;
514 sweeprate = 500;
515 break;
516
517 default:
518 return -EINVAL;
519 }
520
521 // determine inversion dependant parameters
522 inversion = p->inversion;
523 if (state->config->invert)
524 inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
525 carrieroffset = -330;
526 switch (inversion) {
527 case INVERSION_OFF:
528 break;
529
530 case INVERSION_ON:
531 sweeprate = -sweeprate;
532 carrieroffset = -carrieroffset;
533 break;
534
535 default:
536 return -EINVAL;
537 }
538
539 stv0297_init(fe);
540 state->config->pll_set(fe, p);
541
542 /* clear software interrupts */
543 stv0297_writereg(state, 0x82, 0x0);
544
545 /* set initial demodulation frequency */
546 stv0297_set_initialdemodfreq(state, 7250);
547
548 /* setup AGC */
549 stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
550 stv0297_writereg(state, 0x41, 0x00);
551 stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
552 stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
553 stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
554 stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
555 stv0297_writereg(state, 0x72, 0x00);
556 stv0297_writereg(state, 0x73, 0x00);
557 stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
558 stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
559 stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
560
561 /* setup STL */
562 stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
563 stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
564 stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
565 stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
566 stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
567
568 /* disable frequency sweep */
569 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
570
571 /* reset deinterleaver */
572 stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
573 stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
574
575 /* ??? */
576 stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
577 stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
578
579 /* reset equaliser */
580 u_threshold = stv0297_readreg(state, 0x00) & 0xf;
581 initial_u = stv0297_readreg(state, 0x01) >> 4;
582 blind_u = stv0297_readreg(state, 0x01) & 0xf;
583 stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
584 stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
585 stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
586 stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
587 stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
588
589 /* data comes from internal A/D */
590 stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
591
592 /* clear phase registers */
593 stv0297_writereg(state, 0x63, 0x00);
594 stv0297_writereg(state, 0x64, 0x00);
595 stv0297_writereg(state, 0x65, 0x00);
596 stv0297_writereg(state, 0x66, 0x00);
597 stv0297_writereg(state, 0x67, 0x00);
598 stv0297_writereg(state, 0x68, 0x00);
599 stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
600
601 /* set parameters */
602 stv0297_set_qam(state, p->u.qam.modulation);
603 stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000);
604 stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);
605 stv0297_set_carrieroffset(state, carrieroffset);
606 stv0297_set_inversion(state, inversion);
607
608 /* kick off lock */
609 stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
610 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
611 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
612 stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
613 stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
614 stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
615 stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
616 stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
617
618 /* wait for WGAGC lock */
619 starttime = jiffies;
620 timeout = jiffies + (200 * HZ) / 1000;
621 while (time_before(jiffies, timeout)) {
622 msleep(10);
623 if (stv0297_readreg(state, 0x43) & 0x08)
624 break;
625 }
626 if (time_after(jiffies, timeout)) {
627 goto timeout;
628 }
629 msleep(20);
630
631 /* wait for equaliser partial convergence */
632 timeout = jiffies + (50 * HZ) / 1000;
633 while (time_before(jiffies, timeout)) {
634 msleep(10);
635
636 if (stv0297_readreg(state, 0x82) & 0x04) {
637 break;
638 }
639 }
640 if (time_after(jiffies, timeout)) {
641 goto timeout;
642 }
643
644 /* wait for equaliser full convergence */
645 timeout = jiffies + (delay * HZ) / 1000;
646 while (time_before(jiffies, timeout)) {
647 msleep(10);
648
649 if (stv0297_readreg(state, 0x82) & 0x08) {
650 break;
651 }
652 }
653 if (time_after(jiffies, timeout)) {
654 goto timeout;
655 }
656
657 /* disable sweep */
658 stv0297_writereg_mask(state, 0x6a, 1, 0);
659 stv0297_writereg_mask(state, 0x88, 8, 0);
660
661 /* wait for main lock */
662 timeout = jiffies + (20 * HZ) / 1000;
663 while (time_before(jiffies, timeout)) {
664 msleep(10);
665
666 if (stv0297_readreg(state, 0xDF) & 0x80) {
667 break;
668 }
669 }
670 if (time_after(jiffies, timeout)) {
671 goto timeout;
672 }
673 msleep(100);
674
675 /* is it still locked after that delay? */
676 if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
677 goto timeout;
678 }
679
680 /* success!! */
681 stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
682 state->base_freq = p->frequency;
683 return 0;
684
685timeout:
686 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
687 return 0;
688}
689
690static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
691{
692 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
693 int reg_00, reg_83;
694
695 reg_00 = stv0297_readreg(state, 0x00);
696 reg_83 = stv0297_readreg(state, 0x83);
697
698 p->frequency = state->base_freq;
699 p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
700 if (state->config->invert)
701 p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
702 p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;
703 p->u.qam.fec_inner = FEC_NONE;
704
705 switch ((reg_00 >> 4) & 0x7) {
706 case 0:
707 p->u.qam.modulation = QAM_16;
708 break;
709 case 1:
710 p->u.qam.modulation = QAM_32;
711 break;
712 case 2:
713 p->u.qam.modulation = QAM_128;
714 break;
715 case 3:
716 p->u.qam.modulation = QAM_256;
717 break;
718 case 4:
719 p->u.qam.modulation = QAM_64;
720 break;
721 }
722
723 return 0;
724}
725
726static void stv0297_release(struct dvb_frontend *fe)
727{
728 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
729 kfree(state);
730}
731
732static struct dvb_frontend_ops stv0297_ops;
733
734struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
735 struct i2c_adapter *i2c, int pwm)
736{
737 struct stv0297_state *state = NULL;
738
739 /* allocate memory for the internal state */
740 state = (struct stv0297_state *) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
741 if (state == NULL)
742 goto error;
743
744 /* setup the state */
745 state->config = config;
746 state->i2c = i2c;
747 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
748 state->base_freq = 0;
749 state->pwm = pwm;
750
751 /* check if the demod is there */
752 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
753 goto error;
754
755 /* create dvb_frontend */
756 state->frontend.ops = &state->ops;
757 state->frontend.demodulator_priv = state;
758 return &state->frontend;
759
760error:
761 kfree(state);
762 return NULL;
763}
764
765static struct dvb_frontend_ops stv0297_ops = {
766
767 .info = {
768 .name = "ST STV0297 DVB-C",
769 .type = FE_QAM,
770 .frequency_min = 64000000,
771 .frequency_max = 1300000000,
772 .frequency_stepsize = 62500,
773 .symbol_rate_min = 870000,
774 .symbol_rate_max = 11700000,
775 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
776 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
777
778 .release = stv0297_release,
779
780 .init = stv0297_init,
781 .sleep = stv0297_sleep,
782
783 .set_frontend = stv0297_set_frontend,
784 .get_frontend = stv0297_get_frontend,
785
786 .read_status = stv0297_read_status,
787 .read_ber = stv0297_read_ber,
788 .read_signal_strength = stv0297_read_signal_strength,
789 .read_snr = stv0297_read_snr,
790 .read_ucblocks = stv0297_read_ucblocks,
791};
792
793MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
794MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
795MODULE_LICENSE("GPL");
796
797EXPORT_SYMBOL(stv0297_attach);
798EXPORT_SYMBOL(stv0297_enable_plli2c);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
new file mode 100644
index 000000000000..3be535989302
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -0,0 +1,44 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
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
21#ifndef STV0297_H
22#define STV0297_H
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27struct stv0297_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* does the "inversion" need inverted? */
33 u8 invert:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
41 struct i2c_adapter* i2c, int pwm);
42extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
43
44#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
new file mode 100644
index 000000000000..15b40541b62d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -0,0 +1,731 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/moduleparam.h>
49#include <linux/string.h>
50#include <linux/slab.h>
51#include <asm/div64.h>
52
53#include "dvb_frontend.h"
54#include "stv0299.h"
55
56struct stv0299_state {
57 struct i2c_adapter* i2c;
58 struct dvb_frontend_ops ops;
59 const struct stv0299_config* config;
60 struct dvb_frontend frontend;
61
62 u8 initialised:1;
63 u32 tuner_frequency;
64 u32 symbol_rate;
65 fe_code_rate_t fec_inner;
66 int errmode;
67};
68
69#define STATUS_BER 0
70#define STATUS_UCBLOCKS 1
71
72static int debug;
73#define dprintk(args...) \
74 do { \
75 if (debug) printk(KERN_DEBUG "stv0299: " args); \
76 } while (0)
77
78
79static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf [] = { reg, data };
83 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
84
85 ret = i2c_transfer (state->i2c, &msg, 1);
86
87 if (ret != 1)
88 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
89 "ret == %i)\n", __FUNCTION__, reg, data, ret);
90
91 return (ret != 1) ? -EREMOTEIO : 0;
92}
93
94int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
95{
96 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
97
98 return stv0299_writeregI(state, reg, data);
99}
100
101static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
107 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
108
109 ret = i2c_transfer (state->i2c, msg, 2);
110
111 if (ret != 2)
112 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
113 __FUNCTION__, reg, ret);
114
115 return b1[0];
116}
117
118static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
119{
120 int ret;
121 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
122 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
123
124 ret = i2c_transfer (state->i2c, msg, 2);
125
126 if (ret != 2)
127 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
128
129 return ret == 2 ? 0 : ret;
130}
131
132static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
133{
134 dprintk ("%s\n", __FUNCTION__);
135
136 switch (fec) {
137 case FEC_AUTO:
138 {
139 return stv0299_writeregI (state, 0x31, 0x1f);
140 }
141 case FEC_1_2:
142 {
143 return stv0299_writeregI (state, 0x31, 0x01);
144 }
145 case FEC_2_3:
146 {
147 return stv0299_writeregI (state, 0x31, 0x02);
148 }
149 case FEC_3_4:
150 {
151 return stv0299_writeregI (state, 0x31, 0x04);
152 }
153 case FEC_5_6:
154 {
155 return stv0299_writeregI (state, 0x31, 0x08);
156 }
157 case FEC_7_8:
158 {
159 return stv0299_writeregI (state, 0x31, 0x10);
160 }
161 default:
162 {
163 return -EINVAL;
164 }
165 }
166}
167
168static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
169{
170 static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
171 FEC_7_8, FEC_1_2 };
172 u8 index;
173
174 dprintk ("%s\n", __FUNCTION__);
175
176 index = stv0299_readreg (state, 0x1b);
177 index &= 0x7;
178
179 if (index > 4)
180 return FEC_AUTO;
181
182 return fec_tab [index];
183}
184
185static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
186{
187 unsigned long start = jiffies;
188
189 dprintk ("%s\n", __FUNCTION__);
190
191 while (stv0299_readreg(state, 0x0a) & 1) {
192 if (jiffies - start > timeout) {
193 dprintk ("%s: timeout!!\n", __FUNCTION__);
194 return -ETIMEDOUT;
195 }
196 msleep(10);
197 };
198
199 return 0;
200}
201
202static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
203{
204 unsigned long start = jiffies;
205
206 dprintk ("%s\n", __FUNCTION__);
207
208 while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
209 if (jiffies - start > timeout) {
210 dprintk ("%s: timeout!!\n", __FUNCTION__);
211 return -ETIMEDOUT;
212 }
213 msleep(10);
214 };
215
216 return 0;
217}
218
219static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
220{
221 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
222 u64 big = srate;
223 u32 ratio;
224
225 // check rate is within limits
226 if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
227
228 // calculate value to program
229 big = big << 20;
230 big += (state->config->mclk-1); // round correctly
231 do_div(big, state->config->mclk);
232 ratio = big << 4;
233
234 return state->config->set_symbol_rate(fe, srate, ratio);
235}
236
237static int stv0299_get_symbolrate (struct stv0299_state* state)
238{
239 u32 Mclk = state->config->mclk / 4096L;
240 u32 srate;
241 s32 offset;
242 u8 sfr[3];
243 s8 rtf;
244
245 dprintk ("%s\n", __FUNCTION__);
246
247 stv0299_readregs (state, 0x1f, sfr, 3);
248 stv0299_readregs (state, 0x1a, &rtf, 1);
249
250 srate = (sfr[0] << 8) | sfr[1];
251 srate *= Mclk;
252 srate /= 16;
253 srate += (sfr[2] >> 4) * Mclk / 256;
254 offset = (s32) rtf * (srate / 4096L);
255 offset /= 128;
256
257 dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
258 dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
259
260 srate += offset;
261
262 srate += 1000;
263 srate /= 2000;
264 srate *= 2000;
265
266 return srate;
267}
268
269static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
270 struct dvb_diseqc_master_cmd *m)
271{
272 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
273 u8 val;
274 int i;
275
276 dprintk ("%s\n", __FUNCTION__);
277
278 if (stv0299_wait_diseqc_idle (state, 100) < 0)
279 return -ETIMEDOUT;
280
281 val = stv0299_readreg (state, 0x08);
282
283 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
284 return -EREMOTEIO;
285
286 for (i=0; i<m->msg_len; i++) {
287 if (stv0299_wait_diseqc_fifo (state, 100) < 0)
288 return -ETIMEDOUT;
289
290 if (stv0299_writeregI (state, 0x09, m->msg[i]))
291 return -EREMOTEIO;
292 }
293
294 if (stv0299_wait_diseqc_idle (state, 100) < 0)
295 return -ETIMEDOUT;
296
297 return 0;
298}
299
300static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
301{
302 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
303 u8 val;
304
305 dprintk ("%s\n", __FUNCTION__);
306
307 if (stv0299_wait_diseqc_idle (state, 100) < 0)
308 return -ETIMEDOUT;
309
310 val = stv0299_readreg (state, 0x08);
311
312 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
313 return -EREMOTEIO;
314
315 if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
316 return -EREMOTEIO;
317
318 if (stv0299_wait_diseqc_idle (state, 100) < 0)
319 return -ETIMEDOUT;
320
321 if (stv0299_writeregI (state, 0x08, val))
322 return -EREMOTEIO;
323
324 return 0;
325}
326
327static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
328{
329 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
330 u8 val;
331
332 if (stv0299_wait_diseqc_idle (state, 100) < 0)
333 return -ETIMEDOUT;
334
335 val = stv0299_readreg (state, 0x08);
336
337 switch (tone) {
338 case SEC_TONE_ON:
339 return stv0299_writeregI (state, 0x08, val | 0x3);
340
341 case SEC_TONE_OFF:
342 return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
343
344 default:
345 return -EINVAL;
346 }
347}
348
349static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
350{
351 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
352 u8 reg0x08;
353 u8 reg0x0c;
354
355 dprintk("%s: %s\n", __FUNCTION__,
356 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
357 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
358
359 reg0x08 = stv0299_readreg (state, 0x08);
360 reg0x0c = stv0299_readreg (state, 0x0c);
361
362 /**
363 * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
364 */
365 reg0x0c &= 0x0f;
366
367 if (voltage == SEC_VOLTAGE_OFF) {
368 stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */
369 return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */
370 }
371
372 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
373
374 switch (voltage) {
375 case SEC_VOLTAGE_13:
376 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10;
377 else reg0x0c |= 0x40;
378
379 return stv0299_writeregI(state, 0x0c, reg0x0c);
380
381 case SEC_VOLTAGE_18:
382 return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd)
389{
390 u8 last = 1;
391 int i;
392
393 /* reset voltage at the end
394 if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
395 cmd |= 0x80;
396 else
397 cmd &= 0x7F;
398 */
399
400 cmd = cmd << 1;
401 dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
402
403 stv0299_set_voltage(fe,SEC_VOLTAGE_18);
404 msleep(32);
405
406 for (i=0; i<9; i++) {
407 if((cmd & 0x01) != last) {
408 stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
409 last = (last) ? 0 : 1;
410 }
411
412 cmd = cmd >> 1;
413
414 if (i != 8)
415 msleep(8);
416 }
417
418 return 0;
419}
420
421static int stv0299_init (struct dvb_frontend* fe)
422{
423 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
424 int i;
425
426 dprintk("stv0299: init chip\n");
427
428 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
429 stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]);
430
431 if (state->config->pll_init) {
432 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
433 state->config->pll_init(fe);
434 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
435 }
436
437 return 0;
438}
439
440static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
441{
442 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
443
444 u8 signal = 0xff - stv0299_readreg (state, 0x18);
445 u8 sync = stv0299_readreg (state, 0x1b);
446
447 dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
448 *status = 0;
449
450 if (signal > 10)
451 *status |= FE_HAS_SIGNAL;
452
453 if (sync & 0x80)
454 *status |= FE_HAS_CARRIER;
455
456 if (sync & 0x10)
457 *status |= FE_HAS_VITERBI;
458
459 if (sync & 0x08)
460 *status |= FE_HAS_SYNC;
461
462 if ((sync & 0x98) == 0x98)
463 *status |= FE_HAS_LOCK;
464
465 return 0;
466}
467
468static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
469{
470 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
471
472 if (state->errmode != STATUS_BER) return 0;
473 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
474
475 return 0;
476}
477
478static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
479{
480 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
481
482 s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
483 | stv0299_readreg (state, 0x19));
484
485 dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
486 stv0299_readreg (state, 0x18),
487 stv0299_readreg (state, 0x19), (int) signal);
488
489 signal = signal * 5 / 4;
490 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
491
492 return 0;
493}
494
495static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
496{
497 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
498
499 s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
500 | stv0299_readreg (state, 0x25));
501 xsnr = 3 * (xsnr - 0xa100);
502 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
503
504 return 0;
505}
506
507static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
508{
509 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
510
511 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
512 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
513
514 return 0;
515}
516
517static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
518{
519 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
520 int invval = 0;
521
522 dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
523
524 // set the inversion
525 if (p->inversion == INVERSION_OFF) invval = 0;
526 else if (p->inversion == INVERSION_ON) invval = 1;
527 else {
528 printk("stv0299 does not support auto-inversion\n");
529 return -EINVAL;
530 }
531 if (state->config->invert) invval = (~invval) & 1;
532 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
533
534 if (state->config->enhanced_tuning) {
535 /* check if we should do a finetune */
536 int frequency_delta = p->frequency - state->tuner_frequency;
537 int minmax = p->u.qpsk.symbol_rate / 2000;
538 if (minmax < 5000) minmax = 5000;
539
540 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
541 (state->fec_inner == p->u.qpsk.fec_inner) &&
542 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
543 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
544
545 // zap the derotator registers first
546 stv0299_writeregI(state, 0x22, 0x00);
547 stv0299_writeregI(state, 0x23, 0x00);
548
549 // now set them as we want
550 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
551 stv0299_writeregI(state, 0x23, Drot_freq);
552 } else {
553 /* A "normal" tune is requested */
554 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
555 state->config->pll_set(fe, p);
556 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
557
558 stv0299_writeregI(state, 0x32, 0x80);
559 stv0299_writeregI(state, 0x22, 0x00);
560 stv0299_writeregI(state, 0x23, 0x00);
561 stv0299_writeregI(state, 0x32, 0x19);
562 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
563 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
564 }
565 } else {
566 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
567 state->config->pll_set(fe, p);
568 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
569
570 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
571 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
572 stv0299_writeregI(state, 0x22, 0x00);
573 stv0299_writeregI(state, 0x23, 0x00);
574 stv0299_readreg (state, 0x23);
575 stv0299_writeregI(state, 0x12, 0xb9);
576 }
577
578 state->tuner_frequency = p->frequency;
579 state->fec_inner = p->u.qpsk.fec_inner;
580 state->symbol_rate = p->u.qpsk.symbol_rate;
581
582 return 0;
583}
584
585static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
586{
587 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
588 s32 derot_freq;
589 int invval;
590
591 derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
592 | stv0299_readreg (state, 0x23));
593
594 derot_freq *= (state->config->mclk >> 16);
595 derot_freq += 500;
596 derot_freq /= 1000;
597
598 p->frequency += derot_freq;
599
600 invval = stv0299_readreg (state, 0x0c) & 1;
601 if (state->config->invert) invval = (~invval) & 1;
602 p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
603
604 p->u.qpsk.fec_inner = stv0299_get_fec (state);
605 p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state);
606
607 return 0;
608}
609
610static int stv0299_sleep(struct dvb_frontend* fe)
611{
612 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
613
614 stv0299_writeregI(state, 0x02, 0x80);
615 state->initialised = 0;
616
617 return 0;
618}
619
620static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
621{
622 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
623
624 fesettings->min_delay_ms = state->config->min_delay_ms;
625 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
626 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
627 fesettings->max_drift = 5000;
628 } else {
629 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
630 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
631 }
632 return 0;
633}
634
635static void stv0299_release(struct dvb_frontend* fe)
636{
637 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
638 kfree(state);
639}
640
641static struct dvb_frontend_ops stv0299_ops;
642
643struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
644 struct i2c_adapter* i2c)
645{
646 struct stv0299_state* state = NULL;
647 int id;
648
649 /* allocate memory for the internal state */
650 state = (struct stv0299_state*) kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
651 if (state == NULL) goto error;
652
653 /* setup the state */
654 state->config = config;
655 state->i2c = i2c;
656 memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
657 state->initialised = 0;
658 state->tuner_frequency = 0;
659 state->symbol_rate = 0;
660 state->fec_inner = 0;
661 state->errmode = STATUS_BER;
662
663 /* check if the demod is there */
664 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
665 msleep(200);
666 id = stv0299_readreg(state, 0x00);
667
668 /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
669 /* register 0x00 might contain 0x80 when returning from standby */
670 if (id != 0xa1 && id != 0x80) goto error;
671
672 /* create dvb_frontend */
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 kfree(state);
679 return NULL;
680}
681
682static struct dvb_frontend_ops stv0299_ops = {
683
684 .info = {
685 .name = "ST STV0299 DVB-S",
686 .type = FE_QPSK,
687 .frequency_min = 950000,
688 .frequency_max = 2150000,
689 .frequency_stepsize = 125, /* kHz for QPSK frontends */
690 .frequency_tolerance = 0,
691 .symbol_rate_min = 1000000,
692 .symbol_rate_max = 45000000,
693 .symbol_rate_tolerance = 500, /* ppm */
694 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
695 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_QPSK |
697 FE_CAN_FEC_AUTO
698 },
699
700 .release = stv0299_release,
701
702 .init = stv0299_init,
703 .sleep = stv0299_sleep,
704
705 .set_frontend = stv0299_set_frontend,
706 .get_frontend = stv0299_get_frontend,
707 .get_tune_settings = stv0299_get_tune_settings,
708
709 .read_status = stv0299_read_status,
710 .read_ber = stv0299_read_ber,
711 .read_signal_strength = stv0299_read_signal_strength,
712 .read_snr = stv0299_read_snr,
713 .read_ucblocks = stv0299_read_ucblocks,
714
715 .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
716 .diseqc_send_burst = stv0299_send_diseqc_burst,
717 .set_tone = stv0299_set_tone,
718 .set_voltage = stv0299_set_voltage,
719 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
720};
721
722module_param(debug, int, 0644);
723MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
724
725MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
726MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
727 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
728MODULE_LICENSE("GPL");
729
730EXPORT_SYMBOL(stv0299_writereg);
731EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
new file mode 100644
index 000000000000..79457a80a11f
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -0,0 +1,104 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#ifndef STV0299_H
46#define STV0299_H
47
48#include <linux/dvb/frontend.h>
49#include "dvb_frontend.h"
50
51#define STV0229_LOCKOUTPUT_0 0
52#define STV0229_LOCKOUTPUT_1 1
53#define STV0229_LOCKOUTPUT_CF 2
54#define STV0229_LOCKOUTPUT_LK 3
55
56#define STV0299_VOLT13_OP0 0
57#define STV0299_VOLT13_OP1 1
58
59struct stv0299_config
60{
61 /* the demodulator's i2c address */
62 u8 demod_address;
63
64 /* inittab - array of pairs of values.
65 * First of each pair is the register, second is the value.
66 * List should be terminated with an 0xff, 0xff pair.
67 */
68 u8* inittab;
69
70 /* master clock to use */
71 u32 mclk;
72
73 /* does the inversion require inversion? */
74 u8 invert:1;
75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */
80 u8 skip_reinit:1;
81
82 /* LOCK OUTPUT setting */
83 u8 lock_output:2;
84
85 /* Is 13v controlled by OP0 or OP1? */
86 u8 volt13_op0_op1:1;
87
88 /* minimum delay before retuning */
89 int min_delay_ms;
90
91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
93
94 /* PLL maintenance */
95 int (*pll_init)(struct dvb_frontend* fe);
96 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
97};
98
99extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
100
101extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
102 struct i2c_adapter* i2c);
103
104#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
new file mode 100644
index 000000000000..4e40d95ee95d
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -0,0 +1,469 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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/config.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/string.h>
31#include <linux/slab.h>
32
33#include "dvb_frontend.h"
34#include "tda10021.h"
35
36
37struct tda10021_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda10021_config* config;
42 struct dvb_frontend frontend;
43
44 u8 pwm;
45 u8 reg0;
46};
47
48
49#if 0
50#define dprintk(x...) printk(x)
51#else
52#define dprintk(x...)
53#endif
54
55static int verbose;
56
57#define XIN 57840000UL
58#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
59#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
60#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
61
62#define FIN (XIN >> 4)
63
64static int tda10021_inittab_size = 0x40;
65static u8 tda10021_inittab[0x40]=
66{
67 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
68 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
69 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff,
70 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
71 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
72 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
73 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
74 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
75};
76
77static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
78{
79 u8 buf[] = { reg, data };
80 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
81 int ret;
82
83 ret = i2c_transfer (state->i2c, &msg, 1);
84 if (ret != 1)
85 printk("DVB: TDA10021(%d): %s, writereg error "
86 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
87 state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
88
89 msleep(10);
90 return (ret != 1) ? -EREMOTEIO : 0;
91}
92
93static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
94{
95 u8 b0 [] = { reg };
96 u8 b1 [] = { 0 };
97 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
98 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
99 int ret;
100
101 ret = i2c_transfer (state->i2c, msg, 2);
102 if (ret != 2)
103 printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
104 state->frontend.dvb->num, __FUNCTION__, ret);
105 return b1[0];
106}
107
108//get access to tuner
109static int lock_tuner(struct tda10021_state* state)
110{
111 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
112 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
113
114 if(i2c_transfer(state->i2c, &msg, 1) != 1)
115 {
116 printk("tda10021: lock tuner fails\n");
117 return -EREMOTEIO;
118 }
119 return 0;
120}
121
122//release access from tuner
123static int unlock_tuner(struct tda10021_state* state)
124{
125 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
126 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
127
128 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
129 {
130 printk("tda10021: unlock tuner fails\n");
131 return -EREMOTEIO;
132 }
133 return 0;
134}
135
136static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
137 fe_spectral_inversion_t inversion)
138{
139 reg0 |= state->reg0 & 0x63;
140
141 if (INVERSION_ON == inversion)
142 ENABLE_INVERSION(reg0);
143 else if (INVERSION_OFF == inversion)
144 DISABLE_INVERSION(reg0);
145
146 tda10021_writereg (state, 0x00, reg0 & 0xfe);
147 tda10021_writereg (state, 0x00, reg0 | 0x01);
148
149 state->reg0 = reg0;
150 return 0;
151}
152
153static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
154{
155 s32 BDR;
156 s32 BDRI;
157 s16 SFIL=0;
158 u16 NDEC = 0;
159 u32 tmp, ratio;
160
161 if (symbolrate > XIN/2)
162 symbolrate = XIN/2;
163 if (symbolrate < 500000)
164 symbolrate = 500000;
165
166 if (symbolrate < XIN/16) NDEC = 1;
167 if (symbolrate < XIN/32) NDEC = 2;
168 if (symbolrate < XIN/64) NDEC = 3;
169
170 if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
171 if (symbolrate < (u32)(XIN/16)) SFIL = 0;
172 if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
173 if (symbolrate < (u32)(XIN/32)) SFIL = 0;
174 if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
175 if (symbolrate < (u32)(XIN/64)) SFIL = 0;
176 if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
177
178 symbolrate <<= NDEC;
179 ratio = (symbolrate << 4) / FIN;
180 tmp = ((symbolrate << 4) % FIN) << 8;
181 ratio = (ratio << 8) + tmp / FIN;
182 tmp = (tmp % FIN) << 8;
183 ratio = (ratio << 8) + (tmp + FIN/2) / FIN;
184
185 BDR = ratio;
186 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
187
188 if (BDRI > 0xFF)
189 BDRI = 0xFF;
190
191 SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
192
193 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
194
195 tda10021_writereg (state, 0x03, NDEC);
196 tda10021_writereg (state, 0x0a, BDR&0xff);
197 tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
198 tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
199
200 tda10021_writereg (state, 0x0d, BDRI);
201 tda10021_writereg (state, 0x0e, SFIL);
202
203 return 0;
204}
205
206static int tda10021_init (struct dvb_frontend *fe)
207{
208 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
209 int i;
210
211 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
212
213 //tda10021_writereg (fe, 0, 0);
214
215 for (i=0; i<tda10021_inittab_size; i++)
216 tda10021_writereg (state, i, tda10021_inittab[i]);
217
218 tda10021_writereg (state, 0x34, state->pwm);
219
220 //Comment by markus
221 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
222 //0x2A[4] == BYPPLL -> Power down mode (default 1)
223 //0x2A[5] == LCK -> PLL Lock Flag
224 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
225
226 //Activate PLL
227 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
228
229 if (state->config->pll_init) {
230 lock_tuner(state);
231 state->config->pll_init(fe);
232 unlock_tuner(state);
233 }
234
235 return 0;
236}
237
238static int tda10021_set_parameters (struct dvb_frontend *fe,
239 struct dvb_frontend_parameters *p)
240{
241 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
242
243 //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256
244 //CONF
245 static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 };
246 //AGCREF value
247 static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c };
248 //LTHR value
249 static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 };
250 //MSETH
251 static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 };
252 //AREF
253 static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b };
254
255 int qam = p->u.qam.modulation;
256
257 if (qam < 0 || qam > 5)
258 return -EINVAL;
259
260 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
261
262 lock_tuner(state);
263 state->config->pll_set(fe, p);
264 unlock_tuner(state);
265
266 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
267 tda10021_writereg (state, 0x34, state->pwm);
268
269 tda10021_writereg (state, 0x01, reg0x01[qam]);
270 tda10021_writereg (state, 0x05, reg0x05[qam]);
271 tda10021_writereg (state, 0x08, reg0x08[qam]);
272 tda10021_writereg (state, 0x09, reg0x09[qam]);
273
274 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
275
276 return 0;
277}
278
279static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
280{
281 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
282 int sync;
283
284 *status = 0;
285 //0x11[0] == EQALGO -> Equalizer algorithms state
286 //0x11[1] == CARLOCK -> Carrier locked
287 //0x11[2] == FSYNC -> Frame synchronisation
288 //0x11[3] == FEL -> Front End locked
289 //0x11[6] == NODVB -> DVB Mode Information
290 sync = tda10021_readreg (state, 0x11);
291
292 if (sync & 2)
293 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
294
295 if (sync & 4)
296 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
297
298 if (sync & 8)
299 *status |= FE_HAS_LOCK;
300
301 return 0;
302}
303
304static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
305{
306 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
307
308 u32 _ber = tda10021_readreg(state, 0x14) |
309 (tda10021_readreg(state, 0x15) << 8) |
310 ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
311 *ber = 10 * _ber;
312
313 return 0;
314}
315
316static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
317{
318 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
319
320 u8 gain = tda10021_readreg(state, 0x17);
321 *strength = (gain << 8) | gain;
322
323 return 0;
324}
325
326static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
327{
328 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
329
330 u8 quality = ~tda10021_readreg(state, 0x18);
331 *snr = (quality << 8) | quality;
332
333 return 0;
334}
335
336static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
337{
338 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
339
340 *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
341 if (*ucblocks == 0x7f)
342 *ucblocks = 0xffffffff;
343
344 /* reset uncorrected block counter */
345 tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
346 tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
347
348 return 0;
349}
350
351static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
352{
353 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
354 int sync;
355 s8 afc = 0;
356
357 sync = tda10021_readreg(state, 0x11);
358 afc = tda10021_readreg(state, 0x19);
359 if (verbose) {
360 /* AFC only valid when carrier has been recovered */
361 printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
362 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
363 state->frontend.dvb->num, afc,
364 -((s32)p->u.qam.symbol_rate * afc) >> 10);
365 }
366
367 p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
368 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
369
370 p->u.qam.fec_inner = FEC_NONE;
371 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
372
373 if (sync & 2)
374 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
375
376 return 0;
377}
378
379static int tda10021_sleep(struct dvb_frontend* fe)
380{
381 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
382
383 tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
384 tda10021_writereg (state, 0x00, 0x80); /* standby */
385
386 return 0;
387}
388
389static void tda10021_release(struct dvb_frontend* fe)
390{
391 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
392 kfree(state);
393}
394
395static struct dvb_frontend_ops tda10021_ops;
396
397struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
398 struct i2c_adapter* i2c,
399 u8 pwm)
400{
401 struct tda10021_state* state = NULL;
402
403 /* allocate memory for the internal state */
404 state = (struct tda10021_state*) kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
405 if (state == NULL) goto error;
406
407 /* setup the state */
408 state->config = config;
409 state->i2c = i2c;
410 memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
411 state->pwm = pwm;
412 state->reg0 = tda10021_inittab[0];
413
414 /* check if the demod is there */
415 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
416
417 /* create dvb_frontend */
418 state->frontend.ops = &state->ops;
419 state->frontend.demodulator_priv = state;
420 return &state->frontend;
421
422error:
423 kfree(state);
424 return NULL;
425}
426
427static struct dvb_frontend_ops tda10021_ops = {
428
429 .info = {
430 .name = "Philips TDA10021 DVB-C",
431 .type = FE_QAM,
432 .frequency_stepsize = 62500,
433 .frequency_min = 51000000,
434 .frequency_max = 858000000,
435 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
436 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
437 #if 0
438 .frequency_tolerance = ???,
439 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
440 #endif
441 .caps = 0x400 | //FE_CAN_QAM_4
442 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
443 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
444 FE_CAN_FEC_AUTO
445 },
446
447 .release = tda10021_release,
448
449 .init = tda10021_init,
450 .sleep = tda10021_sleep,
451
452 .set_frontend = tda10021_set_parameters,
453 .get_frontend = tda10021_get_frontend,
454
455 .read_status = tda10021_read_status,
456 .read_ber = tda10021_read_ber,
457 .read_signal_strength = tda10021_read_signal_strength,
458 .read_snr = tda10021_read_snr,
459 .read_ucblocks = tda10021_read_ucblocks,
460};
461
462module_param(verbose, int, 0644);
463MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
464
465MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
466MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
467MODULE_LICENSE("GPL");
468
469EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
new file mode 100644
index 000000000000..7d6a51ce291e
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -0,0 +1,42 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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#ifndef TDA10021_H
25#define TDA10021_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda10021_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37};
38
39extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
40 struct i2c_adapter* i2c, u8 pwm);
41
42#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
new file mode 100644
index 000000000000..687ad9cf3384
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -0,0 +1,1206 @@
1 /*
2 Driver for Philips tda1004xh OFDM Demodulator
3
4 (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22/*
23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware.
27 */
28#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
29#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/device.h>
35#include "dvb_frontend.h"
36#include "tda1004x.h"
37
38#define TDA1004X_DEMOD_TDA10045 0
39#define TDA1004X_DEMOD_TDA10046 1
40
41
42struct tda1004x_state {
43 struct i2c_adapter* i2c;
44 struct dvb_frontend_ops ops;
45 const struct tda1004x_config* config;
46 struct dvb_frontend frontend;
47
48 /* private demod data */
49 u8 initialised:1;
50 u8 demod_type;
51};
52
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "tda1004x: " args); \
58 } while (0)
59
60#define TDA1004X_CHIPID 0x00
61#define TDA1004X_AUTO 0x01
62#define TDA1004X_IN_CONF1 0x02
63#define TDA1004X_IN_CONF2 0x03
64#define TDA1004X_OUT_CONF1 0x04
65#define TDA1004X_OUT_CONF2 0x05
66#define TDA1004X_STATUS_CD 0x06
67#define TDA1004X_CONFC4 0x07
68#define TDA1004X_DSSPARE2 0x0C
69#define TDA10045H_CODE_IN 0x0D
70#define TDA10045H_FWPAGE 0x0E
71#define TDA1004X_SCAN_CPT 0x10
72#define TDA1004X_DSP_CMD 0x11
73#define TDA1004X_DSP_ARG 0x12
74#define TDA1004X_DSP_DATA1 0x13
75#define TDA1004X_DSP_DATA2 0x14
76#define TDA1004X_CONFADC1 0x15
77#define TDA1004X_CONFC1 0x16
78#define TDA10045H_S_AGC 0x1a
79#define TDA10046H_AGC_TUN_LEVEL 0x1a
80#define TDA1004X_SNR 0x1c
81#define TDA1004X_CONF_TS1 0x1e
82#define TDA1004X_CONF_TS2 0x1f
83#define TDA1004X_CBER_RESET 0x20
84#define TDA1004X_CBER_MSB 0x21
85#define TDA1004X_CBER_LSB 0x22
86#define TDA1004X_CVBER_LUT 0x23
87#define TDA1004X_VBER_MSB 0x24
88#define TDA1004X_VBER_MID 0x25
89#define TDA1004X_VBER_LSB 0x26
90#define TDA1004X_UNCOR 0x27
91
92#define TDA10045H_CONFPLL_P 0x2D
93#define TDA10045H_CONFPLL_M_MSB 0x2E
94#define TDA10045H_CONFPLL_M_LSB 0x2F
95#define TDA10045H_CONFPLL_N 0x30
96
97#define TDA10046H_CONFPLL1 0x2D
98#define TDA10046H_CONFPLL2 0x2F
99#define TDA10046H_CONFPLL3 0x30
100#define TDA10046H_TIME_WREF1 0x31
101#define TDA10046H_TIME_WREF2 0x32
102#define TDA10046H_TIME_WREF3 0x33
103#define TDA10046H_TIME_WREF4 0x34
104#define TDA10046H_TIME_WREF5 0x35
105
106#define TDA10045H_UNSURW_MSB 0x31
107#define TDA10045H_UNSURW_LSB 0x32
108#define TDA10045H_WREF_MSB 0x33
109#define TDA10045H_WREF_MID 0x34
110#define TDA10045H_WREF_LSB 0x35
111#define TDA10045H_MUXOUT 0x36
112#define TDA1004X_CONFADC2 0x37
113
114#define TDA10045H_IOFFSET 0x38
115
116#define TDA10046H_CONF_TRISTATE1 0x3B
117#define TDA10046H_CONF_TRISTATE2 0x3C
118#define TDA10046H_CONF_POLARITY 0x3D
119#define TDA10046H_FREQ_OFFSET 0x3E
120#define TDA10046H_GPIO_OUT_SEL 0x41
121#define TDA10046H_GPIO_SELECT 0x42
122#define TDA10046H_AGC_CONF 0x43
123#define TDA10046H_AGC_GAINS 0x46
124#define TDA10046H_AGC_TUN_MIN 0x47
125#define TDA10046H_AGC_TUN_MAX 0x48
126#define TDA10046H_AGC_IF_MIN 0x49
127#define TDA10046H_AGC_IF_MAX 0x4A
128
129#define TDA10046H_FREQ_PHY2_MSB 0x4D
130#define TDA10046H_FREQ_PHY2_LSB 0x4E
131
132#define TDA10046H_CVBER_CTRL 0x4F
133#define TDA10046H_AGC_IF_LEVEL 0x52
134#define TDA10046H_CODE_CPT 0x57
135#define TDA10046H_CODE_IN 0x58
136
137
138static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };
143
144 dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
145
146 msg.addr = state->config->demod_address;
147 ret = i2c_transfer(state->i2c, &msg, 1);
148
149 if (ret != 1)
150 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
151 __FUNCTION__, reg, data, ret);
152
153 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
154 reg, data, ret);
155 return (ret != 1) ? -1 : 0;
156}
157
158static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
159{
160 int ret;
161 u8 b0[] = { reg };
162 u8 b1[] = { 0 };
163 struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},
164 { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};
165
166 dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
167
168 msg[0].addr = state->config->demod_address;
169 msg[1].addr = state->config->demod_address;
170 ret = i2c_transfer(state->i2c, msg, 2);
171
172 if (ret != 2) {
173 dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
174 ret);
175 return -1;
176 }
177
178 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
179 reg, b1[0], ret);
180 return b1[0];
181}
182
183static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
184{
185 int val;
186 dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
187 mask, data);
188
189 // read a byte and check
190 val = tda1004x_read_byte(state, reg);
191 if (val < 0)
192 return val;
193
194 // mask if off
195 val = val & ~mask;
196 val |= data & 0xff;
197
198 // write it out again
199 return tda1004x_write_byteI(state, reg, val);
200}
201
202static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
203{
204 int i;
205 int result;
206
207 dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
208
209 result = 0;
210 for (i = 0; i < len; i++) {
211 result = tda1004x_write_byteI(state, reg + i, buf[i]);
212 if (result != 0)
213 break;
214 }
215
216 return result;
217}
218
219static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
220{
221 int result;
222 dprintk("%s\n", __FUNCTION__);
223
224 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
225 msleep(1);
226 return result;
227}
228
229static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
230{
231 dprintk("%s\n", __FUNCTION__);
232
233 return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
234}
235
236static int tda10045h_set_bandwidth(struct tda1004x_state *state,
237 fe_bandwidth_t bandwidth)
238{
239 static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
240 static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
241 static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
242
243 switch (bandwidth) {
244 case BANDWIDTH_6_MHZ:
245 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
246 break;
247
248 case BANDWIDTH_7_MHZ:
249 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
250 break;
251
252 case BANDWIDTH_8_MHZ:
253 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
254 break;
255
256 default:
257 return -EINVAL;
258 }
259
260 tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
261
262 return 0;
263}
264
265static int tda10046h_set_bandwidth(struct tda1004x_state *state,
266 fe_bandwidth_t bandwidth)
267{
268 static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };
269 static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };
270 static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };
271
272 switch (bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
275 break;
276
277 case BANDWIDTH_7_MHZ:
278 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
279 break;
280
281 case BANDWIDTH_8_MHZ:
282 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
283 break;
284
285 default:
286 return -EINVAL;
287 }
288
289 return 0;
290}
291
292static int tda1004x_do_upload(struct tda1004x_state *state,
293 unsigned char *mem, unsigned int len,
294 u8 dspCodeCounterReg, u8 dspCodeInReg)
295{
296 u8 buf[65];
297 struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 };
298 int tx_size;
299 int pos = 0;
300
301 /* clear code counter */
302 tda1004x_write_byteI(state, dspCodeCounterReg, 0);
303 fw_msg.addr = state->config->demod_address;
304
305 buf[0] = dspCodeInReg;
306 while (pos != len) {
307
308 // work out how much to send this time
309 tx_size = len - pos;
310 if (tx_size > 0x10) {
311 tx_size = 0x10;
312 }
313
314 // send the chunk
315 memcpy(buf + 1, mem + pos, tx_size);
316 fw_msg.len = tx_size + 1;
317 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
318 printk("tda1004x: Error during firmware upload\n");
319 return -EIO;
320 }
321 pos += tx_size;
322
323 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
324 }
325 return 0;
326}
327
328static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
329{
330 u8 data1, data2;
331
332 // check upload was OK
333 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
334 tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
335
336 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
337 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
338 if (data1 != 0x67 || data2 != dspVersion) {
339 return -EIO;
340 }
341
342 return 0;
343}
344
345static int tda10045_fwupload(struct dvb_frontend* fe)
346{
347 struct tda1004x_state* state = fe->demodulator_priv;
348 int ret;
349 const struct firmware *fw;
350
351
352 /* don't re-upload unless necessary */
353 if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0;
354
355 /* request the firmware, this will block until someone uploads it */
356 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
357 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
358 if (ret) {
359 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
360 return ret;
361 }
362
363 /* reset chip */
364 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
365 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
366 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
367 msleep(10);
368
369 /* set parameters */
370 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
371
372 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
373 if (ret)
374 return ret;
375 printk("tda1004x: firmware upload complete\n");
376
377 /* wait for DSP to initialise */
378 /* DSPREADY doesn't seem to work on the TDA10045H */
379 msleep(100);
380
381 return tda1004x_check_upload_ok(state, 0x2c);
382}
383
384static int tda10046_fwupload(struct dvb_frontend* fe)
385{
386 struct tda1004x_state* state = fe->demodulator_priv;
387 unsigned long timeout;
388 int ret;
389 const struct firmware *fw;
390
391 /* reset + wake up chip */
392 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
393 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
394 msleep(100);
395
396 /* don't re-upload unless necessary */
397 if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0;
398
399 /* request the firmware, this will block until someone uploads it */
400 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
401 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
402 if (ret) {
403 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
404 return ret;
405 }
406
407 /* set parameters */
408 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
409 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0);
410 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
411 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
412 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
413 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
414
415 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
416 if (ret)
417 return ret;
418 printk("tda1004x: firmware upload complete\n");
419
420 /* wait for DSP to initialise */
421 timeout = jiffies + HZ;
422 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
423 if (time_after(jiffies, timeout)) {
424 printk("tda1004x: DSP failed to initialised.\n");
425 return -EIO;
426 }
427 msleep(1);
428 }
429
430 return tda1004x_check_upload_ok(state, 0x20);
431}
432
433static int tda1004x_encode_fec(int fec)
434{
435 // convert known FEC values
436 switch (fec) {
437 case FEC_1_2:
438 return 0;
439 case FEC_2_3:
440 return 1;
441 case FEC_3_4:
442 return 2;
443 case FEC_5_6:
444 return 3;
445 case FEC_7_8:
446 return 4;
447 }
448
449 // unsupported
450 return -EINVAL;
451}
452
453static int tda1004x_decode_fec(int tdafec)
454{
455 // convert known FEC values
456 switch (tdafec) {
457 case 0:
458 return FEC_1_2;
459 case 1:
460 return FEC_2_3;
461 case 2:
462 return FEC_3_4;
463 case 3:
464 return FEC_5_6;
465 case 4:
466 return FEC_7_8;
467 }
468
469 // unsupported
470 return -1;
471}
472
473int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data)
474{
475 struct tda1004x_state* state = fe->demodulator_priv;
476
477 return tda1004x_write_byteI(state, reg, data);
478}
479
480static int tda10045_init(struct dvb_frontend* fe)
481{
482 struct tda1004x_state* state = fe->demodulator_priv;
483
484 dprintk("%s\n", __FUNCTION__);
485
486 if (state->initialised) return 0;
487
488 if (tda10045_fwupload(fe)) {
489 printk("tda1004x: firmware upload failed\n");
490 return -EIO;
491 }
492
493 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
494
495 // Init the PLL
496 if (state->config->pll_init) {
497 tda1004x_enable_tuner_i2c(state);
498 state->config->pll_init(fe);
499 tda1004x_disable_tuner_i2c(state);
500 }
501
502 // tda setup
503 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
504 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
505 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
506 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
507 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
508 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
509 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
510 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
511 tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
512 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
513 tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
514
515 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
516
517 state->initialised = 1;
518 return 0;
519}
520
521static int tda10046_init(struct dvb_frontend* fe)
522{
523 struct tda1004x_state* state = fe->demodulator_priv;
524 dprintk("%s\n", __FUNCTION__);
525
526 if (state->initialised) return 0;
527
528 if (tda10046_fwupload(fe)) {
529 printk("tda1004x: firmware upload failed\n");
530 return -EIO;
531 }
532
533 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip
534
535 // Init the PLL
536 if (state->config->pll_init) {
537 tda1004x_enable_tuner_i2c(state);
538 state->config->pll_init(fe);
539 tda1004x_disable_tuner_i2c(state);
540 }
541
542 // tda setup
543 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
544 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40);
545 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
546 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
547 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
548 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
549 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
550 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
551 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
552 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup
553 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
554 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
555 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
556 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
557 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
558 tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
559 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
560 tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
561 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
562 tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
563 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
564 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
565 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
566 tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
567 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
568
569 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
570
571 state->initialised = 1;
572 return 0;
573}
574
575static int tda1004x_set_fe(struct dvb_frontend* fe,
576 struct dvb_frontend_parameters *fe_params)
577{
578 struct tda1004x_state* state = fe->demodulator_priv;
579 int tmp;
580 int inversion;
581
582 dprintk("%s\n", __FUNCTION__);
583
584 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
585 // setup auto offset
586 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
587 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
588 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
589
590 // disable agc_conf[2]
591 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
592 }
593
594 // set frequency
595 tda1004x_enable_tuner_i2c(state);
596 state->config->pll_set(fe, fe_params);
597 tda1004x_disable_tuner_i2c(state);
598
599 if (state->demod_type == TDA1004X_DEMOD_TDA10046)
600 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
601
602 // Hardcoded to use auto as much as possible on the TDA10045 as it
603 // is very unreliable if AUTO mode is _not_ used.
604 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
605 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
606 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
607 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
608 }
609
610 // Set standard params.. or put them to auto
611 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
612 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
613 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
614 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
615 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
616 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
617 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
618 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
619 } else {
620 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto
621
622 // set HP FEC
623 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
624 if (tmp < 0) return tmp;
625 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
626
627 // set LP FEC
628 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
629 if (tmp < 0) return tmp;
630 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
631
632 // set constellation
633 switch (fe_params->u.ofdm.constellation) {
634 case QPSK:
635 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
636 break;
637
638 case QAM_16:
639 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
640 break;
641
642 case QAM_64:
643 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
644 break;
645
646 default:
647 return -EINVAL;
648 }
649
650 // set hierarchy
651 switch (fe_params->u.ofdm.hierarchy_information) {
652 case HIERARCHY_NONE:
653 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
654 break;
655
656 case HIERARCHY_1:
657 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
658 break;
659
660 case HIERARCHY_2:
661 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
662 break;
663
664 case HIERARCHY_4:
665 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
666 break;
667
668 default:
669 return -EINVAL;
670 }
671 }
672
673 // set bandwidth
674 switch(state->demod_type) {
675 case TDA1004X_DEMOD_TDA10045:
676 tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
677 break;
678
679 case TDA1004X_DEMOD_TDA10046:
680 tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
681 break;
682 }
683
684 // set inversion
685 inversion = fe_params->inversion;
686 if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON;
687 switch (inversion) {
688 case INVERSION_OFF:
689 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
690 break;
691
692 case INVERSION_ON:
693 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
694 break;
695
696 default:
697 return -EINVAL;
698 }
699
700 // set guard interval
701 switch (fe_params->u.ofdm.guard_interval) {
702 case GUARD_INTERVAL_1_32:
703 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
704 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
705 break;
706
707 case GUARD_INTERVAL_1_16:
708 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
709 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
710 break;
711
712 case GUARD_INTERVAL_1_8:
713 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
714 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
715 break;
716
717 case GUARD_INTERVAL_1_4:
718 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
719 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
720 break;
721
722 case GUARD_INTERVAL_AUTO:
723 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
724 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
725 break;
726
727 default:
728 return -EINVAL;
729 }
730
731 // set transmission mode
732 switch (fe_params->u.ofdm.transmission_mode) {
733 case TRANSMISSION_MODE_2K:
734 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
735 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
736 break;
737
738 case TRANSMISSION_MODE_8K:
739 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
740 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
741 break;
742
743 case TRANSMISSION_MODE_AUTO:
744 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
745 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
746 break;
747
748 default:
749 return -EINVAL;
750 }
751
752 // start the lock
753 switch(state->demod_type) {
754 case TDA1004X_DEMOD_TDA10045:
755 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
756 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
757 msleep(10);
758 break;
759
760 case TDA1004X_DEMOD_TDA10046:
761 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
762 msleep(10);
763 break;
764 }
765
766 return 0;
767}
768
769static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
770{
771 struct tda1004x_state* state = fe->demodulator_priv;
772 dprintk("%s\n", __FUNCTION__);
773
774 // inversion status
775 fe_params->inversion = INVERSION_OFF;
776 if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) {
777 fe_params->inversion = INVERSION_ON;
778 }
779 if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
780
781 // bandwidth
782 switch(state->demod_type) {
783 case TDA1004X_DEMOD_TDA10045:
784 switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
785 case 0x14:
786 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
787 break;
788 case 0xdb:
789 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
790 break;
791 case 0x4f:
792 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
793 break;
794 }
795 break;
796
797 case TDA1004X_DEMOD_TDA10046:
798 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
799 case 0x60:
800 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
801 break;
802 case 0x6e:
803 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
804 break;
805 case 0x80:
806 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
807 break;
808 }
809 break;
810 }
811
812 // FEC
813 fe_params->u.ofdm.code_rate_HP =
814 tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
815 fe_params->u.ofdm.code_rate_LP =
816 tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
817
818 // constellation
819 switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
820 case 0:
821 fe_params->u.ofdm.constellation = QPSK;
822 break;
823 case 1:
824 fe_params->u.ofdm.constellation = QAM_16;
825 break;
826 case 2:
827 fe_params->u.ofdm.constellation = QAM_64;
828 break;
829 }
830
831 // transmission mode
832 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
833 if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) {
834 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
835 }
836
837 // guard interval
838 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
839 case 0:
840 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
841 break;
842 case 1:
843 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
844 break;
845 case 2:
846 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
847 break;
848 case 3:
849 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
850 break;
851 }
852
853 // hierarchy
854 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
855 case 0:
856 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
857 break;
858 case 1:
859 fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
860 break;
861 case 2:
862 fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
863 break;
864 case 3:
865 fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
866 break;
867 }
868
869 return 0;
870}
871
872static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
873{
874 struct tda1004x_state* state = fe->demodulator_priv;
875 int status;
876 int cber;
877 int vber;
878
879 dprintk("%s\n", __FUNCTION__);
880
881 // read status
882 status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
883 if (status == -1) {
884 return -EIO;
885 }
886
887 // decode
888 *fe_status = 0;
889 if (status & 4) *fe_status |= FE_HAS_SIGNAL;
890 if (status & 2) *fe_status |= FE_HAS_CARRIER;
891 if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
892
893 // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
894 // is getting anything valid
895 if (!(*fe_status & FE_HAS_VITERBI)) {
896 // read the CBER
897 cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
898 if (cber == -1) return -EIO;
899 status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
900 if (status == -1) return -EIO;
901 cber |= (status << 8);
902 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
903
904 if (cber != 65535) {
905 *fe_status |= FE_HAS_VITERBI;
906 }
907 }
908
909 // if we DO have some valid VITERBI output, but don't already have SYNC
910 // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
911 if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
912 // read the VBER
913 vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
914 if (vber == -1) return -EIO;
915 status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
916 if (status == -1) return -EIO;
917 vber |= (status << 8);
918 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
919 if (status == -1) return -EIO;
920 vber |= ((status << 16) & 0x0f);
921 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
922
923 // if RS has passed some valid TS packets, then we must be
924 // getting some SYNC bytes
925 if (vber < 16632) {
926 *fe_status |= FE_HAS_SYNC;
927 }
928 }
929
930 // success
931 dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
932 return 0;
933}
934
935static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
936{
937 struct tda1004x_state* state = fe->demodulator_priv;
938 int tmp;
939 int reg = 0;
940
941 dprintk("%s\n", __FUNCTION__);
942
943 // determine the register to use
944 switch(state->demod_type) {
945 case TDA1004X_DEMOD_TDA10045:
946 reg = TDA10045H_S_AGC;
947 break;
948
949 case TDA1004X_DEMOD_TDA10046:
950 reg = TDA10046H_AGC_IF_LEVEL;
951 break;
952 }
953
954 // read it
955 tmp = tda1004x_read_byte(state, reg);
956 if (tmp < 0)
957 return -EIO;
958
959 *signal = (tmp << 8) | tmp;
960 dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
961 return 0;
962}
963
964static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
965{
966 struct tda1004x_state* state = fe->demodulator_priv;
967 int tmp;
968
969 dprintk("%s\n", __FUNCTION__);
970
971 // read it
972 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
973 if (tmp < 0)
974 return -EIO;
975 if (tmp) {
976 tmp = 255 - tmp;
977 }
978
979 *snr = ((tmp << 8) | tmp);
980 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
981 return 0;
982}
983
984static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
985{
986 struct tda1004x_state* state = fe->demodulator_priv;
987 int tmp;
988 int tmp2;
989 int counter;
990
991 dprintk("%s\n", __FUNCTION__);
992
993 // read the UCBLOCKS and reset
994 counter = 0;
995 tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
996 if (tmp < 0)
997 return -EIO;
998 tmp &= 0x7f;
999 while (counter++ < 5) {
1000 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1001 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1002 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1003
1004 tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
1005 if (tmp2 < 0)
1006 return -EIO;
1007 tmp2 &= 0x7f;
1008 if ((tmp2 < tmp) || (tmp2 == 0))
1009 break;
1010 }
1011
1012 if (tmp != 0x7f) {
1013 *ucblocks = tmp;
1014 } else {
1015 *ucblocks = 0xffffffff;
1016 }
1017 dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
1018 return 0;
1019}
1020
1021static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1022{
1023 struct tda1004x_state* state = fe->demodulator_priv;
1024 int tmp;
1025
1026 dprintk("%s\n", __FUNCTION__);
1027
1028 // read it in
1029 tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
1030 if (tmp < 0) return -EIO;
1031 *ber = tmp << 1;
1032 tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
1033 if (tmp < 0) return -EIO;
1034 *ber |= (tmp << 9);
1035 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1036
1037 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
1038 return 0;
1039}
1040
1041static int tda1004x_sleep(struct dvb_frontend* fe)
1042{
1043 struct tda1004x_state* state = fe->demodulator_priv;
1044
1045 switch(state->demod_type) {
1046 case TDA1004X_DEMOD_TDA10045:
1047 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
1048 break;
1049
1050 case TDA1004X_DEMOD_TDA10046:
1051 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1052 break;
1053 }
1054 state->initialised = 0;
1055
1056 return 0;
1057}
1058
1059static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1060{
1061 fesettings->min_delay_ms = 800;
1062 fesettings->step_size = 166667;
1063 fesettings->max_drift = 166667*2;
1064 return 0;
1065}
1066
1067static void tda1004x_release(struct dvb_frontend* fe)
1068{
1069 struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv;
1070 kfree(state);
1071}
1072
1073static struct dvb_frontend_ops tda10045_ops;
1074
1075struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1076 struct i2c_adapter* i2c)
1077{
1078 struct tda1004x_state* state = NULL;
1079
1080 /* allocate memory for the internal state */
1081 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1082 if (state == NULL) goto error;
1083
1084 /* setup the state */
1085 state->config = config;
1086 state->i2c = i2c;
1087 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1088 state->initialised = 0;
1089 state->demod_type = TDA1004X_DEMOD_TDA10045;
1090
1091 /* check if the demod is there */
1092 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error;
1093
1094 /* create dvb_frontend */
1095 state->frontend.ops = &state->ops;
1096 state->frontend.demodulator_priv = state;
1097 return &state->frontend;
1098
1099error:
1100 kfree(state);
1101 return NULL;
1102}
1103
1104static struct dvb_frontend_ops tda10046_ops;
1105
1106struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1107 struct i2c_adapter* i2c)
1108{
1109 struct tda1004x_state* state = NULL;
1110
1111 /* allocate memory for the internal state */
1112 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1113 if (state == NULL) goto error;
1114
1115 /* setup the state */
1116 state->config = config;
1117 state->i2c = i2c;
1118 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1119 state->initialised = 0;
1120 state->demod_type = TDA1004X_DEMOD_TDA10046;
1121
1122 /* check if the demod is there */
1123 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error;
1124
1125 /* create dvb_frontend */
1126 state->frontend.ops = &state->ops;
1127 state->frontend.demodulator_priv = state;
1128 return &state->frontend;
1129
1130error:
1131 if (state) kfree(state);
1132 return NULL;
1133}
1134
1135static struct dvb_frontend_ops tda10045_ops = {
1136
1137 .info = {
1138 .name = "Philips TDA10045H DVB-T",
1139 .type = FE_OFDM,
1140 .frequency_min = 51000000,
1141 .frequency_max = 858000000,
1142 .frequency_stepsize = 166667,
1143 .caps =
1144 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1145 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1146 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1147 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1148 },
1149
1150 .release = tda1004x_release,
1151
1152 .init = tda10045_init,
1153 .sleep = tda1004x_sleep,
1154
1155 .set_frontend = tda1004x_set_fe,
1156 .get_frontend = tda1004x_get_fe,
1157 .get_tune_settings = tda1004x_get_tune_settings,
1158
1159 .read_status = tda1004x_read_status,
1160 .read_ber = tda1004x_read_ber,
1161 .read_signal_strength = tda1004x_read_signal_strength,
1162 .read_snr = tda1004x_read_snr,
1163 .read_ucblocks = tda1004x_read_ucblocks,
1164};
1165
1166static struct dvb_frontend_ops tda10046_ops = {
1167
1168 .info = {
1169 .name = "Philips TDA10046H DVB-T",
1170 .type = FE_OFDM,
1171 .frequency_min = 51000000,
1172 .frequency_max = 858000000,
1173 .frequency_stepsize = 166667,
1174 .caps =
1175 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1176 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1177 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1178 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1179 },
1180
1181 .release = tda1004x_release,
1182
1183 .init = tda10046_init,
1184 .sleep = tda1004x_sleep,
1185
1186 .set_frontend = tda1004x_set_fe,
1187 .get_frontend = tda1004x_get_fe,
1188 .get_tune_settings = tda1004x_get_tune_settings,
1189
1190 .read_status = tda1004x_read_status,
1191 .read_ber = tda1004x_read_ber,
1192 .read_signal_strength = tda1004x_read_signal_strength,
1193 .read_snr = tda1004x_read_snr,
1194 .read_ucblocks = tda1004x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
1201MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(tda10045_attach);
1205EXPORT_SYMBOL(tda10046_attach);
1206EXPORT_SYMBOL(tda1004x_write_byte);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
new file mode 100644
index 000000000000..e452fc0bad11
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -0,0 +1,56 @@
1 /*
2 Driver for Philips tda1004xh OFDM Frontend
3
4 (c) 2004 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef TDA1004X_H
24#define TDA1004X_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct tda1004x_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* does the "inversion" need inverted? */
35 u8 invert:1;
36
37 /* Does the OCLK signal need inverted? */
38 u8 invert_oclk:1;
39
40 /* PLL maintenance */
41 int (*pll_init)(struct dvb_frontend* fe);
42 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
43
44 /* request firmware for device */
45 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
46};
47
48extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
49 struct i2c_adapter* i2c);
50
51extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
52 struct i2c_adapter* i2c);
53
54extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data);
55
56#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
new file mode 100644
index 000000000000..da82e90d6d13
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -0,0 +1,456 @@
1/*
2 Driver for Philips TDA8083 based QPSK Demodulator
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include "dvb_frontend.h"
34#include "tda8083.h"
35
36
37struct tda8083_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda8083_config* config;
42 struct dvb_frontend frontend;
43};
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "tda8083: " args); \
49 } while (0)
50
51
52static u8 tda8083_init_tab [] = {
53 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
54 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
55 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
56 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
57 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00
59};
60
61
62static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
63{
64 int ret;
65 u8 buf [] = { reg, data };
66 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
67
68 ret = i2c_transfer(state->i2c, &msg, 1);
69
70 if (ret != 1)
71 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
72 __FUNCTION__, reg, ret);
73
74 return (ret != 1) ? -1 : 0;
75}
76
77static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
78{
79 int ret;
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
82
83 ret = i2c_transfer(state->i2c, msg, 2);
84
85 if (ret != 2)
86 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
87 __FUNCTION__, reg1, ret);
88
89 return ret == 2 ? 0 : -1;
90}
91
92static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
93{
94 u8 val;
95
96 tda8083_readregs (state, reg, &val, 1);
97
98 return val;
99}
100
101static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
102{
103 /* XXX FIXME: implement other modes than FEC_AUTO */
104 if (inversion == INVERSION_AUTO)
105 return 0;
106
107 return -EINVAL;
108}
109
110static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
111{
112 if (fec == FEC_AUTO)
113 return tda8083_writereg (state, 0x07, 0xff);
114
115 if (fec >= FEC_1_2 && fec <= FEC_8_9)
116 return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
117
118 return -EINVAL;
119}
120
121static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
122{
123 u8 index;
124 static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
125 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
126
127 index = tda8083_readreg(state, 0x0e) & 0x07;
128
129 return fec_tab [index];
130}
131
132static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
133{
134 u32 ratio;
135 u32 tmp;
136 u8 filter;
137
138 if (srate > 32000000)
139 srate = 32000000;
140 if (srate < 500000)
141 srate = 500000;
142
143 filter = 0;
144 if (srate < 24000000)
145 filter = 2;
146 if (srate < 16000000)
147 filter = 3;
148
149 tmp = 31250 << 16;
150 ratio = tmp / srate;
151
152 tmp = (tmp % srate) << 8;
153 ratio = (ratio << 8) + tmp / srate;
154
155 tmp = (tmp % srate) << 8;
156 ratio = (ratio << 8) + tmp / srate;
157
158 dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
159
160 tda8083_writereg (state, 0x05, filter);
161 tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
162 tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff);
163 tda8083_writereg (state, 0x04, (ratio ) & 0xff);
164
165 tda8083_writereg (state, 0x00, 0x3c);
166 tda8083_writereg (state, 0x00, 0x04);
167
168 return 1;
169}
170
171static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
172{
173 unsigned long start = jiffies;
174
175 while (jiffies - start < timeout &&
176 !(tda8083_readreg(state, 0x02) & 0x80))
177 {
178 msleep(50);
179 };
180}
181
182static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
183{
184 tda8083_writereg (state, 0x26, 0xf1);
185
186 switch (tone) {
187 case SEC_TONE_OFF:
188 return tda8083_writereg (state, 0x29, 0x00);
189 case SEC_TONE_ON:
190 return tda8083_writereg (state, 0x29, 0x80);
191 default:
192 return -EINVAL;
193 };
194}
195
196static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
197{
198 switch (voltage) {
199 case SEC_VOLTAGE_13:
200 return tda8083_writereg (state, 0x20, 0x00);
201 case SEC_VOLTAGE_18:
202 return tda8083_writereg (state, 0x20, 0x11);
203 default:
204 return -EINVAL;
205 };
206}
207
208static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
209{
210 switch (burst) {
211 case SEC_MINI_A:
212 tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */
213 break;
214 case SEC_MINI_B:
215 tda8083_writereg (state, 0x29, (7 << 2)); /* send B */
216 break;
217 default:
218 return -EINVAL;
219 };
220
221 tda8083_wait_diseqc_fifo (state, 100);
222
223 return 0;
224}
225
226static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
227 struct dvb_diseqc_master_cmd *m)
228{
229 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
230 int i;
231
232 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
233
234 for (i=0; i<m->msg_len; i++)
235 tda8083_writereg (state, 0x23 + i, m->msg[i]);
236
237 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
238
239 tda8083_wait_diseqc_fifo (state, 100);
240
241 return 0;
242}
243
244static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
245{
246 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
247
248 u8 signal = ~tda8083_readreg (state, 0x01);
249 u8 sync = tda8083_readreg (state, 0x02);
250
251 *status = 0;
252
253 if (signal > 10)
254 *status |= FE_HAS_SIGNAL;
255
256 if (sync & 0x01)
257 *status |= FE_HAS_CARRIER;
258
259 if (sync & 0x02)
260 *status |= FE_HAS_VITERBI;
261
262 if (sync & 0x10)
263 *status |= FE_HAS_SYNC;
264
265 if ((sync & 0x1f) == 0x1f)
266 *status |= FE_HAS_LOCK;
267
268 return 0;
269}
270
271static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
272{
273 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
274
275 u8 signal = ~tda8083_readreg (state, 0x01);
276 *strength = (signal << 8) | signal;
277
278 return 0;
279}
280
281static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
282{
283 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
284
285 u8 _snr = tda8083_readreg (state, 0x08);
286 *snr = (_snr << 8) | _snr;
287
288 return 0;
289}
290
291static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
292{
293 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
294
295 state->config->pll_set(fe, p);
296 tda8083_set_inversion (state, p->inversion);
297 tda8083_set_fec (state, p->u.qpsk.fec_inner);
298 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate);
299
300 tda8083_writereg (state, 0x00, 0x3c);
301 tda8083_writereg (state, 0x00, 0x04);
302
303 return 0;
304}
305
306static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
307{
308 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
309
310 /* FIXME: get symbolrate & frequency offset...*/
311 /*p->frequency = ???;*/
312 p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
313 INVERSION_ON : INVERSION_OFF;
314 p->u.qpsk.fec_inner = tda8083_get_fec (state);
315 /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/
316
317 return 0;
318}
319
320static int tda8083_sleep(struct dvb_frontend* fe)
321{
322 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
323
324 tda8083_writereg (state, 0x00, 0x02);
325 return 0;
326}
327
328static int tda8083_init(struct dvb_frontend* fe)
329{
330 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
331 int i;
332
333 for (i=0; i<44; i++)
334 tda8083_writereg (state, i, tda8083_init_tab[i]);
335
336 if (state->config->pll_init) state->config->pll_init(fe);
337
338 tda8083_writereg (state, 0x00, 0x3c);
339 tda8083_writereg (state, 0x00, 0x04);
340
341 return 0;
342}
343
344static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
345{
346 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
347
348 tda8083_send_diseqc_burst (state, burst);
349 tda8083_writereg (state, 0x00, 0x3c);
350 tda8083_writereg (state, 0x00, 0x04);
351
352 return 0;
353}
354
355static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
356{
357 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
358
359 tda8083_set_tone (state, tone);
360 tda8083_writereg (state, 0x00, 0x3c);
361 tda8083_writereg (state, 0x00, 0x04);
362
363 return 0;
364}
365
366static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
367{
368 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
369
370 tda8083_set_voltage (state, voltage);
371 tda8083_writereg (state, 0x00, 0x3c);
372 tda8083_writereg (state, 0x00, 0x04);
373
374 return 0;
375}
376
377static void tda8083_release(struct dvb_frontend* fe)
378{
379 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
380 kfree(state);
381}
382
383static struct dvb_frontend_ops tda8083_ops;
384
385struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
386 struct i2c_adapter* i2c)
387{
388 struct tda8083_state* state = NULL;
389
390 /* allocate memory for the internal state */
391 state = (struct tda8083_state*) kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
392 if (state == NULL) goto error;
393
394 /* setup the state */
395 state->config = config;
396 state->i2c = i2c;
397 memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
398
399 /* check if the demod is there */
400 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
401
402 /* create dvb_frontend */
403 state->frontend.ops = &state->ops;
404 state->frontend.demodulator_priv = state;
405 return &state->frontend;
406
407error:
408 kfree(state);
409 return NULL;
410}
411
412static struct dvb_frontend_ops tda8083_ops = {
413
414 .info = {
415 .name = "Philips TDA8083 DVB-S",
416 .type = FE_QPSK,
417 .frequency_min = 950000, /* FIXME: guessed! */
418 .frequency_max = 1400000, /* FIXME: guessed! */
419 .frequency_stepsize = 125, /* kHz for QPSK frontends */
420 /* .frequency_tolerance = ???,*/
421 .symbol_rate_min = 1000000, /* FIXME: guessed! */
422 .symbol_rate_max = 45000000, /* FIXME: guessed! */
423 /* .symbol_rate_tolerance = ???,*/
424 .caps = FE_CAN_INVERSION_AUTO |
425 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
426 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
427 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
428 FE_CAN_QPSK | FE_CAN_MUTE_TS
429 },
430
431 .release = tda8083_release,
432
433 .init = tda8083_init,
434 .sleep = tda8083_sleep,
435
436 .set_frontend = tda8083_set_frontend,
437 .get_frontend = tda8083_get_frontend,
438
439 .read_status = tda8083_read_status,
440 .read_signal_strength = tda8083_read_signal_strength,
441 .read_snr = tda8083_read_snr,
442
443 .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
444 .diseqc_send_burst = tda8083_diseqc_send_burst,
445 .set_tone = tda8083_diseqc_set_tone,
446 .set_voltage = tda8083_diseqc_set_voltage,
447};
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
453MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
454MODULE_LICENSE("GPL");
455
456EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
new file mode 100644
index 000000000000..466663307bf1
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef TDA8083_H
28#define TDA8083_H
29
30#include <linux/dvb/frontend.h>
31
32struct tda8083_config
33{
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 /* PLL maintenance */
38 int (*pll_init)(struct dvb_frontend* fe);
39 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
40};
41
42extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
new file mode 100644
index 000000000000..c99632114283
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -0,0 +1,734 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
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/config.h>
25#include <linux/delay.h>
26#include <linux/init.h>
27#include <linux/spinlock.h>
28#include <linux/threads.h>
29#include <linux/interrupt.h>
30#include <asm/irq.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "tda80xx.h"
38
39enum {
40 ID_TDA8044 = 0x04,
41 ID_TDA8083 = 0x05,
42};
43
44
45struct tda80xx_state {
46
47 struct i2c_adapter* i2c;
48
49 struct dvb_frontend_ops ops;
50
51 /* configuration settings */
52 const struct tda80xx_config* config;
53
54 struct dvb_frontend frontend;
55
56 u32 clk;
57 int afc_loop;
58 struct work_struct worklet;
59 fe_code_rate_t code_rate;
60 fe_spectral_inversion_t spectral_inversion;
61 fe_status_t status;
62 u8 id;
63};
64
65static int debug = 1;
66#define dprintk if (debug) printk
67
68static u8 tda8044_inittab_pre[] = {
69 0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
70 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
71 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
72 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
73 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00
75};
76
77static u8 tda8044_inittab_post[] = {
78 0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
79 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
80 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
81 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
82 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00
84};
85
86static u8 tda8083_inittab[] = {
87 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
88 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
89 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
90 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
91 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00
93};
94
95static __inline__ u32 tda80xx_div(u32 a, u32 b)
96{
97 return (a + (b / 2)) / b;
98}
99
100static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
101{
102 u32 r;
103
104 while ((r = a % b)) {
105 a = b;
106 b = r;
107 }
108
109 return b;
110}
111
112static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
113{
114 int ret;
115 struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
116 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
117
118 ret = i2c_transfer(state->i2c, msg, 2);
119
120 if (ret != 2)
121 dprintk("%s: readreg error (reg %02x, ret == %i)\n",
122 __FUNCTION__, reg, ret);
123
124 mdelay(10);
125
126 return (ret == 2) ? 0 : -EREMOTEIO;
127}
128
129static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
130{
131 int ret;
132 u8 wbuf[len + 1];
133 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
134
135 wbuf[0] = reg;
136 memcpy(&wbuf[1], buf, len);
137
138 ret = i2c_transfer(state->i2c, &msg, 1);
139
140 if (ret != 1)
141 dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
142
143 mdelay(10);
144
145 return (ret == 1) ? 0 : -EREMOTEIO;
146}
147
148static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
149{
150 u8 val;
151
152 tda80xx_read(state, reg, &val, 1);
153
154 return val;
155}
156
157static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
158{
159 return tda80xx_write(state, reg, &data, 1);
160}
161
162static int tda80xx_set_parameters(struct tda80xx_state* state,
163 fe_spectral_inversion_t inversion,
164 u32 symbol_rate,
165 fe_code_rate_t fec_inner)
166{
167 u8 buf[15];
168 u64 ratio;
169 u32 clk;
170 u32 k;
171 u32 sr = symbol_rate;
172 u32 gcd;
173 u8 scd;
174
175 if (symbol_rate > (state->clk * 3) / 16)
176 scd = 0;
177 else if (symbol_rate > (state->clk * 3) / 32)
178 scd = 1;
179 else if (symbol_rate > (state->clk * 3) / 64)
180 scd = 2;
181 else
182 scd = 3;
183
184 clk = scd ? (state->clk / (scd * 2)) : state->clk;
185
186 /*
187 * Viterbi decoder:
188 * Differential decoding off
189 * Spectral inversion unknown
190 * QPSK modulation
191 */
192 if (inversion == INVERSION_ON)
193 buf[0] = 0x60;
194 else if (inversion == INVERSION_OFF)
195 buf[0] = 0x20;
196 else
197 buf[0] = 0x00;
198
199 /*
200 * CLK ratio:
201 * system clock frequency is up to 64 or 96 MHz
202 *
203 * formula:
204 * r = k * clk / symbol_rate
205 *
206 * k: 2^21 for caa 0..3,
207 * 2^20 for caa 4..5,
208 * 2^19 for caa 6..7
209 */
210 if (symbol_rate <= (clk * 3) / 32)
211 k = (1 << 19);
212 else if (symbol_rate <= (clk * 3) / 16)
213 k = (1 << 20);
214 else
215 k = (1 << 21);
216
217 gcd = tda80xx_gcd(clk, sr);
218 clk /= gcd;
219 sr /= gcd;
220
221 gcd = tda80xx_gcd(k, sr);
222 k /= gcd;
223 sr /= gcd;
224
225 ratio = (u64)k * (u64)clk;
226 do_div(ratio, sr);
227
228 buf[1] = ratio >> 16;
229 buf[2] = ratio >> 8;
230 buf[3] = ratio;
231
232 /* nyquist filter roll-off factor 35% */
233 buf[4] = 0x20;
234
235 clk = scd ? (state->clk / (scd * 2)) : state->clk;
236
237 /* Anti Alias Filter */
238 if (symbol_rate < (clk * 3) / 64)
239 printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
240 else if (symbol_rate <= clk / 16)
241 buf[4] |= 0x07;
242 else if (symbol_rate <= (clk * 3) / 32)
243 buf[4] |= 0x06;
244 else if (symbol_rate <= clk / 8)
245 buf[4] |= 0x05;
246 else if (symbol_rate <= (clk * 3) / 16)
247 buf[4] |= 0x04;
248 else if (symbol_rate <= clk / 4)
249 buf[4] |= 0x03;
250 else if (symbol_rate <= (clk * 3) / 8)
251 buf[4] |= 0x02;
252 else if (symbol_rate <= clk / 2)
253 buf[4] |= 0x01;
254 else
255 buf[4] |= 0x00;
256
257 /* Sigma Delta converter */
258 buf[5] = 0x00;
259
260 /* FEC: Possible puncturing rates */
261 if (fec_inner == FEC_NONE)
262 buf[6] = 0x00;
263 else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
264 buf[6] = (1 << (8 - fec_inner));
265 else if (fec_inner == FEC_AUTO)
266 buf[6] = 0xff;
267 else
268 return -EINVAL;
269
270 /* carrier lock detector threshold value */
271 buf[7] = 0x30;
272 /* AFC1: proportional part settings */
273 buf[8] = 0x42;
274 /* AFC1: integral part settings */
275 buf[9] = 0x98;
276 /* PD: Leaky integrator SCPC mode */
277 buf[10] = 0x28;
278 /* AFC2, AFC1 controls */
279 buf[11] = 0x30;
280 /* PD: proportional part settings */
281 buf[12] = 0x42;
282 /* PD: integral part settings */
283 buf[13] = 0x99;
284 /* AGC */
285 buf[14] = 0x50 | scd;
286
287 printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
288
289 return tda80xx_write(state, 0x01, buf, sizeof(buf));
290}
291
292static int tda80xx_set_clk(struct tda80xx_state* state)
293{
294 u8 buf[2];
295
296 /* CLK proportional part */
297 buf[0] = (0x06 << 5) | 0x08; /* CMP[2:0], CSP[4:0] */
298 /* CLK integral part */
299 buf[1] = (0x04 << 5) | 0x1a; /* CMI[2:0], CSI[4:0] */
300
301 return tda80xx_write(state, 0x17, buf, sizeof(buf));
302}
303
304#if 0
305static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
306{
307 /* a constant value is nonsense here imho */
308 return tda80xx_writereg(state, 0x22, 0xf9);
309}
310#endif
311
312static int tda80xx_close_loop(struct tda80xx_state* state)
313{
314 u8 buf[2];
315
316 /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
317 buf[0] = 0x68;
318 /* AFC1: Loop closed, CAR Feedback: 8192 */
319 buf[1] = 0x70;
320
321 return tda80xx_write(state, 0x0b, buf, sizeof(buf));
322}
323
324static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
325{
326 schedule_work(priv);
327
328 return IRQ_HANDLED;
329}
330
331static void tda80xx_read_status_int(struct tda80xx_state* state)
332{
333 u8 val;
334
335 static const fe_spectral_inversion_t inv_tab[] = {
336 INVERSION_OFF, INVERSION_ON
337 };
338
339 static const fe_code_rate_t fec_tab[] = {
340 FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
341 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
342 };
343
344 val = tda80xx_readreg(state, 0x02);
345
346 state->status = 0;
347
348 if (val & 0x01) /* demodulator lock */
349 state->status |= FE_HAS_SIGNAL;
350 if (val & 0x02) /* clock recovery lock */
351 state->status |= FE_HAS_CARRIER;
352 if (val & 0x04) /* viterbi lock */
353 state->status |= FE_HAS_VITERBI;
354 if (val & 0x08) /* deinterleaver lock (packet sync) */
355 state->status |= FE_HAS_SYNC;
356 if (val & 0x10) /* derandomizer lock (frame sync) */
357 state->status |= FE_HAS_LOCK;
358 if (val & 0x20) /* frontend can not lock */
359 state->status |= FE_TIMEDOUT;
360
361 if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
362 printk("tda80xx: closing loop\n");
363 tda80xx_close_loop(state);
364 state->afc_loop = 0;
365 }
366
367 if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
368 val = tda80xx_readreg(state, 0x0e);
369 state->code_rate = fec_tab[val & 0x07];
370 if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
371 state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
372 else
373 state->spectral_inversion = INVERSION_AUTO;
374 }
375 else {
376 state->code_rate = FEC_AUTO;
377 }
378}
379
380static void tda80xx_worklet(void *priv)
381{
382 struct tda80xx_state *state = priv;
383
384 tda80xx_writereg(state, 0x00, 0x04);
385 enable_irq(state->config->irq);
386
387 tda80xx_read_status_int(state);
388}
389
390static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
391{
392 size_t i;
393
394 for (i = 0; i < 100; i++) {
395 if (tda80xx_readreg(state, 0x02) & 0x80)
396 break;
397 msleep(10);
398 }
399}
400
401static int tda8044_init(struct dvb_frontend* fe)
402{
403 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
404 int ret;
405
406 /*
407 * this function is a mess...
408 */
409
410 if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
411 return ret;
412
413 tda80xx_writereg(state, 0x0f, 0x50);
414#if 1
415 tda80xx_writereg(state, 0x20, 0x8F); /* FIXME */
416 tda80xx_writereg(state, 0x20, state->config->volt18setting); /* FIXME */
417 //tda80xx_writereg(state, 0x00, 0x04);
418 tda80xx_writereg(state, 0x00, 0x0C);
419#endif
420 //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
421
422 tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
423
424 if (state->config->pll_init) {
425 tda80xx_writereg(state, 0x1c, 0x80);
426 state->config->pll_init(fe);
427 tda80xx_writereg(state, 0x1c, 0x00);
428 }
429
430 return 0;
431}
432
433static int tda8083_init(struct dvb_frontend* fe)
434{
435 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
436
437 tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
438
439 if (state->config->pll_init) {
440 tda80xx_writereg(state, 0x1c, 0x80);
441 state->config->pll_init(fe);
442 tda80xx_writereg(state, 0x1c, 0x00);
443 }
444
445 return 0;
446}
447
448static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
449{
450 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
451
452 switch (voltage) {
453 case SEC_VOLTAGE_13:
454 return tda80xx_writereg(state, 0x20, state->config->volt13setting);
455 case SEC_VOLTAGE_18:
456 return tda80xx_writereg(state, 0x20, state->config->volt18setting);
457 case SEC_VOLTAGE_OFF:
458 return tda80xx_writereg(state, 0x20, 0);
459 default:
460 return -EINVAL;
461 }
462}
463
464static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
465{
466 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
467
468 switch (tone) {
469 case SEC_TONE_OFF:
470 return tda80xx_writereg(state, 0x29, 0x00);
471 case SEC_TONE_ON:
472 return tda80xx_writereg(state, 0x29, 0x80);
473 default:
474 return -EINVAL;
475 }
476}
477
478static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
479{
480 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
481
482 if (cmd->msg_len > 6)
483 return -EINVAL;
484
485 tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
486 tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
487 tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
488 tda80xx_wait_diseqc_fifo(state);
489
490 return 0;
491}
492
493static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
494{
495 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
496
497 switch (cmd) {
498 case SEC_MINI_A:
499 tda80xx_writereg(state, 0x29, 0x14);
500 break;
501 case SEC_MINI_B:
502 tda80xx_writereg(state, 0x29, 0x1c);
503 break;
504 default:
505 return -EINVAL;
506 }
507
508 tda80xx_wait_diseqc_fifo(state);
509
510 return 0;
511}
512
513static int tda80xx_sleep(struct dvb_frontend* fe)
514{
515 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
516
517 tda80xx_writereg(state, 0x00, 0x02); /* enter standby */
518
519 return 0;
520}
521
522static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
523{
524 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
525
526 tda80xx_writereg(state, 0x1c, 0x80);
527 state->config->pll_set(fe, p);
528 tda80xx_writereg(state, 0x1c, 0x00);
529
530 tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
531 tda80xx_set_clk(state);
532 //tda80xx_set_scpc_freq_offset(state);
533 state->afc_loop = 1;
534
535 return 0;
536}
537
538static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
539{
540 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
541
542 if (!state->config->irq)
543 tda80xx_read_status_int(state);
544
545 p->inversion = state->spectral_inversion;
546 p->u.qpsk.fec_inner = state->code_rate;
547
548 return 0;
549}
550
551static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
552{
553 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
554
555 if (!state->config->irq)
556 tda80xx_read_status_int(state);
557 *status = state->status;
558
559 return 0;
560}
561
562static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
563{
564 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
565 int ret;
566 u8 buf[3];
567
568 if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
569 return ret;
570
571 *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
572
573 return 0;
574}
575
576static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
577{
578 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
579
580 u8 gain = ~tda80xx_readreg(state, 0x01);
581 *strength = (gain << 8) | gain;
582
583 return 0;
584}
585
586static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
587{
588 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
589
590 u8 quality = tda80xx_readreg(state, 0x08);
591 *snr = (quality << 8) | quality;
592
593 return 0;
594}
595
596static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
597{
598 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
599
600 *ucblocks = tda80xx_readreg(state, 0x0f);
601 if (*ucblocks == 0xff)
602 *ucblocks = 0xffffffff;
603
604 return 0;
605}
606
607static int tda80xx_init(struct dvb_frontend* fe)
608{
609 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
610
611 switch(state->id) {
612 case ID_TDA8044:
613 return tda8044_init(fe);
614
615 case ID_TDA8083:
616 return tda8083_init(fe);
617 }
618 return 0;
619}
620
621static void tda80xx_release(struct dvb_frontend* fe)
622{
623 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
624
625 if (state->config->irq)
626 free_irq(state->config->irq, &state->worklet);
627
628 kfree(state);
629}
630
631static struct dvb_frontend_ops tda80xx_ops;
632
633struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct tda80xx_state* state = NULL;
637 int ret;
638
639 /* allocate memory for the internal state */
640 state = (struct tda80xx_state*) kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
647 state->spectral_inversion = INVERSION_AUTO;
648 state->code_rate = FEC_AUTO;
649 state->status = 0;
650 state->afc_loop = 0;
651
652 /* check if the demod is there */
653 if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
654 state->id = tda80xx_readreg(state, 0x00);
655
656 switch (state->id) {
657 case ID_TDA8044:
658 state->clk = 96000000;
659 printk("tda80xx: Detected tda8044\n");
660 break;
661
662 case ID_TDA8083:
663 state->clk = 64000000;
664 printk("tda80xx: Detected tda8083\n");
665 break;
666
667 default:
668 goto error;
669 }
670
671 /* setup IRQ */
672 if (state->config->irq) {
673 INIT_WORK(&state->worklet, tda80xx_worklet, state);
674 if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
675 printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
676 goto error;
677 }
678 }
679
680 /* create dvb_frontend */
681 state->frontend.ops = &state->ops;
682 state->frontend.demodulator_priv = state;
683 return &state->frontend;
684
685error:
686 kfree(state);
687 return NULL;
688}
689
690static struct dvb_frontend_ops tda80xx_ops = {
691
692 .info = {
693 .name = "Philips TDA80xx DVB-S",
694 .type = FE_QPSK,
695 .frequency_min = 500000,
696 .frequency_max = 2700000,
697 .frequency_stepsize = 125,
698 .symbol_rate_min = 4500000,
699 .symbol_rate_max = 45000000,
700 .caps = FE_CAN_INVERSION_AUTO |
701 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
702 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
703 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
704 FE_CAN_QPSK |
705 FE_CAN_MUTE_TS
706 },
707
708 .release = tda80xx_release,
709
710 .init = tda80xx_init,
711 .sleep = tda80xx_sleep,
712
713 .set_frontend = tda80xx_set_frontend,
714 .get_frontend = tda80xx_get_frontend,
715
716 .read_status = tda80xx_read_status,
717 .read_ber = tda80xx_read_ber,
718 .read_signal_strength = tda80xx_read_signal_strength,
719 .read_snr = tda80xx_read_snr,
720 .read_ucblocks = tda80xx_read_ucblocks,
721
722 .diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
723 .diseqc_send_burst = tda80xx_send_diseqc_burst,
724 .set_tone = tda80xx_set_tone,
725 .set_voltage = tda80xx_set_voltage,
726};
727
728module_param(debug, int, 0644);
729
730MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
731MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
732MODULE_LICENSE("GPL");
733
734EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
new file mode 100644
index 000000000000..cd639a0aad55
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.h
@@ -0,0 +1,51 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
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#ifndef TDA80XX_H
25#define TDA80XX_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda80xx_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* IRQ to use (0=>no IRQ used) */
35 u32 irq;
36
37 /* Register setting to use for 13v */
38 u8 volt13setting;
39
40 /* Register setting to use for 18v */
41 u8 volt18setting;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
49 struct i2c_adapter* i2c);
50
51#endif // TDA80XX_H
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
new file mode 100644
index 000000000000..9c0d23e1d9e5
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -0,0 +1,450 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
21#include <linux/config.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <asm/div64.h>
30
31#include "dvb_frontend.h"
32#include "ves1820.h"
33
34
35
36struct ves1820_state {
37 struct i2c_adapter* i2c;
38 struct dvb_frontend_ops ops;
39 /* configuration settings */
40 const struct ves1820_config* config;
41 struct dvb_frontend frontend;
42
43 /* private demodulator data */
44 u8 reg0;
45 u8 pwm;
46};
47
48
49static int verbose;
50
51static u8 ves1820_inittab[] = {
52 0x69, 0x6A, 0x93, 0x12, 0x12, 0x46, 0x26, 0x1A,
53 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
54 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
56 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x40
59};
60
61static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
62{
63 u8 buf[] = { 0x00, reg, data };
64 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
65 int ret;
66
67 ret = i2c_transfer(state->i2c, &msg, 1);
68
69 if (ret != 1)
70 printk("ves1820: %s(): writereg error (reg == 0x%02x,"
71 "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
72
73 msleep(10);
74 return (ret != 1) ? -EREMOTEIO : 0;
75}
76
77static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
78{
79 u8 b0[] = { 0x00, reg };
80 u8 b1[] = { 0 };
81 struct i2c_msg msg[] = {
82 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
83 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
84 };
85 int ret;
86
87 ret = i2c_transfer(state->i2c, msg, 2);
88
89 if (ret != 2)
90 printk("ves1820: %s(): readreg error (reg == 0x%02x,"
91 "ret == %i)\n", __FUNCTION__, reg, ret);
92
93 return b1[0];
94}
95
96static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
97{
98 reg0 |= state->reg0 & 0x62;
99
100 if (INVERSION_ON == inversion) {
101 if (!state->config->invert) reg0 |= 0x20;
102 else reg0 &= ~0x20;
103 } else if (INVERSION_OFF == inversion) {
104 if (!state->config->invert) reg0 &= ~0x20;
105 else reg0 |= 0x20;
106 }
107
108 ves1820_writereg(state, 0x00, reg0 & 0xfe);
109 ves1820_writereg(state, 0x00, reg0 | 0x01);
110
111 state->reg0 = reg0;
112
113 return 0;
114}
115
116static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
117{
118 s32 BDR;
119 s32 BDRI;
120 s16 SFIL = 0;
121 u16 NDEC = 0;
122 u32 ratio;
123 u32 fin;
124 u32 tmp;
125 u64 fptmp;
126 u64 fpxin;
127
128 if (symbolrate > state->config->xin / 2)
129 symbolrate = state->config->xin / 2;
130
131 if (symbolrate < 500000)
132 symbolrate = 500000;
133
134 if (symbolrate < state->config->xin / 16)
135 NDEC = 1;
136 if (symbolrate < state->config->xin / 32)
137 NDEC = 2;
138 if (symbolrate < state->config->xin / 64)
139 NDEC = 3;
140
141 /* yeuch! */
142 fpxin = state->config->xin * 10;
143 fptmp = fpxin; do_div(fptmp, 123);
144 if (symbolrate < fptmp);
145 SFIL = 1;
146 fptmp = fpxin; do_div(fptmp, 160);
147 if (symbolrate < fptmp);
148 SFIL = 0;
149 fptmp = fpxin; do_div(fptmp, 246);
150 if (symbolrate < fptmp);
151 SFIL = 1;
152 fptmp = fpxin; do_div(fptmp, 320);
153 if (symbolrate < fptmp);
154 SFIL = 0;
155 fptmp = fpxin; do_div(fptmp, 492);
156 if (symbolrate < fptmp);
157 SFIL = 1;
158 fptmp = fpxin; do_div(fptmp, 640);
159 if (symbolrate < fptmp);
160 SFIL = 0;
161 fptmp = fpxin; do_div(fptmp, 984);
162 if (symbolrate < fptmp);
163 SFIL = 1;
164
165 fin = state->config->xin >> 4;
166 symbolrate <<= NDEC;
167 ratio = (symbolrate << 4) / fin;
168 tmp = ((symbolrate << 4) % fin) << 8;
169 ratio = (ratio << 8) + tmp / fin;
170 tmp = (tmp % fin) << 8;
171 ratio = (ratio << 8) + (tmp + fin / 2) / fin;
172
173 BDR = ratio;
174 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
175
176 if (BDRI > 0xFF)
177 BDRI = 0xFF;
178
179 SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
180
181 NDEC = (NDEC << 6) | ves1820_inittab[0x03];
182
183 ves1820_writereg(state, 0x03, NDEC);
184 ves1820_writereg(state, 0x0a, BDR & 0xff);
185 ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
186 ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
187
188 ves1820_writereg(state, 0x0d, BDRI);
189 ves1820_writereg(state, 0x0e, SFIL);
190
191 return 0;
192}
193
194static int ves1820_init(struct dvb_frontend* fe)
195{
196 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
197 int i;
198 int val;
199
200 ves1820_writereg(state, 0, 0);
201
202 for (i = 0; i < 53; i++) {
203 val = ves1820_inittab[i];
204 if ((i == 2) && (state->config->selagc)) val |= 0x08;
205 ves1820_writereg(state, i, val);
206 }
207
208 ves1820_writereg(state, 0x34, state->pwm);
209
210 if (state->config->pll_init) state->config->pll_init(fe);
211
212 return 0;
213}
214
215static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
216{
217 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
218 static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
219 static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
220 static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
221 static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
222 static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
223 int real_qam = p->u.qam.modulation - QAM_16;
224
225 if (real_qam < 0 || real_qam > 4)
226 return -EINVAL;
227
228 state->config->pll_set(fe, p);
229 ves1820_set_symbolrate(state, p->u.qam.symbol_rate);
230 ves1820_writereg(state, 0x34, state->pwm);
231
232 ves1820_writereg(state, 0x01, reg0x01[real_qam]);
233 ves1820_writereg(state, 0x05, reg0x05[real_qam]);
234 ves1820_writereg(state, 0x08, reg0x08[real_qam]);
235 ves1820_writereg(state, 0x09, reg0x09[real_qam]);
236
237 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
238
239 return 0;
240}
241
242static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
243{
244 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
245 int sync;
246
247 *status = 0;
248 sync = ves1820_readreg(state, 0x11);
249
250 if (sync & 1)
251 *status |= FE_HAS_SIGNAL;
252
253 if (sync & 2)
254 *status |= FE_HAS_CARRIER;
255
256 if (sync & 2) /* XXX FIXME! */
257 *status |= FE_HAS_VITERBI;
258
259 if (sync & 4)
260 *status |= FE_HAS_SYNC;
261
262 if (sync & 8)
263 *status |= FE_HAS_LOCK;
264
265 return 0;
266}
267
268static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
269{
270 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
271
272 u32 _ber = ves1820_readreg(state, 0x14) |
273 (ves1820_readreg(state, 0x15) << 8) |
274 ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
275 *ber = 10 * _ber;
276
277 return 0;
278}
279
280static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
281{
282 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
283
284 u8 gain = ves1820_readreg(state, 0x17);
285 *strength = (gain << 8) | gain;
286
287 return 0;
288}
289
290static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
291{
292 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
293
294 u8 quality = ~ves1820_readreg(state, 0x18);
295 *snr = (quality << 8) | quality;
296
297 return 0;
298}
299
300static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
301{
302 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
303
304 *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
305 if (*ucblocks == 0x7f)
306 *ucblocks = 0xffffffff;
307
308 /* reset uncorrected block counter */
309 ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
310 ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
311
312 return 0;
313}
314
315static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
316{
317 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
318 int sync;
319 s8 afc = 0;
320
321 sync = ves1820_readreg(state, 0x11);
322 afc = ves1820_readreg(state, 0x19);
323 if (verbose) {
324 /* AFC only valid when carrier has been recovered */
325 printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
326 "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10);
327 }
328
329 if (!state->config->invert) {
330 p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
331 } else {
332 p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
333 }
334
335 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
336
337 p->u.qam.fec_inner = FEC_NONE;
338
339 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
340 if (sync & 2)
341 p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10;
342
343 return 0;
344}
345
346static int ves1820_sleep(struct dvb_frontend* fe)
347{
348 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
349
350 ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */
351 ves1820_writereg(state, 0x00, 0x80); /* standby */
352
353 return 0;
354}
355
356static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358
359 fesettings->min_delay_ms = 200;
360 fesettings->step_size = 0;
361 fesettings->max_drift = 0;
362 return 0;
363}
364
365static void ves1820_release(struct dvb_frontend* fe)
366{
367 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
368 kfree(state);
369}
370
371static struct dvb_frontend_ops ves1820_ops;
372
373struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
374 struct i2c_adapter* i2c,
375 u8 pwm)
376{
377 struct ves1820_state* state = NULL;
378
379 /* allocate memory for the internal state */
380 state = (struct ves1820_state*) kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
381 if (state == NULL)
382 goto error;
383
384 /* setup the state */
385 memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
386 state->reg0 = ves1820_inittab[0];
387 state->config = config;
388 state->i2c = i2c;
389 state->pwm = pwm;
390
391 /* check if the demod is there */
392 if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
393 goto error;
394
395 if (verbose)
396 printk("ves1820: pwm=0x%02x\n", state->pwm);
397
398 state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
399 state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
400
401 /* create dvb_frontend */
402 state->frontend.ops = &state->ops;
403 state->frontend.demodulator_priv = state;
404 return &state->frontend;
405
406error:
407 kfree(state);
408 return NULL;
409}
410
411static struct dvb_frontend_ops ves1820_ops = {
412
413 .info = {
414 .name = "VLSI VES1820 DVB-C",
415 .type = FE_QAM,
416 .frequency_stepsize = 62500,
417 .frequency_min = 51000000,
418 .frequency_max = 858000000,
419 .caps = FE_CAN_QAM_16 |
420 FE_CAN_QAM_32 |
421 FE_CAN_QAM_64 |
422 FE_CAN_QAM_128 |
423 FE_CAN_QAM_256 |
424 FE_CAN_FEC_AUTO
425 },
426
427 .release = ves1820_release,
428
429 .init = ves1820_init,
430 .sleep = ves1820_sleep,
431
432 .set_frontend = ves1820_set_parameters,
433 .get_frontend = ves1820_get_frontend,
434 .get_tune_settings = ves1820_get_tune_settings,
435
436 .read_status = ves1820_read_status,
437 .read_ber = ves1820_read_ber,
438 .read_signal_strength = ves1820_read_signal_strength,
439 .read_snr = ves1820_read_snr,
440 .read_ucblocks = ves1820_read_ucblocks,
441};
442
443module_param(verbose, int, 0644);
444MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
445
446MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
447MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
new file mode 100644
index 000000000000..355f130b1be8
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -0,0 +1,51 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
21#ifndef VES1820_H
22#define VES1820_H
23
24#include <linux/dvb/frontend.h>
25
26#define VES1820_SELAGC_PWM 0
27#define VES1820_SELAGC_SIGNAMPERR 1
28
29struct ves1820_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* value of XIN to use */
35 u32 xin;
36
37 /* does inversion need inverted? */
38 u8 invert:1;
39
40 /* SELAGC control */
41 u8 selagc:1;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
49 struct i2c_adapter* i2c, u8 pwm);
50
51#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
new file mode 100644
index 000000000000..edcad283aa86
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -0,0 +1,545 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32
33#include "dvb_frontend.h"
34#include "ves1x93.h"
35
36
37struct ves1x93_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct ves1x93_config* config;
42 struct dvb_frontend frontend;
43
44 /* previous uncorrected block counter */
45 fe_spectral_inversion_t inversion;
46 u8 *init_1x93_tab;
47 u8 *init_1x93_wtab;
48 u8 tab_size;
49 u8 demod_type;
50};
51
52static int debug = 0;
53#define dprintk if (debug) printk
54
55#define DEMOD_VES1893 0
56#define DEMOD_VES1993 1
57
58static u8 init_1893_tab [] = {
59 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
60 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
61 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
63 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
66};
67
68static u8 init_1993_tab [] = {
69 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
70 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
71 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
73 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
76 0x00, 0x00, 0x0e, 0x80, 0x00
77};
78
79static u8 init_1893_wtab[] =
80{
81 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
82 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
83 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
84 1,1,1,0,1,1
85};
86
87static u8 init_1993_wtab[] =
88{
89 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
90 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
91 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
92 1,1,1,0,1,1,1,1, 1,1,1,1,1
93};
94
95static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
96{
97 u8 buf [] = { 0x00, reg, data };
98 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
99 int err;
100
101 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
102 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
103 return -EREMOTEIO;
104 }
105
106 return 0;
107}
108
109static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
110{
111 int ret;
112 u8 b0 [] = { 0x00, reg };
113 u8 b1 [] = { 0 };
114 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
115 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
116
117 ret = i2c_transfer (state->i2c, msg, 2);
118
119 if (ret != 2) return ret;
120
121 return b1[0];
122}
123
124static int ves1x93_clr_bit (struct ves1x93_state* state)
125{
126 msleep(10);
127 ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
128 ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
129 msleep(50);
130 return 0;
131}
132
133static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
134{
135 u8 val;
136
137 /*
138 * inversion on/off are interchanged because i and q seem to
139 * be swapped on the hardware
140 */
141
142 switch (inversion) {
143 case INVERSION_OFF:
144 val = 0xc0;
145 break;
146 case INVERSION_ON:
147 val = 0x80;
148 break;
149 case INVERSION_AUTO:
150 val = 0x00;
151 break;
152 default:
153 return -EINVAL;
154 }
155
156 return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
157}
158
159static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
160{
161 if (fec == FEC_AUTO)
162 return ves1x93_writereg (state, 0x0d, 0x08);
163 else if (fec < FEC_1_2 || fec > FEC_8_9)
164 return -EINVAL;
165 else
166 return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
167}
168
169static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
170{
171 return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
172}
173
174static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
175{
176 u32 BDR;
177 u32 ratio;
178 u8 ADCONF, FCONF, FNR, AGCR;
179 u32 BDRI;
180 u32 tmp;
181 u32 FIN;
182
183 dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);
184
185 if (srate > state->config->xin/2)
186 srate = state->config->xin/2;
187
188 if (srate < 500000)
189 srate = 500000;
190
191#define MUL (1UL<<26)
192
193 FIN = (state->config->xin + 6000) >> 4;
194
195 tmp = srate << 6;
196 ratio = tmp / FIN;
197
198 tmp = (tmp % FIN) << 8;
199 ratio = (ratio << 8) + tmp / FIN;
200
201 tmp = (tmp % FIN) << 8;
202 ratio = (ratio << 8) + tmp / FIN;
203
204 FNR = 0xff;
205
206 if (ratio < MUL/3) FNR = 0;
207 if (ratio < (MUL*11)/50) FNR = 1;
208 if (ratio < MUL/6) FNR = 2;
209 if (ratio < MUL/9) FNR = 3;
210 if (ratio < MUL/12) FNR = 4;
211 if (ratio < (MUL*11)/200) FNR = 5;
212 if (ratio < MUL/24) FNR = 6;
213 if (ratio < (MUL*27)/1000) FNR = 7;
214 if (ratio < MUL/48) FNR = 8;
215 if (ratio < (MUL*137)/10000) FNR = 9;
216
217 if (FNR == 0xff) {
218 ADCONF = 0x89;
219 FCONF = 0x80;
220 FNR = 0;
221 } else {
222 ADCONF = 0x81;
223 FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
224 /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
225 }
226
227 BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
228 BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
229
230 dprintk("FNR= %d\n", FNR);
231 dprintk("ratio= %08x\n", (unsigned int) ratio);
232 dprintk("BDR= %08x\n", (unsigned int) BDR);
233 dprintk("BDRI= %02x\n", (unsigned int) BDRI);
234
235 if (BDRI > 0xff)
236 BDRI = 0xff;
237
238 ves1x93_writereg (state, 0x06, 0xff & BDR);
239 ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
240 ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
241
242 ves1x93_writereg (state, 0x09, BDRI);
243 ves1x93_writereg (state, 0x20, ADCONF);
244 ves1x93_writereg (state, 0x21, FCONF);
245
246 AGCR = state->init_1x93_tab[0x05];
247 if (state->config->invert_pwm)
248 AGCR |= 0x20;
249
250 if (srate < 6000000)
251 AGCR |= 0x80;
252 else
253 AGCR &= ~0x80;
254
255 ves1x93_writereg (state, 0x05, AGCR);
256
257 /* ves1993 hates this, will lose lock */
258 if (state->demod_type != DEMOD_VES1993)
259 ves1x93_clr_bit (state);
260
261 return 0;
262}
263
264static int ves1x93_init (struct dvb_frontend* fe)
265{
266 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
267 int i;
268 int val;
269
270 dprintk("%s: init chip\n", __FUNCTION__);
271
272 for (i = 0; i < state->tab_size; i++) {
273 if (state->init_1x93_wtab[i]) {
274 val = state->init_1x93_tab[i];
275
276 if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
277 ves1x93_writereg (state, i, val);
278 }
279 }
280
281 if (state->config->pll_init) {
282 ves1x93_writereg(state, 0x00, 0x11);
283 state->config->pll_init(fe);
284 ves1x93_writereg(state, 0x00, 0x01);
285 }
286
287 return 0;
288}
289
290static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
291{
292 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
293
294 switch (voltage) {
295 case SEC_VOLTAGE_13:
296 return ves1x93_writereg (state, 0x1f, 0x20);
297 case SEC_VOLTAGE_18:
298 return ves1x93_writereg (state, 0x1f, 0x30);
299 case SEC_VOLTAGE_OFF:
300 return ves1x93_writereg (state, 0x1f, 0x00);
301 default:
302 return -EINVAL;
303 }
304}
305
306static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
307{
308 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
309
310 u8 sync = ves1x93_readreg (state, 0x0e);
311
312 /*
313 * The ves1893 sometimes returns sync values that make no sense,
314 * because, e.g., the SIGNAL bit is 0, while some of the higher
315 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
316 * Tests showed that the the VITERBI and SYNC bits are returned
317 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
318 * If such a case occurs, we read the value again, until we get a
319 * valid value.
320 */
321 int maxtry = 10; /* just for safety - let's not get stuck here */
322 while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
323 msleep(10);
324 sync = ves1x93_readreg (state, 0x0e);
325 }
326
327 *status = 0;
328
329 if (sync & 1)
330 *status |= FE_HAS_SIGNAL;
331
332 if (sync & 2)
333 *status |= FE_HAS_CARRIER;
334
335 if (sync & 4)
336 *status |= FE_HAS_VITERBI;
337
338 if (sync & 8)
339 *status |= FE_HAS_SYNC;
340
341 if ((sync & 0x1f) == 0x1f)
342 *status |= FE_HAS_LOCK;
343
344 return 0;
345}
346
347static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
348{
349 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
350
351 *ber = ves1x93_readreg (state, 0x15);
352 *ber |= (ves1x93_readreg (state, 0x16) << 8);
353 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
354 *ber *= 10;
355
356 return 0;
357}
358
359static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
360{
361 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
362
363 u8 signal = ~ves1x93_readreg (state, 0x0b);
364 *strength = (signal << 8) | signal;
365
366 return 0;
367}
368
369static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
370{
371 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
372
373 u8 _snr = ~ves1x93_readreg (state, 0x1c);
374 *snr = (_snr << 8) | _snr;
375
376 return 0;
377}
378
379static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
380{
381 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
382
383 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
384
385 if (*ucblocks == 0x7f)
386 *ucblocks = 0xffffffff; /* counter overflow... */
387
388 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */
389 ves1x93_writereg (state, 0x18, 0x80); /* dto. */
390
391 return 0;
392}
393
394static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
395{
396 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
397
398 ves1x93_writereg(state, 0x00, 0x11);
399 state->config->pll_set(fe, p);
400 ves1x93_writereg(state, 0x00, 0x01);
401 ves1x93_set_inversion (state, p->inversion);
402 ves1x93_set_fec (state, p->u.qpsk.fec_inner);
403 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
404 state->inversion = p->inversion;
405
406 return 0;
407}
408
409static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
410{
411 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
412 int afc;
413
414 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
415 afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
416
417 p->frequency -= afc;
418
419 /*
420 * inversion indicator is only valid
421 * if auto inversion was used
422 */
423 if (state->inversion == INVERSION_AUTO)
424 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
425 INVERSION_OFF : INVERSION_ON;
426 p->u.qpsk.fec_inner = ves1x93_get_fec (state);
427 /* XXX FIXME: timing offset !! */
428
429 return 0;
430}
431
432static int ves1x93_sleep(struct dvb_frontend* fe)
433{
434 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
435
436 return ves1x93_writereg (state, 0x00, 0x08);
437}
438
439static void ves1x93_release(struct dvb_frontend* fe)
440{
441 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
442 kfree(state);
443}
444
445static struct dvb_frontend_ops ves1x93_ops;
446
447struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
448 struct i2c_adapter* i2c)
449{
450 struct ves1x93_state* state = NULL;
451 u8 identity;
452
453 /* allocate memory for the internal state */
454 state = (struct ves1x93_state*) kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
455 if (state == NULL) goto error;
456
457 /* setup the state */
458 state->config = config;
459 state->i2c = i2c;
460 memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
461 state->inversion = INVERSION_OFF;
462
463 /* check if the demod is there + identify it */
464 identity = ves1x93_readreg(state, 0x1e);
465 switch (identity) {
466 case 0xdc: /* VES1893A rev1 */
467 printk("ves1x93: Detected ves1893a rev1\n");
468 state->demod_type = DEMOD_VES1893;
469 state->init_1x93_tab = init_1893_tab;
470 state->init_1x93_wtab = init_1893_wtab;
471 state->tab_size = sizeof(init_1893_tab);
472 break;
473
474 case 0xdd: /* VES1893A rev2 */
475 printk("ves1x93: Detected ves1893a rev2\n");
476 state->demod_type = DEMOD_VES1893;
477 state->init_1x93_tab = init_1893_tab;
478 state->init_1x93_wtab = init_1893_wtab;
479 state->tab_size = sizeof(init_1893_tab);
480 break;
481
482 case 0xde: /* VES1993 */
483 printk("ves1x93: Detected ves1993\n");
484 state->demod_type = DEMOD_VES1993;
485 state->init_1x93_tab = init_1993_tab;
486 state->init_1x93_wtab = init_1993_wtab;
487 state->tab_size = sizeof(init_1993_tab);
488 break;
489
490 default:
491 goto error;
492 }
493
494 /* create dvb_frontend */
495 state->frontend.ops = &state->ops;
496 state->frontend.demodulator_priv = state;
497 return &state->frontend;
498
499error:
500 kfree(state);
501 return NULL;
502}
503
504static struct dvb_frontend_ops ves1x93_ops = {
505
506 .info = {
507 .name = "VLSI VES1x93 DVB-S",
508 .type = FE_QPSK,
509 .frequency_min = 950000,
510 .frequency_max = 2150000,
511 .frequency_stepsize = 125, /* kHz for QPSK frontends */
512 .frequency_tolerance = 29500,
513 .symbol_rate_min = 1000000,
514 .symbol_rate_max = 45000000,
515 /* .symbol_rate_tolerance = ???,*/
516 .caps = FE_CAN_INVERSION_AUTO |
517 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
518 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
519 FE_CAN_QPSK
520 },
521
522 .release = ves1x93_release,
523
524 .init = ves1x93_init,
525 .sleep = ves1x93_sleep,
526
527 .set_frontend = ves1x93_set_frontend,
528 .get_frontend = ves1x93_get_frontend,
529
530 .read_status = ves1x93_read_status,
531 .read_ber = ves1x93_read_ber,
532 .read_signal_strength = ves1x93_read_signal_strength,
533 .read_snr = ves1x93_read_snr,
534 .read_ucblocks = ves1x93_read_ucblocks,
535
536 .set_voltage = ves1x93_set_voltage,
537};
538
539module_param(debug, int, 0644);
540
541MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
542MODULE_AUTHOR("Ralph Metzler");
543MODULE_LICENSE("GPL");
544
545EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
new file mode 100644
index 000000000000..1627e37c57a4
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -0,0 +1,50 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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
26#ifndef VES1X93_H
27#define VES1X93_H
28
29#include <linux/dvb/frontend.h>
30
31struct ves1x93_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* value of XIN to use */
37 u32 xin;
38
39 /* should PWM be inverted? */
40 u8 invert_pwm:1;
41
42 /* PLL maintenance */
43 int (*pll_init)(struct dvb_frontend* fe);
44 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
45};
46
47extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
48 struct i2c_adapter* i2c);
49
50#endif // VES1X93_H
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
new file mode 100644
index 000000000000..7ffa2c7315b3
--- /dev/null
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -0,0 +1,134 @@
1config DVB_AV7110
2 tristate "AV7110 cards"
3 depends on DVB_CORE && PCI
4 select FW_LOADER
5 select VIDEO_DEV
6 select VIDEO_SAA7146_VV
7 select DVB_VES1820
8 select DVB_VES1X93
9 select DVB_STV0299
10 select DVB_TDA8083
11 select DVB_SP8870
12 select DVB_STV0297
13 select DVB_L64781
14 help
15 Support for SAA7146 and AV7110 based DVB cards as produced
16 by Fujitsu-Siemens, Technotrend, Hauppauge and others.
17
18 This driver only supports the fullfeatured cards with
19 onboard MPEG2 decoder.
20
21 This driver needs an external firmware. Please use the script
22 "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
23 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
24
25 Say Y if you own such a card and want to use it.
26
27config DVB_AV7110_FIRMWARE
28 bool "Compile AV7110 firmware into the driver"
29 depends on DVB_AV7110 && !STANDALONE
30 default y if DVB_AV7110=y
31 help
32 The AV7110 firmware is normally loaded by the firmware hotplug manager.
33 If you want to compile the firmware into the driver you need to say
34 Y here and provide the correct path of the firmware. You need this
35 option if you want to compile the whole driver statically into the
36 kernel.
37
38 All other people say N.
39
40config DVB_AV7110_FIRMWARE_FILE
41 string "Full pathname of av7110 firmware file"
42 depends on DVB_AV7110_FIRMWARE
43 default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw"
44
45config DVB_AV7110_OSD
46 bool "AV7110 OSD support"
47 depends on DVB_AV7110
48 default y if DVB_AV7110=y || DVB_AV7110=m
49 help
50 The AV7110 firmware provides some code to generate an OnScreenDisplay
51 on the video output. This is kind of nonstandard and not guaranteed to
52 be maintained.
53
54 Anyway, some popular DVB software like VDR uses this OSD to render
55 its menus, so say Y if you want to use this software.
56
57 All other people say N.
58
59config DVB_BUDGET
60 tristate "Budget cards"
61 depends on DVB_CORE && PCI
62 select VIDEO_SAA7146
63 select DVB_STV0299
64 select DVB_VES1X93
65 select DVB_VES1820
66 select DVB_L64781
67 select DVB_TDA8083
68 select DVB_TDA10021
69 help
70 Support for simple SAA7146 based DVB cards
71 (so called Budget- or Nova-PCI cards) without onboard
72 MPEG2 decoder.
73
74 Say Y if you own such a card and want to use it.
75
76 To compile this driver as a module, choose M here: the
77 module will be called budget.
78
79config DVB_BUDGET_CI
80 tristate "Budget cards with onboard CI connector"
81 depends on DVB_CORE && PCI
82 select VIDEO_SAA7146
83 select DVB_STV0299
84 select DVB_TDA1004X
85 help
86 Support for simple SAA7146 based DVB cards
87 (so called Budget- or Nova-PCI cards) without onboard
88 MPEG2 decoder, but with onboard Common Interface connector.
89
90 Note: The Common Interface is not yet supported by this driver
91 due to lack of information from the vendor.
92
93 Say Y if you own such a card and want to use it.
94
95 To compile this driver as a module, choose M here: the
96 module will be called budget-ci.
97
98config DVB_BUDGET_AV
99 tristate "Budget cards with analog video inputs"
100 depends on DVB_CORE && PCI
101 select VIDEO_DEV
102 select VIDEO_SAA7146_VV
103 select DVB_STV0299
104 help
105 Support for simple SAA7146 based DVB cards
106 (so called Budget- or Nova-PCI cards) without onboard
107 MPEG2 decoder, but with one or more analog video inputs.
108
109 Say Y if you own such a card and want to use it.
110
111 To compile this driver as a module, choose M here: the
112 module will be called budget-av.
113
114config DVB_BUDGET_PATCH
115 tristate "AV7110 cards with Budget Patch"
116 depends on DVB_CORE && DVB_BUDGET
117 select DVB_AV7110
118 select DVB_STV0299
119 select DVB_VES1X93
120 select DVB_TDA8083
121 help
122 Support for Budget Patch (full TS) modification on
123 SAA7146+AV7110 based cards (DVB-S cards). This
124 driver doesn't use onboard MPEG2 decoder. The
125 card is driven in Budget-only mode. Card is
126 required to have loaded firmware to tune properly.
127 Firmware can be loaded by insertion and removal of
128 standard AV7110 driver prior to loading this
129 driver.
130
131 Say Y if you own such a card and want to use it.
132
133 To compile this driver as a module, choose M here: the
134 module will be called budget-patch.
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
new file mode 100644
index 000000000000..825ab1c38a4f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for the kernel SAA7146 FULL TS DVB device driver
3# and the AV7110 DVB device driver
4#
5
6dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o
7
8obj-$(CONFIG_DVB_BUDGET) += budget-core.o budget.o ttpci-eeprom.o
9obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o budget-av.o ttpci-eeprom.o
10obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o
11obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o
12obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
13
14EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
15
16hostprogs-y := fdump
17
18ifdef CONFIG_DVB_AV7110_FIRMWARE
19$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h
20
21$(obj)/av7110_firm.h:
22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
23endif
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
new file mode 100644
index 000000000000..922c205a2652
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -0,0 +1,2739 @@
1/*
2 * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
3 * av7110.c: initialization and demux stuff
4 *
5 * Copyright (C) 1999-2002 Ralph Metzler
6 * & Marcus Metzler for convergence integrated media GmbH
7 *
8 * originally based on code by:
9 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 *
28 *
29 * the project's page is at http://www.linuxtv.org/dvb/
30 */
31
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/kmod.h>
36#include <linux/delay.h>
37#include <linux/fs.h>
38#include <linux/timer.h>
39#include <linux/poll.h>
40#include <linux/byteorder/swabb.h>
41#include <linux/smp_lock.h>
42
43#include <linux/kernel.h>
44#include <linux/moduleparam.h>
45#include <linux/sched.h>
46#include <linux/types.h>
47#include <linux/fcntl.h>
48#include <linux/interrupt.h>
49#include <linux/string.h>
50#include <linux/pci.h>
51#include <linux/vmalloc.h>
52#include <linux/firmware.h>
53#include <linux/crc32.h>
54#include <linux/i2c.h>
55
56#include <asm/system.h>
57#include <asm/semaphore.h>
58
59#include <linux/dvb/frontend.h>
60
61#include "dvb_frontend.h"
62
63#include "ttpci-eeprom.h"
64#include "av7110.h"
65#include "av7110_hw.h"
66#include "av7110_av.h"
67#include "av7110_ca.h"
68#include "av7110_ipack.h"
69
70#define TS_WIDTH 376
71#define TS_HEIGHT 512
72#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
73#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
74
75
76int av7110_debug;
77
78static int vidmode = CVBS_RGB_OUT;
79static int pids_off;
80static int adac = DVB_ADAC_TI;
81static int hw_sections;
82static int rgb_on;
83static int volume = 255;
84static int budgetpatch = 0;
85
86module_param_named(debug, av7110_debug, int, 0644);
87MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
88module_param(vidmode, int, 0444);
89MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
90module_param(pids_off, int, 0444);
91MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
92module_param(adac, int, 0444);
93MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
94module_param(hw_sections, int, 0444);
95MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
96module_param(rgb_on, int, 0444);
97MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
98 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
99module_param(volume, int, 0444);
100MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
101module_param(budgetpatch, int, 0444);
102MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
103
104static void restart_feeds(struct av7110 *av7110);
105
106static int av7110_num = 0;
107
108#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
109{\
110 if (fe_func != NULL) { \
111 av7110_copy = fe_func; \
112 fe_func = av7110_func; \
113 } \
114}
115
116
117static void init_av7110_av(struct av7110 *av7110)
118{
119 struct saa7146_dev *dev = av7110->dev;
120
121 /* set internal volume control to maximum */
122 av7110->adac_type = DVB_ADAC_TI;
123 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
124
125 av7710_set_video_mode(av7110, vidmode);
126
127 /* handle different card types */
128 /* remaining inits according to card and frontend type */
129 av7110->analog_tuner_flags = 0;
130 av7110->current_input = 0;
131 if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
132 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
133 av7110->dvb_adapter->num);
134 av7110->adac_type = DVB_ADAC_CRYSTAL;
135 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
136 i2c_writereg(av7110, 0x20, 0x02, 0x49);
137 i2c_writereg(av7110, 0x20, 0x03, 0x00);
138 i2c_writereg(av7110, 0x20, 0x04, 0x00);
139
140 /**
141 * some special handling for the Siemens DVB-C cards...
142 */
143 } else if (0 == av7110_init_analog_module(av7110)) {
144 /* done. */
145 }
146 else if (dev->pci->subsystem_vendor == 0x110a) {
147 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
148 av7110->dvb_adapter->num);
149 av7110->adac_type = DVB_ADAC_NONE;
150 }
151 else {
152 av7110->adac_type = adac;
153 printk("dvb-ttpci: adac type set to %d @ card %d\n",
154 av7110->dvb_adapter->num, av7110->adac_type);
155 }
156
157 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
158 // switch DVB SCART on
159 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
160 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
161 if (rgb_on &&
162 (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
163 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
164 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
165 }
166 }
167
168 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
169 av7110_setup_irc_config(av7110, 0);
170}
171
172static void recover_arm(struct av7110 *av7110)
173{
174 dprintk(4, "%p\n",av7110);
175
176 av7110_bootarm(av7110);
177 msleep(100);
178 restart_feeds(av7110);
179 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
180}
181
182static void arm_error(struct av7110 *av7110)
183{
184 dprintk(4, "%p\n",av7110);
185
186 av7110->arm_errors++;
187 av7110->arm_ready = 0;
188 recover_arm(av7110);
189}
190
191static void av7110_arm_sync(struct av7110 *av7110)
192{
193 av7110->arm_rmmod = 1;
194 wake_up_interruptible(&av7110->arm_wait);
195
196 while (av7110->arm_thread)
197 msleep(1);
198}
199
200static int arm_thread(void *data)
201{
202 struct av7110 *av7110 = data;
203 u16 newloops = 0;
204 int timeout;
205
206 dprintk(4, "%p\n",av7110);
207
208 lock_kernel();
209 daemonize("arm_mon");
210 sigfillset(&current->blocked);
211 unlock_kernel();
212
213 av7110->arm_thread = current;
214
215 for (;;) {
216 timeout = wait_event_interruptible_timeout(av7110->arm_wait,
217 av7110->arm_rmmod, 5 * HZ);
218 if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
219 /* got signal or told to quit*/
220 break;
221 }
222
223 if (!av7110->arm_ready)
224 continue;
225
226 if (down_interruptible(&av7110->dcomlock))
227 break;
228
229 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
230 up(&av7110->dcomlock);
231
232 if (newloops == av7110->arm_loops) {
233 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
234 av7110->dvb_adapter->num);
235
236 arm_error(av7110);
237 av7710_set_video_mode(av7110, vidmode);
238
239 init_av7110_av(av7110);
240
241 if (down_interruptible(&av7110->dcomlock))
242 break;
243
244 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
245 up(&av7110->dcomlock);
246 }
247 av7110->arm_loops = newloops;
248 }
249
250 av7110->arm_thread = NULL;
251 return 0;
252}
253
254
255/**
256 * Hack! we save the last av7110 ptr. This should be ok, since
257 * you rarely will use more then one IR control.
258 *
259 * If we want to support multiple controls we would have to do much more...
260 */
261void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
262{
263 static struct av7110 *last;
264
265 dprintk(4, "%p\n", av7110);
266
267 if (!av7110)
268 av7110 = last;
269 else
270 last = av7110;
271
272 if (av7110) {
273 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
274 av7110->ir_config = ir_config;
275 }
276}
277
278static void (*irc_handler)(u32);
279
280void av7110_register_irc_handler(void (*func)(u32))
281{
282 dprintk(4, "registering %p\n", func);
283 irc_handler = func;
284}
285
286void av7110_unregister_irc_handler(void (*func)(u32))
287{
288 dprintk(4, "unregistering %p\n", func);
289 irc_handler = NULL;
290}
291
292static void run_handlers(unsigned long ircom)
293{
294 if (irc_handler != NULL)
295 (*irc_handler)((u32) ircom);
296}
297
298static DECLARE_TASKLET(irtask, run_handlers, 0);
299
300static void IR_handle(struct av7110 *av7110, u32 ircom)
301{
302 dprintk(4, "ircommand = %08x\n", ircom);
303 irtask.data = (unsigned long) ircom;
304 tasklet_schedule(&irtask);
305}
306
307/****************************************************************************
308 * IRQ handling
309 ****************************************************************************/
310
311static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
312 u8 *buffer2, size_t buffer2_len,
313 struct dvb_demux_filter *dvbdmxfilter,
314 enum dmx_success success,
315 struct av7110 *av7110)
316{
317 if (!dvbdmxfilter->feed->demux->dmx.frontend)
318 return 0;
319 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
320 return 0;
321
322 switch (dvbdmxfilter->type) {
323 case DMX_TYPE_SEC:
324 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
325 return 0;
326 if (dvbdmxfilter->doneq) {
327 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
328 int i;
329 u8 xor, neq = 0;
330
331 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
332 xor = filter->filter_value[i] ^ buffer1[i];
333 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
334 }
335 if (!neq)
336 return 0;
337 }
338 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
339 buffer2, buffer2_len,
340 &dvbdmxfilter->filter,
341 DMX_OK);
342 case DMX_TYPE_TS:
343 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
344 return 0;
345 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
346 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
347 buffer2, buffer2_len,
348 &dvbdmxfilter->feed->feed.ts,
349 DMX_OK);
350 else
351 av7110_p2t_write(buffer1, buffer1_len,
352 dvbdmxfilter->feed->pid,
353 &av7110->p2t_filter[dvbdmxfilter->index]);
354 default:
355 return 0;
356 }
357}
358
359
360//#define DEBUG_TIMING
361static inline void print_time(char *s)
362{
363#ifdef DEBUG_TIMING
364 struct timeval tv;
365 do_gettimeofday(&tv);
366 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
367#endif
368}
369
370#define DEBI_READ 0
371#define DEBI_WRITE 1
372static inline void start_debi_dma(struct av7110 *av7110, int dir,
373 unsigned long addr, unsigned int len)
374{
375 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
376 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
377 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
378 return;
379 }
380
381 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
382 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
383 if (len < 5)
384 len = 5; /* we want a real DEBI DMA */
385 if (dir == DEBI_WRITE)
386 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
387 else
388 irdebi(av7110, DEBISWAB, addr, 0, len);
389}
390
391static void debiirq(unsigned long data)
392{
393 struct av7110 *av7110 = (struct av7110 *) data;
394 int type = av7110->debitype;
395 int handle = (type >> 8) & 0x1f;
396 unsigned int xfer = 0;
397
398 print_time("debi");
399 dprintk(4, "type 0x%04x\n", type);
400
401 if (type == -1) {
402 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
403 jiffies, saa7146_read(av7110->dev, PSR),
404 saa7146_read(av7110->dev, SSR));
405 goto debi_done;
406 }
407 av7110->debitype = -1;
408
409 switch (type & 0xff) {
410
411 case DATA_TS_RECORD:
412 dvb_dmx_swfilter_packets(&av7110->demux,
413 (const u8 *) av7110->debi_virt,
414 av7110->debilen / 188);
415 xfer = RX_BUFF;
416 break;
417
418 case DATA_PES_RECORD:
419 if (av7110->demux.recording)
420 av7110_record_cb(&av7110->p2t[handle],
421 (u8 *) av7110->debi_virt,
422 av7110->debilen);
423 xfer = RX_BUFF;
424 break;
425
426 case DATA_IPMPE:
427 case DATA_FSECTION:
428 case DATA_PIPING:
429 if (av7110->handle2filter[handle])
430 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
431 av7110->debilen, NULL, 0,
432 av7110->handle2filter[handle],
433 DMX_OK, av7110);
434 xfer = RX_BUFF;
435 break;
436
437 case DATA_CI_GET:
438 {
439 u8 *data = av7110->debi_virt;
440
441 if ((data[0] < 2) && data[2] == 0xff) {
442 int flags = 0;
443 if (data[5] > 0)
444 flags |= CA_CI_MODULE_PRESENT;
445 if (data[5] > 5)
446 flags |= CA_CI_MODULE_READY;
447 av7110->ci_slot[data[0]].flags = flags;
448 } else
449 ci_get_data(&av7110->ci_rbuffer,
450 av7110->debi_virt,
451 av7110->debilen);
452 xfer = RX_BUFF;
453 break;
454 }
455
456 case DATA_COMMON_INTERFACE:
457 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
458#if 0
459 {
460 int i;
461
462 printk("av7110%d: ", av7110->num);
463 printk("%02x ", *(u8 *)av7110->debi_virt);
464 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
465 for (i = 2; i < av7110->debilen; i++)
466 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
467 for (i = 2; i < av7110->debilen; i++)
468 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
469
470 printk("\n");
471 }
472#endif
473 xfer = RX_BUFF;
474 break;
475
476 case DATA_DEBUG_MESSAGE:
477 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
478 printk("%s\n", (s8 *) av7110->debi_virt);
479 xfer = RX_BUFF;
480 break;
481
482 case DATA_CI_PUT:
483 dprintk(4, "debi DATA_CI_PUT\n");
484 case DATA_MPEG_PLAY:
485 dprintk(4, "debi DATA_MPEG_PLAY\n");
486 case DATA_BMP_LOAD:
487 dprintk(4, "debi DATA_BMP_LOAD\n");
488 xfer = TX_BUFF;
489 break;
490 default:
491 break;
492 }
493debi_done:
494 spin_lock(&av7110->debilock);
495 if (xfer)
496 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
497 ARM_ClearMailBox(av7110);
498 spin_unlock(&av7110->debilock);
499}
500
501/* irq from av7110 firmware writing the mailbox register in the DPRAM */
502static void gpioirq(unsigned long data)
503{
504 struct av7110 *av7110 = (struct av7110 *) data;
505 u32 rxbuf, txbuf;
506 int len;
507
508 if (av7110->debitype != -1)
509 /* we shouldn't get any irq while a debi xfer is running */
510 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
511 jiffies, saa7146_read(av7110->dev, PSR),
512 saa7146_read(av7110->dev, SSR));
513
514 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
515 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
516 BUG(); /* maybe we should try resetting the debi? */
517 }
518
519 spin_lock(&av7110->debilock);
520 ARM_ClearIrq(av7110);
521
522 /* see what the av7110 wants */
523 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
524 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
525 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
526 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
527 len = (av7110->debilen + 3) & ~3;
528
529 print_time("gpio");
530 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
531
532 switch (av7110->debitype & 0xff) {
533
534 case DATA_TS_PLAY:
535 case DATA_PES_PLAY:
536 break;
537
538 case DATA_MPEG_VIDEO_EVENT:
539 {
540 u32 h_ar;
541 struct video_event event;
542
543 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
544 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
545
546 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
547 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
548
549 av7110->video_size.h = h_ar & 0xfff;
550 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
551 av7110->video_size.w,
552 av7110->video_size.h,
553 av7110->video_size.aspect_ratio);
554
555 event.type = VIDEO_EVENT_SIZE_CHANGED;
556 event.u.size.w = av7110->video_size.w;
557 event.u.size.h = av7110->video_size.h;
558 switch ((h_ar >> 12) & 0xf)
559 {
560 case 3:
561 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
562 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
563 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
564 break;
565 case 4:
566 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
567 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
568 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
569 break;
570 default:
571 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
572 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
573 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
574 }
575 dvb_video_add_event(av7110, &event);
576 break;
577 }
578
579 case DATA_CI_PUT:
580 {
581 int avail;
582 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
583
584 avail = dvb_ringbuffer_avail(cibuf);
585 if (avail <= 2) {
586 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
587 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
588 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
589 break;
590 }
591 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
592 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
593 if (avail < len + 2) {
594 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
595 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
596 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
597 break;
598 }
599 DVB_RINGBUFFER_SKIP(cibuf, 2);
600
601 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
602
603 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
604 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
605 dprintk(8, "DMA: CI\n");
606 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
607 spin_unlock(&av7110->debilock);
608 wake_up(&cibuf->queue);
609 return;
610 }
611
612 case DATA_MPEG_PLAY:
613 if (!av7110->playing) {
614 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
615 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
616 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
617 break;
618 }
619 len = 0;
620 if (av7110->debitype & 0x100) {
621 spin_lock(&av7110->aout.lock);
622 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
623 spin_unlock(&av7110->aout.lock);
624 }
625 if (len <= 0 && (av7110->debitype & 0x200)
626 &&av7110->videostate.play_state != VIDEO_FREEZED) {
627 spin_lock(&av7110->avout.lock);
628 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
629 spin_unlock(&av7110->avout.lock);
630 }
631 if (len <= 0) {
632 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
633 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
634 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
635 break;
636 }
637 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
638 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
639 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
640 dprintk(8, "DMA: MPEG_PLAY\n");
641 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
642 spin_unlock(&av7110->debilock);
643 return;
644
645 case DATA_BMP_LOAD:
646 len = av7110->debilen;
647 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
648 if (!len) {
649 av7110->bmp_state = BMP_LOADED;
650 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
651 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
652 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
653 wake_up(&av7110->bmpq);
654 dprintk(8, "gpio DATA_BMP_LOAD done\n");
655 break;
656 }
657 if (len > av7110->bmplen)
658 len = av7110->bmplen;
659 if (len > 2 * 1024)
660 len = 2 * 1024;
661 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
662 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
663 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
664 av7110->bmpp += len;
665 av7110->bmplen -= len;
666 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
667 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
668 spin_unlock(&av7110->debilock);
669 return;
670
671 case DATA_CI_GET:
672 case DATA_COMMON_INTERFACE:
673 case DATA_FSECTION:
674 case DATA_IPMPE:
675 case DATA_PIPING:
676 if (!len || len > 4 * 1024) {
677 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
678 break;
679 }
680 /* fall through */
681
682 case DATA_TS_RECORD:
683 case DATA_PES_RECORD:
684 dprintk(8, "DMA: TS_REC etc.\n");
685 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
686 spin_unlock(&av7110->debilock);
687 return;
688
689 case DATA_DEBUG_MESSAGE:
690 if (!len || len > 0xff) {
691 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
692 break;
693 }
694 start_debi_dma(av7110, DEBI_READ, Reserved, len);
695 spin_unlock(&av7110->debilock);
696 return;
697
698 case DATA_IRCOMMAND:
699 IR_handle(av7110,
700 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
701 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
702 break;
703
704 default:
705 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
706 av7110->debitype, av7110->debilen);
707 break;
708 }
709 av7110->debitype = -1;
710 ARM_ClearMailBox(av7110);
711 spin_unlock(&av7110->debilock);
712}
713
714
715#ifdef CONFIG_DVB_AV7110_OSD
716static int dvb_osd_ioctl(struct inode *inode, struct file *file,
717 unsigned int cmd, void *parg)
718{
719 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
720 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
721
722 dprintk(4, "%p\n", av7110);
723
724 if (cmd == OSD_SEND_CMD)
725 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
726 if (cmd == OSD_GET_CAPABILITY)
727 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
728
729 return -EINVAL;
730}
731
732
733static struct file_operations dvb_osd_fops = {
734 .owner = THIS_MODULE,
735 .ioctl = dvb_generic_ioctl,
736 .open = dvb_generic_open,
737 .release = dvb_generic_release,
738};
739
740static struct dvb_device dvbdev_osd = {
741 .priv = NULL,
742 .users = 1,
743 .writers = 1,
744 .fops = &dvb_osd_fops,
745 .kernel_ioctl = dvb_osd_ioctl,
746};
747#endif /* CONFIG_DVB_AV7110_OSD */
748
749
750static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
751 u16 subpid, u16 pcrpid)
752{
753 dprintk(4, "%p\n", av7110);
754
755 if (vpid == 0x1fff || apid == 0x1fff ||
756 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
757 vpid = apid = ttpid = subpid = pcrpid = 0;
758 av7110->pids[DMX_PES_VIDEO] = 0;
759 av7110->pids[DMX_PES_AUDIO] = 0;
760 av7110->pids[DMX_PES_TELETEXT] = 0;
761 av7110->pids[DMX_PES_PCR] = 0;
762 }
763
764 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5,
765 pcrpid, vpid, apid, ttpid, subpid);
766}
767
768void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
769 u16 subpid, u16 pcrpid)
770{
771 dprintk(4, "%p\n", av7110);
772
773 if (down_interruptible(&av7110->pid_mutex))
774 return;
775
776 if (!(vpid & 0x8000))
777 av7110->pids[DMX_PES_VIDEO] = vpid;
778 if (!(apid & 0x8000))
779 av7110->pids[DMX_PES_AUDIO] = apid;
780 if (!(ttpid & 0x8000))
781 av7110->pids[DMX_PES_TELETEXT] = ttpid;
782 if (!(pcrpid & 0x8000))
783 av7110->pids[DMX_PES_PCR] = pcrpid;
784
785 av7110->pids[DMX_PES_SUBTITLE] = 0;
786
787 if (av7110->fe_synced) {
788 pcrpid = av7110->pids[DMX_PES_PCR];
789 SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
790 }
791
792 up(&av7110->pid_mutex);
793}
794
795
796/******************************************************************************
797 * hardware filter functions
798 ******************************************************************************/
799
800static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
801{
802 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
803 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
804 u16 buf[20];
805 int ret, i;
806 u16 handle;
807// u16 mode = 0x0320;
808 u16 mode = 0xb96a;
809
810 dprintk(4, "%p\n", av7110);
811
812 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
813 if (hw_sections) {
814 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
815 dvbdmxfilter->maskandmode[0];
816 for (i = 3; i < 18; i++)
817 buf[i + 4 - 2] =
818 (dvbdmxfilter->filter.filter_value[i] << 8) |
819 dvbdmxfilter->maskandmode[i];
820 mode = 4;
821 }
822 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
823 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
824 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
825 }
826
827 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
828 buf[1] = 16;
829 buf[2] = dvbdmxfeed->pid;
830 buf[3] = mode;
831
832 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
833 if (ret != 0 || handle >= 32) {
834 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
835 "ret %x handle %04x\n",
836 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
837 ret, handle);
838 dvbdmxfilter->hw_handle = 0xffff;
839 return -1;
840 }
841
842 av7110->handle2filter[handle] = dvbdmxfilter;
843 dvbdmxfilter->hw_handle = handle;
844
845 return ret;
846}
847
848static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
849{
850 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
851 u16 buf[3];
852 u16 answ[2];
853 int ret;
854 u16 handle;
855
856 dprintk(4, "%p\n", av7110);
857
858 handle = dvbdmxfilter->hw_handle;
859 if (handle >= 32) {
860 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
861 __FUNCTION__, handle, dvbdmxfilter->type);
862 return 0;
863 }
864
865 av7110->handle2filter[handle] = NULL;
866
867 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
868 buf[1] = 1;
869 buf[2] = handle;
870 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
871 if (ret != 0 || answ[1] != handle) {
872 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
873 "resp %04x %04x pid %d\n",
874 __FUNCTION__, buf[0], buf[1], buf[2], ret,
875 answ[0], answ[1], dvbdmxfilter->feed->pid);
876 ret = -1;
877 }
878 return ret;
879}
880
881
882static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
883{
884 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
885 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
886 u16 *pid = dvbdmx->pids, npids[5];
887 int i;
888
889 dprintk(4, "%p\n", av7110);
890
891 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
892 i = dvbdmxfeed->pes_type;
893 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
894 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
895 npids[i] = 0;
896 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
897 StartHWFilter(dvbdmxfeed->filter);
898 return;
899 }
900 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
901 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
902
903 if (dvbdmxfeed->pes_type < 2 && npids[0])
904 if (av7110->fe_synced)
905 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
906
907 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
908 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
909 av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
910 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
911 av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
912 }
913}
914
915static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
916{
917 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
918 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
919 u16 *pid = dvbdmx->pids, npids[5];
920 int i;
921
922 dprintk(4, "%p\n", av7110);
923
924 if (dvbdmxfeed->pes_type <= 1) {
925 av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
926 if (!av7110->rec_mode)
927 dvbdmx->recording = 0;
928 if (!av7110->playing)
929 dvbdmx->playing = 0;
930 }
931 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
932 i = dvbdmxfeed->pes_type;
933 switch (i) {
934 case 2: //teletext
935 if (dvbdmxfeed->ts_type & TS_PACKET)
936 StopHWFilter(dvbdmxfeed->filter);
937 npids[2] = 0;
938 break;
939 case 0:
940 case 1:
941 case 4:
942 if (!pids_off)
943 return;
944 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
945 break;
946 }
947 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
948}
949
950static int av7110_start_feed(struct dvb_demux_feed *feed)
951{
952 struct dvb_demux *demux = feed->demux;
953 struct av7110 *av7110 = demux->priv;
954
955 dprintk(4, "%p\n", av7110);
956
957 if (!demux->dmx.frontend)
958 return -EINVAL;
959
960 if (feed->pid > 0x1fff)
961 return -EINVAL;
962
963 if (feed->type == DMX_TYPE_TS) {
964 if ((feed->ts_type & TS_DECODER) &&
965 (feed->pes_type < DMX_TS_PES_OTHER)) {
966 switch (demux->dmx.frontend->source) {
967 case DMX_MEMORY_FE:
968 if (feed->ts_type & TS_DECODER)
969 if (feed->pes_type < 2 &&
970 !(demux->pids[0] & 0x8000) &&
971 !(demux->pids[1] & 0x8000)) {
972 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
973 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
974 av7110_av_start_play(av7110,RP_AV);
975 demux->playing = 1;
976 }
977 break;
978 default:
979 dvb_feed_start_pid(feed);
980 break;
981 }
982 } else if ((feed->ts_type & TS_PACKET) &&
983 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
984 StartHWFilter(feed->filter);
985 }
986 }
987
988 if (feed->type == DMX_TYPE_SEC) {
989 int i;
990
991 for (i = 0; i < demux->filternum; i++) {
992 if (demux->filter[i].state != DMX_STATE_READY)
993 continue;
994 if (demux->filter[i].type != DMX_TYPE_SEC)
995 continue;
996 if (demux->filter[i].filter.parent != &feed->feed.sec)
997 continue;
998 demux->filter[i].state = DMX_STATE_GO;
999 if (demux->dmx.frontend->source != DMX_MEMORY_FE)
1000 StartHWFilter(&demux->filter[i]);
1001 }
1002 }
1003
1004 return 0;
1005}
1006
1007
1008static int av7110_stop_feed(struct dvb_demux_feed *feed)
1009{
1010 struct dvb_demux *demux = feed->demux;
1011 struct av7110 *av7110 = demux->priv;
1012
1013 dprintk(4, "%p\n", av7110);
1014
1015 if (feed->type == DMX_TYPE_TS) {
1016 if (feed->ts_type & TS_DECODER) {
1017 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1018 !demux->pesfilter[feed->pes_type])
1019 return -EINVAL;
1020 demux->pids[feed->pes_type] |= 0x8000;
1021 demux->pesfilter[feed->pes_type] = NULL;
1022 }
1023 if (feed->ts_type & TS_DECODER &&
1024 feed->pes_type < DMX_TS_PES_OTHER) {
1025 dvb_feed_stop_pid(feed);
1026 } else
1027 if ((feed->ts_type & TS_PACKET) &&
1028 (demux->dmx.frontend->source != DMX_MEMORY_FE))
1029 StopHWFilter(feed->filter);
1030 }
1031
1032 if (feed->type == DMX_TYPE_SEC) {
1033 int i;
1034
1035 for (i = 0; i<demux->filternum; i++)
1036 if (demux->filter[i].state == DMX_STATE_GO &&
1037 demux->filter[i].filter.parent == &feed->feed.sec) {
1038 demux->filter[i].state = DMX_STATE_READY;
1039 if (demux->dmx.frontend->source != DMX_MEMORY_FE)
1040 StopHWFilter(&demux->filter[i]);
1041 }
1042 }
1043
1044 return 0;
1045}
1046
1047
1048static void restart_feeds(struct av7110 *av7110)
1049{
1050 struct dvb_demux *dvbdmx = &av7110->demux;
1051 struct dvb_demux_feed *feed;
1052 int mode;
1053 int i;
1054
1055 dprintk(4, "%p\n", av7110);
1056
1057 mode = av7110->playing;
1058 av7110->playing = 0;
1059 av7110->rec_mode = 0;
1060
1061 for (i = 0; i < dvbdmx->filternum; i++) {
1062 feed = &dvbdmx->feed[i];
1063 if (feed->state == DMX_STATE_GO)
1064 av7110_start_feed(feed);
1065 }
1066
1067 if (mode)
1068 av7110_av_start_play(av7110, mode);
1069}
1070
1071static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1072 uint64_t *stc, unsigned int *base)
1073{
1074 int ret;
1075 u16 fwstc[4];
1076 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1077 struct dvb_demux *dvbdemux;
1078 struct av7110 *av7110;
1079
1080 /* pointer casting paranoia... */
1081 if (!demux)
1082 BUG();
1083 dvbdemux = (struct dvb_demux *) demux->priv;
1084 if (!dvbdemux)
1085 BUG();
1086 av7110 = (struct av7110 *) dvbdemux->priv;
1087
1088 dprintk(4, "%p\n", av7110);
1089
1090 if (num != 0)
1091 return -EINVAL;
1092
1093 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1094 if (ret) {
1095 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
1096 return -EIO;
1097 }
1098 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1099 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1100
1101 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1102 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1103 *base = 1;
1104
1105 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1106
1107 return 0;
1108}
1109
1110
1111/******************************************************************************
1112 * SEC device file operations
1113 ******************************************************************************/
1114
1115
1116static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1117{
1118 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1119
1120 switch (tone) {
1121 case SEC_TONE_ON:
1122 Set22K(av7110, 1);
1123 break;
1124
1125 case SEC_TONE_OFF:
1126 Set22K(av7110, 0);
1127 break;
1128
1129 default:
1130 return -EINVAL;
1131 }
1132
1133 return 0;
1134}
1135
1136static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1137 struct dvb_diseqc_master_cmd* cmd)
1138{
1139 struct av7110* av7110 = fe->dvb->priv;
1140
1141 av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
1142
1143 return 0;
1144}
1145
1146static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1147 fe_sec_mini_cmd_t minicmd)
1148{
1149 struct av7110* av7110 = fe->dvb->priv;
1150
1151 av7110_diseqc_send(av7110, 0, NULL, minicmd);
1152
1153 return 0;
1154}
1155
1156/* simplified code from budget-core.c */
1157static int stop_ts_capture(struct av7110 *budget)
1158{
1159 dprintk(2, "budget: %p\n", budget);
1160
1161 if (--budget->feeding1)
1162 return budget->feeding1;
1163 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1164 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1165 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1166 return 0;
1167}
1168
1169static int start_ts_capture(struct av7110 *budget)
1170{
1171 dprintk(2, "budget: %p\n", budget);
1172
1173 if (budget->feeding1)
1174 return ++budget->feeding1;
1175 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1176 budget->tsf = 0xff;
1177 budget->ttbp = 0;
1178 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1179 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1180 return ++budget->feeding1;
1181}
1182
1183static int budget_start_feed(struct dvb_demux_feed *feed)
1184{
1185 struct dvb_demux *demux = feed->demux;
1186 struct av7110 *budget = (struct av7110 *) demux->priv;
1187 int status;
1188
1189 dprintk(2, "av7110: %p\n", budget);
1190
1191 spin_lock(&budget->feedlock1);
1192 feed->pusi_seen = 0; /* have a clean section start */
1193 status = start_ts_capture(budget);
1194 spin_unlock(&budget->feedlock1);
1195 return status;
1196}
1197
1198static int budget_stop_feed(struct dvb_demux_feed *feed)
1199{
1200 struct dvb_demux *demux = feed->demux;
1201 struct av7110 *budget = (struct av7110 *) demux->priv;
1202 int status;
1203
1204 dprintk(2, "budget: %p\n", budget);
1205
1206 spin_lock(&budget->feedlock1);
1207 status = stop_ts_capture(budget);
1208 spin_unlock(&budget->feedlock1);
1209 return status;
1210}
1211
1212static void vpeirq(unsigned long data)
1213{
1214 struct av7110 *budget = (struct av7110 *) data;
1215 u8 *mem = (u8 *) (budget->grabbing);
1216 u32 olddma = budget->ttbp;
1217 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1218
1219 if (!budgetpatch) {
1220 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1221 " check saa7146 IER register\n");
1222 BUG();
1223 }
1224 /* nearest lower position divisible by 188 */
1225 newdma -= newdma % 188;
1226
1227 if (newdma >= TS_BUFLEN)
1228 return;
1229
1230 budget->ttbp = newdma;
1231
1232 if (!budget->feeding1 || (newdma == olddma))
1233 return;
1234
1235#if 0
1236 /* track rps1 activity */
1237 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1238 mem[olddma],
1239 saa7146_read(budget->dev, EC1R) & 0x3fff);
1240#endif
1241
1242 if (newdma > olddma)
1243 /* no wraparound, dump olddma..newdma */
1244 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1245 else {
1246 /* wraparound, dump olddma..buflen and 0..newdma */
1247 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1248 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1249 }
1250}
1251
1252static int av7110_register(struct av7110 *av7110)
1253{
1254 int ret, i;
1255 struct dvb_demux *dvbdemux = &av7110->demux;
1256 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1257
1258 dprintk(4, "%p\n", av7110);
1259
1260 if (av7110->registered)
1261 return -1;
1262
1263 av7110->registered = 1;
1264
1265 dvbdemux->priv = (void *) av7110;
1266
1267 for (i = 0; i < 32; i++)
1268 av7110->handle2filter[i] = NULL;
1269
1270 dvbdemux->filternum = 32;
1271 dvbdemux->feednum = 32;
1272 dvbdemux->start_feed = av7110_start_feed;
1273 dvbdemux->stop_feed = av7110_stop_feed;
1274 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1275 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1276 DMX_MEMORY_BASED_FILTERING);
1277
1278 dvb_dmx_init(&av7110->demux);
1279 av7110->demux.dmx.get_stc = dvb_get_stc;
1280
1281 av7110->dmxdev.filternum = 32;
1282 av7110->dmxdev.demux = &dvbdemux->dmx;
1283 av7110->dmxdev.capabilities = 0;
1284
1285 dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
1286
1287 av7110->hw_frontend.source = DMX_FRONTEND_0;
1288
1289 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1290
1291 if (ret < 0)
1292 return ret;
1293
1294 av7110->mem_frontend.source = DMX_MEMORY_FE;
1295
1296 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1297
1298 if (ret < 0)
1299 return ret;
1300
1301 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1302 &av7110->hw_frontend);
1303 if (ret < 0)
1304 return ret;
1305
1306 av7110_av_register(av7110);
1307 av7110_ca_register(av7110);
1308
1309#ifdef CONFIG_DVB_AV7110_OSD
1310 dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev,
1311 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1312#endif
1313
1314 dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
1315
1316 if (budgetpatch) {
1317 /* initialize software demux1 without its own frontend
1318 * demux1 hardware is connected to frontend0 of demux0
1319 */
1320 dvbdemux1->priv = (void *) av7110;
1321
1322 dvbdemux1->filternum = 256;
1323 dvbdemux1->feednum = 256;
1324 dvbdemux1->start_feed = budget_start_feed;
1325 dvbdemux1->stop_feed = budget_stop_feed;
1326 dvbdemux1->write_to_decoder = NULL;
1327
1328 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1329 DMX_MEMORY_BASED_FILTERING);
1330
1331 dvb_dmx_init(&av7110->demux1);
1332
1333 av7110->dmxdev1.filternum = 256;
1334 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1335 av7110->dmxdev1.capabilities = 0;
1336
1337 dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter);
1338
1339 dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
1340 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1341 }
1342 return 0;
1343}
1344
1345
1346static void dvb_unregister(struct av7110 *av7110)
1347{
1348 struct dvb_demux *dvbdemux = &av7110->demux;
1349 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1350
1351 dprintk(4, "%p\n", av7110);
1352
1353 if (!av7110->registered)
1354 return;
1355
1356 if (budgetpatch) {
1357 dvb_net_release(&av7110->dvb_net1);
1358 dvbdemux->dmx.close(&dvbdemux1->dmx);
1359 dvb_dmxdev_release(&av7110->dmxdev1);
1360 dvb_dmx_release(&av7110->demux1);
1361 }
1362
1363 dvb_net_release(&av7110->dvb_net);
1364
1365 dvbdemux->dmx.close(&dvbdemux->dmx);
1366 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1367 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1368
1369 dvb_dmxdev_release(&av7110->dmxdev);
1370 dvb_dmx_release(&av7110->demux);
1371
1372 if (av7110->fe != NULL)
1373 dvb_unregister_frontend(av7110->fe);
1374 dvb_unregister_device(av7110->osd_dev);
1375 av7110_av_unregister(av7110);
1376 av7110_ca_unregister(av7110);
1377}
1378
1379
1380/****************************************************************************
1381 * I2C client commands
1382 ****************************************************************************/
1383
1384int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1385{
1386 u8 msg[2] = { reg, val };
1387 struct i2c_msg msgs;
1388
1389 msgs.flags = 0;
1390 msgs.addr = id / 2;
1391 msgs.len = 2;
1392 msgs.buf = msg;
1393 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1394}
1395
1396#if 0
1397u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1398{
1399 u8 mm1[] = {0x00};
1400 u8 mm2[] = {0x00};
1401 struct i2c_msg msgs[2];
1402
1403 msgs[0].flags = 0;
1404 msgs[1].flags = I2C_M_RD;
1405 msgs[0].addr = msgs[1].addr = id / 2;
1406 mm1[0] = reg;
1407 msgs[0].len = 1; msgs[1].len = 1;
1408 msgs[0].buf = mm1; msgs[1].buf = mm2;
1409 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1410
1411 return mm2[0];
1412}
1413#endif
1414
1415/****************************************************************************
1416 * INITIALIZATION
1417 ****************************************************************************/
1418
1419
1420static int check_firmware(struct av7110* av7110)
1421{
1422 u32 crc = 0, len = 0;
1423 unsigned char *ptr;
1424
1425 /* check for firmware magic */
1426 ptr = av7110->bin_fw;
1427 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1428 ptr[2] != 'F' || ptr[3] != 'W') {
1429 printk("dvb-ttpci: this is not an av7110 firmware\n");
1430 return -EINVAL;
1431 }
1432 ptr += 4;
1433
1434 /* check dpram file */
1435 crc = ntohl(*(u32*) ptr);
1436 ptr += 4;
1437 len = ntohl(*(u32*) ptr);
1438 ptr += 4;
1439 if (len >= 512) {
1440 printk("dvb-ttpci: dpram file is way to big.\n");
1441 return -EINVAL;
1442 }
1443 if (crc != crc32_le(0, ptr, len)) {
1444 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1445 return -EINVAL;
1446 }
1447 av7110->bin_dpram = ptr;
1448 av7110->size_dpram = len;
1449 ptr += len;
1450
1451 /* check root file */
1452 crc = ntohl(*(u32*) ptr);
1453 ptr += 4;
1454 len = ntohl(*(u32*) ptr);
1455 ptr += 4;
1456
1457 if (len <= 200000 || len >= 300000 ||
1458 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1459 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1460 return -EINVAL;
1461 }
1462 if( crc != crc32_le(0, ptr, len)) {
1463 printk("dvb-ttpci: crc32 of root file does not match.\n");
1464 return -EINVAL;
1465 }
1466 av7110->bin_root = ptr;
1467 av7110->size_root = len;
1468 return 0;
1469}
1470
1471#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1472#include "av7110_firm.h"
1473static void put_firmware(struct av7110* av7110)
1474{
1475 av7110->bin_fw = NULL;
1476}
1477
1478static inline int get_firmware(struct av7110* av7110)
1479{
1480 av7110->bin_fw = dvb_ttpci_fw;
1481 av7110->size_fw = sizeof(dvb_ttpci_fw);
1482 return check_firmware(av7110);
1483}
1484#else
1485static void put_firmware(struct av7110* av7110)
1486{
1487 vfree(av7110->bin_fw);
1488}
1489
1490static int get_firmware(struct av7110* av7110)
1491{
1492 int ret;
1493 const struct firmware *fw;
1494
1495 /* request the av7110 firmware, this will block until someone uploads it */
1496 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1497 if (ret) {
1498 if (ret == -ENOENT) {
1499 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1500 " file not found: dvb-ttpci-01.fw\n");
1501 printk(KERN_ERR "dvb-ttpci: usually this should be in"
1502 " /usr/lib/hotplug/firmware\n");
1503 printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
1504 " http://www.linuxtv.org/download/dvb/firmware/\n");
1505 } else
1506 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1507 " (error %i)\n", ret);
1508 return -EINVAL;
1509 }
1510
1511 if (fw->size <= 200000) {
1512 printk("dvb-ttpci: this firmware is way too small.\n");
1513 release_firmware(fw);
1514 return -EINVAL;
1515 }
1516
1517 /* check if the firmware is available */
1518 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1519 if (NULL == av7110->bin_fw) {
1520 dprintk(1, "out of memory\n");
1521 release_firmware(fw);
1522 return -ENOMEM;
1523 }
1524
1525 memcpy(av7110->bin_fw, fw->data, fw->size);
1526 av7110->size_fw = fw->size;
1527 if ((ret = check_firmware(av7110)))
1528 vfree(av7110->bin_fw);
1529
1530 release_firmware(fw);
1531 return ret;
1532}
1533#endif
1534
1535
1536static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1537{
1538 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1539 u8 pwr = 0;
1540 u8 buf[4];
1541 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1542 u32 div = (params->frequency + 479500) / 125;
1543
1544 if (params->frequency > 2000000) pwr = 3;
1545 else if (params->frequency > 1800000) pwr = 2;
1546 else if (params->frequency > 1600000) pwr = 1;
1547 else if (params->frequency > 1200000) pwr = 0;
1548 else if (params->frequency >= 1100000) pwr = 1;
1549 else pwr = 2;
1550
1551 buf[0] = (div >> 8) & 0x7f;
1552 buf[1] = div & 0xff;
1553 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1554 buf[3] = (pwr << 6) | 0x30;
1555
1556 // NOTE: since we're using a prescaler of 2, we set the
1557 // divisor frequency to 62.5kHz and divide by 125 above
1558
1559 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1560 return -EIO;
1561 return 0;
1562}
1563
1564static struct ves1x93_config alps_bsrv2_config = {
1565 .demod_address = 0x08,
1566 .xin = 90100000UL,
1567 .invert_pwm = 0,
1568 .pll_set = alps_bsrv2_pll_set,
1569};
1570
1571
1572static u8 alps_bsru6_inittab[] = {
1573 0x01, 0x15,
1574 0x02, 0x30,
1575 0x03, 0x00,
1576 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1577 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1578 0x06, 0x40, /* DAC not used, set to high impendance mode */
1579 0x07, 0x00, /* DAC LSB */
1580 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1581 0x09, 0x00, /* FIFO */
1582 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1583 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1584 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1585 0x10, 0x3f, // AGC2 0x3d
1586 0x11, 0x84,
1587 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1588 0x15, 0xc9, // lock detector threshold
1589 0x16, 0x00,
1590 0x17, 0x00,
1591 0x18, 0x00,
1592 0x19, 0x00,
1593 0x1a, 0x00,
1594 0x1f, 0x50,
1595 0x20, 0x00,
1596 0x21, 0x00,
1597 0x22, 0x00,
1598 0x23, 0x00,
1599 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1600 0x29, 0x1e, // 1/2 threshold
1601 0x2a, 0x14, // 2/3 threshold
1602 0x2b, 0x0f, // 3/4 threshold
1603 0x2c, 0x09, // 5/6 threshold
1604 0x2d, 0x05, // 7/8 threshold
1605 0x2e, 0x01,
1606 0x31, 0x1f, // test all FECs
1607 0x32, 0x19, // viterbi and synchro search
1608 0x33, 0xfc, // rs control
1609 0x34, 0x93, // error control
1610 0x0f, 0x52,
1611 0xff, 0xff
1612};
1613
1614static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
1615{
1616 u8 aclk = 0;
1617 u8 bclk = 0;
1618
1619 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
1620 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
1621 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
1622 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
1623 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
1624 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
1625
1626 stv0299_writereg(fe, 0x13, aclk);
1627 stv0299_writereg(fe, 0x14, bclk);
1628 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1629 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1630 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
1631
1632 return 0;
1633}
1634
1635static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1636{
1637 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1638 int ret;
1639 u8 data[4];
1640 u32 div;
1641 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1642
1643 if ((params->frequency < 950000) || (params->frequency > 2150000))
1644 return -EINVAL;
1645
1646 div = (params->frequency + (125 - 1)) / 125; // round correctly
1647 data[0] = (div >> 8) & 0x7f;
1648 data[1] = div & 0xff;
1649 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1650 data[3] = 0xC4;
1651
1652 if (params->frequency > 1530000) data[3] = 0xc0;
1653
1654 ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
1655 if (ret != 1)
1656 return -EIO;
1657 return 0;
1658}
1659
1660static struct stv0299_config alps_bsru6_config = {
1661
1662 .demod_address = 0x68,
1663 .inittab = alps_bsru6_inittab,
1664 .mclk = 88000000UL,
1665 .invert = 1,
1666 .enhanced_tuning = 0,
1667 .skip_reinit = 0,
1668 .lock_output = STV0229_LOCKOUTPUT_1,
1669 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1670 .min_delay_ms = 100,
1671 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1672 .pll_set = alps_bsru6_pll_set,
1673};
1674
1675
1676
1677static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1678{
1679 struct av7110* av7110 = fe->dvb->priv;
1680 u32 div;
1681 u8 data[4];
1682 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1683
1684 div = (params->frequency + 35937500 + 31250) / 62500;
1685
1686 data[0] = (div >> 8) & 0x7f;
1687 data[1] = div & 0xff;
1688 data[2] = 0x85 | ((div >> 10) & 0x60);
1689 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1690
1691 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1692 return -EIO;
1693 return 0;
1694}
1695
1696static struct ves1820_config alps_tdbe2_config = {
1697 .demod_address = 0x09,
1698 .xin = 57840000UL,
1699 .invert = 1,
1700 .selagc = VES1820_SELAGC_SIGNAMPERR,
1701 .pll_set = alps_tdbe2_pll_set,
1702};
1703
1704
1705
1706
1707static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1708 struct dvb_frontend_parameters* params)
1709{
1710 struct av7110* av7110 = fe->dvb->priv;
1711 u32 div;
1712 u8 data[4];
1713 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1714
1715 div = params->frequency / 125;
1716 data[0] = (div >> 8) & 0x7f;
1717 data[1] = div & 0xff;
1718 data[2] = 0x8e;
1719 data[3] = 0x00;
1720
1721 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1722 return -EIO;
1723 return 0;
1724}
1725
1726static struct tda8083_config grundig_29504_451_config = {
1727 .demod_address = 0x68,
1728 .pll_set = grundig_29504_451_pll_set,
1729};
1730
1731
1732
1733static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1734 struct dvb_frontend_parameters* params)
1735{
1736 struct av7110* av7110 = fe->dvb->priv;
1737 u32 div;
1738 u32 f = params->frequency;
1739 u8 data[4];
1740 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1741
1742 div = (f + 36125000 + 31250) / 62500;
1743
1744 data[0] = (div >> 8) & 0x7f;
1745 data[1] = div & 0xff;
1746 data[2] = 0x8e;
1747 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1748
1749 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1750 return -EIO;
1751 return 0;
1752}
1753
1754static struct ves1820_config philips_cd1516_config = {
1755 .demod_address = 0x09,
1756 .xin = 57840000UL,
1757 .invert = 1,
1758 .selagc = VES1820_SELAGC_SIGNAMPERR,
1759 .pll_set = philips_cd1516_pll_set,
1760};
1761
1762
1763
1764static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1765{
1766 struct av7110* av7110 = fe->dvb->priv;
1767 u32 div, pwr;
1768 u8 data[4];
1769 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1770
1771 div = (params->frequency + 36200000) / 166666;
1772
1773 if (params->frequency <= 782000000)
1774 pwr = 1;
1775 else
1776 pwr = 2;
1777
1778 data[0] = (div >> 8) & 0x7f;
1779 data[1] = div & 0xff;
1780 data[2] = 0x85;
1781 data[3] = pwr << 6;
1782
1783 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1784 return -EIO;
1785 return 0;
1786}
1787
1788static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1789{
1790 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1791
1792 return request_firmware(fw, name, &av7110->dev->pci->dev);
1793}
1794
1795static struct sp8870_config alps_tdlb7_config = {
1796
1797 .demod_address = 0x71,
1798 .pll_set = alps_tdlb7_pll_set,
1799 .request_firmware = alps_tdlb7_request_firmware,
1800};
1801
1802
1803
1804static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1805{
1806 struct av7110* av7110 = fe->dvb->priv;
1807 u32 div;
1808 u8 data[4];
1809 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1810 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1811 int i;
1812
1813 div = (params->frequency + 36150000 + 31250) / 62500;
1814
1815 data[0] = (div >> 8) & 0x7f;
1816 data[1] = div & 0xff;
1817 data[2] = 0xce;
1818
1819 if (params->frequency < 45000000)
1820 return -EINVAL;
1821 else if (params->frequency < 137000000)
1822 data[3] = 0x01;
1823 else if (params->frequency < 403000000)
1824 data[3] = 0x02;
1825 else if (params->frequency < 860000000)
1826 data[3] = 0x04;
1827 else
1828 return -EINVAL;
1829
1830 stv0297_enable_plli2c(fe);
1831 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1832 printk("nexusca: pll transfer failed!\n");
1833 return -EIO;
1834 }
1835
1836 // wait for PLL lock
1837 for(i = 0; i < 20; i++) {
1838
1839 stv0297_enable_plli2c(fe);
1840 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1841 if (data[0] & 0x40) break;
1842 msleep(10);
1843 }
1844
1845 return 0;
1846}
1847
1848static struct stv0297_config nexusca_stv0297_config = {
1849
1850 .demod_address = 0x1C,
1851 .invert = 1,
1852 .pll_set = nexusca_stv0297_pll_set,
1853};
1854
1855
1856
1857static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1858{
1859 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1860 u32 div;
1861 u8 cfg, cpump, band_select;
1862 u8 data[4];
1863 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1864
1865 div = (36125000 + params->frequency) / 166666;
1866
1867 cfg = 0x88;
1868
1869 if (params->frequency < 175000000) cpump = 2;
1870 else if (params->frequency < 390000000) cpump = 1;
1871 else if (params->frequency < 470000000) cpump = 2;
1872 else if (params->frequency < 750000000) cpump = 1;
1873 else cpump = 3;
1874
1875 if (params->frequency < 175000000) band_select = 0x0e;
1876 else if (params->frequency < 470000000) band_select = 0x05;
1877 else band_select = 0x03;
1878
1879 data[0] = (div >> 8) & 0x7f;
1880 data[1] = div & 0xff;
1881 data[2] = ((div >> 10) & 0x60) | cfg;
1882 data[3] = (cpump << 6) | band_select;
1883
1884 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1885 return 0;
1886}
1887
1888static struct l64781_config grundig_29504_401_config = {
1889 .demod_address = 0x55,
1890 .pll_set = grundig_29504_401_pll_set,
1891};
1892
1893
1894
1895static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
1896{
1897 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1898
1899 av7110->fe_status = status;
1900
1901 if (av7110->fe_synced == synced)
1902 return;
1903
1904 av7110->fe_synced = synced;
1905
1906 if (av7110->playing)
1907 return;
1908
1909 if (down_interruptible(&av7110->pid_mutex))
1910 return;
1911
1912 if (av7110->fe_synced) {
1913 SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
1914 av7110->pids[DMX_PES_AUDIO],
1915 av7110->pids[DMX_PES_TELETEXT], 0,
1916 av7110->pids[DMX_PES_PCR]);
1917 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
1918 } else {
1919 SetPIDs(av7110, 0, 0, 0, 0, 0);
1920 av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
1921 av7110_wait_msgstate(av7110, GPMQBusy);
1922 }
1923
1924 up(&av7110->pid_mutex);
1925}
1926
1927static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1928{
1929 struct av7110* av7110 = fe->dvb->priv;
1930 av7110_fe_lock_fix(av7110, 0);
1931 return av7110->fe_set_frontend(fe, params);
1932}
1933
1934static int av7110_fe_init(struct dvb_frontend* fe)
1935{
1936 struct av7110* av7110 = fe->dvb->priv;
1937
1938 av7110_fe_lock_fix(av7110, 0);
1939 return av7110->fe_init(fe);
1940}
1941
1942static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
1943{
1944 struct av7110* av7110 = fe->dvb->priv;
1945 int ret;
1946
1947 /* call the real implementation */
1948 ret = av7110->fe_read_status(fe, status);
1949 if (ret)
1950 return ret;
1951
1952 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) {
1953 av7110_fe_lock_fix(av7110, *status);
1954 }
1955
1956 return 0;
1957}
1958
1959static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
1960{
1961 struct av7110* av7110 = fe->dvb->priv;
1962
1963 av7110_fe_lock_fix(av7110, 0);
1964 return av7110->fe_diseqc_reset_overload(fe);
1965}
1966
1967static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
1968 struct dvb_diseqc_master_cmd* cmd)
1969{
1970 struct av7110* av7110 = fe->dvb->priv;
1971
1972 av7110_fe_lock_fix(av7110, 0);
1973 return av7110->fe_diseqc_send_master_cmd(fe, cmd);
1974}
1975
1976static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
1977{
1978 struct av7110* av7110 = fe->dvb->priv;
1979
1980 av7110_fe_lock_fix(av7110, 0);
1981 return av7110->fe_diseqc_send_burst(fe, minicmd);
1982}
1983
1984static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1985{
1986 struct av7110* av7110 = fe->dvb->priv;
1987
1988 av7110_fe_lock_fix(av7110, 0);
1989 return av7110->fe_set_tone(fe, tone);
1990}
1991
1992static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
1993{
1994 struct av7110* av7110 = fe->dvb->priv;
1995
1996 av7110_fe_lock_fix(av7110, 0);
1997 return av7110->fe_set_voltage(fe, voltage);
1998}
1999
2000static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
2001{
2002 struct av7110* av7110 = fe->dvb->priv;
2003
2004 av7110_fe_lock_fix(av7110, 0);
2005 return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2006}
2007
2008static u8 read_pwm(struct av7110* av7110)
2009{
2010 u8 b = 0xff;
2011 u8 pwm;
2012 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2013 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2014
2015 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
2016 pwm = 0x48;
2017
2018 return pwm;
2019}
2020
2021static int frontend_init(struct av7110 *av7110)
2022{
2023 int ret;
2024
2025 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2026 switch(av7110->dev->pci->subsystem_device) {
2027 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2028 av7110->fe = ves1820_attach(&philips_cd1516_config,
2029 &av7110->i2c_adap, read_pwm(av7110));
2030 break;
2031 }
2032
2033 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2034 switch(av7110->dev->pci->subsystem_device) {
2035 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2036 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2037 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2038
2039 // try the ALPS BSRV2 first of all
2040 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2041 if (av7110->fe) {
2042 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2043 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2044 av7110->fe->ops->set_tone = av7110_set_tone;
2045 break;
2046 }
2047
2048 // try the ALPS BSRU6 now
2049 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2050 if (av7110->fe) {
2051 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2052 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2053 av7110->fe->ops->set_tone = av7110_set_tone;
2054 break;
2055 }
2056
2057 // Try the grundig 29504-451
2058 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2059 if (av7110->fe) {
2060 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2061 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2062 av7110->fe->ops->set_tone = av7110_set_tone;
2063 break;
2064 }
2065
2066 /* Try DVB-C cards */
2067 switch(av7110->dev->pci->subsystem_device) {
2068 case 0x0000:
2069 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2070 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2071 read_pwm(av7110));
2072 break;
2073 case 0x0003:
2074 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2075 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2076 read_pwm(av7110));
2077 break;
2078 }
2079 break;
2080
2081 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2082
2083 // ALPS TDLB7
2084 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
2085 break;
2086
2087 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2088
2089 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
2090 break;
2091
2092 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2093 /* Grundig 29504-451 */
2094 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2095 if (av7110->fe) {
2096 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2097 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2098 av7110->fe->ops->set_tone = av7110_set_tone;
2099 }
2100 break;
2101
2102 case 0x0008: // Hauppauge/TT DVB-T
2103
2104 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2105 break;
2106
2107 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2108
2109 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
2110 if (av7110->fe) {
2111 /* set TDA9819 into DVB mode */
2112 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2113 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2114
2115 /* tuner on this needs a slower i2c bus speed */
2116 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2117 break;
2118 }
2119 }
2120 }
2121
2122 if (!av7110->fe) {
2123 /* FIXME: propagate the failure code from the lower layers */
2124 ret = -ENOMEM;
2125 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2126 av7110->dev->pci->vendor,
2127 av7110->dev->pci->device,
2128 av7110->dev->pci->subsystem_vendor,
2129 av7110->dev->pci->subsystem_device);
2130 } else {
2131 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2132 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2133 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2134 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2135 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2136 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2137 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2138 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2139 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2140
2141 ret = dvb_register_frontend(av7110->dvb_adapter, av7110->fe);
2142 if (ret < 0) {
2143 printk("av7110: Frontend registration failed!\n");
2144 if (av7110->fe->ops->release)
2145 av7110->fe->ops->release(av7110->fe);
2146 av7110->fe = NULL;
2147 }
2148 }
2149 return ret;
2150}
2151
2152/* Budgetpatch note:
2153 * Original hardware design by Roberto Deza:
2154 * There is a DVB_Wiki at
2155 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2156 * where is described this 'DVB TT Budget Patch', on Card Modding:
2157 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2158 * On the short description there is also a link to a external file,
2159 * with more details:
2160 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2161 *
2162 * New software triggering design by Emard that works on
2163 * original Roberto Deza's hardware:
2164 *
2165 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2166 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2167 * HS is an internal event of 7146, accessible with RPS
2168 * and temporarily raised high every n lines
2169 * (n in defined in the RPS_THRESH1 counter threshold)
2170 * I think HS is raised high on the beginning of the n-th line
2171 * and remains high until this n-th line that triggered
2172 * it is completely received. When the receiption of n-th line
2173 * ends, HS is lowered.
2174 *
2175 * To transmit data over DMA, 7146 needs changing state at
2176 * port B VSYNC pin. Any changing of port B VSYNC will
2177 * cause some DMA data transfer, with more or less packets loss.
2178 * It depends on the phase and frequency of VSYNC and
2179 * the way of 7146 is instructed to trigger on port B (defined
2180 * in DD1_INIT register, 3rd nibble from the right valid
2181 * numbers are 0-7, see datasheet)
2182 *
2183 * The correct triggering can minimize packet loss,
2184 * dvbtraffic should give this stable bandwidths:
2185 * 22k transponder = 33814 kbit/s
2186 * 27.5k transponder = 38045 kbit/s
2187 * by experiment it is found that the best results
2188 * (stable bandwidths and almost no packet loss)
2189 * are obtained using DD1_INIT triggering number 2
2190 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2191 * and a VSYNC phase that occurs in the middle of DMA transfer
2192 * (about byte 188*512=96256 in the DMA window).
2193 *
2194 * Phase of HS is still not clear to me how to control,
2195 * It just happens to be so. It can be seen if one enables
2196 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2197 * time RPS_INTERRUPT is called, the Event Counter 1 will
2198 * increment. That's how the 7146 is programmed to do event
2199 * counting in this budget-patch.c
2200 * I *think* HPS setting has something to do with the phase
2201 * of HS but I cant be 100% sure in that.
2202 *
2203 * hardware debug note: a working budget card (including budget patch)
2204 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2205 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2206 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2207 * watch cat /proc/interrupts
2208 *
2209 * If this frequency is 3x lower (and data received in the DMA
2210 * buffer don't start with 0x47, but in the middle of packets,
2211 * whose lengths appear to be like 188 292 188 104 etc.
2212 * this means VSYNC line is not connected in the hardware.
2213 * (check soldering pcb and pins)
2214 * The same behaviour of missing VSYNC can be duplicated on budget
2215 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2216 */
2217static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
2218{
2219 const int length = TS_WIDTH * TS_HEIGHT;
2220 struct pci_dev *pdev = dev->pci;
2221 struct av7110 *av7110;
2222 int ret, count = 0;
2223
2224 dprintk(4, "dev: %p\n", dev);
2225
2226 /* Set RPS_IRQ to 1 to track rps1 activity.
2227 * Enabling this won't send any interrupt to PC CPU.
2228 */
2229#define RPS_IRQ 0
2230
2231 if (budgetpatch == 1) {
2232 budgetpatch = 0;
2233 /* autodetect the presence of budget patch
2234 * this only works if saa7146 has been recently
2235 * reset with with MASK_31 to MC1
2236 *
2237 * will wait for VBI_B event (vertical blank at port B)
2238 * and will reset GPIO3 after VBI_B is detected.
2239 * (GPIO3 should be raised high by CPU to
2240 * test if GPIO3 will generate vertical blank signal
2241 * in budget patch GPIO3 is connected to VSYNC_B
2242 */
2243
2244 /* RESET SAA7146 */
2245 saa7146_write(dev, MC1, MASK_31);
2246 /* autodetection success seems to be time-dependend after reset */
2247
2248 /* Fix VSYNC level */
2249 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2250 /* set vsync_b triggering */
2251 saa7146_write(dev, DD1_STREAM_B, 0);
2252 /* port B VSYNC at rising edge */
2253 saa7146_write(dev, DD1_INIT, 0x00000200);
2254 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2255 saa7146_write(dev, MC2,
2256 1 * (MASK_08 | MASK_24) | // BRS control
2257 0 * (MASK_09 | MASK_25) | // a
2258 1 * (MASK_10 | MASK_26) | // b
2259 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2260 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2261 0 * (MASK_01 | MASK_15) // DEBI
2262 );
2263
2264 /* start writing RPS1 code from beginning */
2265 count = 0;
2266 /* Disable RPS1 */
2267 saa7146_write(dev, MC1, MASK_29);
2268 /* RPS1 timeout disable */
2269 saa7146_write(dev, RPS_TOV1, 0);
2270 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2271 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2272 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2273 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2274#if RPS_IRQ
2275 /* issue RPS1 interrupt to increment counter */
2276 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2277#endif
2278 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2279 /* Jump to begin of RPS program as safety measure (p37) */
2280 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2281 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2282
2283#if RPS_IRQ
2284 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2285 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2286 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2287 */
2288 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2289 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2290 saa7146_write(dev, ECT1R, 0x3fff );
2291#endif
2292 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2293 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2294 /* Enable RPS1, (rFC p33) */
2295 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2296
2297 mdelay(10);
2298 /* now send VSYNC_B to rps1 by rising GPIO3 */
2299 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2300 mdelay(10);
2301 /* if rps1 responded by lowering the GPIO3,
2302 * then we have budgetpatch hardware
2303 */
2304 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2305 budgetpatch = 1;
2306 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2307 }
2308 /* Disable RPS1 */
2309 saa7146_write(dev, MC1, ( MASK_29 ));
2310#if RPS_IRQ
2311 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2312#endif
2313 }
2314
2315 /* prepare the av7110 device struct */
2316 av7110 = kmalloc(sizeof(struct av7110), GFP_KERNEL);
2317 if (!av7110) {
2318 dprintk(1, "out of memory\n");
2319 return -ENOMEM;
2320 }
2321
2322 memset(av7110, 0, sizeof(struct av7110));
2323
2324 av7110->card_name = (char*) pci_ext->ext_priv;
2325 av7110->dev = dev;
2326 dev->ext_priv = av7110;
2327
2328 ret = get_firmware(av7110);
2329 if (ret < 0)
2330 goto err_kfree_0;
2331
2332 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2333 THIS_MODULE);
2334 if (ret < 0)
2335 goto err_put_firmware_1;
2336
2337 /* the Siemens DVB needs this if you want to have the i2c chips
2338 get recognized before the main driver is fully loaded */
2339 saa7146_write(dev, GPIO_CTRL, 0x500000);
2340
2341#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2342 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2343#else
2344 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2345#endif
2346 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2347
2348 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2349
2350 ret = i2c_add_adapter(&av7110->i2c_adap);
2351 if (ret < 0)
2352 goto err_dvb_unregister_adapter_2;
2353
2354 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
2355 av7110->dvb_adapter->proposed_mac);
2356 ret = -ENOMEM;
2357
2358 if (budgetpatch) {
2359 spin_lock_init(&av7110->feedlock1);
2360 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2361 &av7110->pt);
2362 if (!av7110->grabbing)
2363 goto err_i2c_del_3;
2364
2365 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2366 saa7146_write(dev, BCS_CTRL, 0x80400040);
2367 /* set dd1 stream a & b */
2368 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2369 saa7146_write(dev, DD1_INIT, 0x03000200);
2370 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2371 saa7146_write(dev, BRS_CTRL, 0x60000000);
2372 saa7146_write(dev, BASE_ODD3, 0);
2373 saa7146_write(dev, BASE_EVEN3, 0);
2374 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2375 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2376
2377 saa7146_write(dev, PITCH3, TS_WIDTH);
2378 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2379
2380 /* upload all */
2381 saa7146_write(dev, MC2, 0x077c077c);
2382 saa7146_write(dev, GPIO_CTRL, 0x000000);
2383#if RPS_IRQ
2384 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2385 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2386 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2387 */
2388 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2389 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2390 saa7146_write(dev, ECT1R, 0x3fff );
2391#endif
2392 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2393 count = 0;
2394
2395 /* Wait Source Line Counter Threshold (p36) */
2396 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2397 /* Set GPIO3=1 (p42) */
2398 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2399 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2400 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2401#if RPS_IRQ
2402 /* issue RPS1 interrupt */
2403 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2404#endif
2405 /* Wait reset Source Line Counter Threshold (p36) */
2406 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2407 /* Set GPIO3=0 (p42) */
2408 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2409 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2410 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2411#if RPS_IRQ
2412 /* issue RPS1 interrupt */
2413 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2414#endif
2415 /* Jump to begin of RPS program (p37) */
2416 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2417 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2418
2419 /* Fix VSYNC level */
2420 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2421 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2422 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2423 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2424 * It generates HS event every TS_HEIGHT lines
2425 * this is related to TS_WIDTH set in register
2426 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2427 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2428 * then RPS_THRESH1 should be set to trigger
2429 * every TS_HEIGHT (512) lines.
2430 */
2431 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2432
2433 /* Enable RPS1 (rFC p33) */
2434 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2435
2436 /* end of budgetpatch register initialization */
2437 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2438 } else {
2439 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2440 saa7146_write(dev, BCS_CTRL, 0x80400040);
2441
2442 /* set dd1 stream a & b */
2443 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2444 saa7146_write(dev, DD1_INIT, 0x03000000);
2445 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2446
2447 /* upload all */
2448 saa7146_write(dev, MC2, 0x077c077c);
2449 saa7146_write(dev, GPIO_CTRL, 0x000000);
2450 }
2451
2452 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2453 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2454
2455 sema_init(&av7110->pid_mutex, 1);
2456
2457 /* locks for data transfers from/to AV7110 */
2458 spin_lock_init(&av7110->debilock);
2459 sema_init(&av7110->dcomlock, 1);
2460 av7110->debitype = -1;
2461
2462 /* default OSD window */
2463 av7110->osdwin = 1;
2464 sema_init(&av7110->osd_sema, 1);
2465
2466 /* ARM "watchdog" */
2467 init_waitqueue_head(&av7110->arm_wait);
2468 av7110->arm_thread = NULL;
2469
2470 /* allocate and init buffers */
2471 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2472 if (!av7110->debi_virt)
2473 goto err_saa71466_vfree_4;
2474
2475
2476 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2477 if (!av7110->iobuf)
2478 goto err_pci_free_5;
2479
2480 ret = av7110_av_init(av7110);
2481 if (ret < 0)
2482 goto err_iobuf_vfree_6;
2483
2484 /* init BMP buffer */
2485 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2486 init_waitqueue_head(&av7110->bmpq);
2487
2488 ret = av7110_ca_init(av7110);
2489 if (ret < 0)
2490 goto err_av7110_av_exit_7;
2491
2492 /* load firmware into AV7110 cards */
2493 ret = av7110_bootarm(av7110);
2494 if (ret < 0)
2495 goto err_av7110_ca_exit_8;
2496
2497 ret = av7110_firmversion(av7110);
2498 if (ret < 0)
2499 goto err_stop_arm_9;
2500
2501 if (FW_VERSION(av7110->arm_app)<0x2501)
2502 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2503 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2504
2505 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2506 if (ret < 0)
2507 goto err_stop_arm_9;
2508
2509 /* set initial volume in mixer struct */
2510 av7110->mixer.volume_left = volume;
2511 av7110->mixer.volume_right = volume;
2512
2513 init_av7110_av(av7110);
2514
2515 ret = av7110_register(av7110);
2516 if (ret < 0)
2517 goto err_arm_thread_stop_10;
2518
2519 /* special case DVB-C: these cards have an analog tuner
2520 plus need some special handling, so we have separate
2521 saa7146_ext_vv data for these... */
2522 ret = av7110_init_v4l(av7110);
2523 if (ret < 0)
2524 goto err_av7110_unregister_11;
2525
2526 av7110->dvb_adapter->priv = av7110;
2527 ret = frontend_init(av7110);
2528 if (ret < 0)
2529 goto err_av7110_exit_v4l_12;
2530
2531#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2532 av7110_ir_init();
2533#endif
2534 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2535 av7110_num++;
2536out:
2537 return ret;
2538
2539err_av7110_exit_v4l_12:
2540 av7110_exit_v4l(av7110);
2541err_av7110_unregister_11:
2542 dvb_unregister(av7110);
2543err_arm_thread_stop_10:
2544 av7110_arm_sync(av7110);
2545err_stop_arm_9:
2546 /* Nothing to do. Rejoice. */
2547err_av7110_ca_exit_8:
2548 av7110_ca_exit(av7110);
2549err_av7110_av_exit_7:
2550 av7110_av_exit(av7110);
2551err_iobuf_vfree_6:
2552 vfree(av7110->iobuf);
2553err_pci_free_5:
2554 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2555err_saa71466_vfree_4:
2556 if (!av7110->grabbing)
2557 saa7146_pgtable_free(pdev, &av7110->pt);
2558err_i2c_del_3:
2559 i2c_del_adapter(&av7110->i2c_adap);
2560err_dvb_unregister_adapter_2:
2561 dvb_unregister_adapter(av7110->dvb_adapter);
2562err_put_firmware_1:
2563 put_firmware(av7110);
2564err_kfree_0:
2565 kfree(av7110);
2566 goto out;
2567}
2568
2569static int av7110_detach(struct saa7146_dev* saa)
2570{
2571 struct av7110 *av7110 = saa->ext_priv;
2572 dprintk(4, "%p\n", av7110);
2573
2574 if (budgetpatch) {
2575 /* Disable RPS1 */
2576 saa7146_write(saa, MC1, MASK_29);
2577 /* VSYNC LOW (inactive) */
2578 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2579 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2580 SAA7146_IER_DISABLE(saa, MASK_10);
2581 SAA7146_ISR_CLEAR(saa, MASK_10);
2582 msleep(50);
2583 tasklet_kill(&av7110->vpe_tasklet);
2584 saa7146_pgtable_free(saa->pci, &av7110->pt);
2585 }
2586 av7110_exit_v4l(av7110);
2587
2588 av7110_arm_sync(av7110);
2589
2590 tasklet_kill(&av7110->debi_tasklet);
2591 tasklet_kill(&av7110->gpio_tasklet);
2592
2593 dvb_unregister(av7110);
2594
2595 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2596 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2597
2598 av7110_ca_exit(av7110);
2599 av7110_av_exit(av7110);
2600
2601 vfree(av7110->iobuf);
2602 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2603 av7110->debi_bus);
2604
2605 i2c_del_adapter(&av7110->i2c_adap);
2606
2607 dvb_unregister_adapter (av7110->dvb_adapter);
2608
2609 av7110_num--;
2610
2611 put_firmware(av7110);
2612
2613 kfree(av7110);
2614
2615 saa->ext_priv = NULL;
2616
2617 return 0;
2618}
2619
2620
2621static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2622{
2623 struct av7110 *av7110 = dev->ext_priv;
2624
2625 //print_time("av7110_irq");
2626
2627 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2628 * intel mode the timeout is asserted all the time...
2629 */
2630
2631 if (*isr & MASK_19) {
2632 //printk("av7110_irq: DEBI\n");
2633 /* Note 1: The DEBI irq is level triggered: We must enable it
2634 * only after we started a DMA xfer, and disable it here
2635 * immediately, or it will be signalled all the time while
2636 * DEBI is idle.
2637 * Note 2: You would think that an irq which is masked is
2638 * not signalled by the hardware. Not so for the SAA7146:
2639 * An irq is signalled as long as the corresponding bit
2640 * in the ISR is set, and disabling irqs just prevents the
2641 * hardware from setting the ISR bit. This means a) that we
2642 * must clear the ISR *after* disabling the irq (which is why
2643 * we must do it here even though saa7146_core did it already),
2644 * and b) that if we were to disable an edge triggered irq
2645 * (like the gpio irqs sadly are) temporarily we would likely
2646 * loose some. This sucks :-(
2647 */
2648 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2649 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2650 tasklet_schedule(&av7110->debi_tasklet);
2651 }
2652
2653 if (*isr & MASK_03) {
2654 //printk("av7110_irq: GPIO\n");
2655 tasklet_schedule(&av7110->gpio_tasklet);
2656 }
2657
2658 if ((*isr & MASK_10) && budgetpatch)
2659 tasklet_schedule(&av7110->vpe_tasklet);
2660}
2661
2662
2663static struct saa7146_extension av7110_extension;
2664
2665#define MAKE_AV7110_INFO(x_var,x_name) \
2666static struct saa7146_pci_extension_data x_var = { \
2667 .ext_priv = x_name, \
2668 .ext = &av7110_extension }
2669
2670MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X");
2671MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2672MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2673MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2674MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
2675MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2676MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2677MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2678MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
2679
2680static struct pci_device_id pci_tbl[] = {
2681 MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000),
2682 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2683 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2684 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
2685 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
2686 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2687 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2688 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2689 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2690
2691/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
2692/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2693/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2694
2695 {
2696 .vendor = 0,
2697 }
2698};
2699
2700MODULE_DEVICE_TABLE(pci, pci_tbl);
2701
2702
2703static struct saa7146_extension av7110_extension = {
2704 .name = "dvb\0",
2705 .flags = SAA7146_I2C_SHORT_DELAY,
2706
2707 .module = THIS_MODULE,
2708 .pci_tbl = &pci_tbl[0],
2709 .attach = av7110_attach,
2710 .detach = av7110_detach,
2711
2712 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2713 .irq_func = av7110_irq,
2714};
2715
2716
2717static int __init av7110_init(void)
2718{
2719 int retval;
2720 retval = saa7146_register_extension(&av7110_extension);
2721 return retval;
2722}
2723
2724
2725static void __exit av7110_exit(void)
2726{
2727#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2728 av7110_ir_exit();
2729#endif
2730 saa7146_unregister_extension(&av7110_extension);
2731}
2732
2733module_init(av7110_init);
2734module_exit(av7110_exit);
2735
2736MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2737 "Siemens, Technotrend, Hauppauge");
2738MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2739MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
new file mode 100644
index 000000000000..5070e0523da7
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -0,0 +1,284 @@
1#ifndef _AV7110_H_
2#define _AV7110_H_
3
4#include <linux/interrupt.h>
5#include <linux/socket.h>
6#include <linux/netdevice.h>
7#include <linux/i2c.h>
8
9#ifdef CONFIG_DEVFS_FS
10#include <linux/devfs_fs_kernel.h>
11#endif
12
13#include <linux/dvb/video.h>
14#include <linux/dvb/audio.h>
15#include <linux/dvb/dmx.h>
16#include <linux/dvb/ca.h>
17#include <linux/dvb/osd.h>
18#include <linux/dvb/net.h>
19
20#include "dvbdev.h"
21#include "demux.h"
22#include "dvb_demux.h"
23#include "dmxdev.h"
24#include "dvb_filter.h"
25#include "dvb_net.h"
26#include "dvb_ringbuffer.h"
27#include "dvb_frontend.h"
28#include "ves1820.h"
29#include "ves1x93.h"
30#include "stv0299.h"
31#include "tda8083.h"
32#include "sp8870.h"
33#include "stv0297.h"
34#include "l64781.h"
35
36#include <media/saa7146_vv.h>
37
38
39#define ANALOG_TUNER_VES1820 1
40#define ANALOG_TUNER_STV0297 2
41#define ANALOG_TUNER_VBI 0x100
42
43extern int av7110_debug;
44
45#define dprintk(level,args...) \
46 do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __FUNCTION__); printk(args); } } while (0)
47
48#define MAXFILT 32
49
50enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
51
52struct av7110_p2t {
53 u8 pes[TS_SIZE];
54 u8 counter;
55 long int pos;
56 int frags;
57 struct dvb_demux_feed *feed;
58};
59
60/* video MPEG decoder events: */
61/* (code copied from dvb_frontend.c, should maybe be factored out...) */
62#define MAX_VIDEO_EVENT 8
63struct dvb_video_events {
64 struct video_event events[MAX_VIDEO_EVENT];
65 int eventw;
66 int eventr;
67 int overflow;
68 wait_queue_head_t wait_queue;
69 spinlock_t lock;
70};
71
72
73/* place to store all the necessary device information */
74struct av7110 {
75
76 /* devices */
77
78 struct dvb_device dvb_dev;
79 struct dvb_net dvb_net;
80
81 struct video_device *v4l_dev;
82 struct video_device *vbi_dev;
83
84 struct saa7146_dev *dev;
85
86 struct i2c_adapter i2c_adap;
87
88 char *card_name;
89
90 /* support for analog module of dvb-c */
91 int analog_tuner_flags;
92 int current_input;
93 u32 current_freq;
94
95 struct tasklet_struct debi_tasklet;
96 struct tasklet_struct gpio_tasklet;
97
98 int adac_type; /* audio DAC type */
99#define DVB_ADAC_TI 0
100#define DVB_ADAC_CRYSTAL 1
101#define DVB_ADAC_MSP 2
102#define DVB_ADAC_NONE -1
103
104
105 /* buffers */
106
107 void *iobuf; /* memory for all buffers */
108 struct dvb_ringbuffer avout; /* buffer for video or A/V mux */
109#define AVOUTLEN (128*1024)
110 struct dvb_ringbuffer aout; /* buffer for audio */
111#define AOUTLEN (64*1024)
112 void *bmpbuf;
113#define BMPLEN (8*32768+1024)
114
115 /* bitmap buffers and states */
116
117 int bmpp;
118 int bmplen;
119 volatile int bmp_state;
120#define BMP_NONE 0
121#define BMP_LOADING 1
122#define BMP_LOADINGS 2
123#define BMP_LOADED 3
124 wait_queue_head_t bmpq;
125
126
127 /* DEBI and polled command interface */
128
129 spinlock_t debilock;
130 struct semaphore dcomlock;
131 volatile int debitype;
132 volatile int debilen;
133
134
135 /* Recording and playback flags */
136
137 int rec_mode;
138 int playing;
139#define RP_NONE 0
140#define RP_VIDEO 1
141#define RP_AUDIO 2
142#define RP_AV 3
143
144
145 /* OSD */
146
147 int osdwin; /* currently active window */
148 u16 osdbpp[8];
149 struct semaphore osd_sema;
150
151 /* CA */
152
153 ca_slot_info_t ci_slot[2];
154
155 int vidmode;
156 struct dmxdev dmxdev;
157 struct dvb_demux demux;
158
159 struct dmx_frontend hw_frontend;
160 struct dmx_frontend mem_frontend;
161
162 /* for budget mode demux1 */
163 struct dmxdev dmxdev1;
164 struct dvb_demux demux1;
165 struct dvb_net dvb_net1;
166 spinlock_t feedlock1;
167 int feeding1;
168 u8 tsf;
169 u32 ttbp;
170 unsigned char *grabbing;
171 struct saa7146_pgtable pt;
172 struct tasklet_struct vpe_tasklet;
173
174 int fe_synced;
175 struct semaphore pid_mutex;
176
177 int video_blank;
178 struct video_status videostate;
179 int display_ar;
180 int trickmode;
181#define TRICK_NONE 0
182#define TRICK_FAST 1
183#define TRICK_SLOW 2
184#define TRICK_FREEZE 3
185 struct audio_status audiostate;
186
187 struct dvb_demux_filter *handle2filter[32];
188 struct av7110_p2t p2t_filter[MAXFILT];
189 struct dvb_filter_pes2ts p2t[2];
190 struct ipack ipack[2];
191 u8 *kbuf[2];
192
193 int sinfo;
194 int feeding;
195
196 int arm_errors;
197 int registered;
198
199
200 /* AV711X */
201
202 u32 arm_fw;
203 u32 arm_rtsl;
204 u32 arm_vid;
205 u32 arm_app;
206 u32 avtype;
207 int arm_ready;
208 struct task_struct *arm_thread;
209 wait_queue_head_t arm_wait;
210 u16 arm_loops;
211 int arm_rmmod;
212
213 void *debi_virt;
214 dma_addr_t debi_bus;
215
216 u16 pids[DMX_PES_OTHER];
217
218 struct dvb_ringbuffer ci_rbuffer;
219 struct dvb_ringbuffer ci_wbuffer;
220
221 struct audio_mixer mixer;
222
223 struct dvb_adapter *dvb_adapter;
224 struct dvb_device *video_dev;
225 struct dvb_device *audio_dev;
226 struct dvb_device *ca_dev;
227 struct dvb_device *osd_dev;
228
229 struct dvb_video_events video_events;
230 video_size_t video_size;
231
232 u32 ir_config;
233
234 /* firmware stuff */
235 unsigned char *bin_fw;
236 unsigned long size_fw;
237
238 unsigned char *bin_dpram;
239 unsigned long size_dpram;
240
241 unsigned char *bin_root;
242 unsigned long size_root;
243
244 struct dvb_frontend* fe;
245 fe_status_t fe_status;
246 int (*fe_init)(struct dvb_frontend* fe);
247 int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
248 int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
249 int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
250 int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
251 int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
252 int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
253 int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
254 int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
255};
256
257
258extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
259 u16 subpid, u16 pcrpid);
260
261extern void av7110_register_irc_handler(void (*func)(u32));
262extern void av7110_unregister_irc_handler(void (*func)(u32));
263extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
264
265extern int av7110_ir_init (void);
266extern void av7110_ir_exit (void);
267
268/* msp3400 i2c subaddresses */
269#define MSP_WR_DEM 0x10
270#define MSP_RD_DEM 0x11
271#define MSP_WR_DSP 0x12
272#define MSP_RD_DSP 0x13
273
274extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
275extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
276extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
277extern int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val);
278
279
280extern int av7110_init_analog_module(struct av7110 *av7110);
281extern int av7110_init_v4l(struct av7110 *av7110);
282extern int av7110_exit_v4l(struct av7110 *av7110);
283
284#endif /* _AV7110_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
new file mode 100644
index 000000000000..d77e8a00688f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -0,0 +1,1459 @@
1/*
2 * av7110_av.c: audio and video MPEG decoder stuff
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 *
27 *
28 * the project's page is at http://www.linuxtv.org/dvb/
29 */
30
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/string.h>
34#include <linux/sched.h>
35#include <linux/delay.h>
36#include <linux/byteorder/swabb.h>
37#include <linux/smp_lock.h>
38#include <linux/fs.h>
39
40#include "av7110.h"
41#include "av7110_hw.h"
42#include "av7110_av.h"
43#include "av7110_ipack.h"
44
45/* MPEG-2 (ISO 13818 / H.222.0) stream types */
46#define PROG_STREAM_MAP 0xBC
47#define PRIVATE_STREAM1 0xBD
48#define PADDING_STREAM 0xBE
49#define PRIVATE_STREAM2 0xBF
50#define AUDIO_STREAM_S 0xC0
51#define AUDIO_STREAM_E 0xDF
52#define VIDEO_STREAM_S 0xE0
53#define VIDEO_STREAM_E 0xEF
54#define ECM_STREAM 0xF0
55#define EMM_STREAM 0xF1
56#define DSM_CC_STREAM 0xF2
57#define ISO13522_STREAM 0xF3
58#define PROG_STREAM_DIR 0xFF
59
60#define PTS_DTS_FLAGS 0xC0
61
62//pts_dts flags
63#define PTS_ONLY 0x80
64#define PTS_DTS 0xC0
65#define TS_SIZE 188
66#define TRANS_ERROR 0x80
67#define PAY_START 0x40
68#define TRANS_PRIO 0x20
69#define PID_MASK_HI 0x1F
70//flags
71#define TRANS_SCRMBL1 0x80
72#define TRANS_SCRMBL2 0x40
73#define ADAPT_FIELD 0x20
74#define PAYLOAD 0x10
75#define COUNT_MASK 0x0F
76
77// adaptation flags
78#define DISCON_IND 0x80
79#define RAND_ACC_IND 0x40
80#define ES_PRI_IND 0x20
81#define PCR_FLAG 0x10
82#define OPCR_FLAG 0x08
83#define SPLICE_FLAG 0x04
84#define TRANS_PRIV 0x02
85#define ADAP_EXT_FLAG 0x01
86
87// adaptation extension flags
88#define LTW_FLAG 0x80
89#define PIECE_RATE 0x40
90#define SEAM_SPLICE 0x20
91
92
93static void p_to_t(u8 const *buf, long int length, u16 pid,
94 u8 *counter, struct dvb_demux_feed *feed);
95
96
97int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
98{
99 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;
100
101 if (!(dvbdmxfeed->ts_type & TS_PACKET))
102 return 0;
103 if (buf[3] == 0xe0) // video PES do not have a length in TS
104 buf[4] = buf[5] = 0;
105 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
106 return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
107 &dvbdmxfeed->feed.ts, DMX_OK);
108 else
109 return dvb_filter_pes2ts(p2t, buf, len, 1);
110}
111
112static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
113{
114 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
115
116 dvbdmxfeed->cb.ts(data, 188, NULL, 0,
117 &dvbdmxfeed->feed.ts, DMX_OK);
118 return 0;
119}
120
121int av7110_av_start_record(struct av7110 *av7110, int av,
122 struct dvb_demux_feed *dvbdmxfeed)
123{
124 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
125
126 dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
127
128 if (av7110->playing || (av7110->rec_mode & av))
129 return -EBUSY;
130 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
131 dvbdmx->recording = 1;
132 av7110->rec_mode |= av;
133
134 switch (av7110->rec_mode) {
135 case RP_AUDIO:
136 dvb_filter_pes2ts_init(&av7110->p2t[0],
137 dvbdmx->pesfilter[0]->pid,
138 dvb_filter_pes2ts_cb,
139 (void *) dvbdmx->pesfilter[0]);
140 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
141 break;
142
143 case RP_VIDEO:
144 dvb_filter_pes2ts_init(&av7110->p2t[1],
145 dvbdmx->pesfilter[1]->pid,
146 dvb_filter_pes2ts_cb,
147 (void *) dvbdmx->pesfilter[1]);
148 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
149 break;
150
151 case RP_AV:
152 dvb_filter_pes2ts_init(&av7110->p2t[0],
153 dvbdmx->pesfilter[0]->pid,
154 dvb_filter_pes2ts_cb,
155 (void *) dvbdmx->pesfilter[0]);
156 dvb_filter_pes2ts_init(&av7110->p2t[1],
157 dvbdmx->pesfilter[1]->pid,
158 dvb_filter_pes2ts_cb,
159 (void *) dvbdmx->pesfilter[1]);
160 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
161 break;
162 }
163 return 0;
164}
165
166int av7110_av_start_play(struct av7110 *av7110, int av)
167{
168 dprintk(2, "av7110:%p, \n", av7110);
169
170 if (av7110->rec_mode)
171 return -EBUSY;
172 if (av7110->playing & av)
173 return -EBUSY;
174
175 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
176
177 if (av7110->playing == RP_NONE) {
178 av7110_ipack_reset(&av7110->ipack[0]);
179 av7110_ipack_reset(&av7110->ipack[1]);
180 }
181
182 av7110->playing |= av;
183 switch (av7110->playing) {
184 case RP_AUDIO:
185 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
186 break;
187 case RP_VIDEO:
188 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
189 av7110->sinfo = 0;
190 break;
191 case RP_AV:
192 av7110->sinfo = 0;
193 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
194 break;
195 }
196 return av7110->playing;
197}
198
199void av7110_av_stop(struct av7110 *av7110, int av)
200{
201 dprintk(2, "av7110:%p, \n", av7110);
202
203 if (!(av7110->playing & av) && !(av7110->rec_mode & av))
204 return;
205
206 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
207 if (av7110->playing) {
208 av7110->playing &= ~av;
209 switch (av7110->playing) {
210 case RP_AUDIO:
211 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
212 break;
213 case RP_VIDEO:
214 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
215 break;
216 case RP_NONE:
217 av7110_set_vidmode(av7110, av7110->vidmode);
218 break;
219 }
220 } else {
221 av7110->rec_mode &= ~av;
222 switch (av7110->rec_mode) {
223 case RP_AUDIO:
224 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
225 break;
226 case RP_VIDEO:
227 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
228 break;
229 case RP_NONE:
230 break;
231 }
232 }
233}
234
235
236int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
237{
238 int len;
239 u32 sync;
240 u16 blen;
241
242 if (!dlen) {
243 wake_up(&buf->queue);
244 return -1;
245 }
246 while (1) {
247 if ((len = dvb_ringbuffer_avail(buf)) < 6)
248 return -1;
249 sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24;
250 sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16;
251 sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
252 sync |= DVB_RINGBUFFER_PEEK(buf, 3);
253
254 if (((sync &~ 0x0f) == 0x000001e0) ||
255 ((sync &~ 0x1f) == 0x000001c0) ||
256 (sync == 0x000001bd))
257 break;
258 printk("resync\n");
259 DVB_RINGBUFFER_SKIP(buf, 1);
260 }
261 blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8;
262 blen |= DVB_RINGBUFFER_PEEK(buf, 5);
263 blen += 6;
264 if (len < blen || blen > dlen) {
265 //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
266 wake_up(&buf->queue);
267 return -1;
268 }
269
270 dvb_ringbuffer_read(buf, dest, (size_t) blen, 0);
271
272 dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
273 (unsigned long) buf->pread, (unsigned long) buf->pwrite);
274 wake_up(&buf->queue);
275 return blen;
276}
277
278
279int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
280{
281 int err, vol, val, balance = 0;
282
283 dprintk(2, "av7110:%p, \n", av7110);
284
285 av7110->mixer.volume_left = volleft;
286 av7110->mixer.volume_right = volright;
287
288 switch (av7110->adac_type) {
289 case DVB_ADAC_TI:
290 volleft = (volleft * 256) / 1036;
291 volright = (volright * 256) / 1036;
292 if (volleft > 0x3f)
293 volleft = 0x3f;
294 if (volright > 0x3f)
295 volright = 0x3f;
296 if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
297 return err;
298 return SendDAC(av7110, 4, volright);
299
300 case DVB_ADAC_CRYSTAL:
301 volleft = 127 - volleft / 2;
302 volright = 127 - volright / 2;
303 i2c_writereg(av7110, 0x20, 0x03, volleft);
304 i2c_writereg(av7110, 0x20, 0x04, volright);
305 return 0;
306
307 case DVB_ADAC_MSP:
308 vol = (volleft > volright) ? volleft : volright;
309 val = (vol * 0x73 / 255) << 8;
310 if (vol > 0)
311 balance = ((volright - volleft) * 127) / vol;
312 msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
313 msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
314 msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
315 return 0;
316 }
317 return 0;
318}
319
320void av7110_set_vidmode(struct av7110 *av7110, int mode)
321{
322 dprintk(2, "av7110:%p, \n", av7110);
323
324 av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
325
326 if (!av7110->playing) {
327 ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
328 av7110->pids[DMX_PES_AUDIO],
329 av7110->pids[DMX_PES_TELETEXT],
330 0, av7110->pids[DMX_PES_PCR]);
331 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
332 }
333}
334
335
336static int sw2mode[16] = {
337 VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL,
338 VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC,
339 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
340 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
341};
342
343static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
344{
345 int i;
346 int hsize, vsize;
347 int sw;
348 u8 *p;
349
350 dprintk(2, "av7110:%p, \n", av7110);
351
352 if (av7110->sinfo)
353 return;
354 for (i = 7; i < count - 10; i++) {
355 p = buf + i;
356 if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
357 continue;
358 p += 4;
359 hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
360 vsize = ((p[1] &0x0F) << 8) | (p[2]);
361 sw = (p[3] & 0x0F);
362 av7110_set_vidmode(av7110, sw2mode[sw]);
363 dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
364 av7110->sinfo = 1;
365 break;
366 }
367}
368
369
370/****************************************************************************
371 * I/O buffer management and control
372 ****************************************************************************/
373
374static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
375 const char *buf, unsigned long count)
376{
377 unsigned long todo = count;
378 int free;
379
380 while (todo > 0) {
381 if (dvb_ringbuffer_free(rbuf) < 2048) {
382 if (wait_event_interruptible(rbuf->queue,
383 (dvb_ringbuffer_free(rbuf) >= 2048)))
384 return count - todo;
385 }
386 free = dvb_ringbuffer_free(rbuf);
387 if (free > todo)
388 free = todo;
389 dvb_ringbuffer_write(rbuf, buf, free);
390 todo -= free;
391 buf += free;
392 }
393
394 return count - todo;
395}
396
397static void play_video_cb(u8 *buf, int count, void *priv)
398{
399 struct av7110 *av7110 = (struct av7110 *) priv;
400 dprintk(2, "av7110:%p, \n", av7110);
401
402 if ((buf[3] & 0xe0) == 0xe0) {
403 get_video_format(av7110, buf, count);
404 aux_ring_buffer_write(&av7110->avout, buf, count);
405 } else
406 aux_ring_buffer_write(&av7110->aout, buf, count);
407}
408
409static void play_audio_cb(u8 *buf, int count, void *priv)
410{
411 struct av7110 *av7110 = (struct av7110 *) priv;
412 dprintk(2, "av7110:%p, \n", av7110);
413
414 aux_ring_buffer_write(&av7110->aout, buf, count);
415}
416
417#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
418 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
419
420static ssize_t dvb_play(struct av7110 *av7110, const u8 __user *buf,
421 unsigned long count, int nonblock, int type)
422{
423 unsigned long todo = count, n;
424 dprintk(2, "av7110:%p, \n", av7110);
425
426 if (!av7110->kbuf[type])
427 return -ENOBUFS;
428
429 if (nonblock && !FREE_COND)
430 return -EWOULDBLOCK;
431
432 while (todo > 0) {
433 if (!FREE_COND) {
434 if (nonblock)
435 return count - todo;
436 if (wait_event_interruptible(av7110->avout.queue,
437 FREE_COND))
438 return count - todo;
439 }
440 n = todo;
441 if (n > IPACKS * 2)
442 n = IPACKS * 2;
443 if (copy_from_user(av7110->kbuf[type], buf, n))
444 return -EFAULT;
445 av7110_ipack_instant_repack(av7110->kbuf[type], n,
446 &av7110->ipack[type]);
447 todo -= n;
448 buf += n;
449 }
450 return count - todo;
451}
452
453static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
454 unsigned long count, int nonblock, int type)
455{
456 unsigned long todo = count, n;
457 dprintk(2, "av7110:%p, \n", av7110);
458
459 if (!av7110->kbuf[type])
460 return -ENOBUFS;
461
462 if (nonblock && !FREE_COND)
463 return -EWOULDBLOCK;
464
465 while (todo > 0) {
466 if (!FREE_COND) {
467 if (nonblock)
468 return count - todo;
469 if (wait_event_interruptible(av7110->avout.queue,
470 FREE_COND))
471 return count - todo;
472 }
473 n = todo;
474 if (n > IPACKS * 2)
475 n = IPACKS * 2;
476 av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]);
477 todo -= n;
478 buf += n;
479 }
480 return count - todo;
481}
482
483static ssize_t dvb_aplay(struct av7110 *av7110, const u8 __user *buf,
484 unsigned long count, int nonblock, int type)
485{
486 unsigned long todo = count, n;
487 dprintk(2, "av7110:%p, \n", av7110);
488
489 if (!av7110->kbuf[type])
490 return -ENOBUFS;
491 if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024)
492 return -EWOULDBLOCK;
493
494 while (todo > 0) {
495 if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) {
496 if (nonblock)
497 return count - todo;
498 if (wait_event_interruptible(av7110->aout.queue,
499 (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
500 return count-todo;
501 }
502 n = todo;
503 if (n > IPACKS * 2)
504 n = IPACKS * 2;
505 if (copy_from_user(av7110->kbuf[type], buf, n))
506 return -EFAULT;
507 av7110_ipack_instant_repack(av7110->kbuf[type], n,
508 &av7110->ipack[type]);
509 todo -= n;
510 buf += n;
511 }
512 return count - todo;
513}
514
515void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed)
516{
517 memset(p->pes, 0, TS_SIZE);
518 p->counter = 0;
519 p->pos = 0;
520 p->frags = 0;
521 if (feed)
522 p->feed = feed;
523}
524
525static void clear_p2t(struct av7110_p2t *p)
526{
527 memset(p->pes, 0, TS_SIZE);
528// p->counter = 0;
529 p->pos = 0;
530 p->frags = 0;
531}
532
533
534static int find_pes_header(u8 const *buf, long int length, int *frags)
535{
536 int c = 0;
537 int found = 0;
538
539 *frags = 0;
540
541 while (c < length - 3 && !found) {
542 if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
543 buf[c + 2] == 0x01) {
544 switch ( buf[c + 3] ) {
545 case PROG_STREAM_MAP:
546 case PRIVATE_STREAM2:
547 case PROG_STREAM_DIR:
548 case ECM_STREAM :
549 case EMM_STREAM :
550 case PADDING_STREAM :
551 case DSM_CC_STREAM :
552 case ISO13522_STREAM:
553 case PRIVATE_STREAM1:
554 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
555 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
556 found = 1;
557 break;
558
559 default:
560 c++;
561 break;
562 }
563 } else
564 c++;
565 }
566 if (c == length - 3 && !found) {
567 if (buf[length - 1] == 0x00)
568 *frags = 1;
569 if (buf[length - 2] == 0x00 &&
570 buf[length - 1] == 0x00)
571 *frags = 2;
572 if (buf[length - 3] == 0x00 &&
573 buf[length - 2] == 0x00 &&
574 buf[length - 1] == 0x01)
575 *frags = 3;
576 return -1;
577 }
578
579 return c;
580}
581
582void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
583{
584 int c, c2, l, add;
585 int check, rest;
586
587 c = 0;
588 c2 = 0;
589 if (p->frags){
590 check = 0;
591 switch(p->frags) {
592 case 1:
593 if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
594 check = 1;
595 c += 2;
596 }
597 break;
598 case 2:
599 if (buf[c] == 0x01) {
600 check = 1;
601 c++;
602 }
603 break;
604 case 3:
605 check = 1;
606 }
607 if (check) {
608 switch (buf[c]) {
609 case PROG_STREAM_MAP:
610 case PRIVATE_STREAM2:
611 case PROG_STREAM_DIR:
612 case ECM_STREAM :
613 case EMM_STREAM :
614 case PADDING_STREAM :
615 case DSM_CC_STREAM :
616 case ISO13522_STREAM:
617 case PRIVATE_STREAM1:
618 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
619 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
620 p->pes[0] = 0x00;
621 p->pes[1] = 0x00;
622 p->pes[2] = 0x01;
623 p->pes[3] = buf[c];
624 p->pos = 4;
625 memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos);
626 c += (TS_SIZE - 4) - p->pos;
627 p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed);
628 clear_p2t(p);
629 break;
630
631 default:
632 c = 0;
633 break;
634 }
635 }
636 p->frags = 0;
637 }
638
639 if (p->pos) {
640 c2 = find_pes_header(buf + c, length - c, &p->frags);
641 if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
642 l = c2+c;
643 else
644 l = (TS_SIZE - 4) - p->pos;
645 memcpy(p->pes + p->pos, buf, l);
646 c += l;
647 p->pos += l;
648 p_to_t(p->pes, p->pos, pid, &p->counter, p->feed);
649 clear_p2t(p);
650 }
651
652 add = 0;
653 while (c < length) {
654 c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
655 if (c2 >= 0) {
656 c2 += c + add;
657 if (c2 > c){
658 p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
659 c = c2;
660 clear_p2t(p);
661 add = 0;
662 } else
663 add = 1;
664 } else {
665 l = length - c;
666 rest = l % (TS_SIZE - 4);
667 l -= rest;
668 p_to_t(buf + c, l, pid, &p->counter, p->feed);
669 memcpy(p->pes, buf + c + l, rest);
670 p->pos = rest;
671 c = length;
672 }
673 }
674}
675
676
677static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
678{
679 int i;
680 int c = 0;
681 int fill;
682 u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 };
683
684 fill = (TS_SIZE - 4) - length;
685 if (pes_start)
686 tshead[1] = 0x40;
687 if (fill)
688 tshead[3] = 0x30;
689 tshead[1] |= (u8)((pid & 0x1F00) >> 8);
690 tshead[2] |= (u8)(pid & 0x00FF);
691 tshead[3] |= ((*counter)++ & 0x0F);
692 memcpy(buf, tshead, 4);
693 c += 4;
694
695 if (fill) {
696 buf[4] = fill - 1;
697 c++;
698 if (fill > 1) {
699 buf[5] = 0x00;
700 c++;
701 }
702 for (i = 6; i < fill + 4; i++) {
703 buf[i] = 0xFF;
704 c++;
705 }
706 }
707
708 return c;
709}
710
711
712static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
713 struct dvb_demux_feed *feed)
714{
715 int l, pes_start;
716 u8 obuf[TS_SIZE];
717 long c = 0;
718
719 pes_start = 0;
720 if (length > 3 &&
721 buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
722 switch (buf[3]) {
723 case PROG_STREAM_MAP:
724 case PRIVATE_STREAM2:
725 case PROG_STREAM_DIR:
726 case ECM_STREAM :
727 case EMM_STREAM :
728 case PADDING_STREAM :
729 case DSM_CC_STREAM :
730 case ISO13522_STREAM:
731 case PRIVATE_STREAM1:
732 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
733 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
734 pes_start = 1;
735 break;
736
737 default:
738 break;
739 }
740
741 while (c < length) {
742 memset(obuf, 0, TS_SIZE);
743 if (length - c >= (TS_SIZE - 4)){
744 l = write_ts_header2(pid, counter, pes_start,
745 obuf, (TS_SIZE - 4));
746 memcpy(obuf + l, buf + c, TS_SIZE - l);
747 c += TS_SIZE - l;
748 } else {
749 l = write_ts_header2(pid, counter, pes_start,
750 obuf, length - c);
751 memcpy(obuf + l, buf + c, TS_SIZE - l);
752 c = length;
753 }
754 feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
755 pes_start = 0;
756 }
757}
758
759
760int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
761{
762 struct dvb_demux *demux = feed->demux;
763 struct av7110 *av7110 = (struct av7110 *) demux->priv;
764 struct ipack *ipack = &av7110->ipack[feed->pes_type];
765
766 dprintk(2, "av7110:%p, \n", av7110);
767
768 switch (feed->pes_type) {
769 case 0:
770 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
771 return -EINVAL;
772 break;
773 case 1:
774 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
775 return -EINVAL;
776 break;
777 default:
778 return -1;
779 }
780
781 if (!(buf[3] & 0x10)) /* no payload? */
782 return -1;
783 if (buf[1] & 0x40)
784 av7110_ipack_flush(ipack);
785
786 if (buf[3] & 0x20) { /* adaptation field? */
787 len -= buf[4] + 1;
788 buf += buf[4] + 1;
789 if (!len)
790 return 0;
791 }
792
793 av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]);
794 return 0;
795}
796
797
798
799/******************************************************************************
800 * Video MPEG decoder events
801 ******************************************************************************/
802void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
803{
804 struct dvb_video_events *events = &av7110->video_events;
805 int wp;
806
807 spin_lock_bh(&events->lock);
808
809 wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
810 if (wp == events->eventr) {
811 events->overflow = 1;
812 events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
813 }
814
815 //FIXME: timestamp?
816 memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
817 events->eventw = wp;
818
819 spin_unlock_bh(&events->lock);
820
821 wake_up_interruptible(&events->wait_queue);
822}
823
824
825static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
826{
827 struct dvb_video_events *events = &av7110->video_events;
828
829 if (events->overflow) {
830 events->overflow = 0;
831 return -EOVERFLOW;
832 }
833 if (events->eventw == events->eventr) {
834 int ret;
835
836 if (flags & O_NONBLOCK)
837 return -EWOULDBLOCK;
838
839 ret = wait_event_interruptible(events->wait_queue,
840 events->eventw != events->eventr);
841 if (ret < 0)
842 return ret;
843 }
844
845 spin_lock_bh(&events->lock);
846
847 memcpy(event, &events->events[events->eventr],
848 sizeof(struct video_event));
849 events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
850
851 spin_unlock_bh(&events->lock);
852
853 return 0;
854}
855
856
857/******************************************************************************
858 * DVB device file operations
859 ******************************************************************************/
860
861static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
862{
863 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
864 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
865 unsigned int mask = 0;
866
867 dprintk(2, "av7110:%p, \n", av7110);
868
869 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
870 poll_wait(file, &av7110->avout.queue, wait);
871
872 poll_wait(file, &av7110->video_events.wait_queue, wait);
873
874 if (av7110->video_events.eventw != av7110->video_events.eventr)
875 mask = POLLPRI;
876
877 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
878 if (av7110->playing) {
879 if (FREE_COND)
880 mask |= (POLLOUT | POLLWRNORM);
881 } else /* if not playing: may play if asked for */
882 mask |= (POLLOUT | POLLWRNORM);
883 }
884
885 return mask;
886}
887
888static ssize_t dvb_video_write(struct file *file, const char __user *buf,
889 size_t count, loff_t *ppos)
890{
891 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
892 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
893
894 dprintk(2, "av7110:%p, \n", av7110);
895
896 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
897 return -EPERM;
898
899 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
900 return -EPERM;
901
902 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
903}
904
905static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
906{
907 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
908 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
909 unsigned int mask = 0;
910
911 dprintk(2, "av7110:%p, \n", av7110);
912
913 poll_wait(file, &av7110->aout.queue, wait);
914
915 if (av7110->playing) {
916 if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
917 mask |= (POLLOUT | POLLWRNORM);
918 } else /* if not playing: may play if asked for */
919 mask = (POLLOUT | POLLWRNORM);
920
921 return mask;
922}
923
924static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
925 size_t count, loff_t *ppos)
926{
927 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
928 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
929
930 dprintk(2, "av7110:%p, \n", av7110);
931
932 if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
933 printk(KERN_ERR "not audio source memory\n");
934 return -EPERM;
935 }
936 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
937}
938
939static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
940
941#define MIN_IFRAME 400000
942
943static int play_iframe(struct av7110 *av7110, u8 __user *buf, unsigned int len, int nonblock)
944{
945 int i, n;
946
947 dprintk(2, "av7110:%p, \n", av7110);
948
949 if (!(av7110->playing & RP_VIDEO)) {
950 if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
951 return -EBUSY;
952 }
953
954 /* setting n always > 1, fixes problems when playing stillframes
955 consisting of I- and P-Frames */
956 n = MIN_IFRAME / len + 1;
957
958 /* FIXME: nonblock? */
959 dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1);
960
961 for (i = 0; i < n; i++)
962 dvb_play(av7110, buf, len, 0, 1);
963
964 av7110_ipack_flush(&av7110->ipack[1]);
965 return 0;
966}
967
968
969static int dvb_video_ioctl(struct inode *inode, struct file *file,
970 unsigned int cmd, void *parg)
971{
972 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
973 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
974 unsigned long arg = (unsigned long) parg;
975 int ret = 0;
976
977 dprintk(2, "av7110:%p, \n", av7110);
978
979 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
980 if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
981 cmd != VIDEO_GET_SIZE ) {
982 return -EPERM;
983 }
984 }
985
986 switch (cmd) {
987 case VIDEO_STOP:
988 av7110->videostate.play_state = VIDEO_STOPPED;
989 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
990 av7110_av_stop(av7110, RP_VIDEO);
991 else
992 vidcom(av7110, VIDEO_CMD_STOP,
993 av7110->videostate.video_blank ? 0 : 1);
994 av7110->trickmode = TRICK_NONE;
995 break;
996
997 case VIDEO_PLAY:
998 av7110->trickmode = TRICK_NONE;
999 if (av7110->videostate.play_state == VIDEO_FREEZED) {
1000 av7110->videostate.play_state = VIDEO_PLAYING;
1001 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1002 }
1003
1004 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
1005 if (av7110->playing == RP_AV) {
1006 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
1007 av7110->playing &= ~RP_VIDEO;
1008 }
1009 av7110_av_start_play(av7110, RP_VIDEO);
1010 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1011 } else {
1012 //av7110_av_stop(av7110, RP_VIDEO);
1013 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1014 }
1015 av7110->videostate.play_state = VIDEO_PLAYING;
1016 break;
1017
1018 case VIDEO_FREEZE:
1019 av7110->videostate.play_state = VIDEO_FREEZED;
1020 if (av7110->playing & RP_VIDEO)
1021 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
1022 else
1023 vidcom(av7110, VIDEO_CMD_FREEZE, 1);
1024 av7110->trickmode = TRICK_FREEZE;
1025 break;
1026
1027 case VIDEO_CONTINUE:
1028 if (av7110->playing & RP_VIDEO)
1029 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
1030 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1031 av7110->videostate.play_state = VIDEO_PLAYING;
1032 av7110->trickmode = TRICK_NONE;
1033 break;
1034
1035 case VIDEO_SELECT_SOURCE:
1036 av7110->videostate.stream_source = (video_stream_source_t) arg;
1037 break;
1038
1039 case VIDEO_SET_BLANK:
1040 av7110->videostate.video_blank = (int) arg;
1041 break;
1042
1043 case VIDEO_GET_STATUS:
1044 memcpy(parg, &av7110->videostate, sizeof(struct video_status));
1045 break;
1046
1047 case VIDEO_GET_EVENT:
1048 ret=dvb_video_get_event(av7110, parg, file->f_flags);
1049 break;
1050
1051 case VIDEO_GET_SIZE:
1052 memcpy(parg, &av7110->video_size, sizeof(video_size_t));
1053 break;
1054
1055 case VIDEO_SET_DISPLAY_FORMAT:
1056 {
1057 video_displayformat_t format = (video_displayformat_t) arg;
1058 u16 val = 0;
1059
1060 switch (format) {
1061 case VIDEO_PAN_SCAN:
1062 val = VID_PAN_SCAN_PREF;
1063 break;
1064
1065 case VIDEO_LETTER_BOX:
1066 val = VID_VC_AND_PS_PREF;
1067 break;
1068
1069 case VIDEO_CENTER_CUT_OUT:
1070 val = VID_CENTRE_CUT_PREF;
1071 break;
1072
1073 default:
1074 ret = -EINVAL;
1075 }
1076 if (ret < 0)
1077 break;
1078 av7110->videostate.video_format = format;
1079 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
1080 1, (u16) val);
1081 break;
1082 }
1083
1084 case VIDEO_SET_FORMAT:
1085 if (arg > 1) {
1086 ret = -EINVAL;
1087 break;
1088 }
1089 av7110->display_ar = arg;
1090 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
1091 1, (u16) arg);
1092 break;
1093
1094 case VIDEO_STILLPICTURE:
1095 {
1096 struct video_still_picture *pic =
1097 (struct video_still_picture *) parg;
1098 av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
1099 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1100 ret = play_iframe(av7110, pic->iFrame, pic->size,
1101 file->f_flags & O_NONBLOCK);
1102 break;
1103 }
1104
1105 case VIDEO_FAST_FORWARD:
1106 //note: arg is ignored by firmware
1107 if (av7110->playing & RP_VIDEO)
1108 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1109 __Scan_I, 2, AV_PES, 0);
1110 else
1111 vidcom(av7110, VIDEO_CMD_FFWD, arg);
1112 av7110->trickmode = TRICK_FAST;
1113 av7110->videostate.play_state = VIDEO_PLAYING;
1114 break;
1115
1116 case VIDEO_SLOWMOTION:
1117 if (av7110->playing&RP_VIDEO) {
1118 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1119 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1120 } else {
1121 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1122 vidcom(av7110, VIDEO_CMD_STOP, 0);
1123 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1124 }
1125 av7110->trickmode = TRICK_SLOW;
1126 av7110->videostate.play_state = VIDEO_PLAYING;
1127 break;
1128
1129 case VIDEO_GET_CAPABILITIES:
1130 *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |
1131 VIDEO_CAP_SYS | VIDEO_CAP_PROG;
1132 break;
1133
1134 case VIDEO_CLEAR_BUFFER:
1135 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1136 av7110_ipack_reset(&av7110->ipack[1]);
1137
1138 if (av7110->playing == RP_AV) {
1139 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1140 __Play, 2, AV_PES, 0);
1141 if (av7110->trickmode == TRICK_FAST)
1142 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1143 __Scan_I, 2, AV_PES, 0);
1144 if (av7110->trickmode == TRICK_SLOW) {
1145 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1146 __Slow, 2, 0, 0);
1147 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1148 }
1149 if (av7110->trickmode == TRICK_FREEZE)
1150 vidcom(av7110, VIDEO_CMD_STOP, 1);
1151 }
1152 break;
1153
1154 case VIDEO_SET_STREAMTYPE:
1155
1156 break;
1157
1158 default:
1159 ret = -ENOIOCTLCMD;
1160 break;
1161 }
1162 return ret;
1163}
1164
1165static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1166 unsigned int cmd, void *parg)
1167{
1168 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1169 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1170 unsigned long arg = (unsigned long) parg;
1171 int ret = 0;
1172
1173 dprintk(2, "av7110:%p, \n", av7110);
1174
1175 if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
1176 (cmd != AUDIO_GET_STATUS))
1177 return -EPERM;
1178
1179 switch (cmd) {
1180 case AUDIO_STOP:
1181 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1182 av7110_av_stop(av7110, RP_AUDIO);
1183 else
1184 audcom(av7110, AUDIO_CMD_MUTE);
1185 av7110->audiostate.play_state = AUDIO_STOPPED;
1186 break;
1187
1188 case AUDIO_PLAY:
1189 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1190 av7110_av_start_play(av7110, RP_AUDIO);
1191 audcom(av7110, AUDIO_CMD_UNMUTE);
1192 av7110->audiostate.play_state = AUDIO_PLAYING;
1193 break;
1194
1195 case AUDIO_PAUSE:
1196 audcom(av7110, AUDIO_CMD_MUTE);
1197 av7110->audiostate.play_state = AUDIO_PAUSED;
1198 break;
1199
1200 case AUDIO_CONTINUE:
1201 if (av7110->audiostate.play_state == AUDIO_PAUSED) {
1202 av7110->audiostate.play_state = AUDIO_PLAYING;
1203 audcom(av7110, AUDIO_CMD_MUTE | AUDIO_CMD_PCM16);
1204 }
1205 break;
1206
1207 case AUDIO_SELECT_SOURCE:
1208 av7110->audiostate.stream_source = (audio_stream_source_t) arg;
1209 break;
1210
1211 case AUDIO_SET_MUTE:
1212 {
1213 audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
1214 av7110->audiostate.mute_state = (int) arg;
1215 break;
1216 }
1217
1218 case AUDIO_SET_AV_SYNC:
1219 av7110->audiostate.AV_sync_state = (int) arg;
1220 audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
1221 break;
1222
1223 case AUDIO_SET_BYPASS_MODE:
1224 ret = -EINVAL;
1225 break;
1226
1227 case AUDIO_CHANNEL_SELECT:
1228 av7110->audiostate.channel_select = (audio_channel_select_t) arg;
1229
1230 switch(av7110->audiostate.channel_select) {
1231 case AUDIO_STEREO:
1232 audcom(av7110, AUDIO_CMD_STEREO);
1233 break;
1234
1235 case AUDIO_MONO_LEFT:
1236 audcom(av7110, AUDIO_CMD_MONO_L);
1237 break;
1238
1239 case AUDIO_MONO_RIGHT:
1240 audcom(av7110, AUDIO_CMD_MONO_R);
1241 break;
1242
1243 default:
1244 ret = -EINVAL;
1245 break;
1246 }
1247 break;
1248
1249 case AUDIO_GET_STATUS:
1250 memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
1251 break;
1252
1253 case AUDIO_GET_CAPABILITIES:
1254 *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1255 break;
1256
1257 case AUDIO_CLEAR_BUFFER:
1258 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1259 av7110_ipack_reset(&av7110->ipack[0]);
1260 if (av7110->playing == RP_AV)
1261 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1262 __Play, 2, AV_PES, 0);
1263 break;
1264 case AUDIO_SET_ID:
1265
1266 break;
1267 case AUDIO_SET_MIXER:
1268 {
1269 struct audio_mixer *amix = (struct audio_mixer *)parg;
1270
1271 av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
1272 break;
1273 }
1274 case AUDIO_SET_STREAMTYPE:
1275 break;
1276 default:
1277 ret = -ENOIOCTLCMD;
1278 }
1279 return ret;
1280}
1281
1282
1283static int dvb_video_open(struct inode *inode, struct file *file)
1284{
1285 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1286 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1287 int err;
1288
1289 dprintk(2, "av7110:%p, \n", av7110);
1290
1291 if ((err = dvb_generic_open(inode, file)) < 0)
1292 return err;
1293
1294 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1295 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1296 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1297 av7110->video_blank = 1;
1298 av7110->audiostate.AV_sync_state = 1;
1299 av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1300
1301 /* empty event queue */
1302 av7110->video_events.eventr = av7110->video_events.eventw = 0;
1303 }
1304
1305 return 0;
1306}
1307
1308static int dvb_video_release(struct inode *inode, struct file *file)
1309{
1310 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1311 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1312
1313 dprintk(2, "av7110:%p, \n", av7110);
1314
1315 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1316 av7110_av_stop(av7110, RP_VIDEO);
1317 }
1318
1319 return dvb_generic_release(inode, file);
1320}
1321
1322static int dvb_audio_open(struct inode *inode, struct file *file)
1323{
1324 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1325 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1326 int err=dvb_generic_open(inode, file);
1327
1328 dprintk(2, "av7110:%p, \n", av7110);
1329
1330 if (err < 0)
1331 return err;
1332 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1333 av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1334 return 0;
1335}
1336
1337static int dvb_audio_release(struct inode *inode, struct file *file)
1338{
1339 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1340 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1341
1342 dprintk(2, "av7110:%p, \n", av7110);
1343
1344 av7110_av_stop(av7110, RP_AUDIO);
1345 return dvb_generic_release(inode, file);
1346}
1347
1348
1349
1350/******************************************************************************
1351 * driver registration
1352 ******************************************************************************/
1353
1354static struct file_operations dvb_video_fops = {
1355 .owner = THIS_MODULE,
1356 .write = dvb_video_write,
1357 .ioctl = dvb_generic_ioctl,
1358 .open = dvb_video_open,
1359 .release = dvb_video_release,
1360 .poll = dvb_video_poll,
1361};
1362
1363static struct dvb_device dvbdev_video = {
1364 .priv = NULL,
1365 .users = 6,
1366 .readers = 5, /* arbitrary */
1367 .writers = 1,
1368 .fops = &dvb_video_fops,
1369 .kernel_ioctl = dvb_video_ioctl,
1370};
1371
1372static struct file_operations dvb_audio_fops = {
1373 .owner = THIS_MODULE,
1374 .write = dvb_audio_write,
1375 .ioctl = dvb_generic_ioctl,
1376 .open = dvb_audio_open,
1377 .release = dvb_audio_release,
1378 .poll = dvb_audio_poll,
1379};
1380
1381static struct dvb_device dvbdev_audio = {
1382 .priv = NULL,
1383 .users = 1,
1384 .writers = 1,
1385 .fops = &dvb_audio_fops,
1386 .kernel_ioctl = dvb_audio_ioctl,
1387};
1388
1389
1390int av7110_av_register(struct av7110 *av7110)
1391{
1392 av7110->audiostate.AV_sync_state = 0;
1393 av7110->audiostate.mute_state = 0;
1394 av7110->audiostate.play_state = AUDIO_STOPPED;
1395 av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1396 av7110->audiostate.channel_select = AUDIO_STEREO;
1397 av7110->audiostate.bypass_mode = 0;
1398
1399 av7110->videostate.video_blank = 0;
1400 av7110->videostate.play_state = VIDEO_STOPPED;
1401 av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1402 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
1403 av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT;
1404 av7110->display_ar = VIDEO_FORMAT_4_3;
1405
1406 init_waitqueue_head(&av7110->video_events.wait_queue);
1407 spin_lock_init(&av7110->video_events.lock);
1408 av7110->video_events.eventw = av7110->video_events.eventr = 0;
1409 av7110->video_events.overflow = 0;
1410 memset(&av7110->video_size, 0, sizeof (video_size_t));
1411
1412 dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
1413 &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
1414
1415 dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
1416 &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
1417
1418 return 0;
1419}
1420
1421void av7110_av_unregister(struct av7110 *av7110)
1422{
1423 dvb_unregister_device(av7110->audio_dev);
1424 dvb_unregister_device(av7110->video_dev);
1425}
1426
1427int av7110_av_init(struct av7110 *av7110)
1428{
1429 void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
1430 int i, ret;
1431
1432 av7110->vidmode = VIDEO_MODE_PAL;
1433
1434 for (i = 0; i < 2; i++) {
1435 struct ipack *ipack = av7110->ipack + i;
1436
1437 ret = av7110_ipack_init(ipack, IPACKS, play[i]);
1438 if (ret < 0) {
1439 if (i)
1440 av7110_ipack_free(--ipack);
1441 goto out;
1442 }
1443 ipack->data = av7110;
1444 }
1445
1446 dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
1447 dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);
1448
1449 av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);
1450 av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;
1451out:
1452 return ret;
1453}
1454
1455void av7110_av_exit(struct av7110 *av7110)
1456{
1457 av7110_ipack_free(&av7110->ipack[0]);
1458 av7110_ipack_free(&av7110->ipack[1]);
1459}
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
new file mode 100644
index 000000000000..cc5e7a7e87c3
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_av.h
@@ -0,0 +1,29 @@
1#ifndef _AV7110_AV_H_
2#define _AV7110_AV_H_
3
4struct av7110;
5
6extern void av7110_set_vidmode(struct av7110 *av7110, int mode);
7
8extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
9extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
10extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
11
12extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
13extern void av7110_av_stop(struct av7110 *av7110, int av);
14extern int av7110_av_start_record(struct av7110 *av7110, int av,
15 struct dvb_demux_feed *dvbdmxfeed);
16extern int av7110_av_start_play(struct av7110 *av7110, int av);
17
18extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
19
20extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
21extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
22
23extern int av7110_av_register(struct av7110 *av7110);
24extern void av7110_av_unregister(struct av7110 *av7110);
25extern int av7110_av_init(struct av7110 *av7110);
26extern void av7110_av_exit(struct av7110 *av7110);
27
28
29#endif /* _AV7110_AV_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
new file mode 100644
index 000000000000..21f7aacf7726
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -0,0 +1,390 @@
1/*
2 * av7110_ca.c: CA and CI stuff
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 *
27 *
28 * the project's page is at http://www.linuxtv.org/dvb/
29 */
30
31#include <linux/kernel.h>
32#include <linux/sched.h>
33#include <linux/types.h>
34#include <linux/delay.h>
35#include <linux/fs.h>
36#include <linux/timer.h>
37#include <linux/poll.h>
38#include <linux/byteorder/swabb.h>
39#include <linux/smp_lock.h>
40
41#include "av7110.h"
42#include "av7110_hw.h"
43
44
45void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
46{
47 dprintk(8, "av7110:%p\n",av7110);
48
49 if (len < 3)
50 return;
51 switch (data[0]) {
52 case CI_MSG_CI_INFO:
53 if (data[2] != 1 && data[2] != 2)
54 break;
55 switch (data[1]) {
56 case 0:
57 av7110->ci_slot[data[2] - 1].flags = 0;
58 break;
59 case 1:
60 av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT;
61 break;
62 case 2:
63 av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY;
64 break;
65 }
66 break;
67 case CI_SWITCH_PRG_REPLY:
68 //av7110->ci_stat=data[1];
69 break;
70 default:
71 break;
72 }
73}
74
75
76void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
77{
78 if (dvb_ringbuffer_free(cibuf) < len + 2)
79 return;
80
81 DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8);
82 DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff);
83 dvb_ringbuffer_write(cibuf, data, len);
84 wake_up_interruptible(&cibuf->queue);
85}
86
87
88/******************************************************************************
89 * CI link layer file ops
90 ******************************************************************************/
91
92static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
93{
94 struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p;
95 void *data;
96
97 for (p = tab; *p; p++) {
98 data = vmalloc(size);
99 if (!data) {
100 while (p-- != tab) {
101 vfree(p[0]->data);
102 p[0]->data = NULL;
103 }
104 return -ENOMEM;
105 }
106 dvb_ringbuffer_init(*p, data, size);
107 }
108 return 0;
109}
110
111static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
112{
113 dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
114 dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
115}
116
117static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
118{
119 vfree(cirbuf->data);
120 cirbuf->data = NULL;
121 vfree(ciwbuf->data);
122 ciwbuf->data = NULL;
123}
124
125static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
126 int slots, ca_slot_info_t *slot)
127{
128 int i;
129 int len = 0;
130 u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 };
131
132 for (i = 0; i < 2; i++) {
133 if (slots & (1 << i))
134 len += 8;
135 }
136
137 if (dvb_ringbuffer_free(cibuf) < len)
138 return -EBUSY;
139
140 for (i = 0; i < 2; i++) {
141 if (slots & (1 << i)) {
142 msg[2] = i;
143 dvb_ringbuffer_write(cibuf, msg, 8);
144 slot[i].flags = 0;
145 }
146 }
147
148 return 0;
149}
150
151static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file,
152 const char __user *buf, size_t count, loff_t *ppos)
153{
154 int free;
155 int non_blocking = file->f_flags & O_NONBLOCK;
156 char *page = (char *)__get_free_page(GFP_USER);
157 int res;
158
159 if (!page)
160 return -ENOMEM;
161
162 res = -EINVAL;
163 if (count > 2048)
164 goto out;
165
166 res = -EFAULT;
167 if (copy_from_user(page, buf, count))
168 goto out;
169
170 free = dvb_ringbuffer_free(cibuf);
171 if (count + 2 > free) {
172 res = -EWOULDBLOCK;
173 if (non_blocking)
174 goto out;
175 res = -ERESTARTSYS;
176 if (wait_event_interruptible(cibuf->queue,
177 (dvb_ringbuffer_free(cibuf) >= count + 2)))
178 goto out;
179 }
180
181 DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8);
182 DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff);
183
184 res = dvb_ringbuffer_write(cibuf, page, count);
185out:
186 free_page((unsigned long)page);
187 return res;
188}
189
190static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
191 char __user *buf, size_t count, loff_t *ppos)
192{
193 int avail;
194 int non_blocking = file->f_flags & O_NONBLOCK;
195 ssize_t len;
196
197 if (!cibuf->data || !count)
198 return 0;
199 if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
200 return -EWOULDBLOCK;
201 if (wait_event_interruptible(cibuf->queue,
202 !dvb_ringbuffer_empty(cibuf)))
203 return -ERESTARTSYS;
204 avail = dvb_ringbuffer_avail(cibuf);
205 if (avail < 4)
206 return 0;
207 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
208 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
209 if (avail < len + 2 || count < len)
210 return -EINVAL;
211 DVB_RINGBUFFER_SKIP(cibuf, 2);
212
213 return dvb_ringbuffer_read(cibuf, buf, len, 1);
214}
215
216static int dvb_ca_open(struct inode *inode, struct file *file)
217{
218 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
219 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
220 int err = dvb_generic_open(inode, file);
221
222 dprintk(8, "av7110:%p\n",av7110);
223
224 if (err < 0)
225 return err;
226 ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
227 return 0;
228}
229
230static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
231{
232 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
233 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
234 struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
235 struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
236 unsigned int mask = 0;
237
238 dprintk(8, "av7110:%p\n",av7110);
239
240 poll_wait(file, &rbuf->queue, wait);
241 poll_wait(file, &wbuf->queue, wait);
242
243 if (!dvb_ringbuffer_empty(rbuf))
244 mask |= (POLLIN | POLLRDNORM);
245
246 if (dvb_ringbuffer_free(wbuf) > 1024)
247 mask |= (POLLOUT | POLLWRNORM);
248
249 return mask;
250}
251
252static int dvb_ca_ioctl(struct inode *inode, struct file *file,
253 unsigned int cmd, void *parg)
254{
255 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
256 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
257 unsigned long arg = (unsigned long) parg;
258
259 dprintk(8, "av7110:%p\n",av7110);
260
261 switch (cmd) {
262 case CA_RESET:
263 return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]);
264 break;
265 case CA_GET_CAP:
266 {
267 ca_caps_t cap;
268
269 cap.slot_num = 2;
270 cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ?
271 CA_CI_LINK : CA_CI) | CA_DESCR;
272 cap.descr_num = 16;
273 cap.descr_type = CA_ECD;
274 memcpy(parg, &cap, sizeof(cap));
275 break;
276 }
277
278 case CA_GET_SLOT_INFO:
279 {
280 ca_slot_info_t *info=(ca_slot_info_t *)parg;
281
282 if (info->num > 1)
283 return -EINVAL;
284 av7110->ci_slot[info->num].num = info->num;
285 av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
286 CA_CI_LINK : CA_CI;
287 memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
288 break;
289 }
290
291 case CA_GET_MSG:
292 break;
293
294 case CA_SEND_MSG:
295 break;
296
297 case CA_GET_DESCR_INFO:
298 {
299 ca_descr_info_t info;
300
301 info.num = 16;
302 info.type = CA_ECD;
303 memcpy(parg, &info, sizeof (info));
304 break;
305 }
306
307 case CA_SET_DESCR:
308 {
309 ca_descr_t *descr = (ca_descr_t*) parg;
310
311 if (descr->index >= 16)
312 return -EINVAL;
313 if (descr->parity > 1)
314 return -EINVAL;
315 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
316 (descr->index<<8)|descr->parity,
317 (descr->cw[0]<<8)|descr->cw[1],
318 (descr->cw[2]<<8)|descr->cw[3],
319 (descr->cw[4]<<8)|descr->cw[5],
320 (descr->cw[6]<<8)|descr->cw[7]);
321 break;
322 }
323
324 default:
325 return -EINVAL;
326 }
327 return 0;
328}
329
330static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
331 size_t count, loff_t *ppos)
332{
333 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
334 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
335
336 dprintk(8, "av7110:%p\n",av7110);
337 return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
338}
339
340static ssize_t dvb_ca_read(struct file *file, char __user *buf,
341 size_t count, loff_t *ppos)
342{
343 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
344 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
345
346 dprintk(8, "av7110:%p\n",av7110);
347 return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
348}
349
350
351
352static struct file_operations dvb_ca_fops = {
353 .owner = THIS_MODULE,
354 .read = dvb_ca_read,
355 .write = dvb_ca_write,
356 .ioctl = dvb_generic_ioctl,
357 .open = dvb_ca_open,
358 .release = dvb_generic_release,
359 .poll = dvb_ca_poll,
360};
361
362static struct dvb_device dvbdev_ca = {
363 .priv = NULL,
364 .users = 1,
365 .writers = 1,
366 .fops = &dvb_ca_fops,
367 .kernel_ioctl = dvb_ca_ioctl,
368};
369
370
371int av7110_ca_register(struct av7110 *av7110)
372{
373 return dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev,
374 &dvbdev_ca, av7110, DVB_DEVICE_CA);
375}
376
377void av7110_ca_unregister(struct av7110 *av7110)
378{
379 dvb_unregister_device(av7110->ca_dev);
380}
381
382int av7110_ca_init(struct av7110* av7110)
383{
384 return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
385}
386
387void av7110_ca_exit(struct av7110* av7110)
388{
389 ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
390}
diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/dvb/ttpci/av7110_ca.h
new file mode 100644
index 000000000000..70ee855ece1b
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ca.h
@@ -0,0 +1,14 @@
1#ifndef _AV7110_CA_H_
2#define _AV7110_CA_H_
3
4struct av7110;
5
6extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
7extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
8
9extern int av7110_ca_register(struct av7110 *av7110);
10extern void av7110_ca_unregister(struct av7110 *av7110);
11extern int av7110_ca_init(struct av7110* av7110);
12extern void av7110_ca_exit(struct av7110* av7110);
13
14#endif /* _AV7110_CA_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
new file mode 100644
index 000000000000..bd6e5ea4aefe
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -0,0 +1,1170 @@
1/*
2 * av7110_hw.c: av7110 low level hardware access and firmware interface
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24 *
25 * the project's page is at http://www.linuxtv.org/dvb/
26 */
27
28/* for debugging ARM communication: */
29//#define COM_DEBUG
30
31#include <stdarg.h>
32#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/string.h>
35#include <linux/sched.h>
36#include <linux/delay.h>
37#include <linux/byteorder/swabb.h>
38#include <linux/smp_lock.h>
39#include <linux/fs.h>
40
41#include "av7110.h"
42#include "av7110_hw.h"
43
44/****************************************************************************
45 * DEBI functions
46 ****************************************************************************/
47
48/* This DEBI code is based on the Stradis driver
49 by Nathan Laredo <laredo@gnu.org> */
50
51int av7110_debiwrite(struct av7110 *av7110, u32 config,
52 int addr, u32 val, int count)
53{
54 struct saa7146_dev *dev = av7110->dev;
55
56 if (count <= 0 || count > 32764) {
57 printk("%s: invalid count %d\n", __FUNCTION__, count);
58 return -1;
59 }
60 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
61 printk("%s: wait_for_debi_done failed\n", __FUNCTION__);
62 return -1;
63 }
64 saa7146_write(dev, DEBI_CONFIG, config);
65 if (count <= 4) /* immediate transfer */
66 saa7146_write(dev, DEBI_AD, val);
67 else /* block transfer */
68 saa7146_write(dev, DEBI_AD, av7110->debi_bus);
69 saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
70 saa7146_write(dev, MC2, (2 << 16) | 2);
71 return 0;
72}
73
74u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
75{
76 struct saa7146_dev *dev = av7110->dev;
77 u32 result = 0;
78
79 if (count > 32764 || count <= 0) {
80 printk("%s: invalid count %d\n", __FUNCTION__, count);
81 return 0;
82 }
83 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
84 printk("%s: wait_for_debi_done #1 failed\n", __FUNCTION__);
85 return 0;
86 }
87 saa7146_write(dev, DEBI_AD, av7110->debi_bus);
88 saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
89
90 saa7146_write(dev, DEBI_CONFIG, config);
91 saa7146_write(dev, MC2, (2 << 16) | 2);
92 if (count > 4)
93 return count;
94 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
95 printk("%s: wait_for_debi_done #2 failed\n", __FUNCTION__);
96 return 0;
97 }
98
99 result = saa7146_read(dev, DEBI_AD);
100 result &= (0xffffffffUL >> ((4 - count) * 8));
101 return result;
102}
103
104
105
106/* av7110 ARM core boot stuff */
107
108void av7110_reset_arm(struct av7110 *av7110)
109{
110 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
111
112 /* Disable DEBI and GPIO irq */
113 SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
114 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
115
116 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
117 msleep(30); /* the firmware needs some time to initialize */
118
119 ARM_ResetMailBox(av7110);
120
121 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
122 SAA7146_IER_ENABLE(av7110->dev, MASK_03);
123
124 av7110->arm_ready = 1;
125 dprintk(1, "reset ARM\n");
126}
127
128
129static int waitdebi(struct av7110 *av7110, int adr, int state)
130{
131 int k;
132
133 dprintk(4, "%p\n", av7110);
134
135 for (k = 0; k < 100; k++) {
136 if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
137 return 0;
138 udelay(5);
139 }
140 return -1;
141}
142
143static int load_dram(struct av7110 *av7110, u32 *data, int len)
144{
145 int i;
146 int blocks, rest;
147 u32 base, bootblock = BOOT_BLOCK;
148
149 dprintk(4, "%p\n", av7110);
150
151 blocks = len / BOOT_MAX_SIZE;
152 rest = len % BOOT_MAX_SIZE;
153 base = DRAM_START_CODE;
154
155 for (i = 0; i < blocks; i++) {
156 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
157 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
158 return -1;
159 }
160 dprintk(4, "writing DRAM block %d\n", i);
161 mwdebi(av7110, DEBISWAB, bootblock,
162 ((char*)data) + i * BOOT_MAX_SIZE, BOOT_MAX_SIZE);
163 bootblock ^= 0x1400;
164 iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
165 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, BOOT_MAX_SIZE, 2);
166 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
167 base += BOOT_MAX_SIZE;
168 }
169
170 if (rest > 0) {
171 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
172 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
173 return -1;
174 }
175 if (rest > 4)
176 mwdebi(av7110, DEBISWAB, bootblock,
177 ((char*)data) + i * BOOT_MAX_SIZE, rest);
178 else
179 mwdebi(av7110, DEBISWAB, bootblock,
180 ((char*)data) + i * BOOT_MAX_SIZE - 4, rest + 4);
181
182 iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
183 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, rest, 2);
184 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
185 }
186 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
187 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
188 return -1;
189 }
190 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
191 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
192 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
193 printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
194 return -1;
195 }
196 return 0;
197}
198
199
200/* we cannot write av7110 DRAM directly, so load a bootloader into
201 * the DPRAM which implements a simple boot protocol */
202static u8 bootcode[] = {
203 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04,
204 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04,
205 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24,
206 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34,
207 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55,
208 0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74,
209 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04,
210 0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64,
211 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02,
212 0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0,
213 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d,
214 0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f,
215 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0,
216 0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0,
217 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01,
218 0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec,
219 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00,
220 0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0
221};
222
223int av7110_bootarm(struct av7110 *av7110)
224{
225 struct saa7146_dev *dev = av7110->dev;
226 u32 ret;
227 int i;
228
229 dprintk(4, "%p\n", av7110);
230
231 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
232
233 /* Disable DEBI and GPIO irq */
234 SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
235 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
236
237 /* enable DEBI */
238 saa7146_write(av7110->dev, MC1, 0x08800880);
239 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
240 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
241
242 /* test DEBI */
243 iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
244 if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
245 printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
246 "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
247 ret, 0x10325476);
248 return -1;
249 }
250 for (i = 0; i < 8192; i += 4)
251 iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
252 dprintk(2, "debi test OK\n");
253
254 /* boot */
255 dprintk(1, "load boot code\n");
256 saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
257 //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
258 //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
259
260 mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
261 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
262
263 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
264 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
265 "saa7146_wait_for_debi_done() timed out\n");
266 return -1;
267 }
268 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
269 mdelay(1);
270
271 dprintk(1, "load dram code\n");
272 if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
273 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
274 "load_dram() failed\n");
275 return -1;
276 }
277
278 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
279 mdelay(1);
280
281 dprintk(1, "load dpram code\n");
282 mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
283
284 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
285 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
286 "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
287 return -1;
288 }
289 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
290 msleep(30); /* the firmware needs some time to initialize */
291
292 //ARM_ClearIrq(av7110);
293 ARM_ResetMailBox(av7110);
294 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
295 SAA7146_IER_ENABLE(av7110->dev, MASK_03);
296
297 av7110->arm_errors = 0;
298 av7110->arm_ready = 1;
299 return 0;
300}
301
302
303/****************************************************************************
304 * DEBI command polling
305 ****************************************************************************/
306
307int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
308{
309 unsigned long start;
310 u32 stat;
311
312 if (FW_VERSION(av7110->arm_app) <= 0x261c) {
313 /* not supported by old firmware */
314 msleep(50);
315 return 0;
316 }
317
318 /* new firmware */
319 start = jiffies;
320 for (;;) {
321 if (down_interruptible(&av7110->dcomlock))
322 return -ERESTARTSYS;
323 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
324 up(&av7110->dcomlock);
325 if ((stat & flags) == 0) {
326 break;
327 }
328 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
329 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
330 __FUNCTION__, stat & flags);
331 return -1;
332 }
333 msleep(1);
334 }
335 return 0;
336}
337
338int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
339{
340 int i;
341 unsigned long start;
342 char *type = NULL;
343 u16 flags[2] = {0, 0};
344 u32 stat;
345
346// dprintk(4, "%p\n", av7110);
347
348 if (!av7110->arm_ready) {
349 dprintk(1, "arm not ready.\n");
350 return -ENXIO;
351 }
352
353 start = jiffies;
354 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
355 msleep(1);
356 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
357 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
358 return -ETIMEDOUT;
359 }
360 }
361
362 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
363
364#ifndef _NOHANDSHAKE
365 start = jiffies;
366 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
367 msleep(1);
368 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
369 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
370 return -ETIMEDOUT;
371 }
372 }
373#endif
374
375 switch ((buf[0] >> 8) & 0xff) {
376 case COMTYPE_PIDFILTER:
377 case COMTYPE_ENCODER:
378 case COMTYPE_REC_PLAY:
379 case COMTYPE_MPEGDECODER:
380 type = "MSG";
381 flags[0] = GPMQOver;
382 flags[1] = GPMQFull;
383 break;
384 case COMTYPE_OSD:
385 type = "OSD";
386 flags[0] = OSDQOver;
387 flags[1] = OSDQFull;
388 break;
389 case COMTYPE_MISC:
390 if (FW_VERSION(av7110->arm_app) >= 0x261d) {
391 type = "MSG";
392 flags[0] = GPMQOver;
393 flags[1] = GPMQBusy;
394 }
395 break;
396 default:
397 break;
398 }
399
400 if (type != NULL) {
401 /* non-immediate COMMAND type */
402 start = jiffies;
403 for (;;) {
404 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
405 if (stat & flags[0]) {
406 printk(KERN_ERR "%s: %s QUEUE overflow\n",
407 __FUNCTION__, type);
408 return -1;
409 }
410 if ((stat & flags[1]) == 0)
411 break;
412 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
413 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
414 __FUNCTION__, type);
415 return -1;
416 }
417 msleep(1);
418 }
419 }
420
421 for (i = 2; i < length; i++)
422 wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
423
424 if (length)
425 wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
426 else
427 wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
428
429 wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
430
431 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
432
433#ifdef COM_DEBUG
434 start = jiffies;
435 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
436 msleep(1);
437 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
438 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
439 __FUNCTION__);
440 return -ETIMEDOUT;
441 }
442 }
443
444 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
445 if (stat & GPMQOver) {
446 printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__);
447 return -ENOSPC;
448 }
449 else if (stat & OSDQOver) {
450 printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__);
451 return -ENOSPC;
452 }
453#endif
454
455 return 0;
456}
457
458int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
459{
460 int ret;
461
462// dprintk(4, "%p\n", av7110);
463
464 if (!av7110->arm_ready) {
465 dprintk(1, "arm not ready.\n");
466 return -1;
467 }
468 if (down_interruptible(&av7110->dcomlock))
469 return -ERESTARTSYS;
470
471 ret = __av7110_send_fw_cmd(av7110, buf, length);
472 up(&av7110->dcomlock);
473 if (ret)
474 printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
475 __FUNCTION__, ret);
476 return ret;
477}
478
479int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
480{
481 va_list args;
482 u16 buf[num + 2];
483 int i, ret;
484
485// dprintk(4, "%p\n", av7110);
486
487 buf[0] = ((type << 8) | com);
488 buf[1] = num;
489
490 if (num) {
491 va_start(args, num);
492 for (i = 0; i < num; i++)
493 buf[i + 2] = va_arg(args, u32);
494 va_end(args);
495 }
496
497 ret = av7110_send_fw_cmd(av7110, buf, num + 2);
498 if (ret)
499 printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
500 return ret;
501}
502
503int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
504{
505 int i, ret;
506 u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
507 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
508
509 dprintk(4, "%p\n", av7110);
510
511 for(i = 0; i < len && i < 32; i++)
512 {
513 if(i % 2 == 0)
514 cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
515 else
516 cmd[(i / 2) + 2] |= buf[i];
517 }
518
519 ret = av7110_send_fw_cmd(av7110, cmd, 18);
520 if (ret)
521 printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
522 return ret;
523}
524
525int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
526 int request_buf_len, u16 *reply_buf, int reply_buf_len)
527{
528 int err;
529 s16 i;
530 unsigned long start;
531#ifdef COM_DEBUG
532 u32 stat;
533#endif
534
535 dprintk(4, "%p\n", av7110);
536
537 if (!av7110->arm_ready) {
538 dprintk(1, "arm not ready.\n");
539 return -1;
540 }
541
542 if (down_interruptible(&av7110->dcomlock))
543 return -ERESTARTSYS;
544
545 if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
546 up(&av7110->dcomlock);
547 printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
548 return err;
549 }
550
551 start = jiffies;
552 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
553#ifdef _NOHANDSHAKE
554 msleep(1);
555#endif
556 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
557 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
558 up(&av7110->dcomlock);
559 return -1;
560 }
561 }
562
563#ifndef _NOHANDSHAKE
564 start = jiffies;
565 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
566 msleep(1);
567 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
568 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
569 up(&av7110->dcomlock);
570 return -1;
571 }
572 }
573#endif
574
575#ifdef COM_DEBUG
576 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
577 if (stat & GPMQOver) {
578 printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
579 up(&av7110->dcomlock);
580 return -1;
581 }
582 else if (stat & OSDQOver) {
583 printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
584 up(&av7110->dcomlock);
585 return -1;
586 }
587#endif
588
589 for (i = 0; i < reply_buf_len; i++)
590 reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
591
592 up(&av7110->dcomlock);
593 return 0;
594}
595
596int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
597{
598 int ret;
599 ret = av7110_fw_request(av7110, &tag, 0, buf, length);
600 if (ret)
601 printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
602 return ret;
603}
604
605
606/****************************************************************************
607 * Firmware commands
608 ****************************************************************************/
609
610/* get version of the firmware ROM, RTSL, video ucode and ARM application */
611int av7110_firmversion(struct av7110 *av7110)
612{
613 u16 buf[20];
614 u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
615
616 dprintk(4, "%p\n", av7110);
617
618 if (av7110_fw_query(av7110, tag, buf, 16)) {
619 printk("dvb-ttpci: failed to boot firmware @ card %d\n",
620 av7110->dvb_adapter->num);
621 return -EIO;
622 }
623
624 av7110->arm_fw = (buf[0] << 16) + buf[1];
625 av7110->arm_rtsl = (buf[2] << 16) + buf[3];
626 av7110->arm_vid = (buf[4] << 16) + buf[5];
627 av7110->arm_app = (buf[6] << 16) + buf[7];
628 av7110->avtype = (buf[8] << 16) + buf[9];
629
630 printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
631 av7110->dvb_adapter->num, av7110->arm_fw,
632 av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
633
634 /* print firmware capabilities */
635 if (FW_CI_LL_SUPPORT(av7110->arm_app))
636 printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
637 av7110->dvb_adapter->num);
638 else
639 printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
640 av7110->dvb_adapter->num);
641
642 return 0;
643}
644
645
646int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
647{
648 int i, ret;
649 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
650 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
651
652 dprintk(4, "%p\n", av7110);
653
654 if (len > 10)
655 len = 10;
656
657 buf[1] = len + 2;
658 buf[2] = len;
659
660 if (burst != -1)
661 buf[3] = burst ? 0x01 : 0x00;
662 else
663 buf[3] = 0xffff;
664
665 for (i = 0; i < len; i++)
666 buf[i + 4] = msg[i];
667
668 if ((ret = av7110_send_fw_cmd(av7110, buf, 18)))
669 printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
670
671 return 0;
672}
673
674
675#ifdef CONFIG_DVB_AV7110_OSD
676
677static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
678{
679 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
680}
681
682static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
683 enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
684{
685 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
686 windownr, colordepth, index, blending);
687}
688
689static inline int SetColor_(struct av7110 *av7110, u8 windownr,
690 enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
691{
692 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
693 windownr, colordepth, index, colorhi, colorlo);
694}
695
696static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
697 u16 colorfg, u16 colorbg)
698{
699 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
700 windownr, fontsize, colorfg, colorbg);
701}
702
703static int FlushText(struct av7110 *av7110)
704{
705 unsigned long start;
706
707 if (down_interruptible(&av7110->dcomlock))
708 return -ERESTARTSYS;
709 start = jiffies;
710 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
711 msleep(1);
712 if (time_after(jiffies, start + ARM_WAIT_OSD)) {
713 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
714 __FUNCTION__);
715 up(&av7110->dcomlock);
716 return -1;
717 }
718 }
719 up(&av7110->dcomlock);
720 return 0;
721}
722
723static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
724{
725 int i, ret;
726 unsigned long start;
727 int length = strlen(buf) + 1;
728 u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
729
730 if (down_interruptible(&av7110->dcomlock))
731 return -ERESTARTSYS;
732
733 start = jiffies;
734 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
735 msleep(1);
736 if (time_after(jiffies, start + ARM_WAIT_OSD)) {
737 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
738 __FUNCTION__);
739 up(&av7110->dcomlock);
740 return -1;
741 }
742 }
743#ifndef _NOHANDSHAKE
744 start = jiffies;
745 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
746 msleep(1);
747 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
748 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
749 __FUNCTION__);
750 up(&av7110->dcomlock);
751 return -1;
752 }
753 }
754#endif
755 for (i = 0; i < length / 2; i++)
756 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
757 swab16(*(u16 *)(buf + 2 * i)), 2);
758 if (length & 1)
759 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
760 ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
761 up(&av7110->dcomlock);
762 if (ret)
763 printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
764 return ret;
765}
766
767static inline int DrawLine(struct av7110 *av7110, u8 windownr,
768 u16 x, u16 y, u16 dx, u16 dy, u16 color)
769{
770 return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
771 windownr, x, y, dx, dy, color);
772}
773
774static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
775 u16 x, u16 y, u16 dx, u16 dy, u16 color)
776{
777 return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
778 windownr, x, y, dx, dy, color);
779}
780
781static inline int HideWindow(struct av7110 *av7110, u8 windownr)
782{
783 return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
784}
785
786static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
787{
788 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
789}
790
791static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
792{
793 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
794}
795
796static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
797{
798 return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
799}
800
801static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
802 osd_raw_window_t disptype,
803 u16 width, u16 height)
804{
805 return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
806 windownr, disptype, width, height);
807}
808
809
810static enum av7110_osd_palette_type bpp2pal[8] = {
811 Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
812};
813static osd_raw_window_t bpp2bit[8] = {
814 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
815};
816
817static inline int LoadBitmap(struct av7110 *av7110, u16 format,
818 u16 dx, u16 dy, int inc, u8 __user * data)
819{
820 int bpp;
821 int i;
822 int d, delta;
823 u8 c;
824 int ret;
825
826 dprintk(4, "%p\n", av7110);
827
828 ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
829 if (ret == -ERESTARTSYS || ret == 0) {
830 printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
831 ret, av7110->bmp_state);
832 av7110->bmp_state = BMP_NONE;
833 return -1;
834 }
835 BUG_ON (av7110->bmp_state == BMP_LOADING);
836
837 av7110->bmp_state = BMP_LOADING;
838 if (format == OSD_BITMAP8) {
839 bpp=8; delta = 1;
840 } else if (format == OSD_BITMAP4) {
841 bpp=4; delta = 2;
842 } else if (format == OSD_BITMAP2) {
843 bpp=2; delta = 4;
844 } else if (format == OSD_BITMAP1) {
845 bpp=1; delta = 8;
846 } else {
847 av7110->bmp_state = BMP_NONE;
848 return -1;
849 }
850 av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
851 av7110->bmpp = 0;
852 if (av7110->bmplen > 32768) {
853 av7110->bmp_state = BMP_NONE;
854 return -1;
855 }
856 for (i = 0; i < dy; i++) {
857 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
858 av7110->bmp_state = BMP_NONE;
859 return -1;
860 }
861 }
862 if (format != OSD_BITMAP8) {
863 for (i = 0; i < dx * dy / delta; i++) {
864 c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
865 for (d = delta - 2; d >= 0; d--) {
866 c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
867 << ((delta - d - 1) * bpp));
868 ((u8 *)av7110->bmpbuf)[1024 + i] = c;
869 }
870 }
871 }
872 av7110->bmplen += 1024;
873 dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
874 return av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
875}
876
877static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
878{
879 int ret;
880
881 dprintk(4, "%p\n", av7110);
882
883 BUG_ON (av7110->bmp_state == BMP_NONE);
884
885 ret = wait_event_interruptible_timeout(av7110->bmpq,
886 av7110->bmp_state != BMP_LOADING, 10*HZ);
887 if (ret == -ERESTARTSYS || ret == 0) {
888 printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
889 ret, av7110->bmp_state);
890 av7110->bmp_state = BMP_NONE;
891 return (ret == 0) ? -ETIMEDOUT : ret;
892 }
893
894 BUG_ON (av7110->bmp_state != BMP_LOADED);
895
896 return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
897}
898
899static inline int ReleaseBitmap(struct av7110 *av7110)
900{
901 dprintk(4, "%p\n", av7110);
902
903 if (av7110->bmp_state != BMP_LOADED)
904 return -1;
905 av7110->bmp_state = BMP_NONE;
906 return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
907}
908
909static u32 RGB2YUV(u16 R, u16 G, u16 B)
910{
911 u16 y, u, v;
912 u16 Y, Cr, Cb;
913
914 y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */
915 u = 2048 + B * 8 -(y >> 5); /* Cr 0..4095 */
916 v = 2048 + R * 8 -(y >> 5); /* Cb 0..4095 */
917
918 Y = y / 256;
919 Cb = u / 16;
920 Cr = v / 16;
921
922 return Cr | (Cb << 16) | (Y << 8);
923}
924
925static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
926{
927 u16 ch, cl;
928 u32 yuv;
929
930 yuv = blend ? RGB2YUV(r,g,b) : 0;
931 cl = (yuv & 0xffff);
932 ch = ((yuv >> 16) & 0xffff);
933 SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
934 color, ch, cl);
935 SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
936 color, ((blend >> 4) & 0x0f));
937}
938
939static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
940{
941 int i;
942 int length = last - first + 1;
943
944 if (length * 4 > DATA_BUFF3_SIZE)
945 return -EINVAL;
946
947 for (i = 0; i < length; i++) {
948 u32 color, blend, yuv;
949
950 if (get_user(color, colors + i))
951 return -EFAULT;
952 blend = (color & 0xF0000000) >> 4;
953 yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
954 (color >> 16) & 0xFF) | blend : 0;
955 yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
956 wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
957 }
958 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
959 av7110->osdwin,
960 bpp2pal[av7110->osdbpp[av7110->osdwin]],
961 first, last);
962}
963
964static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
965 int x1, int y1, int inc, u8 __user * data)
966{
967 uint w, h, bpp, bpl, size, lpb, bnum, brest;
968 int i;
969 int rc;
970
971 w = x1 - x0 + 1;
972 h = y1 - y0 + 1;
973 if (inc <= 0)
974 inc = w;
975 if (w <= 0 || w > 720 || h <= 0 || h > 576)
976 return -1;
977 bpp = av7110->osdbpp[av7110->osdwin] + 1;
978 bpl = ((w * bpp + 7) & ~7) / 8;
979 size = h * bpl;
980 lpb = (32 * 1024) / bpl;
981 bnum = size / (lpb * bpl);
982 brest = size - bnum * lpb * bpl;
983
984 for (i = 0; i < bnum; i++) {
985 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
986 w, lpb, inc, data);
987 if (rc)
988 return rc;
989 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
990 if (rc)
991 return rc;
992 data += lpb * inc;
993 }
994 if (brest) {
995 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
996 w, brest / bpl, inc, data);
997 if (rc)
998 return rc;
999 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
1000 if (rc)
1001 return rc;
1002 }
1003 ReleaseBitmap(av7110);
1004 return 0;
1005}
1006
1007int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
1008{
1009 int ret;
1010
1011 ret = down_interruptible(&av7110->osd_sema);
1012 if (ret)
1013 return -ERESTARTSYS;
1014
1015 /* stupid, but OSD functions don't provide a return code anyway */
1016 ret = 0;
1017
1018 switch (dc->cmd) {
1019 case OSD_Close:
1020 DestroyOSDWindow(av7110, av7110->osdwin);
1021 goto out;
1022 case OSD_Open:
1023 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
1024 CreateOSDWindow(av7110, av7110->osdwin,
1025 bpp2bit[av7110->osdbpp[av7110->osdwin]],
1026 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1027 if (!dc->data) {
1028 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1029 SetColorBlend(av7110, av7110->osdwin);
1030 }
1031 goto out;
1032 case OSD_Show:
1033 MoveWindowRel(av7110, av7110->osdwin, 0, 0);
1034 goto out;
1035 case OSD_Hide:
1036 HideWindow(av7110, av7110->osdwin);
1037 goto out;
1038 case OSD_Clear:
1039 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
1040 goto out;
1041 case OSD_Fill:
1042 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
1043 goto out;
1044 case OSD_SetColor:
1045 OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
1046 goto out;
1047 case OSD_SetPalette:
1048 {
1049 if (FW_VERSION(av7110->arm_app) >= 0x2618) {
1050 ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
1051 goto out;
1052 } else {
1053 int i, len = dc->x0-dc->color+1;
1054 u8 __user *colors = (u8 __user *)dc->data;
1055 u8 r, g, b, blend;
1056
1057 for (i = 0; i<len; i++) {
1058 if (get_user(r, colors + i * 4) ||
1059 get_user(g, colors + i * 4 + 1) ||
1060 get_user(b, colors + i * 4 + 2) ||
1061 get_user(blend, colors + i * 4 + 3)) {
1062 ret = -EFAULT;
1063 goto out;
1064 }
1065 OSDSetColor(av7110, dc->color + i, r, g, b, blend);
1066 }
1067 }
1068 ret = 0;
1069 goto out;
1070 }
1071 case OSD_SetTrans:
1072 goto out;
1073 case OSD_SetPixel:
1074 DrawLine(av7110, av7110->osdwin,
1075 dc->x0, dc->y0, 0, 0, dc->color);
1076 goto out;
1077 case OSD_GetPixel:
1078 goto out;
1079 case OSD_SetRow:
1080 dc->y1 = dc->y0;
1081 /* fall through */
1082 case OSD_SetBlock:
1083 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
1084 goto out;
1085 case OSD_FillRow:
1086 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1087 dc->x1-dc->x0+1, dc->y1, dc->color);
1088 goto out;
1089 case OSD_FillBlock:
1090 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1091 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
1092 goto out;
1093 case OSD_Line:
1094 DrawLine(av7110, av7110->osdwin,
1095 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
1096 goto out;
1097 case OSD_Query:
1098 goto out;
1099 case OSD_Test:
1100 goto out;
1101 case OSD_Text:
1102 {
1103 char textbuf[240];
1104
1105 if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
1106 ret = -EFAULT;
1107 goto out;
1108 }
1109 textbuf[239] = 0;
1110 if (dc->x1 > 3)
1111 dc->x1 = 3;
1112 SetFont(av7110, av7110->osdwin, dc->x1,
1113 (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
1114 FlushText(av7110);
1115 WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
1116 goto out;
1117 }
1118 case OSD_SetWindow:
1119 if (dc->x0 < 1 || dc->x0 > 7) {
1120 ret = -EINVAL;
1121 goto out;
1122 }
1123 av7110->osdwin = dc->x0;
1124 goto out;
1125 case OSD_MoveWindow:
1126 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1127 SetColorBlend(av7110, av7110->osdwin);
1128 goto out;
1129 case OSD_OpenRaw:
1130 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
1131 ret = -EINVAL;
1132 goto out;
1133 }
1134 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) {
1135 av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
1136 }
1137 else {
1138 av7110->osdbpp[av7110->osdwin] = 0;
1139 }
1140 CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
1141 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1142 if (!dc->data) {
1143 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1144 SetColorBlend(av7110, av7110->osdwin);
1145 }
1146 goto out;
1147 default:
1148 ret = -EINVAL;
1149 goto out;
1150 }
1151
1152out:
1153 up(&av7110->osd_sema);
1154 return ret;
1155}
1156
1157int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
1158{
1159 switch (cap->cmd) {
1160 case OSD_CAP_MEMSIZE:
1161 if (FW_4M_SDRAM(av7110->arm_app))
1162 cap->val = 1000000;
1163 else
1164 cap->val = 92000;
1165 return 0;
1166 default:
1167 return -EINVAL;
1168 }
1169}
1170#endif /* CONFIG_DVB_AV7110_OSD */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
new file mode 100644
index 000000000000..bf901c624682
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -0,0 +1,500 @@
1#ifndef _AV7110_HW_H_
2#define _AV7110_HW_H_
3
4#include "av7110.h"
5
6/* DEBI transfer mode defs */
7
8#define DEBINOSWAP 0x000e0000
9#define DEBISWAB 0x001e0000
10#define DEBISWAP 0x002e0000
11
12#define ARM_WAIT_FREE (HZ)
13#define ARM_WAIT_SHAKE (HZ/5)
14#define ARM_WAIT_OSD (HZ)
15
16
17enum av7110_bootstate
18{
19 BOOTSTATE_BUFFER_EMPTY = 0,
20 BOOTSTATE_BUFFER_FULL = 1,
21 BOOTSTATE_BOOT_COMPLETE = 2
22};
23
24enum av7110_type_rec_play_format
25{ RP_None,
26 AudioPES,
27 AudioMp2,
28 AudioPCM,
29 VideoPES,
30 AV_PES
31};
32
33enum av7110_osd_palette_type
34{
35 NoPalet = 0, /* No palette */
36 Pal1Bit = 2, /* 2 colors for 1 Bit Palette */
37 Pal2Bit = 4, /* 4 colors for 2 bit palette */
38 Pal4Bit = 16, /* 16 colors for 4 bit palette */
39 Pal8Bit = 256 /* 256 colors for 16 bit palette */
40};
41
42/* switch defines */
43#define SB_GPIO 3
44#define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */
45#define SB_ON SAA7146_GPIO_INPUT /* SlowBlank on (AV-Mode) */
46#define SB_WIDE SAA7146_GPIO_OUTHI /* SlowBlank 6V (16/9-Mode) (not implemented) */
47
48#define FB_GPIO 1
49#define FB_OFF SAA7146_GPIO_LO /* FastBlank off (CVBS-Mode) */
50#define FB_ON SAA7146_GPIO_OUTHI /* FastBlank on (RGB-Mode) */
51#define FB_LOOP SAA7146_GPIO_INPUT /* FastBlank loop-through (PC graphics ???) */
52
53enum av7110_video_output_mode
54{
55 NO_OUT = 0, /* disable analog output */
56 CVBS_RGB_OUT = 1,
57 CVBS_YC_OUT = 2,
58 YC_OUT = 3
59};
60
61/* firmware internal msg q status: */
62#define GPMQFull 0x0001 /* Main Message Queue Full */
63#define GPMQOver 0x0002 /* Main Message Queue Overflow */
64#define HPQFull 0x0004 /* High Priority Msg Queue Full */
65#define HPQOver 0x0008
66#define OSDQFull 0x0010 /* OSD Queue Full */
67#define OSDQOver 0x0020
68#define GPMQBusy 0x0040 /* Queue not empty, FW >= 261d */
69#define HPQBusy 0x0080
70#define OSDQBusy 0x0100
71
72/* hw section filter flags */
73#define SECTION_EIT 0x01
74#define SECTION_SINGLE 0x00
75#define SECTION_CYCLE 0x02
76#define SECTION_CONTINUOS 0x04
77#define SECTION_MODE 0x06
78#define SECTION_IPMPE 0x0C /* size up to 4k */
79#define SECTION_HIGH_SPEED 0x1C /* larger buffer */
80#define DATA_PIPING_FLAG 0x20 /* for Data Piping Filter */
81
82#define PBUFSIZE_NONE 0x0000
83#define PBUFSIZE_1P 0x0100
84#define PBUFSIZE_2P 0x0200
85#define PBUFSIZE_1K 0x0300
86#define PBUFSIZE_2K 0x0400
87#define PBUFSIZE_4K 0x0500
88#define PBUFSIZE_8K 0x0600
89#define PBUFSIZE_16K 0x0700
90#define PBUFSIZE_32K 0x0800
91
92
93/* firmware command codes */
94enum av7110_osd_command {
95 WCreate,
96 WDestroy,
97 WMoveD,
98 WMoveA,
99 WHide,
100 WTop,
101 DBox,
102 DLine,
103 DText,
104 Set_Font,
105 SetColor,
106 SetBlend,
107 SetWBlend,
108 SetCBlend,
109 SetNonBlend,
110 LoadBmp,
111 BlitBmp,
112 ReleaseBmp,
113 SetWTrans,
114 SetWNoTrans,
115 Set_Palette
116};
117
118enum av7110_pid_command {
119 MultiPID,
120 VideoPID,
121 AudioPID,
122 InitFilt,
123 FiltError,
124 NewVersion,
125 CacheError,
126 AddPIDFilter,
127 DelPIDFilter,
128 Scan,
129 SetDescr,
130 SetIR,
131 FlushTSQueue
132};
133
134enum av7110_mpeg_command {
135 SelAudChannels
136};
137
138enum av7110_audio_command {
139 AudioDAC,
140 CabADAC,
141 ON22K,
142 OFF22K,
143 MainSwitch,
144 ADSwitch,
145 SendDiSEqC,
146 SetRegister
147};
148
149enum av7110_request_command {
150 AudioState,
151 AudioBuffState,
152 VideoState1,
153 VideoState2,
154 VideoState3,
155 CrashCounter,
156 ReqVersion,
157 ReqVCXO,
158 ReqRegister,
159 ReqSecFilterError,
160 ReqSTC
161};
162
163enum av7110_encoder_command {
164 SetVidMode,
165 SetTestMode,
166 LoadVidCode,
167 SetMonitorType,
168 SetPanScanType,
169 SetFreezeMode
170};
171
172enum av7110_rec_play_state {
173 __Record,
174 __Stop,
175 __Play,
176 __Pause,
177 __Slow,
178 __FF_IP,
179 __Scan_I,
180 __Continue
181};
182
183enum av7110_fw_cmd_misc {
184 AV7110_FW_VIDEO_ZOOM = 1,
185 AV7110_FW_VIDEO_COMMAND,
186 AV7110_FW_AUDIO_COMMAND
187};
188
189enum av7110_command_type {
190 COMTYPE_NOCOM,
191 COMTYPE_PIDFILTER,
192 COMTYPE_MPEGDECODER,
193 COMTYPE_OSD,
194 COMTYPE_BMP,
195 COMTYPE_ENCODER,
196 COMTYPE_AUDIODAC,
197 COMTYPE_REQUEST,
198 COMTYPE_SYSTEM,
199 COMTYPE_REC_PLAY,
200 COMTYPE_COMMON_IF,
201 COMTYPE_PID_FILTER,
202 COMTYPE_PES,
203 COMTYPE_TS,
204 COMTYPE_VIDEO,
205 COMTYPE_AUDIO,
206 COMTYPE_CI_LL,
207 COMTYPE_MISC = 0x80
208};
209
210#define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */
211#define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */
212#define VID_VERT_COMP_PREF 0x02 /* Vertical compression display preferred */
213#define VID_VC_AND_PS_PREF 0x03 /* PanScan and vertical Compression if allowed */
214#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */
215
216/* MPEG video decoder commands */
217#define VIDEO_CMD_STOP 0x000e
218#define VIDEO_CMD_PLAY 0x000d
219#define VIDEO_CMD_FREEZE 0x0102
220#define VIDEO_CMD_FFWD 0x0016
221#define VIDEO_CMD_SLOW 0x0022
222
223/* MPEG audio decoder commands */
224#define AUDIO_CMD_MUTE 0x0001
225#define AUDIO_CMD_UNMUTE 0x0002
226#define AUDIO_CMD_PCM16 0x0010
227#define AUDIO_CMD_STEREO 0x0080
228#define AUDIO_CMD_MONO_L 0x0100
229#define AUDIO_CMD_MONO_R 0x0200
230#define AUDIO_CMD_SYNC_OFF 0x000e
231#define AUDIO_CMD_SYNC_ON 0x000f
232
233/* firmware data interface codes */
234#define DATA_NONE 0x00
235#define DATA_FSECTION 0x01
236#define DATA_IPMPE 0x02
237#define DATA_MPEG_RECORD 0x03
238#define DATA_DEBUG_MESSAGE 0x04
239#define DATA_COMMON_INTERFACE 0x05
240#define DATA_MPEG_PLAY 0x06
241#define DATA_BMP_LOAD 0x07
242#define DATA_IRCOMMAND 0x08
243#define DATA_PIPING 0x09
244#define DATA_STREAMING 0x0a
245#define DATA_CI_GET 0x0b
246#define DATA_CI_PUT 0x0c
247#define DATA_MPEG_VIDEO_EVENT 0x0d
248
249#define DATA_PES_RECORD 0x10
250#define DATA_PES_PLAY 0x11
251#define DATA_TS_RECORD 0x12
252#define DATA_TS_PLAY 0x13
253
254/* ancient CI command codes, only two are actually still used
255 * by the link level CI firmware */
256#define CI_CMD_ERROR 0x00
257#define CI_CMD_ACK 0x01
258#define CI_CMD_SYSTEM_READY 0x02
259#define CI_CMD_KEYPRESS 0x03
260#define CI_CMD_ON_TUNED 0x04
261#define CI_CMD_ON_SWITCH_PROGRAM 0x05
262#define CI_CMD_SECTION_ARRIVED 0x06
263#define CI_CMD_SECTION_TIMEOUT 0x07
264#define CI_CMD_TIME 0x08
265#define CI_CMD_ENTER_MENU 0x09
266#define CI_CMD_FAST_PSI 0x0a
267#define CI_CMD_GET_SLOT_INFO 0x0b
268
269#define CI_MSG_NONE 0x00
270#define CI_MSG_CI_INFO 0x01
271#define CI_MSG_MENU 0x02
272#define CI_MSG_LIST 0x03
273#define CI_MSG_TEXT 0x04
274#define CI_MSG_REQUEST_INPUT 0x05
275#define CI_MSG_INPUT_COMPLETE 0x06
276#define CI_MSG_LIST_MORE 0x07
277#define CI_MSG_MENU_MORE 0x08
278#define CI_MSG_CLOSE_MMI_IMM 0x09
279#define CI_MSG_SECTION_REQUEST 0x0a
280#define CI_MSG_CLOSE_FILTER 0x0b
281#define CI_PSI_COMPLETE 0x0c
282#define CI_MODULE_READY 0x0d
283#define CI_SWITCH_PRG_REPLY 0x0e
284#define CI_MSG_TEXT_MORE 0x0f
285
286#define CI_MSG_CA_PMT 0xe0
287#define CI_MSG_ERROR 0xf0
288
289
290/* base address of the dual ported RAM which serves as communication
291 * area between PCI bus and av7110,
292 * as seen by the DEBI bus of the saa7146 */
293#define DPRAM_BASE 0x4000
294
295/* boot protocol area */
296#define BOOT_STATE (DPRAM_BASE + 0x3F8)
297#define BOOT_SIZE (DPRAM_BASE + 0x3FA)
298#define BOOT_BASE (DPRAM_BASE + 0x3FC)
299#define BOOT_BLOCK (DPRAM_BASE + 0x400)
300#define BOOT_MAX_SIZE 0xc00
301
302/* firmware command protocol area */
303#define IRQ_STATE (DPRAM_BASE + 0x0F4)
304#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6)
305#define MSGSTATE (DPRAM_BASE + 0x0F8)
306#define FILT_STATE (DPRAM_BASE + 0x0FA)
307#define COMMAND (DPRAM_BASE + 0x0FC)
308#define COM_BUFF (DPRAM_BASE + 0x100)
309#define COM_BUFF_SIZE 0x20
310
311/* various data buffers */
312#define BUFF1_BASE (DPRAM_BASE + 0x120)
313#define BUFF1_SIZE 0xE0
314
315#define DATA_BUFF0_BASE (DPRAM_BASE + 0x200)
316#define DATA_BUFF0_SIZE 0x0800
317
318#define DATA_BUFF1_BASE (DATA_BUFF0_BASE+DATA_BUFF0_SIZE)
319#define DATA_BUFF1_SIZE 0x0800
320
321#define DATA_BUFF2_BASE (DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
322#define DATA_BUFF2_SIZE 0x0800
323
324#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
325#define DATA_BUFF3_SIZE 0x0400
326
327#define Reserved (DPRAM_BASE + 0x1E00)
328#define Reserved_SIZE 0x1C0
329
330
331/* firmware status area */
332#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
333#define STATUS_SCR (STATUS_BASE + 0x00)
334#define STATUS_MODES (STATUS_BASE + 0x04)
335#define STATUS_LOOPS (STATUS_BASE + 0x08)
336
337#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C)
338/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */
339#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E)
340
341/* firmware data protocol area */
342#define RX_TYPE (DPRAM_BASE + 0x1FE8)
343#define RX_LEN (DPRAM_BASE + 0x1FEA)
344#define TX_TYPE (DPRAM_BASE + 0x1FEC)
345#define TX_LEN (DPRAM_BASE + 0x1FEE)
346
347#define RX_BUFF (DPRAM_BASE + 0x1FF4)
348#define TX_BUFF (DPRAM_BASE + 0x1FF6)
349
350#define HANDSHAKE_REG (DPRAM_BASE + 0x1FF8)
351#define COM_IF_LOCK (DPRAM_BASE + 0x1FFA)
352
353#define IRQ_RX (DPRAM_BASE + 0x1FFC)
354#define IRQ_TX (DPRAM_BASE + 0x1FFE)
355
356/* used by boot protocol to load firmware into av7110 DRAM */
357#define DRAM_START_CODE 0x2e000404
358#define DRAM_MAX_CODE_SIZE 0x00100000
359
360/* saa7146 gpio lines */
361#define RESET_LINE 2
362#define DEBI_DONE_LINE 1
363#define ARM_IRQ_LINE 0
364
365
366
367extern void av7110_reset_arm(struct av7110 *av7110);
368extern int av7110_bootarm(struct av7110 *av7110);
369extern int av7110_firmversion(struct av7110 *av7110);
370#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
371#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000)
372#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF)
373
374extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
375extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
376extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
377extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
378extern int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len);
379extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
380 int request_buf_len, u16 *reply_buf, int reply_buf_len);
381extern int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* Buff, s16 length);
382
383
384/* DEBI (saa7146 data extension bus interface) access */
385extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
386 int addr, u32 val, int count);
387extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
388 int addr, int count);
389
390
391/* DEBI during interrupt */
392/* single word writes */
393static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
394{
395 av7110_debiwrite(av7110, config, addr, val, count);
396}
397
398/* buffer writes */
399static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, char *val, int count)
400{
401 memcpy(av7110->debi_virt, val, count);
402 av7110_debiwrite(av7110, config, addr, 0, count);
403}
404
405static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
406{
407 u32 res;
408
409 res=av7110_debiread(av7110, config, addr, count);
410 if (count<=4)
411 memcpy(av7110->debi_virt, (char *) &res, count);
412 return res;
413}
414
415/* DEBI outside interrupts, only for count <= 4! */
416static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
417{
418 unsigned long flags;
419
420 spin_lock_irqsave(&av7110->debilock, flags);
421 av7110_debiwrite(av7110, config, addr, val, count);
422 spin_unlock_irqrestore(&av7110->debilock, flags);
423}
424
425static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
426{
427 unsigned long flags;
428 u32 res;
429
430 spin_lock_irqsave(&av7110->debilock, flags);
431 res=av7110_debiread(av7110, config, addr, count);
432 spin_unlock_irqrestore(&av7110->debilock, flags);
433 return res;
434}
435
436/* handle mailbox registers of the dual ported RAM */
437static inline void ARM_ResetMailBox(struct av7110 *av7110)
438{
439 unsigned long flags;
440
441 spin_lock_irqsave(&av7110->debilock, flags);
442 av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
443 av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
444 spin_unlock_irqrestore(&av7110->debilock, flags);
445}
446
447static inline void ARM_ClearMailBox(struct av7110 *av7110)
448{
449 iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
450}
451
452static inline void ARM_ClearIrq(struct av7110 *av7110)
453{
454 irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
455}
456
457/****************************************************************************
458 * Firmware commands
459 ****************************************************************************/
460
461static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
462{
463 return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
464}
465
466static inline void av7710_set_video_mode(struct av7110 *av7110, int mode)
467{
468 av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
469}
470
471static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
472{
473 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
474 (com>>16), (com&0xffff),
475 (arg>>16), (arg&0xffff));
476}
477
478static int inline audcom(struct av7110 *av7110, u32 com)
479{
480 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
481 (com>>16), (com&0xffff));
482}
483
484static inline void Set22K(struct av7110 *av7110, int state)
485{
486 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
487}
488
489
490extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
491
492
493#ifdef CONFIG_DVB_AV7110_OSD
494extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
495extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
496#endif /* CONFIG_DVB_AV7110_OSD */
497
498
499
500#endif /* _AV7110_HW_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
new file mode 100644
index 000000000000..246640741888
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ipack.c
@@ -0,0 +1,403 @@
1#include "dvb_filter.h"
2#include "av7110_ipack.h"
3#include <linux/string.h> /* for memcpy() */
4#include <linux/vmalloc.h>
5
6
7void av7110_ipack_reset(struct ipack *p)
8{
9 p->found = 0;
10 p->cid = 0;
11 p->plength = 0;
12 p->flag1 = 0;
13 p->flag2 = 0;
14 p->hlength = 0;
15 p->mpeg = 0;
16 p->check = 0;
17 p->which = 0;
18 p->done = 0;
19 p->count = 0;
20}
21
22
23int av7110_ipack_init(struct ipack *p, int size,
24 void (*func)(u8 *buf, int size, void *priv))
25{
26 if (!(p->buf = vmalloc(size*sizeof(u8)))) {
27 printk ("Couldn't allocate memory for ipack\n");
28 return -ENOMEM;
29 }
30 p->size = size;
31 p->func = func;
32 p->repack_subids = 0;
33 av7110_ipack_reset(p);
34 return 0;
35}
36
37
38void av7110_ipack_free(struct ipack *p)
39{
40 vfree(p->buf);
41}
42
43
44static void send_ipack(struct ipack *p)
45{
46 int off;
47 struct dvb_audio_info ai;
48 int ac3_off = 0;
49 int streamid = 0;
50 int nframes = 0;
51 int f = 0;
52
53 switch (p->mpeg) {
54 case 2:
55 if (p->count < 10)
56 return;
57 p->buf[3] = p->cid;
58 p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
59 p->buf[5] = (u8)((p->count - 6) & 0x00ff);
60 if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
61 off = 9 + p->buf[8];
62 streamid = p->buf[off];
63 if ((streamid & 0xf8) == 0x80) {
64 ai.off = 0;
65 ac3_off = ((p->buf[off + 2] << 8)|
66 p->buf[off + 3]);
67 if (ac3_off < p->count)
68 f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
69 p->count - ac3_off, &ai, 0);
70 if (!f) {
71 nframes = (p->count - off - 3 - ac3_off) /
72 ai.framesize + 1;
73 p->buf[off + 2] = (ac3_off >> 8) & 0xff;
74 p->buf[off + 3] = (ac3_off) & 0xff;
75 p->buf[off + 1] = nframes;
76 ac3_off += nframes * ai.framesize - p->count;
77 }
78 }
79 }
80 p->func(p->buf, p->count, p->data);
81
82 p->buf[6] = 0x80;
83 p->buf[7] = 0x00;
84 p->buf[8] = 0x00;
85 p->count = 9;
86 if (p->repack_subids && p->cid == PRIVATE_STREAM1
87 && (streamid & 0xf8) == 0x80) {
88 p->count += 4;
89 p->buf[9] = streamid;
90 p->buf[10] = (ac3_off >> 8) & 0xff;
91 p->buf[11] = (ac3_off) & 0xff;
92 p->buf[12] = 0;
93 }
94 break;
95
96 case 1:
97 if (p->count < 8)
98 return;
99 p->buf[3] = p->cid;
100 p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
101 p->buf[5] = (u8)((p->count - 6) & 0x00ff);
102 p->func(p->buf, p->count, p->data);
103
104 p->buf[6] = 0x0f;
105 p->count = 7;
106 break;
107 }
108}
109
110
111void av7110_ipack_flush(struct ipack *p)
112{
113 if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
114 return;
115 p->plength = p->found - 6;
116 p->found = 0;
117 send_ipack(p);
118 av7110_ipack_reset(p);
119}
120
121
122static void write_ipack(struct ipack *p, const u8 *data, int count)
123{
124 u8 headr[3] = { 0x00, 0x00, 0x01 };
125
126 if (p->count < 6) {
127 memcpy(p->buf, headr, 3);
128 p->count = 6;
129 }
130
131 if (p->count + count < p->size){
132 memcpy(p->buf+p->count, data, count);
133 p->count += count;
134 } else {
135 int rest = p->size - p->count;
136 memcpy(p->buf+p->count, data, rest);
137 p->count += rest;
138 send_ipack(p);
139 if (count - rest > 0)
140 write_ipack(p, data + rest, count - rest);
141 }
142}
143
144
145int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
146{
147 int l;
148 int c = 0;
149
150 while (c < count && (p->mpeg == 0 ||
151 (p->mpeg == 1 && p->found < 7) ||
152 (p->mpeg == 2 && p->found < 9))
153 && (p->found < 5 || !p->done)) {
154 switch (p->found) {
155 case 0:
156 case 1:
157 if (buf[c] == 0x00)
158 p->found++;
159 else
160 p->found = 0;
161 c++;
162 break;
163 case 2:
164 if (buf[c] == 0x01)
165 p->found++;
166 else if (buf[c] == 0)
167 p->found = 2;
168 else
169 p->found = 0;
170 c++;
171 break;
172 case 3:
173 p->cid = 0;
174 switch (buf[c]) {
175 case PROG_STREAM_MAP:
176 case PRIVATE_STREAM2:
177 case PROG_STREAM_DIR:
178 case ECM_STREAM :
179 case EMM_STREAM :
180 case PADDING_STREAM :
181 case DSM_CC_STREAM :
182 case ISO13522_STREAM:
183 p->done = 1;
184 /* fall through */
185 case PRIVATE_STREAM1:
186 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
187 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
188 p->found++;
189 p->cid = buf[c];
190 c++;
191 break;
192 default:
193 p->found = 0;
194 break;
195 }
196 break;
197
198 case 4:
199 if (count-c > 1) {
200 p->plen[0] = buf[c];
201 c++;
202 p->plen[1] = buf[c];
203 c++;
204 p->found += 2;
205 p->plength = (p->plen[0] << 8) | p->plen[1];
206 } else {
207 p->plen[0] = buf[c];
208 p->found++;
209 return count;
210 }
211 break;
212 case 5:
213 p->plen[1] = buf[c];
214 c++;
215 p->found++;
216 p->plength = (p->plen[0] << 8) | p->plen[1];
217 break;
218 case 6:
219 if (!p->done) {
220 p->flag1 = buf[c];
221 c++;
222 p->found++;
223 if ((p->flag1 & 0xc0) == 0x80)
224 p->mpeg = 2;
225 else {
226 p->hlength = 0;
227 p->which = 0;
228 p->mpeg = 1;
229 p->flag2 = 0;
230 }
231 }
232 break;
233
234 case 7:
235 if (!p->done && p->mpeg == 2) {
236 p->flag2 = buf[c];
237 c++;
238 p->found++;
239 }
240 break;
241
242 case 8:
243 if (!p->done && p->mpeg == 2) {
244 p->hlength = buf[c];
245 c++;
246 p->found++;
247 }
248 break;
249 }
250 }
251
252 if (c == count)
253 return count;
254
255 if (!p->plength)
256 p->plength = MMAX_PLENGTH - 6;
257
258 if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
259 (p->mpeg == 1 && p->found >= 7))) {
260 switch (p->cid) {
261 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
262 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
263 case PRIVATE_STREAM1:
264 if (p->mpeg == 2 && p->found == 9) {
265 write_ipack(p, &p->flag1, 1);
266 write_ipack(p, &p->flag2, 1);
267 write_ipack(p, &p->hlength, 1);
268 }
269
270 if (p->mpeg == 1 && p->found == 7)
271 write_ipack(p, &p->flag1, 1);
272
273 if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
274 p->found < 14) {
275 while (c < count && p->found < 14) {
276 p->pts[p->found - 9] = buf[c];
277 write_ipack(p, buf + c, 1);
278 c++;
279 p->found++;
280 }
281 if (c == count)
282 return count;
283 }
284
285 if (p->mpeg == 1 && p->which < 2000) {
286
287 if (p->found == 7) {
288 p->check = p->flag1;
289 p->hlength = 1;
290 }
291
292 while (!p->which && c < count &&
293 p->check == 0xff){
294 p->check = buf[c];
295 write_ipack(p, buf + c, 1);
296 c++;
297 p->found++;
298 p->hlength++;
299 }
300
301 if (c == count)
302 return count;
303
304 if ((p->check & 0xc0) == 0x40 && !p->which) {
305 p->check = buf[c];
306 write_ipack(p, buf + c, 1);
307 c++;
308 p->found++;
309 p->hlength++;
310
311 p->which = 1;
312 if (c == count)
313 return count;
314 p->check = buf[c];
315 write_ipack(p, buf + c, 1);
316 c++;
317 p->found++;
318 p->hlength++;
319 p->which = 2;
320 if (c == count)
321 return count;
322 }
323
324 if (p->which == 1) {
325 p->check = buf[c];
326 write_ipack(p, buf + c, 1);
327 c++;
328 p->found++;
329 p->hlength++;
330 p->which = 2;
331 if (c == count)
332 return count;
333 }
334
335 if ((p->check & 0x30) && p->check != 0xff) {
336 p->flag2 = (p->check & 0xf0) << 2;
337 p->pts[0] = p->check;
338 p->which = 3;
339 }
340
341 if (c == count)
342 return count;
343 if (p->which > 2){
344 if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
345 while (c < count && p->which < 7) {
346 p->pts[p->which - 2] = buf[c];
347 write_ipack(p, buf + c, 1);
348 c++;
349 p->found++;
350 p->which++;
351 p->hlength++;
352 }
353 if (c == count)
354 return count;
355 } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
356 while (c < count && p->which < 12) {
357 if (p->which < 7)
358 p->pts[p->which - 2] = buf[c];
359 write_ipack(p, buf + c, 1);
360 c++;
361 p->found++;
362 p->which++;
363 p->hlength++;
364 }
365 if (c == count)
366 return count;
367 }
368 p->which = 2000;
369 }
370
371 }
372
373 while (c < count && p->found < p->plength + 6) {
374 l = count - c;
375 if (l + p->found > p->plength + 6)
376 l = p->plength + 6 - p->found;
377 write_ipack(p, buf + c, l);
378 p->found += l;
379 c += l;
380 }
381 break;
382 }
383
384
385 if (p->done) {
386 if (p->found + count - c < p->plength + 6) {
387 p->found += count - c;
388 c = count;
389 } else {
390 c += p->plength + 6 - p->found;
391 p->found = p->plength + 6;
392 }
393 }
394
395 if (p->plength && p->found == p->plength + 6) {
396 send_ipack(p);
397 av7110_ipack_reset(p);
398 if (c < count)
399 av7110_ipack_instant_repack(buf + c, count - c, p);
400 }
401 }
402 return count;
403}
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h
new file mode 100644
index 000000000000..becf94d3fdfa
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ipack.h
@@ -0,0 +1,12 @@
1#ifndef _AV7110_IPACK_H_
2#define _AV7110_IPACK_H_
3
4extern int av7110_ipack_init(struct ipack *p, int size,
5 void (*func)(u8 *buf, int size, void *priv));
6
7extern void av7110_ipack_reset(struct ipack *p);
8extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
9extern void av7110_ipack_free(struct ipack * p);
10extern void av7110_ipack_flush(struct ipack *p);
11
12#endif
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
new file mode 100644
index 000000000000..6d2256f1e354
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -0,0 +1,212 @@
1#include <linux/types.h>
2#include <linux/init.h>
3#include <linux/module.h>
4#include <linux/moduleparam.h>
5#include <linux/input.h>
6#include <linux/proc_fs.h>
7#include <asm/bitops.h>
8
9#include "av7110.h"
10
11#define UP_TIMEOUT (HZ/4)
12
13/* enable ir debugging by or'ing av7110_debug with 16 */
14
15static int ir_initialized;
16static struct input_dev input_dev;
17
18static u32 ir_config;
19
20static u16 key_map [256] = {
21 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
22 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
23 KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
27 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
28 KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
29 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
31 KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
37 0, 0, 0, 0, KEY_EPG, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
41};
42
43
44static void av7110_emit_keyup(unsigned long data)
45{
46 if (!data || !test_bit(data, input_dev.key))
47 return;
48
49 input_event(&input_dev, EV_KEY, data, !!0);
50}
51
52
53static struct timer_list keyup_timer = { .function = av7110_emit_keyup };
54
55
56static void av7110_emit_key(u32 ircom)
57{
58 u8 data;
59 u8 addr;
60 static u16 old_toggle = 0;
61 u16 new_toggle;
62 u16 keycode;
63
64 /* extract device address and data */
65 if (ir_config & 0x0001) {
66 /* TODO RCMM: ? bits device address, 8 bits data */
67 data = ircom & 0xff;
68 addr = (ircom >> 8) & 0xff;
69 } else {
70 /* RC5: 5 bits device address, 6 bits data */
71 data = ircom & 0x3f;
72 addr = (ircom >> 6) & 0x1f;
73 }
74
75 keycode = key_map[data];
76
77 dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n",
78 ircom, addr, data, keycode);
79
80 /* check device address (if selected) */
81 if (ir_config & 0x4000)
82 if (addr != ((ir_config >> 16) & 0xff))
83 return;
84
85 if (!keycode) {
86 printk ("%s: unknown key 0x%02x!!\n", __FUNCTION__, data);
87 return;
88 }
89
90 if (ir_config & 0x0001)
91 new_toggle = 0; /* RCMM */
92 else
93 new_toggle = (ircom & 0x800); /* RC5 */
94
95 if (timer_pending(&keyup_timer)) {
96 del_timer(&keyup_timer);
97 if (keyup_timer.data != keycode || new_toggle != old_toggle) {
98 input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
99 input_event(&input_dev, EV_KEY, keycode, !0);
100 } else
101 input_event(&input_dev, EV_KEY, keycode, 2);
102
103 } else
104 input_event(&input_dev, EV_KEY, keycode, !0);
105
106 keyup_timer.expires = jiffies + UP_TIMEOUT;
107 keyup_timer.data = keycode;
108
109 add_timer(&keyup_timer);
110
111 old_toggle = new_toggle;
112}
113
114static void input_register_keys(void)
115{
116 int i;
117
118 memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
119
120 for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
121 if (key_map[i] > KEY_MAX)
122 key_map[i] = 0;
123 else if (key_map[i] > KEY_RESERVED)
124 set_bit(key_map[i], input_dev.keybit);
125 }
126}
127
128
129static void input_repeat_key(unsigned long data)
130{
131 /* dummy routine to disable autorepeat in the input driver */
132}
133
134
135static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
136 unsigned long count, void *data)
137{
138 char *page;
139 int size = 4 + 256 * sizeof(u16);
140
141 if (count < size)
142 return -EINVAL;
143
144 page = (char *) vmalloc(size);
145 if (!page)
146 return -ENOMEM;
147
148 if (copy_from_user(page, buffer, size)) {
149 vfree(page);
150 return -EFAULT;
151 }
152
153 memcpy(&ir_config, page, 4);
154 memcpy(&key_map, page + 4, 256 * sizeof(u16));
155 vfree(page);
156 av7110_setup_irc_config(NULL, ir_config);
157 input_register_keys();
158 return count;
159}
160
161
162int __init av7110_ir_init(void)
163{
164 static struct proc_dir_entry *e;
165
166 if (ir_initialized)
167 return 0;
168
169 init_timer(&keyup_timer);
170 keyup_timer.data = 0;
171
172 input_dev.name = "DVB on-card IR receiver";
173
174 /**
175 * enable keys
176 */
177 set_bit(EV_KEY, input_dev.evbit);
178 set_bit(EV_REP, input_dev.evbit);
179
180 input_register_keys();
181
182 input_register_device(&input_dev);
183 input_dev.timer.function = input_repeat_key;
184
185 av7110_setup_irc_config(NULL, 0x0001);
186 av7110_register_irc_handler(av7110_emit_key);
187
188 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
189 if (e) {
190 e->write_proc = av7110_ir_write_proc;
191 e->size = 4 + 256 * sizeof(u16);
192 }
193
194 ir_initialized = 1;
195 return 0;
196}
197
198
199void __exit av7110_ir_exit(void)
200{
201 if (ir_initialized == 0)
202 return;
203 del_timer_sync(&keyup_timer);
204 remove_proc_entry("av7110_ir", NULL);
205 av7110_unregister_irc_handler(av7110_emit_key);
206 input_unregister_device(&input_dev);
207 ir_initialized = 0;
208}
209
210//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
211//MODULE_LICENSE("GPL");
212
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
new file mode 100644
index 000000000000..eb84fb08d95c
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -0,0 +1,771 @@
1/*
2 * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24 *
25 * the project's page is at http://www.linuxtv.org/dvb/
26 */
27
28#include <linux/kernel.h>
29#include <linux/sched.h>
30#include <linux/types.h>
31#include <linux/delay.h>
32#include <linux/fs.h>
33#include <linux/timer.h>
34#include <linux/poll.h>
35#include <linux/byteorder/swabb.h>
36#include <linux/smp_lock.h>
37
38#include "av7110.h"
39#include "av7110_hw.h"
40#include "av7110_av.h"
41
42int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
43{
44 u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
45 struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
46
47 if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
48 dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
49 av7110->dvb_adapter->num, reg, val);
50 return -EIO;
51 }
52 return 0;
53}
54
55int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
56{
57 u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
58 u8 msg2[2];
59 struct i2c_msg msgs[2] = {
60 { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 },
61 { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
62 };
63
64 if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
65 dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
66 av7110->dvb_adapter->num, reg);
67 return -EIO;
68 }
69 *val = (msg2[0] << 8) | msg2[1];
70 return 0;
71}
72
73static struct v4l2_input inputs[2] = {
74 {
75 .index = 0,
76 .name = "DVB",
77 .type = V4L2_INPUT_TYPE_CAMERA,
78 .audioset = 1,
79 .tuner = 0, /* ignored */
80 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
81 .status = 0,
82 }, {
83 .index = 1,
84 .name = "Television",
85 .type = V4L2_INPUT_TYPE_TUNER,
86 .audioset = 2,
87 .tuner = 0,
88 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
89 .status = 0,
90 }
91};
92
93static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
94{
95 u8 buf[] = { 0x00, reg, data };
96 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
97
98 dprintk(4, "dev: %p\n", dev);
99
100 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
101 return -1;
102 return 0;
103}
104
105static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
106{
107 u8 buf [] = { reg, data };
108 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
109
110 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
111 return -1;
112 return 0;
113}
114
115
116static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
117{
118 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
119
120 dprintk(4, "dev: %p\n", dev);
121
122 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
123 return -1;
124 return 0;
125}
126
127static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
128{
129 u32 div;
130 u8 config;
131 u8 buf[4];
132
133 dprintk(4, "freq: 0x%08x\n", freq);
134
135 /* magic number: 614. tuning with the frequency given by v4l2
136 is always off by 614*62.5 = 38375 kHz...*/
137 div = freq + 614;
138
139 buf[0] = (div >> 8) & 0x7f;
140 buf[1] = div & 0xff;
141 buf[2] = 0x8e;
142
143 if (freq < (u32) (16 * 168.25))
144 config = 0xa0;
145 else if (freq < (u32) (16 * 447.25))
146 config = 0x90;
147 else
148 config = 0x30;
149 config &= ~0x02;
150
151 buf[3] = config;
152
153 return tuner_write(dev, 0x61, buf);
154}
155
156static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
157{
158 u32 div;
159 u8 data[4];
160
161 div = (freq + 38900000 + 31250) / 62500;
162
163 data[0] = (div >> 8) & 0x7f;
164 data[1] = div & 0xff;
165 data[2] = 0xce;
166
167 if (freq < 45000000)
168 return -EINVAL;
169 else if (freq < 137000000)
170 data[3] = 0x01;
171 else if (freq < 403000000)
172 data[3] = 0x02;
173 else if (freq < 860000000)
174 data[3] = 0x04;
175 else
176 return -EINVAL;
177
178 stv0297_writereg(dev, 0x1C, 0x87, 0x78);
179 stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
180 return tuner_write(dev, 0x63, data);
181}
182
183
184
185static struct saa7146_standard analog_standard[];
186static struct saa7146_standard dvb_standard[];
187static struct saa7146_standard standard[];
188
189static struct v4l2_audio msp3400_v4l2_audio = {
190 .index = 0,
191 .name = "Television",
192 .capability = V4L2_AUDCAP_STEREO
193};
194
195static int av7110_dvb_c_switch(struct saa7146_fh *fh)
196{
197 struct saa7146_dev *dev = fh->dev;
198 struct saa7146_vv *vv = dev->vv_data;
199 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
200 u16 adswitch;
201 int source, sync, err;
202
203 dprintk(4, "%p\n", av7110);
204
205 if ((vv->video_status & STATUS_OVERLAY) != 0) {
206 vv->ov_suspend = vv->video_fh;
207 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
208 if (err != 0) {
209 dprintk(2, "suspending video failed\n");
210 vv->ov_suspend = NULL;
211 }
212 }
213
214 if (0 != av7110->current_input) {
215 adswitch = 1;
216 source = SAA7146_HPS_SOURCE_PORT_B;
217 sync = SAA7146_HPS_SYNC_PORT_B;
218 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
219 dprintk(1, "switching to analog TV\n");
220 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
221 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
222 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
223 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
224 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
225 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
226
227 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
228 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
229 dprintk(1, "setting band in demodulator failed.\n");
230 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
231 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
232 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
233 }
234 } else {
235 adswitch = 0;
236 source = SAA7146_HPS_SOURCE_PORT_A;
237 sync = SAA7146_HPS_SYNC_PORT_A;
238 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
239 dprintk(1, "switching DVB mode\n");
240 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
241 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
242 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
243 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
244 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
245 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
246
247 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
248 if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
249 dprintk(1, "setting band in demodulator failed.\n");
250 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
251 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
252 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
253 }
254 }
255
256 /* hmm, this does not do anything!? */
257 if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
258 dprintk(1, "ADSwitch error\n");
259
260 saa7146_set_hps_source_and_sync(dev, source, sync);
261
262 if (vv->ov_suspend != NULL) {
263 saa7146_start_preview(vv->ov_suspend);
264 vv->ov_suspend = NULL;
265 }
266
267 return 0;
268}
269
270static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
271{
272 struct saa7146_dev *dev = fh->dev;
273 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
274 dprintk(4, "saa7146_dev: %p\n", dev);
275
276 switch (cmd) {
277 case VIDIOC_G_TUNER:
278 {
279 struct v4l2_tuner *t = arg;
280 u16 stereo_det;
281 s8 stereo;
282
283 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
284
285 if (!av7110->analog_tuner_flags || t->index != 0)
286 return -EINVAL;
287
288 memset(t, 0, sizeof(*t));
289 strcpy(t->name, "Television");
290
291 t->type = V4L2_TUNER_ANALOG_TV;
292 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
293 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
294 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
295 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
296 /* FIXME: add the real signal strength here */
297 t->signal = 0xffff;
298 t->afc = 0;
299
300 // FIXME: standard / stereo detection is still broken
301 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
302 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
303
304 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
305 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
306 stereo = (s8)(stereo_det >> 8);
307 if (stereo > 0x10) {
308 /* stereo */
309 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
310 t->audmode = V4L2_TUNER_MODE_STEREO;
311 }
312 else if (stereo < -0x10) {
313 /* bilingual*/
314 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
315 t->audmode = V4L2_TUNER_MODE_LANG1;
316 }
317 else /* mono */
318 t->rxsubchans = V4L2_TUNER_SUB_MONO;
319
320 return 0;
321 }
322 case VIDIOC_S_TUNER:
323 {
324 struct v4l2_tuner *t = arg;
325 u16 fm_matrix, src;
326 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
327
328 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
329 return -EINVAL;
330
331 switch (t->audmode) {
332 case V4L2_TUNER_MODE_STEREO:
333 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
334 fm_matrix = 0x3001; // stereo
335 src = 0x0020;
336 break;
337 case V4L2_TUNER_MODE_LANG1:
338 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
339 fm_matrix = 0x3000; // mono
340 src = 0x0000;
341 break;
342 case V4L2_TUNER_MODE_LANG2:
343 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
344 fm_matrix = 0x3000; // mono
345 src = 0x0010;
346 break;
347 default: /* case V4L2_TUNER_MODE_MONO: {*/
348 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
349 fm_matrix = 0x3000; // mono
350 src = 0x0030;
351 break;
352 }
353 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
354 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
355 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
356 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
357 return 0;
358 }
359 case VIDIOC_G_FREQUENCY:
360 {
361 struct v4l2_frequency *f = arg;
362
363 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
364
365 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
366 return -EINVAL;
367
368 memset(f, 0, sizeof(*f));
369 f->type = V4L2_TUNER_ANALOG_TV;
370 f->frequency = av7110->current_freq;
371 return 0;
372 }
373 case VIDIOC_S_FREQUENCY:
374 {
375 struct v4l2_frequency *f = arg;
376
377 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
378
379 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
380 return -EINVAL;
381
382 if (V4L2_TUNER_ANALOG_TV != f->type)
383 return -EINVAL;
384
385 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
386 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
387
388 /* tune in desired frequency */
389 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
390 ves1820_set_tv_freq(dev, f->frequency);
391 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
392 stv0297_set_tv_freq(dev, f->frequency);
393 }
394 av7110->current_freq = f->frequency;
395
396 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
397 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
398 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
399 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
400 return 0;
401 }
402 case VIDIOC_ENUMINPUT:
403 {
404 struct v4l2_input *i = arg;
405
406 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
407
408 if (av7110->analog_tuner_flags) {
409 if (i->index < 0 || i->index >= 2)
410 return -EINVAL;
411 } else {
412 if (i->index != 0)
413 return -EINVAL;
414 }
415
416 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
417
418 return 0;
419 }
420 case VIDIOC_G_INPUT:
421 {
422 int *input = (int *)arg;
423 *input = av7110->current_input;
424 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
425 return 0;
426 }
427 case VIDIOC_S_INPUT:
428 {
429 int input = *(int *)arg;
430
431 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
432
433 if (!av7110->analog_tuner_flags)
434 return 0;
435
436 if (input < 0 || input >= 2)
437 return -EINVAL;
438
439 /* FIXME: switch inputs here */
440 av7110->current_input = input;
441 return av7110_dvb_c_switch(fh);
442 }
443 case VIDIOC_G_AUDIO:
444 {
445 struct v4l2_audio *a = arg;
446
447 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
448 if (a->index != 0)
449 return -EINVAL;
450 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
451 break;
452 }
453 case VIDIOC_S_AUDIO:
454 {
455 struct v4l2_audio *a = arg;
456 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
457 break;
458 }
459 default:
460 printk("no such ioctl\n");
461 return -ENOIOCTLCMD;
462 }
463 return 0;
464}
465
466
467/****************************************************************************
468 * INITIALIZATION
469 ****************************************************************************/
470
471static struct saa7146_extension_ioctls ioctls[] = {
472 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
473 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
474 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
475 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
476 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
477 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
478 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
479 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
480 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
481 { 0, 0 }
482};
483
484static u8 saa7113_init_regs[] = {
485 0x02, 0xd0,
486 0x03, 0x23,
487 0x04, 0x00,
488 0x05, 0x00,
489 0x06, 0xe9,
490 0x07, 0x0d,
491 0x08, 0x98,
492 0x09, 0x02,
493 0x0a, 0x80,
494 0x0b, 0x40,
495 0x0c, 0x40,
496 0x0d, 0x00,
497 0x0e, 0x01,
498 0x0f, 0x7c,
499 0x10, 0x48,
500 0x11, 0x0c,
501 0x12, 0x8b,
502 0x13, 0x1a,
503 0x14, 0x00,
504 0x15, 0x00,
505 0x16, 0x00,
506 0x17, 0x00,
507 0x18, 0x00,
508 0x19, 0x00,
509 0x1a, 0x00,
510 0x1b, 0x00,
511 0x1c, 0x00,
512 0x1d, 0x00,
513 0x1e, 0x00,
514
515 0x41, 0x77,
516 0x42, 0x77,
517 0x43, 0x77,
518 0x44, 0x77,
519 0x45, 0x77,
520 0x46, 0x77,
521 0x47, 0x77,
522 0x48, 0x77,
523 0x49, 0x77,
524 0x4a, 0x77,
525 0x4b, 0x77,
526 0x4c, 0x77,
527 0x4d, 0x77,
528 0x4e, 0x77,
529 0x4f, 0x77,
530 0x50, 0x77,
531 0x51, 0x77,
532 0x52, 0x77,
533 0x53, 0x77,
534 0x54, 0x77,
535 0x55, 0x77,
536 0x56, 0x77,
537 0x57, 0xff,
538
539 0xff
540};
541
542
543static struct saa7146_ext_vv av7110_vv_data_st;
544static struct saa7146_ext_vv av7110_vv_data_c;
545
546int av7110_init_analog_module(struct av7110 *av7110)
547{
548 u16 version1, version2;
549
550 if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
551 || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
552 return -ENODEV;
553
554 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
555 av7110->dvb_adapter->num);
556 av7110->adac_type = DVB_ADAC_MSP;
557 msleep(100); // the probing above resets the msp...
558 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
559 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
560 dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
561 av7110->dvb_adapter->num, version1, version2);
562 msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
563 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
564 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
565 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
566 msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
567 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
568 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
569 msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
570
571 if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
572 INFO(("saa7113 not accessible.\n"));
573 } else {
574 u8 *i = saa7113_init_regs;
575
576 if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
577 /* Fujitsu/Siemens DVB-Cable */
578 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
579 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
580 /* Hauppauge/TT DVB-C premium */
581 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
582 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
583 /* Hauppauge/TT DVB-C premium */
584 av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
585 }
586
587 /* setup for DVB by default */
588 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
589 if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
590 dprintk(1, "setting band in demodulator failed.\n");
591 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
592 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
593 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
594 }
595
596 /* init the saa7113 */
597 while (*i != 0xff) {
598 if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
599 dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num);
600 break;
601 }
602 i += 2;
603 }
604 /* setup msp for analog sound: B/G Dual-FM */
605 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
606 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1
607 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
608 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
609 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
610 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
611 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
612 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2
613 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
614 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2
615 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2
616 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
617 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
618 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
619 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
620 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
621 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
622 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
623 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
624 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
625 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
626 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
627 }
628
629 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
630 /* set dd1 stream a & b */
631 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
632 saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
633 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
634
635 return 0;
636}
637
638int av7110_init_v4l(struct av7110 *av7110)
639{
640 struct saa7146_dev* dev = av7110->dev;
641 int ret;
642
643 /* special case DVB-C: these cards have an analog tuner
644 plus need some special handling, so we have separate
645 saa7146_ext_vv data for these... */
646 if (av7110->analog_tuner_flags)
647 ret = saa7146_vv_init(dev, &av7110_vv_data_c);
648 else
649 ret = saa7146_vv_init(dev, &av7110_vv_data_st);
650
651 if (ret) {
652 ERR(("cannot init capture device. skipping.\n"));
653 return -ENODEV;
654 }
655
656 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
657 ERR(("cannot register capture device. skipping.\n"));
658 saa7146_vv_release(dev);
659 return -ENODEV;
660 }
661 if (av7110->analog_tuner_flags) {
662 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
663 ERR(("cannot register vbi v4l2 device. skipping.\n"));
664 } else {
665 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
666 }
667 }
668 return 0;
669}
670
671int av7110_exit_v4l(struct av7110 *av7110)
672{
673 saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
674 if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
675 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
676 return 0;
677}
678
679
680
681/* FIXME: these values are experimental values that look better than the
682 values from the latest "official" driver -- at least for me... (MiHu) */
683static struct saa7146_standard standard[] = {
684 {
685 .name = "PAL", .id = V4L2_STD_PAL_BG,
686 .v_offset = 0x15, .v_field = 288,
687 .h_offset = 0x48, .h_pixels = 708,
688 .v_max_out = 576, .h_max_out = 768,
689 }, {
690 .name = "NTSC", .id = V4L2_STD_NTSC,
691 .v_offset = 0x10, .v_field = 244,
692 .h_offset = 0x40, .h_pixels = 708,
693 .v_max_out = 480, .h_max_out = 640,
694 }
695};
696
697static struct saa7146_standard analog_standard[] = {
698 {
699 .name = "PAL", .id = V4L2_STD_PAL_BG,
700 .v_offset = 0x1b, .v_field = 288,
701 .h_offset = 0x08, .h_pixels = 708,
702 .v_max_out = 576, .h_max_out = 768,
703 }, {
704 .name = "NTSC", .id = V4L2_STD_NTSC,
705 .v_offset = 0x10, .v_field = 244,
706 .h_offset = 0x40, .h_pixels = 708,
707 .v_max_out = 480, .h_max_out = 640,
708 }
709};
710
711static struct saa7146_standard dvb_standard[] = {
712 {
713 .name = "PAL", .id = V4L2_STD_PAL_BG,
714 .v_offset = 0x14, .v_field = 288,
715 .h_offset = 0x48, .h_pixels = 708,
716 .v_max_out = 576, .h_max_out = 768,
717 }, {
718 .name = "NTSC", .id = V4L2_STD_NTSC,
719 .v_offset = 0x10, .v_field = 244,
720 .h_offset = 0x40, .h_pixels = 708,
721 .v_max_out = 480, .h_max_out = 640,
722 }
723};
724
725static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
726{
727 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
728
729 if (std->id == V4L2_STD_PAL) {
730 av7110->vidmode = VIDEO_MODE_PAL;
731 av7110_set_vidmode(av7110, av7110->vidmode);
732 }
733 else if (std->id == V4L2_STD_NTSC) {
734 av7110->vidmode = VIDEO_MODE_NTSC;
735 av7110_set_vidmode(av7110, av7110->vidmode);
736 }
737 else
738 return -1;
739
740 return 0;
741}
742
743
744static struct saa7146_ext_vv av7110_vv_data_st = {
745 .inputs = 1,
746 .audios = 1,
747 .capabilities = 0,
748 .flags = 0,
749
750 .stds = &standard[0],
751 .num_stds = ARRAY_SIZE(standard),
752 .std_callback = &std_callback,
753
754 .ioctls = &ioctls[0],
755 .ioctl = av7110_ioctl,
756};
757
758static struct saa7146_ext_vv av7110_vv_data_c = {
759 .inputs = 1,
760 .audios = 1,
761 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
762 .flags = SAA7146_USE_PORT_B_FOR_VBI,
763
764 .stds = &standard[0],
765 .num_stds = ARRAY_SIZE(standard),
766 .std_callback = &std_callback,
767
768 .ioctls = &ioctls[0],
769 .ioctl = av7110_ioctl,
770};
771
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
new file mode 100644
index 000000000000..14e963206b89
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -0,0 +1,1014 @@
1/*
2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
3 * with analog video in
4 *
5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
6 *
7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
8 * Andrew de Quincey <adq_dvb@lidskialf.net>
9 *
10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31 *
32 *
33 * the project's page is at http://www.linuxtv.org/dvb/
34 */
35
36#include "budget.h"
37#include "stv0299.h"
38#include "tda10021.h"
39#include "tda1004x.h"
40#include <media/saa7146_vv.h>
41#include <linux/module.h>
42#include <linux/errno.h>
43#include <linux/slab.h>
44#include <linux/interrupt.h>
45#include <linux/input.h>
46#include <linux/spinlock.h>
47
48#include "dvb_ca_en50221.h"
49
50#define DEBICICAM 0x02420000
51
52struct budget_av {
53 struct budget budget;
54 struct video_device *vd;
55 int cur_input;
56 int has_saa7113;
57 struct tasklet_struct ciintf_irq_tasklet;
58 int slot_status;
59 struct dvb_ca_en50221 ca;
60};
61
62static int enable_ci = 0;
63
64
65/****************************************************************************
66 * INITIALIZATION
67 ****************************************************************************/
68
69static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
70{
71 u8 mm1[] = { 0x00 };
72 u8 mm2[] = { 0x00 };
73 struct i2c_msg msgs[2];
74
75 msgs[0].flags = 0;
76 msgs[1].flags = I2C_M_RD;
77 msgs[0].addr = msgs[1].addr = id / 2;
78 mm1[0] = reg;
79 msgs[0].len = 1;
80 msgs[1].len = 1;
81 msgs[0].buf = mm1;
82 msgs[1].buf = mm2;
83
84 i2c_transfer(i2c, msgs, 2);
85
86 return mm2[0];
87}
88
89static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
90{
91 u8 mm1[] = { reg };
92 struct i2c_msg msgs[2] = {
93 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
94 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
95 };
96
97 if (i2c_transfer(i2c, msgs, 2) != 2)
98 return -EIO;
99
100 return 0;
101}
102
103static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
104{
105 u8 msg[2] = { reg, val };
106 struct i2c_msg msgs;
107
108 msgs.flags = 0;
109 msgs.addr = id / 2;
110 msgs.len = 2;
111 msgs.buf = msg;
112 return i2c_transfer(i2c, &msgs, 1);
113}
114
115static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
116{
117 struct budget_av *budget_av = (struct budget_av *) ca->data;
118 int result;
119
120 if (slot != 0)
121 return -EINVAL;
122
123 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
124 udelay(1);
125
126 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0);
127
128 if (result == -ETIMEDOUT)
129 budget_av->slot_status = 0;
130 return result;
131}
132
133static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
134{
135 struct budget_av *budget_av = (struct budget_av *) ca->data;
136 int result;
137
138 if (slot != 0)
139 return -EINVAL;
140
141 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
142 udelay(1);
143
144 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0);
145
146 if (result == -ETIMEDOUT)
147 budget_av->slot_status = 0;
148 return result;
149}
150
151static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
152{
153 struct budget_av *budget_av = (struct budget_av *) ca->data;
154 int result;
155
156 if (slot != 0)
157 return -EINVAL;
158
159 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
160 udelay(1);
161
162 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
163
164 if (result == -ETIMEDOUT)
165 budget_av->slot_status = 0;
166 return result;
167}
168
169static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
170{
171 struct budget_av *budget_av = (struct budget_av *) ca->data;
172 int result;
173
174 if (slot != 0)
175 return -EINVAL;
176
177 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
178 udelay(1);
179
180 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
181
182 if (result == -ETIMEDOUT)
183 budget_av->slot_status = 0;
184 return result;
185}
186
187static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
188{
189 struct budget_av *budget_av = (struct budget_av *) ca->data;
190 struct saa7146_dev *saa = budget_av->budget.dev;
191 int max = 20;
192
193 if (slot != 0)
194 return -EINVAL;
195
196 dprintk(1, "ciintf_slot_reset\n");
197
198 /* reset the card */
199 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
200 msleep(100);
201 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
202
203 while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
204 msleep(100);
205
206 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
207 return 0;
208}
209
210static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
211{
212 struct budget_av *budget_av = (struct budget_av *) ca->data;
213 struct saa7146_dev *saa = budget_av->budget.dev;
214
215 if (slot != 0)
216 return -EINVAL;
217
218 dprintk(1, "ciintf_slot_shutdown\n");
219
220 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
221 budget_av->slot_status = 0;
222 return 0;
223}
224
225static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
226{
227 struct budget_av *budget_av = (struct budget_av *) ca->data;
228 struct saa7146_dev *saa = budget_av->budget.dev;
229
230 if (slot != 0)
231 return -EINVAL;
232
233 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
234
235 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
236 return 0;
237}
238
239static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
240{
241 struct budget_av *budget_av = (struct budget_av *) ca->data;
242 struct saa7146_dev *saa = budget_av->budget.dev;
243 int cam = 0;
244
245 if (slot != 0)
246 return -EINVAL;
247
248 if (!budget_av->slot_status) {
249 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
250 udelay(1);
251 cam = saa7146_read(saa, PSR) & MASK_06;
252 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
253
254 if (cam)
255 budget_av->slot_status = 1;
256 } else if (!open) {
257 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
258 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
259 budget_av->slot_status = 0;
260 }
261
262 if (budget_av->slot_status == 1)
263 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
264
265 return 0;
266}
267
268static int ciintf_init(struct budget_av *budget_av)
269{
270 struct saa7146_dev *saa = budget_av->budget.dev;
271 int result;
272
273 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
274
275 /* setup GPIOs */
276 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
277 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
278 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
279
280 /* Reset the card */
281 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
282 msleep(50);
283 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
284 msleep(100);
285
286 /* Enable DEBI pins */
287 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
288
289 /* register CI interface */
290 budget_av->ca.owner = THIS_MODULE;
291 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
292 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
293 budget_av->ca.read_cam_control = ciintf_read_cam_control;
294 budget_av->ca.write_cam_control = ciintf_write_cam_control;
295 budget_av->ca.slot_reset = ciintf_slot_reset;
296 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
297 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
298 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
299 budget_av->ca.data = budget_av;
300 if ((result = dvb_ca_en50221_init(budget_av->budget.dvb_adapter,
301 &budget_av->ca, 0, 1)) != 0) {
302 printk("budget_av: CI interface detected, but initialisation failed.\n");
303 goto error;
304 }
305 // success!
306 printk("ciintf_init: CI interface initialised\n");
307 budget_av->budget.ci_present = 1;
308 return 0;
309
310error:
311 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
312 return result;
313}
314
315static void ciintf_deinit(struct budget_av *budget_av)
316{
317 struct saa7146_dev *saa = budget_av->budget.dev;
318
319 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
320 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
321 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
322 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
323
324 /* release the CA device */
325 dvb_ca_en50221_release(&budget_av->ca);
326
327 /* disable DEBI pins */
328 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
329}
330
331
332static const u8 saa7113_tab[] = {
333 0x01, 0x08,
334 0x02, 0xc0,
335 0x03, 0x33,
336 0x04, 0x00,
337 0x05, 0x00,
338 0x06, 0xeb,
339 0x07, 0xe0,
340 0x08, 0x28,
341 0x09, 0x00,
342 0x0a, 0x80,
343 0x0b, 0x47,
344 0x0c, 0x40,
345 0x0d, 0x00,
346 0x0e, 0x01,
347 0x0f, 0x44,
348
349 0x10, 0x08,
350 0x11, 0x0c,
351 0x12, 0x7b,
352 0x13, 0x00,
353 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
354
355 0x57, 0xff,
356 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
357 0x5b, 0x83, 0x5e, 0x00,
358 0xff
359};
360
361static int saa7113_init(struct budget_av *budget_av)
362{
363 struct budget *budget = &budget_av->budget;
364 const u8 *data = saa7113_tab;
365
366 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
367 dprintk(1, "saa7113 not found on KNC card\n");
368 return -ENODEV;
369 }
370
371 dprintk(1, "saa7113 detected and initializing\n");
372
373 while (*data != 0xff) {
374 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
375 data += 2;
376 }
377
378 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
379
380 return 0;
381}
382
383static int saa7113_setinput(struct budget_av *budget_av, int input)
384{
385 struct budget *budget = &budget_av->budget;
386
387 if (1 != budget_av->has_saa7113)
388 return -ENODEV;
389
390 if (input == 1) {
391 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
392 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
393 } else if (input == 0) {
394 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
395 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
396 } else
397 return -EINVAL;
398
399 budget_av->cur_input = input;
400 return 0;
401}
402
403
404static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
405{
406 u8 aclk = 0;
407 u8 bclk = 0;
408 u8 m1;
409
410 aclk = 0xb5;
411 if (srate < 2000000)
412 bclk = 0x86;
413 else if (srate < 5000000)
414 bclk = 0x89;
415 else if (srate < 15000000)
416 bclk = 0x8f;
417 else if (srate < 45000000)
418 bclk = 0x95;
419
420 m1 = 0x14;
421 if (srate < 4000000)
422 m1 = 0x10;
423
424 stv0299_writereg(fe, 0x13, aclk);
425 stv0299_writereg(fe, 0x14, bclk);
426 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
427 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
428 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
429 stv0299_writereg(fe, 0x0f, 0x80 | m1);
430
431 return 0;
432}
433
434static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
435 struct dvb_frontend_parameters *params)
436{
437 struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
438 u32 div;
439 u8 buf[4];
440 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
441
442 if ((params->frequency < 950000) || (params->frequency > 2150000))
443 return -EINVAL;
444
445 div = (params->frequency + (125 - 1)) / 125; // round correctly
446 buf[0] = (div >> 8) & 0x7f;
447 buf[1] = div & 0xff;
448 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
449 buf[3] = 0x20;
450
451 if (params->u.qpsk.symbol_rate < 4000000)
452 buf[3] |= 1;
453
454 if (params->frequency < 1250000)
455 buf[3] |= 0;
456 else if (params->frequency < 1550000)
457 buf[3] |= 0x40;
458 else if (params->frequency < 2050000)
459 buf[3] |= 0x80;
460 else if (params->frequency < 2150000)
461 buf[3] |= 0xC0;
462
463 if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1)
464 return -EIO;
465 return 0;
466}
467
468static u8 typhoon_cinergy1200s_inittab[] = {
469 0x01, 0x15,
470 0x02, 0x30,
471 0x03, 0x00,
472 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
473 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
474 0x06, 0x40, /* DAC not used, set to high impendance mode */
475 0x07, 0x00, /* DAC LSB */
476 0x08, 0x40, /* DiSEqC off */
477 0x09, 0x00, /* FIFO */
478 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
479 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
480 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
481 0x10, 0x3f, // AGC2 0x3d
482 0x11, 0x84,
483 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
484 0x15, 0xc9, // lock detector threshold
485 0x16, 0x00,
486 0x17, 0x00,
487 0x18, 0x00,
488 0x19, 0x00,
489 0x1a, 0x00,
490 0x1f, 0x50,
491 0x20, 0x00,
492 0x21, 0x00,
493 0x22, 0x00,
494 0x23, 0x00,
495 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
496 0x29, 0x1e, // 1/2 threshold
497 0x2a, 0x14, // 2/3 threshold
498 0x2b, 0x0f, // 3/4 threshold
499 0x2c, 0x09, // 5/6 threshold
500 0x2d, 0x05, // 7/8 threshold
501 0x2e, 0x01,
502 0x31, 0x1f, // test all FECs
503 0x32, 0x19, // viterbi and synchro search
504 0x33, 0xfc, // rs control
505 0x34, 0x93, // error control
506 0x0f, 0x92,
507 0xff, 0xff
508};
509
510static struct stv0299_config typhoon_config = {
511 .demod_address = 0x68,
512 .inittab = typhoon_cinergy1200s_inittab,
513 .mclk = 88000000UL,
514 .invert = 0,
515 .enhanced_tuning = 0,
516 .skip_reinit = 0,
517 .lock_output = STV0229_LOCKOUTPUT_1,
518 .volt13_op0_op1 = STV0299_VOLT13_OP0,
519 .min_delay_ms = 100,
520 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
521 .pll_set = philips_su1278_ty_ci_pll_set,
522};
523
524
525static struct stv0299_config cinergy_1200s_config = {
526 .demod_address = 0x68,
527 .inittab = typhoon_cinergy1200s_inittab,
528 .mclk = 88000000UL,
529 .invert = 0,
530 .enhanced_tuning = 0,
531 .skip_reinit = 0,
532 .lock_output = STV0229_LOCKOUTPUT_0,
533 .volt13_op0_op1 = STV0299_VOLT13_OP0,
534 .min_delay_ms = 100,
535 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
536 .pll_set = philips_su1278_ty_ci_pll_set,
537};
538
539
540static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
541{
542 struct budget *budget = (struct budget *) fe->dvb->priv;
543 u8 buf[4];
544 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
545
546#define TUNER_MUL 62500
547
548 u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
549
550 buf[0] = (div >> 8) & 0x7f;
551 buf[1] = div & 0xff;
552 buf[2] = 0x8e;
553 buf[3] = (params->frequency < 174500000 ? 0xa1 :
554 params->frequency < 454000000 ? 0x92 : 0x34);
555
556 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
557 return -EIO;
558 return 0;
559}
560
561static struct tda10021_config philips_cu1216_config = {
562 .demod_address = 0x0c,
563 .pll_set = philips_cu1216_pll_set,
564};
565
566
567
568
569static int philips_tu1216_pll_init(struct dvb_frontend *fe)
570{
571 struct budget *budget = (struct budget *) fe->dvb->priv;
572 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
573 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
574
575 // setup PLL configuration
576 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
577 return -EIO;
578 msleep(1);
579
580 return 0;
581}
582
583static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
584{
585 struct budget *budget = (struct budget *) fe->dvb->priv;
586 u8 tuner_buf[4];
587 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
588 sizeof(tuner_buf) };
589 int tuner_frequency = 0;
590 u8 band, cp, filter;
591
592 // determine charge pump
593 tuner_frequency = params->frequency + 36166000;
594 if (tuner_frequency < 87000000)
595 return -EINVAL;
596 else if (tuner_frequency < 130000000)
597 cp = 3;
598 else if (tuner_frequency < 160000000)
599 cp = 5;
600 else if (tuner_frequency < 200000000)
601 cp = 6;
602 else if (tuner_frequency < 290000000)
603 cp = 3;
604 else if (tuner_frequency < 420000000)
605 cp = 5;
606 else if (tuner_frequency < 480000000)
607 cp = 6;
608 else if (tuner_frequency < 620000000)
609 cp = 3;
610 else if (tuner_frequency < 830000000)
611 cp = 5;
612 else if (tuner_frequency < 895000000)
613 cp = 7;
614 else
615 return -EINVAL;
616
617 // determine band
618 if (params->frequency < 49000000)
619 return -EINVAL;
620 else if (params->frequency < 161000000)
621 band = 1;
622 else if (params->frequency < 444000000)
623 band = 2;
624 else if (params->frequency < 861000000)
625 band = 4;
626 else
627 return -EINVAL;
628
629 // setup PLL filter
630 switch (params->u.ofdm.bandwidth) {
631 case BANDWIDTH_6_MHZ:
632 filter = 0;
633 break;
634
635 case BANDWIDTH_7_MHZ:
636 filter = 0;
637 break;
638
639 case BANDWIDTH_8_MHZ:
640 filter = 1;
641 break;
642
643 default:
644 return -EINVAL;
645 }
646
647 // calculate divisor
648 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
649 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
650
651 // setup tuner buffer
652 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
653 tuner_buf[1] = tuner_frequency & 0xff;
654 tuner_buf[2] = 0xca;
655 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
656
657 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
658 return -EIO;
659
660 msleep(1);
661 return 0;
662}
663
664static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
665 const struct firmware **fw, char *name)
666{
667 struct budget *budget = (struct budget *) fe->dvb->priv;
668
669 return request_firmware(fw, name, &budget->dev->pci->dev);
670}
671
672static struct tda1004x_config philips_tu1216_config = {
673
674 .demod_address = 0x8,
675 .invert = 1,
676 .invert_oclk = 1,
677 .pll_init = philips_tu1216_pll_init,
678 .pll_set = philips_tu1216_pll_set,
679 .request_firmware = philips_tu1216_request_firmware,
680};
681
682
683
684
685static u8 read_pwm(struct budget_av *budget_av)
686{
687 u8 b = 0xff;
688 u8 pwm;
689 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
690 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
691 };
692
693 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
694 || (pwm == 0xff))
695 pwm = 0x48;
696
697 return pwm;
698}
699
700
701static void frontend_init(struct budget_av *budget_av)
702{
703 switch (budget_av->budget.dev->pci->subsystem_device) {
704 case 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
705 budget_av->budget.dvb_frontend =
706 stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
707 if (budget_av->budget.dvb_frontend != NULL) {
708 break;
709 }
710 break;
711
712 case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
713 budget_av->budget.dvb_frontend =
714 tda10021_attach(&philips_cu1216_config,
715 &budget_av->budget.i2c_adap, read_pwm(budget_av));
716 if (budget_av->budget.dvb_frontend != NULL) {
717 break;
718 }
719 break;
720
721 case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
722 budget_av->budget.dvb_frontend =
723 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
724 if (budget_av->budget.dvb_frontend != NULL) {
725 break;
726 }
727 break;
728
729 case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
730 budget_av->budget.dvb_frontend =
731 stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
732 if (budget_av->budget.dvb_frontend != NULL) {
733 break;
734 }
735 break;
736
737 case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
738 budget_av->budget.dvb_frontend =
739 tda10021_attach(&philips_cu1216_config,
740 &budget_av->budget.i2c_adap, read_pwm(budget_av));
741 if (budget_av->budget.dvb_frontend) {
742 break;
743 }
744 break;
745
746 case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
747 budget_av->budget.dvb_frontend =
748 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
749 if (budget_av->budget.dvb_frontend) {
750 break;
751 }
752 break;
753 }
754
755 if (budget_av->budget.dvb_frontend == NULL) {
756 printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
757 budget_av->budget.dev->pci->vendor,
758 budget_av->budget.dev->pci->device,
759 budget_av->budget.dev->pci->subsystem_vendor,
760 budget_av->budget.dev->pci->subsystem_device);
761 } else {
762 if (dvb_register_frontend
763 (budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
764 printk("budget-av: Frontend registration failed!\n");
765 if (budget_av->budget.dvb_frontend->ops->release)
766 budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
767 budget_av->budget.dvb_frontend = NULL;
768 }
769 }
770}
771
772
773static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
774{
775 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
776
777 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
778
779 if (*isr & MASK_10)
780 ttpci_budget_irq10_handler(dev, isr);
781}
782
783static int budget_av_detach(struct saa7146_dev *dev)
784{
785 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
786 int err;
787
788 dprintk(2, "dev: %p\n", dev);
789
790 if (1 == budget_av->has_saa7113) {
791 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
792
793 msleep(200);
794
795 saa7146_unregister_device(&budget_av->vd, dev);
796 }
797
798 if (budget_av->budget.ci_present)
799 ciintf_deinit(budget_av);
800
801 if (budget_av->budget.dvb_frontend != NULL)
802 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
803 err = ttpci_budget_deinit(&budget_av->budget);
804
805 kfree(budget_av);
806
807 return err;
808}
809
810static struct saa7146_ext_vv vv_data;
811
812static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
813{
814 struct budget_av *budget_av;
815 u8 *mac;
816 int err;
817
818 dprintk(2, "dev: %p\n", dev);
819
820 if (!(budget_av = kmalloc(sizeof(struct budget_av), GFP_KERNEL)))
821 return -ENOMEM;
822
823 memset(budget_av, 0, sizeof(struct budget_av));
824
825 budget_av->budget.ci_present = 0;
826
827 dev->ext_priv = budget_av;
828
829 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
830 kfree(budget_av);
831 return err;
832 }
833
834 /* knc1 initialization */
835 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
836 saa7146_write(dev, DD1_INIT, 0x07000600);
837 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
838
839 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
840 msleep(500);
841
842 if (0 == saa7113_init(budget_av)) {
843 budget_av->has_saa7113 = 1;
844
845 if (0 != saa7146_vv_init(dev, &vv_data)) {
846 /* fixme: proper cleanup here */
847 ERR(("cannot init vv subsystem.\n"));
848 return err;
849 }
850
851 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
852 /* fixme: proper cleanup here */
853 ERR(("cannot register capture v4l2 device.\n"));
854 return err;
855 }
856
857 /* beware: this modifies dev->vv ... */
858 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
859 SAA7146_HPS_SYNC_PORT_A);
860
861 saa7113_setinput(budget_av, 0);
862 } else {
863 budget_av->has_saa7113 = 0;
864
865 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
866 }
867
868 /* fixme: find some sane values here... */
869 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
870
871 mac = budget_av->budget.dvb_adapter->proposed_mac;
872 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
873 printk("KNC1-%d: Could not read MAC from KNC1 card\n",
874 budget_av->budget.dvb_adapter->num);
875 memset(mac, 0, 6);
876 } else {
877 printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
878 budget_av->budget.dvb_adapter->num,
879 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
880 }
881
882 budget_av->budget.dvb_adapter->priv = budget_av;
883 frontend_init(budget_av);
884
885 if (enable_ci)
886 ciintf_init(budget_av);
887
888 return 0;
889}
890
891#define KNC1_INPUTS 2
892static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
893 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
894 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
895};
896
897static struct saa7146_extension_ioctls ioctls[] = {
898 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
899 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
900 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
901 {0, 0}
902};
903
904static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
905{
906 struct saa7146_dev *dev = fh->dev;
907 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
908
909 switch (cmd) {
910 case VIDIOC_ENUMINPUT:{
911 struct v4l2_input *i = arg;
912
913 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
914 if (i->index < 0 || i->index >= KNC1_INPUTS) {
915 return -EINVAL;
916 }
917 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
918 return 0;
919 }
920 case VIDIOC_G_INPUT:{
921 int *input = (int *) arg;
922
923 *input = budget_av->cur_input;
924
925 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
926 return 0;
927 }
928 case VIDIOC_S_INPUT:{
929 int input = *(int *) arg;
930 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
931 return saa7113_setinput(budget_av, input);
932 }
933 default:
934 return -ENOIOCTLCMD;
935 }
936 return 0;
937}
938
939static struct saa7146_standard standard[] = {
940 {.name = "PAL",.id = V4L2_STD_PAL,
941 .v_offset = 0x17,.v_field = 288,
942 .h_offset = 0x14,.h_pixels = 680,
943 .v_max_out = 576,.h_max_out = 768 },
944
945 {.name = "NTSC",.id = V4L2_STD_NTSC,
946 .v_offset = 0x16,.v_field = 240,
947 .h_offset = 0x06,.h_pixels = 708,
948 .v_max_out = 480,.h_max_out = 640, },
949};
950
951static struct saa7146_ext_vv vv_data = {
952 .inputs = 2,
953 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
954 .flags = 0,
955 .stds = &standard[0],
956 .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
957 .ioctls = &ioctls[0],
958 .ioctl = av_ioctl,
959};
960
961static struct saa7146_extension budget_extension;
962
963MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
964MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
965MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
966MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
967MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
968MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
969
970static struct pci_device_id pci_tbl[] = {
971 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
972 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
973 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
974 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
975 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
976 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
977 {
978 .vendor = 0,
979 }
980};
981
982MODULE_DEVICE_TABLE(pci, pci_tbl);
983
984static struct saa7146_extension budget_extension = {
985 .name = "budget dvb /w video in\0",
986 .pci_tbl = pci_tbl,
987
988 .module = THIS_MODULE,
989 .attach = budget_av_attach,
990 .detach = budget_av_detach,
991
992 .irq_mask = MASK_10,
993 .irq_func = budget_av_irq,
994};
995
996static int __init budget_av_init(void)
997{
998 return saa7146_register_extension(&budget_extension);
999}
1000
1001static void __exit budget_av_exit(void)
1002{
1003 saa7146_unregister_extension(&budget_extension);
1004}
1005
1006module_init(budget_av_init);
1007module_exit(budget_av_exit);
1008
1009MODULE_LICENSE("GPL");
1010MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1011MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1012 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
1013module_param_named(enable_ci, enable_ci, int, 0644);
1014MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
new file mode 100644
index 000000000000..521111be3558
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -0,0 +1,995 @@
1/*
2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7 * partially based on the Siemens DVB driver by Ralph+Marcus Metzler
8 *
9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 *
28 *
29 * the project's page is at http://www.linuxtv.org/dvb/
30 */
31
32#include "budget.h"
33
34#include <linux/module.h>
35#include <linux/errno.h>
36#include <linux/slab.h>
37#include <linux/interrupt.h>
38#include <linux/input.h>
39#include <linux/spinlock.h>
40
41#include "dvb_ca_en50221.h"
42#include "stv0299.h"
43#include "tda1004x.h"
44
45#define DEBIADDR_IR 0x1234
46#define DEBIADDR_CICONTROL 0x0000
47#define DEBIADDR_CIVERSION 0x4000
48#define DEBIADDR_IO 0x1000
49#define DEBIADDR_ATTR 0x3000
50
51#define CICONTROL_RESET 0x01
52#define CICONTROL_ENABLETS 0x02
53#define CICONTROL_CAMDETECT 0x08
54
55#define DEBICICTL 0x00420000
56#define DEBICICAM 0x02420000
57
58#define SLOTSTATUS_NONE 1
59#define SLOTSTATUS_PRESENT 2
60#define SLOTSTATUS_RESET 4
61#define SLOTSTATUS_READY 8
62#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
63
64struct budget_ci {
65 struct budget budget;
66 struct input_dev input_dev;
67 struct tasklet_struct msp430_irq_tasklet;
68 struct tasklet_struct ciintf_irq_tasklet;
69 int slot_status;
70 struct dvb_ca_en50221 ca;
71 char ir_dev_name[50];
72};
73
74/* from reading the following remotes:
75 Zenith Universal 7 / TV Mode 807 / VCR Mode 837
76 Hauppauge (from NOVA-CI-s box product)
77 i've taken a "middle of the road" approach and note the differences
78*/
79static u16 key_map[64] = {
80 /* 0x0X */
81 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
82 KEY_9,
83 KEY_ENTER,
84 KEY_RED,
85 KEY_POWER, /* RADIO on Hauppauge */
86 KEY_MUTE,
87 0,
88 KEY_A, /* TV on Hauppauge */
89 /* 0x1X */
90 KEY_VOLUMEUP, KEY_VOLUMEDOWN,
91 0, 0,
92 KEY_B,
93 0, 0, 0, 0, 0, 0, 0,
94 KEY_UP, KEY_DOWN,
95 KEY_OPTION, /* RESERVED on Hauppauge */
96 KEY_BREAK,
97 /* 0x2X */
98 KEY_CHANNELUP, KEY_CHANNELDOWN,
99 KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */
100 0, KEY_RESTART, KEY_OK,
101 KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */
102 0,
103 KEY_ENTER, /* VCR mode on Zenith */
104 KEY_PAUSE,
105 0,
106 KEY_RIGHT, KEY_LEFT,
107 0,
108 KEY_MENU, /* FULL SCREEN on Hauppauge */
109 0,
110 /* 0x3X */
111 KEY_SLOW,
112 KEY_PREVIOUS, /* VCR mode on Zenith */
113 KEY_REWIND,
114 0,
115 KEY_FASTFORWARD,
116 KEY_PLAY, KEY_STOP,
117 KEY_RECORD,
118 KEY_TUNER, /* TV/VCR on Zenith */
119 0,
120 KEY_C,
121 0,
122 KEY_EXIT,
123 KEY_POWER2,
124 KEY_TUNER, /* VCR mode on Zenith */
125 0,
126};
127
128static void msp430_ir_debounce(unsigned long data)
129{
130 struct input_dev *dev = (struct input_dev *) data;
131
132 if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
133 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
134 return;
135 }
136
137 dev->rep[0] = 0;
138 dev->timer.expires = jiffies + HZ * 350 / 1000;
139 add_timer(&dev->timer);
140 input_event(dev, EV_KEY, key_map[dev->repeat_key], 2); /* REPEAT */
141}
142
143static void msp430_ir_interrupt(unsigned long data)
144{
145 struct budget_ci *budget_ci = (struct budget_ci *) data;
146 struct input_dev *dev = &budget_ci->input_dev;
147 unsigned int code =
148 ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
149
150 if (code & 0x40) {
151 code &= 0x3f;
152
153 if (timer_pending(&dev->timer)) {
154 if (code == dev->repeat_key) {
155 ++dev->rep[0];
156 return;
157 }
158 del_timer(&dev->timer);
159 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
160 }
161
162 if (!key_map[code]) {
163 printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
164 return;
165 }
166
167 /* initialize debounce and repeat */
168 dev->repeat_key = code;
169 /* Zenith remote _always_ sends 2 sequences */
170 dev->rep[0] = ~0;
171 /* 350 milliseconds */
172 dev->timer.expires = jiffies + HZ * 350 / 1000;
173 /* MAKE */
174 input_event(dev, EV_KEY, key_map[code], !0);
175 add_timer(&dev->timer);
176 }
177}
178
179static int msp430_ir_init(struct budget_ci *budget_ci)
180{
181 struct saa7146_dev *saa = budget_ci->budget.dev;
182 int i;
183
184 memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
185
186 sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
187 budget_ci->input_dev.name = budget_ci->ir_dev_name;
188
189 set_bit(EV_KEY, budget_ci->input_dev.evbit);
190
191 for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
192 if (key_map[i])
193 set_bit(key_map[i], budget_ci->input_dev.keybit);
194
195 input_register_device(&budget_ci->input_dev);
196
197 budget_ci->input_dev.timer.function = msp430_ir_debounce;
198
199 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
200
201 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
202
203 return 0;
204}
205
206static void msp430_ir_deinit(struct budget_ci *budget_ci)
207{
208 struct saa7146_dev *saa = budget_ci->budget.dev;
209 struct input_dev *dev = &budget_ci->input_dev;
210
211 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
212 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
213
214 if (del_timer(&dev->timer))
215 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
216
217 input_unregister_device(dev);
218}
219
220static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
221{
222 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
223
224 if (slot != 0)
225 return -EINVAL;
226
227 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
228 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
229}
230
231static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
232{
233 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
234
235 if (slot != 0)
236 return -EINVAL;
237
238 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
239 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
240}
241
242static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
243{
244 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
245
246 if (slot != 0)
247 return -EINVAL;
248
249 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
250 DEBIADDR_IO | (address & 3), 1, 1, 0);
251}
252
253static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
254{
255 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
256
257 if (slot != 0)
258 return -EINVAL;
259
260 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
261 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
262}
263
264static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
265{
266 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
267 struct saa7146_dev *saa = budget_ci->budget.dev;
268
269 if (slot != 0)
270 return -EINVAL;
271
272 // trigger on RISING edge during reset so we know when READY is re-asserted
273 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
274 budget_ci->slot_status = SLOTSTATUS_RESET;
275 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
276 msleep(1);
277 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
278 CICONTROL_RESET, 1, 0);
279
280 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
281 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
282 return 0;
283}
284
285static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
286{
287 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
288 struct saa7146_dev *saa = budget_ci->budget.dev;
289
290 if (slot != 0)
291 return -EINVAL;
292
293 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
294 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
295 return 0;
296}
297
298static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
299{
300 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
301 struct saa7146_dev *saa = budget_ci->budget.dev;
302 int tmp;
303
304 if (slot != 0)
305 return -EINVAL;
306
307 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
308
309 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
310 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
311 tmp | CICONTROL_ENABLETS, 1, 0);
312
313 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
314 return 0;
315}
316
317static void ciintf_interrupt(unsigned long data)
318{
319 struct budget_ci *budget_ci = (struct budget_ci *) data;
320 struct saa7146_dev *saa = budget_ci->budget.dev;
321 unsigned int flags;
322
323 // ensure we don't get spurious IRQs during initialisation
324 if (!budget_ci->budget.ci_present)
325 return;
326
327 // read the CAM status
328 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
329 if (flags & CICONTROL_CAMDETECT) {
330
331 // GPIO should be set to trigger on falling edge if a CAM is present
332 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
333
334 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
335 // CAM insertion IRQ
336 budget_ci->slot_status = SLOTSTATUS_PRESENT;
337 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
338 DVB_CA_EN50221_CAMCHANGE_INSERTED);
339
340 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
341 // CAM ready (reset completed)
342 budget_ci->slot_status = SLOTSTATUS_READY;
343 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
344
345 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
346 // FR/DA IRQ
347 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
348 }
349 } else {
350
351 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
352 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
353 // the CAM might not actually be ready yet.
354 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
355
356 // generate a CAM removal IRQ if we haven't already
357 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
358 // CAM removal IRQ
359 budget_ci->slot_status = SLOTSTATUS_NONE;
360 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
361 DVB_CA_EN50221_CAMCHANGE_REMOVED);
362 }
363 }
364}
365
366static int ciintf_init(struct budget_ci *budget_ci)
367{
368 struct saa7146_dev *saa = budget_ci->budget.dev;
369 int flags;
370 int result;
371
372 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
373
374 // enable DEBI pins
375 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
376
377 // test if it is there
378 if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
379 result = -ENODEV;
380 goto error;
381 }
382 // determine whether a CAM is present or not
383 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
384 budget_ci->slot_status = SLOTSTATUS_NONE;
385 if (flags & CICONTROL_CAMDETECT)
386 budget_ci->slot_status = SLOTSTATUS_PRESENT;
387
388 // register CI interface
389 budget_ci->ca.owner = THIS_MODULE;
390 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
391 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
392 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
393 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
394 budget_ci->ca.slot_reset = ciintf_slot_reset;
395 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
396 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
397 budget_ci->ca.data = budget_ci;
398 if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,
399 &budget_ci->ca,
400 DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
401 DVB_CA_EN50221_FLAG_IRQ_FR |
402 DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
403 printk("budget_ci: CI interface detected, but initialisation failed.\n");
404 goto error;
405 }
406 // Setup CI slot IRQ
407 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
408 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
409 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
410 } else {
411 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
412 }
413 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
414 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
415 CICONTROL_RESET, 1, 0);
416
417 // success!
418 printk("budget_ci: CI interface initialised\n");
419 budget_ci->budget.ci_present = 1;
420
421 // forge a fake CI IRQ so the CAM state is setup correctly
422 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
423 if (budget_ci->slot_status != SLOTSTATUS_NONE)
424 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
425 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
426
427 return 0;
428
429error:
430 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
431 return result;
432}
433
434static void ciintf_deinit(struct budget_ci *budget_ci)
435{
436 struct saa7146_dev *saa = budget_ci->budget.dev;
437
438 // disable CI interrupts
439 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
440 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
441 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
442 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
443 msleep(1);
444 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
445 CICONTROL_RESET, 1, 0);
446
447 // disable TS data stream to CI interface
448 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
449
450 // release the CA device
451 dvb_ca_en50221_release(&budget_ci->ca);
452
453 // disable DEBI pins
454 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
455}
456
457static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
458{
459 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
460
461 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
462
463 if (*isr & MASK_06)
464 tasklet_schedule(&budget_ci->msp430_irq_tasklet);
465
466 if (*isr & MASK_10)
467 ttpci_budget_irq10_handler(dev, isr);
468
469 if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
470 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
471}
472
473
474static u8 alps_bsru6_inittab[] = {
475 0x01, 0x15,
476 0x02, 0x00,
477 0x03, 0x00,
478 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
479 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
480 0x06, 0x40, /* DAC not used, set to high impendance mode */
481 0x07, 0x00, /* DAC LSB */
482 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
483 0x09, 0x00, /* FIFO */
484 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
485 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
486 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
487 0x10, 0x3f, // AGC2 0x3d
488 0x11, 0x84,
489 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
490 0x15, 0xc9, // lock detector threshold
491 0x16, 0x00,
492 0x17, 0x00,
493 0x18, 0x00,
494 0x19, 0x00,
495 0x1a, 0x00,
496 0x1f, 0x50,
497 0x20, 0x00,
498 0x21, 0x00,
499 0x22, 0x00,
500 0x23, 0x00,
501 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
502 0x29, 0x1e, // 1/2 threshold
503 0x2a, 0x14, // 2/3 threshold
504 0x2b, 0x0f, // 3/4 threshold
505 0x2c, 0x09, // 5/6 threshold
506 0x2d, 0x05, // 7/8 threshold
507 0x2e, 0x01,
508 0x31, 0x1f, // test all FECs
509 0x32, 0x19, // viterbi and synchro search
510 0x33, 0xfc, // rs control
511 0x34, 0x93, // error control
512 0x0f, 0x52,
513 0xff, 0xff
514};
515
516static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
517{
518 u8 aclk = 0;
519 u8 bclk = 0;
520
521 if (srate < 1500000) {
522 aclk = 0xb7;
523 bclk = 0x47;
524 } else if (srate < 3000000) {
525 aclk = 0xb7;
526 bclk = 0x4b;
527 } else if (srate < 7000000) {
528 aclk = 0xb7;
529 bclk = 0x4f;
530 } else if (srate < 14000000) {
531 aclk = 0xb7;
532 bclk = 0x53;
533 } else if (srate < 30000000) {
534 aclk = 0xb6;
535 bclk = 0x53;
536 } else if (srate < 45000000) {
537 aclk = 0xb4;
538 bclk = 0x51;
539 }
540
541 stv0299_writereg(fe, 0x13, aclk);
542 stv0299_writereg(fe, 0x14, bclk);
543 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
544 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
545 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
546
547 return 0;
548}
549
550static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
551{
552 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
553 u8 buf[4];
554 u32 div;
555 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
556
557 if ((params->frequency < 950000) || (params->frequency > 2150000))
558 return -EINVAL;
559
560 div = (params->frequency + (125 - 1)) / 125; // round correctly
561 buf[0] = (div >> 8) & 0x7f;
562 buf[1] = div & 0xff;
563 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
564 buf[3] = 0xC4;
565
566 if (params->frequency > 1530000)
567 buf[3] = 0xc0;
568
569 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
570 return -EIO;
571 return 0;
572}
573
574static struct stv0299_config alps_bsru6_config = {
575
576 .demod_address = 0x68,
577 .inittab = alps_bsru6_inittab,
578 .mclk = 88000000UL,
579 .invert = 1,
580 .enhanced_tuning = 0,
581 .skip_reinit = 0,
582 .lock_output = STV0229_LOCKOUTPUT_1,
583 .volt13_op0_op1 = STV0299_VOLT13_OP1,
584 .min_delay_ms = 100,
585 .set_symbol_rate = alps_bsru6_set_symbol_rate,
586 .pll_set = alps_bsru6_pll_set,
587};
588
589
590
591
592static u8 philips_su1278_tt_inittab[] = {
593 0x01, 0x0f,
594 0x02, 0x30,
595 0x03, 0x00,
596 0x04, 0x5b,
597 0x05, 0x85,
598 0x06, 0x02,
599 0x07, 0x00,
600 0x08, 0x02,
601 0x09, 0x00,
602 0x0C, 0x01,
603 0x0D, 0x81,
604 0x0E, 0x44,
605 0x0f, 0x14,
606 0x10, 0x3c,
607 0x11, 0x84,
608 0x12, 0xda,
609 0x13, 0x97,
610 0x14, 0x95,
611 0x15, 0xc9,
612 0x16, 0x19,
613 0x17, 0x8c,
614 0x18, 0x59,
615 0x19, 0xf8,
616 0x1a, 0xfe,
617 0x1c, 0x7f,
618 0x1d, 0x00,
619 0x1e, 0x00,
620 0x1f, 0x50,
621 0x20, 0x00,
622 0x21, 0x00,
623 0x22, 0x00,
624 0x23, 0x00,
625 0x28, 0x00,
626 0x29, 0x28,
627 0x2a, 0x14,
628 0x2b, 0x0f,
629 0x2c, 0x09,
630 0x2d, 0x09,
631 0x31, 0x1f,
632 0x32, 0x19,
633 0x33, 0xfc,
634 0x34, 0x93,
635 0xff, 0xff
636};
637
638static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
639{
640 stv0299_writereg(fe, 0x0e, 0x44);
641 if (srate >= 10000000) {
642 stv0299_writereg(fe, 0x13, 0x97);
643 stv0299_writereg(fe, 0x14, 0x95);
644 stv0299_writereg(fe, 0x15, 0xc9);
645 stv0299_writereg(fe, 0x17, 0x8c);
646 stv0299_writereg(fe, 0x1a, 0xfe);
647 stv0299_writereg(fe, 0x1c, 0x7f);
648 stv0299_writereg(fe, 0x2d, 0x09);
649 } else {
650 stv0299_writereg(fe, 0x13, 0x99);
651 stv0299_writereg(fe, 0x14, 0x8d);
652 stv0299_writereg(fe, 0x15, 0xce);
653 stv0299_writereg(fe, 0x17, 0x43);
654 stv0299_writereg(fe, 0x1a, 0x1d);
655 stv0299_writereg(fe, 0x1c, 0x12);
656 stv0299_writereg(fe, 0x2d, 0x05);
657 }
658 stv0299_writereg(fe, 0x0e, 0x23);
659 stv0299_writereg(fe, 0x0f, 0x94);
660 stv0299_writereg(fe, 0x10, 0x39);
661 stv0299_writereg(fe, 0x15, 0xc9);
662
663 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
664 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
665 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
666
667 return 0;
668}
669
670static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
671 struct dvb_frontend_parameters *params)
672{
673 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
674 u32 div;
675 u8 buf[4];
676 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
677
678 if ((params->frequency < 950000) || (params->frequency > 2150000))
679 return -EINVAL;
680
681 div = (params->frequency + (500 - 1)) / 500; // round correctly
682 buf[0] = (div >> 8) & 0x7f;
683 buf[1] = div & 0xff;
684 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
685 buf[3] = 0x20;
686
687 if (params->u.qpsk.symbol_rate < 4000000)
688 buf[3] |= 1;
689
690 if (params->frequency < 1250000)
691 buf[3] |= 0;
692 else if (params->frequency < 1550000)
693 buf[3] |= 0x40;
694 else if (params->frequency < 2050000)
695 buf[3] |= 0x80;
696 else if (params->frequency < 2150000)
697 buf[3] |= 0xC0;
698
699 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
700 return -EIO;
701 return 0;
702}
703
704static struct stv0299_config philips_su1278_tt_config = {
705
706 .demod_address = 0x68,
707 .inittab = philips_su1278_tt_inittab,
708 .mclk = 64000000UL,
709 .invert = 0,
710 .enhanced_tuning = 1,
711 .skip_reinit = 1,
712 .lock_output = STV0229_LOCKOUTPUT_1,
713 .volt13_op0_op1 = STV0299_VOLT13_OP1,
714 .min_delay_ms = 50,
715 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
716 .pll_set = philips_su1278_tt_pll_set,
717};
718
719
720
721static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
722{
723 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
724 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
725 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
726 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len =
727 sizeof(td1316_init) };
728
729 // setup PLL configuration
730 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
731 return -EIO;
732 msleep(1);
733
734 // disable the mc44BC374c (do not check for errors)
735 tuner_msg.addr = 0x65;
736 tuner_msg.buf = disable_mc44BC374c;
737 tuner_msg.len = sizeof(disable_mc44BC374c);
738 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
739 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
740 }
741
742 return 0;
743}
744
745static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
746{
747 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
748 u8 tuner_buf[4];
749 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
750 int tuner_frequency = 0;
751 u8 band, cp, filter;
752
753 // determine charge pump
754 tuner_frequency = params->frequency + 36130000;
755 if (tuner_frequency < 87000000)
756 return -EINVAL;
757 else if (tuner_frequency < 130000000)
758 cp = 3;
759 else if (tuner_frequency < 160000000)
760 cp = 5;
761 else if (tuner_frequency < 200000000)
762 cp = 6;
763 else if (tuner_frequency < 290000000)
764 cp = 3;
765 else if (tuner_frequency < 420000000)
766 cp = 5;
767 else if (tuner_frequency < 480000000)
768 cp = 6;
769 else if (tuner_frequency < 620000000)
770 cp = 3;
771 else if (tuner_frequency < 830000000)
772 cp = 5;
773 else if (tuner_frequency < 895000000)
774 cp = 7;
775 else
776 return -EINVAL;
777
778 // determine band
779 if (params->frequency < 49000000)
780 return -EINVAL;
781 else if (params->frequency < 159000000)
782 band = 1;
783 else if (params->frequency < 444000000)
784 band = 2;
785 else if (params->frequency < 861000000)
786 band = 4;
787 else
788 return -EINVAL;
789
790 // setup PLL filter and TDA9889
791 switch (params->u.ofdm.bandwidth) {
792 case BANDWIDTH_6_MHZ:
793 tda1004x_write_byte(fe, 0x0C, 0x14);
794 filter = 0;
795 break;
796
797 case BANDWIDTH_7_MHZ:
798 tda1004x_write_byte(fe, 0x0C, 0x80);
799 filter = 0;
800 break;
801
802 case BANDWIDTH_8_MHZ:
803 tda1004x_write_byte(fe, 0x0C, 0x14);
804 filter = 1;
805 break;
806
807 default:
808 return -EINVAL;
809 }
810
811 // calculate divisor
812 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
813 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
814
815 // setup tuner buffer
816 tuner_buf[0] = tuner_frequency >> 8;
817 tuner_buf[1] = tuner_frequency & 0xff;
818 tuner_buf[2] = 0xca;
819 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
820
821 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
822 return -EIO;
823
824 msleep(1);
825 return 0;
826}
827
828static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
829 const struct firmware **fw, char *name)
830{
831 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
832
833 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
834}
835
836static struct tda1004x_config philips_tdm1316l_config = {
837
838 .demod_address = 0x8,
839 .invert = 0,
840 .invert_oclk = 0,
841 .pll_init = philips_tdm1316l_pll_init,
842 .pll_set = philips_tdm1316l_pll_set,
843 .request_firmware = philips_tdm1316l_request_firmware,
844};
845
846
847
848static void frontend_init(struct budget_ci *budget_ci)
849{
850 switch (budget_ci->budget.dev->pci->subsystem_device) {
851 case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
852 budget_ci->budget.dvb_frontend =
853 stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
854 if (budget_ci->budget.dvb_frontend) {
855 break;
856 }
857 break;
858
859 case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
860 budget_ci->budget.dvb_frontend =
861 stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
862 if (budget_ci->budget.dvb_frontend) {
863 break;
864 }
865 break;
866
867 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
868 budget_ci->budget.dvb_frontend =
869 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
870 if (budget_ci->budget.dvb_frontend) {
871 break;
872 }
873 break;
874 }
875
876 if (budget_ci->budget.dvb_frontend == NULL) {
877 printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
878 budget_ci->budget.dev->pci->vendor,
879 budget_ci->budget.dev->pci->device,
880 budget_ci->budget.dev->pci->subsystem_vendor,
881 budget_ci->budget.dev->pci->subsystem_device);
882 } else {
883 if (dvb_register_frontend
884 (budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
885 printk("budget-ci: Frontend registration failed!\n");
886 if (budget_ci->budget.dvb_frontend->ops->release)
887 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
888 budget_ci->budget.dvb_frontend = NULL;
889 }
890 }
891}
892
893static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
894{
895 struct budget_ci *budget_ci;
896 int err;
897
898 if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL)))
899 return -ENOMEM;
900
901 dprintk(2, "budget_ci: %p\n", budget_ci);
902
903 budget_ci->budget.ci_present = 0;
904
905 dev->ext_priv = budget_ci;
906
907 if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
908 kfree(budget_ci);
909 return err;
910 }
911
912 tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
913 (unsigned long) budget_ci);
914
915 msp430_ir_init(budget_ci);
916
917 ciintf_init(budget_ci);
918
919 budget_ci->budget.dvb_adapter->priv = budget_ci;
920 frontend_init(budget_ci);
921
922 return 0;
923}
924
925static int budget_ci_detach(struct saa7146_dev *dev)
926{
927 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
928 struct saa7146_dev *saa = budget_ci->budget.dev;
929 int err;
930
931 if (budget_ci->budget.ci_present)
932 ciintf_deinit(budget_ci);
933 if (budget_ci->budget.dvb_frontend)
934 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
935 err = ttpci_budget_deinit(&budget_ci->budget);
936
937 tasklet_kill(&budget_ci->msp430_irq_tasklet);
938
939 msp430_ir_deinit(budget_ci);
940
941 // disable frontend and CI interface
942 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
943
944 kfree(budget_ci);
945
946 return err;
947}
948
949static struct saa7146_extension budget_extension;
950
951MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
952MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
953
954static struct pci_device_id pci_tbl[] = {
955 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
956 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
957 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
958 {
959 .vendor = 0,
960 }
961};
962
963MODULE_DEVICE_TABLE(pci, pci_tbl);
964
965static struct saa7146_extension budget_extension = {
966 .name = "budget_ci dvb\0",
967 .flags = 0,
968
969 .module = THIS_MODULE,
970 .pci_tbl = &pci_tbl[0],
971 .attach = budget_ci_attach,
972 .detach = budget_ci_detach,
973
974 .irq_mask = MASK_03 | MASK_06 | MASK_10,
975 .irq_func = budget_ci_irq,
976};
977
978static int __init budget_ci_init(void)
979{
980 return saa7146_register_extension(&budget_extension);
981}
982
983static void __exit budget_ci_exit(void)
984{
985 saa7146_unregister_extension(&budget_extension);
986}
987
988module_init(budget_ci_init);
989module_exit(budget_ci_exit);
990
991MODULE_LICENSE("GPL");
992MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
993MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
994 "budget PCI DVB cards w/ CI-module produced by "
995 "Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
new file mode 100644
index 000000000000..93a9b40917e4
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -0,0 +1,480 @@
1/*
2 * budget-core.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * Copyright (C) 1999-2002 Ralph Metzler
9 * & Marcus Metzler for convergence integrated media GmbH
10 *
11 * 26feb2004 Support for FS Activy Card (Grundig tuner) by
12 * Michael Dreher <michael@5dot1.de>,
13 * Oliver Endriss <o.endriss@gmx.de>,
14 * Andreas 'randy' Weinberger
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
32 *
33 *
34 * the project's page is at http://www.linuxtv.org/dvb/
35 */
36
37#include <linux/moduleparam.h>
38
39#include "budget.h"
40#include "ttpci-eeprom.h"
41
42int budget_debug;
43module_param_named(debug, budget_debug, int, 0644);
44MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
45
46/****************************************************************************
47 * TT budget / WinTV Nova
48 ****************************************************************************/
49
50static int stop_ts_capture(struct budget *budget)
51{
52 dprintk(2, "budget: %p\n", budget);
53
54 if (--budget->feeding)
55 return budget->feeding;
56
57 saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
58 SAA7146_IER_DISABLE(budget->dev, MASK_10);
59 return 0;
60}
61
62static int start_ts_capture(struct budget *budget)
63{
64 struct saa7146_dev *dev = budget->dev;
65
66 dprintk(2, "budget: %p\n", budget);
67
68 if (budget->feeding)
69 return ++budget->feeding;
70
71 saa7146_write(dev, MC1, MASK_20); // DMA3 off
72
73 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
74
75 saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
76
77 budget->tsf = 0xff;
78 budget->ttbp = 0;
79
80 /*
81 * Signal path on the Activy:
82 *
83 * tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory
84 *
85 * Since the tuner feeds 204 bytes packets into the SAA7146,
86 * DMA3 is configured to strip the trailing 16 FEC bytes:
87 * Pitch: 188, NumBytes3: 188, NumLines3: 1024
88 */
89
90 switch(budget->card->type) {
91 case BUDGET_FS_ACTIVY:
92 saa7146_write(dev, DD1_INIT, 0x04000000);
93 saa7146_write(dev, MC2, (MASK_09 | MASK_25));
94 saa7146_write(dev, BRS_CTRL, 0x00000000);
95 break;
96 case BUDGET_PATCH:
97 saa7146_write(dev, DD1_INIT, 0x00000200);
98 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
99 saa7146_write(dev, BRS_CTRL, 0x60000000);
100 break;
101 default:
102 if (budget->video_port == BUDGET_VIDEO_PORTA) {
103 saa7146_write(dev, DD1_INIT, 0x06000200);
104 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
105 saa7146_write(dev, BRS_CTRL, 0x00000000);
106 } else {
107 saa7146_write(dev, DD1_INIT, 0x02000600);
108 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
109 saa7146_write(dev, BRS_CTRL, 0x60000000);
110 }
111 }
112
113 saa7146_write(dev, MC2, (MASK_08 | MASK_24));
114 mdelay(10);
115
116 saa7146_write(dev, BASE_ODD3, 0);
117 saa7146_write(dev, BASE_EVEN3, 0);
118 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
119 saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
120
121 if (budget->card->type == BUDGET_FS_ACTIVY) {
122 saa7146_write(dev, PITCH3, TS_WIDTH / 2);
123 saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT * 2) << 16) | (TS_WIDTH / 2));
124 } else {
125 saa7146_write(dev, PITCH3, TS_WIDTH);
126 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
127 }
128
129 saa7146_write(dev, MC2, (MASK_04 | MASK_20));
130
131 SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */
132 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
133 saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
134
135 return ++budget->feeding;
136}
137
138static void vpeirq(unsigned long data)
139{
140 struct budget *budget = (struct budget *) data;
141 u8 *mem = (u8 *) (budget->grabbing);
142 u32 olddma = budget->ttbp;
143 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
144
145 /* nearest lower position divisible by 188 */
146 newdma -= newdma % 188;
147
148 if (newdma >= TS_BUFLEN)
149 return;
150
151 budget->ttbp = newdma;
152
153 if (budget->feeding == 0 || newdma == olddma)
154 return;
155
156 if (newdma > olddma) { /* no wraparound, dump olddma..newdma */
157 dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (newdma - olddma) / 188);
158 } else { /* wraparound, dump olddma..buflen and 0..newdma */
159 dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
160 dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
161 }
162}
163
164
165int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
166 int uselocks, int nobusyloop)
167{
168 struct saa7146_dev *saa = budget->dev;
169 int result = 0;
170 unsigned long flags = 0;
171
172 if (count > 4 || count <= 0)
173 return 0;
174
175 if (uselocks)
176 spin_lock_irqsave(&budget->debilock, flags);
177
178 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
179 if (uselocks)
180 spin_unlock_irqrestore(&budget->debilock, flags);
181 return result;
182 }
183
184 saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
185 saa7146_write(saa, DEBI_CONFIG, config);
186 saa7146_write(saa, DEBI_PAGE, 0);
187 saa7146_write(saa, MC2, (2 << 16) | 2);
188
189 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
190 if (uselocks)
191 spin_unlock_irqrestore(&budget->debilock, flags);
192 return result;
193 }
194
195 result = saa7146_read(saa, DEBI_AD);
196 result &= (0xffffffffUL >> ((4 - count) * 8));
197
198 if (uselocks)
199 spin_unlock_irqrestore(&budget->debilock, flags);
200
201 return result;
202}
203
204int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr,
205 int count, u32 value, int uselocks, int nobusyloop)
206{
207 struct saa7146_dev *saa = budget->dev;
208 unsigned long flags = 0;
209 int result;
210
211 if (count > 4 || count <= 0)
212 return 0;
213
214 if (uselocks)
215 spin_lock_irqsave(&budget->debilock, flags);
216
217 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
218 if (uselocks)
219 spin_unlock_irqrestore(&budget->debilock, flags);
220 return result;
221 }
222
223 saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff));
224 saa7146_write(saa, DEBI_CONFIG, config);
225 saa7146_write(saa, DEBI_PAGE, 0);
226 saa7146_write(saa, DEBI_AD, value);
227 saa7146_write(saa, MC2, (2 << 16) | 2);
228
229 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
230 if (uselocks)
231 spin_unlock_irqrestore(&budget->debilock, flags);
232 return result;
233 }
234
235 if (uselocks)
236 spin_unlock_irqrestore(&budget->debilock, flags);
237 return 0;
238}
239
240
241/****************************************************************************
242 * DVB API SECTION
243 ****************************************************************************/
244
245static int budget_start_feed(struct dvb_demux_feed *feed)
246{
247 struct dvb_demux *demux = feed->demux;
248 struct budget *budget = (struct budget *) demux->priv;
249 int status;
250
251 dprintk(2, "budget: %p\n", budget);
252
253 if (!demux->dmx.frontend)
254 return -EINVAL;
255
256 spin_lock(&budget->feedlock);
257 feed->pusi_seen = 0; /* have a clean section start */
258 status = start_ts_capture(budget);
259 spin_unlock(&budget->feedlock);
260 return status;
261}
262
263static int budget_stop_feed(struct dvb_demux_feed *feed)
264{
265 struct dvb_demux *demux = feed->demux;
266 struct budget *budget = (struct budget *) demux->priv;
267 int status;
268
269 dprintk(2, "budget: %p\n", budget);
270
271 spin_lock(&budget->feedlock);
272 status = stop_ts_capture(budget);
273 spin_unlock(&budget->feedlock);
274 return status;
275}
276
277static int budget_register(struct budget *budget)
278{
279 struct dvb_demux *dvbdemux = &budget->demux;
280 int ret;
281
282 dprintk(2, "budget: %p\n", budget);
283
284 dvbdemux->priv = (void *) budget;
285
286 dvbdemux->filternum = 256;
287 dvbdemux->feednum = 256;
288 dvbdemux->start_feed = budget_start_feed;
289 dvbdemux->stop_feed = budget_stop_feed;
290 dvbdemux->write_to_decoder = NULL;
291
292 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
293 DMX_MEMORY_BASED_FILTERING);
294
295 dvb_dmx_init(&budget->demux);
296
297 budget->dmxdev.filternum = 256;
298 budget->dmxdev.demux = &dvbdemux->dmx;
299 budget->dmxdev.capabilities = 0;
300
301 dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
302
303 budget->hw_frontend.source = DMX_FRONTEND_0;
304
305 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
306
307 if (ret < 0)
308 return ret;
309
310 budget->mem_frontend.source = DMX_MEMORY_FE;
311 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
312 if (ret < 0)
313 return ret;
314
315 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);
316 if (ret < 0)
317 return ret;
318
319 dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
320
321 return 0;
322}
323
324static void budget_unregister(struct budget *budget)
325{
326 struct dvb_demux *dvbdemux = &budget->demux;
327
328 dprintk(2, "budget: %p\n", budget);
329
330 dvb_net_release(&budget->dvb_net);
331
332 dvbdemux->dmx.close(&dvbdemux->dmx);
333 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
334 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
335
336 dvb_dmxdev_release(&budget->dmxdev);
337 dvb_dmx_release(&budget->demux);
338}
339
340int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
341 struct saa7146_pci_extension_data *info,
342 struct module *owner)
343{
344 int length = TS_WIDTH * TS_HEIGHT;
345 int ret = 0;
346 struct budget_info *bi = info->ext_priv;
347
348 memset(budget, 0, sizeof(struct budget));
349
350 dprintk(2, "dev: %p, budget: %p\n", dev, budget);
351
352 budget->card = bi;
353 budget->dev = (struct saa7146_dev *) dev;
354
355 dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner);
356
357 /* set dd1 stream a & b */
358 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
359 saa7146_write(dev, MC2, (MASK_09 | MASK_25));
360 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
361 saa7146_write(dev, DD1_INIT, 0x02000000);
362 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
363
364 if (bi->type != BUDGET_FS_ACTIVY)
365 budget->video_port = BUDGET_VIDEO_PORTB;
366 else
367 budget->video_port = BUDGET_VIDEO_PORTA;
368 spin_lock_init(&budget->feedlock);
369 spin_lock_init(&budget->debilock);
370
371 /* the Siemens DVB needs this if you want to have the i2c chips
372 get recognized before the main driver is loaded */
373 if (bi->type != BUDGET_FS_ACTIVY)
374 saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */
375
376#ifdef I2C_ADAP_CLASS_TV_DIGITAL
377 budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
378#else
379 budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
380#endif
381
382 strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
383
384 saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
385 strcpy(budget->i2c_adap.name, budget->card->name);
386
387 if (i2c_add_adapter(&budget->i2c_adap) < 0) {
388 dvb_unregister_adapter(budget->dvb_adapter);
389 return -ENOMEM;
390 }
391
392 ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac);
393
394 if (NULL ==
395 (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) {
396 ret = -ENOMEM;
397 goto err;
398 }
399
400 saa7146_write(dev, PCI_BT_V1, 0x001c0000);
401 /* upload all */
402 saa7146_write(dev, GPIO_CTRL, 0x000000);
403
404 tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
405
406 /* frontend power on */
407 if (bi->type == BUDGET_FS_ACTIVY)
408 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
409 else
410 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
411
412 if (budget_register(budget) == 0) {
413 return 0;
414 }
415err:
416 i2c_del_adapter(&budget->i2c_adap);
417
418 vfree(budget->grabbing);
419
420 dvb_unregister_adapter(budget->dvb_adapter);
421
422 return ret;
423}
424
425int ttpci_budget_deinit(struct budget *budget)
426{
427 struct saa7146_dev *dev = budget->dev;
428
429 dprintk(2, "budget: %p\n", budget);
430
431 budget_unregister(budget);
432
433 i2c_del_adapter(&budget->i2c_adap);
434
435 dvb_unregister_adapter(budget->dvb_adapter);
436
437 tasklet_kill(&budget->vpe_tasklet);
438
439 saa7146_pgtable_free(dev->pci, &budget->pt);
440
441 vfree(budget->grabbing);
442
443 return 0;
444}
445
446void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr)
447{
448 struct budget *budget = (struct budget *) dev->ext_priv;
449
450 dprintk(8, "dev: %p, budget: %p\n", dev, budget);
451
452 if (*isr & MASK_10)
453 tasklet_schedule(&budget->vpe_tasklet);
454}
455
456void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
457{
458 struct budget *budget = (struct budget *) dev->ext_priv;
459
460 spin_lock(&budget->feedlock);
461 budget->video_port = video_port;
462 if (budget->feeding) {
463 int oldfeeding = budget->feeding;
464 budget->feeding = 1;
465 stop_ts_capture(budget);
466 start_ts_capture(budget);
467 budget->feeding = oldfeeding;
468 }
469 spin_unlock(&budget->feedlock);
470}
471
472EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
473EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
474EXPORT_SYMBOL_GPL(ttpci_budget_init);
475EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
476EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
477EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
478EXPORT_SYMBOL_GPL(budget_debug);
479
480MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
new file mode 100644
index 000000000000..5d524a4f213f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -0,0 +1,754 @@
1/*
2 * budget-patch.c: driver for Budget Patch,
3 * hardware modification of DVB-S cards enabling full TS
4 *
5 * Written by Emard <emard@softhome.net>
6 *
7 * Original idea by Roberto Deza <rdeza@unav.es>
8 *
9 * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
10 * and Metzlerbros
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 *
29 *
30 * the project's page is at http://www.linuxtv.org/dvb/
31 */
32
33#include "av7110.h"
34#include "av7110_hw.h"
35#include "budget.h"
36#include "stv0299.h"
37#include "ves1x93.h"
38#include "tda8083.h"
39
40#define budget_patch budget
41
42static struct saa7146_extension budget_extension;
43
44MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
45//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
46
47static struct pci_device_id pci_tbl[] = {
48 MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
49// MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
50 {
51 .vendor = 0,
52 }
53};
54
55/* those lines are for budget-patch to be tried
56** on a true budget card and observe the
57** behaviour of VSYNC generated by rps1.
58** this code was shamelessly copy/pasted from budget.c
59*/
60static void gpio_Set22K (struct budget *budget, int state)
61{
62 struct saa7146_dev *dev=budget->dev;
63 dprintk(2, "budget: %p\n", budget);
64 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
65}
66
67/* Diseqc functions only for TT Budget card */
68/* taken from the Skyvision DVB driver by
69 Ralph Metzler <rjkm@metzlerbros.de> */
70
71static void DiseqcSendBit (struct budget *budget, int data)
72{
73 struct saa7146_dev *dev=budget->dev;
74 dprintk(2, "budget: %p\n", budget);
75
76 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
77 udelay(data ? 500 : 1000);
78 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
79 udelay(data ? 1000 : 500);
80}
81
82static void DiseqcSendByte (struct budget *budget, int data)
83{
84 int i, par=1, d;
85
86 dprintk(2, "budget: %p\n", budget);
87
88 for (i=7; i>=0; i--) {
89 d = (data>>i)&1;
90 par ^= d;
91 DiseqcSendBit(budget, d);
92 }
93
94 DiseqcSendBit(budget, par);
95}
96
97static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
98{
99 struct saa7146_dev *dev=budget->dev;
100 int i;
101
102 dprintk(2, "budget: %p\n", budget);
103
104 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
105 mdelay(16);
106
107 for (i=0; i<len; i++)
108 DiseqcSendByte(budget, msg[i]);
109
110 mdelay(16);
111
112 if (burst!=-1) {
113 if (burst)
114 DiseqcSendByte(budget, 0xff);
115 else {
116 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
117 udelay(12500);
118 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
119 }
120 msleep(20);
121 }
122
123 return 0;
124}
125
126/* shamelessly copy/pasted from budget.c
127*/
128static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
129{
130 struct budget* budget = (struct budget*) fe->dvb->priv;
131
132 switch (tone) {
133 case SEC_TONE_ON:
134 gpio_Set22K (budget, 1);
135 break;
136
137 case SEC_TONE_OFF:
138 gpio_Set22K (budget, 0);
139 break;
140
141 default:
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
149{
150 struct budget* budget = (struct budget*) fe->dvb->priv;
151
152 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
153
154 return 0;
155}
156
157static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
158{
159 struct budget* budget = (struct budget*) fe->dvb->priv;
160
161 SendDiSEqCMsg (budget, 0, NULL, minicmd);
162
163 return 0;
164}
165
166static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
167{
168 int i;
169
170 dprintk(2, "budget: %p\n", budget);
171
172 for (i = 2; i < length; i++)
173 {
174 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
175 msleep(5);
176 }
177 if (length)
178 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
179 else
180 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
181 msleep(5);
182 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
183 msleep(5);
184 return 0;
185}
186
187static void av7110_set22k(struct budget_patch *budget, int state)
188{
189 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
190
191 dprintk(2, "budget: %p\n", budget);
192 budget_av7110_send_fw_cmd(budget, buf, 2);
193}
194
195static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
196{
197 int i;
198 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
199 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
200
201 dprintk(2, "budget: %p\n", budget);
202
203 if (len>10)
204 len=10;
205
206 buf[1] = len+2;
207 buf[2] = len;
208
209 if (burst != -1)
210 buf[3]=burst ? 0x01 : 0x00;
211 else
212 buf[3]=0xffff;
213
214 for (i=0; i<len; i++)
215 buf[i+4]=msg[i];
216
217 budget_av7110_send_fw_cmd(budget, buf, 18);
218 return 0;
219}
220
221static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
222{
223 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
224
225 switch (tone) {
226 case SEC_TONE_ON:
227 av7110_set22k (budget, 1);
228 break;
229
230 case SEC_TONE_OFF:
231 av7110_set22k (budget, 0);
232 break;
233
234 default:
235 return -EINVAL;
236 }
237
238 return 0;
239}
240
241static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
242{
243 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
244
245 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
246
247 return 0;
248}
249
250static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
251{
252 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
253
254 av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
255
256 return 0;
257}
258
259static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
260{
261 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
262 u8 pwr = 0;
263 u8 buf[4];
264 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
265 u32 div = (params->frequency + 479500) / 125;
266
267 if (params->frequency > 2000000) pwr = 3;
268 else if (params->frequency > 1800000) pwr = 2;
269 else if (params->frequency > 1600000) pwr = 1;
270 else if (params->frequency > 1200000) pwr = 0;
271 else if (params->frequency >= 1100000) pwr = 1;
272 else pwr = 2;
273
274 buf[0] = (div >> 8) & 0x7f;
275 buf[1] = div & 0xff;
276 buf[2] = ((div & 0x18000) >> 10) | 0x95;
277 buf[3] = (pwr << 6) | 0x30;
278
279 // NOTE: since we're using a prescaler of 2, we set the
280 // divisor frequency to 62.5kHz and divide by 125 above
281
282 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
283 return 0;
284}
285
286static struct ves1x93_config alps_bsrv2_config = {
287 .demod_address = 0x08,
288 .xin = 90100000UL,
289 .invert_pwm = 0,
290 .pll_set = alps_bsrv2_pll_set,
291};
292
293static u8 alps_bsru6_inittab[] = {
294 0x01, 0x15,
295 0x02, 0x00,
296 0x03, 0x00,
297 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
298 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
299 0x06, 0x40, /* DAC not used, set to high impendance mode */
300 0x07, 0x00, /* DAC LSB */
301 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
302 0x09, 0x00, /* FIFO */
303 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
304 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00,
311 0x17, 0x00,
312 0x18, 0x00,
313 0x19, 0x00,
314 0x1a, 0x00,
315 0x1f, 0x50,
316 0x20, 0x00,
317 0x21, 0x00,
318 0x22, 0x00,
319 0x23, 0x00,
320 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
321 0x29, 0x1e, // 1/2 threshold
322 0x2a, 0x14, // 2/3 threshold
323 0x2b, 0x0f, // 3/4 threshold
324 0x2c, 0x09, // 5/6 threshold
325 0x2d, 0x05, // 7/8 threshold
326 0x2e, 0x01,
327 0x31, 0x1f, // test all FECs
328 0x32, 0x19, // viterbi and synchro search
329 0x33, 0xfc, // rs control
330 0x34, 0x93, // error control
331 0x0f, 0x52,
332 0xff, 0xff
333};
334
335static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
336{
337 u8 aclk = 0;
338 u8 bclk = 0;
339
340 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
341 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
342 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
343 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
344 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
345 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
346
347 stv0299_writereg (fe, 0x13, aclk);
348 stv0299_writereg (fe, 0x14, bclk);
349 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
350 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
351 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
352
353 return 0;
354}
355
356static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
357{
358 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
359 u8 data[4];
360 u32 div;
361 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
362
363 if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
364
365 div = (params->frequency + (125 - 1)) / 125; // round correctly
366 data[0] = (div >> 8) & 0x7f;
367 data[1] = div & 0xff;
368 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
369 data[3] = 0xC4;
370
371 if (params->frequency > 1530000) data[3] = 0xc0;
372
373 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
374 return 0;
375}
376
377static struct stv0299_config alps_bsru6_config = {
378
379 .demod_address = 0x68,
380 .inittab = alps_bsru6_inittab,
381 .mclk = 88000000UL,
382 .invert = 1,
383 .enhanced_tuning = 0,
384 .skip_reinit = 0,
385 .lock_output = STV0229_LOCKOUTPUT_1,
386 .volt13_op0_op1 = STV0299_VOLT13_OP1,
387 .min_delay_ms = 100,
388 .set_symbol_rate = alps_bsru6_set_symbol_rate,
389 .pll_set = alps_bsru6_pll_set,
390};
391
392static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
393{
394 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
395 u32 div;
396 u8 data[4];
397 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
398
399 div = params->frequency / 125;
400 data[0] = (div >> 8) & 0x7f;
401 data[1] = div & 0xff;
402 data[2] = 0x8e;
403 data[3] = 0x00;
404
405 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
406 return 0;
407}
408
409static struct tda8083_config grundig_29504_451_config = {
410 .demod_address = 0x68,
411 .pll_set = grundig_29504_451_pll_set,
412};
413
414static void frontend_init(struct budget_patch* budget)
415{
416 switch(budget->dev->pci->subsystem_device) {
417 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
418 case 0x1013: // SATELCO Multimedia PCI
419
420 // try the ALPS BSRV2 first of all
421 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
422 if (budget->dvb_frontend) {
423 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
424 budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst;
425 budget->dvb_frontend->ops->set_tone = budget_patch_set_tone;
426 break;
427 }
428
429 // try the ALPS BSRU6 now
430 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
431 if (budget->dvb_frontend) {
432 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
433 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
434 budget->dvb_frontend->ops->set_tone = budget_set_tone;
435 break;
436 }
437
438 // Try the grundig 29504-451
439 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
440 if (budget->dvb_frontend) {
441 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
442 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
443 budget->dvb_frontend->ops->set_tone = budget_set_tone;
444 break;
445 }
446 break;
447 }
448
449 if (budget->dvb_frontend == NULL) {
450 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
451 budget->dev->pci->vendor,
452 budget->dev->pci->device,
453 budget->dev->pci->subsystem_vendor,
454 budget->dev->pci->subsystem_device);
455 } else {
456 if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
457 printk("budget-av: Frontend registration failed!\n");
458 if (budget->dvb_frontend->ops->release)
459 budget->dvb_frontend->ops->release(budget->dvb_frontend);
460 budget->dvb_frontend = NULL;
461 }
462 }
463}
464
465/* written by Emard */
466static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
467{
468 struct budget_patch *budget;
469 int err;
470 int count = 0;
471 int detected = 0;
472
473#define PATCH_RESET 0
474#define RPS_IRQ 0
475#define HPS_SETUP 0
476#if PATCH_RESET
477 saa7146_write(dev, MC1, MASK_31);
478 msleep(40);
479#endif
480#if HPS_SETUP
481 // initialize registers. Better to have it like this
482 // than leaving something unconfigured
483 saa7146_write(dev, DD1_STREAM_B, 0);
484 // port B VSYNC at rising edge
485 saa7146_write(dev, DD1_INIT, 0x00000200); // have this in budget-core too!
486 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
487
488 // debi config
489 // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
490
491 // zero all HPS registers
492 saa7146_write(dev, HPS_H_PRESCALE, 0); // r68
493 saa7146_write(dev, HPS_H_SCALE, 0); // r6c
494 saa7146_write(dev, BCS_CTRL, 0); // r70
495 saa7146_write(dev, HPS_V_SCALE, 0); // r60
496 saa7146_write(dev, HPS_V_GAIN, 0); // r64
497 saa7146_write(dev, CHROMA_KEY_RANGE, 0); // r74
498 saa7146_write(dev, CLIP_FORMAT_CTRL, 0); // r78
499 // Set HPS prescaler for port B input
500 saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
501 saa7146_write(dev, MC2,
502 0 * (MASK_08 | MASK_24) | // BRS control
503 0 * (MASK_09 | MASK_25) | // a
504 0 * (MASK_10 | MASK_26) | // b
505 1 * (MASK_06 | MASK_22) | // HPS_CTRL1
506 1 * (MASK_05 | MASK_21) | // HPS_CTRL2
507 0 * (MASK_01 | MASK_15) // DEBI
508 );
509#endif
510 // Disable RPS1 and RPS0
511 saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
512 // RPS1 timeout disable
513 saa7146_write(dev, RPS_TOV1, 0);
514
515 // code for autodetection
516 // will wait for VBI_B event (vertical blank at port B)
517 // and will reset GPIO3 after VBI_B is detected.
518 // (GPIO3 should be raised high by CPU to
519 // test if GPIO3 will generate vertical blank signal
520 // in budget patch GPIO3 is connected to VSYNC_B
521 count = 0;
522#if 0
523 WRITE_RPS1(cpu_to_le32(CMD_UPLOAD |
524 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
525#endif
526 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
527 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
528 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
529 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
530#if RPS_IRQ
531 // issue RPS1 interrupt to increment counter
532 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
533 // at least a NOP is neede between two interrupts
534 WRITE_RPS1(cpu_to_le32(CMD_NOP));
535 // interrupt again
536 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
537#endif
538 WRITE_RPS1(cpu_to_le32(CMD_STOP));
539
540#if RPS_IRQ
541 // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
542 // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
543 // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
544 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
545 // set event counter 1 treshold to maximum allowed value (rEC p55)
546 saa7146_write(dev, ECT1R, 0x3fff );
547#endif
548 // Fix VSYNC level
549 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
550 // Set RPS1 Address register to point to RPS code (r108 p42)
551 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
552 // Enable RPS1, (rFC p33)
553 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
554
555
556 mdelay(50);
557 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
558 mdelay(150);
559
560
561 if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
562 detected = 1;
563
564#if RPS_IRQ
565 printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
566#endif
567 // Disable RPS1
568 saa7146_write(dev, MC1, ( MASK_29 ));
569
570 if(detected == 0)
571 printk("budget-patch not detected or saa7146 in non-default state.\n"
572 "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
573
574 else
575 printk("BUDGET-PATCH DETECTED.\n");
576
577
578/* OLD (Original design by Roberto Deza):
579** This code will setup the SAA7146_RPS1 to generate a square
580** wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
581** TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
582** then, this GPIO3 output which is connected to the D1B_VSYNC
583** input, will trigger the acquisition of the alternate field
584** and so on.
585** Currently, the TT_budget / WinTV_Nova cards have two ICs
586** (74HCT4040, LVC74) for the generation of this VSYNC signal,
587** which seems that can be done perfectly without this :-)).
588*/
589
590/* New design (By Emard)
591** this rps1 code will copy internal HS event to GPIO3 pin.
592** GPIO3 is in budget-patch hardware connectd to port B VSYNC
593
594** HS is an internal event of 7146, accessible with RPS
595** and temporarily raised high every n lines
596** (n in defined in the RPS_THRESH1 counter threshold)
597** I think HS is raised high on the beginning of the n-th line
598** and remains high until this n-th line that triggered
599** it is completely received. When the receiption of n-th line
600** ends, HS is lowered.
601
602** To transmit data over DMA, 7146 needs changing state at
603** port B VSYNC pin. Any changing of port B VSYNC will
604** cause some DMA data transfer, with more or less packets loss.
605** It depends on the phase and frequency of VSYNC and
606** the way of 7146 is instructed to trigger on port B (defined
607** in DD1_INIT register, 3rd nibble from the right valid
608** numbers are 0-7, see datasheet)
609**
610** The correct triggering can minimize packet loss,
611** dvbtraffic should give this stable bandwidths:
612** 22k transponder = 33814 kbit/s
613** 27.5k transponder = 38045 kbit/s
614** by experiment it is found that the best results
615** (stable bandwidths and almost no packet loss)
616** are obtained using DD1_INIT triggering number 2
617** (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
618** and a VSYNC phase that occurs in the middle of DMA transfer
619** (about byte 188*512=96256 in the DMA window).
620**
621** Phase of HS is still not clear to me how to control,
622** It just happens to be so. It can be seen if one enables
623** RPS_IRQ and print Event Counter 1 in vpeirq(). Every
624** time RPS_INTERRUPT is called, the Event Counter 1 will
625** increment. That's how the 7146 is programmed to do event
626** counting in this budget-patch.c
627** I *think* HPS setting has something to do with the phase
628** of HS but I cant be 100% sure in that.
629
630** hardware debug note: a working budget card (including budget patch)
631** with vpeirq() interrupt setup in mode "0x90" (every 64K) will
632** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
633** and that means 3*25=75 Hz of interrupt freqency, as seen by
634** watch cat /proc/interrupts
635**
636** If this frequency is 3x lower (and data received in the DMA
637** buffer don't start with 0x47, but in the middle of packets,
638** whose lengths appear to be like 188 292 188 104 etc.
639** this means VSYNC line is not connected in the hardware.
640** (check soldering pcb and pins)
641** The same behaviour of missing VSYNC can be duplicated on budget
642** cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
643*/
644
645 // Setup RPS1 "program" (p35)
646 count = 0;
647
648
649 // Wait Source Line Counter Threshold (p36)
650 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
651 // Set GPIO3=1 (p42)
652 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
653 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
654 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
655#if RPS_IRQ
656 // issue RPS1 interrupt
657 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
658#endif
659 // Wait reset Source Line Counter Threshold (p36)
660 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
661 // Set GPIO3=0 (p42)
662 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
663 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
664 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
665#if RPS_IRQ
666 // issue RPS1 interrupt
667 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
668#endif
669 // Jump to begin of RPS program (p37)
670 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
671 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
672
673 // Fix VSYNC level
674 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
675 // Set RPS1 Address register to point to RPS code (r108 p42)
676 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
677 // Set Source Line Counter Threshold, using BRS (rCC p43)
678 // It generates HS event every TS_HEIGHT lines
679 // this is related to TS_WIDTH set in register
680 // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
681 // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
682 //,then RPS_THRESH1
683 // should be set to trigger every TS_HEIGHT (512) lines.
684 //
685 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
686
687 // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
688 // Enable RPS1 (rFC p33)
689 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
690
691
692 if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
693 return -ENOMEM;
694
695 dprintk(2, "budget: %p\n", budget);
696
697 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
698 kfree (budget);
699 return err;
700 }
701
702
703 dev->ext_priv = budget;
704
705 budget->dvb_adapter->priv = budget;
706 frontend_init(budget);
707
708 return 0;
709}
710
711static int budget_patch_detach (struct saa7146_dev* dev)
712{
713 struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
714 int err;
715
716 if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
717
718 err = ttpci_budget_deinit (budget);
719
720 kfree (budget);
721
722 return err;
723}
724
725static int __init budget_patch_init(void)
726{
727 return saa7146_register_extension(&budget_extension);
728}
729
730static void __exit budget_patch_exit(void)
731{
732 saa7146_unregister_extension(&budget_extension);
733}
734
735static struct saa7146_extension budget_extension = {
736 .name = "budget_patch dvb\0",
737 .flags = 0,
738
739 .module = THIS_MODULE,
740 .pci_tbl = pci_tbl,
741 .attach = budget_patch_attach,
742 .detach = budget_patch_detach,
743
744 .irq_mask = MASK_10,
745 .irq_func = ttpci_budget_irq10_handler,
746};
747
748module_init(budget_patch_init);
749module_exit(budget_patch_exit);
750
751MODULE_LICENSE("GPL");
752MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
753MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
754 "based so-called Budget Patch cards");
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
new file mode 100644
index 000000000000..5e6a10f4ad95
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -0,0 +1,573 @@
1/*
2 * budget.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * Copyright (C) 1999-2002 Ralph Metzler
9 * & Marcus Metzler for convergence integrated media GmbH
10 *
11 * 26feb2004 Support for FS Activy Card (Grundig tuner) by
12 * Michael Dreher <michael@5dot1.de>,
13 * Oliver Endriss <o.endriss@gmx.de> and
14 * Andreas 'randy' Weinberger
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
32 *
33 *
34 * the project's page is at http://www.linuxtv.org/dvb/
35 */
36
37#include "budget.h"
38#include "stv0299.h"
39#include "ves1x93.h"
40#include "ves1820.h"
41#include "l64781.h"
42#include "tda8083.h"
43
44static void Set22K (struct budget *budget, int state)
45{
46 struct saa7146_dev *dev=budget->dev;
47 dprintk(2, "budget: %p\n", budget);
48 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
49}
50
51/* Diseqc functions only for TT Budget card */
52/* taken from the Skyvision DVB driver by
53 Ralph Metzler <rjkm@metzlerbros.de> */
54
55static void DiseqcSendBit (struct budget *budget, int data)
56{
57 struct saa7146_dev *dev=budget->dev;
58 dprintk(2, "budget: %p\n", budget);
59
60 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
61 udelay(data ? 500 : 1000);
62 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
63 udelay(data ? 1000 : 500);
64}
65
66static void DiseqcSendByte (struct budget *budget, int data)
67{
68 int i, par=1, d;
69
70 dprintk(2, "budget: %p\n", budget);
71
72 for (i=7; i>=0; i--) {
73 d = (data>>i)&1;
74 par ^= d;
75 DiseqcSendBit(budget, d);
76 }
77
78 DiseqcSendBit(budget, par);
79}
80
81static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
82{
83 struct saa7146_dev *dev=budget->dev;
84 int i;
85
86 dprintk(2, "budget: %p\n", budget);
87
88 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
89 mdelay(16);
90
91 for (i=0; i<len; i++)
92 DiseqcSendByte(budget, msg[i]);
93
94 mdelay(16);
95
96 if (burst!=-1) {
97 if (burst)
98 DiseqcSendByte(budget, 0xff);
99 else {
100 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
101 udelay(12500);
102 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
103 }
104 msleep(20);
105 }
106
107 return 0;
108}
109
110/*
111 * Routines for the Fujitsu Siemens Activy budget card
112 * 22 kHz tone and DiSEqC are handled by the frontend.
113 * Voltage must be set here.
114 */
115static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
116{
117 struct saa7146_dev *dev=budget->dev;
118
119 dprintk(2, "budget: %p\n", budget);
120
121 switch (voltage) {
122 case SEC_VOLTAGE_13:
123 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
124 break;
125 case SEC_VOLTAGE_18:
126 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
127 break;
128 default:
129 return -EINVAL;
130 }
131
132 return 0;
133}
134
135static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
136{
137 struct budget* budget = (struct budget*) fe->dvb->priv;
138
139 return SetVoltage_Activy (budget, voltage);
140}
141
142static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
143{
144 struct budget* budget = (struct budget*) fe->dvb->priv;
145
146 switch (tone) {
147 case SEC_TONE_ON:
148 Set22K (budget, 1);
149 break;
150
151 case SEC_TONE_OFF:
152 Set22K (budget, 0);
153 break;
154
155 default:
156 return -EINVAL;
157 }
158
159 return 0;
160}
161
162static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
163{
164 struct budget* budget = (struct budget*) fe->dvb->priv;
165
166 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
167
168 return 0;
169}
170
171static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
172{
173 struct budget* budget = (struct budget*) fe->dvb->priv;
174
175 SendDiSEqCMsg (budget, 0, NULL, minicmd);
176
177 return 0;
178}
179
180static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
181{
182 struct budget* budget = (struct budget*) fe->dvb->priv;
183 u8 pwr = 0;
184 u8 buf[4];
185 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
186 u32 div = (params->frequency + 479500) / 125;
187
188 if (params->frequency > 2000000) pwr = 3;
189 else if (params->frequency > 1800000) pwr = 2;
190 else if (params->frequency > 1600000) pwr = 1;
191 else if (params->frequency > 1200000) pwr = 0;
192 else if (params->frequency >= 1100000) pwr = 1;
193 else pwr = 2;
194
195 buf[0] = (div >> 8) & 0x7f;
196 buf[1] = div & 0xff;
197 buf[2] = ((div & 0x18000) >> 10) | 0x95;
198 buf[3] = (pwr << 6) | 0x30;
199
200 // NOTE: since we're using a prescaler of 2, we set the
201 // divisor frequency to 62.5kHz and divide by 125 above
202
203 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
204 return 0;
205}
206
207static struct ves1x93_config alps_bsrv2_config =
208{
209 .demod_address = 0x08,
210 .xin = 90100000UL,
211 .invert_pwm = 0,
212 .pll_set = alps_bsrv2_pll_set,
213};
214
215static u8 alps_bsru6_inittab[] = {
216 0x01, 0x15,
217 0x02, 0x00,
218 0x03, 0x00,
219 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
220 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
221 0x06, 0x40, /* DAC not used, set to high impendance mode */
222 0x07, 0x00, /* DAC LSB */
223 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
224 0x09, 0x00, /* FIFO */
225 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
226 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
227 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
228 0x10, 0x3f, // AGC2 0x3d
229 0x11, 0x84,
230 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
231 0x15, 0xc9, // lock detector threshold
232 0x16, 0x00,
233 0x17, 0x00,
234 0x18, 0x00,
235 0x19, 0x00,
236 0x1a, 0x00,
237 0x1f, 0x50,
238 0x20, 0x00,
239 0x21, 0x00,
240 0x22, 0x00,
241 0x23, 0x00,
242 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
243 0x29, 0x1e, // 1/2 threshold
244 0x2a, 0x14, // 2/3 threshold
245 0x2b, 0x0f, // 3/4 threshold
246 0x2c, 0x09, // 5/6 threshold
247 0x2d, 0x05, // 7/8 threshold
248 0x2e, 0x01,
249 0x31, 0x1f, // test all FECs
250 0x32, 0x19, // viterbi and synchro search
251 0x33, 0xfc, // rs control
252 0x34, 0x93, // error control
253 0x0f, 0x52,
254 0xff, 0xff
255};
256
257static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
258{
259 u8 aclk = 0;
260 u8 bclk = 0;
261
262 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
263 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
264 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
265 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
266 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
267 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
268
269 stv0299_writereg (fe, 0x13, aclk);
270 stv0299_writereg (fe, 0x14, bclk);
271 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
272 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
273 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
274
275 return 0;
276}
277
278static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
279{
280 struct budget* budget = (struct budget*) fe->dvb->priv;
281 u8 data[4];
282 u32 div;
283 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
284
285 if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
286
287 div = (params->frequency + (125 - 1)) / 125; // round correctly
288 data[0] = (div >> 8) & 0x7f;
289 data[1] = div & 0xff;
290 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
291 data[3] = 0xC4;
292
293 if (params->frequency > 1530000) data[3] = 0xc0;
294
295 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
296 return 0;
297}
298
299static struct stv0299_config alps_bsru6_config = {
300
301 .demod_address = 0x68,
302 .inittab = alps_bsru6_inittab,
303 .mclk = 88000000UL,
304 .invert = 1,
305 .enhanced_tuning = 0,
306 .skip_reinit = 0,
307 .lock_output = STV0229_LOCKOUTPUT_1,
308 .volt13_op0_op1 = STV0299_VOLT13_OP1,
309 .min_delay_ms = 100,
310 .set_symbol_rate = alps_bsru6_set_symbol_rate,
311 .pll_set = alps_bsru6_pll_set,
312};
313
314static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
315{
316 struct budget* budget = (struct budget*) fe->dvb->priv;
317 u32 div;
318 u8 data[4];
319 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
320
321 div = (params->frequency + 35937500 + 31250) / 62500;
322
323 data[0] = (div >> 8) & 0x7f;
324 data[1] = div & 0xff;
325 data[2] = 0x85 | ((div >> 10) & 0x60);
326 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
327
328 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
329 return 0;
330}
331
332static struct ves1820_config alps_tdbe2_config = {
333 .demod_address = 0x09,
334 .xin = 57840000UL,
335 .invert = 1,
336 .selagc = VES1820_SELAGC_SIGNAMPERR,
337 .pll_set = alps_tdbe2_pll_set,
338};
339
340static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
341{
342 struct budget* budget = (struct budget*) fe->dvb->priv;
343 u32 div;
344 u8 cfg, cpump, band_select;
345 u8 data[4];
346 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
347
348 div = (36125000 + params->frequency) / 166666;
349
350 cfg = 0x88;
351
352 if (params->frequency < 175000000) cpump = 2;
353 else if (params->frequency < 390000000) cpump = 1;
354 else if (params->frequency < 470000000) cpump = 2;
355 else if (params->frequency < 750000000) cpump = 1;
356 else cpump = 3;
357
358 if (params->frequency < 175000000) band_select = 0x0e;
359 else if (params->frequency < 470000000) band_select = 0x05;
360 else band_select = 0x03;
361
362 data[0] = (div >> 8) & 0x7f;
363 data[1] = div & 0xff;
364 data[2] = ((div >> 10) & 0x60) | cfg;
365 data[3] = (cpump << 6) | band_select;
366
367 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
368 return 0;
369}
370
371static struct l64781_config grundig_29504_401_config = {
372 .demod_address = 0x55,
373 .pll_set = grundig_29504_401_pll_set,
374};
375
376static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
377{
378 struct budget* budget = (struct budget*) fe->dvb->priv;
379 u32 div;
380 u8 data[4];
381 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
382
383 div = params->frequency / 125;
384 data[0] = (div >> 8) & 0x7f;
385 data[1] = div & 0xff;
386 data[2] = 0x8e;
387 data[3] = 0x00;
388
389 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
390 return 0;
391}
392
393static struct tda8083_config grundig_29504_451_config = {
394 .demod_address = 0x68,
395 .pll_set = grundig_29504_451_pll_set,
396};
397
398static u8 read_pwm(struct budget* budget)
399{
400 u8 b = 0xff;
401 u8 pwm;
402 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
403 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
404
405 if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
406 pwm = 0x48;
407
408 return pwm;
409}
410
411static void frontend_init(struct budget *budget)
412{
413 switch(budget->dev->pci->subsystem_device) {
414 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
415 case 0x1013:
416 // try the ALPS BSRV2 first of all
417 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
418 if (budget->dvb_frontend) {
419 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
420 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
421 budget->dvb_frontend->ops->set_tone = budget_set_tone;
422 break;
423 }
424
425 // try the ALPS BSRU6 now
426 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
427 if (budget->dvb_frontend) {
428 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
429 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
430 budget->dvb_frontend->ops->set_tone = budget_set_tone;
431 break;
432 }
433 break;
434
435 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
436
437 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
438 if (budget->dvb_frontend) break;
439 break;
440
441 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
442
443 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
444 if (budget->dvb_frontend) break;
445 break;
446
447 case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
448 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
449 if (budget->dvb_frontend) {
450 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
451 break;
452 }
453 break;
454
455 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
456 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
457 if (budget->dvb_frontend) {
458 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
459 break;
460 }
461 break;
462 }
463
464 if (budget->dvb_frontend == NULL) {
465 printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
466 budget->dev->pci->vendor,
467 budget->dev->pci->device,
468 budget->dev->pci->subsystem_vendor,
469 budget->dev->pci->subsystem_device);
470 } else {
471 if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
472 printk("budget: Frontend registration failed!\n");
473 if (budget->dvb_frontend->ops->release)
474 budget->dvb_frontend->ops->release(budget->dvb_frontend);
475 budget->dvb_frontend = NULL;
476 }
477 }
478}
479
480static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
481{
482 struct budget *budget = NULL;
483 int err;
484
485 budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
486 if( NULL == budget ) {
487 return -ENOMEM;
488 }
489
490 dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
491
492 dev->ext_priv = budget;
493
494 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
495 printk("==> failed\n");
496 kfree (budget);
497 return err;
498 }
499
500 budget->dvb_adapter->priv = budget;
501 frontend_init(budget);
502
503 return 0;
504}
505
506static int budget_detach (struct saa7146_dev* dev)
507{
508 struct budget *budget = (struct budget*) dev->ext_priv;
509 int err;
510
511 if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
512
513 err = ttpci_budget_deinit (budget);
514
515 kfree (budget);
516 dev->ext_priv = NULL;
517
518 return err;
519}
520
521static struct saa7146_extension budget_extension;
522
523MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
524MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
525MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
526MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
527MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
528MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
529
530static struct pci_device_id pci_tbl[] = {
531 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
532 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
533 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
534 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
535 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
536 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
537 {
538 .vendor = 0,
539 }
540};
541
542MODULE_DEVICE_TABLE(pci, pci_tbl);
543
544static struct saa7146_extension budget_extension = {
545 .name = "budget dvb\0",
546 .flags = 0,
547
548 .module = THIS_MODULE,
549 .pci_tbl = pci_tbl,
550 .attach = budget_attach,
551 .detach = budget_detach,
552
553 .irq_mask = MASK_10,
554 .irq_func = ttpci_budget_irq10_handler,
555};
556
557static int __init budget_init(void)
558{
559 return saa7146_register_extension(&budget_extension);
560}
561
562static void __exit budget_exit(void)
563{
564 saa7146_unregister_extension(&budget_extension);
565}
566
567module_init(budget_init);
568module_exit(budget_exit);
569
570MODULE_LICENSE("GPL");
571MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
572MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
573 "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
new file mode 100644
index 000000000000..10bd41f0363b
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -0,0 +1,110 @@
1#ifndef __BUDGET_DVB__
2#define __BUDGET_DVB__
3
4#include "dvb_frontend.h"
5#include "dvbdev.h"
6#include "demux.h"
7#include "dvb_demux.h"
8#include "dmxdev.h"
9#include "dvb_filter.h"
10#include "dvb_net.h"
11
12#include <linux/module.h>
13#include <media/saa7146.h>
14
15extern int budget_debug;
16
17#ifdef dprintk
18#undef dprintk
19#endif
20
21#define dprintk(level,args...) \
22 do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
23
24struct budget_info {
25 char *name;
26 int type;
27};
28
29/* place to store all the necessary device information */
30struct budget {
31
32 /* devices */
33 struct dvb_device dvb_dev;
34 struct dvb_net dvb_net;
35
36 struct saa7146_dev *dev;
37
38 struct i2c_adapter i2c_adap;
39 struct budget_info *card;
40
41 unsigned char *grabbing;
42 struct saa7146_pgtable pt;
43
44 struct tasklet_struct fidb_tasklet;
45 struct tasklet_struct vpe_tasklet;
46
47 struct dmxdev dmxdev;
48 struct dvb_demux demux;
49
50 struct dmx_frontend hw_frontend;
51 struct dmx_frontend mem_frontend;
52
53 int fe_synced;
54 struct semaphore pid_mutex;
55
56 int ci_present;
57 int video_port;
58
59 u8 tsf;
60 u32 ttbp;
61 int feeding;
62
63 spinlock_t feedlock;
64
65 spinlock_t debilock;
66
67 struct dvb_adapter *dvb_adapter;
68 struct dvb_frontend *dvb_frontend;
69 void *priv;
70};
71
72#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \
73static struct budget_info x_var ## _info = { \
74 .name=x_name, \
75 .type=x_type }; \
76static struct saa7146_pci_extension_data x_var = { \
77 .ext_priv = &x_var ## _info, \
78 .ext = &budget_extension };
79
80#define TS_WIDTH (376)
81#define TS_HEIGHT (512)
82#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
83#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
84
85#define BUDGET_TT 0
86#define BUDGET_TT_HW_DISEQC 1
87#define BUDGET_PATCH 3
88#define BUDGET_FS_ACTIVY 4
89#define BUDGET_CIN1200S 5
90#define BUDGET_CIN1200C 6
91#define BUDGET_CIN1200T 7
92#define BUDGET_KNC1S 8
93#define BUDGET_KNC1C 9
94#define BUDGET_KNC1T 10
95
96#define BUDGET_VIDEO_PORTA 0
97#define BUDGET_VIDEO_PORTB 1
98
99extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
100 struct saa7146_pci_extension_data *info,
101 struct module *owner);
102extern int ttpci_budget_deinit(struct budget *budget);
103extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
104extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port);
105extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
106 int uselocks, int nobusyloop);
107extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value,
108 int uselocks, int nobusyloop);
109
110#endif
diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c
new file mode 100644
index 000000000000..0b478db3e744
--- /dev/null
+++ b/drivers/media/dvb/ttpci/fdump.c
@@ -0,0 +1,44 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <unistd.h>
6
7int main(int argc, char **argv)
8{
9 unsigned char buf[8];
10 unsigned int i, count, bytes = 0;
11 FILE *fd_in, *fd_out;
12
13 if (argc != 4) {
14 fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
15 return -1;
16 }
17
18 fd_in = fopen(argv[1], "rb");
19 if (fd_in == NULL) {
20 fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
21 return -1;
22 }
23
24 fd_out = fopen(argv[3], "w+");
25 if (fd_out == NULL) {
26 fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
27 return -1;
28 }
29
30 fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
31
32 while ((count = fread(buf, 1, 8, fd_in)) > 0) {
33 fprintf(fd_out, "\n\t");
34 for (i = 0; i < count; i++, bytes++)
35 fprintf(fd_out, "0x%02x, ", buf[i]);
36 }
37
38 fprintf(fd_out, "\n};\n\n");
39
40 fclose(fd_in);
41 fclose(fd_out);
42
43 return 0;
44}
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
new file mode 100644
index 000000000000..e9a8457b0727
--- /dev/null
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c
@@ -0,0 +1,146 @@
1/*
2 Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,
3 decode it and store it in the associated adapter struct for
4 use by dvb_net.c
5
6 This card appear to have the 24C16 write protect held to ground,
7 thus permitting normal read/write operation. Theoretically it
8 would be possible to write routines to burn a different (encoded)
9 MAC address into the EEPROM.
10
11 Robert Schlabbach GMX
12 Michael Glaum KVH Industries
13 Holger Waechtler Convergence
14
15 Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
16 Metzler Brothers Systementwicklung GbR
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
22
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
32*/
33
34#include <asm/errno.h>
35#include <linux/init.h>
36#include <linux/module.h>
37#include <linux/string.h>
38#include <linux/i2c.h>
39
40
41#if 1
42#define dprintk(x...) do { printk(x); } while (0)
43#else
44#define dprintk(x...) do { } while (0)
45#endif
46
47
48static int check_mac_tt(u8 *buf)
49{
50 int i;
51 u16 tmp = 0xffff;
52
53 for (i = 0; i < 8; i++) {
54 tmp = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
55 tmp ^= (tmp >> 4) & 0x0f;
56 tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
57 }
58 tmp ^= 0xffff;
59 return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
60}
61
62static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
63{
64 u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
65 0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
66 0x1d, 0x36, 0x64, 0x78};
67 u8 data[20];
68 int i;
69
70 /* In case there is a sig check failure have the orig contents available */
71 memcpy(data, encodedMAC, 20);
72
73 for (i = 0; i < 20; i++)
74 data[i] ^= xor[i];
75 for (i = 0; i < 10; i++)
76 data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
77 >> ((data[2 * i + 1] >> 6) & 3);
78
79 if (check_mac_tt(data))
80 return -ENODEV;
81
82 decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];
83 decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];
84 return 0;
85}
86
87static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
88{
89 int ret;
90 u8 b0[] = { 0xcc };
91
92 struct i2c_msg msg[] = {
93 { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },
94 { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 }
95 };
96
97 /* dprintk("%s\n", __FUNCTION__); */
98
99 ret = i2c_transfer(adapter, msg, 2);
100
101 if (ret != 2) /* Assume EEPROM isn't there */
102 return (-ENODEV);
103
104 return 0;
105}
106
107
108int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)
109{
110 int ret, i;
111 u8 encodedMAC[20];
112 u8 decodedMAC[6];
113
114 ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);
115
116 if (ret != 0) { /* Will only be -ENODEV */
117 dprintk("Couldn't read from EEPROM: not there?\n");
118 memset(proposed_mac, 0, 6);
119 return ret;
120 }
121
122 ret = getmac_tt(decodedMAC, encodedMAC);
123 if( ret != 0 ) {
124 dprintk("adapter failed MAC signature check\n");
125 dprintk("encoded MAC from EEPROM was " );
126 for(i=0; i<19; i++) {
127 dprintk( "%.2x:", encodedMAC[i]);
128 }
129 dprintk("%.2x\n", encodedMAC[19]);
130 memset(proposed_mac, 0, 6);
131 return ret;
132 }
133
134 memcpy(proposed_mac, decodedMAC, 6);
135 dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
136 decodedMAC[0], decodedMAC[1], decodedMAC[2],
137 decodedMAC[3], decodedMAC[4], decodedMAC[5]);
138 return 0;
139}
140
141EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
142
143MODULE_LICENSE("GPL");
144MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
145MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "
146 "made by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h
new file mode 100644
index 000000000000..e2dc6cfe205c
--- /dev/null
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.h
@@ -0,0 +1,33 @@
1/*
2 Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
3 decode it and store it in associated adapter net device
4
5 Robert Schlabbach GMX
6 Michael Glaum KVH Industries
7 Holger Waechtler Convergence
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
25#ifndef __TTPCI_EEPROM_H__
26#define __TTPCI_EEPROM_H__
27
28#include <linux/types.h>
29#include <linux/i2c.h>
30
31extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac);
32
33#endif
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
new file mode 100644
index 000000000000..4aa714ab4c28
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -0,0 +1,15 @@
1config DVB_TTUSB_BUDGET
2 tristate "Technotrend/Hauppauge Nova-USB devices"
3 depends on DVB_CORE && USB
4 select DVB_CX22700
5 select DVB_TDA1004X
6 select DVB_TDA8083
7 select DVB_STV0299
8 help
9 Support for external USB adapters designed by Technotrend and
10 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
11
12 These devices don't have a MPEG decoder built in, so you need
13 an external software decoder to watch TV.
14
15 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile
new file mode 100644
index 000000000000..6ab97f6b53fc
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
new file mode 100644
index 000000000000..4c046ece883a
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -0,0 +1,1610 @@
1/*
2 * TTUSB DVB driver
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/wait.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/usb.h>
18#include <linux/delay.h>
19#include <linux/time.h>
20#include <linux/errno.h>
21#include <asm/semaphore.h>
22
23#include "dvb_frontend.h"
24#include "dmxdev.h"
25#include "dvb_demux.h"
26#include "dvb_net.h"
27#include "cx22700.h"
28#include "tda1004x.h"
29#include "stv0299.h"
30#include "tda8083.h"
31
32#include <linux/dvb/frontend.h>
33#include <linux/dvb/dmx.h>
34#include <linux/pci.h>
35
36
37/*
38 TTUSB_HWSECTIONS:
39 the DSP supports filtering in hardware, however, since the "muxstream"
40 is a bit braindead (no matching channel masks or no matching filter mask),
41 we won't support this - yet. it doesn't event support negative filters,
42 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
43 parse TS data. USB bandwith will be a problem when having large
44 datastreams, especially for dvb-net, but hey, that's not my problem.
45
46 TTUSB_DISEQC, TTUSB_TONE:
47 let the STC do the diseqc/tone stuff. this isn't supported at least with
48 my TTUSB, so let it undef'd unless you want to implement another
49 frontend. never tested.
50
51 DEBUG:
52 define it to > 3 for really hardcore debugging. you probably don't want
53 this unless the device doesn't load at all. > 2 for bandwidth statistics.
54*/
55
56static int debug;
57
58module_param(debug, int, 0644);
59MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
60
61#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
62
63#define ISO_BUF_COUNT 4
64#define FRAMES_PER_ISO_BUF 4
65#define ISO_FRAME_SIZE 912
66#define TTUSB_MAXCHANNEL 32
67#ifdef TTUSB_HWSECTIONS
68#define TTUSB_MAXFILTER 16 /* ??? */
69#endif
70
71#define TTUSB_REV_2_2 0x22
72#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
73
74/**
75 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
76 * the dvb_demux field must be the first in struct!!
77 */
78struct ttusb {
79 struct dvb_demux dvb_demux;
80 struct dmxdev dmxdev;
81 struct dvb_net dvbnet;
82
83 /* and one for USB access. */
84 struct semaphore semi2c;
85 struct semaphore semusb;
86
87 struct dvb_adapter *adapter;
88 struct usb_device *dev;
89
90 struct i2c_adapter i2c_adap;
91
92 int disconnecting;
93 int iso_streaming;
94
95 unsigned int bulk_out_pipe;
96 unsigned int bulk_in_pipe;
97 unsigned int isoc_in_pipe;
98
99 void *iso_buffer;
100 dma_addr_t iso_dma_handle;
101
102 struct urb *iso_urb[ISO_BUF_COUNT];
103
104 int running_feed_count;
105 int last_channel;
106 int last_filter;
107
108 u8 c; /* transaction counter, wraps around... */
109 fe_sec_tone_mode_t tone;
110 fe_sec_voltage_t voltage;
111
112 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
113 u8 mux_npacks;
114 u8 muxpack[256 + 8];
115 int muxpack_ptr, muxpack_len;
116
117 int insync;
118
119 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
120 /* (including stuffing. yes. really.) */
121
122 u8 last_result[32];
123
124 int revision;
125
126#if 0
127 devfs_handle_t stc_devfs_handle;
128#endif
129
130 struct dvb_frontend* fe;
131};
132
133/* ugly workaround ... don't know why it's neccessary to read */
134/* all result codes. */
135
136#define DEBUG 0
137static int ttusb_cmd(struct ttusb *ttusb,
138 const u8 * data, int len, int needresult)
139{
140 int actual_len;
141 int err;
142#if DEBUG >= 3
143 int i;
144
145 printk(">");
146 for (i = 0; i < len; ++i)
147 printk(" %02x", data[i]);
148 printk("\n");
149#endif
150
151 if (down_interruptible(&ttusb->semusb) < 0)
152 return -EAGAIN;
153
154 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
155 (u8 *) data, len, &actual_len, 1000);
156 if (err != 0) {
157 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
158 __FUNCTION__, err);
159 up(&ttusb->semusb);
160 return err;
161 }
162 if (actual_len != len) {
163 dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
164 actual_len, len);
165 up(&ttusb->semusb);
166 return -1;
167 }
168
169 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
170 ttusb->last_result, 32, &actual_len, 1000);
171
172 if (err != 0) {
173 printk("%s: failed, receive error %d\n", __FUNCTION__,
174 err);
175 up(&ttusb->semusb);
176 return err;
177 }
178#if DEBUG >= 3
179 actual_len = ttusb->last_result[3] + 4;
180 printk("<");
181 for (i = 0; i < actual_len; ++i)
182 printk(" %02x", ttusb->last_result[i]);
183 printk("\n");
184#endif
185 if (!needresult)
186 up(&ttusb->semusb);
187 return 0;
188}
189
190static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
191{
192 memcpy(data, ttusb->last_result, len);
193 up(&ttusb->semusb);
194 return 0;
195}
196
197static int ttusb_i2c_msg(struct ttusb *ttusb,
198 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
199 u8 rcv_len)
200{
201 u8 b[0x28];
202 u8 id = ++ttusb->c;
203 int i, err;
204
205 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
206 return -EINVAL;
207
208 b[0] = 0xaa;
209 b[1] = id;
210 b[2] = 0x31;
211 b[3] = snd_len + 3;
212 b[4] = addr << 1;
213 b[5] = snd_len;
214 b[6] = rcv_len;
215
216 for (i = 0; i < snd_len; i++)
217 b[7 + i] = snd_buf[i];
218
219 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
220
221 if (err)
222 return -EREMOTEIO;
223
224 err = ttusb_result(ttusb, b, 0x20);
225
226 /* check if the i2c transaction was successful */
227 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
228
229 if (rcv_len > 0) {
230
231 if (err || b[0] != 0x55 || b[1] != id) {
232 dprintk
233 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
234 __FUNCTION__, err, id);
235 return -EREMOTEIO;
236 }
237
238 for (i = 0; i < rcv_len; i++)
239 rcv_buf[i] = b[7 + i];
240 }
241
242 return rcv_len;
243}
244
245static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
246{
247 struct ttusb *ttusb = i2c_get_adapdata(adapter);
248 int i = 0;
249 int inc;
250
251 if (down_interruptible(&ttusb->semi2c) < 0)
252 return -EAGAIN;
253
254 while (i < num) {
255 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
256 int err;
257
258 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
259 addr = msg[i].addr;
260 snd_buf = msg[i].buf;
261 snd_len = msg[i].len;
262 rcv_buf = msg[i + 1].buf;
263 rcv_len = msg[i + 1].len;
264 inc = 2;
265 } else {
266 addr = msg[i].addr;
267 snd_buf = msg[i].buf;
268 snd_len = msg[i].len;
269 rcv_buf = NULL;
270 rcv_len = 0;
271 inc = 1;
272 }
273
274 err = ttusb_i2c_msg(ttusb, addr,
275 snd_buf, snd_len, rcv_buf, rcv_len);
276
277 if (err < rcv_len) {
278 dprintk("%s: i == %i\n", __FUNCTION__, i);
279 break;
280 }
281
282 i += inc;
283 }
284
285 up(&ttusb->semi2c);
286 return i;
287}
288
289#include "dvb-ttusb-dspbootcode.h"
290
291static int ttusb_boot_dsp(struct ttusb *ttusb)
292{
293 int i, err;
294 u8 b[40];
295
296 /* BootBlock */
297 b[0] = 0xaa;
298 b[2] = 0x13;
299 b[3] = 28;
300
301 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
302 /* 32 is max packet size, no messages should be splitted. */
303 for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
304 memcpy(&b[4], &dsp_bootcode[i], 28);
305
306 b[1] = ++ttusb->c;
307
308 err = ttusb_cmd(ttusb, b, 32, 0);
309 if (err)
310 goto done;
311 }
312
313 /* last block ... */
314 b[1] = ++ttusb->c;
315 b[2] = 0x13;
316 b[3] = 0;
317
318 err = ttusb_cmd(ttusb, b, 4, 0);
319 if (err)
320 goto done;
321
322 /* BootEnd */
323 b[1] = ++ttusb->c;
324 b[2] = 0x14;
325 b[3] = 0;
326
327 err = ttusb_cmd(ttusb, b, 4, 0);
328
329 done:
330 if (err) {
331 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
332 __FUNCTION__, err);
333 }
334
335 return err;
336}
337
338static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
339 int pid)
340{
341 int err;
342 /* SetChannel */
343 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
344 (pid >> 8) & 0xff, pid & 0xff
345 };
346
347 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
348 return err;
349}
350
351static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
352{
353 int err;
354 /* DelChannel */
355 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
356
357 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
358 return err;
359}
360
361#ifdef TTUSB_HWSECTIONS
362static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
363 int associated_chan, u8 filter[8], u8 mask[8])
364{
365 int err;
366 /* SetFilter */
367 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
368 filter[0], filter[1], filter[2], filter[3],
369 filter[4], filter[5], filter[6], filter[7],
370 filter[8], filter[9], filter[10], filter[11],
371 mask[0], mask[1], mask[2], mask[3],
372 mask[4], mask[5], mask[6], mask[7],
373 mask[8], mask[9], mask[10], mask[11]
374 };
375
376 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
377 return err;
378}
379
380static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
381{
382 int err;
383 /* DelFilter */
384 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
385
386 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
387 return err;
388}
389#endif
390
391static int ttusb_init_controller(struct ttusb *ttusb)
392{
393 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
394 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
395 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
396 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
397 u8 b3[] =
398 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
399 u8 b4[] =
400 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
401
402 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
403 u8 get_dsp_version[0x20] =
404 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
405 int err;
406
407 /* reset board */
408 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
409 return err;
410
411 /* reset board (again?) */
412 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
413 return err;
414
415 ttusb_boot_dsp(ttusb);
416
417 /* set i2c bit rate */
418 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
419 return err;
420
421 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
422 return err;
423
424 err = ttusb_result(ttusb, b4, sizeof(b4));
425
426 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
427 return err;
428
429 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
430 return err;
431
432 dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__,
433 get_version[4], get_version[5], get_version[6],
434 get_version[7], get_version[8]);
435
436 if (memcmp(get_version + 4, "V 0.0", 5) &&
437 memcmp(get_version + 4, "V 1.1", 5) &&
438 memcmp(get_version + 4, "V 2.1", 5) &&
439 memcmp(get_version + 4, "V 2.2", 5)) {
440 printk
441 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
442 __FUNCTION__, get_version[4], get_version[5],
443 get_version[6], get_version[7], get_version[8]);
444 }
445
446 ttusb->revision = ((get_version[6] - '0') << 4) |
447 (get_version[8] - '0');
448
449 err =
450 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
451 if (err)
452 return err;
453
454 err =
455 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
456 if (err)
457 return err;
458 printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
459 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
460 return 0;
461}
462
463#ifdef TTUSB_DISEQC
464static int ttusb_send_diseqc(struct dvb_frontend* fe,
465 const struct dvb_diseqc_master_cmd *cmd)
466{
467 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
468 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
469
470 int err;
471
472 b[3] = 4 + 2 + cmd->msg_len;
473 b[4] = 0xFF; /* send diseqc master, not burst */
474 b[5] = cmd->msg_len;
475
476 memcpy(b + 5, cmd->msg, cmd->msg_len);
477
478 /* Diseqc */
479 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
480 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
481 __FUNCTION__, err);
482 }
483
484 return err;
485}
486#endif
487
488static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
489{
490 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
491 int ret;
492 u8 data[1];
493 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
494
495 switch(voltage) {
496 case SEC_VOLTAGE_OFF:
497 data[0] = 0x00;
498 break;
499 case SEC_VOLTAGE_13:
500 data[0] = 0x44;
501 break;
502 case SEC_VOLTAGE_18:
503 data[0] = 0x4c;
504 break;
505 default:
506 return -EINVAL;
507 };
508
509 ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
510 return (ret != 1) ? -EIO : 0;
511}
512
513static int ttusb_update_lnb(struct ttusb *ttusb)
514{
515 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
516 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
517 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
518 };
519 int err;
520
521 /* SetLNB */
522 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
523 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
524 __FUNCTION__, err);
525 }
526
527 return err;
528}
529
530static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
531{
532 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
533
534 ttusb->voltage = voltage;
535 return ttusb_update_lnb(ttusb);
536}
537
538#ifdef TTUSB_TONE
539static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
540{
541 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
542
543 ttusb->tone = tone;
544 return ttusb_update_lnb(ttusb);
545}
546#endif
547
548
549#if 0
550static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
551{
552 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
553 int err, actual_len;
554
555 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
556 if (err) {
557 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
558 __FUNCTION__, err);
559 }
560}
561#endif
562
563/*****************************************************************************/
564
565#ifdef TTUSB_HWSECTIONS
566static void ttusb_handle_ts_data(struct ttusb_channel *channel,
567 const u8 * data, int len);
568static void ttusb_handle_sec_data(struct ttusb_channel *channel,
569 const u8 * data, int len);
570#endif
571
572static int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid;
573
574static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
575 int len)
576{
577 u16 csum = 0, cc;
578 int i;
579 for (i = 0; i < len; i += 2)
580 csum ^= le16_to_cpup((u16 *) (muxpack + i));
581 if (csum) {
582 printk("%s: muxpack with incorrect checksum, ignoring\n",
583 __FUNCTION__);
584 numinvalid++;
585 return;
586 }
587
588 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
589 cc &= 0x7FFF;
590 if ((cc != ttusb->cc) && (ttusb->cc != -1))
591 printk("%s: cc discontinuity (%d frames missing)\n",
592 __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
593 ttusb->cc = (cc + 1) & 0x7FFF;
594 if (muxpack[0] & 0x80) {
595#ifdef TTUSB_HWSECTIONS
596 /* section data */
597 int pusi = muxpack[0] & 0x40;
598 int channel = muxpack[0] & 0x1F;
599 int payload = muxpack[1];
600 const u8 *data = muxpack + 2;
601 /* check offset flag */
602 if (muxpack[0] & 0x20)
603 data++;
604
605 ttusb_handle_sec_data(ttusb->channel + channel, data,
606 payload);
607 data += payload;
608
609 if ((!!(ttusb->muxpack[0] & 0x20)) ^
610 !!(ttusb->muxpack[1] & 1))
611 data++;
612#warning TODO: pusi
613 printk("cc: %04x\n", (data[0] << 8) | data[1]);
614#endif
615 numsec++;
616 } else if (muxpack[0] == 0x47) {
617#ifdef TTUSB_HWSECTIONS
618 /* we have TS data here! */
619 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
620 int channel;
621 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
622 if (ttusb->channel[channel].active
623 && (pid == ttusb->channel[channel].pid))
624 ttusb_handle_ts_data(ttusb->channel +
625 channel, muxpack,
626 188);
627#endif
628 numts++;
629 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
630 } else if (muxpack[0] != 0) {
631 numinvalid++;
632 printk("illegal muxpack type %02x\n", muxpack[0]);
633 } else
634 numstuff++;
635}
636
637static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
638{
639 int maxwork = 1024;
640 while (len) {
641 if (!(maxwork--)) {
642 printk("%s: too much work\n", __FUNCTION__);
643 break;
644 }
645
646 switch (ttusb->mux_state) {
647 case 0:
648 case 1:
649 case 2:
650 len--;
651 if (*data++ == 0xAA)
652 ++ttusb->mux_state;
653 else {
654 ttusb->mux_state = 0;
655#if DEBUG > 3
656 if (ttusb->insync)
657 printk("%02x ", data[-1]);
658#else
659 if (ttusb->insync) {
660 printk("%s: lost sync.\n",
661 __FUNCTION__);
662 ttusb->insync = 0;
663 }
664#endif
665 }
666 break;
667 case 3:
668 ttusb->insync = 1;
669 len--;
670 ttusb->mux_npacks = *data++;
671 ++ttusb->mux_state;
672 ttusb->muxpack_ptr = 0;
673 /* maximum bytes, until we know the length */
674 ttusb->muxpack_len = 2;
675 break;
676 case 4:
677 {
678 int avail;
679 avail = len;
680 if (avail >
681 (ttusb->muxpack_len -
682 ttusb->muxpack_ptr))
683 avail =
684 ttusb->muxpack_len -
685 ttusb->muxpack_ptr;
686 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
687 data, avail);
688 ttusb->muxpack_ptr += avail;
689 if (ttusb->muxpack_ptr > 264)
690 BUG();
691 data += avail;
692 len -= avail;
693 /* determine length */
694 if (ttusb->muxpack_ptr == 2) {
695 if (ttusb->muxpack[0] & 0x80) {
696 ttusb->muxpack_len =
697 ttusb->muxpack[1] + 2;
698 if (ttusb->
699 muxpack[0] & 0x20)
700 ttusb->
701 muxpack_len++;
702 if ((!!
703 (ttusb->
704 muxpack[0] & 0x20)) ^
705 !!(ttusb->
706 muxpack[1] & 1))
707 ttusb->
708 muxpack_len++;
709 ttusb->muxpack_len += 4;
710 } else if (ttusb->muxpack[0] ==
711 0x47)
712 ttusb->muxpack_len =
713 188 + 4;
714 else if (ttusb->muxpack[0] == 0x00)
715 ttusb->muxpack_len =
716 ttusb->muxpack[1] + 2 +
717 4;
718 else {
719 dprintk
720 ("%s: invalid state: first byte is %x\n",
721 __FUNCTION__,
722 ttusb->muxpack[0]);
723 ttusb->mux_state = 0;
724 }
725 }
726
727 /**
728 * if length is valid and we reached the end:
729 * goto next muxpack
730 */
731 if ((ttusb->muxpack_ptr >= 2) &&
732 (ttusb->muxpack_ptr ==
733 ttusb->muxpack_len)) {
734 ttusb_process_muxpack(ttusb,
735 ttusb->
736 muxpack,
737 ttusb->
738 muxpack_ptr);
739 ttusb->muxpack_ptr = 0;
740 /* maximum bytes, until we know the length */
741 ttusb->muxpack_len = 2;
742
743 /**
744 * no muxpacks left?
745 * return to search-sync state
746 */
747 if (!ttusb->mux_npacks--) {
748 ttusb->mux_state = 0;
749 break;
750 }
751 }
752 break;
753 }
754 default:
755 BUG();
756 break;
757 }
758 }
759}
760
761static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
762{
763 struct ttusb *ttusb = urb->context;
764
765 if (!ttusb->iso_streaming)
766 return;
767
768#if 0
769 printk("%s: status %d, errcount == %d, length == %i\n",
770 __FUNCTION__,
771 urb->status, urb->error_count, urb->actual_length);
772#endif
773
774 if (!urb->status) {
775 int i;
776 for (i = 0; i < urb->number_of_packets; ++i) {
777 struct usb_iso_packet_descriptor *d;
778 u8 *data;
779 int len;
780 numpkt++;
781 if ((jiffies - lastj) >= HZ) {
782#if DEBUG > 2
783 printk
784 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
785 numpkt * HZ / (jiffies - lastj),
786 numts, numstuff, numsec, numinvalid,
787 numts + numstuff + numsec +
788 numinvalid);
789#endif
790 numts = numstuff = numsec = numinvalid = 0;
791 lastj = jiffies;
792 numpkt = 0;
793 }
794 d = &urb->iso_frame_desc[i];
795 data = urb->transfer_buffer + d->offset;
796 len = d->actual_length;
797 d->actual_length = 0;
798 d->status = 0;
799 ttusb_process_frame(ttusb, data, len);
800 }
801 }
802 usb_submit_urb(urb, GFP_ATOMIC);
803}
804
805static void ttusb_free_iso_urbs(struct ttusb *ttusb)
806{
807 int i;
808
809 for (i = 0; i < ISO_BUF_COUNT; i++)
810 if (ttusb->iso_urb[i])
811 usb_free_urb(ttusb->iso_urb[i]);
812
813 pci_free_consistent(NULL,
814 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
815 ISO_BUF_COUNT, ttusb->iso_buffer,
816 ttusb->iso_dma_handle);
817}
818
819static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
820{
821 int i;
822
823 ttusb->iso_buffer = pci_alloc_consistent(NULL,
824 ISO_FRAME_SIZE *
825 FRAMES_PER_ISO_BUF *
826 ISO_BUF_COUNT,
827 &ttusb->iso_dma_handle);
828
829 memset(ttusb->iso_buffer, 0,
830 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
831
832 for (i = 0; i < ISO_BUF_COUNT; i++) {
833 struct urb *urb;
834
835 if (!
836 (urb =
837 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
838 ttusb_free_iso_urbs(ttusb);
839 return -ENOMEM;
840 }
841
842 ttusb->iso_urb[i] = urb;
843 }
844
845 return 0;
846}
847
848static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
849{
850 int i;
851
852 for (i = 0; i < ISO_BUF_COUNT; i++)
853 usb_kill_urb(ttusb->iso_urb[i]);
854
855 ttusb->iso_streaming = 0;
856}
857
858static int ttusb_start_iso_xfer(struct ttusb *ttusb)
859{
860 int i, j, err, buffer_offset = 0;
861
862 if (ttusb->iso_streaming) {
863 printk("%s: iso xfer already running!\n", __FUNCTION__);
864 return 0;
865 }
866
867 ttusb->cc = -1;
868 ttusb->insync = 0;
869 ttusb->mux_state = 0;
870
871 for (i = 0; i < ISO_BUF_COUNT; i++) {
872 int frame_offset = 0;
873 struct urb *urb = ttusb->iso_urb[i];
874
875 urb->dev = ttusb->dev;
876 urb->context = ttusb;
877 urb->complete = ttusb_iso_irq;
878 urb->pipe = ttusb->isoc_in_pipe;
879 urb->transfer_flags = URB_ISO_ASAP;
880 urb->interval = 1;
881 urb->number_of_packets = FRAMES_PER_ISO_BUF;
882 urb->transfer_buffer_length =
883 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
884 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
885 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
886
887 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
888 urb->iso_frame_desc[j].offset = frame_offset;
889 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
890 frame_offset += ISO_FRAME_SIZE;
891 }
892 }
893
894 for (i = 0; i < ISO_BUF_COUNT; i++) {
895 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
896 ttusb_stop_iso_xfer(ttusb);
897 printk
898 ("%s: failed urb submission (%i: err = %i)!\n",
899 __FUNCTION__, i, err);
900 return err;
901 }
902 }
903
904 ttusb->iso_streaming = 1;
905
906 return 0;
907}
908
909#ifdef TTUSB_HWSECTIONS
910static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
911 int len)
912{
913 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
914}
915
916static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
917 int len)
918{
919// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
920#error TODO: handle ugly stuff
921// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
922}
923#endif
924
925static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
926{
927 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
928 int feed_type = 1;
929
930 dprintk("ttusb_start_feed\n");
931
932 switch (dvbdmxfeed->type) {
933 case DMX_TYPE_TS:
934 break;
935 case DMX_TYPE_SEC:
936 break;
937 default:
938 return -EINVAL;
939 }
940
941 if (dvbdmxfeed->type == DMX_TYPE_TS) {
942 switch (dvbdmxfeed->pes_type) {
943 case DMX_TS_PES_VIDEO:
944 case DMX_TS_PES_AUDIO:
945 case DMX_TS_PES_TELETEXT:
946 case DMX_TS_PES_PCR:
947 case DMX_TS_PES_OTHER:
948 break;
949 default:
950 return -EINVAL;
951 }
952 }
953
954#ifdef TTUSB_HWSECTIONS
955#error TODO: allocate filters
956 if (dvbdmxfeed->type == DMX_TYPE_TS) {
957 feed_type = 1;
958 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
959 feed_type = 2;
960 }
961#endif
962
963 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
964
965 if (0 == ttusb->running_feed_count++)
966 ttusb_start_iso_xfer(ttusb);
967
968 return 0;
969}
970
971static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
972{
973 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
974
975 ttusb_del_channel(ttusb, dvbdmxfeed->index);
976
977 if (--ttusb->running_feed_count == 0)
978 ttusb_stop_iso_xfer(ttusb);
979
980 return 0;
981}
982
983static int ttusb_setup_interfaces(struct ttusb *ttusb)
984{
985 usb_set_interface(ttusb->dev, 1, 1);
986
987 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
988 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
989 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
990
991 return 0;
992}
993
994#if 0
995static u8 stc_firmware[8192];
996
997static int stc_open(struct inode *inode, struct file *file)
998{
999 struct ttusb *ttusb = file->private_data;
1000 int addr;
1001
1002 for (addr = 0; addr < 8192; addr += 16) {
1003 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
1004 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
1005 16);
1006 }
1007
1008 return 0;
1009}
1010
1011static ssize_t stc_read(struct file *file, char *buf, size_t count,
1012 loff_t * offset)
1013{
1014 int tc = count;
1015
1016 if ((tc + *offset) > 8192)
1017 tc = 8192 - *offset;
1018
1019 if (tc < 0)
1020 return 0;
1021
1022 if (copy_to_user(buf, stc_firmware + *offset, tc))
1023 return -EFAULT;
1024
1025 *offset += tc;
1026
1027 return tc;
1028}
1029
1030static int stc_release(struct inode *inode, struct file *file)
1031{
1032 return 0;
1033}
1034
1035static struct file_operations stc_fops = {
1036 .owner = THIS_MODULE,
1037 .read = stc_read,
1038 .open = stc_open,
1039 .release = stc_release,
1040};
1041#endif
1042
1043static u32 functionality(struct i2c_adapter *adapter)
1044{
1045 return I2C_FUNC_I2C;
1046}
1047
1048
1049
1050static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1051{
1052 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1053 u8 data[4];
1054 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1055 u32 div;
1056
1057 div = (params->frequency + 36166667) / 166667;
1058
1059 data[0] = (div >> 8) & 0x7f;
1060 data[1] = div & 0xff;
1061 data[2] = ((div >> 10) & 0x60) | 0x85;
1062 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1063
1064 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1065 return 0;
1066}
1067
1068struct cx22700_config alps_tdmb7_config = {
1069 .demod_address = 0x43,
1070 .pll_set = alps_tdmb7_pll_set,
1071};
1072
1073
1074
1075
1076
1077static int philips_tdm1316l_pll_init(struct dvb_frontend* fe)
1078{
1079 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1080 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1081 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1082 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1083
1084 // setup PLL configuration
1085 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1086 msleep(1);
1087
1088 // disable the mc44BC374c (do not check for errors)
1089 tuner_msg.addr = 0x65;
1090 tuner_msg.buf = disable_mc44BC374c;
1091 tuner_msg.len = sizeof(disable_mc44BC374c);
1092 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1093 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1094 }
1095
1096 return 0;
1097}
1098
1099static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1100{
1101 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1102 u8 tuner_buf[4];
1103 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1104 int tuner_frequency = 0;
1105 u8 band, cp, filter;
1106
1107 // determine charge pump
1108 tuner_frequency = params->frequency + 36130000;
1109 if (tuner_frequency < 87000000) return -EINVAL;
1110 else if (tuner_frequency < 130000000) cp = 3;
1111 else if (tuner_frequency < 160000000) cp = 5;
1112 else if (tuner_frequency < 200000000) cp = 6;
1113 else if (tuner_frequency < 290000000) cp = 3;
1114 else if (tuner_frequency < 420000000) cp = 5;
1115 else if (tuner_frequency < 480000000) cp = 6;
1116 else if (tuner_frequency < 620000000) cp = 3;
1117 else if (tuner_frequency < 830000000) cp = 5;
1118 else if (tuner_frequency < 895000000) cp = 7;
1119 else return -EINVAL;
1120
1121 // determine band
1122 if (params->frequency < 49000000) return -EINVAL;
1123 else if (params->frequency < 159000000) band = 1;
1124 else if (params->frequency < 444000000) band = 2;
1125 else if (params->frequency < 861000000) band = 4;
1126 else return -EINVAL;
1127
1128 // setup PLL filter
1129 switch (params->u.ofdm.bandwidth) {
1130 case BANDWIDTH_6_MHZ:
1131 tda1004x_write_byte(fe, 0x0C, 0);
1132 filter = 0;
1133 break;
1134
1135 case BANDWIDTH_7_MHZ:
1136 tda1004x_write_byte(fe, 0x0C, 0);
1137 filter = 0;
1138 break;
1139
1140 case BANDWIDTH_8_MHZ:
1141 tda1004x_write_byte(fe, 0x0C, 0xFF);
1142 filter = 1;
1143 break;
1144
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 // calculate divisor
1150 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1151 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1152
1153 // setup tuner buffer
1154 tuner_buf[0] = tuner_frequency >> 8;
1155 tuner_buf[1] = tuner_frequency & 0xff;
1156 tuner_buf[2] = 0xca;
1157 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1158
1159 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1160 return -EIO;
1161
1162 msleep(1);
1163 return 0;
1164}
1165
1166static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1167{
1168 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1169
1170 return request_firmware(fw, name, &ttusb->dev->dev);
1171}
1172
1173static struct tda1004x_config philips_tdm1316l_config = {
1174
1175 .demod_address = 0x8,
1176 .invert = 1,
1177 .invert_oclk = 0,
1178 .pll_init = philips_tdm1316l_pll_init,
1179 .pll_set = philips_tdm1316l_pll_set,
1180 .request_firmware = philips_tdm1316l_request_firmware,
1181};
1182
1183static u8 alps_bsbe1_inittab[] = {
1184 0x01, 0x15,
1185 0x02, 0x30,
1186 0x03, 0x00,
1187 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1188 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1189 0x06, 0x40, /* DAC not used, set to high impendance mode */
1190 0x07, 0x00, /* DAC LSB */
1191 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1192 0x09, 0x00, /* FIFO */
1193 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1194 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1195 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1196 0x10, 0x3f, // AGC2 0x3d
1197 0x11, 0x84,
1198 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1199 0x15, 0xc9, // lock detector threshold
1200 0x16, 0x00,
1201 0x17, 0x00,
1202 0x18, 0x00,
1203 0x19, 0x00,
1204 0x1a, 0x00,
1205 0x1f, 0x50,
1206 0x20, 0x00,
1207 0x21, 0x00,
1208 0x22, 0x00,
1209 0x23, 0x00,
1210 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1211 0x29, 0x1e, // 1/2 threshold
1212 0x2a, 0x14, // 2/3 threshold
1213 0x2b, 0x0f, // 3/4 threshold
1214 0x2c, 0x09, // 5/6 threshold
1215 0x2d, 0x05, // 7/8 threshold
1216 0x2e, 0x01,
1217 0x31, 0x1f, // test all FECs
1218 0x32, 0x19, // viterbi and synchro search
1219 0x33, 0xfc, // rs control
1220 0x34, 0x93, // error control
1221 0x0f, 0x92,
1222 0xff, 0xff
1223};
1224
1225static u8 alps_bsru6_inittab[] = {
1226 0x01, 0x15,
1227 0x02, 0x30,
1228 0x03, 0x00,
1229 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1230 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1231 0x06, 0x40, /* DAC not used, set to high impendance mode */
1232 0x07, 0x00, /* DAC LSB */
1233 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1234 0x09, 0x00, /* FIFO */
1235 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1236 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1237 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1238 0x10, 0x3f, // AGC2 0x3d
1239 0x11, 0x84,
1240 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1241 0x15, 0xc9, // lock detector threshold
1242 0x16, 0x00,
1243 0x17, 0x00,
1244 0x18, 0x00,
1245 0x19, 0x00,
1246 0x1a, 0x00,
1247 0x1f, 0x50,
1248 0x20, 0x00,
1249 0x21, 0x00,
1250 0x22, 0x00,
1251 0x23, 0x00,
1252 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1253 0x29, 0x1e, // 1/2 threshold
1254 0x2a, 0x14, // 2/3 threshold
1255 0x2b, 0x0f, // 3/4 threshold
1256 0x2c, 0x09, // 5/6 threshold
1257 0x2d, 0x05, // 7/8 threshold
1258 0x2e, 0x01,
1259 0x31, 0x1f, // test all FECs
1260 0x32, 0x19, // viterbi and synchro search
1261 0x33, 0xfc, // rs control
1262 0x34, 0x93, // error control
1263 0x0f, 0x52,
1264 0xff, 0xff
1265};
1266
1267static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1268{
1269 u8 aclk = 0;
1270 u8 bclk = 0;
1271
1272 if (srate < 1500000) {
1273 aclk = 0xb7;
1274 bclk = 0x47;
1275 } else if (srate < 3000000) {
1276 aclk = 0xb7;
1277 bclk = 0x4b;
1278 } else if (srate < 7000000) {
1279 aclk = 0xb7;
1280 bclk = 0x4f;
1281 } else if (srate < 14000000) {
1282 aclk = 0xb7;
1283 bclk = 0x53;
1284 } else if (srate < 30000000) {
1285 aclk = 0xb6;
1286 bclk = 0x53;
1287 } else if (srate < 45000000) {
1288 aclk = 0xb4;
1289 bclk = 0x51;
1290 }
1291
1292 stv0299_writereg(fe, 0x13, aclk);
1293 stv0299_writereg(fe, 0x14, bclk);
1294 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1295 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1296 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1297
1298 return 0;
1299}
1300
1301static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1302{
1303 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1304 u8 buf[4];
1305 u32 div;
1306 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1307
1308 if ((params->frequency < 950000) || (params->frequency > 2150000))
1309 return -EINVAL;
1310
1311 div = (params->frequency + (125 - 1)) / 125; // round correctly
1312 buf[0] = (div >> 8) & 0x7f;
1313 buf[1] = div & 0xff;
1314 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1315 buf[3] = 0xC4;
1316
1317 if (params->frequency > 1530000)
1318 buf[3] = 0xC0;
1319
1320 /* BSBE1 wants XCE bit set */
1321 if (ttusb->revision == TTUSB_REV_2_2)
1322 buf[3] |= 0x20;
1323
1324 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1325 return -EIO;
1326
1327 return 0;
1328}
1329
1330static struct stv0299_config alps_stv0299_config = {
1331 .demod_address = 0x68,
1332 .inittab = alps_bsru6_inittab,
1333 .mclk = 88000000UL,
1334 .invert = 1,
1335 .enhanced_tuning = 0,
1336 .skip_reinit = 0,
1337 .lock_output = STV0229_LOCKOUTPUT_1,
1338 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1339 .min_delay_ms = 100,
1340 .set_symbol_rate = alps_stv0299_set_symbol_rate,
1341 .pll_set = philips_tsa5059_pll_set,
1342};
1343
1344static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1345{
1346 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1347 u8 buf[4];
1348 u32 div;
1349 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1350
1351 div = params->frequency / 125;
1352
1353 buf[0] = (div >> 8) & 0x7f;
1354 buf[1] = div & 0xff;
1355 buf[2] = 0x8e;
1356 buf[3] = 0x00;
1357
1358 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1359 return -EIO;
1360
1361 return 0;
1362}
1363
1364static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1365
1366 .demod_address = 0x68,
1367 .pll_set = ttusb_novas_grundig_29504_491_pll_set,
1368};
1369
1370
1371
1372static void frontend_init(struct ttusb* ttusb)
1373{
1374 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1375 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1376 // try the stv0299 based first
1377 ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap);
1378 if (ttusb->fe != NULL) {
1379 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1380 alps_stv0299_config.inittab = alps_bsbe1_inittab;
1381 ttusb->fe->ops->set_voltage = lnbp21_set_voltage;
1382 } else { // ALPS BSRU6
1383 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1384 }
1385 break;
1386 }
1387
1388 // Grundig 29504-491
1389 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1390 if (ttusb->fe != NULL) {
1391 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1392 break;
1393 }
1394
1395 break;
1396
1397 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1398 // try the ALPS TDMB7 first
1399 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
1400 if (ttusb->fe != NULL)
1401 break;
1402
1403 // Philips td1316
1404 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
1405 if (ttusb->fe != NULL)
1406 break;
1407 break;
1408 }
1409
1410 if (ttusb->fe == NULL) {
1411 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
1412 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1413 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1414 } else {
1415 if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) {
1416 printk("dvb-ttusb-budget: Frontend registration failed!\n");
1417 if (ttusb->fe->ops->release)
1418 ttusb->fe->ops->release(ttusb->fe);
1419 ttusb->fe = NULL;
1420 }
1421 }
1422}
1423
1424
1425
1426static struct i2c_algorithm ttusb_dec_algo = {
1427 .name = "ttusb dec i2c algorithm",
1428 .id = I2C_ALGO_BIT,
1429 .master_xfer = master_xfer,
1430 .functionality = functionality,
1431};
1432
1433static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1434{
1435 struct usb_device *udev;
1436 struct ttusb *ttusb;
1437 int result;
1438
1439 dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
1440
1441 udev = interface_to_usbdev(intf);
1442
1443 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
1444
1445 if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
1446 return -ENOMEM;
1447
1448 memset(ttusb, 0, sizeof(struct ttusb));
1449
1450 ttusb->dev = udev;
1451 ttusb->c = 0;
1452 ttusb->mux_state = 0;
1453 sema_init(&ttusb->semi2c, 0);
1454 sema_init(&ttusb->semusb, 1);
1455
1456 ttusb_setup_interfaces(ttusb);
1457
1458 ttusb_alloc_iso_urbs(ttusb);
1459 if (ttusb_init_controller(ttusb))
1460 printk("ttusb_init_controller: error\n");
1461
1462 up(&ttusb->semi2c);
1463
1464 dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
1465 ttusb->adapter->priv = ttusb;
1466
1467 /* i2c */
1468 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1469 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1470
1471 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1472
1473#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1474 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1475#else
1476 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1477#endif
1478 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1479 ttusb->i2c_adap.algo_data = NULL;
1480 ttusb->i2c_adap.id = I2C_ALGO_BIT;
1481
1482 result = i2c_add_adapter(&ttusb->i2c_adap);
1483 if (result) {
1484 dvb_unregister_adapter (ttusb->adapter);
1485 return result;
1486 }
1487
1488 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1489
1490 ttusb->dvb_demux.dmx.capabilities =
1491 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1492 ttusb->dvb_demux.priv = NULL;
1493#ifdef TTUSB_HWSECTIONS
1494 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1495#else
1496 ttusb->dvb_demux.filternum = 32;
1497#endif
1498 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1499 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1500 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1501 ttusb->dvb_demux.write_to_decoder = NULL;
1502
1503 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1504 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1505 i2c_del_adapter(&ttusb->i2c_adap);
1506 dvb_unregister_adapter (ttusb->adapter);
1507 return -ENODEV;
1508 }
1509//FIXME dmxdev (nur WAS?)
1510 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1511 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1512 ttusb->dmxdev.capabilities = 0;
1513
1514 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, ttusb->adapter)) < 0) {
1515 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1516 result);
1517 dvb_dmx_release(&ttusb->dvb_demux);
1518 i2c_del_adapter(&ttusb->i2c_adap);
1519 dvb_unregister_adapter (ttusb->adapter);
1520 return -ENODEV;
1521 }
1522
1523 if (dvb_net_init(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
1524 printk("ttusb_dvb: dvb_net_init failed!\n");
1525 dvb_dmxdev_release(&ttusb->dmxdev);
1526 dvb_dmx_release(&ttusb->dvb_demux);
1527 i2c_del_adapter(&ttusb->i2c_adap);
1528 dvb_unregister_adapter (ttusb->adapter);
1529 return -ENODEV;
1530 }
1531
1532#if 0
1533 ttusb->stc_devfs_handle =
1534 devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
1535 DEVFS_FL_DEFAULT, 0, 192,
1536 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
1537 | S_IROTH | S_IWOTH, &stc_fops, ttusb);
1538#endif
1539 usb_set_intfdata(intf, (void *) ttusb);
1540
1541 frontend_init(ttusb);
1542
1543 return 0;
1544}
1545
1546static void ttusb_disconnect(struct usb_interface *intf)
1547{
1548 struct ttusb *ttusb = usb_get_intfdata(intf);
1549
1550 usb_set_intfdata(intf, NULL);
1551
1552 ttusb->disconnecting = 1;
1553
1554 ttusb_stop_iso_xfer(ttusb);
1555
1556 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1557 dvb_net_release(&ttusb->dvbnet);
1558 dvb_dmxdev_release(&ttusb->dmxdev);
1559 dvb_dmx_release(&ttusb->dvb_demux);
1560 if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe);
1561 i2c_del_adapter(&ttusb->i2c_adap);
1562 dvb_unregister_adapter(ttusb->adapter);
1563
1564 ttusb_free_iso_urbs(ttusb);
1565
1566 kfree(ttusb);
1567
1568 dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__);
1569}
1570
1571static struct usb_device_id ttusb_table[] = {
1572 {USB_DEVICE(0xb48, 0x1003)},
1573/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */
1574 {USB_DEVICE(0xb48, 0x1005)},
1575 {}
1576};
1577
1578MODULE_DEVICE_TABLE(usb, ttusb_table);
1579
1580static struct usb_driver ttusb_driver = {
1581 .name = "Technotrend/Hauppauge USB-Nova",
1582 .probe = ttusb_probe,
1583 .disconnect = ttusb_disconnect,
1584 .id_table = ttusb_table,
1585};
1586
1587static int __init ttusb_init(void)
1588{
1589 int err;
1590
1591 if ((err = usb_register(&ttusb_driver)) < 0) {
1592 printk("%s: usb_register failed! Error number %d",
1593 __FILE__, err);
1594 return err;
1595 }
1596
1597 return 0;
1598}
1599
1600static void __exit ttusb_exit(void)
1601{
1602 usb_deregister(&ttusb_driver);
1603}
1604
1605module_init(ttusb_init);
1606module_exit(ttusb_exit);
1607
1608MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1609MODULE_DESCRIPTION("TTUSB DVB Driver");
1610MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
new file mode 100644
index 000000000000..95ee7995455e
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
@@ -0,0 +1,1644 @@
1
2#include <asm/types.h>
3
4static u8 dsp_bootcode [] = {
5 0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00,
6 0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f,
7 0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb,
8 0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8,
9 0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe,
10 0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5,
11 0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00,
12 0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8,
13 0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5,
14 0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01,
15 0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8,
16 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8,
17 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89,
18 0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20,
19 0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d,
20 0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02,
21 0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00,
22 0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03,
23 0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74,
24 0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11,
25 0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8,
26 0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95,
27 0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6,
28 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee,
29 0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff,
30 0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45,
31 0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3,
32 0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16,
33 0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20,
34 0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e,
35 0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95,
36 0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11,
37 0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01,
38 0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11,
39 0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00,
40 0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11,
41 0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10,
42 0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15,
43 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
44 0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21,
45 0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8,
46 0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16,
47 0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11,
48 0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d,
49 0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8,
50 0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d,
51 0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01,
52 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb,
53 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00,
54 0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c,
55 0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11,
56 0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e,
57 0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12,
58 0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3,
59 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66,
60 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87,
61 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8,
62 0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8,
63 0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8,
64 0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12,
65 0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f,
66 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
67 0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93,
68 0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05,
69 0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0,
70 0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f,
71 0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8,
72 0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f,
73 0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93,
74 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8,
75 0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0,
76 0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11,
77 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
78 0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2,
79 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74,
80 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
81 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2,
82 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00,
83 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6,
84 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
85 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
86 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
87 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
88 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
89 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
90 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
91 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
92 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
93 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
94 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd,
95 0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95,
96 0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30,
97 0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff,
98 0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80,
99 0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95,
100 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a,
101 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19,
102 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15,
103 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11,
104 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b,
105 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb,
106 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
107 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2,
108 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2,
109 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1,
110 0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04,
111 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
112 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
113 0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e,
114 0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01,
115 0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff,
116 0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00,
117 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
118 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2,
119 0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2,
120 0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1,
121 0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1,
122 0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff,
123 0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06,
124 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
125 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39,
126 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18,
127 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01,
128 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02,
129 0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11,
130 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95,
131 0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98,
132 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b,
133 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71,
134 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
135 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0,
136 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
137 0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15,
138 0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11,
139 0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83,
140 0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05,
141 0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8,
142 0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01,
143 0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c,
144 0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1,
145 0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9,
146 0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00,
147 0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00,
148 0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74,
149 0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10,
150 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74,
151 0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12,
152 0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11,
153 0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2,
154 0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2,
155 0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c,
156 0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0,
157 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8,
158 0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
159 0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16,
160 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
161 0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff,
162 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8,
163 0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2,
164 0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0,
165 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a,
166 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff,
167 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff,
168 0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2,
169 0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0,
170 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8,
171 0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
172 0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a,
173 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
174 0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff,
175 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2,
176 0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12,
177 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58,
178 0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8,
179 0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2,
180 0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16,
181 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58,
182 0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8,
183 0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2,
184 0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a,
185 0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00,
186 0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2,
187 0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e,
188 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00,
189 0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2,
190 0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
191 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
192 0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed,
193 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02,
194 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08,
195 0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20,
196 0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10,
197 0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08,
198 0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74,
199 0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12,
200 0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04,
201 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
202 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
203 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
204 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69,
205 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
206 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
207 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
208 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41,
209 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
210 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57,
211 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c,
212 0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36,
213 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea,
214 0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00,
215 0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95,
216 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8,
217 0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74,
218 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73,
219 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff,
220 0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1,
221 0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
222 0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01,
223 0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a,
224 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
225 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc,
226 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02,
227 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
228 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
229 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
230 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
231 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09,
232 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
233 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00,
234 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
235 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
236 0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
237 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
238 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
239 0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01,
240 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02,
241 0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03,
242 0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11,
243 0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00,
244 0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00,
245 0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95,
246 0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11,
247 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a,
248 0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00,
249 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1,
250 0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
251 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
252 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
253 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
254 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
255 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c,
256 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
257 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00,
258 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
259 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
260 0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
261 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
262 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
263 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01,
264 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02,
265 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03,
266 0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04,
267 0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d,
268 0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01,
269 0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c,
270 0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa,
271 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00,
272 0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38,
273 0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1,
274 0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56,
275 0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95,
276 0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8,
277 0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3,
278 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2,
279 0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1,
280 0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95,
281 0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1,
282 0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00,
283 0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8,
284 0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44,
285 0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd,
286 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8,
287 0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2,
288 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
289 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
290 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
291 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
292 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
293 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
294 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
295 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
296 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
297 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
298 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff,
299 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04,
300 0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18,
301 0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d,
302 0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e,
303 0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16,
304 0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12,
305 0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c,
306 0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08,
307 0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38,
308 0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00,
309 0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6,
310 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b,
311 0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa,
312 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c,
313 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f,
314 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a,
315 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a,
316 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b,
317 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b,
318 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
319 0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
320 0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
321 0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91,
322 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11,
323 0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79,
324 0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95,
325 0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11,
326 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
327 0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11,
328 0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8,
329 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
330 0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0,
331 0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8,
332 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
333 0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00,
334 0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11,
335 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02,
336 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20,
337 0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11,
338 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73,
339 0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b,
340 0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
341 0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00,
342 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12,
343 0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
344 0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
345 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92,
346 0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00,
347 0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13,
348 0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01,
349 0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda,
350 0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
351 0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05,
352 0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01,
353 0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01,
354 0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8,
355 0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00,
356 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba,
357 0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11,
358 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12,
359 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13,
360 0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20,
361 0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
362 0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8,
363 0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11,
364 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce,
365 0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30,
366 0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00,
367 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc,
368 0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16,
369 0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03,
370 0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45,
371 0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03,
372 0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00,
373 0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b,
374 0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff,
375 0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16,
376 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
377 0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9,
378 0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01,
379 0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74,
380 0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11,
381 0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9,
382 0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9,
383 0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8,
384 0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11,
385 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00,
386 0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00,
387 0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8,
388 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8,
389 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30,
390 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8,
391 0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9,
392 0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8,
393 0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76,
394 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8,
395 0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8,
396 0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80,
397 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80,
398 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00,
399 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8,
400 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8,
401 0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00,
402 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a,
403 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
404 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
405 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
406 0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1,
407 0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01,
408 0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8,
409 0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6,
410 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f,
411 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20,
412 0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c,
413 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00,
414 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff,
415 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d,
416 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09,
417 0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74,
418 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01,
419 0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
420 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
421 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
422 0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11,
423 0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00,
424 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
425 0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00,
426 0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f,
427 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80,
428 0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00,
429 0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33,
430 0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25,
431 0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82,
432 0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2,
433 0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3,
434 0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36,
435 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8,
436 0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39,
437 0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8,
438 0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2,
439 0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79,
440 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95,
441 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30,
442 0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8,
443 0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11,
444 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
445 0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79,
446 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff,
447 0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20,
448 0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74,
449 0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72,
450 0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95,
451 0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f,
452 0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00,
453 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83,
454 0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff,
455 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00,
456 0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91,
457 0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11,
458 0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30,
459 0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30,
460 0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08,
461 0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9,
462 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1,
463 0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b,
464 0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08,
465 0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b,
466 0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff,
467 0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00,
468 0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75,
469 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
470 0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8,
471 0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00,
472 0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74,
473 0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95,
474 0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a,
475 0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62,
476 0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80,
477 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11,
478 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb,
479 0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73,
480 0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
481 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73,
482 0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20,
483 0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee,
484 0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96,
485 0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a,
486 0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
487 0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03,
488 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95,
489 0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb,
490 0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41,
491 0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
492 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13,
493 0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8,
494 0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00,
495 0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0,
496 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8,
497 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8,
498 0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12,
499 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38,
500 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
501 0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01,
502 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81,
503 0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
504 0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86,
505 0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
506 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
507 0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67,
508 0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a,
509 0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
510 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
511 0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67,
512 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b,
513 0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
514 0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30,
515 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
516 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a,
517 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02,
518 0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30,
519 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
520 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a,
521 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01,
522 0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11,
523 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
524 0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8,
525 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
526 0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8,
527 0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80,
528 0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00,
529 0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80,
530 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
531 0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
532 0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20,
533 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
534 0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73,
535 0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20,
536 0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73,
537 0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8,
538 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
539 0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00,
540 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30,
541 0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20,
542 0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8,
543 0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b,
544 0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00,
545 0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16,
546 0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08,
547 0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30,
548 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
549 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
550 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a,
551 0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16,
552 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
553 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
554 0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00,
555 0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17,
556 0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17,
557 0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d,
558 0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18,
559 0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f,
560 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01,
561 0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74,
562 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04,
563 0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
564 0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8,
565 0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72,
566 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00,
567 0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79,
568 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00,
569 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8,
570 0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8,
571 0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00,
572 0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc,
573 0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00,
574 0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00,
575 0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12,
576 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12,
577 0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01,
578 0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02,
579 0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11,
580 0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80,
581 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
582 0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
583 0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20,
584 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
585 0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00,
586 0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00,
587 0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11,
588 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11,
589 0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80,
590 0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20,
591 0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b,
592 0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01,
593 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73,
594 0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
595 0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11,
596 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02,
597 0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb,
598 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95,
599 0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8,
600 0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e,
601 0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e,
602 0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00,
603 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11,
604 0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff,
605 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00,
606 0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70,
607 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8,
608 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12,
609 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12,
610 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4,
611 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
612 0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01,
613 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8,
614 0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71,
615 0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04,
616 0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a,
617 0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00,
618 0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff,
619 0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00,
620 0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00,
621 0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00,
622 0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11,
623 0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95,
624 0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11,
625 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
626 0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17,
627 0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15,
628 0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05,
629 0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06,
630 0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11,
631 0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06,
632 0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20,
633 0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01,
634 0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa,
635 0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00,
636 0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11,
637 0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a,
638 0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09,
639 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce,
640 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95,
641 0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73,
642 0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8,
643 0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12,
644 0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c,
645 0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11,
646 0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01,
647 0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1,
648 0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02,
649 0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87,
650 0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20,
651 0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
652 0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce,
653 0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17,
654 0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09,
655 0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74,
656 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16,
657 0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
658 0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
659 0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc,
660 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11,
661 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
662 0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16,
663 0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95,
664 0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00,
665 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
666 0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45,
667 0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae,
668 0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1,
669 0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb,
670 0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9,
671 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
672 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
673 0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11,
674 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
675 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
676 0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06,
677 0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00,
678 0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f,
679 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
680 0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11,
681 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
682 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
683 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11,
684 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
685 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
686 0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45,
687 0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06,
688 0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04,
689 0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30,
690 0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04,
691 0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0,
692 0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18,
693 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04,
694 0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86,
695 0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e,
696 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74,
697 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e,
698 0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8,
699 0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30,
700 0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09,
701 0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10,
702 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
703 0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71,
704 0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00,
705 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95,
706 0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01,
707 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee,
708 0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99,
709 0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a,
710 0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00,
711 0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c,
712 0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01,
713 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9,
714 0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82,
715 0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01,
716 0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82,
717 0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01,
718 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
719 0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8,
720 0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8,
721 0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00,
722 0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11,
723 0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1,
724 0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02,
725 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
726 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14,
727 0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12,
728 0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff,
729 0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13,
730 0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c,
731 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
732 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01,
733 0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9,
734 0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02,
735 0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11,
736 0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00,
737 0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00,
738 0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa,
739 0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8,
740 0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00,
741 0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48,
742 0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8,
743 0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01,
744 0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a,
745 0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01,
746 0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a,
747 0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12,
748 0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73,
749 0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c,
750 0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81,
751 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10,
752 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1,
753 0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01,
754 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13,
755 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11,
756 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73,
757 0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01,
758 0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13,
759 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00,
760 0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a,
761 0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84,
762 0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88,
763 0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85,
764 0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00,
765 0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03,
766 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
767 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
768 0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84,
769 0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01,
770 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
771 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
772 0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff,
773 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
774 0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78,
775 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1,
776 0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5,
777 0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06,
778 0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30,
779 0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01,
780 0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07,
781 0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b,
782 0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73,
783 0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
784 0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11,
785 0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd,
786 0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4,
787 0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60,
788 0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8,
789 0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8,
790 0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00,
791 0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20,
792 0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
793 0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73,
794 0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74,
795 0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8,
796 0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7,
797 0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0,
798 0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1,
799 0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03,
800 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11,
801 0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01,
802 0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95,
803 0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01,
804 0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c,
805 0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3,
806 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
807 0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e,
808 0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5,
809 0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87,
810 0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62,
811 0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5,
812 0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66,
813 0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87,
814 0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00,
815 0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00,
816 0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7,
817 0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6,
818 0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6,
819 0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11,
820 0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09,
821 0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
822 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
823 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
824 0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b,
825 0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73,
826 0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01,
827 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09,
828 0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16,
829 0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08,
830 0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07,
831 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0,
832 0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00,
833 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01,
834 0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16,
835 0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00,
836 0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02,
837 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
838 0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12,
839 0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00,
840 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81,
841 0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d,
842 0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1,
843 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
844 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
845 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c,
846 0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11,
847 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e,
848 0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00,
849 0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95,
850 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1,
851 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
852 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
853 0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00,
854 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00,
855 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
856 0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e,
857 0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00,
858 0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00,
859 0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14,
860 0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c,
861 0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11,
862 0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13,
863 0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12,
864 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
865 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
866 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
867 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
868 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
869 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
870 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
871 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
872 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
873 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
874 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11,
875 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13,
876 0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14,
877 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
878 0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d,
879 0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e,
880 0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66,
881 0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11,
882 0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32,
883 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
884 0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d,
885 0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20,
886 0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04,
887 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
888 0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04,
889 0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1,
890 0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30,
891 0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa,
892 0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b,
893 0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8,
894 0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa,
895 0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96,
896 0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20,
897 0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00,
898 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16,
899 0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1,
900 0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12,
901 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c,
902 0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03,
903 0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01,
904 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10,
905 0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8,
906 0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04,
907 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10,
908 0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc,
909 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
910 0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c,
911 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
912 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
913 0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c,
914 0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95,
915 0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30,
916 0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01,
917 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae,
918 0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06,
919 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03,
920 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8,
921 0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45,
922 0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
923 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
924 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
925 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
926 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
927 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
928 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
929 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
930 0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10,
931 0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5,
932 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10,
933 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13,
934 0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8,
935 0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd,
936 0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05,
937 0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18,
938 0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03,
939 0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02,
940 0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33,
941 0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1,
942 0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13,
943 0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
944 0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27,
945 0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95,
946 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30,
947 0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45,
948 0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
949 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
950 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
951 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
952 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
953 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
954 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
955 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
956 0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c,
957 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab,
958 0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f,
959 0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa,
960 0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f,
961 0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c,
962 0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa,
963 0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c,
964 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab,
965 0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa,
966 0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1,
967 0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95,
968 0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1,
969 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
970 0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1,
971 0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c,
972 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa,
973 0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c,
974 0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00,
975 0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17,
976 0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74,
977 0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1,
978 0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c,
979 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa,
980 0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45,
981 0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05,
982 0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b,
983 0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04,
984 0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f,
985 0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
986 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16,
987 0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16,
988 0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1,
989 0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04,
990 0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73,
991 0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1,
992 0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95,
993 0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16,
994 0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
995 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3,
996 0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45,
997 0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17,
998 0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06,
999 0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9,
1000 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
1001 0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00,
1002 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16,
1003 0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b,
1004 0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31,
1005 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
1006 0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c,
1007 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
1008 0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04,
1009 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
1010 0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff,
1011 0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86,
1012 0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16,
1013 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc,
1014 0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11,
1015 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
1016 0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81,
1017 0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8,
1018 0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c,
1019 0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61,
1020 0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8,
1021 0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13,
1022 0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01,
1023 0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8,
1024 0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10,
1025 0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75,
1026 0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01,
1027 0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63,
1028 0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8,
1029 0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03,
1030 0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00,
1031 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b,
1032 0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01,
1033 0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8,
1034 0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8,
1035 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9,
1036 0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04,
1037 0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8,
1038 0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20,
1039 0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01,
1040 0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74,
1041 0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04,
1042 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
1043 0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8,
1044 0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68,
1045 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00,
1046 0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40,
1047 0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f,
1048 0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11,
1049 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81,
1050 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00,
1051 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1,
1052 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b,
1053 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
1054 0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0,
1055 0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00,
1056 0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95,
1057 0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff,
1058 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06,
1059 0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00,
1060 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
1061 0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02,
1062 0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9,
1063 0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef,
1064 0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d,
1065 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
1066 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17,
1067 0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11,
1068 0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45,
1069 0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78,
1070 0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2,
1071 0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08,
1072 0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1,
1073 0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0,
1074 0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95,
1075 0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00,
1076 0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17,
1077 0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42,
1078 0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb,
1079 0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90,
1080 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01,
1081 0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01,
1082 0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16,
1083 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
1084 0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16,
1085 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
1086 0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf,
1087 0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00,
1088 0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16,
1089 0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9,
1090 0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90,
1091 0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90,
1092 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc,
1093 0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00,
1094 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11,
1095 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10,
1096 0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8,
1097 0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90,
1098 0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01,
1099 0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e,
1100 0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01,
1101 0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12,
1102 0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04,
1103 0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16,
1104 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
1105 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
1106 0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95,
1107 0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00,
1108 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
1109 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00,
1110 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11,
1111 0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07,
1112 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
1113 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
1114 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95,
1115 0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff,
1116 0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
1117 0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
1118 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
1119 0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec,
1120 0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01,
1121 0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb,
1122 0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00,
1123 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
1124 0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08,
1125 0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85,
1126 0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8,
1127 0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00,
1128 0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02,
1129 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00,
1130 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
1131 0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8,
1132 0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85,
1133 0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06,
1134 0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20,
1135 0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d,
1136 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11,
1137 0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec,
1138 0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81,
1139 0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01,
1140 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
1141 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
1142 0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76,
1143 0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00,
1144 0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1,
1145 0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3,
1146 0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00,
1147 0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1,
1148 0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3,
1149 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00,
1150 0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81,
1151 0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1152 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff,
1153 0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80,
1154 0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8,
1155 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
1156 0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00,
1157 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
1158 0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17,
1159 0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17,
1160 0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f,
1161 0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17,
1162 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3,
1163 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06,
1164 0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b,
1165 0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07,
1166 0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14,
1167 0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95,
1168 0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57,
1169 0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6,
1170 0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8,
1171 0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11,
1172 0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81,
1173 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07,
1174 0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2,
1175 0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08,
1176 0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11,
1177 0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81,
1178 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09,
1179 0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11,
1180 0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
1181 0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95,
1182 0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52,
1183 0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55,
1184 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1185 0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55,
1186 0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12,
1187 0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82,
1188 0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73,
1189 0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12,
1190 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
1191 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d,
1192 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34,
1193 0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13,
1194 0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83,
1195 0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55,
1196 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1197 0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40,
1198 0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40,
1199 0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
1200 0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95,
1201 0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52,
1202 0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55,
1203 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1204 0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73,
1205 0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12,
1206 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
1207 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f,
1208 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32,
1209 0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57,
1210 0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40,
1211 0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95,
1212 0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82,
1213 0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2,
1214 0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1215 0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11,
1216 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e,
1217 0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04,
1218 0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff,
1219 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20,
1220 0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12,
1221 0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1,
1222 0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54,
1223 0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54,
1224 0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1225 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
1226 0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2,
1227 0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55,
1228 0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12,
1229 0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13,
1230 0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56,
1231 0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1,
1232 0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82,
1233 0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01,
1234 0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80,
1235 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
1236 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9,
1237 0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16,
1238 0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a,
1239 0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c,
1240 0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17,
1241 0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81,
1242 0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53,
1243 0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20,
1244 0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08,
1245 0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b,
1246 0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06,
1247 0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00,
1248 0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03,
1249 0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01,
1250 0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08,
1251 0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00,
1252 0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17,
1253 0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18,
1254 0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c,
1255 0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00,
1256 0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2,
1257 0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04,
1258 0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14,
1259 0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06,
1260 0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10,
1261 0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11,
1262 0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05,
1263 0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05,
1264 0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05,
1265 0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea,
1266 0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07,
1267 0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7,
1268 0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b,
1269 0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27,
1270 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
1271 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11,
1272 0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2,
1273 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10,
1274 0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16,
1275 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11,
1276 0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09,
1277 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1278 0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71,
1279 0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b,
1280 0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11,
1281 0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81,
1282 0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff,
1283 0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86,
1284 0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80,
1285 0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e,
1286 0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16,
1287 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16,
1288 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11,
1289 0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1290 0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9,
1291 0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03,
1292 0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12,
1293 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1294 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1295 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1296 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1297 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1298 0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8,
1299 0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01,
1300 0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12,
1301 0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82,
1302 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76,
1303 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66,
1304 0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b,
1305 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07,
1306 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1307 0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11,
1308 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1309 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1310 0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
1311 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
1312 0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11,
1313 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1314 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1315 0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
1316 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
1317 0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11,
1318 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1319 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1320 0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1321 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
1322 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
1323 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
1324 0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81,
1325 0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1326 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1327 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1328 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1329 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1330 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1331 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1332 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1333 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1334 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73,
1335 0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11,
1336 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1,
1337 0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
1338 0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08,
1339 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
1340 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b,
1341 0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11,
1342 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44,
1343 0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81,
1344 0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
1345 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
1346 0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01,
1347 0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81,
1348 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1349 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
1350 0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11,
1351 0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93,
1352 0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1353 0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10,
1354 0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08,
1355 0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01,
1356 0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0,
1357 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1358 0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95,
1359 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
1360 0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95,
1361 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
1362 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04,
1363 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1364 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1365 0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e,
1366 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
1367 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1368 0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1369 0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1,
1370 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c,
1371 0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
1372 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1373 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6,
1374 0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1375 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1376 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
1377 0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82,
1378 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1379 0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1,
1380 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
1381 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08,
1382 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
1383 0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1384 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6,
1385 0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1386 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1387 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
1388 0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82,
1389 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1390 0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1391 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1,
1392 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04,
1393 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
1394 0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1395 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1,
1396 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03,
1397 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1398 0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02,
1399 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
1400 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1401 0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1,
1402 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
1403 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
1404 0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62,
1405 0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16,
1406 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
1407 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05,
1408 0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00,
1409 0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11,
1410 0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95,
1411 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
1412 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1413 0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01,
1414 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81,
1415 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1416 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1417 0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95,
1418 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c,
1419 0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53,
1420 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00,
1421 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
1422 0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1,
1423 0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
1424 0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20,
1425 0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1,
1426 0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06,
1427 0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39,
1428 0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1,
1429 0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a,
1430 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41,
1431 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1,
1432 0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e,
1433 0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48,
1434 0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1,
1435 0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12,
1436 0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1437 0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06,
1438 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12,
1439 0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82,
1440 0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95,
1441 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1442 0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd,
1443 0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01,
1444 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8,
1445 0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80,
1446 0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80,
1447 0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11,
1448 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
1449 0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01,
1450 0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11,
1451 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
1452 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
1453 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
1454 0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1455 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06,
1456 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1457 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01,
1458 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1459 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1460 0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06,
1461 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1462 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03,
1463 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1464 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1465 0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06,
1466 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1467 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05,
1468 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1469 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1470 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
1471 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1,
1472 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07,
1473 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1474 0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1475 0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06,
1476 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1477 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09,
1478 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1479 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1480 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
1481 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1482 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b,
1483 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1484 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1485 0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
1486 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1487 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d,
1488 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1489 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1490 0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06,
1491 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1492 0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
1493 0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
1494 0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1,
1495 0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73,
1496 0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1497 0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95,
1498 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80,
1499 0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80,
1500 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
1501 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95,
1502 0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11,
1503 0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1504 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
1505 0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2,
1506 0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02,
1507 0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6,
1508 0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12,
1509 0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
1510 0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62,
1511 0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01,
1512 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11,
1513 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff,
1514 0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11,
1515 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11,
1516 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3,
1517 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1518 0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff,
1519 0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b,
1520 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11,
1521 0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01,
1522 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00,
1523 0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1,
1524 0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04,
1525 0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24,
1526 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
1527 0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08,
1528 0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31,
1529 0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11,
1530 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16,
1531 0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06,
1532 0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1533 0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11,
1534 0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73,
1535 0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b,
1536 0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8,
1537 0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11,
1538 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44,
1539 0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95,
1540 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1541 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95,
1542 0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45,
1543 0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c,
1544 0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17,
1545 0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86,
1546 0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95,
1547 0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1548 0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11,
1549 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80,
1550 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
1551 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc,
1552 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82,
1553 0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12,
1554 0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02,
1555 0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1,
1556 0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0,
1557 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82,
1558 0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
1559 0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02,
1560 0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1,
1561 0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda,
1562 0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b,
1563 0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00,
1564 0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1565 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9,
1566 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
1567 0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf,
1568 0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01,
1569 0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12,
1570 0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01,
1571 0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16,
1572 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d,
1573 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79,
1574 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68,
1575 0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65,
1576 0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f,
1577 0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e,
1578 0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47,
1579 0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30,
1580 0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c,
1581 0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62,
1582 0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20,
1583 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31,
1584 0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31,
1585 0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35,
1586 0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00,
1587 0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00,
1588 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
1589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1591 0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00,
1592 0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01,
1593 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1,
1594 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00,
1595 0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02,
1596 0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1597 0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7,
1598 0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41,
1599 0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00,
1600 0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00,
1601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603 0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00,
1604 0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40,
1605 0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80,
1606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1607 0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00,
1608 0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00,
1609 0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8,
1610 0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0,
1611 0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81,
1612 0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73,
1613 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1614 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1615 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1616 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1617 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1618 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1619 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1620 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1621 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1622 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1623 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1624 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1625 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1626 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1627 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1628 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1629 0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1630 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1631 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1632 0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1633 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1634 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1635 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1636 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1637 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1638 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1639 0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1640 0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1641 0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1642 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00,
1643};
1644
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
new file mode 100644
index 000000000000..c334526af66f
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -0,0 +1,21 @@
1config DVB_TTUSB_DEC
2 tristate "Technotrend/Hauppauge USB DEC devices"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 select CRC32
6 help
7 Support for external USB adapters designed by Technotrend and
8 produced by Hauppauge, shipped under the brand name 'DEC2000-t'
9 and 'DEC3000-s'.
10
11 Even if these devices have a MPEG decoder built in, they transmit
12 only compressed MPEG data over the USB bus, so you need
13 an external software decoder to watch TV on your computer.
14
15 This driver needs external firmware. Please use the commands
16 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
17 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
18 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
19 download/extract them, and then copy them to /usr/lib/hotplug/firmware.
20
21 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile
new file mode 100644
index 000000000000..b41bf1f06a9f
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
new file mode 100644
index 000000000000..64e771bd8907
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -0,0 +1,1744 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 * IR support by Peter Beutner <p.beutner@gmx.net>
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 <asm/semaphore.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/spinlock.h>
30#include <linux/usb.h>
31#include <linux/version.h>
32#include <linux/interrupt.h>
33#include <linux/firmware.h>
34#include <linux/crc32.h>
35#include <linux/init.h>
36#include <linux/input.h>
37
38#include "dmxdev.h"
39#include "dvb_demux.h"
40#include "dvb_filter.h"
41#include "dvb_frontend.h"
42#include "dvb_net.h"
43#include "ttusbdecfe.h"
44
45static int debug;
46static int output_pva;
47static int enable_rc;
48
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
51module_param(output_pva, int, 0444);
52MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
53module_param(enable_rc, int, 0644);
54MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
55
56#define dprintk if (debug) printk
57
58#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
59
60#define COMMAND_PIPE 0x03
61#define RESULT_PIPE 0x04
62#define IN_PIPE 0x08
63#define OUT_PIPE 0x07
64#define IRQ_PIPE 0x0A
65
66#define COMMAND_PACKET_SIZE 0x3c
67#define ARM_PACKET_SIZE 0x1000
68#define IRQ_PACKET_SIZE 0x8
69
70#define ISO_BUF_COUNT 0x04
71#define FRAMES_PER_ISO_BUF 0x04
72#define ISO_FRAME_SIZE 0x0380
73
74#define MAX_PVA_LENGTH 6144
75
76enum ttusb_dec_model {
77 TTUSB_DEC2000T,
78 TTUSB_DEC2540T,
79 TTUSB_DEC3000S
80};
81
82enum ttusb_dec_packet_type {
83 TTUSB_DEC_PACKET_PVA,
84 TTUSB_DEC_PACKET_SECTION,
85 TTUSB_DEC_PACKET_EMPTY
86};
87
88enum ttusb_dec_interface {
89 TTUSB_DEC_INTERFACE_INITIAL,
90 TTUSB_DEC_INTERFACE_IN,
91 TTUSB_DEC_INTERFACE_OUT
92};
93
94struct ttusb_dec {
95 enum ttusb_dec_model model;
96 char *model_name;
97 char *firmware_name;
98 int can_playback;
99
100 /* DVB bits */
101 struct dvb_adapter *adapter;
102 struct dmxdev dmxdev;
103 struct dvb_demux demux;
104 struct dmx_frontend frontend;
105 struct dvb_net dvb_net;
106 struct dvb_frontend* fe;
107
108 u16 pid[DMX_PES_OTHER];
109
110 /* USB bits */
111 struct usb_device *udev;
112 u8 trans_count;
113 unsigned int command_pipe;
114 unsigned int result_pipe;
115 unsigned int in_pipe;
116 unsigned int out_pipe;
117 unsigned int irq_pipe;
118 enum ttusb_dec_interface interface;
119 struct semaphore usb_sem;
120
121 void *irq_buffer;
122 struct urb *irq_urb;
123 dma_addr_t irq_dma_handle;
124 void *iso_buffer;
125 dma_addr_t iso_dma_handle;
126 struct urb *iso_urb[ISO_BUF_COUNT];
127 int iso_stream_count;
128 struct semaphore iso_sem;
129
130 u8 packet[MAX_PVA_LENGTH + 4];
131 enum ttusb_dec_packet_type packet_type;
132 int packet_state;
133 int packet_length;
134 int packet_payload_length;
135 u16 next_packet_id;
136
137 int pva_stream_count;
138 int filter_stream_count;
139
140 struct dvb_filter_pes2ts a_pes2ts;
141 struct dvb_filter_pes2ts v_pes2ts;
142
143 u8 v_pes[16 + MAX_PVA_LENGTH];
144 int v_pes_length;
145 int v_pes_postbytes;
146
147 struct list_head urb_frame_list;
148 struct tasklet_struct urb_tasklet;
149 spinlock_t urb_frame_list_lock;
150
151 struct dvb_demux_filter *audio_filter;
152 struct dvb_demux_filter *video_filter;
153 struct list_head filter_info_list;
154 spinlock_t filter_info_list_lock;
155
156 struct input_dev rc_input_dev;
157
158 int active; /* Loaded successfully */
159};
160
161struct urb_frame {
162 u8 data[ISO_FRAME_SIZE];
163 int length;
164 struct list_head urb_frame_list;
165};
166
167struct filter_info {
168 u8 stream_id;
169 struct dvb_demux_filter *filter;
170 struct list_head filter_info_list;
171};
172
173static u16 rc_keys[] = {
174 KEY_POWER,
175 KEY_MUTE,
176 KEY_1,
177 KEY_2,
178 KEY_3,
179 KEY_4,
180 KEY_5,
181 KEY_6,
182 KEY_7,
183 KEY_8,
184 KEY_9,
185 KEY_0,
186 KEY_CHANNELUP,
187 KEY_VOLUMEDOWN,
188 KEY_OK,
189 KEY_VOLUMEUP,
190 KEY_CHANNELDOWN,
191 KEY_PREVIOUS,
192 KEY_ESC,
193 KEY_RED,
194 KEY_GREEN,
195 KEY_YELLOW,
196 KEY_BLUE,
197 KEY_OPTION,
198 KEY_M,
199 KEY_RADIO
200};
201
202static void ttusb_dec_set_model(struct ttusb_dec *dec,
203 enum ttusb_dec_model model);
204
205static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
206{
207 struct ttusb_dec * dec = urb->context;
208 char *buffer = dec->irq_buffer;
209 int retval;
210
211 switch(urb->status) {
212 case 0: /*success*/
213 break;
214 case -ECONNRESET:
215 case -ENOENT:
216 case -ESHUTDOWN:
217 case -ETIMEDOUT:
218 /* this urb is dead, cleanup */
219 dprintk("%s:urb shutting down with status: %d\n",
220 __FUNCTION__, urb->status);
221 return;
222 default:
223 dprintk("%s:nonzero status received: %d\n",
224 __FUNCTION__,urb->status);
225 goto exit;
226 }
227
228 if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) {
229 /* IR - Event */
230 /* this is an fact a bit too simple implementation;
231 * the box also reports a keyrepeat signal
232 * (with buffer[3] == 0x40) in an intervall of ~100ms.
233 * But to handle this correctly we had to imlemenent some
234 * kind of timer which signals a 'key up' event if no
235 * keyrepeat signal is recieved for lets say 200ms.
236 * this should/could be added later ...
237 * for now lets report each signal as a key down and up*/
238 dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
239 input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
240 input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
241 input_sync(&dec->rc_input_dev);
242 }
243
244exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
245 if(retval)
246 printk("%s - usb_commit_urb failed with result: %d\n",
247 __FUNCTION__, retval);
248}
249
250static u16 crc16(u16 crc, const u8 *buf, size_t len)
251{
252 u16 tmp;
253
254 while (len--) {
255 crc ^= *buf++;
256 crc ^= (u8)crc >> 4;
257 tmp = (u8)crc;
258 crc ^= (tmp ^ (tmp << 1)) << 4;
259 }
260 return crc;
261}
262
263static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
264 int param_length, const u8 params[],
265 int *result_length, u8 cmd_result[])
266{
267 int result, actual_len, i;
268 u8 *b;
269
270 dprintk("%s\n", __FUNCTION__);
271
272 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
273 if (!b)
274 return -ENOMEM;
275
276 if ((result = down_interruptible(&dec->usb_sem))) {
277 kfree(b);
278 printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
279 return result;
280 }
281
282 b[0] = 0xaa;
283 b[1] = ++dec->trans_count;
284 b[2] = command;
285 b[3] = param_length;
286
287 if (params)
288 memcpy(&b[4], params, param_length);
289
290 if (debug) {
291 printk("%s: command: ", __FUNCTION__);
292 for (i = 0; i < param_length + 4; i++)
293 printk("0x%02X ", b[i]);
294 printk("\n");
295 }
296
297 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
298 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
299
300 if (result) {
301 printk("%s: command bulk message failed: error %d\n",
302 __FUNCTION__, result);
303 up(&dec->usb_sem);
304 kfree(b);
305 return result;
306 }
307
308 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
309 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
310
311 if (result) {
312 printk("%s: result bulk message failed: error %d\n",
313 __FUNCTION__, result);
314 up(&dec->usb_sem);
315 kfree(b);
316 return result;
317 } else {
318 if (debug) {
319 printk("%s: result: ", __FUNCTION__);
320 for (i = 0; i < actual_len; i++)
321 printk("0x%02X ", b[i]);
322 printk("\n");
323 }
324
325 if (result_length)
326 *result_length = b[3];
327 if (cmd_result && b[3] > 0)
328 memcpy(cmd_result, &b[4], b[3]);
329
330 up(&dec->usb_sem);
331
332 kfree(b);
333 return 0;
334 }
335}
336
337static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
338 unsigned int *model, unsigned int *version)
339{
340 u8 c[COMMAND_PACKET_SIZE];
341 int c_length;
342 int result;
343 unsigned int tmp;
344
345 dprintk("%s\n", __FUNCTION__);
346
347 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
348 if (result)
349 return result;
350
351 if (c_length >= 0x0c) {
352 if (mode != NULL) {
353 memcpy(&tmp, c, 4);
354 *mode = ntohl(tmp);
355 }
356 if (model != NULL) {
357 memcpy(&tmp, &c[4], 4);
358 *model = ntohl(tmp);
359 }
360 if (version != NULL) {
361 memcpy(&tmp, &c[8], 4);
362 *version = ntohl(tmp);
363 }
364 return 0;
365 } else {
366 return -1;
367 }
368}
369
370static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
371{
372 struct ttusb_dec *dec = (struct ttusb_dec *)priv;
373
374 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
375 &dec->audio_filter->feed->feed.ts,
376 DMX_OK);
377
378 return 0;
379}
380
381static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
382{
383 struct ttusb_dec *dec = (struct ttusb_dec *)priv;
384
385 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
386 &dec->video_filter->feed->feed.ts,
387 DMX_OK);
388
389 return 0;
390}
391
392static void ttusb_dec_set_pids(struct ttusb_dec *dec)
393{
394 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0xff, 0xff,
396 0xff, 0xff, 0xff, 0xff };
397
398 u16 pcr = htons(dec->pid[DMX_PES_PCR]);
399 u16 audio = htons(dec->pid[DMX_PES_AUDIO]);
400 u16 video = htons(dec->pid[DMX_PES_VIDEO]);
401
402 dprintk("%s\n", __FUNCTION__);
403
404 memcpy(&b[0], &pcr, 2);
405 memcpy(&b[2], &audio, 2);
406 memcpy(&b[4], &video, 2);
407
408 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
409
410 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
411 ttusb_dec_audio_pes2ts_cb, dec);
412 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
413 ttusb_dec_video_pes2ts_cb, dec);
414 dec->v_pes_length = 0;
415 dec->v_pes_postbytes = 0;
416}
417
418static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
419{
420 if (length < 8) {
421 printk("%s: packet too short - discarding\n", __FUNCTION__);
422 return;
423 }
424
425 if (length > 8 + MAX_PVA_LENGTH) {
426 printk("%s: packet too long - discarding\n", __FUNCTION__);
427 return;
428 }
429
430 switch (pva[2]) {
431
432 case 0x01: { /* VideoStream */
433 int prebytes = pva[5] & 0x03;
434 int postbytes = (pva[5] & 0x0c) >> 2;
435 u16 v_pes_payload_length;
436
437 if (output_pva) {
438 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
439 &dec->video_filter->feed->feed.ts, DMX_OK);
440 return;
441 }
442
443 if (dec->v_pes_postbytes > 0 &&
444 dec->v_pes_postbytes == prebytes) {
445 memcpy(&dec->v_pes[dec->v_pes_length],
446 &pva[12], prebytes);
447
448 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
449 dec->v_pes_length + prebytes, 1);
450 }
451
452 if (pva[5] & 0x10) {
453 dec->v_pes[7] = 0x80;
454 dec->v_pes[8] = 0x05;
455
456 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
457 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
458 ((pva[9] & 0xc0) >> 6);
459 dec->v_pes[11] = 0x01 |
460 ((pva[9] & 0x3f) << 2) |
461 ((pva[10] & 0x80) >> 6);
462 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
463 ((pva[11] & 0xc0) >> 7);
464 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
465
466 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
467 length - 12 - prebytes);
468 dec->v_pes_length = 14 + length - 12 - prebytes;
469 } else {
470 dec->v_pes[7] = 0x00;
471 dec->v_pes[8] = 0x00;
472
473 memcpy(&dec->v_pes[9], &pva[8], length - 8);
474 dec->v_pes_length = 9 + length - 8;
475 }
476
477 dec->v_pes_postbytes = postbytes;
478
479 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
480 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
481 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
482 dec->v_pes[6] = 0x84;
483 else
484 dec->v_pes[6] = 0x80;
485
486 v_pes_payload_length = htons(dec->v_pes_length - 6 +
487 postbytes);
488 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
489
490 if (postbytes == 0)
491 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
492 dec->v_pes_length, 1);
493
494 break;
495 }
496
497 case 0x02: /* MainAudioStream */
498 if (output_pva) {
499 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
500 &dec->audio_filter->feed->feed.ts, DMX_OK);
501 return;
502 }
503
504 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
505 pva[5] & 0x10);
506 break;
507
508 default:
509 printk("%s: unknown PVA type: %02x.\n", __FUNCTION__,
510 pva[2]);
511 break;
512 }
513}
514
515static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
516 int length)
517{
518 struct list_head *item;
519 struct filter_info *finfo;
520 struct dvb_demux_filter *filter = NULL;
521 unsigned long flags;
522 u8 sid;
523
524 sid = packet[1];
525 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
526 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
527 item = item->next) {
528 finfo = list_entry(item, struct filter_info, filter_info_list);
529 if (finfo->stream_id == sid) {
530 filter = finfo->filter;
531 break;
532 }
533 }
534 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
535
536 if (filter)
537 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
538 &filter->filter, DMX_OK);
539}
540
541static void ttusb_dec_process_packet(struct ttusb_dec *dec)
542{
543 int i;
544 u16 csum = 0;
545 u16 packet_id;
546
547 if (dec->packet_length % 2) {
548 printk("%s: odd sized packet - discarding\n", __FUNCTION__);
549 return;
550 }
551
552 for (i = 0; i < dec->packet_length; i += 2)
553 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
554
555 if (csum) {
556 printk("%s: checksum failed - discarding\n", __FUNCTION__);
557 return;
558 }
559
560 packet_id = dec->packet[dec->packet_length - 4] << 8;
561 packet_id += dec->packet[dec->packet_length - 3];
562
563 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
564 printk("%s: warning: lost packets between %u and %u\n",
565 __FUNCTION__, dec->next_packet_id - 1, packet_id);
566 }
567
568 if (packet_id == 0xffff)
569 dec->next_packet_id = 0x8000;
570 else
571 dec->next_packet_id = packet_id + 1;
572
573 switch (dec->packet_type) {
574 case TTUSB_DEC_PACKET_PVA:
575 if (dec->pva_stream_count)
576 ttusb_dec_process_pva(dec, dec->packet,
577 dec->packet_payload_length);
578 break;
579
580 case TTUSB_DEC_PACKET_SECTION:
581 if (dec->filter_stream_count)
582 ttusb_dec_process_filter(dec, dec->packet,
583 dec->packet_payload_length);
584 break;
585
586 case TTUSB_DEC_PACKET_EMPTY:
587 break;
588 }
589}
590
591static void swap_bytes(u8 *b, int length)
592{
593 u8 c;
594
595 length -= length % 2;
596 for (; length; b += 2, length -= 2) {
597 c = *b;
598 *b = *(b + 1);
599 *(b + 1) = c;
600 }
601}
602
603static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
604 int length)
605{
606 swap_bytes(b, length);
607
608 while (length) {
609 switch (dec->packet_state) {
610
611 case 0:
612 case 1:
613 case 2:
614 if (*b++ == 0xaa)
615 dec->packet_state++;
616 else
617 dec->packet_state = 0;
618
619 length--;
620 break;
621
622 case 3:
623 if (*b == 0x00) {
624 dec->packet_state++;
625 dec->packet_length = 0;
626 } else if (*b != 0xaa) {
627 dec->packet_state = 0;
628 }
629
630 b++;
631 length--;
632 break;
633
634 case 4:
635 dec->packet[dec->packet_length++] = *b++;
636
637 if (dec->packet_length == 2) {
638 if (dec->packet[0] == 'A' &&
639 dec->packet[1] == 'V') {
640 dec->packet_type =
641 TTUSB_DEC_PACKET_PVA;
642 dec->packet_state++;
643 } else if (dec->packet[0] == 'S') {
644 dec->packet_type =
645 TTUSB_DEC_PACKET_SECTION;
646 dec->packet_state++;
647 } else if (dec->packet[0] == 0x00) {
648 dec->packet_type =
649 TTUSB_DEC_PACKET_EMPTY;
650 dec->packet_payload_length = 2;
651 dec->packet_state = 7;
652 } else {
653 printk("%s: unknown packet type: "
654 "%02x%02x\n", __FUNCTION__,
655 dec->packet[0], dec->packet[1]);
656 dec->packet_state = 0;
657 }
658 }
659
660 length--;
661 break;
662
663 case 5:
664 dec->packet[dec->packet_length++] = *b++;
665
666 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
667 dec->packet_length == 8) {
668 dec->packet_state++;
669 dec->packet_payload_length = 8 +
670 (dec->packet[6] << 8) +
671 dec->packet[7];
672 } else if (dec->packet_type ==
673 TTUSB_DEC_PACKET_SECTION &&
674 dec->packet_length == 5) {
675 dec->packet_state++;
676 dec->packet_payload_length = 5 +
677 ((dec->packet[3] & 0x0f) << 8) +
678 dec->packet[4];
679 }
680
681 length--;
682 break;
683
684 case 6: {
685 int remainder = dec->packet_payload_length -
686 dec->packet_length;
687
688 if (length >= remainder) {
689 memcpy(dec->packet + dec->packet_length,
690 b, remainder);
691 dec->packet_length += remainder;
692 b += remainder;
693 length -= remainder;
694 dec->packet_state++;
695 } else {
696 memcpy(&dec->packet[dec->packet_length],
697 b, length);
698 dec->packet_length += length;
699 length = 0;
700 }
701
702 break;
703 }
704
705 case 7: {
706 int tail = 4;
707
708 dec->packet[dec->packet_length++] = *b++;
709
710 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
711 dec->packet_payload_length % 2)
712 tail++;
713
714 if (dec->packet_length ==
715 dec->packet_payload_length + tail) {
716 ttusb_dec_process_packet(dec);
717 dec->packet_state = 0;
718 }
719
720 length--;
721 break;
722 }
723
724 default:
725 printk("%s: illegal packet state encountered.\n",
726 __FUNCTION__);
727 dec->packet_state = 0;
728 }
729 }
730}
731
732static void ttusb_dec_process_urb_frame_list(unsigned long data)
733{
734 struct ttusb_dec *dec = (struct ttusb_dec *)data;
735 struct list_head *item;
736 struct urb_frame *frame;
737 unsigned long flags;
738
739 while (1) {
740 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
741 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
742 frame = list_entry(item, struct urb_frame,
743 urb_frame_list);
744 list_del(&frame->urb_frame_list);
745 } else {
746 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
747 flags);
748 return;
749 }
750 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
751
752 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
753 kfree(frame);
754 }
755}
756
757static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs)
758{
759 struct ttusb_dec *dec = urb->context;
760
761 if (!urb->status) {
762 int i;
763
764 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
765 struct usb_iso_packet_descriptor *d;
766 u8 *b;
767 int length;
768 struct urb_frame *frame;
769
770 d = &urb->iso_frame_desc[i];
771 b = urb->transfer_buffer + d->offset;
772 length = d->actual_length;
773
774 if ((frame = kmalloc(sizeof(struct urb_frame),
775 GFP_ATOMIC))) {
776 unsigned long flags;
777
778 memcpy(frame->data, b, length);
779 frame->length = length;
780
781 spin_lock_irqsave(&dec->urb_frame_list_lock,
782 flags);
783 list_add_tail(&frame->urb_frame_list,
784 &dec->urb_frame_list);
785 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
786 flags);
787
788 tasklet_schedule(&dec->urb_tasklet);
789 }
790 }
791 } else {
792 /* -ENOENT is expected when unlinking urbs */
793 if (urb->status != -ENOENT)
794 dprintk("%s: urb error: %d\n", __FUNCTION__,
795 urb->status);
796 }
797
798 if (dec->iso_stream_count)
799 usb_submit_urb(urb, GFP_ATOMIC);
800}
801
802static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
803{
804 int i, j, buffer_offset = 0;
805
806 dprintk("%s\n", __FUNCTION__);
807
808 for (i = 0; i < ISO_BUF_COUNT; i++) {
809 int frame_offset = 0;
810 struct urb *urb = dec->iso_urb[i];
811
812 urb->dev = dec->udev;
813 urb->context = dec;
814 urb->complete = ttusb_dec_process_urb;
815 urb->pipe = dec->in_pipe;
816 urb->transfer_flags = URB_ISO_ASAP;
817 urb->interval = 1;
818 urb->number_of_packets = FRAMES_PER_ISO_BUF;
819 urb->transfer_buffer_length = ISO_FRAME_SIZE *
820 FRAMES_PER_ISO_BUF;
821 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
822 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
823
824 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
825 urb->iso_frame_desc[j].offset = frame_offset;
826 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
827 frame_offset += ISO_FRAME_SIZE;
828 }
829 }
830}
831
832static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
833{
834 int i;
835
836 dprintk("%s\n", __FUNCTION__);
837
838 if (down_interruptible(&dec->iso_sem))
839 return;
840
841 dec->iso_stream_count--;
842
843 if (!dec->iso_stream_count) {
844 for (i = 0; i < ISO_BUF_COUNT; i++)
845 usb_kill_urb(dec->iso_urb[i]);
846 }
847
848 up(&dec->iso_sem);
849}
850
851/* Setting the interface of the DEC tends to take down the USB communications
852 * for a short period, so it's important not to call this function just before
853 * trying to talk to it.
854 */
855static int ttusb_dec_set_interface(struct ttusb_dec *dec,
856 enum ttusb_dec_interface interface)
857{
858 int result = 0;
859 u8 b[] = { 0x05 };
860
861 if (interface != dec->interface) {
862 switch (interface) {
863 case TTUSB_DEC_INTERFACE_INITIAL:
864 result = usb_set_interface(dec->udev, 0, 0);
865 break;
866 case TTUSB_DEC_INTERFACE_IN:
867 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
868 b, NULL, NULL);
869 if (result)
870 return result;
871 result = usb_set_interface(dec->udev, 0, 8);
872 break;
873 case TTUSB_DEC_INTERFACE_OUT:
874 result = usb_set_interface(dec->udev, 0, 1);
875 break;
876 }
877
878 if (result)
879 return result;
880
881 dec->interface = interface;
882 }
883
884 return 0;
885}
886
887static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
888{
889 int i, result;
890
891 dprintk("%s\n", __FUNCTION__);
892
893 if (down_interruptible(&dec->iso_sem))
894 return -EAGAIN;
895
896 if (!dec->iso_stream_count) {
897 ttusb_dec_setup_urbs(dec);
898
899 dec->packet_state = 0;
900 dec->v_pes_postbytes = 0;
901 dec->next_packet_id = 0;
902
903 for (i = 0; i < ISO_BUF_COUNT; i++) {
904 if ((result = usb_submit_urb(dec->iso_urb[i],
905 GFP_ATOMIC))) {
906 printk("%s: failed urb submission %d: "
907 "error %d\n", __FUNCTION__, i, result);
908
909 while (i) {
910 usb_kill_urb(dec->iso_urb[i - 1]);
911 i--;
912 }
913
914 up(&dec->iso_sem);
915 return result;
916 }
917 }
918 }
919
920 dec->iso_stream_count++;
921
922 up(&dec->iso_sem);
923
924 return 0;
925}
926
927static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
928{
929 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
930 struct ttusb_dec *dec = dvbdmx->priv;
931 u8 b0[] = { 0x05 };
932 int result = 0;
933
934 dprintk("%s\n", __FUNCTION__);
935
936 dprintk(" ts_type:");
937
938 if (dvbdmxfeed->ts_type & TS_DECODER)
939 dprintk(" TS_DECODER");
940
941 if (dvbdmxfeed->ts_type & TS_PACKET)
942 dprintk(" TS_PACKET");
943
944 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
945 dprintk(" TS_PAYLOAD_ONLY");
946
947 dprintk("\n");
948
949 switch (dvbdmxfeed->pes_type) {
950
951 case DMX_TS_PES_VIDEO:
952 dprintk(" pes_type: DMX_TS_PES_VIDEO\n");
953 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
954 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
955 dec->video_filter = dvbdmxfeed->filter;
956 ttusb_dec_set_pids(dec);
957 break;
958
959 case DMX_TS_PES_AUDIO:
960 dprintk(" pes_type: DMX_TS_PES_AUDIO\n");
961 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
962 dec->audio_filter = dvbdmxfeed->filter;
963 ttusb_dec_set_pids(dec);
964 break;
965
966 case DMX_TS_PES_TELETEXT:
967 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
968 dprintk(" pes_type: DMX_TS_PES_TELETEXT\n");
969 break;
970
971 case DMX_TS_PES_PCR:
972 dprintk(" pes_type: DMX_TS_PES_PCR\n");
973 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
974 ttusb_dec_set_pids(dec);
975 break;
976
977 case DMX_TS_PES_OTHER:
978 dprintk(" pes_type: DMX_TS_PES_OTHER\n");
979 break;
980
981 default:
982 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
983 return -EINVAL;
984
985 }
986
987 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
988 if (result)
989 return result;
990
991 dec->pva_stream_count++;
992 return ttusb_dec_start_iso_xfer(dec);
993}
994
995static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
996{
997 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
998 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
999 0x00, 0x00, 0x00, 0x00,
1000 0x00, 0x00, 0x00, 0x00,
1001 0x00, 0x00, 0x00, 0x00,
1002 0x00, 0xff, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00,
1005 0x00 };
1006 u16 pid;
1007 u8 c[COMMAND_PACKET_SIZE];
1008 int c_length;
1009 int result;
1010 struct filter_info *finfo;
1011 unsigned long flags;
1012 u8 x = 1;
1013
1014 dprintk("%s\n", __FUNCTION__);
1015
1016 pid = htons(dvbdmxfeed->pid);
1017 memcpy(&b0[0], &pid, 2);
1018 memcpy(&b0[4], &x, 1);
1019 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1020
1021 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1022 &c_length, c);
1023
1024 if (!result) {
1025 if (c_length == 2) {
1026 if (!(finfo = kmalloc(sizeof(struct filter_info),
1027 GFP_ATOMIC)))
1028 return -ENOMEM;
1029
1030 finfo->stream_id = c[1];
1031 finfo->filter = dvbdmxfeed->filter;
1032
1033 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1034 list_add_tail(&finfo->filter_info_list,
1035 &dec->filter_info_list);
1036 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1037 flags);
1038
1039 dvbdmxfeed->priv = finfo;
1040
1041 dec->filter_stream_count++;
1042 return ttusb_dec_start_iso_xfer(dec);
1043 }
1044
1045 return -EAGAIN;
1046 } else
1047 return result;
1048}
1049
1050static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1051{
1052 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1053
1054 dprintk("%s\n", __FUNCTION__);
1055
1056 if (!dvbdmx->dmx.frontend)
1057 return -EINVAL;
1058
1059 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1060
1061 switch (dvbdmxfeed->type) {
1062
1063 case DMX_TYPE_TS:
1064 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1065 break;
1066
1067 case DMX_TYPE_SEC:
1068 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1069 break;
1070
1071 default:
1072 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1073 return -EINVAL;
1074
1075 }
1076}
1077
1078static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1079{
1080 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1081 u8 b0[] = { 0x00 };
1082
1083 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1084
1085 dec->pva_stream_count--;
1086
1087 ttusb_dec_stop_iso_xfer(dec);
1088
1089 return 0;
1090}
1091
1092static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1093{
1094 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1095 u8 b0[] = { 0x00, 0x00 };
1096 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1097 unsigned long flags;
1098
1099 b0[1] = finfo->stream_id;
1100 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1101 list_del(&finfo->filter_info_list);
1102 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1103 kfree(finfo);
1104 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1105
1106 dec->filter_stream_count--;
1107
1108 ttusb_dec_stop_iso_xfer(dec);
1109
1110 return 0;
1111}
1112
1113static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1114{
1115 dprintk("%s\n", __FUNCTION__);
1116
1117 switch (dvbdmxfeed->type) {
1118 case DMX_TYPE_TS:
1119 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1120 break;
1121
1122 case DMX_TYPE_SEC:
1123 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1124 break;
1125 }
1126
1127 return 0;
1128}
1129
1130static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1131{
1132 int i;
1133
1134 dprintk("%s\n", __FUNCTION__);
1135
1136 for (i = 0; i < ISO_BUF_COUNT; i++)
1137 if (dec->iso_urb[i])
1138 usb_free_urb(dec->iso_urb[i]);
1139
1140 pci_free_consistent(NULL,
1141 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
1142 ISO_BUF_COUNT),
1143 dec->iso_buffer, dec->iso_dma_handle);
1144}
1145
1146static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1147{
1148 int i;
1149
1150 dprintk("%s\n", __FUNCTION__);
1151
1152 dec->iso_buffer = pci_alloc_consistent(NULL,
1153 ISO_FRAME_SIZE *
1154 (FRAMES_PER_ISO_BUF *
1155 ISO_BUF_COUNT),
1156 &dec->iso_dma_handle);
1157
1158 memset(dec->iso_buffer, 0,
1159 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
1160
1161 for (i = 0; i < ISO_BUF_COUNT; i++) {
1162 struct urb *urb;
1163
1164 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1165 ttusb_dec_free_iso_urbs(dec);
1166 return -ENOMEM;
1167 }
1168
1169 dec->iso_urb[i] = urb;
1170 }
1171
1172 ttusb_dec_setup_urbs(dec);
1173
1174 return 0;
1175}
1176
1177static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1178{
1179 spin_lock_init(&dec->urb_frame_list_lock);
1180 INIT_LIST_HEAD(&dec->urb_frame_list);
1181 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1182 (unsigned long)dec);
1183}
1184
1185static void ttusb_init_rc( struct ttusb_dec *dec)
1186{
1187 u8 b[] = { 0x00, 0x01 };
1188 int i;
1189
1190 init_input_dev(&dec->rc_input_dev);
1191
1192 dec->rc_input_dev.name = "ttusb_dec remote control";
1193 dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
1194 dec->rc_input_dev.keycodesize = sizeof(u16);
1195 dec->rc_input_dev.keycodemax = 0x1a;
1196 dec->rc_input_dev.keycode = rc_keys;
1197
1198 for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
1199 set_bit(rc_keys[i], dec->rc_input_dev.keybit);
1200
1201 input_register_device(&dec->rc_input_dev);
1202
1203 if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
1204 printk("%s: usb_submit_urb failed\n",__FUNCTION__);
1205 }
1206 /* enable irq pipe */
1207 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
1208}
1209
1210static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1211{
1212 dprintk("%s\n", __FUNCTION__);
1213
1214 dec->v_pes[0] = 0x00;
1215 dec->v_pes[1] = 0x00;
1216 dec->v_pes[2] = 0x01;
1217 dec->v_pes[3] = 0xe0;
1218}
1219
1220static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1221{
1222 dprintk("%s\n", __FUNCTION__);
1223
1224 sema_init(&dec->usb_sem, 1);
1225 sema_init(&dec->iso_sem, 1);
1226
1227 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1228 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1229 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1230 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1231 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1232
1233 if(enable_rc) {
1234 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1235 if(!dec->irq_urb) {
1236 return -ENOMEM;
1237 }
1238 dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
1239 SLAB_ATOMIC, &dec->irq_dma_handle);
1240 if(!dec->irq_buffer) {
1241 return -ENOMEM;
1242 }
1243 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1244 dec->irq_buffer, IRQ_PACKET_SIZE,
1245 ttusb_dec_handle_irq, dec, 1);
1246 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1247 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1248 }
1249
1250 return ttusb_dec_alloc_iso_urbs(dec);
1251}
1252
1253static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1254{
1255 int i, j, actual_len, result, size, trans_count;
1256 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00,
1258 0x61, 0x00 };
1259 u8 b1[] = { 0x61 };
1260 u8 *b;
1261 char idstring[21];
1262 u8 *firmware = NULL;
1263 size_t firmware_size = 0;
1264 u16 firmware_csum = 0;
1265 u16 firmware_csum_ns;
1266 u32 firmware_size_nl;
1267 u32 crc32_csum, crc32_check, tmp;
1268 const struct firmware *fw_entry = NULL;
1269
1270 dprintk("%s\n", __FUNCTION__);
1271
1272 if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
1273 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
1274 __FUNCTION__, dec->firmware_name);
1275 return 1;
1276 }
1277
1278 firmware = fw_entry->data;
1279 firmware_size = fw_entry->size;
1280
1281 if (firmware_size < 60) {
1282 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
1283 __FUNCTION__, firmware_size);
1284 return -1;
1285 }
1286
1287 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1288 at offset 56 of file, so use it to check if the firmware file is
1289 valid. */
1290 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1291 memcpy(&tmp, &firmware[56], 4);
1292 crc32_check = htonl(tmp);
1293 if (crc32_csum != crc32_check) {
1294 printk("%s: crc32 check of DSP code failed (calculated "
1295 "0x%08x != 0x%08x in file), file invalid.\n",
1296 __FUNCTION__, crc32_csum, crc32_check);
1297 return -1;
1298 }
1299 memcpy(idstring, &firmware[36], 20);
1300 idstring[20] = '\0';
1301 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1302
1303 firmware_size_nl = htonl(firmware_size);
1304 memcpy(b0, &firmware_size_nl, 4);
1305 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1306 firmware_csum_ns = htons(firmware_csum);
1307 memcpy(&b0[6], &firmware_csum_ns, 2);
1308
1309 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1310
1311 if (result)
1312 return result;
1313
1314 trans_count = 0;
1315 j = 0;
1316
1317 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
1318 if (b == NULL)
1319 return -ENOMEM;
1320
1321 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1322 size = firmware_size - i;
1323 if (size > COMMAND_PACKET_SIZE)
1324 size = COMMAND_PACKET_SIZE;
1325
1326 b[j + 0] = 0xaa;
1327 b[j + 1] = trans_count++;
1328 b[j + 2] = 0xf0;
1329 b[j + 3] = size;
1330 memcpy(&b[j + 4], &firmware[i], size);
1331
1332 j += COMMAND_PACKET_SIZE + 4;
1333
1334 if (j >= ARM_PACKET_SIZE) {
1335 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1336 ARM_PACKET_SIZE, &actual_len,
1337 100);
1338 j = 0;
1339 } else if (size < COMMAND_PACKET_SIZE) {
1340 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1341 j - COMMAND_PACKET_SIZE + size,
1342 &actual_len, 100);
1343 }
1344 }
1345
1346 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1347
1348 kfree(b);
1349
1350 return result;
1351}
1352
1353static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1354{
1355 int result;
1356 unsigned int mode, model, version;
1357
1358 dprintk("%s\n", __FUNCTION__);
1359
1360 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
1361
1362 if (!result) {
1363 if (!mode) {
1364 if (version == 0xABCDEFAB)
1365 printk(KERN_INFO "ttusb_dec: no version "
1366 "info in Firmware\n");
1367 else
1368 printk(KERN_INFO "ttusb_dec: Firmware "
1369 "%x.%02x%c%c\n",
1370 version >> 24, (version >> 16) & 0xff,
1371 (version >> 8) & 0xff, version & 0xff);
1372
1373 result = ttusb_dec_boot_dsp(dec);
1374 if (result)
1375 return result;
1376 else
1377 return 1;
1378 } else {
1379 /* We can't trust the USB IDs that some firmwares
1380 give the box */
1381 switch (model) {
1382 case 0x00070008:
1383 case 0x0007000c:
1384 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1385 break;
1386 case 0x00070009:
1387 case 0x00070013:
1388 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1389 break;
1390 case 0x00070011:
1391 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1392 break;
1393 default:
1394 printk(KERN_ERR "%s: unknown model returned "
1395 "by firmware (%08x) - please report\n",
1396 __FUNCTION__, model);
1397 return -1;
1398 break;
1399 }
1400
1401 if (version >= 0x01770000)
1402 dec->can_playback = 1;
1403
1404 return 0;
1405 }
1406 }
1407 else
1408 return result;
1409}
1410
1411static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1412{
1413 int result;
1414
1415 dprintk("%s\n", __FUNCTION__);
1416
1417 if ((result = dvb_register_adapter(&dec->adapter,
1418 dec->model_name, THIS_MODULE)) < 0) {
1419 printk("%s: dvb_register_adapter failed: error %d\n",
1420 __FUNCTION__, result);
1421
1422 return result;
1423 }
1424
1425 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1426
1427 dec->demux.priv = (void *)dec;
1428 dec->demux.filternum = 31;
1429 dec->demux.feednum = 31;
1430 dec->demux.start_feed = ttusb_dec_start_feed;
1431 dec->demux.stop_feed = ttusb_dec_stop_feed;
1432 dec->demux.write_to_decoder = NULL;
1433
1434 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
1435 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1436 result);
1437
1438 dvb_unregister_adapter(dec->adapter);
1439
1440 return result;
1441 }
1442
1443 dec->dmxdev.filternum = 32;
1444 dec->dmxdev.demux = &dec->demux.dmx;
1445 dec->dmxdev.capabilities = 0;
1446
1447 if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) {
1448 printk("%s: dvb_dmxdev_init failed: error %d\n",
1449 __FUNCTION__, result);
1450
1451 dvb_dmx_release(&dec->demux);
1452 dvb_unregister_adapter(dec->adapter);
1453
1454 return result;
1455 }
1456
1457 dec->frontend.source = DMX_FRONTEND_0;
1458
1459 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1460 &dec->frontend)) < 0) {
1461 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1462 result);
1463
1464 dvb_dmxdev_release(&dec->dmxdev);
1465 dvb_dmx_release(&dec->demux);
1466 dvb_unregister_adapter(dec->adapter);
1467
1468 return result;
1469 }
1470
1471 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1472 &dec->frontend)) < 0) {
1473 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1474 result);
1475
1476 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1477 dvb_dmxdev_release(&dec->dmxdev);
1478 dvb_dmx_release(&dec->demux);
1479 dvb_unregister_adapter(dec->adapter);
1480
1481 return result;
1482 }
1483
1484 dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);
1485
1486 return 0;
1487}
1488
1489static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1490{
1491 dprintk("%s\n", __FUNCTION__);
1492
1493 dvb_net_release(&dec->dvb_net);
1494 dec->demux.dmx.close(&dec->demux.dmx);
1495 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1496 dvb_dmxdev_release(&dec->dmxdev);
1497 dvb_dmx_release(&dec->demux);
1498 if (dec->fe) dvb_unregister_frontend(dec->fe);
1499 dvb_unregister_adapter(dec->adapter);
1500}
1501
1502static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1503{
1504
1505 dprintk("%s\n", __FUNCTION__);
1506 /* we have to check whether the irq URB is already submitted.
1507 * As the irq is submitted after the interface is changed,
1508 * this is the best method i figured out.
1509 * Any others?*/
1510 if(dec->interface == TTUSB_DEC_INTERFACE_IN)
1511 usb_kill_urb(dec->irq_urb);
1512
1513 usb_free_urb(dec->irq_urb);
1514
1515 usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
1516 dec->irq_buffer, dec->irq_dma_handle);
1517
1518 input_unregister_device(&dec->rc_input_dev);
1519}
1520
1521
1522static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1523{
1524 int i;
1525
1526 dprintk("%s\n", __FUNCTION__);
1527
1528 dec->iso_stream_count = 0;
1529
1530 for (i = 0; i < ISO_BUF_COUNT; i++)
1531 usb_kill_urb(dec->iso_urb[i]);
1532
1533 ttusb_dec_free_iso_urbs(dec);
1534}
1535
1536static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1537{
1538 struct list_head *item;
1539 struct urb_frame *frame;
1540
1541 tasklet_kill(&dec->urb_tasklet);
1542
1543 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1544 frame = list_entry(item, struct urb_frame, urb_frame_list);
1545 list_del(&frame->urb_frame_list);
1546 kfree(frame);
1547 }
1548}
1549
1550static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1551{
1552 INIT_LIST_HEAD(&dec->filter_info_list);
1553 spin_lock_init(&dec->filter_info_list_lock);
1554}
1555
1556static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1557{
1558 struct list_head *item;
1559 struct filter_info *finfo;
1560
1561 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1562 finfo = list_entry(item, struct filter_info, filter_info_list);
1563 list_del(&finfo->filter_info_list);
1564 kfree(finfo);
1565 }
1566}
1567
1568int fe_send_command(struct dvb_frontend* fe, const u8 command,
1569 int param_length, const u8 params[],
1570 int *result_length, u8 cmd_result[])
1571{
1572 struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv;
1573 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1574}
1575
1576struct ttusbdecfe_config fe_config = {
1577 .send_command = fe_send_command
1578};
1579
1580static int ttusb_dec_probe(struct usb_interface *intf,
1581 const struct usb_device_id *id)
1582{
1583 struct usb_device *udev;
1584 struct ttusb_dec *dec;
1585
1586 dprintk("%s\n", __FUNCTION__);
1587
1588 udev = interface_to_usbdev(intf);
1589
1590 if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
1591 printk("%s: couldn't allocate memory.\n", __FUNCTION__);
1592 return -ENOMEM;
1593 }
1594
1595 usb_set_intfdata(intf, (void *)dec);
1596
1597 memset(dec, 0, sizeof(struct ttusb_dec));
1598
1599 switch (le16_to_cpu(id->idProduct)) {
1600 case 0x1006:
1601 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1602 break;
1603
1604 case 0x1008:
1605 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1606 break;
1607
1608 case 0x1009:
1609 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1610 break;
1611 }
1612
1613 dec->udev = udev;
1614
1615 if (ttusb_dec_init_usb(dec))
1616 return 0;
1617 if (ttusb_dec_init_stb(dec)) {
1618 ttusb_dec_exit_usb(dec);
1619 return 0;
1620 }
1621 ttusb_dec_init_dvb(dec);
1622
1623 dec->adapter->priv = dec;
1624 switch (le16_to_cpu(id->idProduct)) {
1625 case 0x1006:
1626 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1627 break;
1628
1629 case 0x1008:
1630 case 0x1009:
1631 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1632 break;
1633 }
1634
1635 if (dec->fe == NULL) {
1636 printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n",
1637 le16_to_cpu(dec->udev->descriptor.idVendor),
1638 le16_to_cpu(dec->udev->descriptor.idProduct));
1639 } else {
1640 if (dvb_register_frontend(dec->adapter, dec->fe)) {
1641 printk("budget-ci: Frontend registration failed!\n");
1642 if (dec->fe->ops->release)
1643 dec->fe->ops->release(dec->fe);
1644 dec->fe = NULL;
1645 }
1646 }
1647
1648 ttusb_dec_init_v_pes(dec);
1649 ttusb_dec_init_filters(dec);
1650 ttusb_dec_init_tasklet(dec);
1651
1652 dec->active = 1;
1653
1654 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1655
1656 if(enable_rc)
1657 ttusb_init_rc(dec);
1658
1659 return 0;
1660}
1661
1662static void ttusb_dec_disconnect(struct usb_interface *intf)
1663{
1664 struct ttusb_dec *dec = usb_get_intfdata(intf);
1665
1666 usb_set_intfdata(intf, NULL);
1667
1668 dprintk("%s\n", __FUNCTION__);
1669
1670 if (dec->active) {
1671 ttusb_dec_exit_tasklet(dec);
1672 ttusb_dec_exit_filters(dec);
1673 if(enable_rc)
1674 ttusb_dec_exit_rc(dec);
1675 ttusb_dec_exit_usb(dec);
1676 ttusb_dec_exit_dvb(dec);
1677 }
1678
1679 kfree(dec);
1680}
1681
1682static void ttusb_dec_set_model(struct ttusb_dec *dec,
1683 enum ttusb_dec_model model)
1684{
1685 dec->model = model;
1686
1687 switch (model) {
1688 case TTUSB_DEC2000T:
1689 dec->model_name = "DEC2000-t";
1690 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1691 break;
1692
1693 case TTUSB_DEC2540T:
1694 dec->model_name = "DEC2540-t";
1695 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1696 break;
1697
1698 case TTUSB_DEC3000S:
1699 dec->model_name = "DEC3000-s";
1700 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1701 break;
1702 }
1703}
1704
1705static struct usb_device_id ttusb_dec_table[] = {
1706 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1707 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1708 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1709 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1710 {}
1711};
1712
1713static struct usb_driver ttusb_dec_driver = {
1714 .name = "ttusb-dec",
1715 .probe = ttusb_dec_probe,
1716 .disconnect = ttusb_dec_disconnect,
1717 .id_table = ttusb_dec_table,
1718};
1719
1720static int __init ttusb_dec_init(void)
1721{
1722 int result;
1723
1724 if ((result = usb_register(&ttusb_dec_driver)) < 0) {
1725 printk("%s: initialisation failed: error %d.\n", __FUNCTION__,
1726 result);
1727 return result;
1728 }
1729
1730 return 0;
1731}
1732
1733static void __exit ttusb_dec_exit(void)
1734{
1735 usb_deregister(&ttusb_dec_driver);
1736}
1737
1738module_init(ttusb_dec_init);
1739module_exit(ttusb_dec_exit);
1740
1741MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1742MODULE_DESCRIPTION(DRIVER_NAME);
1743MODULE_LICENSE("GPL");
1744MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
new file mode 100644
index 000000000000..1699cc9f6bb0
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -0,0 +1,255 @@
1/*
2 * TTUSB DEC Frontend Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
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 */
21
22#include "dvb_frontend.h"
23#include "ttusbdecfe.h"
24
25
26#define LOF_HI 10600000
27#define LOF_LO 9750000
28
29struct ttusbdecfe_state {
30
31 struct dvb_frontend_ops ops;
32
33 /* configuration settings */
34 const struct ttusbdecfe_config* config;
35
36 struct dvb_frontend frontend;
37
38 u8 hi_band;
39 u8 voltage;
40};
41
42
43static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
44{
45 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
46 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
47
48 return 0;
49}
50
51static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
52{
53 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
54 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
55 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x01,
57 0x00, 0x00, 0x00, 0xff,
58 0x00, 0x00, 0x00, 0xff };
59
60 u32 freq = htonl(p->frequency / 1000);
61 memcpy(&b[4], &freq, sizeof (u32));
62 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
63
64 return 0;
65}
66
67static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
68{
69 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
70
71 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
72 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x01,
74 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00 };
81 u32 freq;
82 u32 sym_rate;
83 u32 band;
84 u32 lnb_voltage;
85
86 freq = htonl(p->frequency +
87 (state->hi_band ? LOF_HI : LOF_LO));
88 memcpy(&b[4], &freq, sizeof(u32));
89 sym_rate = htonl(p->u.qam.symbol_rate);
90 memcpy(&b[12], &sym_rate, sizeof(u32));
91 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
92 memcpy(&b[24], &band, sizeof(u32));
93 lnb_voltage = htonl(state->voltage);
94 memcpy(&b[28], &lnb_voltage, sizeof(u32));
95
96 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
97
98 return 0;
99}
100
101static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
102{
103 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
104 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00 };
107
108 memcpy(&b[4], cmd->msg, cmd->msg_len);
109
110 state->config->send_command(fe, 0x72,
111 sizeof(b) - (6 - cmd->msg_len), b,
112 NULL, NULL);
113
114 return 0;
115}
116
117
118static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
119{
120 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
121
122 state->hi_band = (SEC_TONE_ON == tone);
123
124 return 0;
125}
126
127
128static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
129{
130 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
131
132 switch (voltage) {
133 case SEC_VOLTAGE_13:
134 state->voltage = 13;
135 break;
136 case SEC_VOLTAGE_18:
137 state->voltage = 18;
138 break;
139 default:
140 return -EINVAL;
141 }
142
143 return 0;
144}
145
146static void ttusbdecfe_release(struct dvb_frontend* fe)
147{
148 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
149 kfree(state);
150}
151
152static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
153
154struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
155{
156 struct ttusbdecfe_state* state = NULL;
157
158 /* allocate memory for the internal state */
159 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
160 if (state == NULL) goto error;
161
162 /* setup the state */
163 state->config = config;
164 memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
165
166 /* create dvb_frontend */
167 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state;
169 return &state->frontend;
170
171error:
172 kfree(state);
173 return NULL;
174}
175
176static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
177
178struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
179{
180 struct ttusbdecfe_state* state = NULL;
181
182 /* allocate memory for the internal state */
183 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
184 if (state == NULL) goto error;
185
186 /* setup the state */
187 state->config = config;
188 state->voltage = 0;
189 state->hi_band = 0;
190 memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
191
192 /* create dvb_frontend */
193 state->frontend.ops = &state->ops;
194 state->frontend.demodulator_priv = state;
195 return &state->frontend;
196
197error:
198 kfree(state);
199 return NULL;
200}
201
202static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
203
204 .info = {
205 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
206 .type = FE_OFDM,
207 .frequency_min = 51000000,
208 .frequency_max = 858000000,
209 .frequency_stepsize = 62500,
210 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
211 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
212 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
213 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
214 FE_CAN_HIERARCHY_AUTO,
215 },
216
217 .release = ttusbdecfe_release,
218
219 .set_frontend = ttusbdecfe_dvbt_set_frontend,
220
221 .read_status = ttusbdecfe_read_status,
222};
223
224static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
225
226 .info = {
227 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
228 .type = FE_QPSK,
229 .frequency_min = 950000,
230 .frequency_max = 2150000,
231 .frequency_stepsize = 125,
232 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
233 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
234 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
235 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
236 FE_CAN_HIERARCHY_AUTO,
237 },
238
239 .release = ttusbdecfe_release,
240
241 .set_frontend = ttusbdecfe_dvbs_set_frontend,
242
243 .read_status = ttusbdecfe_read_status,
244
245 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
246 .set_voltage = ttusbdecfe_dvbs_set_voltage,
247 .set_tone = ttusbdecfe_dvbs_set_tone,
248};
249
250MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
251MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
252MODULE_LICENSE("GPL");
253
254EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
255EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
new file mode 100644
index 000000000000..15ccc3d1a20e
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
@@ -0,0 +1,38 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
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 */
21
22#ifndef TTUSBDECFE_H
23#define TTUSBDECFE_H
24
25#include <linux/dvb/frontend.h>
26
27struct ttusbdecfe_config
28{
29 int (*send_command)(struct dvb_frontend* fe, const u8 command,
30 int param_length, const u8 params[],
31 int *result_length, u8 cmd_result[]);
32};
33
34extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config);
35
36extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config);
37
38#endif // TTUSBDECFE_H
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
new file mode 100644
index 000000000000..d318be383de6
--- /dev/null
+++ b/drivers/media/radio/Kconfig
@@ -0,0 +1,354 @@
1#
2# Multimedia Video device configuration
3#
4
5menu "Radio Adapters"
6 depends on VIDEO_DEV!=n
7
8config RADIO_CADET
9 tristate "ADS Cadet AM/FM Tuner"
10 depends on ISA && VIDEO_DEV
11 ---help---
12 Choose Y here if you have one of these AM/FM radio cards, and then
13 fill in the port address below.
14
15 In order to control your radio card, you will need to use programs
16 that are compatible with the Video For Linux API. Information on
17 this API and pointers to "v4l" programs may be found at
18 <file:Documentation/video4linux/API.html>.
19
20 Further documentation on this driver can be found on the WWW at
21 <http://linux.blackhawke.net/cadet/>.
22
23 To compile this driver as a module, choose M here: the
24 module will be called radio-cadet.
25
26config RADIO_RTRACK
27 tristate "AIMSlab RadioTrack (aka RadioReveal) support"
28 depends on ISA && VIDEO_DEV
29 ---help---
30 Choose Y here if you have one of these FM radio cards, and then fill
31 in the port address below.
32
33 Note that newer AIMSlab RadioTrack cards have a different chipset
34 and are not supported by this driver. For these cards, use the
35 RadioTrack II driver below.
36
37 If you have a GemTeks combined (PnP) sound- and radio card you must
38 use this driver as a module and setup the card with isapnptools.
39 You must also pass the module a suitable io parameter, 0x248 has
40 been reported to be used by these cards.
41
42 In order to control your radio card, you will need to use programs
43 that are compatible with the Video For Linux API. Information on
44 this API and pointers to "v4l" programs may be found at
45 <file:Documentation/video4linux/API.html>. More information is
46 contained in the file
47 <file:Documentation/video4linux/radiotrack.txt>.
48
49 To compile this driver as a module, choose M here: the
50 module will be called radio-aimslab.
51
52config RADIO_RTRACK_PORT
53 hex "RadioTrack i/o port (0x20f or 0x30f)"
54 depends on RADIO_RTRACK=y
55 default "20f"
56 help
57 Enter either 0x30f or 0x20f here. The card default is 0x30f, if you
58 haven't changed the jumper setting on the card.
59
60config RADIO_RTRACK2
61 tristate "AIMSlab RadioTrack II support"
62 depends on ISA && VIDEO_DEV
63 ---help---
64 Choose Y here if you have this FM radio card, and then fill in the
65 port address below.
66
67 In order to control your radio card, you will need to use programs
68 that are compatible with the Video For Linux API. Information on
69 this API and pointers to "v4l" programs may be found at
70 <file:Documentation/video4linux/API.html>.
71
72 To compile this driver as a module, choose M here: the
73 module will be called radio-rtrack2.
74
75config RADIO_RTRACK2_PORT
76 hex "RadioTrack II i/o port (0x20c or 0x30c)"
77 depends on RADIO_RTRACK2=y
78 default "30c"
79 help
80 Enter either 0x30c or 0x20c here. The card default is 0x30c, if you
81 haven't changed the jumper setting on the card.
82
83config RADIO_AZTECH
84 tristate "Aztech/Packard Bell Radio"
85 depends on ISA && VIDEO_DEV
86 ---help---
87 Choose Y here if you have one of these FM radio cards, and then fill
88 in the port address below.
89
90 In order to control your radio card, you will need to use programs
91 that are compatible with the Video For Linux API. Information on
92 this API and pointers to "v4l" programs may be found at
93 <file:Documentation/video4linux/API.html>.
94
95 To compile this driver as a module, choose M here: the
96 module will be called radio-aztech.
97
98config RADIO_AZTECH_PORT
99 hex "Aztech/Packard Bell I/O port (0x350 or 0x358)"
100 depends on RADIO_AZTECH=y
101 default "350"
102 help
103 Enter either 0x350 or 0x358 here. The card default is 0x350, if you
104 haven't changed the setting of jumper JP3 on the card. Removing the
105 jumper sets the card to 0x358.
106
107config RADIO_GEMTEK
108 tristate "GemTek Radio Card support"
109 depends on ISA && VIDEO_DEV
110 ---help---
111 Choose Y here if you have this FM radio card, and then fill in the
112 port address below.
113
114 In order to control your radio card, you will need to use programs
115 that are compatible with the Video For Linux API. Information on
116 this API and pointers to "v4l" programs may be found at
117 <file:Documentation/video4linux/API.html>.
118
119 To compile this driver as a module, choose M here: the
120 module will be called radio-gemtek.
121
122config RADIO_GEMTEK_PORT
123 hex "GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)"
124 depends on RADIO_GEMTEK=y
125 default "34c"
126 help
127 Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
128 0x34c, if you haven't changed the jumper setting on the card. On
129 Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
130 port is 0x28c.
131
132config RADIO_GEMTEK_PCI
133 tristate "GemTek PCI Radio Card support"
134 depends on VIDEO_DEV && PCI
135 ---help---
136 Choose Y here if you have this PCI FM radio card.
137
138 In order to control your radio card, you will need to use programs
139 that are compatible with the Video for Linux API. Information on
140 this API and pointers to "v4l" programs may be found at
141 <file:Documentation/video4linux/API.html>.
142
143 To compile this driver as a module, choose M here: the
144 module will be called radio-gemtek-pci.
145
146config RADIO_MAXIRADIO
147 tristate "Guillemot MAXI Radio FM 2000 radio"
148 depends on VIDEO_DEV && PCI
149 ---help---
150 Choose Y here if you have this radio card. This card may also be
151 found as Gemtek PCI FM.
152
153 In order to control your radio card, you will need to use programs
154 that are compatible with the Video For Linux API. Information on
155 this API and pointers to "v4l" programs may be found at
156 <file:Documentation/video4linux/API.html>.
157
158 To compile this driver as a module, choose M here: the
159 module will be called radio-maxiradio.
160
161config RADIO_MAESTRO
162 tristate "Maestro on board radio"
163 depends on VIDEO_DEV
164 ---help---
165 Say Y here to directly support the on-board radio tuner on the
166 Maestro 2 or 2E sound card.
167
168 In order to control your radio card, you will need to use programs
169 that are compatible with the Video For Linux API. Information on
170 this API and pointers to "v4l" programs may be found at
171 <file:Documentation/video4linux/API.html>.
172
173 To compile this driver as a module, choose M here: the
174 module will be called radio-maestro.
175
176config RADIO_MIROPCM20
177 tristate "miroSOUND PCM20 radio"
178 depends on ISA && VIDEO_DEV && SOUND_ACI_MIXER
179 ---help---
180 Choose Y here if you have this FM radio card. You also need to say Y
181 to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound")
182 for this to work.
183
184 In order to control your radio card, you will need to use programs
185 that are compatible with the Video For Linux API. Information on
186 this API and pointers to "v4l" programs may be found at
187 <file:Documentation/video4linux/API.html>.
188
189 To compile this driver as a module, choose M here: the
190 module will be called miropcm20.
191
192config RADIO_MIROPCM20_RDS
193 tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)"
194 depends on RADIO_MIROPCM20 && EXPERIMENTAL
195 ---help---
196 Choose Y here if you want to see RDS/RBDS information like
197 RadioText, Programme Service name, Clock Time and date, Programme
198 TYpe and Traffic Announcement/Programme identification. You also
199 need to say Y to "miroSOUND PCM20 radio" and devfs!
200
201 It's not possible to read the raw RDS packets from the device, so
202 the driver cant provide an V4L interface for this. But the
203 availability of RDS is reported over V4L by the basic driver
204 already. Here RDS can be read from files in /dev/v4l/rds.
205
206 To compile this driver as a module, choose M here: the
207 module will be called miropcm20-rds.
208
209config RADIO_SF16FMI
210 tristate "SF16FMI Radio"
211 depends on ISA && VIDEO_DEV
212 ---help---
213 Choose Y here if you have one of these FM radio cards. If you
214 compile the driver into the kernel and your card is not PnP one, you
215 have to add "sf16fm=<io>" to the kernel command line (I/O address is
216 0x284 or 0x384).
217
218 In order to control your radio card, you will need to use programs
219 that are compatible with the Video For Linux API. Information on
220 this API and pointers to "v4l" programs may be found at
221 <file:Documentation/video4linux/API.html>.
222
223 To compile this driver as a module, choose M here: the
224 module will be called radio-sf16fmi.
225
226config RADIO_SF16FMR2
227 tristate "SF16FMR2 Radio"
228 depends on ISA && VIDEO_DEV
229 ---help---
230 Choose Y here if you have one of these FM radio cards.
231
232 In order to control your radio card, you will need to use programs
233 that are compatible with the Video For Linux API. Information on
234 this API and pointers to "v4l" programs may be found on the WWW at
235 <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
236
237 To compile this driver as a module, choose M here: the
238 module will be called radio-sf16fmr2.
239
240config RADIO_TERRATEC
241 tristate "TerraTec ActiveRadio ISA Standalone"
242 depends on ISA && VIDEO_DEV
243 ---help---
244 Choose Y here if you have this FM radio card, and then fill in the
245 port address below. (TODO)
246
247 Note: This driver is in its early stages. Right now volume and
248 frequency control and muting works at least for me, but
249 unfortunately I have not found anybody who wants to use this card
250 with Linux. So if it is this what YOU are trying to do right now,
251 PLEASE DROP ME A NOTE!! Rolf Offermanns <rolf@offermanns.de>.
252
253 In order to control your radio card, you will need to use programs
254 that are compatible with the Video For Linux API. Information on
255 this API and pointers to "v4l" programs may be found at
256 <file:Documentation/video4linux/API.html>.
257
258 To compile this driver as a module, choose M here: the
259 module will be called radio-terratec.
260
261config RADIO_TERRATEC_PORT
262 hex "Terratec i/o port (normally 0x590)"
263 depends on RADIO_TERRATEC=y
264 default "590"
265 help
266 Fill in the I/O port of your TerraTec FM radio card. If unsure, go
267 with the default.
268
269config RADIO_TRUST
270 tristate "Trust FM radio card"
271 depends on ISA && VIDEO_DEV
272 help
273 This is a driver for the Trust FM radio cards. Say Y if you have
274 such a card and want to use it under Linux.
275
276 To compile this driver as a module, choose M here: the
277 module will be called radio-trust.
278
279config RADIO_TRUST_PORT
280 hex "Trust i/o port (usually 0x350 or 0x358)"
281 depends on RADIO_TRUST=y
282 default "350"
283 help
284 Enter the I/O port of your Trust FM radio card. If unsure, try the
285 values "0x350" or "0x358".
286
287config RADIO_TYPHOON
288 tristate "Typhoon Radio (a.k.a. EcoRadio)"
289 depends on ISA && VIDEO_DEV
290 ---help---
291 Choose Y here if you have one of these FM radio cards, and then fill
292 in the port address and the frequency used for muting below.
293
294 In order to control your radio card, you will need to use programs
295 that are compatible with the Video For Linux API. Information on
296 this API and pointers to "v4l" programs may be found at
297 <file:Documentation/video4linux/API.html>.
298
299 To compile this driver as a module, choose M here: the
300 module will be called radio-typhoon.
301
302config RADIO_TYPHOON_PROC_FS
303 bool "Support for /proc/radio-typhoon"
304 depends on PROC_FS && RADIO_TYPHOON
305 help
306 Say Y here if you want the typhoon radio card driver to write
307 status information (frequency, volume, muted, mute frequency,
308 base address) to /proc/radio-typhoon. The file can be viewed with
309 your favorite pager (i.e. use "more /proc/radio-typhoon" or "less
310 /proc/radio-typhoon" or simply "cat /proc/radio-typhoon").
311
312config RADIO_TYPHOON_PORT
313 hex "Typhoon I/O port (0x316 or 0x336)"
314 depends on RADIO_TYPHOON=y
315 default "316"
316 help
317 Enter the I/O port of your Typhoon or EcoRadio radio card.
318
319config RADIO_TYPHOON_MUTEFREQ
320 int "Typhoon frequency set when muting the device (kHz)"
321 depends on RADIO_TYPHOON=y
322 default "87500"
323 help
324 Enter the frequency used for muting the radio. The device is never
325 completely silent. If the volume is just turned down, you can still
326 hear silent voices and music. For that reason, the frequency of the
327 radio device is set to the frequency you can enter here whenever
328 the device is muted. There should be no local radio station at that
329 frequency.
330
331config RADIO_ZOLTRIX
332 tristate "Zoltrix Radio"
333 depends on ISA && VIDEO_DEV
334 ---help---
335 Choose Y here if you have one of these FM radio cards, and then fill
336 in the port address below.
337
338 In order to control your radio card, you will need to use programs
339 that are compatible with the Video For Linux API. Information on
340 this API and pointers to "v4l" programs may be found at
341 <file:Documentation/video4linux/API.html>.
342
343 To compile this driver as a module, choose M here: the
344 module will be called radio-zoltrix.
345
346config RADIO_ZOLTRIX_PORT
347 hex "ZOLTRIX I/O port (0x20c or 0x30c)"
348 depends on RADIO_ZOLTRIX=y
349 default "20c"
350 help
351 Enter the I/O port of your Zoltrix radio card.
352
353endmenu
354
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
new file mode 100644
index 000000000000..8b351945d066
--- /dev/null
+++ b/drivers/media/radio/Makefile
@@ -0,0 +1,22 @@
1#
2# Makefile for the kernel character device drivers.
3#
4
5miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o
6
7obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
8obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
9obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
10obj-$(CONFIG_RADIO_SF16FMR2) += radio-sf16fmr2.o
11obj-$(CONFIG_RADIO_CADET) += radio-cadet.o
12obj-$(CONFIG_RADIO_TYPHOON) += radio-typhoon.o
13obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o
14obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
15obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
16obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
17obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o
18obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o
19obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
20obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
21obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
22obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
new file mode 100644
index 000000000000..c2ebe8754a95
--- /dev/null
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -0,0 +1,264 @@
1/* Miro PCM20 radio driver for Linux radio support
2 * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
3 * Thanks to Norberto Pellici for the ACI device interface specification
4 * The API part is based on the radiotrack driver by M. Kirkwood
5 * This driver relies on the aci mixer (drivers/sound/aci.c)
6 * Look there for further info...
7 */
8
9/* Revision history:
10 *
11 * 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
12 * 2000-09-05 Robert Siemer <Robert.Siemer@gmx.de>
13 * removed unfinished volume control (maybe adding it later again)
14 * use OSS-mixer; added stereo control
15 */
16
17/* What ever you think about the ACI, version 0x07 is not very well!
18 * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
19 * conditions... Robert
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/videodev.h>
25#include "../../../sound/oss/aci.h"
26#include "miropcm20-rds-core.h"
27
28static int radio_nr = -1;
29module_param(radio_nr, int, 0);
30
31struct pcm20_device {
32 unsigned long freq;
33 int muted;
34 int stereo;
35};
36
37
38static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
39{
40 dev->muted = mute;
41 return aci_write_cmd(ACI_SET_TUNERMUTE, mute);
42}
43
44static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
45{
46 dev->stereo = stereo;
47 return aci_write_cmd(ACI_SET_TUNERMONO, !stereo);
48}
49
50static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
51{
52 unsigned char freql;
53 unsigned char freqh;
54
55 dev->freq=freq;
56
57 freq /= 160;
58 if (!(aci_version==0x07 || aci_version>=0xb0))
59 freq /= 10; /* I don't know exactly which version
60 * needs this hack */
61 freql = freq & 0xff;
62 freqh = freq >> 8;
63
64 aci_rds_cmd(RDS_RESET, NULL, 0);
65 pcm20_stereo(dev, 1);
66
67 return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh);
68}
69
70static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
71{
72 /* okay, check for signal, stereo and rds here... */
73 int i;
74 unsigned char buf;
75
76 if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0)
77 return i;
78 pr_debug("check_sig: 0x%x\n", i);
79 if (i & 0x80) {
80 /* no signal from tuner */
81 *flags=0;
82 *signal=0;
83 return 0;
84 } else
85 *signal=0xffff;
86
87 if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0)
88 return i;
89 if (i & 0x40) {
90 *flags=0;
91 } else {
92 /* stereo */
93 *flags=VIDEO_TUNER_STEREO_ON;
94 /* I can't see stereo, when forced to mono */
95 dev->stereo=1;
96 }
97
98 if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
99 return i;
100 if (buf & 1)
101 /* RDS available */
102 *flags|=VIDEO_TUNER_RDS_ON;
103 else
104 return 0;
105
106 if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
107 return i;
108 pr_debug("rds-signal: %d\n", buf);
109 if (buf > 15) {
110 printk("miropcm20-radio: RX strengths unexpected high...\n");
111 buf=15;
112 }
113 /* refine signal */
114 if ((*signal=SCALE(15, 0xffff, buf))==0)
115 *signal = 1;
116
117 return 0;
118}
119
120static int pcm20_do_ioctl(struct inode *inode, struct file *file,
121 unsigned int cmd, void *arg)
122{
123 struct video_device *dev = video_devdata(file);
124 struct pcm20_device *pcm20 = dev->priv;
125 int i;
126
127 switch(cmd)
128 {
129 case VIDIOCGCAP:
130 {
131 struct video_capability *v = arg;
132 memset(v,0,sizeof(*v));
133 v->type=VID_TYPE_TUNER;
134 strcpy(v->name, "Miro PCM20");
135 v->channels=1;
136 v->audios=1;
137 return 0;
138 }
139 case VIDIOCGTUNER:
140 {
141 struct video_tuner *v = arg;
142 if(v->tuner) /* Only 1 tuner */
143 return -EINVAL;
144 v->rangelow=87*16000;
145 v->rangehigh=108*16000;
146 pcm20_getflags(pcm20, &v->flags, &v->signal);
147 v->flags|=VIDEO_TUNER_LOW;
148 v->mode=VIDEO_MODE_AUTO;
149 strcpy(v->name, "FM");
150 return 0;
151 }
152 case VIDIOCSTUNER:
153 {
154 struct video_tuner *v = arg;
155 if(v->tuner!=0)
156 return -EINVAL;
157 /* Only 1 tuner so no setting needed ! */
158 return 0;
159 }
160 case VIDIOCGFREQ:
161 {
162 unsigned long *freq = arg;
163 *freq = pcm20->freq;
164 return 0;
165 }
166 case VIDIOCSFREQ:
167 {
168 unsigned long *freq = arg;
169 pcm20->freq = *freq;
170 i=pcm20_setfreq(pcm20, pcm20->freq);
171 pr_debug("First view (setfreq): 0x%x\n", i);
172 return i;
173 }
174 case VIDIOCGAUDIO:
175 {
176 struct video_audio *v = arg;
177 memset(v,0, sizeof(*v));
178 v->flags=VIDEO_AUDIO_MUTABLE;
179 if (pcm20->muted)
180 v->flags|=VIDEO_AUDIO_MUTE;
181 v->mode=VIDEO_SOUND_STEREO;
182 if (pcm20->stereo)
183 v->mode|=VIDEO_SOUND_MONO;
184 /* v->step=2048; */
185 strcpy(v->name, "Radio");
186 return 0;
187 }
188 case VIDIOCSAUDIO:
189 {
190 struct video_audio *v = arg;
191 if(v->audio)
192 return -EINVAL;
193
194 pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE));
195 if(v->flags&VIDEO_SOUND_MONO)
196 pcm20_stereo(pcm20, 0);
197 if(v->flags&VIDEO_SOUND_STEREO)
198 pcm20_stereo(pcm20, 1);
199
200 return 0;
201 }
202 default:
203 return -ENOIOCTLCMD;
204 }
205}
206
207static int pcm20_ioctl(struct inode *inode, struct file *file,
208 unsigned int cmd, unsigned long arg)
209{
210 return video_usercopy(inode, file, cmd, arg, pcm20_do_ioctl);
211}
212
213static struct pcm20_device pcm20_unit = {
214 .freq = 87*16000,
215 .muted = 1,
216};
217
218static struct file_operations pcm20_fops = {
219 .owner = THIS_MODULE,
220 .open = video_exclusive_open,
221 .release = video_exclusive_release,
222 .ioctl = pcm20_ioctl,
223 .llseek = no_llseek,
224};
225
226static struct video_device pcm20_radio = {
227 .owner = THIS_MODULE,
228 .name = "Miro PCM 20 radio",
229 .type = VID_TYPE_TUNER,
230 .hardware = VID_HARDWARE_RTRACK,
231 .fops = &pcm20_fops,
232 .priv = &pcm20_unit
233};
234
235static int __init pcm20_init(void)
236{
237 if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
238 goto video_register_device;
239
240 if(attach_aci_rds()<0)
241 goto attach_aci_rds;
242
243 printk(KERN_INFO "Miro PCM20 radio card driver.\n");
244
245 return 0;
246
247 attach_aci_rds:
248 video_unregister_device(&pcm20_radio);
249 video_register_device:
250 return -EINVAL;
251}
252
253MODULE_AUTHOR("Ruurd Reitsma");
254MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
255MODULE_LICENSE("GPL");
256
257static void __exit pcm20_cleanup(void)
258{
259 unload_aci_rds();
260 video_unregister_device(&pcm20_radio);
261}
262
263module_init(pcm20_init);
264module_exit(pcm20_cleanup);
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
new file mode 100644
index 000000000000..a917a90cb5dc
--- /dev/null
+++ b/drivers/media/radio/miropcm20-rds-core.c
@@ -0,0 +1,210 @@
1/*
2 * Many thanks to Fred Seidel <seidel@metabox.de>, the
3 * designer of the RDS decoder hardware. With his help
4 * I was able to code this driver.
5 * Thanks also to Norberto Pellicci, Dominic Mounteney
6 * <DMounteney@pinnaclesys.com> and www.teleauskunft.de
7 * for good hints on finding Fred. It was somewhat hard
8 * to locate him here in Germany... [:
9 *
10 * Revision history:
11 *
12 * 2000-08-09 Robert Siemer <Robert.Siemer@gmx.de>
13 * RDS support for MiroSound PCM20 radio
14 */
15
16#include <linux/module.h>
17#include <linux/errno.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <asm/semaphore.h>
22#include <asm/io.h>
23#include "../../../sound/oss/aci.h"
24#include "miropcm20-rds-core.h"
25
26#define DEBUG 0
27
28static struct semaphore aci_rds_sem;
29
30#define RDS_DATASHIFT 2 /* Bit 2 */
31#define RDS_DATAMASK (1 << RDS_DATASHIFT)
32#define RDS_BUSYMASK 0x10 /* Bit 4 */
33#define RDS_CLOCKMASK 0x08 /* Bit 3 */
34
35#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1)
36
37
38#if DEBUG
39static void print_matrix(char array[], unsigned int length)
40{
41 int i, j;
42
43 for (i=0; i<length; i++) {
44 printk(KERN_DEBUG "aci-rds: ");
45 for (j=7; j>=0; j--) {
46 printk("%d", (array[i] >> j) & 0x1);
47 }
48 if (i%8 == 0)
49 printk(" byte-border\n");
50 else
51 printk("\n");
52 }
53}
54#endif /* DEBUG */
55
56static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
57{
58 int i;
59
60 if (size != 8)
61 return -1;
62 for (i = 7; i >= 0; i--)
63 sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
64 sendbuffer[0] |= RDS_CLOCKMASK;
65
66 return 0;
67}
68
69static int rds_waitread(void)
70{
71 unsigned char byte;
72 int i=2000;
73
74 do {
75 byte=inb(RDS_REGISTER);
76 i--;
77 }
78 while ((byte & RDS_BUSYMASK) && i);
79
80 if (i) {
81 #if DEBUG
82 printk(KERN_DEBUG "rds_waitread()");
83 print_matrix(&byte, 1);
84 #endif
85 return (byte);
86 } else {
87 printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
88 return -1;
89 }
90}
91
92/* don't use any ..._nowait() function if you are not sure what you do... */
93
94static inline void rds_rawwrite_nowait(unsigned char byte)
95{
96 #if DEBUG
97 printk(KERN_DEBUG "rds_rawwrite()");
98 print_matrix(&byte, 1);
99 #endif
100 outb(byte, RDS_REGISTER);
101}
102
103static int rds_rawwrite(unsigned char byte)
104{
105 if (rds_waitread() >= 0) {
106 rds_rawwrite_nowait(byte);
107 return 0;
108 } else
109 return -1;
110}
111
112static int rds_write(unsigned char cmd)
113{
114 unsigned char sendbuffer[8];
115 int i;
116
117 if (byte2trans(cmd, sendbuffer, 8) != 0){
118 return -1;
119 } else {
120 for (i=0; i<8; i++) {
121 rds_rawwrite(sendbuffer[i]);
122 }
123 }
124 return 0;
125}
126
127static int rds_readcycle_nowait(void)
128{
129 rds_rawwrite_nowait(0);
130 return rds_waitread();
131}
132
133static int rds_readcycle(void)
134{
135 if (rds_rawwrite(0) < 0)
136 return -1;
137 return rds_waitread();
138}
139
140static int rds_read(unsigned char databuffer[], int datasize)
141{
142 #define READSIZE (8*datasize)
143
144 int i,j;
145
146 if (datasize < 1) /* nothing to read */
147 return 0;
148
149 /* to be able to use rds_readcycle_nowait()
150 I have to waitread() here */
151 if (rds_waitread() < 0)
152 return -1;
153
154 memset(databuffer, 0, datasize);
155
156 for (i=0; i< READSIZE; i++)
157 if((j=rds_readcycle_nowait()) < 0) {
158 return -1;
159 } else {
160 databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
161 }
162
163 return 0;
164}
165
166static int rds_ack(void)
167{
168 int i=rds_readcycle();
169
170 if (i < 0)
171 return -1;
172 if (i & RDS_DATAMASK) {
173 return 0; /* ACK */
174 } else {
175 printk(KERN_DEBUG "aci-rds: NACK\n");
176 return 1; /* NACK */
177 }
178}
179
180int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
181{
182 int ret;
183
184 if (down_interruptible(&aci_rds_sem))
185 return -EINTR;
186
187 rds_write(cmd);
188
189 /* RDS_RESET doesn't need further processing */
190 if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
191 ret = -1;
192 else
193 ret = 0;
194
195 up(&aci_rds_sem);
196
197 return ret;
198}
199EXPORT_SYMBOL(aci_rds_cmd);
200
201int __init attach_aci_rds(void)
202{
203 init_MUTEX(&aci_rds_sem);
204 return 0;
205}
206
207void __exit unload_aci_rds(void)
208{
209}
210MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/miropcm20-rds-core.h b/drivers/media/radio/miropcm20-rds-core.h
new file mode 100644
index 000000000000..aeb5761f0469
--- /dev/null
+++ b/drivers/media/radio/miropcm20-rds-core.h
@@ -0,0 +1,19 @@
1#ifndef _MIROPCM20_RDS_CORE_H_
2#define _MIROPCM20_RDS_CORE_H_
3
4extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
5
6#define RDS_STATUS 0x01
7#define RDS_STATIONNAME 0x02
8#define RDS_TEXT 0x03
9#define RDS_ALTFREQ 0x04
10#define RDS_TIMEDATE 0x05
11#define RDS_PI_CODE 0x06
12#define RDS_PTYTATP 0x07
13#define RDS_RESET 0x08
14#define RDS_RXVALUE 0x09
15
16extern void __exit unload_aci_rds(void);
17extern int __init attach_aci_rds(void);
18
19#endif /* _MIROPCM20_RDS_CORE_H_ */
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
new file mode 100644
index 000000000000..df79d5e0aaed
--- /dev/null
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -0,0 +1,133 @@
1/* MiroSOUND PCM20 radio rds interface driver
2 * (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
3 * Thanks to Fred Seidel. See miropcm20-rds-core.c for further information.
4 */
5
6/* Revision history:
7 *
8 * 2001-04-18 Robert Siemer <Robert.Siemer@gmx.de>
9 * separate file for user interface driver
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/fs.h>
16#include <linux/miscdevice.h>
17#include <linux/delay.h>
18#include <asm/uaccess.h>
19#include "miropcm20-rds-core.h"
20
21static char * text_buffer;
22static int rds_users = 0;
23
24
25static int rds_f_open(struct inode *in, struct file *fi)
26{
27 if (rds_users)
28 return -EBUSY;
29
30 rds_users++;
31 if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
32 rds_users--;
33 printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
34 return -ENOMEM;
35 }
36
37 return 0;
38}
39
40static int rds_f_release(struct inode *in, struct file *fi)
41{
42 kfree(text_buffer);
43
44 rds_users--;
45 return 0;
46}
47
48static void print_matrix(char *ch, char out[])
49{
50 int j;
51
52 for (j=7; j>=0; j--) {
53 out[7-j] = ((*ch >> j) & 0x1) + '0';
54 }
55}
56
57static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
58{
59// i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset);
60
61 char c;
62 char bits[8];
63
64 msleep(2000);
65 aci_rds_cmd(RDS_STATUS, &c, 1);
66 print_matrix(&c, bits);
67 if (copy_to_user(buffer, bits, 8))
68 return -EFAULT;
69
70/* if ((c >> 3) & 1) {
71 aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8);
72 text_buffer[0] = ' ' ;
73 text_buffer[9] = '\n';
74 return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18;
75 }
76*/
77/* if ((c >> 6) & 1) {
78 aci_rds_cmd(RDS_PTYTATP, &c, 1);
79 if ( c & 1)
80 sprintf(text_buffer, " M");
81 else
82 sprintf(text_buffer, " S");
83 if ((c >> 1) & 1)
84 sprintf(text_buffer+2, " TA");
85 else
86 sprintf(text_buffer+2, " --");
87 if ((c >> 7) & 1)
88 sprintf(text_buffer+5, " TP");
89 else
90 sprintf(text_buffer+5, " --");
91 sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f);
92 return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20;
93 }
94*/
95
96 if ((c >> 4) & 1) {
97 aci_rds_cmd(RDS_TEXT, text_buffer, 65);
98 text_buffer[0] = ' ' ;
99 text_buffer[65] = '\n';
100 return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8;
101 } else {
102 put_user('\n', buffer+8);
103 return 9;
104 }
105}
106
107static struct file_operations rds_fops = {
108 .owner = THIS_MODULE,
109 .read = rds_f_read,
110 .open = rds_f_open,
111 .release = rds_f_release
112};
113
114static struct miscdevice rds_miscdev = {
115 .minor = MISC_DYNAMIC_MINOR,
116 .name = "radiotext",
117 .devfs_name = "v4l/rds/radiotext",
118 .fops = &rds_fops,
119};
120
121static int __init miropcm20_rds_init(void)
122{
123 return misc_register(&rds_miscdev);
124}
125
126static void __exit miropcm20_rds_cleanup(void)
127{
128 misc_deregister(&rds_miscdev);
129}
130
131module_init(miropcm20_rds_init);
132module_exit(miropcm20_rds_cleanup);
133MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
new file mode 100644
index 000000000000..8b4ad70dd1b2
--- /dev/null
+++ b/drivers/media/radio/radio-aimslab.c
@@ -0,0 +1,368 @@
1/* radiotrack (radioreveal) driver for Linux radio support
2 * (c) 1997 M. Kirkwood
3 * Converted to new API by Alan Cox <Alan.Cox@linux.org>
4 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
5 *
6 * History:
7 * 1999-02-24 Russell Kroll <rkroll@exploits.org>
8 * Fine tuning/VIDEO_TUNER_LOW
9 * Frequency range expanded to start at 87 MHz
10 *
11 * TODO: Allow for more than one of these foolish entities :-)
12 *
13 * Notes on the hardware (reverse engineered from other peoples'
14 * reverse engineering of AIMS' code :-)
15 *
16 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
17 *
18 * The signal strength query is unsurprisingly inaccurate. And it seems
19 * to indicate that (on my card, at least) the frequency setting isn't
20 * too great. (I have to tune up .025MHz from what the freq should be
21 * to get a report that the thing is tuned.)
22 *
23 * Volume control is (ugh) analogue:
24 * out(port, start_increasing_volume);
25 * wait(a_wee_while);
26 * out(port, stop_changing_the_volume);
27 *
28 */
29
30#include <linux/module.h> /* Modules */
31#include <linux/init.h> /* Initdata */
32#include <linux/ioport.h> /* check_region, request_region */
33#include <linux/delay.h> /* udelay */
34#include <asm/io.h> /* outb, outb_p */
35#include <asm/uaccess.h> /* copy to/from user */
36#include <linux/videodev.h> /* kernel radio structs */
37#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */
38#include <asm/semaphore.h> /* Lock for the I/O */
39
40#ifndef CONFIG_RADIO_RTRACK_PORT
41#define CONFIG_RADIO_RTRACK_PORT -1
42#endif
43
44static int io = CONFIG_RADIO_RTRACK_PORT;
45static int radio_nr = -1;
46static struct semaphore lock;
47
48struct rt_device
49{
50 int port;
51 int curvol;
52 unsigned long curfreq;
53 int muted;
54};
55
56
57/* local things */
58
59static void sleep_delay(long n)
60{
61 /* Sleep nicely for 'n' uS */
62 int d=n/(1000000/HZ);
63 if(!d)
64 udelay(n);
65 else
66 msleep(jiffies_to_msecs(d));
67}
68
69static void rt_decvol(void)
70{
71 outb(0x58, io); /* volume down + sigstr + on */
72 sleep_delay(100000);
73 outb(0xd8, io); /* volume steady + sigstr + on */
74}
75
76static void rt_incvol(void)
77{
78 outb(0x98, io); /* volume up + sigstr + on */
79 sleep_delay(100000);
80 outb(0xd8, io); /* volume steady + sigstr + on */
81}
82
83static void rt_mute(struct rt_device *dev)
84{
85 dev->muted = 1;
86 down(&lock);
87 outb(0xd0, io); /* volume steady, off */
88 up(&lock);
89}
90
91static int rt_setvol(struct rt_device *dev, int vol)
92{
93 int i;
94
95 down(&lock);
96
97 if(vol == dev->curvol) { /* requested volume = current */
98 if (dev->muted) { /* user is unmuting the card */
99 dev->muted = 0;
100 outb (0xd8, io); /* enable card */
101 }
102 up(&lock);
103 return 0;
104 }
105
106 if(vol == 0) { /* volume = 0 means mute the card */
107 outb(0x48, io); /* volume down but still "on" */
108 sleep_delay(2000000); /* make sure it's totally down */
109 outb(0xd0, io); /* volume steady, off */
110 dev->curvol = 0; /* track the volume state! */
111 up(&lock);
112 return 0;
113 }
114
115 dev->muted = 0;
116 if(vol > dev->curvol)
117 for(i = dev->curvol; i < vol; i++)
118 rt_incvol();
119 else
120 for(i = dev->curvol; i > vol; i--)
121 rt_decvol();
122
123 dev->curvol = vol;
124 up(&lock);
125 return 0;
126}
127
128/* the 128+64 on these outb's is to keep the volume stable while tuning
129 * without them, the volume _will_ creep up with each frequency change
130 * and bit 4 (+16) is to keep the signal strength meter enabled
131 */
132
133static void send_0_byte(int port, struct rt_device *dev)
134{
135 if ((dev->curvol == 0) || (dev->muted)) {
136 outb_p(128+64+16+ 1, port); /* wr-enable + data low */
137 outb_p(128+64+16+2+1, port); /* clock */
138 }
139 else {
140 outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */
141 outb_p(128+64+16+8+2+1, port); /* clock */
142 }
143 sleep_delay(1000);
144}
145
146static void send_1_byte(int port, struct rt_device *dev)
147{
148 if ((dev->curvol == 0) || (dev->muted)) {
149 outb_p(128+64+16+4 +1, port); /* wr-enable+data high */
150 outb_p(128+64+16+4+2+1, port); /* clock */
151 }
152 else {
153 outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */
154 outb_p(128+64+16+8+4+2+1, port); /* clock */
155 }
156
157 sleep_delay(1000);
158}
159
160static int rt_setfreq(struct rt_device *dev, unsigned long freq)
161{
162 int i;
163
164 /* adapted from radio-aztech.c */
165
166 /* now uses VIDEO_TUNER_LOW for fine tuning */
167
168 freq += 171200; /* Add 10.7 MHz IF */
169 freq /= 800; /* Convert to 50 kHz units */
170
171 down(&lock); /* Stop other ops interfering */
172
173 send_0_byte (io, dev); /* 0: LSB of frequency */
174
175 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
176 if (freq & (1 << i))
177 send_1_byte (io, dev);
178 else
179 send_0_byte (io, dev);
180
181 send_0_byte (io, dev); /* 14: test bit - always 0 */
182 send_0_byte (io, dev); /* 15: test bit - always 0 */
183
184 send_0_byte (io, dev); /* 16: band data 0 - always 0 */
185 send_0_byte (io, dev); /* 17: band data 1 - always 0 */
186 send_0_byte (io, dev); /* 18: band data 2 - always 0 */
187 send_0_byte (io, dev); /* 19: time base - always 0 */
188
189 send_0_byte (io, dev); /* 20: spacing (0 = 25 kHz) */
190 send_1_byte (io, dev); /* 21: spacing (1 = 25 kHz) */
191 send_0_byte (io, dev); /* 22: spacing (0 = 25 kHz) */
192 send_1_byte (io, dev); /* 23: AM/FM (FM = 1, always) */
193
194 if ((dev->curvol == 0) || (dev->muted))
195 outb (0xd0, io); /* volume steady + sigstr */
196 else
197 outb (0xd8, io); /* volume steady + sigstr + on */
198
199 up(&lock);
200
201 return 0;
202}
203
204static int rt_getsigstr(struct rt_device *dev)
205{
206 if (inb(io) & 2) /* bit set = no signal present */
207 return 0;
208 return 1; /* signal present */
209}
210
211static int rt_do_ioctl(struct inode *inode, struct file *file,
212 unsigned int cmd, void *arg)
213{
214 struct video_device *dev = video_devdata(file);
215 struct rt_device *rt=dev->priv;
216
217 switch(cmd)
218 {
219 case VIDIOCGCAP:
220 {
221 struct video_capability *v = arg;
222 memset(v,0,sizeof(*v));
223 v->type=VID_TYPE_TUNER;
224 v->channels=1;
225 v->audios=1;
226 strcpy(v->name, "RadioTrack");
227 return 0;
228 }
229 case VIDIOCGTUNER:
230 {
231 struct video_tuner *v = arg;
232 if(v->tuner) /* Only 1 tuner */
233 return -EINVAL;
234 v->rangelow=(87*16000);
235 v->rangehigh=(108*16000);
236 v->flags=VIDEO_TUNER_LOW;
237 v->mode=VIDEO_MODE_AUTO;
238 strcpy(v->name, "FM");
239 v->signal=0xFFFF*rt_getsigstr(rt);
240 return 0;
241 }
242 case VIDIOCSTUNER:
243 {
244 struct video_tuner *v = arg;
245 if(v->tuner!=0)
246 return -EINVAL;
247 /* Only 1 tuner so no setting needed ! */
248 return 0;
249 }
250 case VIDIOCGFREQ:
251 {
252 unsigned long *freq = arg;
253 *freq = rt->curfreq;
254 return 0;
255 }
256 case VIDIOCSFREQ:
257 {
258 unsigned long *freq = arg;
259 rt->curfreq = *freq;
260 rt_setfreq(rt, rt->curfreq);
261 return 0;
262 }
263 case VIDIOCGAUDIO:
264 {
265 struct video_audio *v = arg;
266 memset(v,0, sizeof(*v));
267 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
268 v->volume=rt->curvol * 6554;
269 v->step=6554;
270 strcpy(v->name, "Radio");
271 return 0;
272 }
273 case VIDIOCSAUDIO:
274 {
275 struct video_audio *v = arg;
276 if(v->audio)
277 return -EINVAL;
278 if(v->flags&VIDEO_AUDIO_MUTE)
279 rt_mute(rt);
280 else
281 rt_setvol(rt,v->volume/6554);
282 return 0;
283 }
284 default:
285 return -ENOIOCTLCMD;
286 }
287}
288
289static int rt_ioctl(struct inode *inode, struct file *file,
290 unsigned int cmd, unsigned long arg)
291{
292 return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
293}
294
295static struct rt_device rtrack_unit;
296
297static struct file_operations rtrack_fops = {
298 .owner = THIS_MODULE,
299 .open = video_exclusive_open,
300 .release = video_exclusive_release,
301 .ioctl = rt_ioctl,
302 .llseek = no_llseek,
303};
304
305static struct video_device rtrack_radio=
306{
307 .owner = THIS_MODULE,
308 .name = "RadioTrack radio",
309 .type = VID_TYPE_TUNER,
310 .hardware = VID_HARDWARE_RTRACK,
311 .fops = &rtrack_fops,
312};
313
314static int __init rtrack_init(void)
315{
316 if(io==-1)
317 {
318 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
319 return -EINVAL;
320 }
321
322 if (!request_region(io, 2, "rtrack"))
323 {
324 printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
325 return -EBUSY;
326 }
327
328 rtrack_radio.priv=&rtrack_unit;
329
330 if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1)
331 {
332 release_region(io, 2);
333 return -EINVAL;
334 }
335 printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
336
337 /* Set up the I/O locking */
338
339 init_MUTEX(&lock);
340
341 /* mute card - prevents noisy bootups */
342
343 /* this ensures that the volume is all the way down */
344 outb(0x48, io); /* volume down but still "on" */
345 sleep_delay(2000000); /* make sure it's totally down */
346 outb(0xc0, io); /* steady volume, mute card */
347 rtrack_unit.curvol = 0;
348
349 return 0;
350}
351
352MODULE_AUTHOR("M.Kirkwood");
353MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
354MODULE_LICENSE("GPL");
355
356module_param(io, int, 0);
357MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
358module_param(radio_nr, int, 0);
359
360static void __exit cleanup_rtrack_module(void)
361{
362 video_unregister_device(&rtrack_radio);
363 release_region(io,2);
364}
365
366module_init(rtrack_init);
367module_exit(cleanup_rtrack_module);
368
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
new file mode 100644
index 000000000000..013c835ed910
--- /dev/null
+++ b/drivers/media/radio/radio-aztech.c
@@ -0,0 +1,315 @@
1/* radio-aztech.c - Aztech radio card driver for Linux 2.2
2 *
3 * Adapted to support the Video for Linux API by
4 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
5 *
6 * Quay Ly
7 * Donald Song
8 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
9 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
10 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
11 *
12 * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
13 * along with more information on the card itself.
14 *
15 * History:
16 * 1999-02-24 Russell Kroll <rkroll@exploits.org>
17 * Fine tuning/VIDEO_TUNER_LOW
18 * Range expanded to 87-108 MHz (from 87.9-107.8)
19 *
20 * Notable changes from the original source:
21 * - includes stripped down to the essentials
22 * - for loops used as delays replaced with udelay()
23 * - #defines removed, changed to static values
24 * - tuning structure changed - no more character arrays, other changes
25*/
26
27#include <linux/module.h> /* Modules */
28#include <linux/init.h> /* Initdata */
29#include <linux/ioport.h> /* check_region, request_region */
30#include <linux/delay.h> /* udelay */
31#include <asm/io.h> /* outb, outb_p */
32#include <asm/uaccess.h> /* copy to/from user */
33#include <linux/videodev.h> /* kernel radio structs */
34#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */
35
36/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
37
38#ifndef CONFIG_RADIO_AZTECH_PORT
39#define CONFIG_RADIO_AZTECH_PORT -1
40#endif
41
42static int io = CONFIG_RADIO_AZTECH_PORT;
43static int radio_nr = -1;
44static int radio_wait_time = 1000;
45static struct semaphore lock;
46
47struct az_device
48{
49 int curvol;
50 unsigned long curfreq;
51 int stereo;
52};
53
54static int volconvert(int level)
55{
56 level>>=14; /* Map 16bits down to 2 bit */
57 level&=3;
58
59 /* convert to card-friendly values */
60 switch (level)
61 {
62 case 0:
63 return 0;
64 case 1:
65 return 1;
66 case 2:
67 return 4;
68 case 3:
69 return 5;
70 }
71 return 0; /* Quieten gcc */
72}
73
74static void send_0_byte (struct az_device *dev)
75{
76 udelay(radio_wait_time);
77 outb_p(2+volconvert(dev->curvol), io);
78 outb_p(64+2+volconvert(dev->curvol), io);
79}
80
81static void send_1_byte (struct az_device *dev)
82{
83 udelay (radio_wait_time);
84 outb_p(128+2+volconvert(dev->curvol), io);
85 outb_p(128+64+2+volconvert(dev->curvol), io);
86}
87
88static int az_setvol(struct az_device *dev, int vol)
89{
90 down(&lock);
91 outb (volconvert(vol), io);
92 up(&lock);
93 return 0;
94}
95
96/* thanks to Michael Dwyer for giving me a dose of clues in
97 * the signal strength department..
98 *
99 * This card has a stereo bit - bit 0 set = mono, not set = stereo
100 * It also has a "signal" bit - bit 1 set = bad signal, not set = good
101 *
102 */
103
104static int az_getsigstr(struct az_device *dev)
105{
106 if (inb(io) & 2) /* bit set = no signal present */
107 return 0;
108 return 1; /* signal present */
109}
110
111static int az_getstereo(struct az_device *dev)
112{
113 if (inb(io) & 1) /* bit set = mono */
114 return 0;
115 return 1; /* stereo */
116}
117
118static int az_setfreq(struct az_device *dev, unsigned long frequency)
119{
120 int i;
121
122 frequency += 171200; /* Add 10.7 MHz IF */
123 frequency /= 800; /* Convert to 50 kHz units */
124
125 down(&lock);
126
127 send_0_byte (dev); /* 0: LSB of frequency */
128
129 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
130 if (frequency & (1 << i))
131 send_1_byte (dev);
132 else
133 send_0_byte (dev);
134
135 send_0_byte (dev); /* 14: test bit - always 0 */
136 send_0_byte (dev); /* 15: test bit - always 0 */
137 send_0_byte (dev); /* 16: band data 0 - always 0 */
138 if (dev->stereo) /* 17: stereo (1 to enable) */
139 send_1_byte (dev);
140 else
141 send_0_byte (dev);
142
143 send_1_byte (dev); /* 18: band data 1 - unknown */
144 send_0_byte (dev); /* 19: time base - always 0 */
145 send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */
146 send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */
147 send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */
148 send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */
149
150 /* latch frequency */
151
152 udelay (radio_wait_time);
153 outb_p(128+64+volconvert(dev->curvol), io);
154
155 up(&lock);
156
157 return 0;
158}
159
160static int az_do_ioctl(struct inode *inode, struct file *file,
161 unsigned int cmd, void *arg)
162{
163 struct video_device *dev = video_devdata(file);
164 struct az_device *az = dev->priv;
165
166 switch(cmd)
167 {
168 case VIDIOCGCAP:
169 {
170 struct video_capability *v = arg;
171 memset(v,0,sizeof(*v));
172 v->type=VID_TYPE_TUNER;
173 v->channels=1;
174 v->audios=1;
175 strcpy(v->name, "Aztech Radio");
176 return 0;
177 }
178 case VIDIOCGTUNER:
179 {
180 struct video_tuner *v = arg;
181 if(v->tuner) /* Only 1 tuner */
182 return -EINVAL;
183 v->rangelow=(87*16000);
184 v->rangehigh=(108*16000);
185 v->flags=VIDEO_TUNER_LOW;
186 v->mode=VIDEO_MODE_AUTO;
187 v->signal=0xFFFF*az_getsigstr(az);
188 if(az_getstereo(az))
189 v->flags|=VIDEO_TUNER_STEREO_ON;
190 strcpy(v->name, "FM");
191 return 0;
192 }
193 case VIDIOCSTUNER:
194 {
195 struct video_tuner *v = arg;
196 if(v->tuner!=0)
197 return -EINVAL;
198 return 0;
199 }
200 case VIDIOCGFREQ:
201 {
202 unsigned long *freq = arg;
203 *freq = az->curfreq;
204 return 0;
205 }
206 case VIDIOCSFREQ:
207 {
208 unsigned long *freq = arg;
209 az->curfreq = *freq;
210 az_setfreq(az, az->curfreq);
211 return 0;
212 }
213 case VIDIOCGAUDIO:
214 {
215 struct video_audio *v = arg;
216 memset(v,0, sizeof(*v));
217 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
218 if(az->stereo)
219 v->mode=VIDEO_SOUND_STEREO;
220 else
221 v->mode=VIDEO_SOUND_MONO;
222 v->volume=az->curvol;
223 v->step=16384;
224 strcpy(v->name, "Radio");
225 return 0;
226 }
227 case VIDIOCSAUDIO:
228 {
229 struct video_audio *v = arg;
230 if(v->audio)
231 return -EINVAL;
232 az->curvol=v->volume;
233
234 az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0;
235 if(v->flags&VIDEO_AUDIO_MUTE)
236 az_setvol(az,0);
237 else
238 az_setvol(az,az->curvol);
239 return 0;
240 }
241 default:
242 return -ENOIOCTLCMD;
243 }
244}
245
246static int az_ioctl(struct inode *inode, struct file *file,
247 unsigned int cmd, unsigned long arg)
248{
249 return video_usercopy(inode, file, cmd, arg, az_do_ioctl);
250}
251
252static struct az_device aztech_unit;
253
254static struct file_operations aztech_fops = {
255 .owner = THIS_MODULE,
256 .open = video_exclusive_open,
257 .release = video_exclusive_release,
258 .ioctl = az_ioctl,
259 .llseek = no_llseek,
260};
261
262static struct video_device aztech_radio=
263{
264 .owner = THIS_MODULE,
265 .name = "Aztech radio",
266 .type = VID_TYPE_TUNER,
267 .hardware = VID_HARDWARE_AZTECH,
268 .fops = &aztech_fops,
269};
270
271static int __init aztech_init(void)
272{
273 if(io==-1)
274 {
275 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
276 return -EINVAL;
277 }
278
279 if (!request_region(io, 2, "aztech"))
280 {
281 printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
282 return -EBUSY;
283 }
284
285 init_MUTEX(&lock);
286 aztech_radio.priv=&aztech_unit;
287
288 if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
289 {
290 release_region(io,2);
291 return -EINVAL;
292 }
293
294 printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
295 /* mute card - prevents noisy bootups */
296 outb (0, io);
297 return 0;
298}
299
300MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
301MODULE_DESCRIPTION("A driver for the Aztech radio card.");
302MODULE_LICENSE("GPL");
303
304module_param(io, int, 0);
305module_param(radio_nr, int, 0);
306MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
307
308static void __exit aztech_cleanup(void)
309{
310 video_unregister_device(&aztech_radio);
311 release_region(io,2);
312}
313
314module_init(aztech_init);
315module_exit(aztech_cleanup);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
new file mode 100644
index 000000000000..53d399b6652b
--- /dev/null
+++ b/drivers/media/radio/radio-cadet.c
@@ -0,0 +1,620 @@
1/* radio-cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card
2 *
3 * by Fred Gleason <fredg@wava.com>
4 * Version 0.3.3
5 *
6 * (Loosely) based on code for the Aztech radio card by
7 *
8 * Russell Kroll (rkroll@exploits.org)
9 * Quay Ly
10 * Donald Song
11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
14 *
15 * History:
16 * 2000-04-29 Russell Kroll <rkroll@exploits.org>
17 * Added ISAPnP detection for Linux 2.3/2.4
18 *
19 * 2001-01-10 Russell Kroll <rkroll@exploits.org>
20 * Removed dead CONFIG_RADIO_CADET_PORT code
21 * PnP detection on load is now default (no args necessary)
22 *
23 * 2002-01-17 Adam Belay <ambx1@neo.rr.com>
24 * Updated to latest pnp code
25 *
26 * 2003-01-31 Alan Cox <alan@redhat.com>
27 * Cleaned up locking, delay code, general odds and ends
28 */
29
30#include <linux/module.h> /* Modules */
31#include <linux/init.h> /* Initdata */
32#include <linux/ioport.h> /* check_region, request_region */
33#include <linux/delay.h> /* udelay */
34#include <asm/io.h> /* outb, outb_p */
35#include <asm/uaccess.h> /* copy to/from user */
36#include <linux/videodev.h> /* kernel radio structs */
37#include <linux/param.h>
38#include <linux/pnp.h>
39
40#define RDS_BUFFER 256
41
42static int io=-1; /* default to isapnp activation */
43static int radio_nr = -1;
44static int users=0;
45static int curtuner=0;
46static int tunestat=0;
47static int sigstrength=0;
48static wait_queue_head_t read_queue;
49static struct timer_list readtimer;
50static __u8 rdsin=0,rdsout=0,rdsstat=0;
51static unsigned char rdsbuf[RDS_BUFFER];
52static spinlock_t cadet_io_lock;
53
54static int cadet_probe(void);
55
56/*
57 * Signal Strength Threshold Values
58 * The V4L API spec does not define any particular unit for the signal
59 * strength value. These values are in microvolts of RF at the tuner's input.
60 */
61static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
62
63static int cadet_getrds(void)
64{
65 int rdsstat=0;
66
67 spin_lock(&cadet_io_lock);
68 outb(3,io); /* Select Decoder Control/Status */
69 outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */
70 spin_unlock(&cadet_io_lock);
71
72 msleep(100);
73
74 spin_lock(&cadet_io_lock);
75 outb(3,io); /* Select Decoder Control/Status */
76 if((inb(io+1)&0x80)!=0) {
77 rdsstat|=VIDEO_TUNER_RDS_ON;
78 }
79 if((inb(io+1)&0x10)!=0) {
80 rdsstat|=VIDEO_TUNER_MBS_ON;
81 }
82 spin_unlock(&cadet_io_lock);
83 return rdsstat;
84}
85
86static int cadet_getstereo(void)
87{
88 int ret = 0;
89 if(curtuner != 0) /* Only FM has stereo capability! */
90 return 0;
91
92 spin_lock(&cadet_io_lock);
93 outb(7,io); /* Select tuner control */
94 if( (inb(io+1) & 0x40) == 0)
95 ret = 1;
96 spin_unlock(&cadet_io_lock);
97 return ret;
98}
99
100static unsigned cadet_gettune(void)
101{
102 int curvol,i;
103 unsigned fifo=0;
104
105 /*
106 * Prepare for read
107 */
108
109 spin_lock(&cadet_io_lock);
110
111 outb(7,io); /* Select tuner control */
112 curvol=inb(io+1); /* Save current volume/mute setting */
113 outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */
114 tunestat=0xffff;
115
116 /*
117 * Read the shift register
118 */
119 for(i=0;i<25;i++) {
120 fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
121 if(i<24) {
122 outb(0x01,io+1);
123 tunestat&=inb(io+1);
124 outb(0x00,io+1);
125 }
126 }
127
128 /*
129 * Restore volume/mute setting
130 */
131 outb(curvol,io+1);
132 spin_unlock(&cadet_io_lock);
133
134 return fifo;
135}
136
137static unsigned cadet_getfreq(void)
138{
139 int i;
140 unsigned freq=0,test,fifo=0;
141
142 /*
143 * Read current tuning
144 */
145 fifo=cadet_gettune();
146
147 /*
148 * Convert to actual frequency
149 */
150 if(curtuner==0) { /* FM */
151 test=12500;
152 for(i=0;i<14;i++) {
153 if((fifo&0x01)!=0) {
154 freq+=test;
155 }
156 test=test<<1;
157 fifo=fifo>>1;
158 }
159 freq-=10700000; /* IF frequency is 10.7 MHz */
160 freq=(freq*16)/1000000; /* Make it 1/16 MHz */
161 }
162 if(curtuner==1) { /* AM */
163 freq=((fifo&0x7fff)-2010)*16;
164 }
165
166 return freq;
167}
168
169static void cadet_settune(unsigned fifo)
170{
171 int i;
172 unsigned test;
173
174 spin_lock(&cadet_io_lock);
175
176 outb(7,io); /* Select tuner control */
177 /*
178 * Write the shift register
179 */
180 test=0;
181 test=(fifo>>23)&0x02; /* Align data for SDO */
182 test|=0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
183 outb(7,io); /* Select tuner control */
184 outb(test,io+1); /* Initialize for write */
185 for(i=0;i<25;i++) {
186 test|=0x01; /* Toggle SCK High */
187 outb(test,io+1);
188 test&=0xfe; /* Toggle SCK Low */
189 outb(test,io+1);
190 fifo=fifo<<1; /* Prepare the next bit */
191 test=0x1c|((fifo>>23)&0x02);
192 outb(test,io+1);
193 }
194 spin_unlock(&cadet_io_lock);
195}
196
197static void cadet_setfreq(unsigned freq)
198{
199 unsigned fifo;
200 int i,j,test;
201 int curvol;
202
203 /*
204 * Formulate a fifo command
205 */
206 fifo=0;
207 if(curtuner==0) { /* FM */
208 test=102400;
209 freq=(freq*1000)/16; /* Make it kHz */
210 freq+=10700; /* IF is 10700 kHz */
211 for(i=0;i<14;i++) {
212 fifo=fifo<<1;
213 if(freq>=test) {
214 fifo|=0x01;
215 freq-=test;
216 }
217 test=test>>1;
218 }
219 }
220 if(curtuner==1) { /* AM */
221 fifo=(freq/16)+2010; /* Make it kHz */
222 fifo|=0x100000; /* Select AM Band */
223 }
224
225 /*
226 * Save current volume/mute setting
227 */
228
229 spin_lock(&cadet_io_lock);
230 outb(7,io); /* Select tuner control */
231 curvol=inb(io+1);
232 spin_unlock(&cadet_io_lock);
233
234 /*
235 * Tune the card
236 */
237 for(j=3;j>-1;j--) {
238 cadet_settune(fifo|(j<<16));
239
240 spin_lock(&cadet_io_lock);
241 outb(7,io); /* Select tuner control */
242 outb(curvol,io+1);
243 spin_unlock(&cadet_io_lock);
244
245 msleep(100);
246
247 cadet_gettune();
248 if((tunestat & 0x40) == 0) { /* Tuned */
249 sigstrength=sigtable[curtuner][j];
250 return;
251 }
252 }
253 sigstrength=0;
254}
255
256
257static int cadet_getvol(void)
258{
259 int ret = 0;
260
261 spin_lock(&cadet_io_lock);
262
263 outb(7,io); /* Select tuner control */
264 if((inb(io + 1) & 0x20) != 0)
265 ret = 0xffff;
266
267 spin_unlock(&cadet_io_lock);
268 return ret;
269}
270
271
272static void cadet_setvol(int vol)
273{
274 spin_lock(&cadet_io_lock);
275 outb(7,io); /* Select tuner control */
276 if(vol>0)
277 outb(0x20,io+1);
278 else
279 outb(0x00,io+1);
280 spin_unlock(&cadet_io_lock);
281}
282
283static void cadet_handler(unsigned long data)
284{
285 /*
286 * Service the RDS fifo
287 */
288
289 if(spin_trylock(&cadet_io_lock))
290 {
291 outb(0x3,io); /* Select RDS Decoder Control */
292 if((inb(io+1)&0x20)!=0) {
293 printk(KERN_CRIT "cadet: RDS fifo overflow\n");
294 }
295 outb(0x80,io); /* Select RDS fifo */
296 while((inb(io)&0x80)!=0) {
297 rdsbuf[rdsin]=inb(io+1);
298 if(rdsin==rdsout)
299 printk(KERN_WARNING "cadet: RDS buffer overflow\n");
300 else
301 rdsin++;
302 }
303 spin_unlock(&cadet_io_lock);
304 }
305
306 /*
307 * Service pending read
308 */
309 if( rdsin!=rdsout)
310 wake_up_interruptible(&read_queue);
311
312 /*
313 * Clean up and exit
314 */
315 init_timer(&readtimer);
316 readtimer.function=cadet_handler;
317 readtimer.data=(unsigned long)0;
318 readtimer.expires=jiffies+(HZ/20);
319 add_timer(&readtimer);
320}
321
322
323
324static ssize_t cadet_read(struct file *file, char __user *data,
325 size_t count, loff_t *ppos)
326{
327 int i=0;
328 unsigned char readbuf[RDS_BUFFER];
329
330 if(rdsstat==0) {
331 spin_lock(&cadet_io_lock);
332 rdsstat=1;
333 outb(0x80,io); /* Select RDS fifo */
334 spin_unlock(&cadet_io_lock);
335 init_timer(&readtimer);
336 readtimer.function=cadet_handler;
337 readtimer.data=(unsigned long)0;
338 readtimer.expires=jiffies+(HZ/20);
339 add_timer(&readtimer);
340 }
341 if(rdsin==rdsout) {
342 if (file->f_flags & O_NONBLOCK)
343 return -EWOULDBLOCK;
344 interruptible_sleep_on(&read_queue);
345 }
346 while( i<count && rdsin!=rdsout)
347 readbuf[i++]=rdsbuf[rdsout++];
348
349 if (copy_to_user(data,readbuf,i))
350 return -EFAULT;
351 return i;
352}
353
354
355
356static int cadet_do_ioctl(struct inode *inode, struct file *file,
357 unsigned int cmd, void *arg)
358{
359 switch(cmd)
360 {
361 case VIDIOCGCAP:
362 {
363 struct video_capability *v = arg;
364 memset(v,0,sizeof(*v));
365 v->type=VID_TYPE_TUNER;
366 v->channels=2;
367 v->audios=1;
368 strcpy(v->name, "ADS Cadet");
369 return 0;
370 }
371 case VIDIOCGTUNER:
372 {
373 struct video_tuner *v = arg;
374 if((v->tuner<0)||(v->tuner>1)) {
375 return -EINVAL;
376 }
377 switch(v->tuner) {
378 case 0:
379 strcpy(v->name,"FM");
380 v->rangelow=1400; /* 87.5 MHz */
381 v->rangehigh=1728; /* 108.0 MHz */
382 v->flags=0;
383 v->mode=0;
384 v->mode|=VIDEO_MODE_AUTO;
385 v->signal=sigstrength;
386 if(cadet_getstereo()==1) {
387 v->flags|=VIDEO_TUNER_STEREO_ON;
388 }
389 v->flags|=cadet_getrds();
390 break;
391 case 1:
392 strcpy(v->name,"AM");
393 v->rangelow=8320; /* 520 kHz */
394 v->rangehigh=26400; /* 1650 kHz */
395 v->flags=0;
396 v->flags|=VIDEO_TUNER_LOW;
397 v->mode=0;
398 v->mode|=VIDEO_MODE_AUTO;
399 v->signal=sigstrength;
400 break;
401 }
402 return 0;
403 }
404 case VIDIOCSTUNER:
405 {
406 struct video_tuner *v = arg;
407 if((v->tuner<0)||(v->tuner>1)) {
408 return -EINVAL;
409 }
410 curtuner=v->tuner;
411 return 0;
412 }
413 case VIDIOCGFREQ:
414 {
415 unsigned long *freq = arg;
416 *freq = cadet_getfreq();
417 return 0;
418 }
419 case VIDIOCSFREQ:
420 {
421 unsigned long *freq = arg;
422 if((curtuner==0)&&((*freq<1400)||(*freq>1728))) {
423 return -EINVAL;
424 }
425 if((curtuner==1)&&((*freq<8320)||(*freq>26400))) {
426 return -EINVAL;
427 }
428 cadet_setfreq(*freq);
429 return 0;
430 }
431 case VIDIOCGAUDIO:
432 {
433 struct video_audio *v = arg;
434 memset(v,0, sizeof(*v));
435 v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
436 if(cadet_getstereo()==0) {
437 v->mode=VIDEO_SOUND_MONO;
438 } else {
439 v->mode=VIDEO_SOUND_STEREO;
440 }
441 v->volume=cadet_getvol();
442 v->step=0xffff;
443 strcpy(v->name, "Radio");
444 return 0;
445 }
446 case VIDIOCSAUDIO:
447 {
448 struct video_audio *v = arg;
449 if(v->audio)
450 return -EINVAL;
451 cadet_setvol(v->volume);
452 if(v->flags&VIDEO_AUDIO_MUTE)
453 cadet_setvol(0);
454 else
455 cadet_setvol(0xffff);
456 return 0;
457 }
458 default:
459 return -ENOIOCTLCMD;
460 }
461}
462
463static int cadet_ioctl(struct inode *inode, struct file *file,
464 unsigned int cmd, unsigned long arg)
465{
466 return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
467}
468
469static int cadet_open(struct inode *inode, struct file *file)
470{
471 if(users)
472 return -EBUSY;
473 users++;
474 init_waitqueue_head(&read_queue);
475 return 0;
476}
477
478static int cadet_release(struct inode *inode, struct file *file)
479{
480 del_timer_sync(&readtimer);
481 rdsstat=0;
482 users--;
483 return 0;
484}
485
486
487static struct file_operations cadet_fops = {
488 .owner = THIS_MODULE,
489 .open = cadet_open,
490 .release = cadet_release,
491 .read = cadet_read,
492 .ioctl = cadet_ioctl,
493 .llseek = no_llseek,
494};
495
496static struct video_device cadet_radio=
497{
498 .owner = THIS_MODULE,
499 .name = "Cadet radio",
500 .type = VID_TYPE_TUNER,
501 .hardware = VID_HARDWARE_CADET,
502 .fops = &cadet_fops,
503};
504
505static struct pnp_device_id cadet_pnp_devices[] = {
506 /* ADS Cadet AM/FM Radio Card */
507 {.id = "MSM0c24", .driver_data = 0},
508 {.id = ""}
509};
510
511MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
512
513static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
514{
515 if (!dev)
516 return -ENODEV;
517 /* only support one device */
518 if (io > 0)
519 return -EBUSY;
520
521 if (!pnp_port_valid(dev, 0)) {
522 return -ENODEV;
523 }
524
525 io = pnp_port_start(dev, 0);
526
527 printk ("radio-cadet: PnP reports device at %#x\n", io);
528
529 return io;
530}
531
532static struct pnp_driver cadet_pnp_driver = {
533 .name = "radio-cadet",
534 .id_table = cadet_pnp_devices,
535 .probe = cadet_pnp_probe,
536 .remove = NULL,
537};
538
539static int cadet_probe(void)
540{
541 static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
542 int i;
543
544 for(i=0;i<8;i++) {
545 io=iovals[i];
546 if(request_region(io,2, "cadet-probe")>=0) {
547 cadet_setfreq(1410);
548 if(cadet_getfreq()==1410) {
549 release_region(io, 2);
550 return io;
551 }
552 release_region(io, 2);
553 }
554 }
555 return -1;
556}
557
558/*
559 * io should only be set if the user has used something like
560 * isapnp (the userspace program) to initialize this card for us
561 */
562
563static int __init cadet_init(void)
564{
565 spin_lock_init(&cadet_io_lock);
566
567 /*
568 * If a probe was requested then probe ISAPnP first (safest)
569 */
570 if (io < 0)
571 pnp_register_driver(&cadet_pnp_driver);
572 /*
573 * If that fails then probe unsafely if probe is requested
574 */
575 if(io < 0)
576 io = cadet_probe ();
577
578 /*
579 * Else we bail out
580 */
581
582 if(io < 0) {
583#ifdef MODULE
584 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
585#endif
586 goto fail;
587 }
588 if (!request_region(io,2,"cadet"))
589 goto fail;
590 if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) {
591 release_region(io,2);
592 goto fail;
593 }
594 printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
595 return 0;
596fail:
597 pnp_unregister_driver(&cadet_pnp_driver);
598 return -1;
599}
600
601
602
603MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
604MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
605MODULE_LICENSE("GPL");
606
607module_param(io, int, 0);
608MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
609module_param(radio_nr, int, 0);
610
611static void __exit cadet_cleanup_module(void)
612{
613 video_unregister_device(&cadet_radio);
614 release_region(io,2);
615 pnp_unregister_driver(&cadet_pnp_driver);
616}
617
618module_init(cadet_init);
619module_exit(cadet_cleanup_module);
620
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
new file mode 100644
index 000000000000..630cc786d0a4
--- /dev/null
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -0,0 +1,416 @@
1/*
2 ***************************************************************************
3 *
4 * radio-gemtek-pci.c - Gemtek PCI Radio driver
5 * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru>
6 *
7 ***************************************************************************
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (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
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
22 * USA.
23 *
24 ***************************************************************************
25 *
26 * Gemtek Corp still silently refuses to release any specifications
27 * of their multimedia devices, so the protocol still has to be
28 * reverse engineered.
29 *
30 * The v4l code was inspired by Jonas Munsin's Gemtek serial line
31 * radio device driver.
32 *
33 * Please, let me know if this piece of code was useful :)
34 *
35 * TODO: multiple device support and portability were not tested
36 *
37 ***************************************************************************
38 */
39
40#include <linux/config.h>
41#include <linux/types.h>
42#include <linux/list.h>
43#include <linux/module.h>
44#include <linux/init.h>
45#include <linux/pci.h>
46#include <linux/videodev.h>
47#include <linux/errno.h>
48
49#include <asm/io.h>
50#include <asm/uaccess.h>
51
52#ifndef PCI_VENDOR_ID_GEMTEK
53#define PCI_VENDOR_ID_GEMTEK 0x5046
54#endif
55
56#ifndef PCI_DEVICE_ID_GEMTEK_PR103
57#define PCI_DEVICE_ID_GEMTEK_PR103 0x1001
58#endif
59
60#ifndef GEMTEK_PCI_RANGE_LOW
61#define GEMTEK_PCI_RANGE_LOW (87*16000)
62#endif
63
64#ifndef GEMTEK_PCI_RANGE_HIGH
65#define GEMTEK_PCI_RANGE_HIGH (108*16000)
66#endif
67
68#ifndef TRUE
69#define TRUE (1)
70#endif
71
72#ifndef FALSE
73#define FALSE (0)
74#endif
75
76struct gemtek_pci_card {
77 struct video_device *videodev;
78
79 u32 iobase;
80 u32 length;
81 u8 chiprev;
82 u16 model;
83
84 u32 current_frequency;
85 u8 mute;
86};
87
88static const char rcsid[] = "$Id: radio-gemtek-pci.c,v 1.1 2001/07/23 08:08:16 ted Exp ted $";
89
90static int nr_radio = -1;
91
92static inline u8 gemtek_pci_out( u16 value, u32 port )
93{
94 outw( value, port );
95
96 return (u8)value;
97}
98
99#define _b0( v ) *((u8 *)&v)
100static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
101{
102 register u8 byte = *last_byte;
103
104 if ( !value ) {
105 if ( !keep )
106 value = (u16)port;
107 byte &= 0xfd;
108 } else
109 byte |= 2;
110
111 _b0( value ) = byte;
112 outw( value, port );
113 byte |= 1;
114 _b0( value ) = byte;
115 outw( value, port );
116 byte &= 0xfe;
117 _b0( value ) = byte;
118 outw( value, port );
119
120 *last_byte = byte;
121}
122
123static inline void gemtek_pci_nil( u32 port, u8 *last_byte )
124{
125 __gemtek_pci_cmd( 0x00, port, last_byte, FALSE );
126}
127
128static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte )
129{
130 __gemtek_pci_cmd( cmd, port, last_byte, TRUE );
131}
132
133static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency )
134{
135 register int i;
136 register u32 value = frequency / 200 + 856;
137 register u16 mask = 0x8000;
138 u8 last_byte;
139 u32 port = card->iobase;
140
141 last_byte = gemtek_pci_out( 0x06, port );
142
143 i = 0;
144 do {
145 gemtek_pci_nil( port, &last_byte );
146 i++;
147 } while ( i < 9 );
148
149 i = 0;
150 do {
151 gemtek_pci_cmd( value & mask, port, &last_byte );
152 mask >>= 1;
153 i++;
154 } while ( i < 16 );
155
156 outw( 0x10, port );
157}
158
159
160static inline void gemtek_pci_mute( struct gemtek_pci_card *card )
161{
162 outb( 0x1f, card->iobase );
163 card->mute = TRUE;
164}
165
166static inline void gemtek_pci_unmute( struct gemtek_pci_card *card )
167{
168 if ( card->mute ) {
169 gemtek_pci_setfrequency( card, card->current_frequency );
170 card->mute = FALSE;
171 }
172}
173
174static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
175{
176 return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
177}
178
179static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
180 unsigned int cmd, void *arg)
181{
182 struct video_device *dev = video_devdata(file);
183 struct gemtek_pci_card *card = dev->priv;
184
185 switch ( cmd ) {
186 case VIDIOCGCAP:
187 {
188 struct video_capability *c = arg;
189
190 memset(c,0,sizeof(*c));
191 c->type = VID_TYPE_TUNER;
192 c->channels = 1;
193 c->audios = 1;
194 strcpy( c->name, "Gemtek PCI Radio" );
195 return 0;
196 }
197
198 case VIDIOCGTUNER:
199 {
200 struct video_tuner *t = arg;
201
202 if ( t->tuner )
203 return -EINVAL;
204
205 t->rangelow = GEMTEK_PCI_RANGE_LOW;
206 t->rangehigh = GEMTEK_PCI_RANGE_HIGH;
207 t->flags = VIDEO_TUNER_LOW;
208 t->mode = VIDEO_MODE_AUTO;
209 t->signal = 0xFFFF * gemtek_pci_getsignal( card );
210 strcpy( t->name, "FM" );
211 return 0;
212 }
213
214 case VIDIOCSTUNER:
215 {
216 struct video_tuner *t = arg;
217 if ( t->tuner )
218 return -EINVAL;
219 return 0;
220 }
221
222 case VIDIOCGFREQ:
223 {
224 unsigned long *freq = arg;
225 *freq = card->current_frequency;
226 return 0;
227 }
228 case VIDIOCSFREQ:
229 {
230 unsigned long *freq = arg;
231
232 if ( (*freq < GEMTEK_PCI_RANGE_LOW) ||
233 (*freq > GEMTEK_PCI_RANGE_HIGH) )
234 return -EINVAL;
235
236 gemtek_pci_setfrequency( card, *freq );
237 card->current_frequency = *freq;
238 card->mute = FALSE;
239
240 return 0;
241 }
242
243 case VIDIOCGAUDIO:
244 {
245 struct video_audio *a = arg;
246
247 memset( a, 0, sizeof( *a ) );
248 a->flags |= VIDEO_AUDIO_MUTABLE;
249 a->volume = 1;
250 a->step = 65535;
251 strcpy( a->name, "Radio" );
252 return 0;
253 }
254
255 case VIDIOCSAUDIO:
256 {
257 struct video_audio *a = arg;
258
259 if ( a->audio )
260 return -EINVAL;
261
262 if ( a->flags & VIDEO_AUDIO_MUTE )
263 gemtek_pci_mute( card );
264 else
265 gemtek_pci_unmute( card );
266 return 0;
267 }
268
269 default:
270 return -ENOIOCTLCMD;
271 }
272}
273
274static int gemtek_pci_ioctl(struct inode *inode, struct file *file,
275 unsigned int cmd, unsigned long arg)
276{
277 return video_usercopy(inode, file, cmd, arg, gemtek_pci_do_ioctl);
278}
279
280enum {
281 GEMTEK_PR103
282};
283
284static char *card_names[] __devinitdata = {
285 "GEMTEK_PR103"
286};
287
288static struct pci_device_id gemtek_pci_id[] =
289{
290 { PCI_VENDOR_ID_GEMTEK, PCI_DEVICE_ID_GEMTEK_PR103,
291 PCI_ANY_ID, PCI_ANY_ID, 0, 0, GEMTEK_PR103 },
292 { 0 }
293};
294
295MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
296
297static int mx = 1;
298
299static struct file_operations gemtek_pci_fops = {
300 .owner = THIS_MODULE,
301 .open = video_exclusive_open,
302 .release = video_exclusive_release,
303 .ioctl = gemtek_pci_ioctl,
304 .llseek = no_llseek,
305};
306
307static struct video_device vdev_template = {
308 .owner = THIS_MODULE,
309 .name = "Gemtek PCI Radio",
310 .type = VID_TYPE_TUNER,
311 .hardware = VID_HARDWARE_GEMTEK,
312 .fops = &gemtek_pci_fops,
313};
314
315static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
316{
317 struct gemtek_pci_card *card;
318 struct video_device *devradio;
319
320 if ( (card = kmalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) {
321 printk( KERN_ERR "gemtek_pci: out of memory\n" );
322 return -ENOMEM;
323 }
324 memset( card, 0, sizeof( struct gemtek_pci_card ) );
325
326 if ( pci_enable_device( pci_dev ) )
327 goto err_pci;
328
329 card->iobase = pci_resource_start( pci_dev, 0 );
330 card->length = pci_resource_len( pci_dev, 0 );
331
332 if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) {
333 printk( KERN_ERR "gemtek_pci: i/o port already in use\n" );
334 goto err_pci;
335 }
336
337 pci_read_config_byte( pci_dev, PCI_REVISION_ID, &card->chiprev );
338 pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model );
339
340 pci_set_drvdata( pci_dev, card );
341
342 if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) {
343 printk( KERN_ERR "gemtek_pci: out of memory\n" );
344 goto err_video;
345 }
346 *devradio = vdev_template;
347
348 if ( video_register_device( devradio, VFL_TYPE_RADIO , nr_radio) == -1 ) {
349 kfree( devradio );
350 goto err_video;
351 }
352
353 card->videodev = devradio;
354 devradio->priv = card;
355 gemtek_pci_mute( card );
356
357 printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
358 card->chiprev, card->iobase, card->iobase + card->length - 1 );
359
360 return 0;
361
362err_video:
363 release_region( card->iobase, card->length );
364
365err_pci:
366 kfree( card );
367 return -ENODEV;
368}
369
370static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
371{
372 struct gemtek_pci_card *card = pci_get_drvdata( pci_dev );
373
374 video_unregister_device( card->videodev );
375 kfree( card->videodev );
376
377 release_region( card->iobase, card->length );
378
379 if ( mx )
380 gemtek_pci_mute( card );
381
382 kfree( card );
383
384 pci_set_drvdata( pci_dev, NULL );
385}
386
387static struct pci_driver gemtek_pci_driver =
388{
389 .name = "gemtek_pci",
390 .id_table = gemtek_pci_id,
391 .probe = gemtek_pci_probe,
392 .remove = __devexit_p(gemtek_pci_remove),
393};
394
395static int __init gemtek_pci_init_module( void )
396{
397 return pci_module_init( &gemtek_pci_driver );
398}
399
400static void __exit gemtek_pci_cleanup_module( void )
401{
402 return pci_unregister_driver( &gemtek_pci_driver );
403}
404
405MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" );
406MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
407MODULE_LICENSE("GPL");
408
409module_param(mx, bool, 0);
410MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
411module_param(nr_radio, int, 0);
412MODULE_PARM_DESC( nr_radio, "video4linux device number to use");
413
414module_init( gemtek_pci_init_module );
415module_exit( gemtek_pci_cleanup_module );
416
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
new file mode 100644
index 000000000000..202bfe6819b8
--- /dev/null
+++ b/drivers/media/radio/radio-gemtek.c
@@ -0,0 +1,304 @@
1/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi>
2 *
3 * GemTek hasn't released any specs on the card, so the protocol had to
4 * be reverse engineered with dosemu.
5 *
6 * Besides the protocol changes, this is mostly a copy of:
7 *
8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
9 *
10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
11 * Converted to new API by Alan Cox <Alan.Cox@linux.org>
12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
13 *
14 * TODO: Allow for more than one of these foolish entities :-)
15 *
16 */
17
18#include <linux/module.h> /* Modules */
19#include <linux/init.h> /* Initdata */
20#include <linux/ioport.h> /* check_region, request_region */
21#include <linux/delay.h> /* udelay */
22#include <asm/io.h> /* outb, outb_p */
23#include <asm/uaccess.h> /* copy to/from user */
24#include <linux/videodev.h> /* kernel radio structs */
25#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */
26#include <linux/spinlock.h>
27
28#ifndef CONFIG_RADIO_GEMTEK_PORT
29#define CONFIG_RADIO_GEMTEK_PORT -1
30#endif
31
32static int io = CONFIG_RADIO_GEMTEK_PORT;
33static int radio_nr = -1;
34static spinlock_t lock;
35
36struct gemtek_device
37{
38 int port;
39 unsigned long curfreq;
40 int muted;
41};
42
43
44/* local things */
45
46/* the correct way to mute the gemtek may be to write the last written
47 * frequency || 0x10, but just writing 0x10 once seems to do it as well
48 */
49static void gemtek_mute(struct gemtek_device *dev)
50{
51 if(dev->muted)
52 return;
53 spin_lock(&lock);
54 outb(0x10, io);
55 spin_unlock(&lock);
56 dev->muted = 1;
57}
58
59static void gemtek_unmute(struct gemtek_device *dev)
60{
61 if(dev->muted == 0)
62 return;
63 spin_lock(&lock);
64 outb(0x20, io);
65 spin_unlock(&lock);
66 dev->muted = 0;
67}
68
69static void zero(void)
70{
71 outb_p(0x04, io);
72 udelay(5);
73 outb_p(0x05, io);
74 udelay(5);
75}
76
77static void one(void)
78{
79 outb_p(0x06, io);
80 udelay(5);
81 outb_p(0x07, io);
82 udelay(5);
83}
84
85static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
86{
87 int i;
88
89/* freq = 78.25*((float)freq/16000.0 + 10.52); */
90
91 freq /= 16;
92 freq += 10520;
93 freq *= 7825;
94 freq /= 100000;
95
96 spin_lock(&lock);
97
98 /* 2 start bits */
99 outb_p(0x03, io);
100 udelay(5);
101 outb_p(0x07, io);
102 udelay(5);
103
104 /* 28 frequency bits (lsb first) */
105 for (i = 0; i < 14; i++)
106 if (freq & (1 << i))
107 one();
108 else
109 zero();
110 /* 36 unknown bits */
111 for (i = 0; i < 11; i++)
112 zero();
113 one();
114 for (i = 0; i < 4; i++)
115 zero();
116 one();
117 zero();
118
119 /* 2 end bits */
120 outb_p(0x03, io);
121 udelay(5);
122 outb_p(0x07, io);
123 udelay(5);
124
125 spin_unlock(&lock);
126
127 return 0;
128}
129
130static int gemtek_getsigstr(struct gemtek_device *dev)
131{
132 spin_lock(&lock);
133 inb(io);
134 udelay(5);
135 spin_unlock(&lock);
136 if (inb(io) & 8) /* bit set = no signal present */
137 return 0;
138 return 1; /* signal present */
139}
140
141static int gemtek_do_ioctl(struct inode *inode, struct file *file,
142 unsigned int cmd, void *arg)
143{
144 struct video_device *dev = video_devdata(file);
145 struct gemtek_device *rt=dev->priv;
146
147 switch(cmd)
148 {
149 case VIDIOCGCAP:
150 {
151 struct video_capability *v = arg;
152 memset(v,0,sizeof(*v));
153 v->type=VID_TYPE_TUNER;
154 v->channels=1;
155 v->audios=1;
156 strcpy(v->name, "GemTek");
157 return 0;
158 }
159 case VIDIOCGTUNER:
160 {
161 struct video_tuner *v = arg;
162 if(v->tuner) /* Only 1 tuner */
163 return -EINVAL;
164 v->rangelow=87*16000;
165 v->rangehigh=108*16000;
166 v->flags=VIDEO_TUNER_LOW;
167 v->mode=VIDEO_MODE_AUTO;
168 v->signal=0xFFFF*gemtek_getsigstr(rt);
169 strcpy(v->name, "FM");
170 return 0;
171 }
172 case VIDIOCSTUNER:
173 {
174 struct video_tuner *v = arg;
175 if(v->tuner!=0)
176 return -EINVAL;
177 /* Only 1 tuner so no setting needed ! */
178 return 0;
179 }
180 case VIDIOCGFREQ:
181 {
182 unsigned long *freq = arg;
183 *freq = rt->curfreq;
184 return 0;
185 }
186 case VIDIOCSFREQ:
187 {
188 unsigned long *freq = arg;
189 rt->curfreq = *freq;
190 /* needs to be called twice in order for getsigstr to work */
191 gemtek_setfreq(rt, rt->curfreq);
192 gemtek_setfreq(rt, rt->curfreq);
193 return 0;
194 }
195 case VIDIOCGAUDIO:
196 {
197 struct video_audio *v = arg;
198 memset(v,0, sizeof(*v));
199 v->flags|=VIDEO_AUDIO_MUTABLE;
200 v->volume=1;
201 v->step=65535;
202 strcpy(v->name, "Radio");
203 return 0;
204 }
205 case VIDIOCSAUDIO:
206 {
207 struct video_audio *v = arg;
208 if(v->audio)
209 return -EINVAL;
210
211 if(v->flags&VIDEO_AUDIO_MUTE)
212 gemtek_mute(rt);
213 else
214 gemtek_unmute(rt);
215
216 return 0;
217 }
218 default:
219 return -ENOIOCTLCMD;
220 }
221}
222
223static int gemtek_ioctl(struct inode *inode, struct file *file,
224 unsigned int cmd, unsigned long arg)
225{
226 return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl);
227}
228
229static struct gemtek_device gemtek_unit;
230
231static struct file_operations gemtek_fops = {
232 .owner = THIS_MODULE,
233 .open = video_exclusive_open,
234 .release = video_exclusive_release,
235 .ioctl = gemtek_ioctl,
236 .llseek = no_llseek,
237};
238
239static struct video_device gemtek_radio=
240{
241 .owner = THIS_MODULE,
242 .name = "GemTek radio",
243 .type = VID_TYPE_TUNER,
244 .hardware = VID_HARDWARE_GEMTEK,
245 .fops = &gemtek_fops,
246};
247
248static int __init gemtek_init(void)
249{
250 if(io==-1)
251 {
252 printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (io=0x020c or io=0x248 for the combined sound/radiocard)\n");
253 return -EINVAL;
254 }
255
256 if (!request_region(io, 4, "gemtek"))
257 {
258 printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
259 return -EBUSY;
260 }
261
262 gemtek_radio.priv=&gemtek_unit;
263
264 if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1)
265 {
266 release_region(io, 4);
267 return -EINVAL;
268 }
269 printk(KERN_INFO "GemTek Radio Card driver.\n");
270
271 spin_lock_init(&lock);
272
273 /* this is _maybe_ unnecessary */
274 outb(0x01, io);
275
276 /* mute card - prevents noisy bootups */
277 gemtek_unit.muted = 0;
278 gemtek_mute(&gemtek_unit);
279
280 return 0;
281}
282
283MODULE_AUTHOR("Jonas Munsin");
284MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
285MODULE_LICENSE("GPL");
286
287module_param(io, int, 0);
288MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
289module_param(radio_nr, int, 0);
290
291static void __exit gemtek_cleanup(void)
292{
293 video_unregister_device(&gemtek_radio);
294 release_region(io,4);
295}
296
297module_init(gemtek_init);
298module_exit(gemtek_cleanup);
299
300/*
301 Local variables:
302 compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
303 End:
304*/
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
new file mode 100644
index 000000000000..e62147e4ed1b
--- /dev/null
+++ b/drivers/media/radio/radio-maestro.c
@@ -0,0 +1,332 @@
1/* Maestro PCI sound card radio driver for Linux support
2 * (c) 2000 A. Tlalka, atlka@pg.gda.pl
3 * Notes on the hardware
4 *
5 * + Frequency control is done digitally
6 * + No volume control - only mute/unmute - you have to use Aux line volume
7 * control on Maestro card to set the volume
8 * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
9 * frequency setting (>100ms) and only when the radio is unmuted.
10 * version 0.02
11 * + io port is automatically detected - only the first radio is used
12 * version 0.03
13 * + thread access locking additions
14 * version 0.04
15 * + code improvements
16 * + VIDEO_TUNER_LOW is permanent
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/ioport.h>
22#include <linux/delay.h>
23#include <linux/sched.h>
24#include <asm/io.h>
25#include <asm/uaccess.h>
26#include <asm/semaphore.h>
27#include <linux/pci.h>
28#include <linux/videodev.h>
29
30#define DRIVER_VERSION "0.04"
31
32#define PCI_VENDOR_ESS 0x125D
33#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */
34#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */
35
36#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
37
38#define IO_MASK 4 /* mask register offset from GPIO_DATA
39 bits 1=unmask write to given bit */
40#define IO_DIR 8 /* direction register offset from GPIO_DATA
41 bits 0/1=read/write direction */
42
43#define GPIO6 0x0040 /* mask bits for GPIO lines */
44#define GPIO7 0x0080
45#define GPIO8 0x0100
46#define GPIO9 0x0200
47
48#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
49#define STR_CLK GPIO7
50#define STR_WREN GPIO8
51#define STR_MOST GPIO9
52
53#define FREQ_LO 50*16000
54#define FREQ_HI 150*16000
55
56#define FREQ_IF 171200 /* 10.7*16000 */
57#define FREQ_STEP 200 /* 12.5*16 */
58
59#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
60 /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
61
62#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
63
64static int radio_nr = -1;
65module_param(radio_nr, int, 0);
66
67static int radio_ioctl(struct inode *inode, struct file *file,
68 unsigned int cmd, unsigned long arg);
69
70static struct file_operations maestro_fops = {
71 .owner = THIS_MODULE,
72 .open = video_exclusive_open,
73 .release = video_exclusive_release,
74 .ioctl = radio_ioctl,
75 .llseek = no_llseek,
76};
77
78static struct video_device maestro_radio=
79{
80 .owner = THIS_MODULE,
81 .name = "Maestro radio",
82 .type = VID_TYPE_TUNER,
83 .hardware = VID_HARDWARE_SF16MI,
84 .fops = &maestro_fops,
85};
86
87static struct radio_device
88{
89 __u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
90 muted, /* VIDEO_AUDIO_MUTE */
91 stereo, /* VIDEO_TUNER_STEREO_ON */
92 tuned; /* signal strength (0 or 0xffff) */
93 struct semaphore lock;
94} radio_unit = {0, 0, 0, 0, };
95
96static __u32 radio_bits_get(struct radio_device *dev)
97{
98 register __u16 io=dev->io, l, rdata;
99 register __u32 data=0;
100 __u16 omask;
101 omask = inw(io + IO_MASK);
102 outw(~(STR_CLK | STR_WREN), io + IO_MASK);
103 outw(0, io);
104 udelay(16);
105
106 for (l=24;l--;) {
107 outw(STR_CLK, io); /* HI state */
108 udelay(2);
109 if(!l)
110 dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
111 outw(0, io); /* LO state */
112 udelay(2);
113 data <<= 1; /* shift data */
114 rdata = inw(io);
115 if(!l)
116 dev->stereo = rdata & STR_MOST ?
117 0 : VIDEO_TUNER_STEREO_ON;
118 else
119 if(rdata & STR_DATA)
120 data++;
121 udelay(2);
122 }
123 if(dev->muted)
124 outw(STR_WREN, io);
125 udelay(4);
126 outw(omask, io + IO_MASK);
127 return data & 0x3ffe;
128}
129
130static void radio_bits_set(struct radio_device *dev, __u32 data)
131{
132 register __u16 io=dev->io, l, bits;
133 __u16 omask, odir;
134 omask = inw(io + IO_MASK);
135 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
136 outw(odir | STR_DATA, io + IO_DIR);
137 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
138 udelay(16);
139 for (l=25;l;l--) {
140 bits = ((data >> 18) & STR_DATA) | STR_WREN ;
141 data <<= 1; /* shift data */
142 outw(bits, io); /* start strobe */
143 udelay(2);
144 outw(bits | STR_CLK, io); /* HI level */
145 udelay(2);
146 outw(bits, io); /* LO level */
147 udelay(4);
148 }
149 if(!dev->muted)
150 outw(0, io);
151 udelay(4);
152 outw(omask, io + IO_MASK);
153 outw(odir, io + IO_DIR);
154 msleep(125);
155}
156
157inline static int radio_function(struct inode *inode, struct file *file,
158 unsigned int cmd, void *arg)
159{
160 struct video_device *dev = video_devdata(file);
161 struct radio_device *card=dev->priv;
162
163 switch(cmd) {
164 case VIDIOCGCAP: {
165 struct video_capability *v = arg;
166 memset(v,0,sizeof(*v));
167 strcpy(v->name, "Maestro radio");
168 v->type=VID_TYPE_TUNER;
169 v->channels=v->audios=1;
170 return 0;
171 }
172 case VIDIOCGTUNER: {
173 struct video_tuner *v = arg;
174 if(v->tuner)
175 return -EINVAL;
176 (void)radio_bits_get(card);
177 v->flags = VIDEO_TUNER_LOW | card->stereo;
178 v->signal = card->tuned;
179 strcpy(v->name, "FM");
180 v->rangelow = FREQ_LO;
181 v->rangehigh = FREQ_HI;
182 v->mode = VIDEO_MODE_AUTO;
183 return 0;
184 }
185 case VIDIOCSTUNER: {
186 struct video_tuner *v = arg;
187 if(v->tuner!=0)
188 return -EINVAL;
189 return 0;
190 }
191 case VIDIOCGFREQ: {
192 unsigned long *freq = arg;
193 *freq = BITS2FREQ(radio_bits_get(card));
194 return 0;
195 }
196 case VIDIOCSFREQ: {
197 unsigned long *freq = arg;
198 if (*freq<FREQ_LO || *freq>FREQ_HI )
199 return -EINVAL;
200 radio_bits_set(card, FREQ2BITS(*freq));
201 return 0;
202 }
203 case VIDIOCGAUDIO: {
204 struct video_audio *v = arg;
205 memset(v,0,sizeof(*v));
206 strcpy(v->name, "Radio");
207 v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
208 v->mode=VIDEO_SOUND_STEREO;
209 return 0;
210 }
211 case VIDIOCSAUDIO: {
212 struct video_audio *v = arg;
213 if(v->audio)
214 return -EINVAL;
215 {
216 register __u16 io=card->io;
217 register __u16 omask = inw(io + IO_MASK);
218 outw(~STR_WREN, io + IO_MASK);
219 outw((card->muted = v->flags & VIDEO_AUDIO_MUTE)
220 ? STR_WREN : 0, io);
221 udelay(4);
222 outw(omask, io + IO_MASK);
223 msleep(125);
224 return 0;
225 }
226 }
227 case VIDIOCGUNIT: {
228 struct video_unit *v = arg;
229 v->video=VIDEO_NO_UNIT;
230 v->vbi=VIDEO_NO_UNIT;
231 v->radio=dev->minor;
232 v->audio=0;
233 v->teletext=VIDEO_NO_UNIT;
234 return 0;
235 }
236 default: return -ENOIOCTLCMD;
237 }
238}
239
240static int radio_ioctl(struct inode *inode, struct file *file,
241 unsigned int cmd, unsigned long arg)
242{
243 struct video_device *dev = video_devdata(file);
244 struct radio_device *card=dev->priv;
245 int ret;
246
247 down(&card->lock);
248 ret = video_usercopy(inode, file, cmd, arg, radio_function);
249 up(&card->lock);
250 return ret;
251}
252
253static __u16 radio_install(struct pci_dev *pcidev);
254
255MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
256MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
257MODULE_LICENSE("GPL");
258
259static void __exit maestro_radio_exit(void)
260{
261 video_unregister_device(&maestro_radio);
262}
263
264static int __init maestro_radio_init(void)
265{
266 register __u16 found=0;
267 struct pci_dev *pcidev = NULL;
268 while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
269 PCI_DEVICE_ID_ESS_ESS1968,
270 pcidev)))
271 found |= radio_install(pcidev);
272 while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
273 PCI_DEVICE_ID_ESS_ESS1978,
274 pcidev)))
275 found |= radio_install(pcidev);
276 if(!found) {
277 printk(KERN_INFO "radio-maestro: no devices found.\n");
278 return -ENODEV;
279 }
280 return 0;
281}
282
283module_init(maestro_radio_init);
284module_exit(maestro_radio_exit);
285
286inline static __u16 radio_power_on(struct radio_device *dev)
287{
288 register __u16 io=dev->io;
289 register __u32 ofreq;
290 __u16 omask, odir;
291 omask = inw(io + IO_MASK);
292 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
293 outw(odir & ~STR_WREN, io + IO_DIR);
294 dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE;
295 outw(odir, io + IO_DIR);
296 outw(~(STR_WREN | STR_CLK), io + IO_MASK);
297 outw(dev->muted ? 0 : STR_WREN, io);
298 udelay(16);
299 outw(omask, io + IO_MASK);
300 ofreq = radio_bits_get(dev);
301 if((ofreq<FREQ2BITS(FREQ_LO)) || (ofreq>FREQ2BITS(FREQ_HI)))
302 ofreq = FREQ2BITS(FREQ_LO);
303 radio_bits_set(dev, ofreq);
304 return (ofreq == radio_bits_get(dev));
305}
306
307static __u16 radio_install(struct pci_dev *pcidev)
308{
309 if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
310 return 0;
311
312 radio_unit.io = pcidev->resource[0].start + GPIO_DATA;
313 maestro_radio.priv = &radio_unit;
314 init_MUTEX(&radio_unit.lock);
315
316 if(radio_power_on(&radio_unit)) {
317 if(video_register_device(&maestro_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
318 printk("radio-maestro: can't register device!");
319 return 0;
320 }
321 printk(KERN_INFO "radio-maestro: version "
322 DRIVER_VERSION
323 " time "
324 __TIME__ " "
325 __DATE__
326 "\n");
327 printk(KERN_INFO "radio-maestro: radio chip initialized\n");
328 return 1;
329 } else
330 return 0;
331}
332
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
new file mode 100644
index 000000000000..5b748a48ce72
--- /dev/null
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -0,0 +1,349 @@
1/*
2 * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux
3 * (C) 2001 Dimitromanolakis Apostolos <apdim@grecian.net>
4 *
5 * Based in the radio Maestro PCI driver. Actually it uses the same chip
6 * for radio but different pci controller.
7 *
8 * I didn't have any specs I reversed engineered the protocol from
9 * the windows driver (radio.dll).
10 *
11 * The card uses the TEA5757 chip that includes a search function but it
12 * is useless as I haven't found any way to read back the frequency. If
13 * anybody does please mail me.
14 *
15 * For the pdf file see:
16 * http://www.semiconductors.philips.com/pip/TEA5757H/V1
17 *
18 *
19 * CHANGES:
20 * 0.75b
21 * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr>
22 *
23 * 0.75
24 * - tiding up
25 * - removed support for multiple devices as it didn't work anyway
26 *
27 * BUGS:
28 * - card unmutes if you change frequency
29 *
30 */
31
32
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/ioport.h>
36#include <linux/delay.h>
37#include <linux/sched.h>
38#include <asm/io.h>
39#include <asm/uaccess.h>
40#include <asm/semaphore.h>
41#include <linux/pci.h>
42#include <linux/videodev.h>
43
44/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */
45#define DRIVER_VERSION "0.75"
46
47#ifndef PCI_VENDOR_ID_GUILLEMOT
48#define PCI_VENDOR_ID_GUILLEMOT 0x5046
49#endif
50
51#ifndef PCI_DEVICE_ID_GUILLEMOT
52#define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
53#endif
54
55
56/* TEA5757 pin mappings */
57static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
58
59static int radio_nr = -1;
60module_param(radio_nr, int, 0);
61
62
63#define FREQ_LO 50*16000
64#define FREQ_HI 150*16000
65
66#define FREQ_IF 171200 /* 10.7*16000 */
67#define FREQ_STEP 200 /* 12.5*16 */
68
69#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
70 /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
71
72#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
73
74
75static int radio_ioctl(struct inode *inode, struct file *file,
76 unsigned int cmd, unsigned long arg);
77
78static struct file_operations maxiradio_fops = {
79 .owner = THIS_MODULE,
80 .open = video_exclusive_open,
81 .release = video_exclusive_release,
82 .ioctl = radio_ioctl,
83 .llseek = no_llseek,
84};
85static struct video_device maxiradio_radio =
86{
87 .owner = THIS_MODULE,
88 .name = "Maxi Radio FM2000 radio",
89 .type = VID_TYPE_TUNER,
90 .hardware = VID_HARDWARE_SF16MI,
91 .fops = &maxiradio_fops,
92};
93
94static struct radio_device
95{
96 __u16 io, /* base of radio io */
97 muted, /* VIDEO_AUDIO_MUTE */
98 stereo, /* VIDEO_TUNER_STEREO_ON */
99 tuned; /* signal strength (0 or 0xffff) */
100
101 unsigned long freq;
102
103 struct semaphore lock;
104} radio_unit = {0, 0, 0, 0, };
105
106
107static void outbit(unsigned long bit, __u16 io)
108{
109 if(bit != 0)
110 {
111 outb( power|wren|data ,io); udelay(4);
112 outb( power|wren|data|clk ,io); udelay(4);
113 outb( power|wren|data ,io); udelay(4);
114 }
115 else
116 {
117 outb( power|wren ,io); udelay(4);
118 outb( power|wren|clk ,io); udelay(4);
119 outb( power|wren ,io); udelay(4);
120 }
121}
122
123static void turn_power(__u16 io, int p)
124{
125 if(p != 0) outb(power, io); else outb(0,io);
126}
127
128
129static void set_freq(__u16 io, __u32 data)
130{
131 unsigned long int si;
132 int bl;
133
134 /* TEA5757 shift register bits (see pdf) */
135
136 outbit(0,io); // 24 search
137 outbit(1,io); // 23 search up/down
138
139 outbit(0,io); // 22 stereo/mono
140
141 outbit(0,io); // 21 band
142 outbit(0,io); // 20 band (only 00=FM works I think)
143
144 outbit(0,io); // 19 port ?
145 outbit(0,io); // 18 port ?
146
147 outbit(0,io); // 17 search level
148 outbit(0,io); // 16 search level
149
150 si = 0x8000;
151 for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; }
152
153 outb(power,io);
154}
155
156static int get_stereo(__u16 io)
157{
158 outb(power,io); udelay(4);
159 return !(inb(io) & mo_st);
160}
161
162static int get_tune(__u16 io)
163{
164 outb(power+clk,io); udelay(4);
165 return !(inb(io) & mo_st);
166}
167
168
169inline static int radio_function(struct inode *inode, struct file *file,
170 unsigned int cmd, void *arg)
171{
172 struct video_device *dev = video_devdata(file);
173 struct radio_device *card=dev->priv;
174
175 switch(cmd) {
176 case VIDIOCGCAP: {
177 struct video_capability *v = arg;
178
179 memset(v,0,sizeof(*v));
180 strcpy(v->name, "Maxi Radio FM2000 radio");
181 v->type=VID_TYPE_TUNER;
182 v->channels=v->audios=1;
183 return 0;
184 }
185 case VIDIOCGTUNER: {
186 struct video_tuner *v = arg;
187
188 if(v->tuner)
189 return -EINVAL;
190
191 card->stereo = 0xffff * get_stereo(card->io);
192 card->tuned = 0xffff * get_tune(card->io);
193
194 v->flags = VIDEO_TUNER_LOW | card->stereo;
195 v->signal = card->tuned;
196
197 strcpy(v->name, "FM");
198
199 v->rangelow = FREQ_LO;
200 v->rangehigh = FREQ_HI;
201 v->mode = VIDEO_MODE_AUTO;
202
203 return 0;
204 }
205 case VIDIOCSTUNER: {
206 struct video_tuner *v = arg;
207 if(v->tuner!=0)
208 return -EINVAL;
209 return 0;
210 }
211 case VIDIOCGFREQ: {
212 unsigned long *freq = arg;
213
214 *freq = card->freq;
215 return 0;
216 }
217 case VIDIOCSFREQ: {
218 unsigned long *freq = arg;
219
220 if (*freq < FREQ_LO || *freq > FREQ_HI)
221 return -EINVAL;
222 card->freq = *freq;
223 set_freq(card->io, FREQ2BITS(card->freq));
224 msleep(125);
225 return 0;
226 }
227 case VIDIOCGAUDIO: {
228 struct video_audio *v = arg;
229 memset(v,0,sizeof(*v));
230 strcpy(v->name, "Radio");
231 v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
232 v->mode=VIDEO_SOUND_STEREO;
233 return 0;
234 }
235
236 case VIDIOCSAUDIO: {
237 struct video_audio *v = arg;
238
239 if(v->audio)
240 return -EINVAL;
241 card->muted = v->flags & VIDEO_AUDIO_MUTE;
242 if(card->muted)
243 turn_power(card->io, 0);
244 else
245 set_freq(card->io, FREQ2BITS(card->freq));
246 return 0;
247 }
248 case VIDIOCGUNIT: {
249 struct video_unit *v = arg;
250
251 v->video=VIDEO_NO_UNIT;
252 v->vbi=VIDEO_NO_UNIT;
253 v->radio=dev->minor;
254 v->audio=0;
255 v->teletext=VIDEO_NO_UNIT;
256 return 0;
257 }
258 default: return -ENOIOCTLCMD;
259 }
260}
261
262static int radio_ioctl(struct inode *inode, struct file *file,
263 unsigned int cmd, unsigned long arg)
264{
265 struct video_device *dev = video_devdata(file);
266 struct radio_device *card=dev->priv;
267 int ret;
268
269 down(&card->lock);
270 ret = video_usercopy(inode, file, cmd, arg, radio_function);
271 up(&card->lock);
272 return ret;
273}
274
275MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
276MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
277MODULE_LICENSE("GPL");
278
279
280static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
281{
282 if(!request_region(pci_resource_start(pdev, 0),
283 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
284 printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
285 goto err_out;
286 }
287
288 if (pci_enable_device(pdev))
289 goto err_out_free_region;
290
291 radio_unit.io = pci_resource_start(pdev, 0);
292 init_MUTEX(&radio_unit.lock);
293 maxiradio_radio.priv = &radio_unit;
294
295 if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
296 printk("radio-maxiradio: can't register device!");
297 goto err_out_free_region;
298 }
299
300 printk(KERN_INFO "radio-maxiradio: version "
301 DRIVER_VERSION
302 " time "
303 __TIME__ " "
304 __DATE__
305 "\n");
306
307 printk(KERN_INFO "radio-maxiradio: found Guillemot MAXI Radio device (io = 0x%x)\n",
308 radio_unit.io);
309 return 0;
310
311err_out_free_region:
312 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
313err_out:
314 return -ENODEV;
315}
316
317static void __devexit maxiradio_remove_one(struct pci_dev *pdev)
318{
319 video_unregister_device(&maxiradio_radio);
320 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
321}
322
323static struct pci_device_id maxiradio_pci_tbl[] = {
324 { PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO,
325 PCI_ANY_ID, PCI_ANY_ID, },
326 { 0,}
327};
328
329MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
330
331static struct pci_driver maxiradio_driver = {
332 .name = "radio-maxiradio",
333 .id_table = maxiradio_pci_tbl,
334 .probe = maxiradio_init_one,
335 .remove = __devexit_p(maxiradio_remove_one),
336};
337
338static int __init maxiradio_radio_init(void)
339{
340 return pci_module_init(&maxiradio_driver);
341}
342
343static void __exit maxiradio_radio_exit(void)
344{
345 pci_unregister_driver(&maxiradio_driver);
346}
347
348module_init(maxiradio_radio_init);
349module_exit(maxiradio_radio_exit);
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
new file mode 100644
index 000000000000..c00245d4d249
--- /dev/null
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -0,0 +1,266 @@
1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
2 *
3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
4 * Converted to new API by Alan Cox <Alan.Cox@linux.org>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 *
7 * TODO: Allow for more than one of these foolish entities :-)
8 *
9 */
10
11#include <linux/module.h> /* Modules */
12#include <linux/init.h> /* Initdata */
13#include <linux/ioport.h> /* check_region, request_region */
14#include <linux/delay.h> /* udelay */
15#include <asm/io.h> /* outb, outb_p */
16#include <asm/uaccess.h> /* copy to/from user */
17#include <linux/videodev.h> /* kernel radio structs */
18#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
19#include <linux/spinlock.h>
20
21#ifndef CONFIG_RADIO_RTRACK2_PORT
22#define CONFIG_RADIO_RTRACK2_PORT -1
23#endif
24
25static int io = CONFIG_RADIO_RTRACK2_PORT;
26static int radio_nr = -1;
27static spinlock_t lock;
28
29struct rt_device
30{
31 int port;
32 unsigned long curfreq;
33 int muted;
34};
35
36
37/* local things */
38
39static void rt_mute(struct rt_device *dev)
40{
41 if(dev->muted)
42 return;
43 spin_lock(&lock);
44 outb(1, io);
45 spin_unlock(&lock);
46 dev->muted = 1;
47}
48
49static void rt_unmute(struct rt_device *dev)
50{
51 if(dev->muted == 0)
52 return;
53 spin_lock(&lock);
54 outb(0, io);
55 spin_unlock(&lock);
56 dev->muted = 0;
57}
58
59static void zero(void)
60{
61 outb_p(1, io);
62 outb_p(3, io);
63 outb_p(1, io);
64}
65
66static void one(void)
67{
68 outb_p(5, io);
69 outb_p(7, io);
70 outb_p(5, io);
71}
72
73static int rt_setfreq(struct rt_device *dev, unsigned long freq)
74{
75 int i;
76
77 freq = freq / 200 + 856;
78
79 spin_lock(&lock);
80
81 outb_p(0xc8, io);
82 outb_p(0xc9, io);
83 outb_p(0xc9, io);
84
85 for (i = 0; i < 10; i++)
86 zero ();
87
88 for (i = 14; i >= 0; i--)
89 if (freq & (1 << i))
90 one ();
91 else
92 zero ();
93
94 outb_p(0xc8, io);
95 if (!dev->muted)
96 outb_p(0, io);
97
98 spin_unlock(&lock);
99 return 0;
100}
101
102static int rt_getsigstr(struct rt_device *dev)
103{
104 if (inb(io) & 2) /* bit set = no signal present */
105 return 0;
106 return 1; /* signal present */
107}
108
109static int rt_do_ioctl(struct inode *inode, struct file *file,
110 unsigned int cmd, void *arg)
111{
112 struct video_device *dev = video_devdata(file);
113 struct rt_device *rt=dev->priv;
114
115 switch(cmd)
116 {
117 case VIDIOCGCAP:
118 {
119 struct video_capability *v = arg;
120 memset(v,0,sizeof(*v));
121 v->type=VID_TYPE_TUNER;
122 v->channels=1;
123 v->audios=1;
124 strcpy(v->name, "RadioTrack II");
125 return 0;
126 }
127 case VIDIOCGTUNER:
128 {
129 struct video_tuner *v = arg;
130 if(v->tuner) /* Only 1 tuner */
131 return -EINVAL;
132 v->rangelow=88*16000;
133 v->rangehigh=108*16000;
134 v->flags=VIDEO_TUNER_LOW;
135 v->mode=VIDEO_MODE_AUTO;
136 v->signal=0xFFFF*rt_getsigstr(rt);
137 strcpy(v->name, "FM");
138 return 0;
139 }
140 case VIDIOCSTUNER:
141 {
142 struct video_tuner *v = arg;
143 if(v->tuner!=0)
144 return -EINVAL;
145 /* Only 1 tuner so no setting needed ! */
146 return 0;
147 }
148 case VIDIOCGFREQ:
149 {
150 unsigned long *freq = arg;
151 *freq = rt->curfreq;
152 return 0;
153 }
154 case VIDIOCSFREQ:
155 {
156 unsigned long *freq = arg;
157 rt->curfreq = *freq;
158 rt_setfreq(rt, rt->curfreq);
159 return 0;
160 }
161 case VIDIOCGAUDIO:
162 {
163 struct video_audio *v = arg;
164 memset(v,0, sizeof(*v));
165 v->flags|=VIDEO_AUDIO_MUTABLE;
166 v->volume=1;
167 v->step=65535;
168 strcpy(v->name, "Radio");
169 return 0;
170 }
171 case VIDIOCSAUDIO:
172 {
173 struct video_audio *v = arg;
174 if(v->audio)
175 return -EINVAL;
176
177 if(v->flags&VIDEO_AUDIO_MUTE)
178 rt_mute(rt);
179 else
180 rt_unmute(rt);
181
182 return 0;
183 }
184 default:
185 return -ENOIOCTLCMD;
186 }
187}
188
189static int rt_ioctl(struct inode *inode, struct file *file,
190 unsigned int cmd, unsigned long arg)
191{
192 return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
193}
194
195static struct rt_device rtrack2_unit;
196
197static struct file_operations rtrack2_fops = {
198 .owner = THIS_MODULE,
199 .open = video_exclusive_open,
200 .release = video_exclusive_release,
201 .ioctl = rt_ioctl,
202 .llseek = no_llseek,
203};
204
205static struct video_device rtrack2_radio=
206{
207 .owner = THIS_MODULE,
208 .name = "RadioTrack II radio",
209 .type = VID_TYPE_TUNER,
210 .hardware = VID_HARDWARE_RTRACK2,
211 .fops = &rtrack2_fops,
212};
213
214static int __init rtrack2_init(void)
215{
216 if(io==-1)
217 {
218 printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
219 return -EINVAL;
220 }
221 if (!request_region(io, 4, "rtrack2"))
222 {
223 printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
224 return -EBUSY;
225 }
226
227 rtrack2_radio.priv=&rtrack2_unit;
228
229 spin_lock_init(&lock);
230 if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
231 {
232 release_region(io, 4);
233 return -EINVAL;
234 }
235
236 printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
237
238 /* mute card - prevents noisy bootups */
239 outb(1, io);
240 rtrack2_unit.muted = 1;
241
242 return 0;
243}
244
245MODULE_AUTHOR("Ben Pfaff");
246MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
247MODULE_LICENSE("GPL");
248
249module_param(io, int, 0);
250MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
251module_param(radio_nr, int, 0);
252
253static void __exit rtrack2_cleanup_module(void)
254{
255 video_unregister_device(&rtrack2_radio);
256 release_region(io,4);
257}
258
259module_init(rtrack2_init);
260module_exit(rtrack2_cleanup_module);
261
262/*
263 Local variables:
264 compile-command: "mmake"
265 End:
266*/
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
new file mode 100644
index 000000000000..3a464a09221f
--- /dev/null
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -0,0 +1,328 @@
1/* SF16FMI radio driver for Linux radio support
2 * heavily based on rtrack driver...
3 * (c) 1997 M. Kirkwood
4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
5 *
6 * Fitted to new interface by Alan Cox <alan.cox@linux.org>
7 * Made working and cleaned up functions <mikael.hedin@irf.se>
8 * Support for ISAPnP by Ladislav Michl <ladis@psi.cz>
9 *
10 * Notes on the hardware
11 *
12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
13 * No volume control - only mute/unmute - you have to use line volume
14 * control on SB-part of SF16FMI
15 *
16 */
17
18#include <linux/kernel.h> /* __setup */
19#include <linux/module.h> /* Modules */
20#include <linux/init.h> /* Initdata */
21#include <linux/ioport.h> /* check_region, request_region */
22#include <linux/delay.h> /* udelay */
23#include <linux/videodev.h> /* kernel radio structs */
24#include <linux/isapnp.h>
25#include <asm/io.h> /* outb, outb_p */
26#include <asm/uaccess.h> /* copy to/from user */
27#include <asm/semaphore.h>
28
29struct fmi_device
30{
31 int port;
32 int curvol; /* 1 or 0 */
33 unsigned long curfreq; /* freq in kHz */
34 __u32 flags;
35};
36
37static int io = -1;
38static int radio_nr = -1;
39static struct pnp_dev *dev = NULL;
40static struct semaphore lock;
41
42/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
43/* It is only useful to give freq in intervall of 800 (=0.05Mhz),
44 * other bits will be truncated, e.g 92.7400016 -> 92.7, but
45 * 92.7400017 -> 92.75
46 */
47#define RSF16_ENCODE(x) ((x)/800+214)
48#define RSF16_MINFREQ 87*16000
49#define RSF16_MAXFREQ 108*16000
50
51static void outbits(int bits, unsigned int data, int port)
52{
53 while(bits--) {
54 if(data & 1) {
55 outb(5, port);
56 udelay(6);
57 outb(7, port);
58 udelay(6);
59 } else {
60 outb(1, port);
61 udelay(6);
62 outb(3, port);
63 udelay(6);
64 }
65 data>>=1;
66 }
67}
68
69static inline void fmi_mute(int port)
70{
71 down(&lock);
72 outb(0x00, port);
73 up(&lock);
74}
75
76static inline void fmi_unmute(int port)
77{
78 down(&lock);
79 outb(0x08, port);
80 up(&lock);
81}
82
83static inline int fmi_setfreq(struct fmi_device *dev)
84{
85 int myport = dev->port;
86 unsigned long freq = dev->curfreq;
87
88 down(&lock);
89
90 outbits(16, RSF16_ENCODE(freq), myport);
91 outbits(8, 0xC0, myport);
92 msleep(143); /* was schedule_timeout(HZ/7) */
93 up(&lock);
94 if (dev->curvol) fmi_unmute(myport);
95 return 0;
96}
97
98static inline int fmi_getsigstr(struct fmi_device *dev)
99{
100 int val;
101 int res;
102 int myport = dev->port;
103
104
105 down(&lock);
106 val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */
107 outb(val, myport);
108 outb(val | 0x10, myport);
109 msleep(143); /* was schedule_timeout(HZ/7) */
110 res = (int)inb(myport+1);
111 outb(val, myport);
112
113 up(&lock);
114 return (res & 2) ? 0 : 0xFFFF;
115}
116
117static int fmi_do_ioctl(struct inode *inode, struct file *file,
118 unsigned int cmd, void *arg)
119{
120 struct video_device *dev = video_devdata(file);
121 struct fmi_device *fmi=dev->priv;
122
123 switch(cmd)
124 {
125 case VIDIOCGCAP:
126 {
127 struct video_capability *v = arg;
128 memset(v,0,sizeof(*v));
129 strcpy(v->name, "SF16-FMx radio");
130 v->type=VID_TYPE_TUNER;
131 v->channels=1;
132 v->audios=1;
133 return 0;
134 }
135 case VIDIOCGTUNER:
136 {
137 struct video_tuner *v = arg;
138 int mult;
139
140 if(v->tuner) /* Only 1 tuner */
141 return -EINVAL;
142 strcpy(v->name, "FM");
143 mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
144 v->rangelow = RSF16_MINFREQ/mult;
145 v->rangehigh = RSF16_MAXFREQ/mult;
146 v->flags=fmi->flags;
147 v->mode=VIDEO_MODE_AUTO;
148 v->signal = fmi_getsigstr(fmi);
149 return 0;
150 }
151 case VIDIOCSTUNER:
152 {
153 struct video_tuner *v = arg;
154 if(v->tuner!=0)
155 return -EINVAL;
156 fmi->flags = v->flags & VIDEO_TUNER_LOW;
157 /* Only 1 tuner so no setting needed ! */
158 return 0;
159 }
160 case VIDIOCGFREQ:
161 {
162 unsigned long *freq = arg;
163 *freq = fmi->curfreq;
164 if (!(fmi->flags & VIDEO_TUNER_LOW))
165 *freq /= 1000;
166 return 0;
167 }
168 case VIDIOCSFREQ:
169 {
170 unsigned long *freq = arg;
171 if (!(fmi->flags & VIDEO_TUNER_LOW))
172 *freq *= 1000;
173 if (*freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ )
174 return -EINVAL;
175 /*rounding in steps of 800 to match th freq
176 that will be used */
177 fmi->curfreq = (*freq/800)*800;
178 fmi_setfreq(fmi);
179 return 0;
180 }
181 case VIDIOCGAUDIO:
182 {
183 struct video_audio *v = arg;
184 memset(v,0,sizeof(*v));
185 v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
186 strcpy(v->name, "Radio");
187 v->mode=VIDEO_SOUND_STEREO;
188 return 0;
189 }
190 case VIDIOCSAUDIO:
191 {
192 struct video_audio *v = arg;
193 if(v->audio)
194 return -EINVAL;
195 fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1;
196 fmi->curvol ?
197 fmi_unmute(fmi->port) : fmi_mute(fmi->port);
198 return 0;
199 }
200 case VIDIOCGUNIT:
201 {
202 struct video_unit *v = arg;
203 v->video=VIDEO_NO_UNIT;
204 v->vbi=VIDEO_NO_UNIT;
205 v->radio=dev->minor;
206 v->audio=0; /* How do we find out this??? */
207 v->teletext=VIDEO_NO_UNIT;
208 return 0;
209 }
210 default:
211 return -ENOIOCTLCMD;
212 }
213}
214
215static int fmi_ioctl(struct inode *inode, struct file *file,
216 unsigned int cmd, unsigned long arg)
217{
218 return video_usercopy(inode, file, cmd, arg, fmi_do_ioctl);
219}
220
221static struct fmi_device fmi_unit;
222
223static struct file_operations fmi_fops = {
224 .owner = THIS_MODULE,
225 .open = video_exclusive_open,
226 .release = video_exclusive_release,
227 .ioctl = fmi_ioctl,
228 .llseek = no_llseek,
229};
230
231static struct video_device fmi_radio=
232{
233 .owner = THIS_MODULE,
234 .name = "SF16FMx radio",
235 .type = VID_TYPE_TUNER,
236 .hardware = VID_HARDWARE_SF16MI,
237 .fops = &fmi_fops,
238};
239
240/* ladis: this is my card. does any other types exist? */
241static struct isapnp_device_id id_table[] __devinitdata = {
242 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
243 ISAPNP_VENDOR('M','F','R'), ISAPNP_FUNCTION(0xad10), 0},
244 { ISAPNP_CARD_END, },
245};
246
247MODULE_DEVICE_TABLE(isapnp, id_table);
248
249static int isapnp_fmi_probe(void)
250{
251 int i = 0;
252
253 while (id_table[i].card_vendor != 0 && dev == NULL) {
254 dev = pnp_find_dev(NULL, id_table[i].vendor,
255 id_table[i].function, NULL);
256 i++;
257 }
258
259 if (!dev)
260 return -ENODEV;
261 if (pnp_device_attach(dev) < 0)
262 return -EAGAIN;
263 if (pnp_activate_dev(dev) < 0) {
264 printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n");
265 pnp_device_detach(dev);
266 return -ENOMEM;
267 }
268 if (!pnp_port_valid(dev, 0)) {
269 pnp_device_detach(dev);
270 return -ENODEV;
271 }
272
273 i = pnp_port_start(dev, 0);
274 printk ("radio-sf16fmi: PnP reports card at %#x\n", i);
275
276 return i;
277}
278
279static int __init fmi_init(void)
280{
281 if (io < 0)
282 io = isapnp_fmi_probe();
283 if (io < 0) {
284 printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
285 return io;
286 }
287 if (!request_region(io, 2, "radio-sf16fmi")) {
288 printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
289 return -EBUSY;
290 }
291
292 fmi_unit.port = io;
293 fmi_unit.curvol = 0;
294 fmi_unit.curfreq = 0;
295 fmi_unit.flags = VIDEO_TUNER_LOW;
296 fmi_radio.priv = &fmi_unit;
297
298 init_MUTEX(&lock);
299
300 if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) {
301 release_region(io, 2);
302 return -EINVAL;
303 }
304
305 printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
306 /* mute card - prevents noisy bootups */
307 fmi_mute(io);
308 return 0;
309}
310
311MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
312MODULE_DESCRIPTION("A driver for the SF16MI radio.");
313MODULE_LICENSE("GPL");
314
315module_param(io, int, 0);
316MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
317module_param(radio_nr, int, 0);
318
319static void __exit fmi_cleanup_module(void)
320{
321 video_unregister_device(&fmi_radio);
322 release_region(io, 2);
323 if (dev)
324 pnp_device_detach(dev);
325}
326
327module_init(fmi_init);
328module_exit(fmi_cleanup_module);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
new file mode 100644
index 000000000000..0732efda6a98
--- /dev/null
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -0,0 +1,434 @@
1/* SF16FMR2 radio driver for Linux radio support
2 * heavily based on fmi driver...
3 * (c) 2000-2002 Ziglio Frediano, freddy77@angelfire.com
4 *
5 * Notes on the hardware
6 *
7 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
8 * No volume control - only mute/unmute - you have to use line volume
9 *
10 * For read stereo/mono you must wait 0.1 sec after set frequency and
11 * card unmuted so I set frequency on unmute
12 * Signal handling seem to work only on autoscanning (not implemented)
13 */
14
15#include <linux/module.h> /* Modules */
16#include <linux/init.h> /* Initdata */
17#include <linux/ioport.h> /* check_region, request_region */
18#include <linux/delay.h> /* udelay */
19#include <asm/io.h> /* outb, outb_p */
20#include <asm/uaccess.h> /* copy to/from user */
21#include <linux/videodev.h> /* kernel radio structs */
22#include <asm/semaphore.h>
23
24static struct semaphore lock;
25
26#undef DEBUG
27//#define DEBUG 1
28
29#ifdef DEBUG
30# define debug_print(s) printk s
31#else
32# define debug_print(s)
33#endif
34
35/* this should be static vars for module size */
36struct fmr2_device
37{
38 int port;
39 int curvol; /* 0-65535, if not volume 0 or 65535 */
40 int mute;
41 int stereo; /* card is producing stereo audio */
42 unsigned long curfreq; /* freq in kHz */
43 int card_type;
44 __u32 flags;
45};
46
47static int io = 0x384;
48static int radio_nr = -1;
49
50/* hw precision is 12.5 kHz
51 * It is only usefull to give freq in intervall of 200 (=0.0125Mhz),
52 * other bits will be truncated
53 */
54#define RSF16_ENCODE(x) ((x)/200+856)
55#define RSF16_MINFREQ 87*16000
56#define RSF16_MAXFREQ 108*16000
57
58static inline void wait(int n,int port)
59{
60 for (;n;--n) inb(port);
61}
62
63static void outbits(int bits, unsigned int data, int nWait, int port)
64{
65 int bit;
66 for(;--bits>=0;) {
67 bit = (data>>bits) & 1;
68 outb(bit,port);
69 wait(nWait,port);
70 outb(bit|2,port);
71 wait(nWait,port);
72 outb(bit,port);
73 wait(nWait,port);
74 }
75}
76
77static inline void fmr2_mute(int port)
78{
79 outb(0x00, port);
80 wait(4,port);
81}
82
83static inline void fmr2_unmute(int port)
84{
85 outb(0x04, port);
86 wait(4,port);
87}
88
89static inline int fmr2_stereo_mode(int port)
90{
91 int n = inb(port);
92 outb(6,port);
93 inb(port);
94 n = ((n>>3)&1)^1;
95 debug_print((KERN_DEBUG "stereo: %d\n", n));
96 return n;
97}
98
99static int fmr2_product_info(struct fmr2_device *dev)
100{
101 int n = inb(dev->port);
102 n &= 0xC1;
103 if (n == 0)
104 {
105 /* this should support volume set */
106 dev->card_type = 12;
107 return 0;
108 }
109 /* not volume (mine is 11) */
110 dev->card_type = (n==128)?11:0;
111 return n;
112}
113
114static inline int fmr2_getsigstr(struct fmr2_device *dev)
115{
116 /* !!! work only if scanning freq */
117 int port = dev->port, res = 0xffff;
118 outb(5,port);
119 wait(4,port);
120 if (!(inb(port)&1)) res = 0;
121 debug_print((KERN_DEBUG "signal: %d\n", res));
122 return res;
123}
124
125/* set frequency and unmute card */
126static int fmr2_setfreq(struct fmr2_device *dev)
127{
128 int port = dev->port;
129 unsigned long freq = dev->curfreq;
130
131 fmr2_mute(port);
132
133 /* 0x42 for mono output
134 * 0x102 forward scanning
135 * 0x182 scansione avanti
136 */
137 outbits(9,0x2,3,port);
138 outbits(16,RSF16_ENCODE(freq),2,port);
139
140 fmr2_unmute(port);
141
142 /* wait 0.11 sec */
143 msleep(110);
144
145 /* NOTE if mute this stop radio
146 you must set freq on unmute */
147 dev->stereo = fmr2_stereo_mode(port);
148 return 0;
149}
150
151/* !!! not tested, in my card this does't work !!! */
152static int fmr2_setvolume(struct fmr2_device *dev)
153{
154 int i,a,n, port = dev->port;
155
156 if (dev->card_type != 11) return 1;
157
158 switch( (dev->curvol+(1<<11)) >> 12 )
159 {
160 case 0: case 1: n = 0x21; break;
161 case 2: n = 0x84; break;
162 case 3: n = 0x90; break;
163 case 4: n = 0x104; break;
164 case 5: n = 0x110; break;
165 case 6: n = 0x204; break;
166 case 7: n = 0x210; break;
167 case 8: n = 0x402; break;
168 case 9: n = 0x404; break;
169 default:
170 case 10: n = 0x408; break;
171 case 11: n = 0x410; break;
172 case 12: n = 0x801; break;
173 case 13: n = 0x802; break;
174 case 14: n = 0x804; break;
175 case 15: n = 0x808; break;
176 case 16: n = 0x810; break;
177 }
178 for(i=12;--i>=0;)
179 {
180 a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */
181 outb(a|4, port);
182 wait(4,port);
183 outb(a|0x24, port);
184 wait(4,port);
185 outb(a|4, port);
186 wait(4,port);
187 }
188 for(i=6;--i>=0;)
189 {
190 a = ((0x18 >> i) & 1) << 6;
191 outb(a|4, port);
192 wait(4,port);
193 outb(a|0x24, port);
194 wait(4,port);
195 outb(a|4, port);
196 wait(4,port);
197 }
198 wait(4,port);
199 outb(0x14, port);
200
201 return 0;
202}
203
204static int fmr2_do_ioctl(struct inode *inode, struct file *file,
205 unsigned int cmd, void *arg)
206{
207 struct video_device *dev = video_devdata(file);
208 struct fmr2_device *fmr2 = dev->priv;
209 debug_print((KERN_DEBUG "freq %ld flags %d vol %d mute %d "
210 "stereo %d type %d\n",
211 fmr2->curfreq, fmr2->flags, fmr2->curvol, fmr2->mute,
212 fmr2->stereo, fmr2->card_type));
213
214 switch(cmd)
215 {
216 case VIDIOCGCAP:
217 {
218 struct video_capability *v = arg;
219 memset(v,0,sizeof(*v));
220 strcpy(v->name, "SF16-FMR2 radio");
221 v->type=VID_TYPE_TUNER;
222 v->channels=1;
223 v->audios=1;
224 return 0;
225 }
226 case VIDIOCGTUNER:
227 {
228 struct video_tuner *v = arg;
229 int mult;
230
231 if(v->tuner) /* Only 1 tuner */
232 return -EINVAL;
233 strcpy(v->name, "FM");
234 mult = (fmr2->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
235 v->rangelow = RSF16_MINFREQ/mult;
236 v->rangehigh = RSF16_MAXFREQ/mult;
237 v->flags = fmr2->flags | VIDEO_AUDIO_MUTABLE;
238 if (fmr2->mute)
239 v->flags |= VIDEO_AUDIO_MUTE;
240 v->mode=VIDEO_MODE_AUTO;
241 down(&lock);
242 v->signal = fmr2_getsigstr(fmr2);
243 up(&lock);
244 return 0;
245 }
246 case VIDIOCSTUNER:
247 {
248 struct video_tuner *v = arg;
249 if (v->tuner!=0)
250 return -EINVAL;
251 fmr2->flags = v->flags & VIDEO_TUNER_LOW;
252 return 0;
253 }
254 case VIDIOCGFREQ:
255 {
256 unsigned long *freq = arg;
257 *freq = fmr2->curfreq;
258 if (!(fmr2->flags & VIDEO_TUNER_LOW))
259 *freq /= 1000;
260 return 0;
261 }
262 case VIDIOCSFREQ:
263 {
264 unsigned long *freq = arg;
265 if (!(fmr2->flags & VIDEO_TUNER_LOW))
266 *freq *= 1000;
267 if ( *freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ )
268 return -EINVAL;
269 /* rounding in steps of 200 to match th freq
270 * that will be used
271 */
272 fmr2->curfreq = (*freq/200)*200;
273
274 /* set card freq (if not muted) */
275 if (fmr2->curvol && !fmr2->mute)
276 {
277 down(&lock);
278 fmr2_setfreq(fmr2);
279 up(&lock);
280 }
281 return 0;
282 }
283 case VIDIOCGAUDIO:
284 {
285 struct video_audio *v = arg;
286 memset(v,0,sizeof(*v));
287 /* !!! do not return VIDEO_AUDIO_MUTE */
288 v->flags = VIDEO_AUDIO_MUTABLE;
289 strcpy(v->name, "Radio");
290 /* get current stereo mode */
291 v->mode = fmr2->stereo ? VIDEO_SOUND_STEREO: VIDEO_SOUND_MONO;
292 /* volume supported ? */
293 if (fmr2->card_type == 11)
294 {
295 v->flags |= VIDEO_AUDIO_VOLUME;
296 v->step = 1 << 12;
297 v->volume = fmr2->curvol;
298 }
299 debug_print((KERN_DEBUG "Get flags %d vol %d\n", v->flags, v->volume));
300 return 0;
301 }
302 case VIDIOCSAUDIO:
303 {
304 struct video_audio *v = arg;
305 if(v->audio)
306 return -EINVAL;
307 debug_print((KERN_DEBUG "Set flags %d vol %d\n", v->flags, v->volume));
308 /* set volume */
309 if (v->flags & VIDEO_AUDIO_VOLUME)
310 fmr2->curvol = v->volume; /* !!! set with precision */
311 if (fmr2->card_type != 11) fmr2->curvol = 65535;
312 fmr2->mute = 0;
313 if (v->flags & VIDEO_AUDIO_MUTE)
314 fmr2->mute = 1;
315#ifdef DEBUG
316 if (fmr2->curvol && !fmr2->mute)
317 printk(KERN_DEBUG "unmute\n");
318 else
319 printk(KERN_DEBUG "mute\n");
320#endif
321 down(&lock);
322 if (fmr2->curvol && !fmr2->mute)
323 {
324 fmr2_setvolume(fmr2);
325 fmr2_setfreq(fmr2);
326 }
327 else fmr2_mute(fmr2->port);
328 up(&lock);
329 return 0;
330 }
331 case VIDIOCGUNIT:
332 {
333 struct video_unit *v = arg;
334 v->video=VIDEO_NO_UNIT;
335 v->vbi=VIDEO_NO_UNIT;
336 v->radio=dev->minor;
337 v->audio=0; /* How do we find out this??? */
338 v->teletext=VIDEO_NO_UNIT;
339 return 0;
340 }
341 default:
342 return -ENOIOCTLCMD;
343 }
344}
345
346static int fmr2_ioctl(struct inode *inode, struct file *file,
347 unsigned int cmd, unsigned long arg)
348 {
349 return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl);
350}
351
352static struct fmr2_device fmr2_unit;
353
354static struct file_operations fmr2_fops = {
355 .owner = THIS_MODULE,
356 .open = video_exclusive_open,
357 .release = video_exclusive_release,
358 .ioctl = fmr2_ioctl,
359 .llseek = no_llseek,
360};
361
362static struct video_device fmr2_radio=
363{
364 .owner = THIS_MODULE,
365 .name = "SF16FMR2 radio",
366 . type = VID_TYPE_TUNER,
367 .hardware = VID_HARDWARE_SF16FMR2,
368 .fops = &fmr2_fops,
369};
370
371static int __init fmr2_init(void)
372{
373 fmr2_unit.port = io;
374 fmr2_unit.curvol = 0;
375 fmr2_unit.mute = 0;
376 fmr2_unit.curfreq = 0;
377 fmr2_unit.stereo = 1;
378 fmr2_unit.flags = VIDEO_TUNER_LOW;
379 fmr2_unit.card_type = 0;
380 fmr2_radio.priv = &fmr2_unit;
381
382 init_MUTEX(&lock);
383
384 if (request_region(io, 2, "sf16fmr2"))
385 {
386 printk(KERN_ERR "fmr2: port 0x%x already in use\n", io);
387 return -EBUSY;
388 }
389
390 if(video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
391 {
392 release_region(io, 2);
393 return -EINVAL;
394 }
395
396 printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
397 debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW));
398 /* mute card - prevents noisy bootups */
399 down(&lock);
400 fmr2_mute(io);
401 fmr2_product_info(&fmr2_unit);
402 up(&lock);
403 debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
404 return 0;
405}
406
407MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
408MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
409MODULE_LICENSE("GPL");
410
411module_param(io, int, 0);
412MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
413module_param(radio_nr, int, 0);
414
415static void __exit fmr2_cleanup_module(void)
416{
417 video_unregister_device(&fmr2_radio);
418 release_region(io,2);
419}
420
421module_init(fmr2_init);
422module_exit(fmr2_cleanup_module);
423
424#ifndef MODULE
425
426static int __init fmr2_setup_io(char *str)
427{
428 get_option(&str, &io);
429 return 1;
430}
431
432__setup("sf16fmr2=", fmr2_setup_io);
433
434#endif
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
new file mode 100644
index 000000000000..248d67fde037
--- /dev/null
+++ b/drivers/media/radio/radio-terratec.c
@@ -0,0 +1,341 @@
1/* Terratec ActiveRadio ISA Standalone card driver for Linux radio support
2 * (c) 1999 R. Offermanns (rolf@offermanns.de)
3 * based on the aimslab radio driver from M. Kirkwood
4 * many thanks to Michael Becker and Friedhelm Birth (from TerraTec)
5 *
6 *
7 * History:
8 * 1999-05-21 First preview release
9 *
10 * Notes on the hardware:
11 * There are two "main" chips on the card:
12 * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf)
13 * - Philips SAA6588 (http://www-us.semiconductors.philips.com/acrobat/datasheets/SAA6588_1.pdf)
14 * (you can get the datasheet at the above links)
15 *
16 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
17 * Volume Control is done digitally
18 *
19 * there is a I2C controlled RDS decoder (SAA6588) onboard, which i would like to support someday
20 * (as soon i have understand how to get started :)
21 * If you can help me out with that, please contact me!!
22 *
23 *
24 */
25
26#include <linux/module.h> /* Modules */
27#include <linux/init.h> /* Initdata */
28#include <linux/ioport.h> /* check_region, request_region */
29#include <linux/delay.h> /* udelay */
30#include <asm/io.h> /* outb, outb_p */
31#include <asm/uaccess.h> /* copy to/from user */
32#include <linux/videodev.h> /* kernel radio structs */
33#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */
34#include <linux/spinlock.h>
35
36#ifndef CONFIG_RADIO_TERRATEC_PORT
37#define CONFIG_RADIO_TERRATEC_PORT 0x590
38#endif
39
40/**************** this ones are for the terratec *******************/
41#define BASEPORT 0x590
42#define VOLPORT 0x591
43#define WRT_DIS 0x00
44#define CLK_OFF 0x00
45#define IIC_DATA 0x01
46#define IIC_CLK 0x02
47#define DATA 0x04
48#define CLK_ON 0x08
49#define WRT_EN 0x10
50/*******************************************************************/
51
52static int io = CONFIG_RADIO_TERRATEC_PORT;
53static int radio_nr = -1;
54static spinlock_t lock;
55
56struct tt_device
57{
58 int port;
59 int curvol;
60 unsigned long curfreq;
61 int muted;
62};
63
64
65/* local things */
66
67static void cardWriteVol(int volume)
68{
69 int i;
70 volume = volume+(volume * 32); // change both channels
71 spin_lock(&lock);
72 for (i=0;i<8;i++)
73 {
74 if (volume & (0x80>>i))
75 outb(0x80, VOLPORT);
76 else outb(0x00, VOLPORT);
77 }
78 spin_unlock(&lock);
79}
80
81
82
83static void tt_mute(struct tt_device *dev)
84{
85 dev->muted = 1;
86 cardWriteVol(0);
87}
88
89static int tt_setvol(struct tt_device *dev, int vol)
90{
91
92// printk(KERN_ERR "setvol called, vol = %d\n", vol);
93
94 if(vol == dev->curvol) { /* requested volume = current */
95 if (dev->muted) { /* user is unmuting the card */
96 dev->muted = 0;
97 cardWriteVol(vol); /* enable card */
98 }
99
100 return 0;
101 }
102
103 if(vol == 0) { /* volume = 0 means mute the card */
104 cardWriteVol(0); /* "turn off card" by setting vol to 0 */
105 dev->curvol = vol; /* track the volume state! */
106 return 0;
107 }
108
109 dev->muted = 0;
110
111 cardWriteVol(vol);
112
113 dev->curvol = vol;
114
115 return 0;
116
117}
118
119
120/* this is the worst part in this driver */
121/* many more or less strange things are going on here, but hey, it works :) */
122
123static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
124{
125 int freq;
126 int i;
127 int p;
128 int temp;
129 long rest;
130
131 unsigned char buffer[25]; /* we have to bit shift 25 registers */
132 freq = freq1/160; /* convert the freq. to a nice to handle value */
133 for(i=24;i>-1;i--)
134 buffer[i]=0;
135
136 rest = freq*10+10700; /* i once had understood what is going on here */
137 /* maybe some wise guy (friedhelm?) can comment this stuff */
138 i=13;
139 p=10;
140 temp=102400;
141 while (rest!=0)
142 {
143 if (rest%temp == rest)
144 buffer[i] = 0;
145 else
146 {
147 buffer[i] = 1;
148 rest = rest-temp;
149 }
150 i--;
151 p--;
152 temp = temp/2;
153 }
154
155 spin_lock(&lock);
156
157 for (i=24;i>-1;i--) /* bit shift the values to the radiocard */
158 {
159 if (buffer[i]==1)
160 {
161 outb(WRT_EN|DATA, BASEPORT);
162 outb(WRT_EN|DATA|CLK_ON , BASEPORT);
163 outb(WRT_EN|DATA, BASEPORT);
164 }
165 else
166 {
167 outb(WRT_EN|0x00, BASEPORT);
168 outb(WRT_EN|0x00|CLK_ON , BASEPORT);
169 }
170 }
171 outb(0x00, BASEPORT);
172
173 spin_unlock(&lock);
174
175 return 0;
176}
177
178static int tt_getsigstr(struct tt_device *dev) /* TODO */
179{
180 if (inb(io) & 2) /* bit set = no signal present */
181 return 0;
182 return 1; /* signal present */
183}
184
185
186/* implement the video4linux api */
187
188static int tt_do_ioctl(struct inode *inode, struct file *file,
189 unsigned int cmd, void *arg)
190{
191 struct video_device *dev = video_devdata(file);
192 struct tt_device *tt=dev->priv;
193
194 switch(cmd)
195 {
196 case VIDIOCGCAP:
197 {
198 struct video_capability *v = arg;
199 memset(v,0,sizeof(*v));
200 v->type=VID_TYPE_TUNER;
201 v->channels=1;
202 v->audios=1;
203 strcpy(v->name, "ActiveRadio");
204 return 0;
205 }
206 case VIDIOCGTUNER:
207 {
208 struct video_tuner *v = arg;
209 if(v->tuner) /* Only 1 tuner */
210 return -EINVAL;
211 v->rangelow=(87*16000);
212 v->rangehigh=(108*16000);
213 v->flags=VIDEO_TUNER_LOW;
214 v->mode=VIDEO_MODE_AUTO;
215 strcpy(v->name, "FM");
216 v->signal=0xFFFF*tt_getsigstr(tt);
217 return 0;
218 }
219 case VIDIOCSTUNER:
220 {
221 struct video_tuner *v = arg;
222 if(v->tuner!=0)
223 return -EINVAL;
224 /* Only 1 tuner so no setting needed ! */
225 return 0;
226 }
227 case VIDIOCGFREQ:
228 {
229 unsigned long *freq = arg;
230 *freq = tt->curfreq;
231 return 0;
232 }
233 case VIDIOCSFREQ:
234 {
235 unsigned long *freq = arg;
236 tt->curfreq = *freq;
237 tt_setfreq(tt, tt->curfreq);
238 return 0;
239 }
240 case VIDIOCGAUDIO:
241 {
242 struct video_audio *v = arg;
243 memset(v,0, sizeof(*v));
244 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
245 v->volume=tt->curvol * 6554;
246 v->step=6554;
247 strcpy(v->name, "Radio");
248 return 0;
249 }
250 case VIDIOCSAUDIO:
251 {
252 struct video_audio *v = arg;
253 if(v->audio)
254 return -EINVAL;
255 if(v->flags&VIDEO_AUDIO_MUTE)
256 tt_mute(tt);
257 else
258 tt_setvol(tt,v->volume/6554);
259 return 0;
260 }
261 default:
262 return -ENOIOCTLCMD;
263 }
264}
265
266static int tt_ioctl(struct inode *inode, struct file *file,
267 unsigned int cmd, unsigned long arg)
268{
269 return video_usercopy(inode, file, cmd, arg, tt_do_ioctl);
270}
271
272static struct tt_device terratec_unit;
273
274static struct file_operations terratec_fops = {
275 .owner = THIS_MODULE,
276 .open = video_exclusive_open,
277 .release = video_exclusive_release,
278 .ioctl = tt_ioctl,
279 .llseek = no_llseek,
280};
281
282static struct video_device terratec_radio=
283{
284 .owner = THIS_MODULE,
285 .name = "TerraTec ActiveRadio",
286 .type = VID_TYPE_TUNER,
287 .hardware = VID_HARDWARE_TERRATEC,
288 .fops = &terratec_fops,
289};
290
291static int __init terratec_init(void)
292{
293 if(io==-1)
294 {
295 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
296 return -EINVAL;
297 }
298 if (!request_region(io, 2, "terratec"))
299 {
300 printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
301 return -EBUSY;
302 }
303
304 terratec_radio.priv=&terratec_unit;
305
306 spin_lock_init(&lock);
307
308 if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1)
309 {
310 release_region(io,2);
311 return -EINVAL;
312 }
313
314 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
315
316 /* mute card - prevents noisy bootups */
317
318 /* this ensures that the volume is all the way down */
319 cardWriteVol(0);
320 terratec_unit.curvol = 0;
321
322 return 0;
323}
324
325MODULE_AUTHOR("R.OFFERMANNS & others");
326MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
327MODULE_LICENSE("GPL");
328module_param(io, int, 0);
329MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
330module_param(radio_nr, int, 0);
331
332static void __exit terratec_cleanup_module(void)
333{
334 video_unregister_device(&terratec_radio);
335 release_region(io,2);
336 printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
337}
338
339module_init(terratec_init);
340module_exit(terratec_cleanup_module);
341
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
new file mode 100644
index 000000000000..b300bedf7c74
--- /dev/null
+++ b/drivers/media/radio/radio-trust.c
@@ -0,0 +1,320 @@
1/* radio-trust.c - Trust FM Radio card driver for Linux 2.2
2 * by Eric Lammerts <eric@scintilla.utwente.nl>
3 *
4 * Based on radio-aztech.c. Original notes:
5 *
6 * Adapted to support the Video for Linux API by
7 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
8 *
9 * Quay Ly
10 * Donald Song
11 * Jason Lewis (jlewis@twilight.vtc.vsc.edu)
12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
14 *
15 * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
16 */
17
18#include <stdarg.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/ioport.h>
22#include <asm/io.h>
23#include <asm/uaccess.h>
24#include <linux/videodev.h>
25#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */
26
27/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
28
29#ifndef CONFIG_RADIO_TRUST_PORT
30#define CONFIG_RADIO_TRUST_PORT -1
31#endif
32
33static int io = CONFIG_RADIO_TRUST_PORT;
34static int radio_nr = -1;
35static int ioval = 0xf;
36static __u16 curvol;
37static __u16 curbass;
38static __u16 curtreble;
39static unsigned long curfreq;
40static int curstereo;
41static int curmute;
42
43/* i2c addresses */
44#define TDA7318_ADDR 0x88
45#define TSA6060T_ADDR 0xc4
46
47#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
48#define TR_SET_SCL outb(ioval |= 2, io)
49#define TR_CLR_SCL outb(ioval &= 0xfd, io)
50#define TR_SET_SDA outb(ioval |= 1, io)
51#define TR_CLR_SDA outb(ioval &= 0xfe, io)
52
53static void write_i2c(int n, ...)
54{
55 unsigned char val, mask;
56 va_list args;
57
58 va_start(args, n);
59
60 /* start condition */
61 TR_SET_SDA;
62 TR_SET_SCL;
63 TR_DELAY;
64 TR_CLR_SDA;
65 TR_CLR_SCL;
66 TR_DELAY;
67
68 for(; n; n--) {
69 val = va_arg(args, unsigned);
70 for(mask = 0x80; mask; mask >>= 1) {
71 if(val & mask)
72 TR_SET_SDA;
73 else
74 TR_CLR_SDA;
75 TR_SET_SCL;
76 TR_DELAY;
77 TR_CLR_SCL;
78 TR_DELAY;
79 }
80 /* acknowledge bit */
81 TR_SET_SDA;
82 TR_SET_SCL;
83 TR_DELAY;
84 TR_CLR_SCL;
85 TR_DELAY;
86 }
87
88 /* stop condition */
89 TR_CLR_SDA;
90 TR_DELAY;
91 TR_SET_SCL;
92 TR_DELAY;
93 TR_SET_SDA;
94 TR_DELAY;
95
96 va_end(args);
97}
98
99static void tr_setvol(__u16 vol)
100{
101 curvol = vol / 2048;
102 write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
103}
104
105static int basstreble2chip[15] = {
106 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
107};
108
109static void tr_setbass(__u16 bass)
110{
111 curbass = bass / 4370;
112 write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
113}
114
115static void tr_settreble(__u16 treble)
116{
117 curtreble = treble / 4370;
118 write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
119}
120
121static void tr_setstereo(int stereo)
122{
123 curstereo = !!stereo;
124 ioval = (ioval & 0xfb) | (!curstereo << 2);
125 outb(ioval, io);
126}
127
128static void tr_setmute(int mute)
129{
130 curmute = !!mute;
131 ioval = (ioval & 0xf7) | (curmute << 3);
132 outb(ioval, io);
133}
134
135static int tr_getsigstr(void)
136{
137 int i, v;
138
139 for(i = 0, v = 0; i < 100; i++) v |= inb(io);
140 return (v & 1)? 0 : 0xffff;
141}
142
143static int tr_getstereo(void)
144{
145 /* don't know how to determine it, just return the setting */
146 return curstereo;
147}
148
149static void tr_setfreq(unsigned long f)
150{
151 f /= 160; /* Convert to 10 kHz units */
152 f += 1070; /* Add 10.7 MHz IF */
153
154 write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
155}
156
157static int tr_do_ioctl(struct inode *inode, struct file *file,
158 unsigned int cmd, void *arg)
159{
160 switch(cmd)
161 {
162 case VIDIOCGCAP:
163 {
164 struct video_capability *v = arg;
165
166 memset(v,0,sizeof(*v));
167 v->type=VID_TYPE_TUNER;
168 v->channels=1;
169 v->audios=1;
170 strcpy(v->name, "Trust FM Radio");
171
172 return 0;
173 }
174 case VIDIOCGTUNER:
175 {
176 struct video_tuner *v = arg;
177
178 if(v->tuner) /* Only 1 tuner */
179 return -EINVAL;
180
181 v->rangelow = 87500 * 16;
182 v->rangehigh = 108000 * 16;
183 v->flags = VIDEO_TUNER_LOW;
184 v->mode = VIDEO_MODE_AUTO;
185
186 v->signal = tr_getsigstr();
187 if(tr_getstereo())
188 v->flags |= VIDEO_TUNER_STEREO_ON;
189
190 strcpy(v->name, "FM");
191
192 return 0;
193 }
194 case VIDIOCSTUNER:
195 {
196 struct video_tuner *v = arg;
197 if(v->tuner != 0)
198 return -EINVAL;
199 return 0;
200 }
201 case VIDIOCGFREQ:
202 {
203 unsigned long *freq = arg;
204 *freq = curfreq;
205 return 0;
206 }
207 case VIDIOCSFREQ:
208 {
209 unsigned long *freq = arg;
210 tr_setfreq(*freq);
211 return 0;
212 }
213 case VIDIOCGAUDIO:
214 {
215 struct video_audio *v = arg;
216
217 memset(v,0, sizeof(*v));
218 v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME |
219 VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
220 v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
221 v->volume = curvol * 2048;
222 v->step = 2048;
223 v->bass = curbass * 4370;
224 v->treble = curtreble * 4370;
225
226 strcpy(v->name, "Trust FM Radio");
227 return 0;
228 }
229 case VIDIOCSAUDIO:
230 {
231 struct video_audio *v = arg;
232
233 if(v->audio)
234 return -EINVAL;
235 tr_setvol(v->volume);
236 tr_setbass(v->bass);
237 tr_settreble(v->treble);
238 tr_setstereo(v->mode & VIDEO_SOUND_STEREO);
239 tr_setmute(v->flags & VIDEO_AUDIO_MUTE);
240 return 0;
241 }
242 default:
243 return -ENOIOCTLCMD;
244 }
245}
246
247static int tr_ioctl(struct inode *inode, struct file *file,
248 unsigned int cmd, unsigned long arg)
249{
250 return video_usercopy(inode, file, cmd, arg, tr_do_ioctl);
251}
252
253static struct file_operations trust_fops = {
254 .owner = THIS_MODULE,
255 .open = video_exclusive_open,
256 .release = video_exclusive_release,
257 .ioctl = tr_ioctl,
258 .llseek = no_llseek,
259};
260
261static struct video_device trust_radio=
262{
263 .owner = THIS_MODULE,
264 .name = "Trust FM Radio",
265 .type = VID_TYPE_TUNER,
266 .hardware = VID_HARDWARE_TRUST,
267 .fops = &trust_fops,
268};
269
270static int __init trust_init(void)
271{
272 if(io == -1) {
273 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
274 return -EINVAL;
275 }
276 if(!request_region(io, 2, "Trust FM Radio")) {
277 printk(KERN_ERR "trust: port 0x%x already in use\n", io);
278 return -EBUSY;
279 }
280 if(video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr)==-1)
281 {
282 release_region(io, 2);
283 return -EINVAL;
284 }
285
286 printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
287
288 write_i2c(2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
289 write_i2c(2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
290 write_i2c(2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
291 write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
292 write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
293
294 tr_setvol(0x8000);
295 tr_setbass(0x8000);
296 tr_settreble(0x8000);
297 tr_setstereo(1);
298
299 /* mute card - prevents noisy bootups */
300 tr_setmute(1);
301
302 return 0;
303}
304
305MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
306MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
307MODULE_LICENSE("GPL");
308
309module_param(io, int, 0);
310MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
311module_param(radio_nr, int, 0);
312
313static void __exit cleanup_trust_module(void)
314{
315 video_unregister_device(&trust_radio);
316 release_region(io, 2);
317}
318
319module_init(trust_init);
320module_exit(cleanup_trust_module);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
new file mode 100644
index 000000000000..d7da901ebe90
--- /dev/null
+++ b/drivers/media/radio/radio-typhoon.c
@@ -0,0 +1,383 @@
1/* Typhoon Radio Card driver for radio support
2 * (c) 1999 Dr. Henrik Seidel <Henrik.Seidel@gmx.de>
3 *
4 * Card manufacturer:
5 * http://194.18.155.92/idc/prod2.idc?nr=50753&lang=e
6 *
7 * Notes on the hardware
8 *
9 * This card has two output sockets, one for speakers and one for line.
10 * The speaker output has volume control, but only in four discrete
11 * steps. The line output has neither volume control nor mute.
12 *
13 * The card has auto-stereo according to its manual, although it all
14 * sounds mono to me (even with the Win/DOS drivers). Maybe it's my
15 * antenna - I really don't know for sure.
16 *
17 * Frequency control is done digitally.
18 *
19 * Volume control is done digitally, but there are only four different
20 * possible values. So you should better always turn the volume up and
21 * use line control. I got the best results by connecting line output
22 * to the sound card microphone input. For such a configuration the
23 * volume control has no effect, since volume control only influences
24 * the speaker output.
25 *
26 * There is no explicit mute/unmute. So I set the radio frequency to a
27 * value where I do expect just noise and turn the speaker volume down.
28 * The frequency change is necessary since the card never seems to be
29 * completely silent.
30 */
31
32#include <linux/module.h> /* Modules */
33#include <linux/init.h> /* Initdata */
34#include <linux/ioport.h> /* check_region, request_region */
35#include <linux/proc_fs.h> /* radio card status report */
36#include <asm/io.h> /* outb, outb_p */
37#include <asm/uaccess.h> /* copy to/from user */
38#include <linux/videodev.h> /* kernel radio structs */
39#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */
40
41#define BANNER "Typhoon Radio Card driver v0.1\n"
42
43#ifndef CONFIG_RADIO_TYPHOON_PORT
44#define CONFIG_RADIO_TYPHOON_PORT -1
45#endif
46
47#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ
48#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
49#endif
50
51#ifndef CONFIG_PROC_FS
52#undef CONFIG_RADIO_TYPHOON_PROC_FS
53#endif
54
55struct typhoon_device {
56 int users;
57 int iobase;
58 int curvol;
59 int muted;
60 unsigned long curfreq;
61 unsigned long mutefreq;
62 struct semaphore lock;
63};
64
65static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
66static int typhoon_setfreq_generic(struct typhoon_device *dev,
67 unsigned long frequency);
68static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
69static void typhoon_mute(struct typhoon_device *dev);
70static void typhoon_unmute(struct typhoon_device *dev);
71static int typhoon_setvol(struct typhoon_device *dev, int vol);
72static int typhoon_ioctl(struct inode *inode, struct file *file,
73 unsigned int cmd, unsigned long arg);
74#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
75static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
76#endif
77
78static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
79{
80 down(&dev->lock);
81 vol >>= 14; /* Map 16 bit to 2 bit */
82 vol &= 3;
83 outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */
84 outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */
85 up(&dev->lock);
86}
87
88static int typhoon_setfreq_generic(struct typhoon_device *dev,
89 unsigned long frequency)
90{
91 unsigned long outval;
92 unsigned long x;
93
94 /*
95 * The frequency transfer curve is not linear. The best fit I could
96 * get is
97 *
98 * outval = -155 + exp((f + 15.55) * 0.057))
99 *
100 * where frequency f is in MHz. Since we don't have exp in the kernel,
101 * I approximate this function by a third order polynomial.
102 *
103 */
104
105 down(&dev->lock);
106 x = frequency / 160;
107 outval = (x * x + 2500) / 5000;
108 outval = (outval * x + 5000) / 10000;
109 outval -= (10 * x * x + 10433) / 20866;
110 outval += 4 * x - 11505;
111
112 outb_p((outval >> 8) & 0x01, dev->iobase + 4);
113 outb_p(outval >> 9, dev->iobase + 6);
114 outb_p(outval & 0xff, dev->iobase + 8);
115 up(&dev->lock);
116
117 return 0;
118}
119
120static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
121{
122 typhoon_setfreq_generic(dev, frequency);
123 dev->curfreq = frequency;
124 return 0;
125}
126
127static void typhoon_mute(struct typhoon_device *dev)
128{
129 if (dev->muted == 1)
130 return;
131 typhoon_setvol_generic(dev, 0);
132 typhoon_setfreq_generic(dev, dev->mutefreq);
133 dev->muted = 1;
134}
135
136static void typhoon_unmute(struct typhoon_device *dev)
137{
138 if (dev->muted == 0)
139 return;
140 typhoon_setfreq_generic(dev, dev->curfreq);
141 typhoon_setvol_generic(dev, dev->curvol);
142 dev->muted = 0;
143}
144
145static int typhoon_setvol(struct typhoon_device *dev, int vol)
146{
147 if (dev->muted && vol != 0) { /* user is unmuting the card */
148 dev->curvol = vol;
149 typhoon_unmute(dev);
150 return 0;
151 }
152 if (vol == dev->curvol) /* requested volume == current */
153 return 0;
154
155 if (vol == 0) { /* volume == 0 means mute the card */
156 typhoon_mute(dev);
157 dev->curvol = vol;
158 return 0;
159 }
160 typhoon_setvol_generic(dev, vol);
161 dev->curvol = vol;
162 return 0;
163}
164
165
166static int typhoon_do_ioctl(struct inode *inode, struct file *file,
167 unsigned int cmd, void *arg)
168{
169 struct video_device *dev = video_devdata(file);
170 struct typhoon_device *typhoon = dev->priv;
171
172 switch (cmd) {
173 case VIDIOCGCAP:
174 {
175 struct video_capability *v = arg;
176 memset(v,0,sizeof(*v));
177 v->type = VID_TYPE_TUNER;
178 v->channels = 1;
179 v->audios = 1;
180 strcpy(v->name, "Typhoon Radio");
181 return 0;
182 }
183 case VIDIOCGTUNER:
184 {
185 struct video_tuner *v = arg;
186 if (v->tuner) /* Only 1 tuner */
187 return -EINVAL;
188 v->rangelow = 875 * 1600;
189 v->rangehigh = 1080 * 1600;
190 v->flags = VIDEO_TUNER_LOW;
191 v->mode = VIDEO_MODE_AUTO;
192 v->signal = 0xFFFF; /* We can't get the signal strength */
193 strcpy(v->name, "FM");
194 return 0;
195 }
196 case VIDIOCSTUNER:
197 {
198 struct video_tuner *v = arg;
199 if (v->tuner != 0)
200 return -EINVAL;
201 /* Only 1 tuner so no setting needed ! */
202 return 0;
203 }
204 case VIDIOCGFREQ:
205 {
206 unsigned long *freq = arg;
207 *freq = typhoon->curfreq;
208 return 0;
209 }
210 case VIDIOCSFREQ:
211 {
212 unsigned long *freq = arg;
213 typhoon->curfreq = *freq;
214 typhoon_setfreq(typhoon, typhoon->curfreq);
215 return 0;
216 }
217 case VIDIOCGAUDIO:
218 {
219 struct video_audio *v = arg;
220 memset(v, 0, sizeof(*v));
221 v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
222 v->mode |= VIDEO_SOUND_MONO;
223 v->volume = typhoon->curvol;
224 v->step = 1 << 14;
225 strcpy(v->name, "Typhoon Radio");
226 return 0;
227 }
228 case VIDIOCSAUDIO:
229 {
230 struct video_audio *v = arg;
231 if (v->audio)
232 return -EINVAL;
233 if (v->flags & VIDEO_AUDIO_MUTE)
234 typhoon_mute(typhoon);
235 else
236 typhoon_unmute(typhoon);
237 if (v->flags & VIDEO_AUDIO_VOLUME)
238 typhoon_setvol(typhoon, v->volume);
239 return 0;
240 }
241 default:
242 return -ENOIOCTLCMD;
243 }
244}
245
246static int typhoon_ioctl(struct inode *inode, struct file *file,
247 unsigned int cmd, unsigned long arg)
248{
249 return video_usercopy(inode, file, cmd, arg, typhoon_do_ioctl);
250}
251
252static struct typhoon_device typhoon_unit =
253{
254 .iobase = CONFIG_RADIO_TYPHOON_PORT,
255 .curfreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
256 .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
257};
258
259static struct file_operations typhoon_fops = {
260 .owner = THIS_MODULE,
261 .open = video_exclusive_open,
262 .release = video_exclusive_release,
263 .ioctl = typhoon_ioctl,
264 .llseek = no_llseek,
265};
266
267static struct video_device typhoon_radio =
268{
269 .owner = THIS_MODULE,
270 .name = "Typhoon Radio",
271 .type = VID_TYPE_TUNER,
272 .hardware = VID_HARDWARE_TYPHOON,
273 .fops = &typhoon_fops,
274};
275
276#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
277
278static int typhoon_get_info(char *buf, char **start, off_t offset, int len)
279{
280 char *out = buf;
281
282 #ifdef MODULE
283 #define MODULEPROCSTRING "Driver loaded as a module"
284 #else
285 #define MODULEPROCSTRING "Driver compiled into kernel"
286 #endif
287
288 /* output must be kept under PAGE_SIZE */
289 out += sprintf(out, BANNER);
290 out += sprintf(out, "Load type: " MODULEPROCSTRING "\n\n");
291 out += sprintf(out, "frequency = %lu kHz\n",
292 typhoon_unit.curfreq >> 4);
293 out += sprintf(out, "volume = %d\n", typhoon_unit.curvol);
294 out += sprintf(out, "mute = %s\n", typhoon_unit.muted ?
295 "on" : "off");
296 out += sprintf(out, "iobase = 0x%x\n", typhoon_unit.iobase);
297 out += sprintf(out, "mute frequency = %lu kHz\n",
298 typhoon_unit.mutefreq >> 4);
299 return out - buf;
300}
301
302#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
303
304MODULE_AUTHOR("Dr. Henrik Seidel");
305MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
306MODULE_LICENSE("GPL");
307
308static int io = -1;
309static int radio_nr = -1;
310
311module_param(io, int, 0);
312MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
313module_param(radio_nr, int, 0);
314
315#ifdef MODULE
316static unsigned long mutefreq = 0;
317module_param(mutefreq, ulong, 0);
318MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
319#endif
320
321static int __init typhoon_init(void)
322{
323#ifdef MODULE
324 if (io == -1) {
325 printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
326 return -EINVAL;
327 }
328 typhoon_unit.iobase = io;
329
330 if (mutefreq < 87000 || mutefreq > 108500) {
331 printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
332 printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
333 return -EINVAL;
334 }
335 typhoon_unit.mutefreq = mutefreq;
336#endif /* MODULE */
337
338 printk(KERN_INFO BANNER);
339 init_MUTEX(&typhoon_unit.lock);
340 io = typhoon_unit.iobase;
341 if (!request_region(io, 8, "typhoon")) {
342 printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
343 typhoon_unit.iobase);
344 return -EBUSY;
345 }
346
347 typhoon_radio.priv = &typhoon_unit;
348 if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) == -1)
349 {
350 release_region(io, 8);
351 return -EINVAL;
352 }
353 printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
354 printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
355 typhoon_unit.mutefreq);
356 typhoon_unit.mutefreq <<= 4;
357
358 /* mute card - prevents noisy bootups */
359 typhoon_mute(&typhoon_unit);
360
361#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
362 if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL,
363 typhoon_get_info))
364 printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
365#endif
366
367 return 0;
368}
369
370static void __exit typhoon_cleanup_module(void)
371{
372
373#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
374 remove_proc_entry("driver/radio-typhoon", NULL);
375#endif
376
377 video_unregister_device(&typhoon_radio);
378 release_region(io, 8);
379}
380
381module_init(typhoon_init);
382module_exit(typhoon_cleanup_module);
383
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
new file mode 100644
index 000000000000..342f92df4aba
--- /dev/null
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -0,0 +1,385 @@
1/* zoltrix radio plus driver for Linux radio support
2 * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
3 *
4 * BUGS
5 * Due to the inconsistency in reading from the signal flags
6 * it is difficult to get an accurate tuned signal.
7 *
8 * It seems that the card is not linear to 0 volume. It cuts off
9 * at a low volume, and it is not possible (at least I have not found)
10 * to get fine volume control over the low volume range.
11 *
12 * Some code derived from code by Romolo Manfredini
13 * romolo@bicnet.it
14 *
15 * 1999-05-06 - (C. van Schaik)
16 * - Make signal strength and stereo scans
17 * kinder to cpu while in delay
18 * 1999-01-05 - (C. van Schaik)
19 * - Changed tuning to 1/160Mhz accuracy
20 * - Added stereo support
21 * (card defaults to stereo)
22 * (can explicitly force mono on the card)
23 * (can detect if station is in stereo)
24 * - Added unmute function
25 * - Reworked ioctl functions
26 * 2002-07-15 - Fix Stereo typo
27 */
28
29#include <linux/module.h> /* Modules */
30#include <linux/init.h> /* Initdata */
31#include <linux/ioport.h> /* check_region, request_region */
32#include <linux/delay.h> /* udelay, msleep */
33#include <asm/io.h> /* outb, outb_p */
34#include <asm/uaccess.h> /* copy to/from user */
35#include <linux/videodev.h> /* kernel radio structs */
36#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */
37
38#ifndef CONFIG_RADIO_ZOLTRIX_PORT
39#define CONFIG_RADIO_ZOLTRIX_PORT -1
40#endif
41
42static int io = CONFIG_RADIO_ZOLTRIX_PORT;
43static int radio_nr = -1;
44
45struct zol_device {
46 int port;
47 int curvol;
48 unsigned long curfreq;
49 int muted;
50 unsigned int stereo;
51 struct semaphore lock;
52};
53
54static int zol_setvol(struct zol_device *dev, int vol)
55{
56 dev->curvol = vol;
57 if (dev->muted)
58 return 0;
59
60 down(&dev->lock);
61 if (vol == 0) {
62 outb(0, io);
63 outb(0, io);
64 inb(io + 3); /* Zoltrix needs to be read to confirm */
65 up(&dev->lock);
66 return 0;
67 }
68
69 outb(dev->curvol-1, io);
70 msleep(10);
71 inb(io + 2);
72 up(&dev->lock);
73 return 0;
74}
75
76static void zol_mute(struct zol_device *dev)
77{
78 dev->muted = 1;
79 down(&dev->lock);
80 outb(0, io);
81 outb(0, io);
82 inb(io + 3); /* Zoltrix needs to be read to confirm */
83 up(&dev->lock);
84}
85
86static void zol_unmute(struct zol_device *dev)
87{
88 dev->muted = 0;
89 zol_setvol(dev, dev->curvol);
90}
91
92static int zol_setfreq(struct zol_device *dev, unsigned long freq)
93{
94 /* tunes the radio to the desired frequency */
95 unsigned long long bitmask, f, m;
96 unsigned int stereo = dev->stereo;
97 int i;
98
99 if (freq == 0)
100 return 1;
101 m = (freq / 160 - 8800) * 2;
102 f = (unsigned long long) m + 0x4d1c;
103
104 bitmask = 0xc480402c10080000ull;
105 i = 45;
106
107 down(&dev->lock);
108
109 outb(0, io);
110 outb(0, io);
111 inb(io + 3); /* Zoltrix needs to be read to confirm */
112
113 outb(0x40, io);
114 outb(0xc0, io);
115
116 bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
117 while (i--) {
118 if ((bitmask & 0x8000000000000000ull) != 0) {
119 outb(0x80, io);
120 udelay(50);
121 outb(0x00, io);
122 udelay(50);
123 outb(0x80, io);
124 udelay(50);
125 } else {
126 outb(0xc0, io);
127 udelay(50);
128 outb(0x40, io);
129 udelay(50);
130 outb(0xc0, io);
131 udelay(50);
132 }
133 bitmask *= 2;
134 }
135 /* termination sequence */
136 outb(0x80, io);
137 outb(0xc0, io);
138 outb(0x40, io);
139 udelay(1000);
140 inb(io+2);
141
142 udelay(1000);
143
144 if (dev->muted)
145 {
146 outb(0, io);
147 outb(0, io);
148 inb(io + 3);
149 udelay(1000);
150 }
151
152 up(&dev->lock);
153
154 if(!dev->muted)
155 {
156 zol_setvol(dev, dev->curvol);
157 }
158 return 0;
159}
160
161/* Get signal strength */
162
163static int zol_getsigstr(struct zol_device *dev)
164{
165 int a, b;
166
167 down(&dev->lock);
168 outb(0x00, io); /* This stuff I found to do nothing */
169 outb(dev->curvol, io);
170 msleep(20);
171
172 a = inb(io);
173 msleep(10);
174 b = inb(io);
175
176 up(&dev->lock);
177
178 if (a != b)
179 return (0);
180
181 if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */
182 || (a == 0xef)) /* with a binary scanner on the card io */
183 return (1);
184 return (0);
185}
186
187static int zol_is_stereo (struct zol_device *dev)
188{
189 int x1, x2;
190
191 down(&dev->lock);
192
193 outb(0x00, io);
194 outb(dev->curvol, io);
195 msleep(20);
196
197 x1 = inb(io);
198 msleep(10);
199 x2 = inb(io);
200
201 up(&dev->lock);
202
203 if ((x1 == x2) && (x1 == 0xcf))
204 return 1;
205 return 0;
206}
207
208static int zol_do_ioctl(struct inode *inode, struct file *file,
209 unsigned int cmd, void *arg)
210{
211 struct video_device *dev = video_devdata(file);
212 struct zol_device *zol = dev->priv;
213
214 switch (cmd) {
215 case VIDIOCGCAP:
216 {
217 struct video_capability *v = arg;
218
219 memset(v,0,sizeof(*v));
220 v->type = VID_TYPE_TUNER;
221 v->channels = 1 + zol->stereo;
222 v->audios = 1;
223 strcpy(v->name, "Zoltrix Radio");
224 return 0;
225 }
226 case VIDIOCGTUNER:
227 {
228 struct video_tuner *v = arg;
229 if (v->tuner)
230 return -EINVAL;
231 strcpy(v->name, "FM");
232 v->rangelow = (int) (88.0 * 16000);
233 v->rangehigh = (int) (108.0 * 16000);
234 v->flags = zol_is_stereo(zol)
235 ? VIDEO_TUNER_STEREO_ON : 0;
236 v->flags |= VIDEO_TUNER_LOW;
237 v->mode = VIDEO_MODE_AUTO;
238 v->signal = 0xFFFF * zol_getsigstr(zol);
239 return 0;
240 }
241 case VIDIOCSTUNER:
242 {
243 struct video_tuner *v = arg;
244 if (v->tuner != 0)
245 return -EINVAL;
246 /* Only 1 tuner so no setting needed ! */
247 return 0;
248 }
249 case VIDIOCGFREQ:
250 {
251 unsigned long *freq = arg;
252 *freq = zol->curfreq;
253 return 0;
254 }
255 case VIDIOCSFREQ:
256 {
257 unsigned long *freq = arg;
258 zol->curfreq = *freq;
259 zol_setfreq(zol, zol->curfreq);
260 return 0;
261 }
262 case VIDIOCGAUDIO:
263 {
264 struct video_audio *v = arg;
265 memset(v, 0, sizeof(*v));
266 v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
267 v->mode |= zol_is_stereo(zol)
268 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
269 v->volume = zol->curvol * 4096;
270 v->step = 4096;
271 strcpy(v->name, "Zoltrix Radio");
272 return 0;
273 }
274 case VIDIOCSAUDIO:
275 {
276 struct video_audio *v = arg;
277 if (v->audio)
278 return -EINVAL;
279
280 if (v->flags & VIDEO_AUDIO_MUTE)
281 zol_mute(zol);
282 else {
283 zol_unmute(zol);
284 zol_setvol(zol, v->volume / 4096);
285 }
286
287 if (v->mode & VIDEO_SOUND_STEREO) {
288 zol->stereo = 1;
289 zol_setfreq(zol, zol->curfreq);
290 }
291 if (v->mode & VIDEO_SOUND_MONO) {
292 zol->stereo = 0;
293 zol_setfreq(zol, zol->curfreq);
294 }
295 return 0;
296 }
297 default:
298 return -ENOIOCTLCMD;
299 }
300}
301
302static int zol_ioctl(struct inode *inode, struct file *file,
303 unsigned int cmd, unsigned long arg)
304{
305 return video_usercopy(inode, file, cmd, arg, zol_do_ioctl);
306}
307
308static struct zol_device zoltrix_unit;
309
310static struct file_operations zoltrix_fops =
311{
312 .owner = THIS_MODULE,
313 .open = video_exclusive_open,
314 .release = video_exclusive_release,
315 .ioctl = zol_ioctl,
316 .llseek = no_llseek,
317};
318
319static struct video_device zoltrix_radio =
320{
321 .owner = THIS_MODULE,
322 .name = "Zoltrix Radio Plus",
323 .type = VID_TYPE_TUNER,
324 .hardware = VID_HARDWARE_ZOLTRIX,
325 .fops = &zoltrix_fops,
326};
327
328static int __init zoltrix_init(void)
329{
330 if (io == -1) {
331 printk(KERN_ERR "You must set an I/O address with io=0x???\n");
332 return -EINVAL;
333 }
334 if ((io != 0x20c) && (io != 0x30c)) {
335 printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
336 return -ENXIO;
337 }
338
339 zoltrix_radio.priv = &zoltrix_unit;
340 if (!request_region(io, 2, "zoltrix")) {
341 printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
342 return -EBUSY;
343 }
344
345 if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1)
346 {
347 release_region(io, 2);
348 return -EINVAL;
349 }
350 printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
351
352 init_MUTEX(&zoltrix_unit.lock);
353
354 /* mute card - prevents noisy bootups */
355
356 /* this ensures that the volume is all the way down */
357
358 outb(0, io);
359 outb(0, io);
360 msleep(20);
361 inb(io + 3);
362
363 zoltrix_unit.curvol = 0;
364 zoltrix_unit.stereo = 1;
365
366 return 0;
367}
368
369MODULE_AUTHOR("C.van Schaik");
370MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
371MODULE_LICENSE("GPL");
372
373module_param(io, int, 0);
374MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
375module_param(radio_nr, int, 0);
376
377static void __exit zoltrix_cleanup_module(void)
378{
379 video_unregister_device(&zoltrix_radio);
380 release_region(io, 2);
381}
382
383module_init(zoltrix_init);
384module_exit(zoltrix_cleanup_module);
385
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
new file mode 100644
index 000000000000..c1b3542dad88
--- /dev/null
+++ b/drivers/media/video/Kconfig
@@ -0,0 +1,360 @@
1#
2# Multimedia Video device configuration
3#
4
5menu "Video For Linux"
6 depends on VIDEO_DEV
7
8comment "Video Adapters"
9
10config VIDEO_BT848
11 tristate "BT848 Video For Linux"
12 depends on VIDEO_DEV && PCI && I2C
13 select I2C_ALGOBIT
14 select FW_LOADER
15 select VIDEO_BTCX
16 select VIDEO_BUF
17 select VIDEO_IR
18 select VIDEO_TUNER
19 select VIDEO_TVEEPROM
20 ---help---
21 Support for BT848 based frame grabber/overlay boards. This includes
22 the Miro, Hauppauge and STB boards. Please read the material in
23 <file:Documentation/video4linux/bttv/> for more information.
24
25 If you say Y or M here, you need to say Y or M to "I2C support" and
26 "I2C bit-banging interfaces" in the device drivers section.
27
28 To compile this driver as a module, choose M here: the
29 module will be called bttv.
30
31config VIDEO_PMS
32 tristate "Mediavision Pro Movie Studio Video For Linux"
33 depends on VIDEO_DEV && ISA
34 help
35 Say Y if you have such a thing.
36
37 To compile this driver as a module, choose M here: the
38 module will be called pms.
39
40config VIDEO_PLANB
41 tristate "PlanB Video-In on PowerMac"
42 depends on PPC_PMAC && VIDEO_DEV && BROKEN
43 help
44 PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
45 input hardware. If you want to experiment with this, say Y.
46 Otherwise, or if you don't understand a word, say N. See
47 <http://www.cpu.lu/~mlan/linux/dev/planb.html> for more info.
48
49 Saying M will compile this driver as a module (planb).
50
51config VIDEO_BWQCAM
52 tristate "Quickcam BW Video For Linux"
53 depends on VIDEO_DEV && PARPORT
54 help
55 Say Y have if you the black and white version of the QuickCam
56 camera. See the next option for the color version.
57
58 To compile this driver as a module, choose M here: the
59 module will be called bw-qcam.
60
61config VIDEO_CQCAM
62 tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
63 depends on EXPERIMENTAL && VIDEO_DEV && PARPORT
64 help
65 This is the video4linux driver for the colour version of the
66 Connectix QuickCam. If you have one of these cameras, say Y here,
67 otherwise say N. This driver does not work with the original
68 monochrome QuickCam, QuickCam VC or QuickClip. It is also available
69 as a module (c-qcam).
70 Read <file:Documentation/video4linux/CQcam.txt> for more information.
71
72config VIDEO_W9966
73 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
74 depends on PARPORT_1284 && VIDEO_DEV && PARPORT
75 help
76 Video4linux driver for Winbond's w9966 based Webcams.
77 Currently tested with the LifeView FlyCam Supra.
78 If you have one of these cameras, say Y here
79 otherwise say N.
80 This driver is also available as a module (w9966).
81
82 Check out <file:Documentation/video4linux/w9966.txt> for more
83 information.
84
85config VIDEO_CPIA
86 tristate "CPiA Video For Linux"
87 depends on VIDEO_DEV
88 ---help---
89 This is the video4linux driver for cameras based on Vision's CPiA
90 (Colour Processor Interface ASIC), such as the Creative Labs Video
91 Blaster Webcam II. If you have one of these cameras, say Y here
92 and select parallel port and/or USB lowlevel support below,
93 otherwise say N. This will not work with the Creative Webcam III.
94
95 Please read <file:Documentation/video4linux/README.cpia> for more
96 information.
97
98 This driver is also available as a module (cpia).
99
100config VIDEO_CPIA_PP
101 tristate "CPiA Parallel Port Lowlevel Support"
102 depends on PARPORT_1284 && VIDEO_CPIA && PARPORT
103 help
104 This is the lowlevel parallel port support for cameras based on
105 Vision's CPiA (Colour Processor Interface ASIC), such as the
106 Creative Webcam II. If you have the parallel port version of one
107 of these cameras, say Y here, otherwise say N. It is also available
108 as a module (cpia_pp).
109
110config VIDEO_CPIA_USB
111 tristate "CPiA USB Lowlevel Support"
112 depends on VIDEO_CPIA && USB
113 help
114 This is the lowlevel USB support for cameras based on Vision's CPiA
115 (Colour Processor Interface ASIC), such as the Creative Webcam II.
116 If you have the USB version of one of these cameras, say Y here,
117 otherwise say N. This will not work with the Creative Webcam III.
118 It is also available as a module (cpia_usb).
119
120config VIDEO_SAA5246A
121 tristate "SAA5246A, SAA5281 Teletext processor"
122 depends on VIDEO_DEV && I2C
123 help
124 Support for I2C bus based teletext using the SAA5246A or SAA5281
125 chip. Useful only if you live in Europe.
126
127 To compile this driver as a module, choose M here: the
128 module will be called saa5246a.
129
130config VIDEO_SAA5249
131 tristate "SAA5249 Teletext processor"
132 depends on VIDEO_DEV && I2C
133 help
134 Support for I2C bus based teletext using the SAA5249 chip. At the
135 moment this is only useful on some European WinTV cards.
136
137 To compile this driver as a module, choose M here: the
138 module will be called saa5249.
139
140config TUNER_3036
141 tristate "SAB3036 tuner"
142 depends on VIDEO_DEV && I2C
143 help
144 Say Y here to include support for Philips SAB3036 compatible tuners.
145 If in doubt, say N.
146
147config VIDEO_VINO
148 tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
149 depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
150 select I2C_ALGO_SGI
151 help
152 Say Y here to build in support for the Vino video input system found
153 on SGI Indy machines.
154
155config VIDEO_STRADIS
156 tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)"
157 depends on EXPERIMENTAL && VIDEO_DEV && PCI
158 help
159 Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
160 driver for PCI. There is a product page at
161 <http://www.stradis.com/decoder.html>.
162
163config VIDEO_ZORAN
164 tristate "Zoran ZR36057/36067 Video For Linux"
165 depends on VIDEO_DEV && PCI && I2C_ALGOBIT
166 help
167 Say Y for support for MJPEG capture cards based on the Zoran
168 36057/36067 PCI controller chipset. This includes the Iomega
169 Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is
170 a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For
171 more information, check <file:Documentation/video4linux/Zoran>.
172
173 To compile this driver as a module, choose M here: the
174 module will be called zr36067.
175
176config VIDEO_ZORAN_BUZ
177 tristate "Iomega Buz support"
178 depends on VIDEO_ZORAN
179 help
180 Support for the Iomega Buz MJPEG capture/playback card.
181
182config VIDEO_ZORAN_DC10
183 tristate "Pinnacle/Miro DC10(+) support"
184 depends on VIDEO_ZORAN
185 help
186 Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
187 card.
188
189config VIDEO_ZORAN_DC30
190 tristate "Pinnacle/Miro DC30(+) support"
191 depends on VIDEO_ZORAN
192 help
193 Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
194 card. This also supports really old DC10 cards based on the
195 zr36050 MJPEG codec and zr36016 VFE.
196
197config VIDEO_ZORAN_LML33
198 tristate "Linux Media Labs LML33 support"
199 depends on VIDEO_ZORAN
200 help
201 Support for the Linux Media Labs LML33 MJPEG capture/playback
202 card.
203
204config VIDEO_ZORAN_LML33R10
205 tristate "Linux Media Labs LML33R10 support"
206 depends on VIDEO_ZORAN
207 help
208 support for the Linux Media Labs LML33R10 MJPEG capture/playback
209 card.
210
211config VIDEO_ZR36120
212 tristate "Zoran ZR36120/36125 Video For Linux"
213 depends on VIDEO_DEV && PCI && I2C && BROKEN
214 help
215 Support for ZR36120/ZR36125 based frame grabber/overlay boards.
216 This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV,
217 and Buster boards. Please read the material in
218 <file:Documentation/video4linux/zr36120.txt> for more information.
219
220 To compile this driver as a module, choose M here: the
221 module will be called zr36120.
222
223config VIDEO_MEYE
224 tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
225 depends on VIDEO_DEV && PCI && SONYPI
226 ---help---
227 This is the video4linux driver for the Motion Eye camera found
228 in the Vaio Picturebook laptops. Please read the material in
229 <file:Documentation/video4linux/meye.txt> for more information.
230
231 If you say Y or M here, you need to say Y or M to "Sony Programmable
232 I/O Control Device" in the character device section.
233
234 To compile this driver as a module, choose M here: the
235 module will be called meye.
236
237config VIDEO_SAA7134
238 tristate "Philips SAA7134 support"
239 depends on VIDEO_DEV && PCI && I2C
240 select VIDEO_BUF
241 select VIDEO_IR
242 select VIDEO_TUNER
243 ---help---
244 This is a video4linux driver for Philips SAA7130/7134 based
245 TV cards.
246
247 To compile this driver as a module, choose M here: the
248 module will be called saa7134.
249
250config VIDEO_SAA7134_DVB
251 tristate "DVB Support for saa7134 based TV cards"
252 depends on VIDEO_SAA7134 && DVB_CORE
253 select VIDEO_BUF_DVB
254 select DVB_MT352
255 ---help---
256 This adds support for DVB cards based on the
257 Philips saa7134 chip.
258
259config VIDEO_MXB
260 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
261 depends on VIDEO_DEV && PCI
262 select VIDEO_SAA7146_VV
263 select VIDEO_TUNER
264 ---help---
265 This is a video4linux driver for the 'Multimedia eXtension Board'
266 TV card by Siemens-Nixdorf.
267
268 To compile this driver as a module, choose M here: the
269 module will be called mxb.
270
271config VIDEO_DPC
272 tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
273 depends on VIDEO_DEV && PCI
274 select VIDEO_SAA7146_VV
275 ---help---
276 This is a video4linux driver for the 'dpc7146 demonstration
277 board' by Philips-Semiconductors. It's the reference design
278 for SAA7146 bases boards, so if you have some unsupported
279 saa7146 based, analog video card, chances are good that it
280 will work with this skeleton driver.
281
282 To compile this driver as a module, choose M here: the
283 module will be called dpc7146.
284
285config VIDEO_HEXIUM_ORION
286 tristate "Hexium HV-PCI6 and Orion frame grabber"
287 depends on VIDEO_DEV && PCI
288 select VIDEO_SAA7146_VV
289 ---help---
290 This is a video4linux driver for the Hexium HV-PCI6 and
291 Orion frame grabber cards by Hexium.
292
293 To compile this driver as a module, choose M here: the
294 module will be called hexium_orion.
295
296config VIDEO_HEXIUM_GEMINI
297 tristate "Hexium Gemini frame grabber"
298 depends on VIDEO_DEV && PCI
299 select VIDEO_SAA7146_VV
300 ---help---
301 This is a video4linux driver for the Hexium Gemini frame
302 grabber card by Hexium. Please note that the Gemini Dual
303 card is *not* fully supported.
304
305 To compile this driver as a module, choose M here: the
306 module will be called hexium_gemini.
307
308config VIDEO_CX88
309 tristate "Conexant 2388x (bt878 successor) support"
310 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
311 select I2C_ALGOBIT
312 select FW_LOADER
313 select VIDEO_BTCX
314 select VIDEO_BUF
315 select VIDEO_TUNER
316 select VIDEO_TVEEPROM
317 select VIDEO_IR
318 ---help---
319 This is a video4linux driver for Conexant 2388x based
320 TV cards.
321
322 To compile this driver as a module, choose M here: the
323 module will be called cx8800
324
325config VIDEO_CX88_DVB
326 tristate "DVB Support for cx2388x based TV cards"
327 depends on VIDEO_CX88 && DVB_CORE
328 select VIDEO_BUF_DVB
329 select DVB_MT352
330 select DVB_OR51132
331 ---help---
332 This adds support for DVB/ATSC cards based on the
333 Connexant 2388x chip.
334
335config VIDEO_OVCAMCHIP
336 tristate "OmniVision Camera Chip support"
337 depends on VIDEO_DEV && I2C
338 ---help---
339 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
340 This driver is intended to be used with the ov511 and w9968cf USB
341 camera drivers.
342
343 To compile this driver as a module, choose M here: the
344 module will be called ovcamchip
345
346config VIDEO_M32R_AR
347 tristate "AR devices"
348 depends on M32R
349 ---help---
350 This is a video4linux driver for the Renesas AR (Artificial Retina)
351 camera module.
352
353config VIDEO_M32R_AR_M64278
354 tristate "Use Colour AR module M64278(VGA)"
355 depends on VIDEO_M32R_AR
356 ---help---
357 Say Y here to use the Renesas M64278E-800 camera module,
358 which supports VGA(640x480 pixcels) size of images.
359
360endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
new file mode 100644
index 000000000000..2dc906fdfa55
--- /dev/null
+++ b/drivers/media/video/Makefile
@@ -0,0 +1,56 @@
1#
2# Makefile for the video capture/playback device drivers.
3#
4
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8zr36067-objs := zoran_procfs.o zoran_device.o \
9 zoran_driver.o zoran_card.o
10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o
11
12obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
13
14obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
15 tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
22obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
23obj-$(CONFIG_VIDEO_W9966) += w9966.o
24obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o zr36060.o
25obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o zr36060.o
26obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \
27 zr36016.o
28obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o
29obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
30obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
31obj-$(CONFIG_VIDEO_PMS) += pms.o
32obj-$(CONFIG_VIDEO_PLANB) += planb.o
33obj-$(CONFIG_VIDEO_VINO) += vino.o
34obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
35obj-$(CONFIG_VIDEO_CPIA) += cpia.o
36obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
37obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
38obj-$(CONFIG_VIDEO_MEYE) += meye.o
39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
42obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
43obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
44obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
45obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
46obj-$(CONFIG_TUNER_3036) += tuner-3036.o
47
48obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o
49obj-$(CONFIG_VIDEO_BUF) += video-buf.o
50obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
51obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
52obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
53
54obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
55
56EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
new file mode 100644
index 000000000000..80254caa444c
--- /dev/null
+++ b/drivers/media/video/adv7170.c
@@ -0,0 +1,535 @@
1/*
2 * adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
3 *
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
5 *
6 * Based on adv7176 driver by:
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
10 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
11 * - some corrections for Pinnacle Systems Inc. DC10plus card.
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
15 *
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
53MODULE_AUTHOR("Maxim Yevtyushkin");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(x) (x)->name
60
61#include <linux/video_encoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75struct adv7170 {
76 unsigned char reg[128];
77
78 int norm;
79 int input;
80 int enable;
81 int bright;
82 int contrast;
83 int hue;
84 int sat;
85};
86
87#define I2C_ADV7170 0xd4
88#define I2C_ADV7171 0x54
89
90static char adv7170_name[] = "adv7170";
91static char adv7171_name[] = "adv7171";
92
93static char *inputs[] = { "pass_through", "play_back" };
94static char *norms[] = { "PAL", "NTSC" };
95
96/* ----------------------------------------------------------------------- */
97
98static inline int
99adv7170_write (struct i2c_client *client,
100 u8 reg,
101 u8 value)
102{
103 struct adv7170 *encoder = i2c_get_clientdata(client);
104
105 encoder->reg[reg] = value;
106 return i2c_smbus_write_byte_data(client, reg, value);
107}
108
109static inline int
110adv7170_read (struct i2c_client *client,
111 u8 reg)
112{
113 return i2c_smbus_read_byte_data(client, reg);
114}
115
116static int
117adv7170_write_block (struct i2c_client *client,
118 const u8 *data,
119 unsigned int len)
120{
121 int ret = -1;
122 u8 reg;
123
124 /* the adv7170 has an autoincrement function, use it if
125 * the adapter understands raw I2C */
126 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
127 /* do raw I2C, not smbus compatible */
128 struct adv7170 *encoder = i2c_get_clientdata(client);
129 struct i2c_msg msg;
130 u8 block_data[32];
131
132 msg.addr = client->addr;
133 msg.flags = 0;
134 while (len >= 2) {
135 msg.buf = (char *) block_data;
136 msg.len = 0;
137 block_data[msg.len++] = reg = data[0];
138 do {
139 block_data[msg.len++] =
140 encoder->reg[reg++] = data[1];
141 len -= 2;
142 data += 2;
143 } while (len >= 2 && data[0] == reg &&
144 msg.len < 32);
145 if ((ret = i2c_transfer(client->adapter,
146 &msg, 1)) < 0)
147 break;
148 }
149 } else {
150 /* do some slow I2C emulation kind of thing */
151 while (len >= 2) {
152 reg = *data++;
153 if ((ret = adv7170_write(client, reg,
154 *data++)) < 0)
155 break;
156 len -= 2;
157 }
158 }
159
160 return ret;
161}
162
163/* ----------------------------------------------------------------------- */
164// Output filter: S-Video Composite
165
166#define MR050 0x11 //0x09
167#define MR060 0x14 //0x0c
168
169//---------------------------------------------------------------------------
170
171#define TR0MODE 0x4c
172#define TR0RST 0x80
173
174#define TR1CAPT 0x00
175#define TR1PLAY 0x00
176
177
178static const unsigned char init_NTSC[] = {
179 0x00, 0x10, // MR0
180 0x01, 0x20, // MR1
181 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
182 0x03, 0x80, // MR3
183 0x04, 0x30, // MR4
184 0x05, 0x00, // Reserved
185 0x06, 0x00, // Reserved
186 0x07, TR0MODE, // TM0
187 0x08, TR1CAPT, // TM1
188 0x09, 0x16, // Fsc0
189 0x0a, 0x7c, // Fsc1
190 0x0b, 0xf0, // Fsc2
191 0x0c, 0x21, // Fsc3
192 0x0d, 0x00, // Subcarrier Phase
193 0x0e, 0x00, // Closed Capt. Ext 0
194 0x0f, 0x00, // Closed Capt. Ext 1
195 0x10, 0x00, // Closed Capt. 0
196 0x11, 0x00, // Closed Capt. 1
197 0x12, 0x00, // Pedestal Ctl 0
198 0x13, 0x00, // Pedestal Ctl 1
199 0x14, 0x00, // Pedestal Ctl 2
200 0x15, 0x00, // Pedestal Ctl 3
201 0x16, 0x00, // CGMS_WSS_0
202 0x17, 0x00, // CGMS_WSS_1
203 0x18, 0x00, // CGMS_WSS_2
204 0x19, 0x00, // Teletext Ctl
205};
206
207static const unsigned char init_PAL[] = {
208 0x00, 0x71, // MR0
209 0x01, 0x20, // MR1
210 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
211 0x03, 0x80, // MR3
212 0x04, 0x30, // MR4
213 0x05, 0x00, // Reserved
214 0x06, 0x00, // Reserved
215 0x07, TR0MODE, // TM0
216 0x08, TR1CAPT, // TM1
217 0x09, 0xcb, // Fsc0
218 0x0a, 0x8a, // Fsc1
219 0x0b, 0x09, // Fsc2
220 0x0c, 0x2a, // Fsc3
221 0x0d, 0x00, // Subcarrier Phase
222 0x0e, 0x00, // Closed Capt. Ext 0
223 0x0f, 0x00, // Closed Capt. Ext 1
224 0x10, 0x00, // Closed Capt. 0
225 0x11, 0x00, // Closed Capt. 1
226 0x12, 0x00, // Pedestal Ctl 0
227 0x13, 0x00, // Pedestal Ctl 1
228 0x14, 0x00, // Pedestal Ctl 2
229 0x15, 0x00, // Pedestal Ctl 3
230 0x16, 0x00, // CGMS_WSS_0
231 0x17, 0x00, // CGMS_WSS_1
232 0x18, 0x00, // CGMS_WSS_2
233 0x19, 0x00, // Teletext Ctl
234};
235
236
237static int
238adv7170_command (struct i2c_client *client,
239 unsigned int cmd,
240 void * arg)
241{
242 struct adv7170 *encoder = i2c_get_clientdata(client);
243
244 switch (cmd) {
245
246 case 0:
247#if 0
248 /* This is just for testing!!! */
249 adv7170_write_block(client, init_common,
250 sizeof(init_common));
251 adv7170_write(client, 0x07, TR0MODE | TR0RST);
252 adv7170_write(client, 0x07, TR0MODE);
253#endif
254 break;
255
256 case ENCODER_GET_CAPABILITIES:
257 {
258 struct video_encoder_capability *cap = arg;
259
260 cap->flags = VIDEO_ENCODER_PAL |
261 VIDEO_ENCODER_NTSC;
262 cap->inputs = 2;
263 cap->outputs = 1;
264 }
265 break;
266
267 case ENCODER_SET_NORM:
268 {
269 int iarg = *(int *) arg;
270
271 dprintk(1, KERN_DEBUG "%s_command: set norm %d",
272 I2C_NAME(client), iarg);
273
274 switch (iarg) {
275
276 case VIDEO_MODE_NTSC:
277 adv7170_write_block(client, init_NTSC,
278 sizeof(init_NTSC));
279 if (encoder->input == 0)
280 adv7170_write(client, 0x02, 0x0e); // Enable genlock
281 adv7170_write(client, 0x07, TR0MODE | TR0RST);
282 adv7170_write(client, 0x07, TR0MODE);
283 break;
284
285 case VIDEO_MODE_PAL:
286 adv7170_write_block(client, init_PAL,
287 sizeof(init_PAL));
288 if (encoder->input == 0)
289 adv7170_write(client, 0x02, 0x0e); // Enable genlock
290 adv7170_write(client, 0x07, TR0MODE | TR0RST);
291 adv7170_write(client, 0x07, TR0MODE);
292 break;
293
294 default:
295 dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
296 I2C_NAME(client), iarg);
297 return -EINVAL;
298
299 }
300 dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
301 norms[iarg]);
302 encoder->norm = iarg;
303 }
304 break;
305
306 case ENCODER_SET_INPUT:
307 {
308 int iarg = *(int *) arg;
309
310 /* RJ: *iarg = 0: input is from decoder
311 *iarg = 1: input is from ZR36060
312 *iarg = 2: color bar */
313
314 dprintk(1, KERN_DEBUG "%s_command: set input from %s\n",
315 I2C_NAME(client),
316 iarg == 0 ? "decoder" : "ZR36060");
317
318 switch (iarg) {
319
320 case 0:
321 adv7170_write(client, 0x01, 0x20);
322 adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
323 adv7170_write(client, 0x02, 0x0e); // Enable genlock
324 adv7170_write(client, 0x07, TR0MODE | TR0RST);
325 adv7170_write(client, 0x07, TR0MODE);
326 //udelay(10);
327 break;
328
329 case 1:
330 adv7170_write(client, 0x01, 0x00);
331 adv7170_write(client, 0x08, TR1PLAY); /* TR1 */
332 adv7170_write(client, 0x02, 0x08);
333 adv7170_write(client, 0x07, TR0MODE | TR0RST);
334 adv7170_write(client, 0x07, TR0MODE);
335 //udelay(10);
336 break;
337
338 default:
339 dprintk(1, KERN_ERR "%s: illegal input: %d\n",
340 I2C_NAME(client), iarg);
341 return -EINVAL;
342
343 }
344 dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
345 inputs[iarg]);
346 encoder->input = iarg;
347 }
348 break;
349
350 case ENCODER_SET_OUTPUT:
351 {
352 int *iarg = arg;
353
354 /* not much choice of outputs */
355 if (*iarg != 0) {
356 return -EINVAL;
357 }
358 }
359 break;
360
361 case ENCODER_ENABLE_OUTPUT:
362 {
363 int *iarg = arg;
364
365 encoder->enable = !!*iarg;
366 }
367 break;
368
369 default:
370 return -EINVAL;
371 }
372
373 return 0;
374}
375
376/* ----------------------------------------------------------------------- */
377
378/*
379 * Generic i2c probe
380 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
381 */
382static unsigned short normal_i2c[] =
383 { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
384 I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
385 I2C_CLIENT_END
386};
387static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
388
389static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
390static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
391static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
392static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
393static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
394
395static struct i2c_client_address_data addr_data = {
396 .normal_i2c = normal_i2c,
397 .normal_i2c_range = normal_i2c_range,
398 .probe = probe,
399 .probe_range = probe_range,
400 .ignore = ignore,
401 .ignore_range = ignore_range,
402 .force = force
403};
404
405static struct i2c_driver i2c_driver_adv7170;
406
407static int
408adv7170_detect_client (struct i2c_adapter *adapter,
409 int address,
410 int kind)
411{
412 int i;
413 struct i2c_client *client;
414 struct adv7170 *encoder;
415 char *dname;
416
417 dprintk(1,
418 KERN_INFO
419 "adv7170.c: detecting adv7170 client on address 0x%x\n",
420 address << 1);
421
422 /* Check if the adapter supports the needed features */
423 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
424 return 0;
425
426 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
427 if (client == 0)
428 return -ENOMEM;
429 memset(client, 0, sizeof(struct i2c_client));
430 client->addr = address;
431 client->adapter = adapter;
432 client->driver = &i2c_driver_adv7170;
433 client->flags = I2C_CLIENT_ALLOW_USE;
434 if ((client->addr == I2C_ADV7170 >> 1) ||
435 (client->addr == (I2C_ADV7170 >> 1) + 1)) {
436 dname = adv7170_name;
437 } else if ((client->addr == I2C_ADV7171 >> 1) ||
438 (client->addr == (I2C_ADV7171 >> 1) + 1)) {
439 dname = adv7171_name;
440 } else {
441 /* We should never get here!!! */
442 kfree(client);
443 return 0;
444 }
445 strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
446
447 encoder = kmalloc(sizeof(struct adv7170), GFP_KERNEL);
448 if (encoder == NULL) {
449 kfree(client);
450 return -ENOMEM;
451 }
452 memset(encoder, 0, sizeof(struct adv7170));
453 encoder->norm = VIDEO_MODE_NTSC;
454 encoder->input = 0;
455 encoder->enable = 1;
456 i2c_set_clientdata(client, encoder);
457
458 i = i2c_attach_client(client);
459 if (i) {
460 kfree(client);
461 kfree(encoder);
462 return i;
463 }
464
465 i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
466 if (i >= 0) {
467 i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
468 i = adv7170_write(client, 0x07, TR0MODE);
469 i = adv7170_read(client, 0x12);
470 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n",
471 I2C_NAME(client), i & 1, client->addr << 1);
472 }
473 if (i < 0) {
474 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
475 I2C_NAME(client), i);
476 }
477
478 return 0;
479}
480
481static int
482adv7170_attach_adapter (struct i2c_adapter *adapter)
483{
484 dprintk(1,
485 KERN_INFO
486 "adv7170.c: starting probe for adapter %s (0x%x)\n",
487 I2C_NAME(adapter), adapter->id);
488 return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
489}
490
491static int
492adv7170_detach_client (struct i2c_client *client)
493{
494 struct adv7170 *encoder = i2c_get_clientdata(client);
495 int err;
496
497 err = i2c_detach_client(client);
498 if (err) {
499 return err;
500 }
501
502 kfree(encoder);
503 kfree(client);
504
505 return 0;
506}
507
508/* ----------------------------------------------------------------------- */
509
510static struct i2c_driver i2c_driver_adv7170 = {
511 .owner = THIS_MODULE,
512 .name = "adv7170", /* name */
513
514 .id = I2C_DRIVERID_ADV7170,
515 .flags = I2C_DF_NOTIFY,
516
517 .attach_adapter = adv7170_attach_adapter,
518 .detach_client = adv7170_detach_client,
519 .command = adv7170_command,
520};
521
522static int __init
523adv7170_init (void)
524{
525 return i2c_add_driver(&i2c_driver_adv7170);
526}
527
528static void __exit
529adv7170_exit (void)
530{
531 i2c_del_driver(&i2c_driver_adv7170);
532}
533
534module_init(adv7170_init);
535module_exit(adv7170_exit);
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
new file mode 100644
index 000000000000..95d0974b0ab5
--- /dev/null
+++ b/drivers/media/video/adv7175.c
@@ -0,0 +1,585 @@
1/*
2 * adv7175 - adv7175a video encoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
6 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
7 * - some corrections for Pinnacle Systems Inc. DC10plus card.
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/errno.h>
31#include <linux/fs.h>
32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/pci.h>
37#include <linux/signal.h>
38#include <asm/io.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <linux/sched.h>
42#include <asm/segment.h>
43#include <linux/types.h>
44
45#include <linux/videodev.h>
46#include <asm/uaccess.h>
47
48MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
49MODULE_AUTHOR("Dave Perks");
50MODULE_LICENSE("GPL");
51
52#include <linux/i2c.h>
53#include <linux/i2c-dev.h>
54
55#define I2C_NAME(s) (s)->name
56
57#include <linux/video_encoder.h>
58
59static int debug = 0;
60module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
63#define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
68
69/* ----------------------------------------------------------------------- */
70
71struct adv7175 {
72 unsigned char reg[128];
73
74 int norm;
75 int input;
76 int enable;
77 int bright;
78 int contrast;
79 int hue;
80 int sat;
81};
82
83#define I2C_ADV7175 0xd4
84#define I2C_ADV7176 0x54
85
86static char adv7175_name[] = "adv7175";
87static char adv7176_name[] = "adv7176";
88
89static char *inputs[] = { "pass_through", "play_back", "color_bar" };
90static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
91
92/* ----------------------------------------------------------------------- */
93
94static inline int
95adv7175_write (struct i2c_client *client,
96 u8 reg,
97 u8 value)
98{
99 struct adv7175 *encoder = i2c_get_clientdata(client);
100
101 encoder->reg[reg] = value;
102 return i2c_smbus_write_byte_data(client, reg, value);
103}
104
105static inline int
106adv7175_read (struct i2c_client *client,
107 u8 reg)
108{
109 return i2c_smbus_read_byte_data(client, reg);
110}
111
112static int
113adv7175_write_block (struct i2c_client *client,
114 const u8 *data,
115 unsigned int len)
116{
117 int ret = -1;
118 u8 reg;
119
120 /* the adv7175 has an autoincrement function, use it if
121 * the adapter understands raw I2C */
122 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
123 /* do raw I2C, not smbus compatible */
124 struct adv7175 *encoder = i2c_get_clientdata(client);
125 struct i2c_msg msg;
126 u8 block_data[32];
127
128 msg.addr = client->addr;
129 msg.flags = 0;
130 while (len >= 2) {
131 msg.buf = (char *) block_data;
132 msg.len = 0;
133 block_data[msg.len++] = reg = data[0];
134 do {
135 block_data[msg.len++] =
136 encoder->reg[reg++] = data[1];
137 len -= 2;
138 data += 2;
139 } while (len >= 2 && data[0] == reg &&
140 msg.len < 32);
141 if ((ret = i2c_transfer(client->adapter,
142 &msg, 1)) < 0)
143 break;
144 }
145 } else {
146 /* do some slow I2C emulation kind of thing */
147 while (len >= 2) {
148 reg = *data++;
149 if ((ret = adv7175_write(client, reg,
150 *data++)) < 0)
151 break;
152 len -= 2;
153 }
154 }
155
156 return ret;
157}
158
159static void
160set_subcarrier_freq (struct i2c_client *client,
161 int pass_through)
162{
163 /* for some reason pass_through NTSC needs
164 * a different sub-carrier freq to remain stable. */
165 if(pass_through)
166 adv7175_write(client, 0x02, 0x00);
167 else
168 adv7175_write(client, 0x02, 0x55);
169
170 adv7175_write(client, 0x03, 0x55);
171 adv7175_write(client, 0x04, 0x55);
172 adv7175_write(client, 0x05, 0x25);
173}
174
175#ifdef ENCODER_DUMP
176static void
177dump (struct i2c_client *client)
178{
179 struct adv7175 *encoder = i2c_get_clientdata(client);
180 int i, j;
181
182 printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client));
183 for (i = 0; i < 182 / 8; i++) {
184 printk("%s: 0x%02x -", I2C_NAME(client), i * 8);
185 for (j = 0; j < 8; j++) {
186 printk(" 0x%02x", encoder->reg[i * 8 + j]);
187 }
188 printk("\n");
189 }
190}
191#endif
192
193/* ----------------------------------------------------------------------- */
194// Output filter: S-Video Composite
195
196#define MR050 0x11 //0x09
197#define MR060 0x14 //0x0c
198
199//---------------------------------------------------------------------------
200
201#define TR0MODE 0x46
202#define TR0RST 0x80
203
204#define TR1CAPT 0x80
205#define TR1PLAY 0x00
206
207static const unsigned char init_common[] = {
208
209 0x00, MR050, /* MR0, PAL enabled */
210 0x01, 0x00, /* MR1 */
211 0x02, 0x0c, /* subc. freq. */
212 0x03, 0x8c, /* subc. freq. */
213 0x04, 0x79, /* subc. freq. */
214 0x05, 0x26, /* subc. freq. */
215 0x06, 0x40, /* subc. phase */
216
217 0x07, TR0MODE, /* TR0, 16bit */
218 0x08, 0x21, /* */
219 0x09, 0x00, /* */
220 0x0a, 0x00, /* */
221 0x0b, 0x00, /* */
222 0x0c, TR1CAPT, /* TR1 */
223 0x0d, 0x4f, /* MR2 */
224 0x0e, 0x00, /* */
225 0x0f, 0x00, /* */
226 0x10, 0x00, /* */
227 0x11, 0x00, /* */
228};
229
230static const unsigned char init_pal[] = {
231 0x00, MR050, /* MR0, PAL enabled */
232 0x01, 0x00, /* MR1 */
233 0x02, 0x0c, /* subc. freq. */
234 0x03, 0x8c, /* subc. freq. */
235 0x04, 0x79, /* subc. freq. */
236 0x05, 0x26, /* subc. freq. */
237 0x06, 0x40, /* subc. phase */
238};
239
240static const unsigned char init_ntsc[] = {
241 0x00, MR060, /* MR0, NTSC enabled */
242 0x01, 0x00, /* MR1 */
243 0x02, 0x55, /* subc. freq. */
244 0x03, 0x55, /* subc. freq. */
245 0x04, 0x55, /* subc. freq. */
246 0x05, 0x25, /* subc. freq. */
247 0x06, 0x1a, /* subc. phase */
248};
249
250static int
251adv7175_command (struct i2c_client *client,
252 unsigned int cmd,
253 void *arg)
254{
255 struct adv7175 *encoder = i2c_get_clientdata(client);
256
257 switch (cmd) {
258
259 case 0:
260 /* This is just for testing!!! */
261 adv7175_write_block(client, init_common,
262 sizeof(init_common));
263 adv7175_write(client, 0x07, TR0MODE | TR0RST);
264 adv7175_write(client, 0x07, TR0MODE);
265 break;
266
267 case ENCODER_GET_CAPABILITIES:
268 {
269 struct video_encoder_capability *cap = arg;
270
271 cap->flags = VIDEO_ENCODER_PAL |
272 VIDEO_ENCODER_NTSC |
273 VIDEO_ENCODER_SECAM; /* well, hacky */
274 cap->inputs = 2;
275 cap->outputs = 1;
276 }
277 break;
278
279 case ENCODER_SET_NORM:
280 {
281 int iarg = *(int *) arg;
282
283 switch (iarg) {
284
285 case VIDEO_MODE_NTSC:
286 adv7175_write_block(client, init_ntsc,
287 sizeof(init_ntsc));
288 if (encoder->input == 0)
289 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
290 adv7175_write(client, 0x07, TR0MODE | TR0RST);
291 adv7175_write(client, 0x07, TR0MODE);
292 break;
293
294 case VIDEO_MODE_PAL:
295 adv7175_write_block(client, init_pal,
296 sizeof(init_pal));
297 if (encoder->input == 0)
298 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
299 adv7175_write(client, 0x07, TR0MODE | TR0RST);
300 adv7175_write(client, 0x07, TR0MODE);
301 break;
302
303 case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM.
304 /* This is an attempt to convert
305 * SECAM->PAL (typically it does not work
306 * due to genlock: when decoder is in SECAM
307 * and encoder in in PAL the subcarrier can
308 * not be syncronized with horizontal
309 * quency) */
310 adv7175_write_block(client, init_pal,
311 sizeof(init_pal));
312 if (encoder->input == 0)
313 adv7175_write(client, 0x0d, 0x49); // Disable genlock
314 adv7175_write(client, 0x07, TR0MODE | TR0RST);
315 adv7175_write(client, 0x07, TR0MODE);
316 break;
317 default:
318 dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
319 I2C_NAME(client), iarg);
320 return -EINVAL;
321
322 }
323 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
324 norms[iarg]);
325 encoder->norm = iarg;
326 }
327 break;
328
329 case ENCODER_SET_INPUT:
330 {
331 int iarg = *(int *) arg;
332
333 /* RJ: *iarg = 0: input is from SAA7110
334 *iarg = 1: input is from ZR36060
335 *iarg = 2: color bar */
336
337 switch (iarg) {
338
339 case 0:
340 adv7175_write(client, 0x01, 0x00);
341
342 if (encoder->norm == VIDEO_MODE_NTSC)
343 set_subcarrier_freq(client, 1);
344
345 adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */
346 if (encoder->norm == VIDEO_MODE_SECAM)
347 adv7175_write(client, 0x0d, 0x49); // Disable genlock
348 else
349 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
350 adv7175_write(client, 0x07, TR0MODE | TR0RST);
351 adv7175_write(client, 0x07, TR0MODE);
352 //udelay(10);
353 break;
354
355 case 1:
356 adv7175_write(client, 0x01, 0x00);
357
358 if (encoder->norm == VIDEO_MODE_NTSC)
359 set_subcarrier_freq(client, 0);
360
361 adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */
362 adv7175_write(client, 0x0d, 0x49);
363 adv7175_write(client, 0x07, TR0MODE | TR0RST);
364 adv7175_write(client, 0x07, TR0MODE);
365 //udelay(10);
366 break;
367
368 case 2:
369 adv7175_write(client, 0x01, 0x80);
370
371 if (encoder->norm == VIDEO_MODE_NTSC)
372 set_subcarrier_freq(client, 0);
373
374 adv7175_write(client, 0x0d, 0x49);
375 adv7175_write(client, 0x07, TR0MODE | TR0RST);
376 adv7175_write(client, 0x07, TR0MODE);
377 //udelay(10);
378 break;
379
380 default:
381 dprintk(1, KERN_ERR "%s: illegal input: %d\n",
382 I2C_NAME(client), iarg);
383 return -EINVAL;
384
385 }
386 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
387 inputs[iarg]);
388 encoder->input = iarg;
389 }
390 break;
391
392 case ENCODER_SET_OUTPUT:
393 {
394 int *iarg = arg;
395
396 /* not much choice of outputs */
397 if (*iarg != 0) {
398 return -EINVAL;
399 }
400 }
401 break;
402
403 case ENCODER_ENABLE_OUTPUT:
404 {
405 int *iarg = arg;
406
407 encoder->enable = !!*iarg;
408 }
409 break;
410
411#ifdef ENCODER_DUMP
412 case ENCODER_DUMP:
413 {
414 dump(client);
415 }
416 break;
417#endif
418
419 default:
420 return -EINVAL;
421 }
422
423 return 0;
424}
425
426/* ----------------------------------------------------------------------- */
427
428/*
429 * Generic i2c probe
430 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
431 */
432static unsigned short normal_i2c[] =
433 { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
434 I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
435 I2C_CLIENT_END
436};
437static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
438
439static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
440static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
441static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
442static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
443static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
444
445static struct i2c_client_address_data addr_data = {
446 .normal_i2c = normal_i2c,
447 .normal_i2c_range = normal_i2c_range,
448 .probe = probe,
449 .probe_range = probe_range,
450 .ignore = ignore,
451 .ignore_range = ignore_range,
452 .force = force
453};
454
455static struct i2c_driver i2c_driver_adv7175;
456
457static int
458adv7175_detect_client (struct i2c_adapter *adapter,
459 int address,
460 int kind)
461{
462 int i;
463 struct i2c_client *client;
464 struct adv7175 *encoder;
465 char *dname;
466
467 dprintk(1,
468 KERN_INFO
469 "adv7175.c: detecting adv7175 client on address 0x%x\n",
470 address << 1);
471
472 /* Check if the adapter supports the needed features */
473 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
474 return 0;
475
476 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
477 if (client == 0)
478 return -ENOMEM;
479 memset(client, 0, sizeof(struct i2c_client));
480 client->addr = address;
481 client->adapter = adapter;
482 client->driver = &i2c_driver_adv7175;
483 client->flags = I2C_CLIENT_ALLOW_USE;
484 if ((client->addr == I2C_ADV7175 >> 1) ||
485 (client->addr == (I2C_ADV7175 >> 1) + 1)) {
486 dname = adv7175_name;
487 } else if ((client->addr == I2C_ADV7176 >> 1) ||
488 (client->addr == (I2C_ADV7176 >> 1) + 1)) {
489 dname = adv7176_name;
490 } else {
491 /* We should never get here!!! */
492 kfree(client);
493 return 0;
494 }
495 strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
496
497 encoder = kmalloc(sizeof(struct adv7175), GFP_KERNEL);
498 if (encoder == NULL) {
499 kfree(client);
500 return -ENOMEM;
501 }
502 memset(encoder, 0, sizeof(struct adv7175));
503 encoder->norm = VIDEO_MODE_PAL;
504 encoder->input = 0;
505 encoder->enable = 1;
506 i2c_set_clientdata(client, encoder);
507
508 i = i2c_attach_client(client);
509 if (i) {
510 kfree(client);
511 kfree(encoder);
512 return i;
513 }
514
515 i = adv7175_write_block(client, init_common, sizeof(init_common));
516 if (i >= 0) {
517 i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
518 i = adv7175_write(client, 0x07, TR0MODE);
519 i = adv7175_read(client, 0x12);
520 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
521 I2C_NAME(client), i & 1, client->addr << 1);
522 }
523 if (i < 0) {
524 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
525 I2C_NAME(client), i);
526 }
527
528 return 0;
529}
530
531static int
532adv7175_attach_adapter (struct i2c_adapter *adapter)
533{
534 dprintk(1,
535 KERN_INFO
536 "adv7175.c: starting probe for adapter %s (0x%x)\n",
537 I2C_NAME(adapter), adapter->id);
538 return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
539}
540
541static int
542adv7175_detach_client (struct i2c_client *client)
543{
544 struct adv7175 *encoder = i2c_get_clientdata(client);
545 int err;
546
547 err = i2c_detach_client(client);
548 if (err) {
549 return err;
550 }
551
552 kfree(encoder);
553 kfree(client);
554
555 return 0;
556}
557
558/* ----------------------------------------------------------------------- */
559
560static struct i2c_driver i2c_driver_adv7175 = {
561 .owner = THIS_MODULE,
562 .name = "adv7175", /* name */
563
564 .id = I2C_DRIVERID_ADV7175,
565 .flags = I2C_DF_NOTIFY,
566
567 .attach_adapter = adv7175_attach_adapter,
568 .detach_client = adv7175_detach_client,
569 .command = adv7175_command,
570};
571
572static int __init
573adv7175_init (void)
574{
575 return i2c_add_driver(&i2c_driver_adv7175);
576}
577
578static void __exit
579adv7175_exit (void)
580{
581 i2c_del_driver(&i2c_driver_adv7175);
582}
583
584module_init(adv7175_init);
585module_exit(adv7175_exit);
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
new file mode 100644
index 000000000000..87fd3a7bb392
--- /dev/null
+++ b/drivers/media/video/arv.c
@@ -0,0 +1,916 @@
1/*
2 * Colour AR M64278(VGA) driver for Video4Linux
3 *
4 * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Some code is taken from AR driver sample program for M3T-M32700UT.
12 *
13 * AR driver sample (M32R SDK):
14 * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION
15 * AND RENESAS SOLUTIONS CORPORATION
16 * All Rights Reserved.
17 *
18 * 2003-09-01: Support w3cam by Takeo Takahashi
19 */
20
21#include <linux/config.h>
22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/sched.h>
34#include <linux/videodev.h>
35
36#include <asm/semaphore.h>
37#include <asm/uaccess.h>
38#include <asm/m32r.h>
39#include <asm/io.h>
40#include <asm/dma.h>
41#include <asm/byteorder.h>
42
43#if 0
44#define DEBUG(n, args...) printk(args)
45#define CHECK_LOST 1
46#else
47#define DEBUG(n, args...)
48#define CHECK_LOST 0
49#endif
50
51/*
52 * USE_INT is always 0, interrupt mode is not available
53 * on linux due to lack of speed
54 */
55#define USE_INT 0 /* Don't modify */
56
57#define VERSION "0.03"
58
59#define ar_inl(addr) inl((unsigned long)(addr))
60#define ar_outl(val, addr) outl((unsigned long)(val),(unsigned long)(addr))
61
62extern struct cpuinfo_m32r boot_cpu_data;
63
64/*
65 * CCD pixel size
66 * Note that M32700UT does not support CIF mode, but QVGA is
67 * supported by M32700UT hardware using VGA mode of AR LSI.
68 *
69 * Supported: VGA (Normal mode, Interlace mode)
70 * QVGA (Always Interlace mode of VGA)
71 *
72 */
73#define AR_WIDTH_VGA 640
74#define AR_HEIGHT_VGA 480
75#define AR_WIDTH_QVGA 320
76#define AR_HEIGHT_QVGA 240
77#define MIN_AR_WIDTH AR_WIDTH_QVGA
78#define MIN_AR_HEIGHT AR_HEIGHT_QVGA
79#define MAX_AR_WIDTH AR_WIDTH_VGA
80#define MAX_AR_HEIGHT AR_HEIGHT_VGA
81
82/* bits & bytes per pixel */
83#define AR_BITS_PER_PIXEL 16
84#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL/8)
85
86/* line buffer size */
87#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
88#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL)
89#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA
90
91/* frame size & type */
92#define AR_FRAME_BYTES_VGA \
93 (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL)
94#define AR_FRAME_BYTES_QVGA \
95 (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL)
96#define MAX_AR_FRAME_BYTES \
97 (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL)
98
99#define AR_MAX_FRAME 15
100
101/* capture size */
102#define AR_SIZE_VGA 0
103#define AR_SIZE_QVGA 1
104
105/* capture mode */
106#define AR_MODE_INTERLACE 0
107#define AR_MODE_NORMAL 1
108
109struct ar_device {
110 struct video_device *vdev;
111 unsigned int start_capture; /* duaring capture in INT. mode. */
112#if USE_INT
113 unsigned char *line_buff; /* DMA line buffer */
114#endif
115 unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */
116 short size; /* capture size */
117 short mode; /* capture mode */
118 int width, height;
119 int frame_bytes, line_bytes;
120 wait_queue_head_t wait;
121 struct semaphore lock;
122};
123
124static int video_nr = -1; /* video device number (first free) */
125static unsigned char yuv[MAX_AR_FRAME_BYTES];
126
127/* module parameters */
128/* default frequency */
129#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */
130static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */
131static int vga = 0; /* default mode(0:QVGA mode, other:VGA mode) */
132static int vga_interlace = 0; /* 0 is normal mode for, else interlace mode */
133MODULE_PARM(freq, "i");
134MODULE_PARM(vga, "i");
135MODULE_PARM(vga_interlace, "i");
136
137static int ar_initialize(struct video_device *dev);
138
139static inline void wait_for_vsync(void)
140{
141 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
142 cpu_relax();
143 while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */
144 cpu_relax();
145}
146
147static inline void wait_acknowledge(void)
148{
149 int i;
150
151 for (i = 0; i < 1000; i++)
152 cpu_relax();
153 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK)
154 cpu_relax();
155}
156
157/*******************************************************************
158 * I2C functions
159 *******************************************************************/
160void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
161 unsigned long data3)
162{
163 int i;
164
165 /* Slave Address */
166 ar_outl(addr, PLDI2CDATA);
167 wait_for_vsync();
168
169 /* Start */
170 ar_outl(1, PLDI2CCND);
171 wait_acknowledge();
172
173 /* Transfer data 1 */
174 ar_outl(data1, PLDI2CDATA);
175 wait_for_vsync();
176 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
177 wait_acknowledge();
178
179 /* Transfer data 2 */
180 ar_outl(data2, PLDI2CDATA);
181 wait_for_vsync();
182 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
183 wait_acknowledge();
184
185 if (n == 3) {
186 /* Transfer data 3 */
187 ar_outl(data3, PLDI2CDATA);
188 wait_for_vsync();
189 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
190 wait_acknowledge();
191 }
192
193 /* Stop */
194 for (i = 0; i < 100; i++)
195 cpu_relax();
196 ar_outl(2, PLDI2CCND);
197 ar_outl(2, PLDI2CCND);
198
199 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
200 cpu_relax();
201}
202
203
204void init_iic(void)
205{
206 DEBUG(1, "init_iic:\n");
207
208 /*
209 * ICU Setting (iic)
210 */
211 /* I2C Setting */
212 ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
213 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
214 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
215
216 /* I2C CLK */
217 /* 50MH-100k */
218 if (freq == 75) {
219 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
220 } else if (freq == 50) {
221 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
222 } else {
223 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
224 }
225 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
226}
227
228/**************************************************************************
229 *
230 * Video4Linux Interface functions
231 *
232 **************************************************************************/
233
234static inline void disable_dma(void)
235{
236 ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */
237}
238
239static inline void enable_dma(void)
240{
241 ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */
242}
243
244static inline void clear_dma_status(void)
245{
246 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
247}
248
249static inline void wait_for_vertical_sync(int exp_line)
250{
251#if CHECK_LOST
252 int tmout = 10000; /* FIXME */
253 int l;
254
255 /*
256 * check HCOUNT because we cannot check vertical sync.
257 */
258 for (; tmout >= 0; tmout--) {
259 l = ar_inl(ARVHCOUNT);
260 if (l == exp_line)
261 break;
262 }
263 if (tmout < 0)
264 printk("arv: lost %d -> %d\n", exp_line, l);
265#else
266 while (ar_inl(ARVHCOUNT) != exp_line)
267 cpu_relax();
268#endif
269}
270
271static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
272{
273 struct video_device *v = video_devdata(file);
274 struct ar_device *ar = v->priv;
275 long ret = ar->frame_bytes; /* return read bytes */
276 unsigned long arvcr1 = 0;
277 unsigned long flags;
278 unsigned char *p;
279 int h, w;
280 unsigned char *py, *pu, *pv;
281#if ! USE_INT
282 int l;
283#endif
284
285 DEBUG(1, "ar_read()\n");
286
287 if (ar->size == AR_SIZE_QVGA)
288 arvcr1 |= ARVCR1_QVGA;
289 if (ar->mode == AR_MODE_NORMAL)
290 arvcr1 |= ARVCR1_NORMAL;
291
292 down(&ar->lock);
293
294#if USE_INT
295 local_irq_save(flags);
296 disable_dma();
297 ar_outl(0xa1871300, M32R_DMA0CR0_PORTL);
298 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
299
300 /* set AR FIFO address as source(BSEL5) */
301 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
302 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
303 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */
304 ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
305 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
306 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
307
308 /*
309 * Okey , kicks AR LSI to invoke an interrupt
310 */
311 ar->start_capture = 0;
312 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
313 local_irq_restore(flags);
314 /* .... AR interrupts .... */
315 interruptible_sleep_on(&ar->wait);
316 if (signal_pending(current)) {
317 printk("arv: interrupted while get frame data.\n");
318 ret = -EINTR;
319 goto out_up;
320 }
321#else /* ! USE_INT */
322 /* polling */
323 ar_outl(arvcr1, ARVCR1);
324 disable_dma();
325 ar_outl(0x8000, M32R_DMAEDET_PORTL);
326 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
327 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
328 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
329 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
330 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);
331 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);
332
333 local_irq_save(flags);
334 while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */
335 cpu_relax();
336 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
337 for (h = 0; h < ar->height; h++) {
338 wait_for_vertical_sync(h);
339 if (h < (AR_HEIGHT_VGA/2))
340 l = h << 1;
341 else
342 l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1);
343 ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL);
344 enable_dma();
345 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
346 cpu_relax();
347 disable_dma();
348 clear_dma_status();
349 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
350 }
351 } else {
352 for (h = 0; h < ar->height; h++) {
353 wait_for_vertical_sync(h);
354 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
355 enable_dma();
356 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
357 cpu_relax();
358 disable_dma();
359 clear_dma_status();
360 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
361 }
362 }
363 local_irq_restore(flags);
364#endif /* ! USE_INT */
365
366 /*
367 * convert YUV422 to YUV422P
368 * +--------------------+
369 * | Y0,Y1,... |
370 * | ..............Yn |
371 * +--------------------+
372 * | U0,U1,........Un |
373 * +--------------------+
374 * | V0,V1,........Vn |
375 * +--------------------+
376 */
377 py = yuv;
378 pu = py + (ar->frame_bytes / 2);
379 pv = pu + (ar->frame_bytes / 4);
380 for (h = 0; h < ar->height; h++) {
381 p = ar->frame[h];
382 for (w = 0; w < ar->line_bytes; w += 4) {
383 *py++ = *p++;
384 *pu++ = *p++;
385 *py++ = *p++;
386 *pv++ = *p++;
387 }
388 }
389 if (copy_to_user(buf, yuv, ar->frame_bytes)) {
390 printk("arv: failed while copy_to_user yuv.\n");
391 ret = -EFAULT;
392 goto out_up;
393 }
394 DEBUG(1, "ret = %d\n", ret);
395out_up:
396 up(&ar->lock);
397 return ret;
398}
399
400static int ar_do_ioctl(struct inode *inode, struct file *file,
401 unsigned int cmd, void *arg)
402{
403 struct video_device *dev = video_devdata(file);
404 struct ar_device *ar = dev->priv;
405
406 DEBUG(1, "ar_ioctl()\n");
407 switch(cmd) {
408 case VIDIOCGCAP:
409 {
410 struct video_capability *b = arg;
411 DEBUG(1, "VIDIOCGCAP:\n");
412 strcpy(b->name, ar->vdev->name);
413 b->type = VID_TYPE_CAPTURE;
414 b->channels = 0;
415 b->audios = 0;
416 b->maxwidth = MAX_AR_WIDTH;
417 b->maxheight = MAX_AR_HEIGHT;
418 b->minwidth = MIN_AR_WIDTH;
419 b->minheight = MIN_AR_HEIGHT;
420 return 0;
421 }
422 case VIDIOCGCHAN:
423 DEBUG(1, "VIDIOCGCHAN:\n");
424 return 0;
425 case VIDIOCSCHAN:
426 DEBUG(1, "VIDIOCSCHAN:\n");
427 return 0;
428 case VIDIOCGTUNER:
429 DEBUG(1, "VIDIOCGTUNER:\n");
430 return 0;
431 case VIDIOCSTUNER:
432 DEBUG(1, "VIDIOCSTUNER:\n");
433 return 0;
434 case VIDIOCGPICT:
435 DEBUG(1, "VIDIOCGPICT:\n");
436 return 0;
437 case VIDIOCSPICT:
438 DEBUG(1, "VIDIOCSPICT:\n");
439 return 0;
440 case VIDIOCCAPTURE:
441 DEBUG(1, "VIDIOCCAPTURE:\n");
442 return -EINVAL;
443 case VIDIOCGWIN:
444 {
445 struct video_window *w = arg;
446 DEBUG(1, "VIDIOCGWIN:\n");
447 memset(w, 0, sizeof(w));
448 w->width = ar->width;
449 w->height = ar->height;
450 return 0;
451 }
452 case VIDIOCSWIN:
453 {
454 struct video_window *w = arg;
455 DEBUG(1, "VIDIOCSWIN:\n");
456 if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) &&
457 (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA))
458 return -EINVAL;
459
460 down(&ar->lock);
461 ar->width = w->width;
462 ar->height = w->height;
463 if (ar->width == AR_WIDTH_VGA) {
464 ar->size = AR_SIZE_VGA;
465 ar->frame_bytes = AR_FRAME_BYTES_VGA;
466 ar->line_bytes = AR_LINE_BYTES_VGA;
467 if (vga_interlace)
468 ar->mode = AR_MODE_INTERLACE;
469 else
470 ar->mode = AR_MODE_NORMAL;
471 } else {
472 ar->size = AR_SIZE_QVGA;
473 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
474 ar->line_bytes = AR_LINE_BYTES_QVGA;
475 ar->mode = AR_MODE_INTERLACE;
476 }
477 up(&ar->lock);
478 return 0;
479 }
480 case VIDIOCGFBUF:
481 DEBUG(1, "VIDIOCGFBUF:\n");
482 return -EINVAL;
483 case VIDIOCSFBUF:
484 DEBUG(1, "VIDIOCSFBUF:\n");
485 return -EINVAL;
486 case VIDIOCKEY:
487 DEBUG(1, "VIDIOCKEY:\n");
488 return 0;
489 case VIDIOCGFREQ:
490 DEBUG(1, "VIDIOCGFREQ:\n");
491 return -EINVAL;
492 case VIDIOCSFREQ:
493 DEBUG(1, "VIDIOCSFREQ:\n");
494 return -EINVAL;
495 case VIDIOCGAUDIO:
496 DEBUG(1, "VIDIOCGAUDIO:\n");
497 return -EINVAL;
498 case VIDIOCSAUDIO:
499 DEBUG(1, "VIDIOCSAUDIO:\n");
500 return -EINVAL;
501 case VIDIOCSYNC:
502 DEBUG(1, "VIDIOCSYNC:\n");
503 return -EINVAL;
504 case VIDIOCMCAPTURE:
505 DEBUG(1, "VIDIOCMCAPTURE:\n");
506 return -EINVAL;
507 case VIDIOCGMBUF:
508 DEBUG(1, "VIDIOCGMBUF:\n");
509 return -EINVAL;
510 case VIDIOCGUNIT:
511 DEBUG(1, "VIDIOCGUNIT:\n");
512 return -EINVAL;
513 case VIDIOCGCAPTURE:
514 DEBUG(1, "VIDIOCGCAPTURE:\n");
515 return -EINVAL;
516 case VIDIOCSCAPTURE:
517 DEBUG(1, "VIDIOCSCAPTURE:\n");
518 return -EINVAL;
519 case VIDIOCSPLAYMODE:
520 DEBUG(1, "VIDIOCSPLAYMODE:\n");
521 return -EINVAL;
522 case VIDIOCSWRITEMODE:
523 DEBUG(1, "VIDIOCSWRITEMODE:\n");
524 return -EINVAL;
525 case VIDIOCGPLAYINFO:
526 DEBUG(1, "VIDIOCGPLAYINFO:\n");
527 return -EINVAL;
528 case VIDIOCSMICROCODE:
529 DEBUG(1, "VIDIOCSMICROCODE:\n");
530 return -EINVAL;
531 case VIDIOCGVBIFMT:
532 DEBUG(1, "VIDIOCGVBIFMT:\n");
533 return -EINVAL;
534 case VIDIOCSVBIFMT:
535 DEBUG(1, "VIDIOCSVBIFMT:\n");
536 return -EINVAL;
537 default:
538 DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
539 return -ENOIOCTLCMD;
540 }
541 return 0;
542}
543
544static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
545 unsigned long arg)
546{
547 return video_usercopy(inode, file, cmd, arg, ar_do_ioctl);
548}
549
550#if USE_INT
551/*
552 * Interrupt handler
553 */
554static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
555{
556 struct ar_device *ar = dev;
557 unsigned int line_count;
558 unsigned int line_number;
559 unsigned int arvcr1;
560
561 line_count = ar_inl(ARVHCOUNT); /* line number */
562 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
563 /* operations for interlace mode */
564 if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */
565 line_number = (line_count << 1);
566 else /* odd line */
567 line_number =
568 (((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
569 } else {
570 line_number = line_count;
571 }
572
573 if (line_number == 0) {
574 /*
575 * It is an interrupt for line 0.
576 * we have to start capture.
577 */
578 disable_dma();
579#if 0
580 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */
581#endif
582 memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);
583#if 0
584 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
585#endif
586 enable_dma();
587 ar->start_capture = 1; /* during capture */
588 return;
589 }
590
591 if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {
592 disable_dma();
593 memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);
594
595 /*
596 * if captured all line of a frame, disable AR interrupt
597 * and wake a process up.
598 */
599 if (line_number == (ar->height - 1)) { /* end of line */
600
601 ar->start_capture = 0;
602
603 /* disable AR interrupt request */
604 arvcr1 = ar_inl(ARVCR1);
605 arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */
606 ar_outl(arvcr1, ARVCR1); /* disable */
607 wake_up_interruptible(&ar->wait);
608 } else {
609#if 0
610 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);
611 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
612#endif
613 enable_dma();
614 }
615 }
616}
617#endif
618
619/*
620 * ar_initialize()
621 * ar_initialize() is called by video_register_device() and
622 * initializes AR LSI and peripherals.
623 *
624 * -1 is returned in all failures.
625 * 0 is returned in success.
626 *
627 */
628static int ar_initialize(struct video_device *dev)
629{
630 struct ar_device *ar = dev->priv;
631 unsigned long cr = 0;
632 int i,found=0;
633
634 DEBUG(1, "ar_initialize:\n");
635
636 /*
637 * initialize AR LSI
638 */
639 ar_outl(0, ARVCR0); /* assert reset of AR LSI */
640 for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */
641 cpu_relax();
642 ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */
643 for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */
644 cpu_relax();
645
646 /* AR uses INT3 of CPU as interrupt pin. */
647 ar_outl(ARINTSEL_INT3, ARINTSEL);
648
649 if (ar->size == AR_SIZE_QVGA)
650 cr |= ARVCR1_QVGA;
651 if (ar->mode == AR_MODE_NORMAL)
652 cr |= ARVCR1_NORMAL;
653 ar_outl(cr, ARVCR1);
654
655 /*
656 * Initialize IIC so that CPU can communicate with AR LSI,
657 * and send boot commands to AR LSI.
658 */
659 init_iic();
660
661 for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */
662 if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */
663 found = 1;
664 break;
665 }
666 }
667
668 if (found == 0)
669 return -ENODEV;
670
671 printk("arv: Initializing ");
672
673 iic(2,0x78,0x11,0x01,0x00); /* start */
674 iic(3,0x78,0x12,0x00,0x06);
675 iic(3,0x78,0x12,0x12,0x30);
676 iic(3,0x78,0x12,0x15,0x58);
677 iic(3,0x78,0x12,0x17,0x30);
678 printk(".");
679 iic(3,0x78,0x12,0x1a,0x97);
680 iic(3,0x78,0x12,0x1b,0xff);
681 iic(3,0x78,0x12,0x1c,0xff);
682 iic(3,0x78,0x12,0x26,0x10);
683 iic(3,0x78,0x12,0x27,0x00);
684 printk(".");
685 iic(2,0x78,0x34,0x02,0x00);
686 iic(2,0x78,0x7a,0x10,0x00);
687 iic(2,0x78,0x80,0x39,0x00);
688 iic(2,0x78,0x81,0xe6,0x00);
689 iic(2,0x78,0x8d,0x00,0x00);
690 printk(".");
691 iic(2,0x78,0x8e,0x0c,0x00);
692 iic(2,0x78,0x8f,0x00,0x00);
693#if 0
694 iic(2,0x78,0x90,0x00,0x00); /* AWB on=1 off=0 */
695#endif
696 iic(2,0x78,0x93,0x01,0x00);
697 iic(2,0x78,0x94,0xcd,0x00);
698 iic(2,0x78,0x95,0x00,0x00);
699 printk(".");
700 iic(2,0x78,0x96,0xa0,0x00);
701 iic(2,0x78,0x97,0x00,0x00);
702 iic(2,0x78,0x98,0x60,0x00);
703 iic(2,0x78,0x99,0x01,0x00);
704 iic(2,0x78,0x9a,0x19,0x00);
705 printk(".");
706 iic(2,0x78,0x9b,0x02,0x00);
707 iic(2,0x78,0x9c,0xe8,0x00);
708 iic(2,0x78,0x9d,0x02,0x00);
709 iic(2,0x78,0x9e,0x2e,0x00);
710 iic(2,0x78,0xb8,0x78,0x00);
711 iic(2,0x78,0xba,0x05,0x00);
712#if 0
713 iic(2,0x78,0x83,0x8c,0x00); /* brightness */
714#endif
715 printk(".");
716
717 /* color correction */
718 iic(3,0x78,0x49,0x00,0x95); /* a */
719 iic(3,0x78,0x49,0x01,0x96); /* b */
720 iic(3,0x78,0x49,0x03,0x85); /* c */
721 iic(3,0x78,0x49,0x04,0x97); /* d */
722 iic(3,0x78,0x49,0x02,0x7e); /* e(Lo) */
723 iic(3,0x78,0x49,0x05,0xa4); /* f(Lo) */
724 iic(3,0x78,0x49,0x06,0x04); /* e(Hi) */
725 iic(3,0x78,0x49,0x07,0x04); /* e(Hi) */
726 iic(2,0x78,0x48,0x01,0x00); /* on=1 off=0 */
727
728 printk(".");
729 iic(2,0x78,0x11,0x00,0x00); /* end */
730 printk(" done\n");
731 return 0;
732}
733
734
735void ar_release(struct video_device *vfd)
736{
737 struct ar_device *ar = vfd->priv;
738 down(&ar->lock);
739 video_device_release(vfd);
740}
741
742/****************************************************************************
743 *
744 * Video4Linux Module functions
745 *
746 ****************************************************************************/
747static struct file_operations ar_fops = {
748 .owner = THIS_MODULE,
749 .open = video_exclusive_open,
750 .release = video_exclusive_release,
751 .read = ar_read,
752 .ioctl = ar_ioctl,
753 .llseek = no_llseek,
754};
755
756static struct video_device ar_template = {
757 .owner = THIS_MODULE,
758 .name = "Colour AR VGA",
759 .type = VID_TYPE_CAPTURE,
760 .hardware = VID_HARDWARE_ARV,
761 .fops = &ar_fops,
762 .release = ar_release,
763 .minor = -1,
764};
765
766#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
767static struct ar_device ardev;
768
769static int __init ar_init(void)
770{
771 struct ar_device *ar;
772 int ret;
773 int i;
774
775 DEBUG(1, "ar_init:\n");
776 ret = -EIO;
777 printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
778
779 ar = &ardev;
780 memset(ar, 0, sizeof(struct ar_device));
781
782#if USE_INT
783 /* allocate a DMA buffer for 1 line. */
784 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
785 if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) {
786 printk("arv: buffer allocation failed for DMA.\n");
787 ret = -ENOMEM;
788 goto out_end;
789 }
790#endif
791 /* allocate buffers for a frame */
792 for (i = 0; i < MAX_AR_HEIGHT; i++) {
793 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
794 if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) {
795 printk("arv: buffer allocation failed for frame.\n");
796 ret = -ENOMEM;
797 goto out_line_buff;
798 }
799 }
800
801 ar->vdev = video_device_alloc();
802 if (!ar->vdev) {
803 printk(KERN_ERR "arv: video_device_alloc() failed\n");
804 return -ENOMEM;
805 }
806 memcpy(ar->vdev, &ar_template, sizeof(ar_template));
807 ar->vdev->priv = ar;
808
809 if (vga) {
810 ar->width = AR_WIDTH_VGA;
811 ar->height = AR_HEIGHT_VGA;
812 ar->size = AR_SIZE_VGA;
813 ar->frame_bytes = AR_FRAME_BYTES_VGA;
814 ar->line_bytes = AR_LINE_BYTES_VGA;
815 if (vga_interlace)
816 ar->mode = AR_MODE_INTERLACE;
817 else
818 ar->mode = AR_MODE_NORMAL;
819 } else {
820 ar->width = AR_WIDTH_QVGA;
821 ar->height = AR_HEIGHT_QVGA;
822 ar->size = AR_SIZE_QVGA;
823 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
824 ar->line_bytes = AR_LINE_BYTES_QVGA;
825 ar->mode = AR_MODE_INTERLACE;
826 }
827 init_MUTEX(&ar->lock);
828 init_waitqueue_head(&ar->wait);
829
830#if USE_INT
831 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
832 printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3);
833 ret = -EIO;
834 goto out_irq;
835 }
836#endif
837
838 if (ar_initialize(ar->vdev) != 0) {
839 printk("arv: M64278 not found.\n");
840 ret = -ENODEV;
841 goto out_dev;
842 }
843
844 /*
845 * ok, we can initialize h/w according to parameters,
846 * so register video device as a frame grabber type.
847 * device is named "video[0-64]".
848 * video_register_device() initializes h/w using ar_initialize().
849 */
850 if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
851 /* return -1, -ENFILE(full) or others */
852 printk("arv: register video (Colour AR) failed.\n");
853 ret = -ENODEV;
854 goto out_dev;
855 }
856
857 printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
858 ar->vdev->minor, M32R_IRQ_INT3, freq);
859
860 return 0;
861
862out_dev:
863#if USE_INT
864 free_irq(M32R_IRQ_INT3, ar);
865
866out_irq:
867#endif
868 for (i = 0; i < MAX_AR_HEIGHT; i++) {
869 if (ar->frame[i])
870 kfree(ar->frame[i]);
871 }
872
873out_line_buff:
874#if USE_INT
875 kfree(ar->line_buff);
876
877out_end:
878#endif
879 return ret;
880}
881
882
883static int __init ar_init_module(void)
884{
885 freq = (boot_cpu_data.bus_clock / 1000000);
886 printk("arv: Bus clock %d\n", freq);
887 if (freq != 50 && freq != 75)
888 freq = DEFAULT_FREQ;
889 return ar_init();
890}
891
892static void __exit ar_cleanup_module(void)
893{
894 struct ar_device *ar;
895 int i;
896
897 ar = &ardev;
898 video_unregister_device(ar->vdev);
899#if USE_INT
900 free_irq(M32R_IRQ_INT3, ar);
901#endif
902 for (i = 0; i < MAX_AR_HEIGHT; i++) {
903 if (ar->frame[i])
904 kfree(ar->frame[i]);
905 }
906#if USE_INT
907 kfree(ar->line_buff);
908#endif
909}
910
911module_init(ar_init_module);
912module_exit(ar_cleanup_module);
913
914MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");
915MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");
916MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
new file mode 100644
index 000000000000..cf0db2554a80
--- /dev/null
+++ b/drivers/media/video/bt819.c
@@ -0,0 +1,660 @@
1/*
2 * bt819 - BT819A VideoStream Decoder (Rockwell Part)
3 *
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 *
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12 *
13 * This code was modify/ported from the saa7111 driver written
14 * by Dave Perks.
15 *
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
53MODULE_AUTHOR("Mike Bernson & Dave Perks");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(s) (s)->name
60
61#include <linux/video_decoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75struct bt819 {
76 unsigned char reg[32];
77
78 int initialized;
79 int norm;
80 int input;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86};
87
88struct timing {
89 int hactive;
90 int hdelay;
91 int vactive;
92 int vdelay;
93 int hscale;
94 int vscale;
95};
96
97/* for values, see the bt819 datasheet */
98static struct timing timing_data[] = {
99 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
100 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
101};
102
103#define I2C_BT819 0x8a
104
105/* ----------------------------------------------------------------------- */
106
107static inline int
108bt819_write (struct i2c_client *client,
109 u8 reg,
110 u8 value)
111{
112 struct bt819 *decoder = i2c_get_clientdata(client);
113
114 decoder->reg[reg] = value;
115 return i2c_smbus_write_byte_data(client, reg, value);
116}
117
118static inline int
119bt819_setbit (struct i2c_client *client,
120 u8 reg,
121 u8 bit,
122 u8 value)
123{
124 struct bt819 *decoder = i2c_get_clientdata(client);
125
126 return bt819_write(client, reg,
127 (decoder->
128 reg[reg] & ~(1 << bit)) |
129 (value ? (1 << bit) : 0));
130}
131
132static int
133bt819_write_block (struct i2c_client *client,
134 const u8 *data,
135 unsigned int len)
136{
137 int ret = -1;
138 u8 reg;
139
140 /* the bt819 has an autoincrement function, use it if
141 * the adapter understands raw I2C */
142 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
143 /* do raw I2C, not smbus compatible */
144 struct bt819 *decoder = i2c_get_clientdata(client);
145 struct i2c_msg msg;
146 u8 block_data[32];
147
148 msg.addr = client->addr;
149 msg.flags = 0;
150 while (len >= 2) {
151 msg.buf = (char *) block_data;
152 msg.len = 0;
153 block_data[msg.len++] = reg = data[0];
154 do {
155 block_data[msg.len++] =
156 decoder->reg[reg++] = data[1];
157 len -= 2;
158 data += 2;
159 } while (len >= 2 && data[0] == reg &&
160 msg.len < 32);
161 if ((ret = i2c_transfer(client->adapter,
162 &msg, 1)) < 0)
163 break;
164 }
165 } else {
166 /* do some slow I2C emulation kind of thing */
167 while (len >= 2) {
168 reg = *data++;
169 if ((ret = bt819_write(client, reg, *data++)) < 0)
170 break;
171 len -= 2;
172 }
173 }
174
175 return ret;
176}
177
178static inline int
179bt819_read (struct i2c_client *client,
180 u8 reg)
181{
182 return i2c_smbus_read_byte_data(client, reg);
183}
184
185static int
186bt819_init (struct i2c_client *client)
187{
188 struct bt819 *decoder = i2c_get_clientdata(client);
189
190 static unsigned char init[] = {
191 //0x1f, 0x00, /* Reset */
192 0x01, 0x59, /* 0x01 input format */
193 0x02, 0x00, /* 0x02 temporal decimation */
194 0x03, 0x12, /* 0x03 Cropping msb */
195 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
196 0x05, 0xe0, /* 0x05 Vertical Active lsb */
197 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
198 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
199 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
200 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
201 0x0a, 0x00, /* 0x0a Brightness control */
202 0x0b, 0x30, /* 0x0b Miscellaneous control */
203 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
204 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
205 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
206 0x0f, 0x00, /* 0x0f Hue control */
207 0x12, 0x04, /* 0x12 Output Format */
208 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
209 chroma comb OFF, line drop scaling, interlace scaling
210 BUG? Why does turning the chroma comb on fuck up color?
211 Bug in the bt819 stepping on my board?
212 */
213 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
214 0x16, 0x07, /* 0x16 Video Timing Polarity
215 ACTIVE=active low
216 FIELD: high=odd,
217 vreset=active high,
218 hreset=active high */
219 0x18, 0x68, /* 0x18 AGC Delay */
220 0x19, 0x5d, /* 0x19 Burst Gate Delay */
221 0x1a, 0x80, /* 0x1a ADC Interface */
222 };
223
224 struct timing *timing = &timing_data[decoder->norm];
225
226 init[0x03 * 2 - 1] =
227 (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
228 vactive >> 8) &
229 0x03) << 4) |
230 (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
231 hactive >> 8) &
232 0x03);
233 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
234 init[0x05 * 2 - 1] = timing->vactive & 0xff;
235 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
236 init[0x07 * 2 - 1] = timing->hactive & 0xff;
237 init[0x08 * 2 - 1] = timing->hscale >> 8;
238 init[0x09 * 2 - 1] = timing->hscale & 0xff;
239 /* 0x15 in array is address 0x19 */
240 init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
241 /* reset */
242 bt819_write(client, 0x1f, 0x00);
243 mdelay(1);
244
245 /* init */
246 return bt819_write_block(client, init, sizeof(init));
247
248}
249
250/* ----------------------------------------------------------------------- */
251
252static int
253bt819_command (struct i2c_client *client,
254 unsigned int cmd,
255 void *arg)
256{
257 int temp;
258
259 struct bt819 *decoder = i2c_get_clientdata(client);
260
261 if (!decoder->initialized) { // First call to bt819_init could be
262 bt819_init(client); // without #FRST = 0
263 decoder->initialized = 1;
264 }
265
266 switch (cmd) {
267
268 case 0:
269 /* This is just for testing!!! */
270 bt819_init(client);
271 break;
272
273 case DECODER_GET_CAPABILITIES:
274 {
275 struct video_decoder_capability *cap = arg;
276
277 cap->flags = VIDEO_DECODER_PAL |
278 VIDEO_DECODER_NTSC |
279 VIDEO_DECODER_AUTO |
280 VIDEO_DECODER_CCIR;
281 cap->inputs = 8;
282 cap->outputs = 1;
283 }
284 break;
285
286 case DECODER_GET_STATUS:
287 {
288 int *iarg = arg;
289 int status;
290 int res;
291
292 status = bt819_read(client, 0x00);
293 res = 0;
294 if ((status & 0x80)) {
295 res |= DECODER_STATUS_GOOD;
296 }
297 switch (decoder->norm) {
298 case VIDEO_MODE_NTSC:
299 res |= DECODER_STATUS_NTSC;
300 break;
301 case VIDEO_MODE_PAL:
302 res |= DECODER_STATUS_PAL;
303 break;
304 default:
305 case VIDEO_MODE_AUTO:
306 if ((status & 0x10)) {
307 res |= DECODER_STATUS_PAL;
308 } else {
309 res |= DECODER_STATUS_NTSC;
310 }
311 break;
312 }
313 res |= DECODER_STATUS_COLOR;
314 *iarg = res;
315
316 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
317 *iarg);
318 }
319 break;
320
321 case DECODER_SET_NORM:
322 {
323 int *iarg = arg;
324 struct timing *timing = NULL;
325
326 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
327 *iarg);
328
329 switch (*iarg) {
330 case VIDEO_MODE_NTSC:
331 bt819_setbit(client, 0x01, 0, 1);
332 bt819_setbit(client, 0x01, 1, 0);
333 bt819_setbit(client, 0x01, 5, 0);
334 bt819_write(client, 0x18, 0x68);
335 bt819_write(client, 0x19, 0x5d);
336 //bt819_setbit(client, 0x1a, 5, 1);
337 timing = &timing_data[VIDEO_MODE_NTSC];
338 break;
339 case VIDEO_MODE_PAL:
340 bt819_setbit(client, 0x01, 0, 1);
341 bt819_setbit(client, 0x01, 1, 1);
342 bt819_setbit(client, 0x01, 5, 1);
343 bt819_write(client, 0x18, 0x7f);
344 bt819_write(client, 0x19, 0x72);
345 //bt819_setbit(client, 0x1a, 5, 0);
346 timing = &timing_data[VIDEO_MODE_PAL];
347 break;
348 case VIDEO_MODE_AUTO:
349 bt819_setbit(client, 0x01, 0, 0);
350 bt819_setbit(client, 0x01, 1, 0);
351 break;
352 default:
353 dprintk(1,
354 KERN_ERR
355 "%s: unsupported norm %d\n",
356 I2C_NAME(client), *iarg);
357 return -EINVAL;
358 }
359
360 if (timing) {
361 bt819_write(client, 0x03,
362 (((timing->vdelay >> 8) & 0x03) << 6) |
363 (((timing->vactive >> 8) & 0x03) << 4) |
364 (((timing->hdelay >> 8) & 0x03) << 2) |
365 ((timing->hactive >> 8) & 0x03) );
366 bt819_write(client, 0x04, timing->vdelay & 0xff);
367 bt819_write(client, 0x05, timing->vactive & 0xff);
368 bt819_write(client, 0x06, timing->hdelay & 0xff);
369 bt819_write(client, 0x07, timing->hactive & 0xff);
370 bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
371 bt819_write(client, 0x09, timing->hscale & 0xff);
372 }
373
374 decoder->norm = *iarg;
375 }
376 break;
377
378 case DECODER_SET_INPUT:
379 {
380 int *iarg = arg;
381
382 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
383 *iarg);
384
385 if (*iarg < 0 || *iarg > 7) {
386 return -EINVAL;
387 }
388
389 if (decoder->input != *iarg) {
390 decoder->input = *iarg;
391 /* select mode */
392 if (decoder->input == 0) {
393 bt819_setbit(client, 0x0b, 6, 0);
394 bt819_setbit(client, 0x1a, 1, 1);
395 } else {
396 bt819_setbit(client, 0x0b, 6, 1);
397 bt819_setbit(client, 0x1a, 1, 0);
398 }
399 }
400 }
401 break;
402
403 case DECODER_SET_OUTPUT:
404 {
405 int *iarg = arg;
406
407 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
408 *iarg);
409
410 /* not much choice of outputs */
411 if (*iarg != 0) {
412 return -EINVAL;
413 }
414 }
415 break;
416
417 case DECODER_ENABLE_OUTPUT:
418 {
419 int *iarg = arg;
420 int enable = (*iarg != 0);
421
422 dprintk(1, KERN_INFO "%s: enable output %x\n",
423 I2C_NAME(client), *iarg);
424
425 if (decoder->enable != enable) {
426 decoder->enable = enable;
427
428 if (decoder->enable) {
429 bt819_setbit(client, 0x16, 7, 0);
430 } else {
431 bt819_setbit(client, 0x16, 7, 1);
432 }
433 }
434 }
435 break;
436
437 case DECODER_SET_PICTURE:
438 {
439 struct video_picture *pic = arg;
440
441 dprintk(1,
442 KERN_INFO
443 "%s: set picture brightness %d contrast %d colour %d\n",
444 I2C_NAME(client), pic->brightness, pic->contrast,
445 pic->colour);
446
447
448 if (decoder->bright != pic->brightness) {
449 /* We want -128 to 127 we get 0-65535 */
450 decoder->bright = pic->brightness;
451 bt819_write(client, 0x0a,
452 (decoder->bright >> 8) - 128);
453 }
454
455 if (decoder->contrast != pic->contrast) {
456 /* We want 0 to 511 we get 0-65535 */
457 decoder->contrast = pic->contrast;
458 bt819_write(client, 0x0c,
459 (decoder->contrast >> 7) & 0xff);
460 bt819_setbit(client, 0x0b, 2,
461 ((decoder->contrast >> 15) & 0x01));
462 }
463
464 if (decoder->sat != pic->colour) {
465 /* We want 0 to 511 we get 0-65535 */
466 decoder->sat = pic->colour;
467 bt819_write(client, 0x0d,
468 (decoder->sat >> 7) & 0xff);
469 bt819_setbit(client, 0x0b, 1,
470 ((decoder->sat >> 15) & 0x01));
471
472 temp = (decoder->sat * 201) / 237;
473 bt819_write(client, 0x0e, (temp >> 7) & 0xff);
474 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
475 }
476
477 if (decoder->hue != pic->hue) {
478 /* We want -128 to 127 we get 0-65535 */
479 decoder->hue = pic->hue;
480 bt819_write(client, 0x0f,
481 128 - (decoder->hue >> 8));
482 }
483 }
484 break;
485
486 default:
487 return -EINVAL;
488 }
489
490 return 0;
491}
492
493/* ----------------------------------------------------------------------- */
494
495/*
496 * Generic i2c probe
497 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
498 */
499static unsigned short normal_i2c[] = {
500 I2C_BT819 >> 1,
501 I2C_CLIENT_END,
502};
503static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
504
505static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
506static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
507static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
508static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
509static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
510
511static struct i2c_client_address_data addr_data = {
512 .normal_i2c = normal_i2c,
513 .normal_i2c_range = normal_i2c_range,
514 .probe = probe,
515 .probe_range = probe_range,
516 .ignore = ignore,
517 .ignore_range = ignore_range,
518 .force = force
519};
520
521static struct i2c_driver i2c_driver_bt819;
522
523static int
524bt819_detect_client (struct i2c_adapter *adapter,
525 int address,
526 int kind)
527{
528 int i, id;
529 struct bt819 *decoder;
530 struct i2c_client *client;
531
532 dprintk(1,
533 KERN_INFO
534 "saa7111.c: detecting bt819 client on address 0x%x\n",
535 address << 1);
536
537 /* Check if the adapter supports the needed features */
538 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
539 return 0;
540
541 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
542 if (client == 0)
543 return -ENOMEM;
544 memset(client, 0, sizeof(struct i2c_client));
545 client->addr = address;
546 client->adapter = adapter;
547 client->driver = &i2c_driver_bt819;
548 client->flags = I2C_CLIENT_ALLOW_USE;
549
550 decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
551 if (decoder == NULL) {
552 kfree(client);
553 return -ENOMEM;
554 }
555
556 memset(decoder, 0, sizeof(struct bt819));
557 decoder->norm = VIDEO_MODE_NTSC;
558 decoder->input = 0;
559 decoder->enable = 1;
560 decoder->bright = 32768;
561 decoder->contrast = 32768;
562 decoder->hue = 32768;
563 decoder->sat = 32768;
564 decoder->initialized = 0;
565 i2c_set_clientdata(client, decoder);
566
567 id = bt819_read(client, 0x17);
568 switch (id & 0xf0) {
569 case 0x70:
570 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
571 break;
572 case 0x60:
573 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
574 break;
575 case 0x20:
576 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
577 break;
578 default:
579 dprintk(1,
580 KERN_ERR
581 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
582 id & 0xf0, id & 0x0f);
583 kfree(decoder);
584 kfree(client);
585 return 0;
586 }
587
588 i = i2c_attach_client(client);
589 if (i) {
590 kfree(client);
591 kfree(decoder);
592 return i;
593 }
594
595 i = bt819_init(client);
596 if (i < 0) {
597 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
598 I2C_NAME(client), i);
599 } else {
600 dprintk(1,
601 KERN_INFO
602 "%s_attach: chip version 0x%x at address 0x%x\n",
603 I2C_NAME(client), id & 0x0f,
604 client->addr << 1);
605 }
606
607 return 0;
608}
609
610static int
611bt819_attach_adapter (struct i2c_adapter *adapter)
612{
613 return i2c_probe(adapter, &addr_data, &bt819_detect_client);
614}
615
616static int
617bt819_detach_client (struct i2c_client *client)
618{
619 struct bt819 *decoder = i2c_get_clientdata(client);
620 int err;
621
622 err = i2c_detach_client(client);
623 if (err) {
624 return err;
625 }
626
627 kfree(decoder);
628 kfree(client);
629
630 return 0;
631}
632
633/* ----------------------------------------------------------------------- */
634
635static struct i2c_driver i2c_driver_bt819 = {
636 .owner = THIS_MODULE,
637 .name = "bt819",
638
639 .id = I2C_DRIVERID_BT819,
640 .flags = I2C_DF_NOTIFY,
641
642 .attach_adapter = bt819_attach_adapter,
643 .detach_client = bt819_detach_client,
644 .command = bt819_command,
645};
646
647static int __init
648bt819_init_module (void)
649{
650 return i2c_add_driver(&i2c_driver_bt819);
651}
652
653static void __exit
654bt819_exit (void)
655{
656 i2c_del_driver(&i2c_driver_bt819);
657}
658
659module_init(bt819_init_module);
660module_exit(bt819_exit);
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
new file mode 100644
index 000000000000..efe605a113a1
--- /dev/null
+++ b/drivers/media/video/bt832.c
@@ -0,0 +1,271 @@
1/* Driver for Bt832 CMOS Camera Video Processor
2 i2c-addresses: 0x88 or 0x8a
3
4 The BT832 interfaces to a Quartzsight Digital Camera (352x288, 25 or 30 fps)
5 via a 9 pin connector ( 4-wire SDATA, 2-wire i2c, SCLK, VCC, GND).
6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
7 connected to bt848/bt878 GPIO pins on this purpose.
8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
9
10 Supported Cards:
11 - Pixelview Rev.4E: 0x8a
12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
13
14 (c) Gunther Mayer, 2002
15
16 STATUS:
17 - detect chip and hexdump
18 - reset chip and leave low power mode
19 - detect camera present
20
21 TODO:
22 - make it work (find correct setup for Bt832 and Bt878)
23*/
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/i2c.h>
28#include <linux/types.h>
29#include <linux/videodev.h>
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/slab.h>
33
34#include "id.h"
35#include "audiochip.h"
36#include "bttv.h"
37#include "bt832.h"
38
39MODULE_LICENSE("GPL");
40
41/* Addresses to scan */
42static unsigned short normal_i2c[] = {I2C_CLIENT_END};
43static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END};
44I2C_CLIENT_INSMOD;
45
46/* ---------------------------------------------------------------------- */
47
48#define dprintk if (debug) printk
49
50static int bt832_detach(struct i2c_client *client);
51
52
53static struct i2c_driver driver;
54static struct i2c_client client_template;
55
56struct bt832 {
57 struct i2c_client client;
58};
59
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{
62 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment
64 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);
66
67 for(i=0;i<65;i++)
68 buf[i]=0;
69 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);
71
72 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote)
74
75 if(1) {
76 int i;
77 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) {
79 if(i!=1) {
80 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n");
82 }
83 printk(" %02x",buf[i]);
84 }
85 printk("\n");
86 }
87 return 0;
88}
89
90// Return: 1 (is a bt832), 0 (No bt832 here)
91int bt832_init(struct i2c_client *i2c_client_s)
92{
93 unsigned char *buf;
94 int rc;
95
96 buf=kmalloc(65,GFP_KERNEL);
97 bt832_hexdump(i2c_client_s,buf);
98
99 if(buf[0x40] != 0x31) {
100 printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
101 kfree(buf);
102 return 0;
103 }
104
105 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00;
108 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);
110
111 bt832_hexdump(i2c_client_s,buf);
112
113
114 // Leave low power mode:
115 printk("Bt832: leave low power mode.\n");
116 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08;
118 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);
120
121 bt832_hexdump(i2c_client_s,buf);
122
123 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00;
126 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);
128
129 bt832_hexdump(i2c_client_s,buf);
130
131
132 // Enable Output
133 printk("Enable Output\n");
134 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip
136 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);
138
139 bt832_hexdump(i2c_client_s,buf);
140
141#if 0
142 // Full 30/25 Frame rate
143 printk("Full 30/25 Frame rate\n");
144 buf[0]=BT832_VP_CONTROL0; // Reg.39
145 buf[1]= 0x00;
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error FFR: rc == %d (should be 2)\n",rc);
148
149 bt832_hexdump(i2c_client_s,buf);
150#endif
151
152#if 1
153 // for testing (even works when no camera attached)
154 printk("bt832: *** Generate NTSC M Bars *****\n");
155 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
156 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
157 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
158 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
159#endif
160
161 printk("Bt832: Camera Present: %s\n",
162 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
163
164 bt832_hexdump(i2c_client_s,buf);
165 kfree(buf);
166 return 1;
167}
168
169
170
171static int bt832_attach(struct i2c_adapter *adap, int addr,
172 unsigned short flags, int kind)
173{
174 struct bt832 *t;
175
176 printk("bt832_attach\n");
177
178 client_template.adapter = adap;
179 client_template.addr = addr;
180
181 printk("bt832: chip found @ 0x%x\n", addr<<1);
182
183 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
184 return -ENOMEM;
185 memset(t,0,sizeof(*t));
186 t->client = client_template;
187 t->client.data = t;
188 i2c_attach_client(&t->client);
189
190 if(! bt832_init(&t->client)) {
191 bt832_detach(&t->client);
192 return -1;
193 }
194
195 return 0;
196}
197
198static int bt832_probe(struct i2c_adapter *adap)
199{
200 if (adap->class & I2C_CLASS_TV_ANALOG)
201 return i2c_probe(adap, &addr_data, bt832_attach);
202 return 0;
203}
204
205static int bt832_detach(struct i2c_client *client)
206{
207 struct bt832 *t = (struct bt832*)client->data;
208
209 printk("bt832: detach.\n");
210 i2c_detach_client(client);
211 kfree(t);
212 return 0;
213}
214
215static int
216bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
217{
218 struct bt832 *t = (struct bt832*)client->data;
219
220 printk("bt832: command %x\n",cmd);
221
222 switch (cmd) {
223 case BT832_HEXDUMP: {
224 unsigned char *buf;
225 buf=kmalloc(65,GFP_KERNEL);
226 bt832_hexdump(&t->client,buf);
227 kfree(buf);
228 }
229 break;
230 case BT832_REATTACH:
231 printk("bt832: re-attach\n");
232 i2c_del_driver(&driver);
233 i2c_add_driver(&driver);
234 break;
235 }
236 return 0;
237}
238
239/* ----------------------------------------------------------------------- */
240
241static struct i2c_driver driver = {
242 .owner = THIS_MODULE,
243 .name = "i2c bt832 driver",
244 .id = -1, /* FIXME */
245 .flags = I2C_DF_NOTIFY,
246 .attach_adapter = bt832_probe,
247 .detach_client = bt832_detach,
248 .command = bt832_command,
249};
250static struct i2c_client client_template =
251{
252 .name = "bt832",
253 .flags = I2C_CLIENT_ALLOW_USE,
254 .driver = &driver,
255};
256
257
258int bt832_init_module(void)
259{
260 i2c_add_driver(&driver);
261 return 0;
262}
263
264static void bt832_cleanup_module(void)
265{
266 i2c_del_driver(&driver);
267}
268
269module_init(bt832_init_module);
270module_exit(bt832_cleanup_module);
271
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
new file mode 100644
index 000000000000..7a98c06e0e34
--- /dev/null
+++ b/drivers/media/video/bt832.h
@@ -0,0 +1,305 @@
1/* Bt832 CMOS Camera Video Processor (VP)
2
3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
4 color digital camera directly to video capture devices via an 8-bit,
5 4:2:2 YUV or YCrCb video interface.
6
7 i2c addresses: 0x88 or 0x8a
8 */
9
10/* The 64 registers: */
11
12// Input Processor
13#define BT832_OFFSET 0
14#define BT832_RCOMP 1
15#define BT832_G1COMP 2
16#define BT832_G2COMP 3
17#define BT832_BCOMP 4
18// Exposures:
19#define BT832_FINEH 5
20#define BT832_FINEL 6
21#define BT832_COARSEH 7
22#define BT832_COARSEL 8
23#define BT832_CAMGAIN 9
24// Main Processor:
25#define BT832_M00 10
26#define BT832_M01 11
27#define BT832_M02 12
28#define BT832_M10 13
29#define BT832_M11 14
30#define BT832_M12 15
31#define BT832_M20 16
32#define BT832_M21 17
33#define BT832_M22 18
34#define BT832_APCOR 19
35#define BT832_GAMCOR 20
36// Level Accumulator Inputs
37#define BT832_VPCONTROL2 21
38#define BT832_ZONECODE0 22
39#define BT832_ZONECODE1 23
40#define BT832_ZONECODE2 24
41#define BT832_ZONECODE3 25
42// Level Accumulator Outputs:
43#define BT832_RACC 26
44#define BT832_GACC 27
45#define BT832_BACC 28
46#define BT832_BLACKACC 29
47#define BT832_EXP_AGC 30
48#define BT832_LACC0 31
49#define BT832_LACC1 32
50#define BT832_LACC2 33
51#define BT832_LACC3 34
52#define BT832_LACC4 35
53#define BT832_LACC5 36
54#define BT832_LACC6 37
55#define BT832_LACC7 38
56// System:
57#define BT832_VP_CONTROL0 39
58#define BT832_VP_CONTROL1 40
59#define BT832_THRESH 41
60#define BT832_VP_TESTCONTROL0 42
61#define BT832_VP_DMCODE 43
62#define BT832_ACB_CONFIG 44
63#define BT832_ACB_GNBASE 45
64#define BT832_ACB_MU 46
65#define BT832_CAM_TEST0 47
66#define BT832_AEC_CONFIG 48
67#define BT832_AEC_TL 49
68#define BT832_AEC_TC 50
69#define BT832_AEC_TH 51
70// Status:
71#define BT832_VP_STATUS 52
72#define BT832_VP_LINECOUNT 53
73#define BT832_CAM_DEVICEL 54 // e.g. 0x19
74#define BT832_CAM_DEVICEH 55 // e.g. 0x40 == 0x194 Mask0, 0x194 = 404 decimal (VVL-404 camera)
75#define BT832_CAM_STATUS 56
76 #define BT832_56_CAMERA_PRESENT 0x20
77//Camera Setups:
78#define BT832_CAM_SETUP0 57
79#define BT832_CAM_SETUP1 58
80#define BT832_CAM_SETUP2 59
81#define BT832_CAM_SETUP3 60
82// System:
83#define BT832_DEFCOR 61
84#define BT832_VP_TESTCONTROL1 62
85#define BT832_DEVICE_ID 63
86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
87
88/* STMicroelectronivcs VV5404 camera module
89 i2c: 0x20: sensor address
90 i2c: 0xa0: eeprom for ccd defect map
91 */
92#define VV5404_device_h 0x00 // 0x19
93#define VV5404_device_l 0x01 // 0x40
94#define VV5404_status0 0x02
95#define VV5404_linecountc 0x03 // current line counter
96#define VV5404_linecountl 0x04
97#define VV5404_setup0 0x10
98#define VV5404_setup1 0x11
99#define VV5404_setup2 0x12
100#define VV5404_setup4 0x14
101#define VV5404_setup5 0x15
102#define VV5404_fine_h 0x20 // fine exposure
103#define VV5404_fine_l 0x21
104#define VV5404_coarse_h 0x22 //coarse exposure
105#define VV5404_coarse_l 0x23
106#define VV5404_gain 0x24 // ADC pre-amp gain setting
107#define VV5404_clk_div 0x25
108#define VV5404_cr 0x76 // control register
109#define VV5404_as0 0x77 // ADC setup register
110
111
112// IOCTL
113#define BT832_HEXDUMP _IOR('b',1,int)
114#define BT832_REATTACH _IOR('b',2,int)
115
116/* from BT8x8VXD/capdrv/dialogs.cpp */
117
118/*
119typedef enum { SVI, Logitech, Rockwell } CAMERA;
120
121static COMBOBOX_ENTRY gwCameraOptions[] =
122{
123 { SVI, "Silicon Vision 512N" },
124 { Logitech, "Logitech VideoMan 1.3" },
125 { Rockwell, "Rockwell QuartzSight PCI 1.0" }
126};
127
128// SRAM table values
129//===========================================================================
130typedef enum { TGB_NTSC624, TGB_NTSC780, TGB_NTSC858, TGB_NTSC392 } TimeGenByte;
131
132BYTE SRAMTable[][ 60 ] =
133{
134 // TGB_NTSC624
135 {
136 0x33, // size of table = 51
137 0x0E, 0xC0, 0x00, 0x00, 0x90, 0x02, 0x03, 0x10, 0x03, 0x06,
138 0x10, 0x04, 0x12, 0x12, 0x05, 0x02, 0x13, 0x04, 0x19, 0x00,
139 0x04, 0x39, 0x00, 0x06, 0x59, 0x08, 0x03, 0x85, 0x08, 0x07,
140 0x03, 0x50, 0x00, 0x91, 0x40, 0x00, 0x11, 0x01, 0x01, 0x4D,
141 0x0D, 0x02, 0x03, 0x11, 0x01, 0x05, 0x37, 0x00, 0x37, 0x21, 0x00
142 },
143 // TGB_NTSC780
144 {
145 0x33, // size of table = 51
146 0x0e, 0xc0, 0x00, 0x00, 0x90, 0xe2, 0x03, 0x10, 0x03, 0x06,
147 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
148 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x85, 0x08, 0x97,
149 0x03, 0x50, 0x50, 0xaf, 0x40, 0x30, 0x5f, 0x01, 0xf1, 0x7f,
150 0x0d, 0xf2, 0x03, 0x11, 0xf1, 0x05, 0x37, 0x30, 0x85, 0x21, 0x50
151 },
152 // TGB_NTSC858
153 {
154 0x33, // size of table = 51
155 0x0c, 0xc0, 0x00, 0x00, 0x90, 0xc2, 0x03, 0x10, 0x03, 0x06,
156 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
157 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x83, 0x08, 0x97,
158 0x03, 0x50, 0x30, 0xc0, 0x40, 0x30, 0x86, 0x01, 0x01, 0xa6,
159 0x0d, 0x62, 0x03, 0x11, 0x61, 0x05, 0x37, 0x30, 0xac, 0x21, 0x50
160 },
161 // TGB_NTSC392
162 // This table has been modified to be used for Fusion Rev D
163 {
164 0x2A, // size of table = 42
165 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
166 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
167 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
168 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
169 0x20, 0x00
170 }
171};
172
173//===========================================================================
174// This is the structure of the camera specifications
175//===========================================================================
176typedef struct tag_cameraSpec
177{
178 SignalFormat signal; // which digital signal format the camera has
179 VideoFormat vidFormat; // video standard
180 SyncVideoRef syncRef; // which sync video reference is used
181 State syncOutput; // enable sync output for sync video input?
182 DecInputClk iClk; // which input clock is used
183 TimeGenByte tgb; // which timing generator byte does the camera use
184 int HReset; // select 64, 48, 32, or 16 CLKx1 for HReset
185 PLLFreq pllFreq; // what synthesized frequency to set PLL to
186 VSIZEPARMS vSize; // video size the camera produces
187 int lineCount; // expected total number of half-line per frame - 1
188 BOOL interlace; // interlace signal?
189} CameraSpec;
190
191//===========================================================================
192// <UPDATE REQUIRED>
193// Camera specifications database. Update this table whenever camera spec
194// has been changed or added/deleted supported camera models
195//===========================================================================
196static CameraSpec dbCameraSpec[ N_CAMERAOPTIONS ] =
197{ // Silicon Vision 512N
198 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC624, 64, KHz19636,
199 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
200 { 512, 0x64, 480, 0x13, 240 }, 0, TRUE
201 },
202 // Logitech VideoMan 1.3
203 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC780, 64, KHz24545,
204 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
205 { 640, 0x80, 480, 0x1A, 240 }, 0, TRUE
206 },
207 // Rockwell QuartzSight
208 // Note: Fusion Rev D (rev ID 0x02) and later supports 16 pixels for HReset which is preferable.
209 // Use 32 for earlier version of hardware. Clkx1_HDELAY also changed from 0x27 to 0x20.
210 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC392, 16, KHz28636,
211 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
212 { 352, 0x20, 576, 0x08, 288 }, 607, FALSE
213 }
214};
215*/
216
217/*
218The corresponding APIs required to be invoked are:
219SetConnector( ConCamera, TRUE/FALSE );
220SetSignalFormat( spec.signal );
221SetVideoFormat( spec.vidFormat );
222SetSyncVideoRef( spec.syncRef );
223SetEnableSyncOutput( spec.syncOutput );
224SetTimGenByte( SRAMTable[ spec.tgb ], SRAMTableSize[ spec.tgb ] );
225SetHReset( spec.HReset );
226SetPLL( spec.pllFreq );
227SetDecInputClock( spec.iClk );
228SetVideoInfo( spec.vSize );
229SetTotalLineCount( spec.lineCount );
230SetInterlaceMode( spec.interlace );
231*/
232
233/* from web:
234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525
241PAL square pixel 14.75 MHz 944 768 625
242PAL CCIR-601 13.5 MHz 864 720 625
243PAL 4FSc 17.72 MHz 1135 948 625
244
245For the CCIR-601 standards, the sampling is based on a static orthogonal sampling grid. The luminance component (Y) is sampled at 13.5 MHz, while the two color difference signals, Cr and Cb are sampled at half that, or 6.75 MHz. The Cr and Cb samples are colocated with alternate Y samples, and they are taken at the same position on each line, such that one sample is coincident with the 50% point of the falling edge of analog sync. The samples are coded to either 8 or 10 bits per component.
246*/
247
248/* from DScaler:*/
249/*
250//===========================================================================
251// CCIR656 Digital Input Support: The tables were taken from DScaler proyect
252//
253// 13 Dec 2000 - Michael Eskin, Conexant Systems - Initial version
254//
255
256//===========================================================================
257// Timing generator SRAM table values for CCIR601 720x480 NTSC
258//===========================================================================
259// For NTSC CCIR656
260BYTE BtCard::SRAMTable_NTSC[] =
261{
262 // SRAM Timing Table for NTSC
263 0x0c, 0xc0, 0x00,
264 0x00, 0x90, 0xc2,
265 0x03, 0x10, 0x03,
266 0x06, 0x10, 0x34,
267 0x12, 0x12, 0x65,
268 0x02, 0x13, 0x24,
269 0x19, 0x00, 0x24,
270 0x39, 0x00, 0x96,
271 0x59, 0x08, 0x93,
272 0x83, 0x08, 0x97,
273 0x03, 0x50, 0x30,
274 0xc0, 0x40, 0x30,
275 0x86, 0x01, 0x01,
276 0xa6, 0x0d, 0x62,
277 0x03, 0x11, 0x61,
278 0x05, 0x37, 0x30,
279 0xac, 0x21, 0x50
280};
281
282//===========================================================================
283// Timing generator SRAM table values for CCIR601 720x576 NTSC
284//===========================================================================
285// For PAL CCIR656
286BYTE BtCard::SRAMTable_PAL[] =
287{
288 // SRAM Timing Table for PAL
289 0x36, 0x11, 0x01,
290 0x00, 0x90, 0x02,
291 0x05, 0x10, 0x04,
292 0x16, 0x14, 0x05,
293 0x11, 0x00, 0x04,
294 0x12, 0xc0, 0x00,
295 0x31, 0x00, 0x06,
296 0x51, 0x08, 0x03,
297 0x89, 0x08, 0x07,
298 0xc0, 0x44, 0x00,
299 0x81, 0x01, 0x01,
300 0xa9, 0x0d, 0x02,
301 0x02, 0x50, 0x03,
302 0x37, 0x3d, 0x00,
303 0xaf, 0x21, 0x00,
304};
305*/
diff --git a/drivers/media/video/bt848.h b/drivers/media/video/bt848.h
new file mode 100644
index 000000000000..0bcd95303bb0
--- /dev/null
+++ b/drivers/media/video/bt848.h
@@ -0,0 +1,366 @@
1/*
2 bt848.h - Bt848 register offsets
3
4 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
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
21#ifndef _BT848_H_
22#define _BT848_H_
23
24#ifndef PCI_VENDOR_ID_BROOKTREE
25#define PCI_VENDOR_ID_BROOKTREE 0x109e
26#endif
27#ifndef PCI_DEVICE_ID_BT848
28#define PCI_DEVICE_ID_BT848 0x350
29#endif
30#ifndef PCI_DEVICE_ID_BT849
31#define PCI_DEVICE_ID_BT849 0x351
32#endif
33#ifndef PCI_DEVICE_ID_BT878
34#define PCI_DEVICE_ID_BT878 0x36e
35#endif
36#ifndef PCI_DEVICE_ID_BT879
37#define PCI_DEVICE_ID_BT879 0x36f
38#endif
39
40
41/* Brooktree 848 registers */
42
43#define BT848_DSTATUS 0x000
44#define BT848_DSTATUS_PRES (1<<7)
45#define BT848_DSTATUS_HLOC (1<<6)
46#define BT848_DSTATUS_FIELD (1<<5)
47#define BT848_DSTATUS_NUML (1<<4)
48#define BT848_DSTATUS_CSEL (1<<3)
49#define BT848_DSTATUS_PLOCK (1<<2)
50#define BT848_DSTATUS_LOF (1<<1)
51#define BT848_DSTATUS_COF (1<<0)
52
53#define BT848_IFORM 0x004
54#define BT848_IFORM_HACTIVE (1<<7)
55#define BT848_IFORM_MUXSEL (3<<5)
56#define BT848_IFORM_MUX0 (2<<5)
57#define BT848_IFORM_MUX1 (3<<5)
58#define BT848_IFORM_MUX2 (1<<5)
59#define BT848_IFORM_XTSEL (3<<3)
60#define BT848_IFORM_XT0 (1<<3)
61#define BT848_IFORM_XT1 (2<<3)
62#define BT848_IFORM_XTAUTO (3<<3)
63#define BT848_IFORM_XTBOTH (3<<3)
64#define BT848_IFORM_NTSC 1
65#define BT848_IFORM_NTSC_J 2
66#define BT848_IFORM_PAL_BDGHI 3
67#define BT848_IFORM_PAL_M 4
68#define BT848_IFORM_PAL_N 5
69#define BT848_IFORM_SECAM 6
70#define BT848_IFORM_PAL_NC 7
71#define BT848_IFORM_AUTO 0
72#define BT848_IFORM_NORM 7
73
74#define BT848_TDEC 0x008
75#define BT848_TDEC_DEC_FIELD (1<<7)
76#define BT848_TDEC_FLDALIGN (1<<6)
77#define BT848_TDEC_DEC_RAT (0x1f)
78
79#define BT848_E_CROP 0x00C
80#define BT848_O_CROP 0x08C
81
82#define BT848_E_VDELAY_LO 0x010
83#define BT848_O_VDELAY_LO 0x090
84
85#define BT848_E_VACTIVE_LO 0x014
86#define BT848_O_VACTIVE_LO 0x094
87
88#define BT848_E_HDELAY_LO 0x018
89#define BT848_O_HDELAY_LO 0x098
90
91#define BT848_E_HACTIVE_LO 0x01C
92#define BT848_O_HACTIVE_LO 0x09C
93
94#define BT848_E_HSCALE_HI 0x020
95#define BT848_O_HSCALE_HI 0x0A0
96
97#define BT848_E_HSCALE_LO 0x024
98#define BT848_O_HSCALE_LO 0x0A4
99
100#define BT848_BRIGHT 0x028
101
102#define BT848_E_CONTROL 0x02C
103#define BT848_O_CONTROL 0x0AC
104#define BT848_CONTROL_LNOTCH (1<<7)
105#define BT848_CONTROL_COMP (1<<6)
106#define BT848_CONTROL_LDEC (1<<5)
107#define BT848_CONTROL_CBSENSE (1<<4)
108#define BT848_CONTROL_CON_MSB (1<<2)
109#define BT848_CONTROL_SAT_U_MSB (1<<1)
110#define BT848_CONTROL_SAT_V_MSB (1<<0)
111
112#define BT848_CONTRAST_LO 0x030
113#define BT848_SAT_U_LO 0x034
114#define BT848_SAT_V_LO 0x038
115#define BT848_HUE 0x03C
116
117#define BT848_E_SCLOOP 0x040
118#define BT848_O_SCLOOP 0x0C0
119#define BT848_SCLOOP_CAGC (1<<6)
120#define BT848_SCLOOP_CKILL (1<<5)
121#define BT848_SCLOOP_HFILT_AUTO (0<<3)
122#define BT848_SCLOOP_HFILT_CIF (1<<3)
123#define BT848_SCLOOP_HFILT_QCIF (2<<3)
124#define BT848_SCLOOP_HFILT_ICON (3<<3)
125
126#define BT848_SCLOOP_PEAK (1<<7)
127#define BT848_SCLOOP_HFILT_MINP (1<<3)
128#define BT848_SCLOOP_HFILT_MEDP (2<<3)
129#define BT848_SCLOOP_HFILT_MAXP (3<<3)
130
131
132#define BT848_OFORM 0x048
133#define BT848_OFORM_RANGE (1<<7)
134#define BT848_OFORM_CORE0 (0<<5)
135#define BT848_OFORM_CORE8 (1<<5)
136#define BT848_OFORM_CORE16 (2<<5)
137#define BT848_OFORM_CORE32 (3<<5)
138
139#define BT848_E_VSCALE_HI 0x04C
140#define BT848_O_VSCALE_HI 0x0CC
141#define BT848_VSCALE_YCOMB (1<<7)
142#define BT848_VSCALE_COMB (1<<6)
143#define BT848_VSCALE_INT (1<<5)
144#define BT848_VSCALE_HI 15
145
146#define BT848_E_VSCALE_LO 0x050
147#define BT848_O_VSCALE_LO 0x0D0
148#define BT848_TEST 0x054
149#define BT848_ADELAY 0x060
150#define BT848_BDELAY 0x064
151
152#define BT848_ADC 0x068
153#define BT848_ADC_RESERVED (2<<6)
154#define BT848_ADC_SYNC_T (1<<5)
155#define BT848_ADC_AGC_EN (1<<4)
156#define BT848_ADC_CLK_SLEEP (1<<3)
157#define BT848_ADC_Y_SLEEP (1<<2)
158#define BT848_ADC_C_SLEEP (1<<1)
159#define BT848_ADC_CRUSH (1<<0)
160
161#define BT848_WC_UP 0x044
162#define BT848_WC_DOWN 0x078
163
164#define BT848_E_VTC 0x06C
165#define BT848_O_VTC 0x0EC
166#define BT848_VTC_HSFMT (1<<7)
167#define BT848_VTC_VFILT_2TAP 0
168#define BT848_VTC_VFILT_3TAP 1
169#define BT848_VTC_VFILT_4TAP 2
170#define BT848_VTC_VFILT_5TAP 3
171
172#define BT848_SRESET 0x07C
173
174#define BT848_COLOR_FMT 0x0D4
175#define BT848_COLOR_FMT_O_RGB32 (0<<4)
176#define BT848_COLOR_FMT_O_RGB24 (1<<4)
177#define BT848_COLOR_FMT_O_RGB16 (2<<4)
178#define BT848_COLOR_FMT_O_RGB15 (3<<4)
179#define BT848_COLOR_FMT_O_YUY2 (4<<4)
180#define BT848_COLOR_FMT_O_BtYUV (5<<4)
181#define BT848_COLOR_FMT_O_Y8 (6<<4)
182#define BT848_COLOR_FMT_O_RGB8 (7<<4)
183#define BT848_COLOR_FMT_O_YCrCb422 (8<<4)
184#define BT848_COLOR_FMT_O_YCrCb411 (9<<4)
185#define BT848_COLOR_FMT_O_RAW (14<<4)
186#define BT848_COLOR_FMT_E_RGB32 0
187#define BT848_COLOR_FMT_E_RGB24 1
188#define BT848_COLOR_FMT_E_RGB16 2
189#define BT848_COLOR_FMT_E_RGB15 3
190#define BT848_COLOR_FMT_E_YUY2 4
191#define BT848_COLOR_FMT_E_BtYUV 5
192#define BT848_COLOR_FMT_E_Y8 6
193#define BT848_COLOR_FMT_E_RGB8 7
194#define BT848_COLOR_FMT_E_YCrCb422 8
195#define BT848_COLOR_FMT_E_YCrCb411 9
196#define BT848_COLOR_FMT_E_RAW 14
197
198#define BT848_COLOR_FMT_RGB32 0x00
199#define BT848_COLOR_FMT_RGB24 0x11
200#define BT848_COLOR_FMT_RGB16 0x22
201#define BT848_COLOR_FMT_RGB15 0x33
202#define BT848_COLOR_FMT_YUY2 0x44
203#define BT848_COLOR_FMT_BtYUV 0x55
204#define BT848_COLOR_FMT_Y8 0x66
205#define BT848_COLOR_FMT_RGB8 0x77
206#define BT848_COLOR_FMT_YCrCb422 0x88
207#define BT848_COLOR_FMT_YCrCb411 0x99
208#define BT848_COLOR_FMT_RAW 0xee
209
210#define BT848_VTOTAL_LO 0xB0
211#define BT848_VTOTAL_HI 0xB4
212
213#define BT848_COLOR_CTL 0x0D8
214#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
215#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
216#define BT848_COLOR_CTL_RGB_DED (1<<5)
217#define BT848_COLOR_CTL_GAMMA (1<<4)
218#define BT848_COLOR_CTL_WSWAP_ODD (1<<3)
219#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2)
220#define BT848_COLOR_CTL_BSWAP_ODD (1<<1)
221#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0)
222
223#define BT848_CAP_CTL 0x0DC
224#define BT848_CAP_CTL_DITH_FRAME (1<<4)
225#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
226#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
227#define BT848_CAP_CTL_CAPTURE_ODD (1<<1)
228#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0)
229
230#define BT848_VBI_PACK_SIZE 0x0E0
231
232#define BT848_VBI_PACK_DEL 0x0E4
233#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc
234#define BT848_VBI_PACK_DEL_EXT_FRAME 2
235#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1
236
237
238#define BT848_INT_STAT 0x100
239#define BT848_INT_MASK 0x104
240
241#define BT848_INT_ETBF (1<<23)
242
243#define BT848_INT_RISCS (0xf<<28)
244#define BT848_INT_RISC_EN (1<<27)
245#define BT848_INT_RACK (1<<25)
246#define BT848_INT_FIELD (1<<24)
247#define BT848_INT_SCERR (1<<19)
248#define BT848_INT_OCERR (1<<18)
249#define BT848_INT_PABORT (1<<17)
250#define BT848_INT_RIPERR (1<<16)
251#define BT848_INT_PPERR (1<<15)
252#define BT848_INT_FDSR (1<<14)
253#define BT848_INT_FTRGT (1<<13)
254#define BT848_INT_FBUS (1<<12)
255#define BT848_INT_RISCI (1<<11)
256#define BT848_INT_GPINT (1<<9)
257#define BT848_INT_I2CDONE (1<<8)
258#define BT848_INT_VPRES (1<<5)
259#define BT848_INT_HLOCK (1<<4)
260#define BT848_INT_OFLOW (1<<3)
261#define BT848_INT_HSYNC (1<<2)
262#define BT848_INT_VSYNC (1<<1)
263#define BT848_INT_FMTCHG (1<<0)
264
265
266#define BT848_GPIO_DMA_CTL 0x10C
267#define BT848_GPIO_DMA_CTL_GPINTC (1<<15)
268#define BT848_GPIO_DMA_CTL_GPINTI (1<<14)
269#define BT848_GPIO_DMA_CTL_GPWEC (1<<13)
270#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11)
271#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10)
272#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6)
273#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6)
274#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6)
275#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6)
276#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4)
277#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4)
278#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4)
279#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4)
280#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2)
281#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2)
282#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2)
283#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2)
284#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1)
285#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0)
286
287#define BT848_I2C 0x110
288#define BT878_I2C_MODE (1<<7)
289#define BT878_I2C_RATE (1<<6)
290#define BT878_I2C_NOSTOP (1<<5)
291#define BT878_I2C_NOSTART (1<<4)
292#define BT848_I2C_DIV (0xf<<4)
293#define BT848_I2C_SYNC (1<<3)
294#define BT848_I2C_W3B (1<<2)
295#define BT848_I2C_SCL (1<<1)
296#define BT848_I2C_SDA (1<<0)
297
298#define BT848_RISC_STRT_ADD 0x114
299#define BT848_GPIO_OUT_EN 0x118
300#define BT848_GPIO_REG_INP 0x11C
301#define BT848_RISC_COUNT 0x120
302#define BT848_GPIO_DATA 0x200
303
304
305/* Bt848 RISC commands */
306
307/* only for the SYNC RISC command */
308#define BT848_FIFO_STATUS_FM1 0x06
309#define BT848_FIFO_STATUS_FM3 0x0e
310#define BT848_FIFO_STATUS_SOL 0x02
311#define BT848_FIFO_STATUS_EOL4 0x01
312#define BT848_FIFO_STATUS_EOL3 0x0d
313#define BT848_FIFO_STATUS_EOL2 0x09
314#define BT848_FIFO_STATUS_EOL1 0x05
315#define BT848_FIFO_STATUS_VRE 0x04
316#define BT848_FIFO_STATUS_VRO 0x0c
317#define BT848_FIFO_STATUS_PXV 0x00
318
319#define BT848_RISC_RESYNC (1<<15)
320
321/* WRITE and SKIP */
322/* disable which bytes of each DWORD */
323#define BT848_RISC_BYTE0 (1U<<12)
324#define BT848_RISC_BYTE1 (1U<<13)
325#define BT848_RISC_BYTE2 (1U<<14)
326#define BT848_RISC_BYTE3 (1U<<15)
327#define BT848_RISC_BYTE_ALL (0x0fU<<12)
328#define BT848_RISC_BYTE_NONE 0
329/* cause RISCI */
330#define BT848_RISC_IRQ (1U<<24)
331/* RISC command is last one in this line */
332#define BT848_RISC_EOL (1U<<26)
333/* RISC command is first one in this line */
334#define BT848_RISC_SOL (1U<<27)
335
336#define BT848_RISC_WRITE (0x01U<<28)
337#define BT848_RISC_SKIP (0x02U<<28)
338#define BT848_RISC_WRITEC (0x05U<<28)
339#define BT848_RISC_JUMP (0x07U<<28)
340#define BT848_RISC_SYNC (0x08U<<28)
341
342#define BT848_RISC_WRITE123 (0x09U<<28)
343#define BT848_RISC_SKIP123 (0x0aU<<28)
344#define BT848_RISC_WRITE1S23 (0x0bU<<28)
345
346
347/* Bt848A and higher only !! */
348#define BT848_TGLB 0x080
349#define BT848_TGCTRL 0x084
350#define BT848_FCAP 0x0E8
351#define BT848_PLL_F_LO 0x0F0
352#define BT848_PLL_F_HI 0x0F4
353
354#define BT848_PLL_XCI 0x0F8
355#define BT848_PLL_X (1<<7)
356#define BT848_PLL_C (1<<6)
357
358#define BT848_DVSIF 0x0FC
359
360/* Bt878 register */
361
362#define BT878_DEVCTRL 0x40
363#define BT878_EN_TBFX 0x02
364#define BT878_EN_VSFX 0x04
365
366#endif
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
new file mode 100644
index 000000000000..72c7eb0f8c24
--- /dev/null
+++ b/drivers/media/video/bt856.c
@@ -0,0 +1,442 @@
1/*
2 * bt856 - BT856A Digital Video Encoder (Rockwell Part)
3 *
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 *
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * This code was modify/ported from the saa7111 driver written
11 * by Dave Perks.
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
15 *
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
53MODULE_AUTHOR("Mike Bernson & Dave Perks");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(s) (s)->name
60
61#include <linux/video_encoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75#define REG_OFFSET 0xCE
76
77struct bt856 {
78 unsigned char reg[32];
79
80 int norm;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86};
87
88#define I2C_BT856 0x88
89
90/* ----------------------------------------------------------------------- */
91
92static inline int
93bt856_write (struct i2c_client *client,
94 u8 reg,
95 u8 value)
96{
97 struct bt856 *encoder = i2c_get_clientdata(client);
98
99 encoder->reg[reg - REG_OFFSET] = value;
100 return i2c_smbus_write_byte_data(client, reg, value);
101}
102
103static inline int
104bt856_setbit (struct i2c_client *client,
105 u8 reg,
106 u8 bit,
107 u8 value)
108{
109 struct bt856 *encoder = i2c_get_clientdata(client);
110
111 return bt856_write(client, reg,
112 (encoder->
113 reg[reg - REG_OFFSET] & ~(1 << bit)) |
114 (value ? (1 << bit) : 0));
115}
116
117static void
118bt856_dump (struct i2c_client *client)
119{
120 int i;
121 struct bt856 *encoder = i2c_get_clientdata(client);
122
123 printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
124 for (i = 0xd6; i <= 0xde; i += 2)
125 printk(" %02x", encoder->reg[i - REG_OFFSET]);
126 printk("\n");
127}
128
129/* ----------------------------------------------------------------------- */
130
131static int
132bt856_command (struct i2c_client *client,
133 unsigned int cmd,
134 void *arg)
135{
136 struct bt856 *encoder = i2c_get_clientdata(client);
137
138 switch (cmd) {
139
140 case 0:
141 /* This is just for testing!!! */
142 dprintk(1, KERN_INFO "bt856: init\n");
143 bt856_write(client, 0xdc, 0x18);
144 bt856_write(client, 0xda, 0);
145 bt856_write(client, 0xde, 0);
146
147 bt856_setbit(client, 0xdc, 3, 1);
148 //bt856_setbit(client, 0xdc, 6, 0);
149 bt856_setbit(client, 0xdc, 4, 1);
150
151 switch (encoder->norm) {
152
153 case VIDEO_MODE_NTSC:
154 bt856_setbit(client, 0xdc, 2, 0);
155 break;
156
157 case VIDEO_MODE_PAL:
158 bt856_setbit(client, 0xdc, 2, 1);
159 break;
160 }
161
162 bt856_setbit(client, 0xdc, 1, 1);
163 bt856_setbit(client, 0xde, 4, 0);
164 bt856_setbit(client, 0xde, 3, 1);
165 if (debug != 0)
166 bt856_dump(client);
167 break;
168
169 case ENCODER_GET_CAPABILITIES:
170 {
171 struct video_encoder_capability *cap = arg;
172
173 dprintk(1, KERN_INFO "%s: get capabilities\n",
174 I2C_NAME(client));
175
176 cap->flags = VIDEO_ENCODER_PAL |
177 VIDEO_ENCODER_NTSC |
178 VIDEO_ENCODER_CCIR;
179 cap->inputs = 2;
180 cap->outputs = 1;
181 }
182 break;
183
184 case ENCODER_SET_NORM:
185 {
186 int *iarg = arg;
187
188 dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
189 *iarg);
190
191 switch (*iarg) {
192
193 case VIDEO_MODE_NTSC:
194 bt856_setbit(client, 0xdc, 2, 0);
195 break;
196
197 case VIDEO_MODE_PAL:
198 bt856_setbit(client, 0xdc, 2, 1);
199 bt856_setbit(client, 0xda, 0, 0);
200 //bt856_setbit(client, 0xda, 0, 1);
201 break;
202
203 default:
204 return -EINVAL;
205
206 }
207 encoder->norm = *iarg;
208 if (debug != 0)
209 bt856_dump(client);
210 }
211 break;
212
213 case ENCODER_SET_INPUT:
214 {
215 int *iarg = arg;
216
217 dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
218 *iarg);
219
220 /* We only have video bus.
221 * iarg = 0: input is from bt819
222 * iarg = 1: input is from ZR36060 */
223
224 switch (*iarg) {
225
226 case 0:
227 bt856_setbit(client, 0xde, 4, 0);
228 bt856_setbit(client, 0xde, 3, 1);
229 bt856_setbit(client, 0xdc, 3, 1);
230 bt856_setbit(client, 0xdc, 6, 0);
231 break;
232 case 1:
233 bt856_setbit(client, 0xde, 4, 0);
234 bt856_setbit(client, 0xde, 3, 1);
235 bt856_setbit(client, 0xdc, 3, 1);
236 bt856_setbit(client, 0xdc, 6, 1);
237 break;
238 case 2: // Color bar
239 bt856_setbit(client, 0xdc, 3, 0);
240 bt856_setbit(client, 0xde, 4, 1);
241 break;
242 default:
243 return -EINVAL;
244
245 }
246
247 if (debug != 0)
248 bt856_dump(client);
249 }
250 break;
251
252 case ENCODER_SET_OUTPUT:
253 {
254 int *iarg = arg;
255
256 dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
257 *iarg);
258
259 /* not much choice of outputs */
260 if (*iarg != 0) {
261 return -EINVAL;
262 }
263 }
264 break;
265
266 case ENCODER_ENABLE_OUTPUT:
267 {
268 int *iarg = arg;
269
270 encoder->enable = !!*iarg;
271
272 dprintk(1, KERN_INFO "%s: enable output %d\n",
273 I2C_NAME(client), encoder->enable);
274 }
275 break;
276
277 default:
278 return -EINVAL;
279 }
280
281 return 0;
282}
283
284/* ----------------------------------------------------------------------- */
285
286/*
287 * Generic i2c probe
288 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
289 */
290static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
291static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
292
293static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
294static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
295static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
296static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
297static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
298
299static struct i2c_client_address_data addr_data = {
300 .normal_i2c = normal_i2c,
301 .normal_i2c_range = normal_i2c_range,
302 .probe = probe,
303 .probe_range = probe_range,
304 .ignore = ignore,
305 .ignore_range = ignore_range,
306 .force = force
307};
308
309static struct i2c_driver i2c_driver_bt856;
310
311static int
312bt856_detect_client (struct i2c_adapter *adapter,
313 int address,
314 int kind)
315{
316 int i;
317 struct i2c_client *client;
318 struct bt856 *encoder;
319
320 dprintk(1,
321 KERN_INFO
322 "bt856.c: detecting bt856 client on address 0x%x\n",
323 address << 1);
324
325 /* Check if the adapter supports the needed features */
326 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
327 return 0;
328
329 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
330 if (client == 0)
331 return -ENOMEM;
332 memset(client, 0, sizeof(struct i2c_client));
333 client->addr = address;
334 client->adapter = adapter;
335 client->driver = &i2c_driver_bt856;
336 client->flags = I2C_CLIENT_ALLOW_USE;
337 strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
338
339 encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL);
340 if (encoder == NULL) {
341 kfree(client);
342 return -ENOMEM;
343 }
344 memset(encoder, 0, sizeof(struct bt856));
345 encoder->norm = VIDEO_MODE_NTSC;
346 encoder->enable = 1;
347 i2c_set_clientdata(client, encoder);
348
349 i = i2c_attach_client(client);
350 if (i) {
351 kfree(client);
352 kfree(encoder);
353 return i;
354 }
355
356 bt856_write(client, 0xdc, 0x18);
357 bt856_write(client, 0xda, 0);
358 bt856_write(client, 0xde, 0);
359
360 bt856_setbit(client, 0xdc, 3, 1);
361 //bt856_setbit(client, 0xdc, 6, 0);
362 bt856_setbit(client, 0xdc, 4, 1);
363
364 switch (encoder->norm) {
365
366 case VIDEO_MODE_NTSC:
367 bt856_setbit(client, 0xdc, 2, 0);
368 break;
369
370 case VIDEO_MODE_PAL:
371 bt856_setbit(client, 0xdc, 2, 1);
372 break;
373 }
374
375 bt856_setbit(client, 0xdc, 1, 1);
376 bt856_setbit(client, 0xde, 4, 0);
377 bt856_setbit(client, 0xde, 3, 1);
378
379 if (debug != 0)
380 bt856_dump(client);
381
382 dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
383 client->addr << 1);
384
385 return 0;
386}
387
388static int
389bt856_attach_adapter (struct i2c_adapter *adapter)
390{
391 dprintk(1,
392 KERN_INFO
393 "bt856.c: starting probe for adapter %s (0x%x)\n",
394 I2C_NAME(adapter), adapter->id);
395 return i2c_probe(adapter, &addr_data, &bt856_detect_client);
396}
397
398static int
399bt856_detach_client (struct i2c_client *client)
400{
401 struct bt856 *encoder = i2c_get_clientdata(client);
402 int err;
403
404 err = i2c_detach_client(client);
405 if (err) {
406 return err;
407 }
408
409 kfree(encoder);
410 kfree(client);
411
412 return 0;
413}
414
415/* ----------------------------------------------------------------------- */
416
417static struct i2c_driver i2c_driver_bt856 = {
418 .owner = THIS_MODULE,
419 .name = "bt856",
420
421 .id = I2C_DRIVERID_BT856,
422 .flags = I2C_DF_NOTIFY,
423
424 .attach_adapter = bt856_attach_adapter,
425 .detach_client = bt856_detach_client,
426 .command = bt856_command,
427};
428
429static int __init
430bt856_init (void)
431{
432 return i2c_add_driver(&i2c_driver_bt856);
433}
434
435static void __exit
436bt856_exit (void)
437{
438 i2c_del_driver(&i2c_driver_bt856);
439}
440
441module_init(bt856_init);
442module_exit(bt856_exit);
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
new file mode 100644
index 000000000000..7f2d515d2873
--- /dev/null
+++ b/drivers/media/video/btcx-risc.c
@@ -0,0 +1,262 @@
1/*
2 $Id: btcx-risc.c,v 1.6 2005/02/21 13:57:59 kraxel Exp $
3
4 btcx-risc.c
5
6 bt848/bt878/cx2388x risc code generator.
7
8 (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/interrupt.h>
31#include <linux/videodev2.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34
35#include "btcx-risc.h"
36
37MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
38MODULE_AUTHOR("Gerd Knorr");
39MODULE_LICENSE("GPL");
40
41static unsigned int debug = 0;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
44
45/* ---------------------------------------------------------- */
46/* allocate/free risc memory */
47
48static int memcnt;
49
50void btcx_riscmem_free(struct pci_dev *pci,
51 struct btcx_riscmem *risc)
52{
53 if (NULL == risc->cpu)
54 return;
55 if (debug) {
56 memcnt--;
57 printk("btcx: riscmem free [%d] dma=%lx\n",
58 memcnt, (unsigned long)risc->dma);
59 }
60 pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
61 memset(risc,0,sizeof(*risc));
62}
63
64int btcx_riscmem_alloc(struct pci_dev *pci,
65 struct btcx_riscmem *risc,
66 unsigned int size)
67{
68 u32 *cpu;
69 dma_addr_t dma;
70
71 if (NULL != risc->cpu && risc->size < size)
72 btcx_riscmem_free(pci,risc);
73 if (NULL == risc->cpu) {
74 cpu = pci_alloc_consistent(pci, size, &dma);
75 if (NULL == cpu)
76 return -ENOMEM;
77 risc->cpu = cpu;
78 risc->dma = dma;
79 risc->size = size;
80 if (debug) {
81 memcnt++;
82 printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
83 memcnt, (unsigned long)dma, cpu, size);
84 }
85 }
86 memset(risc->cpu,0,risc->size);
87 return 0;
88}
89
90/* ---------------------------------------------------------- */
91/* screen overlay helpers */
92
93int
94btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
95 struct v4l2_clip *clips, unsigned int n)
96{
97 if (win->left < 0) {
98 /* left */
99 clips[n].c.left = 0;
100 clips[n].c.top = 0;
101 clips[n].c.width = -win->left;
102 clips[n].c.height = win->height;
103 n++;
104 }
105 if (win->left + win->width > swidth) {
106 /* right */
107 clips[n].c.left = swidth - win->left;
108 clips[n].c.top = 0;
109 clips[n].c.width = win->width - clips[n].c.left;
110 clips[n].c.height = win->height;
111 n++;
112 }
113 if (win->top < 0) {
114 /* top */
115 clips[n].c.left = 0;
116 clips[n].c.top = 0;
117 clips[n].c.width = win->width;
118 clips[n].c.height = -win->top;
119 n++;
120 }
121 if (win->top + win->height > sheight) {
122 /* bottom */
123 clips[n].c.left = 0;
124 clips[n].c.top = sheight - win->top;
125 clips[n].c.width = win->width;
126 clips[n].c.height = win->height - clips[n].c.top;
127 n++;
128 }
129 return n;
130}
131
132int
133btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
134{
135 s32 nx,nw,dx;
136 unsigned int i;
137
138 /* fixup window */
139 nx = (win->left + mask) & ~mask;
140 nw = (win->width) & ~mask;
141 if (nx + nw > win->left + win->width)
142 nw -= mask+1;
143 dx = nx - win->left;
144 win->left = nx;
145 win->width = nw;
146 if (debug)
147 printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
148 win->width, win->height, win->left, win->top, dx);
149
150 /* fixup clips */
151 for (i = 0; i < n; i++) {
152 nx = (clips[i].c.left-dx) & ~mask;
153 nw = (clips[i].c.width) & ~mask;
154 if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
155 nw += mask+1;
156 clips[i].c.left = nx;
157 clips[i].c.width = nw;
158 if (debug)
159 printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n",
160 clips[i].c.width, clips[i].c.height,
161 clips[i].c.left, clips[i].c.top);
162 }
163 return 0;
164}
165
166void
167btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
168{
169 struct v4l2_clip swap;
170 int i,j,n;
171
172 if (nclips < 2)
173 return;
174 for (i = nclips-2; i >= 0; i--) {
175 for (n = 0, j = 0; j <= i; j++) {
176 if (clips[j].c.left > clips[j+1].c.left) {
177 swap = clips[j];
178 clips[j] = clips[j+1];
179 clips[j+1] = swap;
180 n++;
181 }
182 }
183 if (0 == n)
184 break;
185 }
186}
187
188void
189btcx_calc_skips(int line, int width, unsigned int *maxy,
190 struct btcx_skiplist *skips, unsigned int *nskips,
191 const struct v4l2_clip *clips, unsigned int nclips)
192{
193 unsigned int clip,skip;
194 int end,maxline;
195
196 skip=0;
197 maxline = 9999;
198 for (clip = 0; clip < nclips; clip++) {
199
200 /* sanity checks */
201 if (clips[clip].c.left + clips[clip].c.width <= 0)
202 continue;
203 if (clips[clip].c.left > (signed)width)
204 break;
205
206 /* vertical range */
207 if (line > clips[clip].c.top+clips[clip].c.height-1)
208 continue;
209 if (line < clips[clip].c.top) {
210 if (maxline > clips[clip].c.top-1)
211 maxline = clips[clip].c.top-1;
212 continue;
213 }
214 if (maxline > clips[clip].c.top+clips[clip].c.height-1)
215 maxline = clips[clip].c.top+clips[clip].c.height-1;
216
217 /* horizontal range */
218 if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
219 /* new one */
220 skips[skip].start = clips[clip].c.left;
221 if (skips[skip].start < 0)
222 skips[skip].start = 0;
223 skips[skip].end = clips[clip].c.left + clips[clip].c.width;
224 if (skips[skip].end > width)
225 skips[skip].end = width;
226 skip++;
227 } else {
228 /* overlaps -- expand last one */
229 end = clips[clip].c.left + clips[clip].c.width;
230 if (skips[skip-1].end < end)
231 skips[skip-1].end = end;
232 if (skips[skip-1].end > width)
233 skips[skip-1].end = width;
234 }
235 }
236 *nskips = skip;
237 *maxy = maxline;
238
239 if (debug) {
240 printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
241 for (skip = 0; skip < *nskips; skip++) {
242 printk(" %d-%d",skips[skip].start,skips[skip].end);
243 }
244 printk("\n");
245 }
246}
247
248/* ---------------------------------------------------------- */
249
250EXPORT_SYMBOL(btcx_riscmem_alloc);
251EXPORT_SYMBOL(btcx_riscmem_free);
252
253EXPORT_SYMBOL(btcx_screen_clips);
254EXPORT_SYMBOL(btcx_align);
255EXPORT_SYMBOL(btcx_sort_clips);
256EXPORT_SYMBOL(btcx_calc_skips);
257
258/*
259 * Local variables:
260 * c-basic-offset: 8
261 * End:
262 */
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
new file mode 100644
index 000000000000..41f60395a520
--- /dev/null
+++ b/drivers/media/video/btcx-risc.h
@@ -0,0 +1,35 @@
1/*
2 * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 */
4struct btcx_riscmem {
5 unsigned int size;
6 u32 *cpu;
7 u32 *jmp;
8 dma_addr_t dma;
9};
10
11struct btcx_skiplist {
12 int start;
13 int end;
14};
15
16int btcx_riscmem_alloc(struct pci_dev *pci,
17 struct btcx_riscmem *risc,
18 unsigned int size);
19void btcx_riscmem_free(struct pci_dev *pci,
20 struct btcx_riscmem *risc);
21
22int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
23 struct v4l2_clip *clips, unsigned int n);
24int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
25 unsigned int n, int mask);
26void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
27void btcx_calc_skips(int line, int width, unsigned int *maxy,
28 struct btcx_skiplist *skips, unsigned int *nskips,
29 const struct v4l2_clip *clips, unsigned int nclips);
30
31/*
32 * Local variables:
33 * c-basic-offset: 8
34 * End:
35 */
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
new file mode 100644
index 000000000000..abce874e71cc
--- /dev/null
+++ b/drivers/media/video/bttv-cards.c
@@ -0,0 +1,4350 @@
1/*
2 $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $
3
4 bttv-cards.c
5
6 this file has configuration informations - card-specific stuff
7 like the big tvcards array for the most part
8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27*/
28
29#include <linux/config.h>
30#include <linux/delay.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kmod.h>
34#include <linux/init.h>
35#include <linux/pci.h>
36#include <linux/vmalloc.h>
37#include <linux/firmware.h>
38
39#include <asm/io.h>
40
41#include "bttvp.h"
42#if 0 /* not working yet */
43#include "bt832.h"
44#endif
45
46/* fwd decl */
47static void boot_msp34xx(struct bttv *btv, int pin);
48static void boot_bt832(struct bttv *btv);
49static void hauppauge_eeprom(struct bttv *btv);
50static void avermedia_eeprom(struct bttv *btv);
51static void osprey_eeprom(struct bttv *btv);
52static void modtec_eeprom(struct bttv *btv);
53static void init_PXC200(struct bttv *btv);
54
55static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
56static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
57static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v,
58 int set);
59static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v,
60 int set);
61static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
62static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
63static void gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set);
64static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
65static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
66static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
67static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
68static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set);
69static void rv605_muxsel(struct bttv *btv, unsigned int input);
70static void eagle_muxsel(struct bttv *btv, unsigned int input);
71static void xguard_muxsel(struct bttv *btv, unsigned int input);
72static void ivc120_muxsel(struct bttv *btv, unsigned int input);
73static void gvc1100_muxsel(struct bttv *btv, unsigned int input);
74
75static void PXC200_muxsel(struct bttv *btv, unsigned int input);
76
77static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input);
78static void picolo_tetra_init(struct bttv *btv);
79
80static void tibetCS16_muxsel(struct bttv *btv, unsigned int input);
81static void tibetCS16_init(struct bttv *btv);
82
83static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input);
84static void kodicom4400r_init(struct bttv *btv);
85
86static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input);
87static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
88
89static int terratec_active_radio_upgrade(struct bttv *btv);
90static int tea5757_read(struct bttv *btv);
91static int tea5757_write(struct bttv *btv, int value);
92static void identify_by_eeprom(struct bttv *btv,
93 unsigned char eeprom_data[256]);
94static int __devinit pvr_boot(struct bttv *btv);
95
96/* config variables */
97static unsigned int triton1=0;
98static unsigned int vsfx=0;
99static unsigned int latency = UNSET;
100static unsigned int no_overlay=-1;
101
102static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
103static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
104static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
105static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
106static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
107static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
108#ifdef MODULE
109static unsigned int autoload = 1;
110#else
111static unsigned int autoload = 0;
112#endif
113static unsigned int gpiomask = UNSET;
114static unsigned int audioall = UNSET;
115static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
116
117/* insmod options */
118module_param(triton1, int, 0444);
119module_param(vsfx, int, 0444);
120module_param(no_overlay, int, 0444);
121module_param(latency, int, 0444);
122module_param(gpiomask, int, 0444);
123module_param(audioall, int, 0444);
124module_param(autoload, int, 0444);
125
126module_param_array(card, int, NULL, 0444);
127module_param_array(pll, int, NULL, 0444);
128module_param_array(tuner, int, NULL, 0444);
129module_param_array(svhs, int, NULL, 0444);
130module_param_array(remote, int, NULL, 0444);
131module_param_array(audiomux, int, NULL, 0444);
132
133MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
134 "[enable bug compatibility for triton1 + others]");
135MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
136 "[yet another chipset flaw workaround]");
137MODULE_PARM_DESC(latency,"pci latency timer");
138MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
139MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
140MODULE_PARM_DESC(tuner,"specify installed tuner type");
141MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
142
143/* ----------------------------------------------------------------------- */
144/* list of card IDs for bt878+ cards */
145
146static struct CARD {
147 unsigned id;
148 int cardnr;
149 char *name;
150} cards[] __devinitdata = {
151 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" },
152 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" },
153 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
154 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" },
155 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" },
156 { 0xff020070, BTTV_OSPREY500, "Osprey-500" },
157 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" },
158 { 0xff040070, BTTV_OSPREY540, "Osprey-540" },
159
160 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" },
161 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
162
163 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
164 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" },
165 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" },
166 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
167 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
168 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
169 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
170 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
171 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
172
173 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
174 // some cards ship with byteswapped IDs ...
175 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
176 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
177 // this seems to happen as well ...
178 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
179
180 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
181 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
182 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" },
183
184 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
185 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" },
186 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
187 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
188 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" },
189 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" },
190 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
191
192 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
193 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" },
194 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
195 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" },
196 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
197
198 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
199 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
200 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
201 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
202
203 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" },
204 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" },
205 // clashes with FlyVideo
206 //{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" },
207 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" },
208 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // LR102
209 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, // ??
210 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // ??
211
212 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
213 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
214 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
215 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
216 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
217
218 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" },
219 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" },
220 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" },
221 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" },
222 { 0x1433aa03, BTTV_PV143, "Security Eyes" },
223
224 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" },
225 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" },
226 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" },
227 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" },
228
229 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" },
230 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" },
231 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" },
232 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" },
233
234 { 0xa132ff00, BTTV_IVC100, "IVC-100" },
235 { 0xa1550000, BTTV_IVC200, "IVC-200" },
236 { 0xa1550001, BTTV_IVC200, "IVC-200" },
237 { 0xa1550002, BTTV_IVC200, "IVC-200" },
238 { 0xa1550003, BTTV_IVC200, "IVC-200" },
239 { 0xa1550100, BTTV_IVC200, "IVC-200G" },
240 { 0xa1550101, BTTV_IVC200, "IVC-200G" },
241 { 0xa1550102, BTTV_IVC200, "IVC-200G" },
242 { 0xa1550103, BTTV_IVC200, "IVC-200G" },
243 { 0xa182ff00, BTTV_IVC120, "IVC-120G" },
244 { 0xa182ff01, BTTV_IVC120, "IVC-120G" },
245 { 0xa182ff02, BTTV_IVC120, "IVC-120G" },
246 { 0xa182ff03, BTTV_IVC120, "IVC-120G" },
247 { 0xa182ff04, BTTV_IVC120, "IVC-120G" },
248 { 0xa182ff05, BTTV_IVC120, "IVC-120G" },
249 { 0xa182ff06, BTTV_IVC120, "IVC-120G" },
250 { 0xa182ff07, BTTV_IVC120, "IVC-120G" },
251 { 0xa182ff08, BTTV_IVC120, "IVC-120G" },
252 { 0xa182ff09, BTTV_IVC120, "IVC-120G" },
253 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" },
254 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" },
255 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" },
256 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" },
257 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" },
258 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" },
259
260 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" },
261 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" },
262
263 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
264 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
265 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
266 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
267 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
268 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" },
269
270 { 0x010115cb, BTTV_GMV1, "AG GMV1" },
271 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
272
273 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
274 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
275 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
276 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" },
277 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" },
278 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" },
279 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"},
280 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" },
281 { 0x146caa0c, BTTV_PV951, "ituner spectra8" },
282 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" },
283
284 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
285 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" },
286
287 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
288 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
289 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
290 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
291
292 // likely broken, vendor id doesn't match the other magic views ...
293 //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
294
295 // DVB cards (using pci function .1 for mpeg data xfer)
296 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
297 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
298 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
299 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
300 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" },
301 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
302 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
303 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" },
304
305 { 0, -1, NULL }
306};
307
308/* ----------------------------------------------------------------------- */
309/* array with description for bt848 / bt878 tv/grabber cards */
310
311struct tvcard bttv_tvcards[] = {
312{
313/* ---- card 0x00 ---------------------------------- */
314 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4,
316 .audio_inputs = 1,
317 .tuner = 0,
318 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1,
321},{
322 .name = "MIRO PCTV",
323 .video_inputs = 4,
324 .audio_inputs = 1,
325 .tuner = 0,
326 .svhs = 2,
327 .gpiomask = 15,
328 .muxsel = { 2, 3, 1, 1},
329 .audiomux = { 2, 0, 0, 0, 10},
330 .needs_tvaudio = 1,
331 .tuner_type = -1,
332},{
333 .name = "Hauppauge (bt848)",
334 .video_inputs = 4,
335 .audio_inputs = 1,
336 .tuner = 0,
337 .svhs = 2,
338 .gpiomask = 7,
339 .muxsel = { 2, 3, 1, 1},
340 .audiomux = { 0, 1, 2, 3, 4},
341 .needs_tvaudio = 1,
342 .tuner_type = -1,
343},{
344 .name = "STB, Gateway P/N 6000699 (bt848)",
345 .video_inputs = 3,
346 .audio_inputs = 1,
347 .tuner = 0,
348 .svhs = 2,
349 .gpiomask = 7,
350 .muxsel = { 2, 3, 1, 1},
351 .audiomux = { 4, 0, 2, 3, 1},
352 .no_msp34xx = 1,
353 .needs_tvaudio = 1,
354 .tuner_type = TUNER_PHILIPS_NTSC,
355 .pll = PLL_28,
356 .has_radio = 1,
357},{
358
359/* ---- card 0x04 ---------------------------------- */
360 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
361 .video_inputs = 4,
362 .audio_inputs = 0,
363 .tuner = -1,
364 .svhs = 2,
365 .gpiomask = 0,
366 .muxsel = { 2, 3, 1, 1},
367 .audiomux = { 0 },
368 .needs_tvaudio = 0,
369 .tuner_type = 4,
370},{
371 .name = "Diamond DTV2000",
372 .video_inputs = 4,
373 .audio_inputs = 1,
374 .tuner = 0,
375 .svhs = 2,
376 .gpiomask = 3,
377 .muxsel = { 2, 3, 1, 0},
378 .audiomux = { 0, 1, 0, 1, 3},
379 .needs_tvaudio = 1,
380 .tuner_type = -1,
381},{
382 .name = "AVerMedia TVPhone",
383 .video_inputs = 3,
384 .audio_inputs = 1,
385 .tuner = 0,
386 .svhs = 3,
387 .muxsel = { 2, 3, 1, 1},
388 .gpiomask = 0x0f,
389 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
390 /* 0x04 for some cards ?? */
391 .needs_tvaudio = 1,
392 .tuner_type = -1,
393 .audio_hook = avermedia_tvphone_audio,
394 .has_remote = 1,
395},{
396 .name = "MATRIX-Vision MV-Delta",
397 .video_inputs = 5,
398 .audio_inputs = 1,
399 .tuner = -1,
400 .svhs = 3,
401 .gpiomask = 0,
402 .muxsel = { 2, 3, 1, 0, 0},
403 .audiomux = {0 },
404 .needs_tvaudio = 1,
405 .tuner_type = -1,
406},{
407
408/* ---- card 0x08 ---------------------------------- */
409 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
410 .video_inputs = 4,
411 .audio_inputs = 1,
412 .tuner = 0,
413 .svhs = 2,
414 .gpiomask = 0xc00,
415 .muxsel = { 2, 3, 1, 1},
416 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
417 .needs_tvaudio = 1,
418 .pll = PLL_28,
419 .tuner_type = -1,
420},{
421 .name = "IMS/IXmicro TurboTV",
422 .video_inputs = 3,
423 .audio_inputs = 1,
424 .tuner = 0,
425 .svhs = 2,
426 .gpiomask = 3,
427 .muxsel = { 2, 3, 1, 1},
428 .audiomux = { 1, 1, 2, 3, 0},
429 .needs_tvaudio = 0,
430 .pll = PLL_28,
431 .tuner_type = TUNER_TEMIC_PAL,
432},{
433 .name = "Hauppauge (bt878)",
434 .video_inputs = 4,
435 .audio_inputs = 1,
436 .tuner = 0,
437 .svhs = 2,
438 .gpiomask = 0x0f, /* old: 7 */
439 .muxsel = { 2, 0, 1, 1},
440 .audiomux = { 0, 1, 2, 3, 4},
441 .needs_tvaudio = 1,
442 .pll = PLL_28,
443 .tuner_type = -1,
444},{
445 .name = "MIRO PCTV pro",
446 .video_inputs = 3,
447 .audio_inputs = 1,
448 .tuner = 0,
449 .svhs = 2,
450 .gpiomask = 0x3014f,
451 .muxsel = { 2, 3, 1, 1},
452 .audiomux = { 0x20001,0x10001, 0, 0,10},
453 .needs_tvaudio = 1,
454 .tuner_type = -1,
455},{
456
457/* ---- card 0x0c ---------------------------------- */
458 .name = "ADS Technologies Channel Surfer TV (bt848)",
459 .video_inputs = 3,
460 .audio_inputs = 1,
461 .tuner = 0,
462 .svhs = 2,
463 .gpiomask = 15,
464 .muxsel = { 2, 3, 1, 1},
465 .audiomux = { 13, 14, 11, 7, 0, 0},
466 .needs_tvaudio = 1,
467 .tuner_type = -1,
468},{
469 .name = "AVerMedia TVCapture 98",
470 .video_inputs = 3,
471 .audio_inputs = 4,
472 .tuner = 0,
473 .svhs = 2,
474 .gpiomask = 15,
475 .muxsel = { 2, 3, 1, 1},
476 .audiomux = { 13, 14, 11, 7, 0, 0},
477 .needs_tvaudio = 1,
478 .msp34xx_alt = 1,
479 .pll = PLL_28,
480 .tuner_type = TUNER_PHILIPS_PAL,
481 .audio_hook = avermedia_tv_stereo_audio,
482},{
483 .name = "Aimslab Video Highway Xtreme (VHX)",
484 .video_inputs = 3,
485 .audio_inputs = 1,
486 .tuner = 0,
487 .svhs = 2,
488 .gpiomask = 7,
489 .muxsel = { 2, 3, 1, 1},
490 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
491 .needs_tvaudio = 1,
492 .pll = PLL_28,
493 .tuner_type = -1,
494},{
495 .name = "Zoltrix TV-Max",
496 .video_inputs = 3,
497 .audio_inputs = 1,
498 .tuner = 0,
499 .svhs = 2,
500 .gpiomask = 15,
501 .muxsel = { 2, 3, 1, 1},
502 .audiomux = {0 , 0, 1 , 0, 10},
503 .needs_tvaudio = 1,
504 .tuner_type = -1,
505},{
506
507/* ---- card 0x10 ---------------------------------- */
508 .name = "Prolink Pixelview PlayTV (bt878)",
509 .video_inputs = 3,
510 .audio_inputs = 1,
511 .tuner = 0,
512 .svhs = 2,
513 .gpiomask = 0x01fe00,
514 .muxsel = { 2, 3, 1, 1},
515#if 0
516 // old
517 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
518#else
519 // 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru>
520 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
521#endif
522 .needs_tvaudio = 1,
523 .pll = PLL_28,
524 .tuner_type = -1,
525},{
526 .name = "Leadtek WinView 601",
527 .video_inputs = 3,
528 .audio_inputs = 1,
529 .tuner = 0,
530 .svhs = 2,
531 .gpiomask = 0x8300f8,
532 .muxsel = { 2, 3, 1, 1,0},
533 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
534 .needs_tvaudio = 1,
535 .tuner_type = -1,
536 .audio_hook = winview_audio,
537 .has_radio = 1,
538},{
539 .name = "AVEC Intercapture",
540 .video_inputs = 3,
541 .audio_inputs = 2,
542 .tuner = 0,
543 .svhs = 2,
544 .gpiomask = 0,
545 .muxsel = {2, 3, 1, 1},
546 .audiomux = {1, 0, 0, 0, 0},
547 .needs_tvaudio = 1,
548 .tuner_type = -1,
549},{
550 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
551 .video_inputs = 4,
552 .audio_inputs = 1,
553 .tuner = -1,
554 .svhs = -1,
555 .gpiomask = 0x8dff00,
556 .muxsel = { 2, 3, 1, 1},
557 .audiomux = { 0 },
558 .no_msp34xx = 1,
559 .tuner_type = -1,
560},{
561
562/* ---- card 0x14 ---------------------------------- */
563 .name = "CEI Raffles Card",
564 .video_inputs = 3,
565 .audio_inputs = 3,
566 .tuner = 0,
567 .svhs = 2,
568 .muxsel = {2, 3, 1, 1},
569 .tuner_type = -1,
570},{
571 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
572 .video_inputs = 4,
573 .audio_inputs = 2, // tuner, line in
574 .tuner = 0,
575 .svhs = 2,
576 .gpiomask = 0x1800,
577 .muxsel = { 2, 3, 1, 1},
578 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
579 .pll = PLL_28,
580 .tuner_type = TUNER_PHILIPS_PAL_I,
581},{
582 .name = "Askey CPH050/ Phoebe Tv Master + FM",
583 .video_inputs = 3,
584 .audio_inputs = 1,
585 .tuner = 0,
586 .svhs = 2,
587 .gpiomask = 0xc00,
588 .muxsel = { 2, 3, 1, 1},
589 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
590 .needs_tvaudio = 1,
591 .pll = PLL_28,
592 .tuner_type = -1,
593},{
594 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
595 .video_inputs = 3,
596 .audio_inputs = 1,
597 .tuner = 0,
598 .svhs = -1,
599 .gpiomask = 7,
600 .muxsel = { 2, 3, -1 },
601 .digital_mode = DIGITAL_MODE_CAMERA,
602 .audiomux = { 0, 0, 0, 0, 0 },
603 .no_msp34xx = 1,
604 .pll = PLL_28,
605 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
606},{
607
608/* ---- card 0x18 ---------------------------------- */
609 .name = "Askey CPH05X/06X (bt878) [many vendors]",
610 .video_inputs = 3,
611 .audio_inputs = 1,
612 .tuner = 0,
613 .svhs = 2,
614 .gpiomask = 0xe00,
615 .muxsel = { 2, 3, 1, 1},
616 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
617 .needs_tvaudio = 1,
618 .pll = PLL_28,
619 .tuner_type = -1,
620 .has_remote = 1,
621},{
622 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
623 .video_inputs = 3,
624 .audio_inputs = 1,
625 .tuner = 0,
626 .svhs = 2,
627 .gpiomask = 0x1f0fff,
628 .muxsel = { 2, 3, 1, 1},
629 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
630 .needs_tvaudio = 0,
631 .tuner_type = TUNER_PHILIPS_PAL,
632 .audio_hook = terratv_audio,
633},{
634 .name = "Hauppauge WinCam newer (bt878)",
635 .video_inputs = 4,
636 .audio_inputs = 1,
637 .tuner = 0,
638 .svhs = 3,
639 .gpiomask = 7,
640 .muxsel = { 2, 0, 1, 1},
641 .audiomux = { 0, 1, 2, 3, 4},
642 .needs_tvaudio = 1,
643 .tuner_type = -1,
644},{
645 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
646 .video_inputs = 4,
647 .audio_inputs = 2,
648 .tuner = 0,
649 .svhs = 2,
650 .gpiomask = 0x1800,
651 .muxsel = { 2, 3, 1, 1},
652 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
653 .pll = PLL_28,
654 .tuner_type = TUNER_PHILIPS_SECAM,
655},{
656
657/* ---- card 0x1c ---------------------------------- */
658 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
659 .video_inputs = 3,
660 .audio_inputs = 1,
661 .tuner = 0,
662 .svhs = 2,
663 .gpiomask = 0x1f0fff,
664 .muxsel = { 2, 3, 1, 1},
665 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
666 .needs_tvaudio = 0,
667 .tuner_type = TUNER_PHILIPS_PAL,
668 .audio_hook = terratv_audio,
669 /* GPIO wiring:
670 External 20 pin connector (for Active Radio Upgrade board)
671 gpio00: i2c-sda
672 gpio01: i2c-scl
673 gpio02: om5610-data
674 gpio03: om5610-clk
675 gpio04: om5610-wre
676 gpio05: om5610-stereo
677 gpio06: rds6588-davn
678 gpio07: Pin 7 n.c.
679 gpio08: nIOW
680 gpio09+10: nIOR, nSEL ?? (bt878)
681 gpio09: nIOR (bt848)
682 gpio10: nSEL (bt848)
683 Sound Routing:
684 gpio16: u2-A0 (1st 4052bt)
685 gpio17: u2-A1
686 gpio18: u2-nEN
687 gpio19: u4-A0 (2nd 4052)
688 gpio20: u4-A1
689 u4-nEN - GND
690 Btspy:
691 00000 : Cdrom (internal audio input)
692 10000 : ext. Video audio input
693 20000 : TV Mono
694 a0000 : TV Mono/2
695 1a0000 : TV Stereo
696 30000 : Radio
697 40000 : Mute
698 */
699
700},{
701 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
702 .name = "Imagenation PXC200",
703 .video_inputs = 5,
704 .audio_inputs = 1,
705 .tuner = -1,
706 .svhs = 1, /* was: 4 */
707 .gpiomask = 0,
708 .muxsel = { 2, 3, 1, 0, 0},
709 .audiomux = { 0 },
710 .needs_tvaudio = 1,
711 .tuner_type = -1,
712 .muxsel_hook = PXC200_muxsel,
713
714},{
715 .name = "Lifeview FlyVideo 98 LR50",
716 .video_inputs = 4,
717 .audio_inputs = 1,
718 .tuner = 0,
719 .svhs = 2,
720 .gpiomask = 0x1800, //0x8dfe00
721 .muxsel = { 2, 3, 1, 1},
722 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
723 .pll = PLL_28,
724 .tuner_type = -1,
725},{
726 .name = "Formac iProTV, Formac ProTV I (bt848)",
727 .video_inputs = 4,
728 .audio_inputs = 1,
729 .tuner = 0,
730 .svhs = 3,
731 .gpiomask = 1,
732 .muxsel = { 2, 3, 1, 1},
733 .audiomux = { 1, 0, 0, 0, 0 },
734 .pll = PLL_28,
735 .tuner_type = TUNER_PHILIPS_PAL,
736},{
737
738/* ---- card 0x20 ---------------------------------- */
739 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
740 .video_inputs = 4,
741 .audio_inputs = 0,
742 .tuner = -1,
743 .svhs = 2,
744 .gpiomask = 0,
745 .muxsel = { 2, 3, 1, 1},
746 .audiomux = { 0 },
747 .needs_tvaudio = 0,
748 .tuner_type = 4,
749},{
750 .name = "Terratec TerraTValue Version Bt878",
751 .video_inputs = 3,
752 .audio_inputs = 1,
753 .tuner = 0,
754 .svhs = 2,
755 .gpiomask = 0xffff00,
756 .muxsel = { 2, 3, 1, 1},
757 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
758 .needs_tvaudio = 1,
759 .pll = PLL_28,
760 .tuner_type = TUNER_PHILIPS_PAL,
761},{
762 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
763 .video_inputs = 4,
764 .audio_inputs = 1,
765 .tuner = 0,
766 .svhs = 2,
767 .muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
768#if 0
769 .gpiomask = 0xc33000,
770 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
771#else
772 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
773 .gpiomask = 0xb33000,
774 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
775#endif
776 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
777 gpio23 -- hef4052:nEnable (0x800000)
778 gpio12 -- hef4052:A1
779 gpio13 -- hef4052:A0
780 0x0000: external audio
781 0x1000: FM
782 0x2000: TV
783 0x3000: n.c.
784 Note: There exists another variant "Winfast 2000" with tv stereo !?
785 Note: eeprom only contains FF and pci subsystem id 107d:6606
786 */
787 .needs_tvaudio = 0,
788 .pll = PLL_28,
789 .has_radio = 1,
790 .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk
791 .audio_hook = winfast2000_audio,
792 .has_remote = 1,
793},{
794 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
795 .video_inputs = 4,
796 .audio_inputs = 3,
797 .tuner = 0,
798 .svhs = 2,
799 .gpiomask = 0x1800,
800 .muxsel = { 2, 3, 1, 1},
801 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
802 .pll = PLL_28,
803 .tuner_type = -1,
804},{
805
806/* ---- card 0x24 ---------------------------------- */
807 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
808 .video_inputs = 4,
809 .audio_inputs = 3,
810 .tuner = 0,
811 .svhs = 2,
812 .gpiomask = 0x1800,
813 .muxsel = { 2, 3, 1, 1},
814 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
815 .pll = PLL_28,
816 .tuner_type = -1,
817 .has_radio = 1,
818},{
819 .name = "Prolink PixelView PlayTV pro",
820 .video_inputs = 3,
821 .audio_inputs = 1,
822 .tuner = 0,
823 .svhs = 2,
824 .gpiomask = 0xff,
825 .muxsel = { 2, 3, 1, 1 },
826 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
827 .no_msp34xx = 1,
828 .pll = PLL_28,
829 .tuner_type = -1,
830},{
831 .name = "Askey CPH06X TView99",
832 .video_inputs = 4,
833 .audio_inputs = 1,
834 .tuner = 0,
835 .svhs = 2,
836 .gpiomask = 0x551e00,
837 .muxsel = { 2, 3, 1, 0},
838 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
839 .needs_tvaudio = 1,
840 .pll = PLL_28,
841 .tuner_type = 1,
842 .has_remote = 1,
843},{
844 .name = "Pinnacle PCTV Studio/Rave",
845 .video_inputs = 3,
846 .audio_inputs = 1,
847 .tuner = 0,
848 .svhs = 2,
849 .gpiomask = 0x03000F,
850 .muxsel = { 2, 3, 1, 1},
851 .audiomux = { 2, 0xd0001, 0, 0, 1},
852 .needs_tvaudio = 0,
853 .pll = PLL_28,
854 .tuner_type = -1,
855},{
856
857/* ---- card 0x28 ---------------------------------- */
858 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
859 .video_inputs = 3,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 7,
864 .muxsel = { 2, 3, 1, 1},
865 .audiomux = { 4, 0, 2, 3, 1},
866 .no_msp34xx = 1,
867 .needs_tvaudio = 1,
868 .tuner_type = TUNER_PHILIPS_NTSC,
869 .pll = PLL_28,
870 .has_radio = 1,
871},{
872 .name = "AVerMedia TVPhone 98",
873 .video_inputs = 3,
874 .audio_inputs = 4,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 15,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 13, 4, 11, 7, 0, 0},
880 .needs_tvaudio = 1,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .has_radio = 1,
884 .audio_hook = avermedia_tvphone_audio,
885},{
886 .name = "ProVideo PV951", /* pic16c54 */
887 .video_inputs = 3,
888 .audio_inputs = 1,
889 .tuner = 0,
890 .svhs = 2,
891 .gpiomask = 0,
892 .muxsel = { 2, 3, 1, 1},
893 .audiomux = { 0, 0, 0, 0, 0},
894 .needs_tvaudio = 1,
895 .no_msp34xx = 1,
896 .pll = PLL_28,
897 .tuner_type = 1,
898},{
899 .name = "Little OnAir TV",
900 .video_inputs = 3,
901 .audio_inputs = 1,
902 .tuner = 0,
903 .svhs = 2,
904 .gpiomask = 0xe00b,
905 .muxsel = {2, 3, 1, 1},
906 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
907 .no_msp34xx = 1,
908 .tuner_type = -1,
909},{
910
911/* ---- card 0x2c ---------------------------------- */
912 .name = "Sigma TVII-FM",
913 .video_inputs = 2,
914 .audio_inputs = 1,
915 .tuner = 0,
916 .svhs = -1,
917 .gpiomask = 3,
918 .muxsel = {2, 3, 1, 1},
919 .audiomux = {1, 1, 0, 2, 3},
920 .no_msp34xx = 1,
921 .pll = PLL_NONE,
922 .tuner_type = -1,
923},{
924 .name = "MATRIX-Vision MV-Delta 2",
925 .video_inputs = 5,
926 .audio_inputs = 1,
927 .tuner = -1,
928 .svhs = 3,
929 .gpiomask = 0,
930 .muxsel = { 2, 3, 1, 0, 0},
931 .audiomux = {0 },
932 .no_msp34xx = 1,
933 .pll = PLL_28,
934 .tuner_type = -1,
935},{
936 .name = "Zoltrix Genie TV/FM",
937 .video_inputs = 3,
938 .audio_inputs = 1,
939 .tuner = 0,
940 .svhs = 2,
941 .gpiomask = 0xbcf03f,
942 .muxsel = { 2, 3, 1, 1},
943 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
944 .no_msp34xx = 1,
945 .pll = PLL_28,
946 .tuner_type = 21,
947},{
948 .name = "Terratec TV/Radio+",
949 .video_inputs = 3,
950 .audio_inputs = 1,
951 .tuner = 0,
952 .svhs = 2,
953 .gpiomask = 0x70000,
954 .muxsel = { 2, 3, 1, 1},
955 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
956 .needs_tvaudio = 1,
957 .no_msp34xx = 1,
958 .pll = PLL_35,
959 .tuner_type = 1,
960 .has_radio = 1,
961},{
962
963/* ---- card 0x30 ---------------------------------- */
964 .name = "Askey CPH03x/ Dynalink Magic TView",
965 .video_inputs = 3,
966 .audio_inputs = 1,
967 .tuner = 0,
968 .svhs = 2,
969 .gpiomask = 15,
970 .muxsel = { 2, 3, 1, 1},
971 .audiomux = {2,0,0,0,1},
972 .needs_tvaudio = 1,
973 .pll = PLL_28,
974 .tuner_type = -1,
975},{
976 .name = "IODATA GV-BCTV3/PCI",
977 .video_inputs = 3,
978 .audio_inputs = 1,
979 .tuner = 0,
980 .svhs = 2,
981 .gpiomask = 0x010f00,
982 .muxsel = {2, 3, 0, 0},
983 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
984 .no_msp34xx = 1,
985 .pll = PLL_28,
986 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
987 .audio_hook = gvbctv3pci_audio,
988},{
989 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
990 .video_inputs = 5,
991 .audio_inputs = 1,
992 .tuner = 0,
993 .svhs = 3,
994 .gpiomask = 0xAA0000,
995 .muxsel = { 2,3,1,1,-1 },
996 .digital_mode = DIGITAL_MODE_CAMERA,
997 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
998 .no_msp34xx = 1,
999 .pll = PLL_28,
1000 .tuner_type = TUNER_PHILIPS_PAL_I,
1001 .has_remote = 1,
1002 /* GPIO wiring: (different from Rev.4C !)
1003 GPIO17: U4.A0 (first hef4052bt)
1004 GPIO19: U4.A1
1005 GPIO20: U5.A1 (second hef4052bt)
1006 GPIO21: U4.nEN
1007 GPIO22: BT832 Reset Line
1008 GPIO23: A5,A0, U5,nEN
1009 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1010 */
1011},{
1012 .name = "Eagle Wireless Capricorn2 (bt878A)",
1013 .video_inputs = 4,
1014 .audio_inputs = 1,
1015 .tuner = 0,
1016 .svhs = 2,
1017 .gpiomask = 7,
1018 .muxsel = { 2, 0, 1, 1},
1019 .audiomux = { 0, 1, 2, 3, 4},
1020 .pll = PLL_28,
1021 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1022},{
1023
1024/* ---- card 0x34 ---------------------------------- */
1025 /* David Härdeman <david@2gen.com> */
1026 .name = "Pinnacle PCTV Studio Pro",
1027 .video_inputs = 4,
1028 .audio_inputs = 1,
1029 .tuner = 0,
1030 .svhs = 3,
1031 .gpiomask = 0x03000F,
1032 .muxsel = { 2, 3, 1, 1},
1033 .audiomux = { 1, 0xd0001, 0, 0, 10},
1034 /* sound path (5 sources):
1035 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1036 0= ext. Audio IN
1037 1= from MUX2
1038 2= Mono TV sound from Tuner
1039 3= not connected
1040 MUX2 (mask 0x30000):
1041 0,2,3= from MSP34xx
1042 1= FM stereo Radio from Tuner */
1043 .needs_tvaudio = 0,
1044 .pll = PLL_28,
1045 .tuner_type = -1,
1046},{
1047 /* Claas Langbehn <claas@bigfoot.com>,
1048 Sven Grothklags <sven@upb.de> */
1049 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1050 .video_inputs = 4,
1051 .audio_inputs = 3,
1052 .tuner = 0,
1053 .svhs = 2,
1054 .gpiomask = 0x1c,
1055 .muxsel = { 2, 3, 1, 1},
1056 .audiomux = { 0, 0, 0x10, 8, 4 },
1057 .needs_tvaudio = 1,
1058 .pll = PLL_28,
1059 .tuner_type = TUNER_PHILIPS_PAL,
1060 .has_radio = 1,
1061},{
1062 /* Tim Röstermundt <rosterm@uni-muenster.de>
1063 in de.comp.os.unix.linux.hardware:
1064 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1065 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1066 options tuner type=5 */
1067 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 2,
1072 .gpiomask = 0x18e0,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1075 /* For cards with tda9820/tda9821:
1076 0x0000: Tuner normal stereo
1077 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1078 0x0880: Tuner A2 stereo */
1079 .pll = PLL_28,
1080 .tuner_type = -1,
1081},{
1082 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1083 old Easy TV BT848 version (model CPH031) */
1084 .name = "Askey CPH031/ BESTBUY Easy TV",
1085 .video_inputs = 4,
1086 .audio_inputs = 1,
1087 .tuner = 0,
1088 .svhs = 2,
1089 .gpiomask = 0xF,
1090 .muxsel = { 2, 3, 1, 0},
1091 .audiomux = { 2, 0, 0, 0, 10},
1092 .needs_tvaudio = 0,
1093 .pll = PLL_28,
1094 .tuner_type = TUNER_TEMIC_PAL,
1095},{
1096
1097/* ---- card 0x38 ---------------------------------- */
1098 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1099 .name = "Lifeview FlyVideo 98FM LR50",
1100 .video_inputs = 4,
1101 .audio_inputs = 3,
1102 .tuner = 0,
1103 .svhs = 2,
1104 .gpiomask = 0x1800,
1105 .muxsel = { 2, 3, 1, 1},
1106 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1107 .pll = PLL_28,
1108 .tuner_type = 5,
1109},{
1110 /* This is the ultimate cheapo capture card
1111 * just a BT848A on a small PCB!
1112 * Steve Hosgood <steve@equiinet.com> */
1113 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1114 .video_inputs = 2,
1115 .audio_inputs = 0,
1116 .tuner = -1,
1117 .svhs = 1,
1118 .gpiomask = 0,
1119 .muxsel = { 3, 1 },
1120 .audiomux = { 0 },
1121 .needs_tvaudio = 0,
1122 .no_msp34xx = 1,
1123 .pll = PLL_35,
1124 .tuner_type = -1,
1125},{
1126 /* Daniel Herrington <daniel.herrington@home.com> */
1127 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1128 .video_inputs = 3,
1129 .audio_inputs = 1,
1130 .tuner = 0,
1131 .svhs = 2,
1132 .gpiomask = 0xe00,
1133 .muxsel = { 2, 3, 1, 1},
1134 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1135 .needs_tvaudio = 1,
1136 .pll = PLL_28,
1137 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1138},{
1139 /* Matti Mottus <mottus@physic.ut.ee> */
1140 .name = "Askey CPH03x TV Capturer",
1141 .video_inputs = 4,
1142 .audio_inputs = 1,
1143 .tuner = 0,
1144 .svhs = 2,
1145 .gpiomask = 0x03000F,
1146 .muxsel = { 2, 3, 1, 0},
1147 .audiomux = { 2,0,0,0,1 },
1148 .pll = PLL_28,
1149 .tuner_type = 0,
1150},{
1151
1152/* ---- card 0x3c ---------------------------------- */
1153 /* Philip Blundell <philb@gnu.org> */
1154 .name = "Modular Technology MM100PCTV",
1155 .video_inputs = 2,
1156 .audio_inputs = 2,
1157 .tuner = 0,
1158 .svhs = -1,
1159 .gpiomask = 11,
1160 .muxsel = { 2, 3, 1, 1},
1161 .audiomux = { 2, 0, 0, 1, 8},
1162 .pll = PLL_35,
1163 .tuner_type = TUNER_TEMIC_PAL,
1164
1165},{
1166 /* Adrian Cox <adrian@humboldt.co.uk */
1167 .name = "AG Electronics GMV1",
1168 .video_inputs = 2,
1169 .audio_inputs = 0,
1170 .tuner = -1,
1171 .svhs = 1,
1172 .gpiomask = 0xF,
1173 .muxsel = { 2, 2},
1174 .audiomux = { },
1175 .no_msp34xx = 1,
1176 .needs_tvaudio = 0,
1177 .pll = PLL_28,
1178 .tuner_type = -1,
1179},{
1180 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1181 new Easy TV BT878 version (model CPH061)
1182 special thanks to Informatica Mieres for providing the card */
1183 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1184 .video_inputs = 3,
1185 .audio_inputs = 2,
1186 .tuner = 0,
1187 .svhs = 2,
1188 .gpiomask = 0xFF,
1189 .muxsel = { 2, 3, 1, 0},
1190 .audiomux = { 1, 0, 4, 4, 9},
1191 .needs_tvaudio = 0,
1192 .pll = PLL_28,
1193 .tuner_type = TUNER_PHILIPS_PAL,
1194},{
1195 /* Lukas Gebauer <geby@volny.cz> */
1196 .name = "ATI TV-Wonder",
1197 .video_inputs = 3,
1198 .audio_inputs = 1,
1199 .tuner = 0,
1200 .svhs = 2,
1201 .gpiomask = 0xf03f,
1202 .muxsel = { 2, 3, 1, 0 },
1203 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1204 .pll = PLL_28,
1205 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1206},{
1207
1208/* ---- card 0x40 ---------------------------------- */
1209 /* Lukas Gebauer <geby@volny.cz> */
1210 .name = "ATI TV-Wonder VE",
1211 .video_inputs = 2,
1212 .audio_inputs = 1,
1213 .tuner = 0,
1214 .svhs = -1,
1215 .gpiomask = 1,
1216 .muxsel = { 2, 3, 0, 1},
1217 .audiomux = { 0, 0, 1, 0, 0},
1218 .no_msp34xx = 1,
1219 .pll = PLL_28,
1220 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1221},{
1222 /* DeeJay <deejay@westel900.net (2000S) */
1223 .name = "Lifeview FlyVideo 2000S LR90",
1224 .video_inputs = 3,
1225 .audio_inputs = 3,
1226 .tuner = 0,
1227 .svhs = 2,
1228 .gpiomask = 0x18e0,
1229 .muxsel = { 2, 3, 0, 1},
1230 /* Radio changed from 1e80 to 0x800 to make
1231 FlyVideo2000S in .hu happy (gm)*/
1232 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1233 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1234 .audio_hook = fv2000s_audio,
1235 .no_msp34xx = 1,
1236 .no_tda9875 = 1,
1237 .needs_tvaudio = 1,
1238 .pll = PLL_28,
1239 .tuner_type = 5,
1240},{
1241 .name = "Terratec TValueRadio",
1242 .video_inputs = 3,
1243 .audio_inputs = 1,
1244 .tuner = 0,
1245 .svhs = 2,
1246 .gpiomask = 0xffff00,
1247 .muxsel = { 2, 3, 1, 1},
1248 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1249 .needs_tvaudio = 1,
1250 .pll = PLL_28,
1251 .tuner_type = TUNER_PHILIPS_PAL,
1252 .has_radio = 1,
1253},{
1254 /* TANAKA Kei <peg00625@nifty.com> */
1255 .name = "IODATA GV-BCTV4/PCI",
1256 .video_inputs = 3,
1257 .audio_inputs = 1,
1258 .tuner = 0,
1259 .svhs = 2,
1260 .gpiomask = 0x010f00,
1261 .muxsel = {2, 3, 0, 0},
1262 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1263 .no_msp34xx = 1,
1264 .pll = PLL_28,
1265 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1266 .audio_hook = gvbctv3pci_audio,
1267},{
1268
1269/* ---- card 0x44 ---------------------------------- */
1270 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1271 // try "insmod msp3400 simple=0" if you have
1272 // sound problems with this card.
1273 .video_inputs = 4,
1274 .audio_inputs = 1,
1275 .tuner = 0,
1276 .svhs = -1,
1277 .gpiomask = 0x4f8a00,
1278 // 0x100000: 1=MSP enabled (0=disable again)
1279 // 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC)
1280 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1281 // tvtuner, radio, external,internal, mute, stereo
1282 /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
1283 .muxsel = { 2, 3 ,0 ,1},
1284 .tuner_type = TUNER_MT2032,
1285 .pll = PLL_28,
1286 .has_radio = 1,
1287},{
1288 /* Philip Blundell <pb@nexus.co.uk> */
1289 .name = "Active Imaging AIMMS",
1290 .video_inputs = 1,
1291 .audio_inputs = 0,
1292 .tuner = -1,
1293 .tuner_type = -1,
1294 .pll = PLL_28,
1295 .muxsel = { 2 },
1296 .gpiomask = 0
1297},{
1298 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1299 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1300 .video_inputs = 3,
1301 .audio_inputs = 4,
1302 .tuner = 0,
1303 .svhs = 2,
1304 .gpiomask = 15,
1305 .muxsel = { 2, 3, 1, 1},
1306 .audiomux = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
1307 .needs_tvaudio = 1,
1308 .pll = PLL_28,
1309 .tuner_type = 25,
1310 .has_remote = 1,
1311 /* GPIO wiring:
1312 GPIO0: U4.A0 (hef4052bt)
1313 GPIO1: U4.A1
1314 GPIO2: U4.A1 (second hef4052bt)
1315 GPIO3: U4.nEN, U5.A0, A5.nEN
1316 GPIO8-15: vrd866b ?
1317 */
1318},{
1319 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
1320 .video_inputs = 4,
1321 .audio_inputs = 0,
1322 .tuner = -1,
1323 .svhs = 2,
1324 .muxsel = { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
1325 .pll = PLL_28,
1326 .no_msp34xx = 1,
1327},{
1328
1329/* ---- card 0x48 ---------------------------------- */
1330 /* Dariusz Kowalewski <darekk@automex.pl> */
1331 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
1332 .video_inputs = 4,
1333 .audio_inputs = 1,
1334 .tuner = 0,
1335 .svhs = 2,
1336 .gpiomask = 0x3f,
1337 .muxsel = { 2, 3, 1, 1 },
1338 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
1339 .needs_tvaudio = 1,
1340 .no_msp34xx = 1,
1341 .no_tda9875 = 1,
1342 .pll = PLL_28,
1343 .tuner_type = 5,
1344 .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo
1345 .has_radio = 1, // Note: not all cards have radio
1346 .has_remote = 1,
1347 /* GPIO wiring:
1348 GPIO0: A0 hef4052
1349 GPIO1: A1 hef4052
1350 GPIO3: nEN hef4052
1351 GPIO8-15: vrd866b
1352 GPIO20,22,23: R30,R29,R28
1353 */
1354},{
1355 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
1356 /* you must jumper JP5 for the card to work */
1357 .name = "Sensoray 311",
1358 .video_inputs = 5,
1359 .audio_inputs = 0,
1360 .tuner = -1,
1361 .svhs = 4,
1362 .gpiomask = 0,
1363 .muxsel = { 2, 3, 1, 0, 0},
1364 .audiomux = { 0 },
1365 .needs_tvaudio = 0,
1366 .tuner_type = -1,
1367},{
1368 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
1369 .name = "RemoteVision MX (RV605)",
1370 .video_inputs = 16,
1371 .audio_inputs = 0,
1372 .tuner = -1,
1373 .svhs = -1,
1374 .gpiomask = 0x00,
1375 .gpiomask2 = 0x07ff,
1376 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
1377 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
1378 .no_msp34xx = 1,
1379 .no_tda9875 = 1,
1380 .tuner_type = -1,
1381 .muxsel_hook = rv605_muxsel,
1382},{
1383 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
1384 .video_inputs = 3,
1385 .audio_inputs = 2,
1386 .tuner = 0,
1387 .svhs = 2,
1388 .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
1389 .muxsel = { 2, 1, 1, },
1390 .audiomux = { 0, 1, 2, 2, 4 },
1391 .needs_tvaudio = 0,
1392 .tuner_type = TUNER_PHILIPS_PAL,
1393 .pll = PLL_28,
1394 .has_radio = 1,
1395},{
1396
1397/* ---- card 0x4c ---------------------------------- */
1398 /* Masaki Suzuki <masaki@btree.org> */
1399 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
1400 .video_inputs = 3,
1401 .audio_inputs = 1,
1402 .tuner = 0,
1403 .svhs = 2,
1404 .gpiomask = 0x140007,
1405 .muxsel = { 2, 3, 1, 1 },
1406 .audiomux = { 0, 1, 2, 3, 4, 0 },
1407 .tuner_type = TUNER_PHILIPS_NTSC,
1408 .audio_hook = windvr_audio,
1409},{
1410 .name = "GrandTec Multi Capture Card (Bt878)",
1411 .video_inputs = 4,
1412 .audio_inputs = 0,
1413 .tuner = -1,
1414 .svhs = -1,
1415 .gpiomask = 0,
1416 .muxsel = { 2, 3, 1, 0 },
1417 .audiomux = { 0 },
1418 .needs_tvaudio = 0,
1419 .no_msp34xx = 1,
1420 .pll = PLL_28,
1421 .tuner_type = -1,
1422},{
1423 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
1424 .video_inputs = 4,
1425 .audio_inputs = 3,
1426 .tuner = 0,
1427 .svhs = 2,
1428 .gpiomask = 7,
1429 .muxsel = { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector
1430 .audiomux = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio!
1431 // This card lacks external Audio In, so we mute it on Ext. & Int.
1432 // The PCB can take a sbx1637/sbx1673, wiring unknown.
1433 // This card lacks PCI subsystem ID, sigh.
1434 // audiomux=1: lower volume, 2+3: mute
1435 // btwincap uses 0x80000/0x80003
1436 .needs_tvaudio = 0,
1437 .no_msp34xx = 1,
1438 .pll = PLL_28,
1439 .tuner_type = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
1440 // radio signal strength indicators work fine.
1441 .has_radio = 1,
1442 /* GPIO Info:
1443 GPIO0,1: HEF4052 A0,A1
1444 GPIO2: HEF4052 nENABLE
1445 GPIO3-7: n.c.
1446 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
1447 GPIO14,15: ??
1448 GPIO16-21: n.c.
1449 GPIO22,23: ??
1450 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
1451},{
1452 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
1453 .name = "DSP Design TCVIDEO",
1454 .video_inputs = 4,
1455 .svhs = -1,
1456 .muxsel = { 2, 3, 1, 0},
1457 .pll = PLL_28,
1458 .tuner_type = -1,
1459},{
1460
1461 /* ---- card 0x50 ---------------------------------- */
1462 .name = "Hauppauge WinTV PVR",
1463 .video_inputs = 4,
1464 .audio_inputs = 1,
1465 .tuner = 0,
1466 .svhs = 2,
1467 .muxsel = { 2, 0, 1, 1},
1468 .needs_tvaudio = 1,
1469 .pll = PLL_28,
1470 .tuner_type = -1,
1471
1472 .gpiomask = 7,
1473 .audiomux = {7},
1474},{
1475 .name = "IODATA GV-BCTV5/PCI",
1476 .video_inputs = 3,
1477 .audio_inputs = 1,
1478 .tuner = 0,
1479 .svhs = 2,
1480 .gpiomask = 0x0f0f80,
1481 .muxsel = {2, 3, 1, 0},
1482 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
1483 .no_msp34xx = 1,
1484 .pll = PLL_28,
1485 .tuner_type = TUNER_PHILIPS_NTSC_M,
1486 .audio_hook = gvbctv5pci_audio,
1487 .has_radio = 1,
1488},{
1489 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
1490 .video_inputs = 4, /* id-inputs-clock */
1491 .audio_inputs = 0,
1492 .tuner = -1,
1493 .svhs = 3,
1494 .muxsel = { 3, 2, 0, 1 },
1495 .pll = PLL_28,
1496 .tuner_type = -1,
1497 .no_msp34xx = 1,
1498 .no_tda9875 = 1,
1499 .no_tda7432 = 1,
1500},{
1501 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
1502 .video_inputs = 3,
1503 .audio_inputs = 0,
1504 .tuner = -1,
1505 .svhs = 2,
1506 .muxsel = { 2, 3, 1 },
1507 .pll = PLL_28,
1508 .tuner_type = -1,
1509 .no_msp34xx = 1,
1510 .no_tda9875 = 1,
1511 .no_tda7432 = 1,
1512},{
1513
1514 /* ---- card 0x54 ---------------------------------- */
1515 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1516 .video_inputs = 2,
1517 .audio_inputs = 0,
1518 .tuner = -1,
1519 .svhs = 1,
1520 .muxsel = { 3, 1 },
1521 .pll = PLL_28,
1522 .tuner_type = -1,
1523 .no_msp34xx = 1,
1524 .no_tda9875 = 1,
1525 .no_tda7432 = 1,
1526},{
1527 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1528 .video_inputs = 1,
1529 .audio_inputs = 0,
1530 .tuner = -1,
1531 .svhs = -1,
1532 .muxsel = { 0 },
1533 .pll = PLL_28,
1534 .tuner_type = -1,
1535 .no_msp34xx = 1,
1536 .no_tda9875 = 1,
1537 .no_tda7432 = 1,
1538},{
1539 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1540 .video_inputs = 2,
1541 .audio_inputs = 0,
1542 .tuner = -1,
1543 .svhs = 1,
1544 .muxsel = { 0, 1 },
1545 .pll = PLL_28,
1546 .tuner_type = -1,
1547 .no_msp34xx = 1,
1548 .no_tda9875 = 1,
1549 .no_tda7432 = 1,
1550},{
1551 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1552 .video_inputs = 1,
1553 .audio_inputs = 1,
1554 .tuner = -1,
1555 .svhs = -1,
1556 .muxsel = { 0 },
1557 .pll = PLL_28,
1558 .tuner_type = -1,
1559 .no_msp34xx = 1,
1560 .no_tda9875 = 1,
1561 .no_tda7432 = 1,
1562},{
1563
1564 /* ---- card 0x58 ---------------------------------- */
1565 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1566 .video_inputs = 2,
1567 .audio_inputs = 1,
1568 .tuner = -1,
1569 .svhs = 1,
1570 .muxsel = { 0, 1 },
1571 .pll = PLL_28,
1572 .tuner_type = -1,
1573 .no_msp34xx = 1,
1574 .no_tda9875 = 1,
1575 .no_tda7432 = 1,
1576},{
1577 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1578 .video_inputs = 2,
1579 .audio_inputs = 1,
1580 .tuner = -1,
1581 .svhs = 1,
1582 .muxsel = { 2, 3 },
1583 .pll = PLL_28,
1584 .tuner_type = -1,
1585 .no_msp34xx = 1,
1586 .no_tda9875 = 1,
1587 .no_tda7432 = 1,
1588},{
1589 .name = "Osprey 500", /* 500 */
1590 .video_inputs = 2,
1591 .audio_inputs = 1,
1592 .tuner = -1,
1593 .svhs = 1,
1594 .muxsel = { 2, 3 },
1595 .pll = PLL_28,
1596 .tuner_type = -1,
1597 .no_msp34xx = 1,
1598 .no_tda9875 = 1,
1599 .no_tda7432 = 1,
1600},{
1601 .name = "Osprey 540", /* 540 */
1602 .video_inputs = 4,
1603 .audio_inputs = 1,
1604 .tuner = -1,
1605#if 0 /* TODO ... */
1606 .svhs = OSPREY540_SVID_ANALOG,
1607 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1608 [OSPREY540_SVID_ANALOG] = 3, },
1609#endif
1610 .pll = PLL_28,
1611 .tuner_type = -1,
1612 .no_msp34xx = 1,
1613 .no_tda9875 = 1,
1614 .no_tda7432 = 1,
1615#if 0 /* TODO ... */
1616 .muxsel_hook = osprey_540_muxsel,
1617 .picture_hook = osprey_540_set_picture,
1618#endif
1619},{
1620
1621 /* ---- card 0x5C ---------------------------------- */
1622 .name = "Osprey 2000", /* 2000 */
1623 .video_inputs = 2,
1624 .audio_inputs = 1,
1625 .tuner = -1,
1626 .svhs = 1,
1627 .muxsel = { 2, 3 },
1628 .pll = PLL_28,
1629 .tuner_type = -1,
1630 .no_msp34xx = 1,
1631 .no_tda9875 = 1,
1632 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1633},{
1634 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1635 .name = "IDS Eagle",
1636 .video_inputs = 4,
1637 .audio_inputs = 0,
1638 .tuner = -1,
1639 .tuner_type = -1,
1640 .svhs = -1,
1641 .gpiomask = 0,
1642 .muxsel = { 0, 1, 2, 3 },
1643 .muxsel_hook = eagle_muxsel,
1644 .no_msp34xx = 1,
1645 .no_tda9875 = 1,
1646 .pll = PLL_28,
1647},{
1648 .name = "Pinnacle PCTV Sat",
1649 .video_inputs = 2,
1650 .audio_inputs = 0,
1651 .svhs = 1,
1652 .tuner = -1,
1653 .tuner_type = -1,
1654 .no_msp34xx = 1,
1655 .no_tda9875 = 1,
1656 .no_tda7432 = 1,
1657 .gpiomask = 0x01,
1658 .audiomux = { 0, 0, 0, 0, 1 },
1659 .muxsel = { 3, 0, 1, 2},
1660 .needs_tvaudio = 0,
1661 .pll = PLL_28,
1662 .no_gpioirq = 1,
1663 .has_dvb = 1,
1664},{
1665 .name = "Formac ProTV II (bt878)",
1666 .video_inputs = 4,
1667 .audio_inputs = 1,
1668 .tuner = 0,
1669 .svhs = 3,
1670 .gpiomask = 2,
1671 // TV, Comp1, Composite over SVID con, SVID
1672 .muxsel = { 2, 3, 1, 1},
1673 .audiomux = { 2, 2, 0, 0, 0 },
1674 .pll = PLL_28,
1675 .has_radio = 1,
1676 .tuner_type = TUNER_PHILIPS_PAL,
1677 /* sound routing:
1678 GPIO=0x00,0x01,0x03: mute (?)
1679 0x02: both TV and radio (tuner: FM1216/I)
1680 The card has onboard audio connectors labeled "cdrom" and "board",
1681 not soldered here, though unknown wiring.
1682 Card lacks: external audio in, pci subsystem id.
1683 */
1684},{
1685
1686 /* ---- card 0x60 ---------------------------------- */
1687 .name = "MachTV",
1688 .video_inputs = 3,
1689 .audio_inputs = 1,
1690 .tuner = 0,
1691 .svhs = -1,
1692 .gpiomask = 7,
1693 .muxsel = { 2, 3, 1, 1},
1694 .audiomux = { 0, 1, 2, 3, 4},
1695 .needs_tvaudio = 1,
1696 .tuner_type = 5,
1697 .pll = 1,
1698},{
1699 .name = "Euresys Picolo",
1700 .video_inputs = 3,
1701 .audio_inputs = 0,
1702 .tuner = -1,
1703 .svhs = 2,
1704 .gpiomask = 0,
1705 .no_msp34xx = 1,
1706 .no_tda9875 = 1,
1707 .no_tda7432 = 1,
1708 .muxsel = { 2, 0, 1},
1709 .pll = PLL_28,
1710},{
1711 /* Luc Van Hoeylandt <luc@e-magic.be> */
1712 .name = "ProVideo PV150", /* 0x4f */
1713 .video_inputs = 2,
1714 .audio_inputs = 0,
1715 .tuner = -1,
1716 .svhs = -1,
1717 .gpiomask = 0,
1718 .muxsel = { 2, 3 },
1719 .audiomux = { 0 },
1720 .needs_tvaudio = 0,
1721 .no_msp34xx = 1,
1722 .pll = PLL_28,
1723 .tuner_type = -1,
1724},{
1725 /* Hiroshi Takekawa <sian@big.or.jp> */
1726 /* This card lacks subsystem ID */
1727 .name = "AD-TVK503", /* 0x63 */
1728 .video_inputs = 4,
1729 .audio_inputs = 1,
1730 .tuner = 0,
1731 .svhs = 2,
1732 .gpiomask = 0x001e8007,
1733 .muxsel = { 2, 3, 1, 0 },
1734 /* Tuner, Radio, external, internal, off, on */
1735 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
1736 .needs_tvaudio = 0,
1737 .no_msp34xx = 1,
1738 .pll = PLL_28,
1739 .tuner_type = 2,
1740 .audio_hook = adtvk503_audio,
1741},{
1742
1743 /* ---- card 0x64 ---------------------------------- */
1744 .name = "Hercules Smart TV Stereo",
1745 .video_inputs = 4,
1746 .audio_inputs = 1,
1747 .tuner = 0,
1748 .svhs = 2,
1749 .gpiomask = 0x00,
1750 .muxsel = { 2, 3, 1, 1 },
1751 .needs_tvaudio = 1,
1752 .no_msp34xx = 1,
1753 .pll = PLL_28,
1754 .tuner_type = 5,
1755 /* Notes:
1756 - card lacks subsystem ID
1757 - stereo variant w/ daughter board with tda9874a @0xb0
1758 - Audio Routing:
1759 always from tda9874 independent of GPIO (?)
1760 external line in: unknown
1761 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
1762 hef4053 (instead 4052) for unknown function
1763 */
1764},{
1765 .name = "Pace TV & Radio Card",
1766 .video_inputs = 4,
1767 .audio_inputs = 1,
1768 .tuner = 0,
1769 .svhs = 2,
1770 .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector
1771 .gpiomask = 0,
1772 .no_tda9875 = 1,
1773 .no_tda7432 = 1,
1774 .tuner_type = 1,
1775 .has_radio = 1,
1776 .pll = PLL_28,
1777 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
1778 only internal line out: (4pin header) RGGL
1779 Radio must be decoded by msp3410d (not routed through)*/
1780 // .digital_mode = DIGITAL_MODE_CAMERA, // todo!
1781},{
1782 /* Chris Willing <chris@vislab.usyd.edu.au> */
1783 .name = "IVC-200",
1784 .video_inputs = 1,
1785 .audio_inputs = 0,
1786 .tuner = -1,
1787 .tuner_type = -1,
1788 .svhs = -1,
1789 .gpiomask = 0xdf,
1790 .muxsel = { 2 },
1791 .pll = PLL_28,
1792},{
1793 .name = "Grand X-Guard / Trust 814PCI",
1794 .video_inputs = 16,
1795 .audio_inputs = 0,
1796 .tuner = -1,
1797 .svhs = -1,
1798 .tuner_type = 4,
1799 .gpiomask2 = 0xff,
1800 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
1801 .muxsel_hook = xguard_muxsel,
1802 .no_msp34xx = 1,
1803 .no_tda9875 = 1,
1804 .no_tda7432 = 1,
1805 .pll = PLL_28,
1806},{
1807
1808 /* ---- card 0x68 ---------------------------------- */
1809 .name = "Nebula Electronics DigiTV",
1810 .video_inputs = 1,
1811 .tuner = -1,
1812 .svhs = -1,
1813 .muxsel = { 2, 3, 1, 0},
1814 .no_msp34xx = 1,
1815 .no_tda9875 = 1,
1816 .no_tda7432 = 1,
1817 .pll = PLL_28,
1818 .tuner_type = -1,
1819 .has_dvb = 1,
1820 .no_gpioirq = 1,
1821},{
1822 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
1823 .name = "ProVideo PV143",
1824 .video_inputs = 4,
1825 .audio_inputs = 0,
1826 .tuner = -1,
1827 .svhs = -1,
1828 .gpiomask = 0,
1829 .muxsel = { 2, 3, 1, 0 },
1830 .audiomux = { 0 },
1831 .needs_tvaudio = 0,
1832 .no_msp34xx = 1,
1833 .pll = PLL_28,
1834 .tuner_type = -1,
1835},{
1836 /* M.Klahr@phytec.de */
1837 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
1838 .video_inputs = 4,
1839 .audio_inputs = 0,
1840 .tuner = -1, /* card has no tuner */
1841 .svhs = 3,
1842 .gpiomask = 0x00,
1843 .muxsel = { 2, 3, 1, 0},
1844 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1845 .needs_tvaudio = 1,
1846 .pll = PLL_28,
1847 .tuner_type = -1,
1848},{
1849 .name = "PHYTEC VD-009-X1 Combi (bt878)",
1850 .video_inputs = 4,
1851 .audio_inputs = 0,
1852 .tuner = -1, /* card has no tuner */
1853 .svhs = 3,
1854 .gpiomask = 0x00,
1855 .muxsel = { 2, 3, 1, 1},
1856 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1857 .needs_tvaudio = 1,
1858 .pll = PLL_28,
1859 .tuner_type = -1,
1860},{
1861
1862 /* ---- card 0x6c ---------------------------------- */
1863 .name = "PHYTEC VD-009 MiniDIN (bt878)",
1864 .video_inputs = 10,
1865 .audio_inputs = 0,
1866 .tuner = -1, /* card has no tuner */
1867 .svhs = 9,
1868 .gpiomask = 0x00,
1869 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1870 via the upper nibble of muxsel. here: used for
1871 xternal video-mux */
1872 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
1873 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1874 .needs_tvaudio = 1,
1875 .pll = PLL_28,
1876 .tuner_type = -1,
1877},{
1878 .name = "PHYTEC VD-009 Combi (bt878)",
1879 .video_inputs = 10,
1880 .audio_inputs = 0,
1881 .tuner = -1, /* card has no tuner */
1882 .svhs = 9,
1883 .gpiomask = 0x00,
1884 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1885 via the upper nibble of muxsel. here: used for
1886 xternal video-mux */
1887 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
1888 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1889 .needs_tvaudio = 1,
1890 .pll = PLL_28,
1891 .tuner_type = -1,
1892},{
1893 .name = "IVC-100",
1894 .video_inputs = 4,
1895 .audio_inputs = 0,
1896 .tuner = -1,
1897 .tuner_type = -1,
1898 .svhs = -1,
1899 .gpiomask = 0xdf,
1900 .muxsel = { 2, 3, 1, 0 },
1901 .pll = PLL_28,
1902},{
1903 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
1904 .name = "IVC-120G",
1905 .video_inputs = 16,
1906 .audio_inputs = 0, /* card has no audio */
1907 .tuner = -1, /* card has no tuner */
1908 .tuner_type = -1,
1909 .svhs = -1, /* card has no svhs */
1910 .needs_tvaudio = 0,
1911 .no_msp34xx = 1,
1912 .no_tda9875 = 1,
1913 .no_tda7432 = 1,
1914 .gpiomask = 0x00,
1915 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1916 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
1917 .muxsel_hook = ivc120_muxsel,
1918 .pll = PLL_28,
1919},{
1920
1921 /* ---- card 0x70 ---------------------------------- */
1922 .name = "pcHDTV HD-2000 TV",
1923 .video_inputs = 4,
1924 .audio_inputs = 1,
1925 .tuner = 0,
1926 .svhs = 2,
1927 .muxsel = { 2, 3, 1, 0},
1928 .tuner_type = TUNER_PHILIPS_ATSC,
1929 .has_dvb = 1,
1930},{
1931 .name = "Twinhan DST + clones",
1932 .no_msp34xx = 1,
1933 .no_tda9875 = 1,
1934 .no_tda7432 = 1,
1935 .tuner_type = TUNER_ABSENT,
1936 .no_video = 1,
1937 .has_dvb = 1,
1938},{
1939 .name = "Winfast VC100",
1940 .video_inputs = 3,
1941 .audio_inputs = 0,
1942 .svhs = 1,
1943 .tuner = -1, // no tuner
1944 .muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector
1945 .no_msp34xx = 1,
1946 .no_tda9875 = 1,
1947 .no_tda7432 = 1,
1948 .tuner_type = TUNER_ABSENT,
1949 .no_video = 1,
1950 .pll = PLL_28,
1951},{
1952 .name = "Teppro TEV-560/InterVision IV-560",
1953 .video_inputs = 3,
1954 .audio_inputs = 1,
1955 .tuner = 0,
1956 .svhs = 2,
1957 .gpiomask = 3,
1958 .muxsel = { 2, 3, 1, 1},
1959 .audiomux = { 1, 1, 1, 1, 0},
1960 .needs_tvaudio = 1,
1961 .tuner_type = TUNER_PHILIPS_PAL,
1962 .pll = PLL_35,
1963},{
1964
1965 /* ---- card 0x74 ---------------------------------- */
1966 .name = "SIMUS GVC1100",
1967 .video_inputs = 4,
1968 .audio_inputs = 0,
1969 .tuner = -1,
1970 .svhs = -1,
1971 .tuner_type = -1,
1972 .pll = PLL_28,
1973 .muxsel = { 2, 2, 2, 2},
1974 .gpiomask = 0x3F,
1975 .muxsel_hook = gvc1100_muxsel,
1976},{
1977 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
1978 .name = "NGS NGSTV+",
1979 .video_inputs = 3,
1980 .tuner = 0,
1981 .svhs = 2,
1982 .gpiomask = 0x008007,
1983 .muxsel = {2, 3, 0, 0},
1984 .audiomux = {0, 0, 0, 0, 0x000003, 0},
1985 .pll = PLL_28,
1986 .tuner_type = TUNER_PHILIPS_PAL,
1987 .has_remote = 1,
1988},{
1989 /* http://linuxmedialabs.com */
1990 .name = "LMLBT4",
1991 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
1992 .audio_inputs = 0,
1993 .tuner = -1,
1994 .svhs = -1,
1995 .muxsel = { 2, 3, 1, 0 },
1996 .no_msp34xx = 1,
1997 .no_tda9875 = 1,
1998 .no_tda7432 = 1,
1999 .needs_tvaudio = 0,
2000},{
2001 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2002 .name = "Tekram M205 PRO",
2003 .video_inputs = 3,
2004 .audio_inputs = 1,
2005 .tuner = 0,
2006 .tuner_type = TUNER_PHILIPS_PAL,
2007 .svhs = 2,
2008 .needs_tvaudio = 0,
2009 .gpiomask = 0x68,
2010 .muxsel = { 2, 3, 1},
2011 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2012 .pll = PLL_28,
2013},{
2014
2015 /* ---- card 0x78 ---------------------------------- */
2016 /* Javier Cendan Ares <jcendan@lycos.es> */
2017 /* bt878 TV + FM without subsystem ID */
2018 .name = "Conceptronic CONTVFMi",
2019 .video_inputs = 3,
2020 .audio_inputs = 1,
2021 .tuner = 0,
2022 .svhs = 2,
2023 .gpiomask = 0x008007,
2024 .muxsel = { 2, 3, 1, 1 },
2025 .audiomux = { 0, 1, 2, 2, 3 },
2026 .needs_tvaudio = 0,
2027 .pll = PLL_28,
2028 .tuner_type = TUNER_PHILIPS_PAL,
2029 .has_remote = 1,
2030 .has_radio = 1,
2031},{
2032 /*Eric DEBIEF <debief@telemsa.com>*/
2033 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2034 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/
2035 /*0x79 in bttv.h*/
2036 .name = "Euresys Picolo Tetra",
2037 .video_inputs = 4,
2038 .audio_inputs = 0,
2039 .tuner = -1,
2040 .svhs = -1,
2041 .gpiomask = 0,
2042 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2043 .no_msp34xx = 1,
2044 .no_tda9875 = 1,
2045 .no_tda7432 = 1,
2046 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2047 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2048 .pll = PLL_28,
2049 .needs_tvaudio = 0,
2050 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2051},{
2052 /* Spirit TV Tuner from http://spiritmodems.com.au */
2053 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2054 .name = "Spirit TV Tuner",
2055 .video_inputs = 3,
2056 .audio_inputs = 1,
2057 .tuner = 0,
2058 .svhs = 2,
2059 .gpiomask = 0x0000000f,
2060 .muxsel = { 2, 1, 1 },
2061 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2062 .tuner_type = TUNER_TEMIC_PAL,
2063 .no_msp34xx = 1,
2064 .no_tda9875 = 1,
2065},{
2066 /* Wolfram Joost <wojo@frokaschwei.de> */
2067 .name = "AVerMedia AVerTV DVB-T 771",
2068 .video_inputs = 2,
2069 .svhs = 1,
2070 .tuner = -1,
2071 .tuner_type = TUNER_ABSENT,
2072 .muxsel = { 3 , 3 },
2073 .no_msp34xx = 1,
2074 .no_tda9875 = 1,
2075 .no_tda7432 = 1,
2076 .pll = PLL_28,
2077 .has_dvb = 1,
2078 .no_gpioirq = 1,
2079 .has_remote = 1,
2080},{
2081 /* ---- card 0x7c ---------------------------------- */
2082 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2083 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */
2084 .name = "AverMedia AverTV DVB-T 761",
2085 .video_inputs = 2,
2086 .tuner = -1,
2087 .svhs = 1,
2088 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2089 .no_msp34xx = 1,
2090 .no_tda9875 = 1,
2091 .no_tda7432 = 1,
2092 .pll = PLL_28,
2093 .tuner_type = -1,
2094 .has_dvb = 1,
2095 .no_gpioirq = 1,
2096 .has_remote = 1,
2097},{
2098 /* andre.schwarz@matrix-vision.de */
2099 .name = "MATRIX Vision Sigma-SQ",
2100 .video_inputs = 16,
2101 .audio_inputs = 0,
2102 .tuner = -1,
2103 .svhs = -1,
2104 .gpiomask = 0x0,
2105 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2106 3, 3, 3, 3, 3, 3, 3, 3 },
2107 .muxsel_hook = sigmaSQ_muxsel,
2108 .audiomux = { 0 },
2109 .no_msp34xx = 1,
2110 .pll = PLL_28,
2111 .tuner_type = -1,
2112},{
2113 /* andre.schwarz@matrix-vision.de */
2114 .name = "MATRIX Vision Sigma-SLC",
2115 .video_inputs = 4,
2116 .audio_inputs = 0,
2117 .tuner = -1,
2118 .svhs = -1,
2119 .gpiomask = 0x0,
2120 .muxsel = { 2, 2, 2, 2 },
2121 .muxsel_hook = sigmaSLC_muxsel,
2122 .audiomux = { 0 },
2123 .no_msp34xx = 1,
2124 .pll = PLL_28,
2125 .tuner_type = -1,
2126},{
2127 /* BTTV_APAC_VIEWCOMP */
2128 /* Attila Kondoros <attila.kondoros@chello.hu> */
2129 /* bt878 TV + FM 0x00000000 subsystem ID */
2130 .name = "APAC Viewcomp 878(AMAX)",
2131 .video_inputs = 2,
2132 .audio_inputs = 1,
2133 .tuner = 0,
2134 .svhs = -1,
2135 .gpiomask = 0xFF,
2136 .muxsel = { 2, 3, 1, 1},
2137 .audiomux = { 2, 0, 0, 0, 10},
2138 .needs_tvaudio = 0,
2139 .pll = PLL_28,
2140 .tuner_type = TUNER_PHILIPS_PAL,
2141 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2142 .has_radio = 1, /* not every card has radio */
2143},{
2144
2145 /* ---- card 0x80 ---------------------------------- */
2146 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2147 .name = "DVICO FusionHDTV DVB-T Lite",
2148 .tuner = -1,
2149 .no_msp34xx = 1,
2150 .no_tda9875 = 1,
2151 .no_tda7432 = 1,
2152 .pll = PLL_28,
2153 .no_video = 1,
2154 .has_dvb = 1,
2155 .tuner_type = -1,
2156},{
2157 /* Steven <photon38@pchome.com.tw> */
2158 .name = "V-Gear MyVCD",
2159 .video_inputs = 3,
2160 .audio_inputs = 1,
2161 .tuner = 0,
2162 .svhs = 2,
2163 .gpiomask = 0x3f,
2164 .muxsel = {2, 3, 1, 0},
2165 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2166 .no_msp34xx = 1,
2167 .pll = PLL_28,
2168 .tuner_type = TUNER_PHILIPS_NTSC_M,
2169 .has_radio = 0,
2170 // .has_remote = 1,
2171},{
2172 /* Rick C <cryptdragoon@gmail.com> */
2173 .name = "Super TV Tuner",
2174 .video_inputs = 4,
2175 .audio_inputs = 1,
2176 .tuner = 0,
2177 .svhs = 2,
2178 .muxsel = { 2, 3, 1, 0},
2179 .tuner_type = TUNER_PHILIPS_NTSC,
2180 .gpiomask = 0x008007,
2181 .audiomux = { 0, 0x000001,0,0, 0},
2182 .needs_tvaudio = 1,
2183 .has_radio = 1,
2184},{
2185 /* Chris Fanning <video4linux@haydon.net> */
2186 .name = "Tibet Systems 'Progress DVR' CS16",
2187 .video_inputs = 16,
2188 .audio_inputs = 0,
2189 .tuner = -1,
2190 .svhs = -1,
2191 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2192 .pll = PLL_28,
2193 .no_msp34xx = 1,
2194 .no_tda9875 = 1,
2195 .no_tda7432 = 1,
2196 .tuner_type = -1,
2197 .muxsel_hook = tibetCS16_muxsel,
2198},
2199{
2200 /* Bill Brack <wbrack@mmm.com.hk> */
2201 /*
2202 * Note that, because of the card's wiring, the "master"
2203 * BT878A chip (i.e. the one which controls the analog switch
2204 * and must use this card type) is the 2nd one detected. The
2205 * other 3 chips should use card type 0x85, whose description
2206 * follows this one. There is a EEPROM on the card (which is
2207 * connected to the I2C of one of those other chips), but is
2208 * not currently handled. There is also a facility for a
2209 * "monitor", which is also not currently implemented.
2210 */
2211 .name = "Kodicom 4400R (master)",
2212 .video_inputs = 16,
2213 .audio_inputs = 0,
2214 .tuner = -1,
2215 .tuner_type = -1,
2216 .svhs = -1,
2217 /* GPIO bits 0-9 used for analog switch:
2218 * 00 - 03: camera selector
2219 * 04 - 06: channel (controller) selector
2220 * 07: data (1->on, 0->off)
2221 * 08: strobe
2222 * 09: reset
2223 * bit 16 is input from sync separator for the channel
2224 */
2225 .gpiomask = 0x0003ff,
2226 .no_gpioirq = 1,
2227 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2228 .pll = PLL_28,
2229 .no_msp34xx = 1,
2230 .no_tda7432 = 1,
2231 .no_tda9875 = 1,
2232 .muxsel_hook = kodicom4400r_muxsel,
2233},
2234{
2235 /* Bill Brack <wbrack@mmm.com.hk> */
2236 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2237 * one which controls the analog switch, and must use the card type)
2238 * is the 2nd one detected. The other 3 chips should use this card
2239 * type
2240 */
2241 .name = "Kodicom 4400R (slave)",
2242 .video_inputs = 16,
2243 .audio_inputs = 0,
2244 .tuner = -1,
2245 .tuner_type = -1,
2246 .svhs = -1,
2247 .gpiomask = 0x010000,
2248 .no_gpioirq = 1,
2249 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2250 .pll = PLL_28,
2251 .no_msp34xx = 1,
2252 .no_tda7432 = 1,
2253 .no_tda9875 = 1,
2254 .muxsel_hook = kodicom4400r_muxsel,
2255}};
2256
2257static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2258
2259/* ----------------------------------------------------------------------- */
2260
2261static unsigned char eeprom_data[256];
2262
2263/*
2264 * identify card
2265 */
2266void __devinit bttv_idcard(struct bttv *btv)
2267{
2268 unsigned int gpiobits;
2269 int i,type;
2270 unsigned short tmp;
2271
2272 /* read PCI subsystem ID */
2273 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_ID, &tmp);
2274 btv->cardid = tmp << 16;
2275 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_VENDOR_ID, &tmp);
2276 btv->cardid |= tmp;
2277
2278 if (0 != btv->cardid && 0xffffffff != btv->cardid) {
2279 /* look for the card */
2280 for (type = -1, i = 0; cards[i].id != 0; i++)
2281 if (cards[i].id == btv->cardid)
2282 type = i;
2283
2284 if (type != -1) {
2285 /* found it */
2286 printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
2287 "PCI subsystem ID is %04x:%04x\n",
2288 btv->c.nr,cards[type].name,cards[type].cardnr,
2289 btv->cardid & 0xffff,
2290 (btv->cardid >> 16) & 0xffff);
2291 btv->c.type = cards[type].cardnr;
2292 } else {
2293 /* 404 */
2294 printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
2295 btv->c.nr, btv->cardid & 0xffff,
2296 (btv->cardid >> 16) & 0xffff);
2297 printk(KERN_DEBUG "please mail id, board name and "
2298 "the correct card= insmod option to kraxel@bytesex.org\n");
2299 }
2300 }
2301
2302 /* let the user override the autodetected type */
2303 if (card[btv->c.nr] < bttv_num_tvcards)
2304 btv->c.type=card[btv->c.nr];
2305
2306 /* print which card config we are using */
2307 printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->c.nr,
2308 bttv_tvcards[btv->c.type].name, btv->c.type,
2309 card[btv->c.nr] < bttv_num_tvcards
2310 ? "insmod option" : "autodetected");
2311
2312 /* overwrite gpio stuff ?? */
2313 if (UNSET == audioall && UNSET == audiomux[0])
2314 return;
2315
2316 if (UNSET != audiomux[0]) {
2317 gpiobits = 0;
2318 for (i = 0; i < 5; i++) {
2319 bttv_tvcards[btv->c.type].audiomux[i] = audiomux[i];
2320 gpiobits |= audiomux[i];
2321 }
2322 } else {
2323 gpiobits = audioall;
2324 for (i = 0; i < 5; i++) {
2325 bttv_tvcards[btv->c.type].audiomux[i] = audioall;
2326 }
2327 }
2328 bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
2329 printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
2330 btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
2331 for (i = 0; i < 5; i++) {
2332 printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].audiomux[i]);
2333 }
2334 printk("\n");
2335}
2336
2337/*
2338 * (most) board specific initialisations goes here
2339 */
2340
2341/* Some Modular Technology cards have an eeprom, but no subsystem ID */
2342void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2343{
2344 int type = -1;
2345
2346 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2347 type = BTTV_MODTEC_205;
2348 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2349 type = BTTV_EURESYS_PICOLO;
2350 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2351 type = BTTV_HAUPPAUGE; /* old bt848 */
2352
2353 if (-1 != type) {
2354 btv->c.type = type;
2355 printk("bttv%d: detected by eeprom: %s [card=%d]\n",
2356 btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
2357 }
2358}
2359
2360static void flyvideo_gpio(struct bttv *btv)
2361{
2362 int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821;
2363 int tuner=-1,ttype;
2364
2365 gpio_inout(0xffffff, 0);
2366 udelay(8); // without this we would see the 0x1800 mask
2367 gpio = gpio_read();
2368 /* FIXME: must restore OUR_EN ??? */
2369
2370 // all cards provide GPIO info, some have an additional eeprom
2371 // LR50: GPIO coding can be found lower right CP1 .. CP9
2372 // CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
2373 // GPIO14-12: n.c.
2374 // LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
2375
2376 // lowest 3 bytes are remote control codes (no handshake needed)
2377 // xxxFFF: No remote control chip soldered
2378 // xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
2379 // Note: Some bits are Audio_Mask !
2380
2381 ttype=(gpio&0x0f0000)>>16;
2382 switch(ttype) {
2383 case 0x0: tuner=2; // NTSC, e.g. TPI8NSR11P
2384 break;
2385 case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P
2386 break;
2387 case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216
2388 break;
2389 case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P
2390 break;
2391 case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF
2392 break;
2393 default:
2394 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
2395 }
2396
2397 has_remote = gpio & 0x800000;
2398 has_radio = gpio & 0x400000;
2399 // unknown 0x200000;
2400 // unknown2 0x100000;
2401 is_capture_only = !(gpio & 0x008000); //GPIO15
2402 has_tda9820_tda9821 = !(gpio & 0x004000);
2403 is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only)
2404 // gpio & 0x001000 // output bit for audio routing
2405
2406 if(is_capture_only)
2407 tuner=4; // No tuner present
2408
2409 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
2410 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
2411 printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
2412 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
2413 is_capture_only?"yes":"no ");
2414
2415 if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through
2416 btv->tuner_type = tuner;
2417 btv->has_radio = has_radio;
2418
2419 // LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
2420 // LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
2421 // Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute
2422 if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
2423 //todo: if(has_tda9874) btv->audio_hook = fv2000s_audio;
2424}
2425
2426static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
2427 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 };
2428static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1,
2429 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 };
2430
2431static void miro_pinnacle_gpio(struct bttv *btv)
2432{
2433 int id,msp,gpio;
2434 char *info;
2435
2436 gpio_inout(0xffffff, 0);
2437 gpio = gpio_read();
2438 id = ((gpio>>10) & 63) -1;
2439 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2440 if (id < 32) {
2441 btv->tuner_type = miro_tunermap[id];
2442 if (0 == (gpio & 0x20)) {
2443 btv->has_radio = 1;
2444 if (!miro_fmtuner[id]) {
2445 btv->has_matchbox = 1;
2446 btv->mbox_we = (1<<6);
2447 btv->mbox_most = (1<<7);
2448 btv->mbox_clk = (1<<8);
2449 btv->mbox_data = (1<<9);
2450 btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9);
2451 }
2452 } else {
2453 btv->has_radio = 0;
2454 }
2455 if (-1 != msp) {
2456 if (btv->c.type == BTTV_MIRO)
2457 btv->c.type = BTTV_MIROPRO;
2458 if (btv->c.type == BTTV_PINNACLE)
2459 btv->c.type = BTTV_PINNACLEPRO;
2460 }
2461 printk(KERN_INFO
2462 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
2463 btv->c.nr, id+1, btv->tuner_type,
2464 !btv->has_radio ? "no" :
2465 (btv->has_matchbox ? "matchbox" : "fmtuner"),
2466 (-1 == msp) ? "no" : "yes");
2467 } else {
2468 /* new cards with microtune tuner */
2469 id = 63 - id;
2470 btv->has_radio = 0;
2471 switch (id) {
2472 case 1:
2473 info = "PAL / mono";
2474 break;
2475 case 2:
2476 info = "PAL+SECAM / stereo";
2477 btv->has_radio = 1;
2478 break;
2479 case 3:
2480 info = "NTSC / stereo";
2481 btv->has_radio = 1;
2482 break;
2483 case 4:
2484 info = "PAL+SECAM / mono";
2485 break;
2486 case 5:
2487 info = "NTSC / mono";
2488 break;
2489 case 6:
2490 info = "NTSC / stereo";
2491 break;
2492 case 7:
2493 info = "PAL / stereo";
2494 break;
2495 default:
2496 info = "oops: unknown card";
2497 break;
2498 }
2499 if (-1 != msp)
2500 btv->c.type = BTTV_PINNACLEPRO;
2501 printk(KERN_INFO
2502 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2503 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
2504 btv->tuner_type = 33;
2505 btv->pinnacle_id = id;
2506 }
2507}
2508
2509/* GPIO21 L: Buffer aktiv, H: Buffer inaktiv */
2510#define LM1882_SYNC_DRIVE 0x200000L
2511
2512static void init_ids_eagle(struct bttv *btv)
2513{
2514 gpio_inout(0xffffff,0xFFFF37);
2515 gpio_write(0x200020);
2516
2517 /* flash strobe inverter ?! */
2518 gpio_write(0x200024);
2519
2520 /* switch sync drive off */
2521 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
2522
2523 /* set BT848 muxel to 2 */
2524 btaor((2)<<5, ~(2<<5), BT848_IFORM);
2525}
2526
2527/* Muxsel helper for the IDS Eagle.
2528 * the eagles does not use the standard muxsel-bits but
2529 * has its own multiplexer */
2530static void eagle_muxsel(struct bttv *btv, unsigned int input)
2531{
2532 btaor((2)<<5, ~(3<<5), BT848_IFORM);
2533 gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
2534
2535#if 0
2536 /* svhs */
2537 /* wake chroma ADC */
2538 btand(~BT848_ADC_C_SLEEP, BT848_ADC);
2539 /* set to YC video */
2540 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
2541 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
2542#else
2543 /* composite */
2544 /* set chroma ADC to sleep */
2545 btor(BT848_ADC_C_SLEEP, BT848_ADC);
2546 /* set to composite video */
2547 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
2548 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
2549#endif
2550
2551 /* switch sync drive off */
2552 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
2553}
2554
2555static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2556{
2557 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2558 gpio_write(masks[input%4]);
2559}
2560
2561/* LMLBT4x initialization - to allow access to GPIO bits for sensors input and
2562 alarms output
2563
2564 GPIObit | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
2565 assignment | TI | O3|INx| O2| O1|IN4|IN3|IN2|IN1| | |
2566
2567 IN - sensor inputs, INx - sensor inputs and TI XORed together
2568 O1,O2,O3 - alarm outputs (relays)
2569
2570 OUT ENABLE 1 1 0 . 1 1 0 0 . 0 0 0 0 = 0x6C0
2571
2572*/
2573
2574static void init_lmlbt4x(struct bttv *btv)
2575{
2576 printk(KERN_DEBUG "LMLBT4x init\n");
2577 btwrite(0x000000, BT848_GPIO_REG_INP);
2578 gpio_inout(0xffffff, 0x0006C0);
2579 gpio_write(0x000000);
2580}
2581
2582static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input)
2583{
2584 unsigned int inmux = input % 8;
2585 gpio_inout( 0xf, 0xf );
2586 gpio_bits( 0xf, inmux );
2587}
2588
2589static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input)
2590{
2591 unsigned int inmux = input % 4;
2592 gpio_inout( 3<<9, 3<<9 );
2593 gpio_bits( 3<<9, inmux<<9 );
2594}
2595
2596/* ----------------------------------------------------------------------- */
2597
2598static void bttv_reset_audio(struct bttv *btv)
2599{
2600 /*
2601 * BT878A has a audio-reset register.
2602 * 1. This register is an audio reset function but it is in
2603 * function-0 (video capture) address space.
2604 * 2. It is enough to do this once per power-up of the card.
2605 * 3. There is a typo in the Conexant doc -- it is not at
2606 * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!).
2607 * --//Shrikumar 030609
2608 */
2609 if (btv->id != 878)
2610 return;
2611
2612 if (bttv_debug)
2613 printk("bttv%d: BT878A ARESET\n",btv->c.nr);
2614 btwrite((1<<7), 0x058);
2615 udelay(10);
2616 btwrite( 0, 0x058);
2617}
2618
2619/* initialization part one -- before registering i2c bus */
2620void __devinit bttv_init_card1(struct bttv *btv)
2621{
2622 switch (btv->c.type) {
2623 case BTTV_HAUPPAUGE:
2624 case BTTV_HAUPPAUGE878:
2625 boot_msp34xx(btv,5);
2626 break;
2627 case BTTV_VOODOOTV_FM:
2628 boot_msp34xx(btv,20);
2629 break;
2630 case BTTV_AVERMEDIA98:
2631 boot_msp34xx(btv,11);
2632 break;
2633 case BTTV_HAUPPAUGEPVR:
2634 pvr_boot(btv);
2635 break;
2636 case BTTV_TWINHAN_DST:
2637 case BTTV_AVDVBT_771:
2638 btv->use_i2c_hw = 1;
2639 break;
2640 }
2641 if (!bttv_tvcards[btv->c.type].has_dvb)
2642 bttv_reset_audio(btv);
2643}
2644
2645/* initialization part two -- after registering i2c bus */
2646void __devinit bttv_init_card2(struct bttv *btv)
2647{
2648 int tda9887;
2649 btv->tuner_type = -1;
2650
2651 if (BTTV_UNKNOWN == btv->c.type) {
2652 bttv_readee(btv,eeprom_data,0xa0);
2653 identify_by_eeprom(btv,eeprom_data);
2654 }
2655
2656 switch (btv->c.type) {
2657 case BTTV_MIRO:
2658 case BTTV_MIROPRO:
2659 case BTTV_PINNACLE:
2660 case BTTV_PINNACLEPRO:
2661 /* miro/pinnacle */
2662 miro_pinnacle_gpio(btv);
2663 break;
2664 case BTTV_FLYVIDEO_98:
2665 case BTTV_MAXI:
2666 case BTTV_LIFE_FLYKIT:
2667 case BTTV_FLYVIDEO:
2668 case BTTV_TYPHOON_TVIEW:
2669 case BTTV_CHRONOS_VS2:
2670 case BTTV_FLYVIDEO_98FM:
2671 case BTTV_FLYVIDEO2000:
2672 case BTTV_FLYVIDEO98EZ:
2673 case BTTV_CONFERENCETV:
2674 case BTTV_LIFETEC_9415:
2675 flyvideo_gpio(btv);
2676 break;
2677 case BTTV_HAUPPAUGE:
2678 case BTTV_HAUPPAUGE878:
2679 case BTTV_HAUPPAUGEPVR:
2680 /* pick up some config infos from the eeprom */
2681 bttv_readee(btv,eeprom_data,0xa0);
2682 hauppauge_eeprom(btv);
2683 break;
2684 case BTTV_AVERMEDIA98:
2685 case BTTV_AVPHONE98:
2686 bttv_readee(btv,eeprom_data,0xa0);
2687 avermedia_eeprom(btv);
2688 break;
2689 case BTTV_PXC200:
2690 init_PXC200(btv);
2691 break;
2692 case BTTV_PICOLO_TETRA_CHIP:
2693 picolo_tetra_init(btv);
2694 break;
2695 case BTTV_VHX:
2696 btv->has_radio = 1;
2697 btv->has_matchbox = 1;
2698 btv->mbox_we = 0x20;
2699 btv->mbox_most = 0;
2700 btv->mbox_clk = 0x08;
2701 btv->mbox_data = 0x10;
2702 btv->mbox_mask = 0x38;
2703 break;
2704 case BTTV_VOBIS_BOOSTAR:
2705 case BTTV_TERRATV:
2706 terratec_active_radio_upgrade(btv);
2707 break;
2708 case BTTV_MAGICTVIEW061:
2709 if (btv->cardid == 0x3002144f) {
2710 btv->has_radio=1;
2711 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2712 }
2713 break;
2714 case BTTV_STB2:
2715 if (btv->cardid == 0x3060121a) {
2716 /* Fix up entry for 3DFX VoodooTV 100,
2717 which is an OEM STB card variant. */
2718 btv->has_radio=0;
2719 btv->tuner_type=TUNER_TEMIC_NTSC;
2720 }
2721 break;
2722 case BTTV_OSPREY1x0:
2723 case BTTV_OSPREY1x0_848:
2724 case BTTV_OSPREY101_848:
2725 case BTTV_OSPREY1x1:
2726 case BTTV_OSPREY1x1_SVID:
2727 case BTTV_OSPREY2xx:
2728 case BTTV_OSPREY2x0_SVID:
2729 case BTTV_OSPREY2x0:
2730 case BTTV_OSPREY500:
2731 case BTTV_OSPREY540:
2732 case BTTV_OSPREY2000:
2733 bttv_readee(btv,eeprom_data,0xa0);
2734 osprey_eeprom(btv);
2735 break;
2736 case BTTV_IDS_EAGLE:
2737 init_ids_eagle(btv);
2738 break;
2739 case BTTV_MODTEC_205:
2740 bttv_readee(btv,eeprom_data,0xa0);
2741 modtec_eeprom(btv);
2742 break;
2743 case BTTV_LMLBT4:
2744 init_lmlbt4x(btv);
2745 break;
2746 case BTTV_TIBET_CS16:
2747 tibetCS16_init(btv);
2748 break;
2749 case BTTV_KODICOM_4400R:
2750 kodicom4400r_init(btv);
2751 break;
2752 }
2753
2754 /* pll configuration */
2755 if (!(btv->id==848 && btv->revision==0x11)) {
2756 /* defaults from card list */
2757 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2758 btv->pll.pll_ifreq=28636363;
2759 btv->pll.pll_crystal=BT848_IFORM_XT0;
2760 }
2761 if (PLL_35 == bttv_tvcards[btv->c.type].pll) {
2762 btv->pll.pll_ifreq=35468950;
2763 btv->pll.pll_crystal=BT848_IFORM_XT1;
2764 }
2765 /* insmod options can override */
2766 switch (pll[btv->c.nr]) {
2767 case 0: /* none */
2768 btv->pll.pll_crystal = 0;
2769 btv->pll.pll_ifreq = 0;
2770 btv->pll.pll_ofreq = 0;
2771 break;
2772 case 1: /* 28 MHz */
2773 case 28:
2774 btv->pll.pll_ifreq = 28636363;
2775 btv->pll.pll_ofreq = 0;
2776 btv->pll.pll_crystal = BT848_IFORM_XT0;
2777 break;
2778 case 2: /* 35 MHz */
2779 case 35:
2780 btv->pll.pll_ifreq = 35468950;
2781 btv->pll.pll_ofreq = 0;
2782 btv->pll.pll_crystal = BT848_IFORM_XT1;
2783 break;
2784 }
2785 }
2786 btv->pll.pll_current = -1;
2787
2788 bttv_reset_audio(btv);
2789
2790 /* tuner configuration (from card list / autodetect / insmod option) */
2791 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2792 if(UNSET == btv->tuner_type)
2793 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2794 if (UNSET != tuner[btv->c.nr])
2795 btv->tuner_type = tuner[btv->c.nr];
2796 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2797 if (btv->pinnacle_id != UNSET)
2798 bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
2799 &btv->pinnacle_id);
2800 if (btv->tuner_type != UNSET)
2801 bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
2802 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2803 if (svhs[btv->c.nr] != UNSET)
2804 btv->svhs = svhs[btv->c.nr];
2805 if (remote[btv->c.nr] != UNSET)
2806 btv->has_remote = remote[btv->c.nr];
2807
2808 if (bttv_tvcards[btv->c.type].has_radio)
2809 btv->has_radio=1;
2810 if (bttv_tvcards[btv->c.type].has_remote)
2811 btv->has_remote=1;
2812 if (bttv_tvcards[btv->c.type].no_gpioirq)
2813 btv->gpioirq=0;
2814 if (bttv_tvcards[btv->c.type].audio_hook)
2815 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2816
2817 if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) {
2818 /* detect Bt832 chip for quartzsight digital camera */
2819 if ((bttv_I2CRead(btv, I2C_BT832_ALT1, "Bt832") >=0) ||
2820 (bttv_I2CRead(btv, I2C_BT832_ALT2, "Bt832") >=0))
2821 boot_bt832(btv);
2822 }
2823
2824 if (!autoload)
2825 return;
2826
2827 /* try to detect audio/fader chips */
2828 if (!bttv_tvcards[btv->c.type].no_msp34xx &&
2829 bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0)
2830 request_module("msp3400");
2831
2832 if (bttv_tvcards[btv->c.type].msp34xx_alt &&
2833 bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
2834 request_module("msp3400");
2835
2836 if (!bttv_tvcards[btv->c.type].no_tda9875 &&
2837 bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0)
2838 request_module("tda9875");
2839
2840 if (!bttv_tvcards[btv->c.type].no_tda7432 &&
2841 bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0)
2842 request_module("tda7432");
2843
2844 if (bttv_tvcards[btv->c.type].needs_tvaudio)
2845 request_module("tvaudio");
2846
2847 /* tuner modules */
2848 tda9887 = 0;
2849 if (btv->pinnacle_id != UNSET)
2850 tda9887 = 1;
2851 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
2852 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
2853 tda9887 = 1;
2854 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
2855 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
2856 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
2857 tda9887)
2858 request_module("tda9887");
2859 if (btv->tuner_type != UNSET)
2860 request_module("tuner");
2861}
2862
2863
2864/* ----------------------------------------------------------------------- */
2865
2866static void modtec_eeprom(struct bttv *btv)
2867{
2868 if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) {
2869 btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I;
2870 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2871 btv->c.nr,&eeprom_data[0x1e]);
2872 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
2873 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
2874 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2875 btv->c.nr,&eeprom_data[0x1e]);
2876 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
2877 btv->tuner_type=TUNER_PHILIPS_NTSC;
2878 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2879 btv->c.nr,&eeprom_data[0x1e]);
2880 } else {
2881 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
2882 btv->c.nr,&eeprom_data[0x1e]);
2883 }
2884}
2885
2886static void __devinit hauppauge_eeprom(struct bttv *btv)
2887{
2888 struct tveeprom tv;
2889
2890 tveeprom_hauppauge_analog(&tv, eeprom_data);
2891 btv->tuner_type = tv.tuner_type;
2892 btv->has_radio = tv.has_radio;
2893}
2894
2895static int terratec_active_radio_upgrade(struct bttv *btv)
2896{
2897 int freq;
2898
2899 btv->has_radio = 1;
2900 btv->has_matchbox = 1;
2901 btv->mbox_we = 0x10;
2902 btv->mbox_most = 0x20;
2903 btv->mbox_clk = 0x08;
2904 btv->mbox_data = 0x04;
2905 btv->mbox_mask = 0x3c;
2906
2907 btv->mbox_iow = 1 << 8;
2908 btv->mbox_ior = 1 << 9;
2909 btv->mbox_csel = 1 << 10;
2910
2911 freq=88000/62.5;
2912 tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8
2913 if (0x1ed8 == tea5757_read(btv)) {
2914 printk("bttv%d: Terratec Active Radio Upgrade found.\n",
2915 btv->c.nr);
2916 btv->has_radio = 1;
2917 btv->has_matchbox = 1;
2918 } else {
2919 btv->has_radio = 0;
2920 btv->has_matchbox = 0;
2921 }
2922 return 0;
2923}
2924
2925
2926/* ----------------------------------------------------------------------- */
2927
2928/*
2929 * minimal bootstrap for the WinTV/PVR -- upload altera firmware.
2930 *
2931 * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have
2932 * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be
2933 * unpacked with unzip).
2934 */
2935#define PVR_GPIO_DELAY 10
2936
2937#define BTTV_ALT_DATA 0x000001
2938#define BTTV_ALT_DCLK 0x100000
2939#define BTTV_ALT_NCONFIG 0x800000
2940
2941static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
2942{
2943 u32 n;
2944 u8 bits;
2945 int i;
2946
2947 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
2948 gpio_write(0);
2949 udelay(PVR_GPIO_DELAY);
2950
2951 gpio_write(BTTV_ALT_NCONFIG);
2952 udelay(PVR_GPIO_DELAY);
2953
2954 for (n = 0; n < microlen; n++) {
2955 bits = micro[n];
2956 for ( i = 0 ; i < 8 ; i++ ) {
2957 gpio_bits(BTTV_ALT_DCLK,0);
2958 if (bits & 0x01)
2959 gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
2960 else
2961 gpio_bits(BTTV_ALT_DATA,0);
2962 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
2963 bits >>= 1;
2964 }
2965 }
2966 gpio_bits(BTTV_ALT_DCLK,0);
2967 udelay(PVR_GPIO_DELAY);
2968
2969 /* begin Altera init loop (Not necessary,but doesn't hurt) */
2970 for (i = 0 ; i < 30 ; i++) {
2971 gpio_bits(BTTV_ALT_DCLK,0);
2972 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
2973 }
2974 gpio_bits(BTTV_ALT_DCLK,0);
2975 return 0;
2976}
2977
2978static int __devinit pvr_boot(struct bttv *btv)
2979{
2980 const struct firmware *fw_entry;
2981 int rc;
2982
2983 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
2984 if (rc != 0) {
2985 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
2986 btv->c.nr);
2987 return rc;
2988 }
2989 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
2990 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
2991 btv->c.nr, (rc < 0) ? "failed" : "ok");
2992 release_firmware(fw_entry);
2993 return rc;
2994}
2995
2996/* ----------------------------------------------------------------------- */
2997/* some osprey specific stuff */
2998
2999static void __devinit osprey_eeprom(struct bttv *btv)
3000{
3001 int i = 0;
3002 unsigned char *ee = eeprom_data;
3003 unsigned long serial = 0;
3004
3005 if (btv->c.type == 0) {
3006 /* this might be an antique... check for MMAC label in eeprom */
3007 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3008 unsigned char checksum = 0;
3009 for (i =0; i<21; i++)
3010 checksum += ee[i];
3011 if (checksum != ee[21])
3012 return;
3013 btv->c.type = BTTV_OSPREY1x0_848;
3014 for (i = 12; i < 21; i++)
3015 serial *= 10, serial += ee[i] - '0';
3016 }
3017 } else {
3018 unsigned short type;
3019 int offset = 4*16;
3020
3021 for(; offset < 8*16; offset += 16) {
3022 unsigned short checksum = 0;
3023 /* verify the checksum */
3024 for(i = 0; i<14; i++) checksum += ee[i+offset];
3025 checksum = ~checksum; /* no idea why */
3026 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3027 ((checksum & 0x0FF) == ee[offset+15])) {
3028 break;
3029 }
3030 }
3031
3032 if (offset >= 8*16)
3033 return;
3034
3035 /* found a valid descriptor */
3036 type = (ee[offset+4]<<8) | (ee[offset+5]);
3037
3038 switch(type) {
3039
3040 /* 848 based */
3041 case 0x0004:
3042 btv->c.type = BTTV_OSPREY1x0_848;
3043 break;
3044 case 0x0005:
3045 btv->c.type = BTTV_OSPREY101_848;
3046 break;
3047
3048 /* 878 based */
3049 case 0x0012:
3050 case 0x0013:
3051 btv->c.type = BTTV_OSPREY1x0;
3052 break;
3053 case 0x0014:
3054 case 0x0015:
3055 btv->c.type = BTTV_OSPREY1x1;
3056 break;
3057 case 0x0016:
3058 case 0x0017:
3059 case 0x0020:
3060 btv->c.type = BTTV_OSPREY1x1_SVID;
3061 break;
3062 case 0x0018:
3063 case 0x0019:
3064 case 0x001E:
3065 case 0x001F:
3066 btv->c.type = BTTV_OSPREY2xx;
3067 break;
3068 case 0x001A:
3069 case 0x001B:
3070 btv->c.type = BTTV_OSPREY2x0_SVID;
3071 break;
3072 case 0x0040:
3073 btv->c.type = BTTV_OSPREY500;
3074 break;
3075 case 0x0050:
3076 case 0x0056:
3077 btv->c.type = BTTV_OSPREY540;
3078 /* bttv_osprey_540_init(btv); */
3079 break;
3080 case 0x0060:
3081 case 0x0070:
3082 btv->c.type = BTTV_OSPREY2x0;
3083 //enable output on select control lines
3084 gpio_inout(0xffffff,0x000303);
3085 break;
3086 default:
3087 /* unknown...leave generic, but get serial # */
3088 break;
3089 }
3090 serial = (ee[offset+6] << 24)
3091 | (ee[offset+7] << 16)
3092 | (ee[offset+8] << 8)
3093 | (ee[offset+9]);
3094 }
3095
3096 printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n",
3097 btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial);
3098}
3099
3100/* ----------------------------------------------------------------------- */
3101/* AVermedia specific stuff, from bktr_card.c */
3102
3103static int tuner_0_table[] = {
3104 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3105 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3106 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3107 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3108 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3109 TUNER_PHILIPS_FM1216ME_MK3 };
3110#if 0
3111int tuner_0_fm_table[] = {
3112 PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL,
3113 PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
3114 PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
3115 PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
3116 PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
3117#endif
3118
3119static int tuner_1_table[] = {
3120 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3121 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3122 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3123 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM
3124 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3125
3126static void __devinit avermedia_eeprom(struct bttv *btv)
3127{
3128 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3129
3130 tuner_make = (eeprom_data[0x41] & 0x7);
3131 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3132 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3133 btv->has_remote = (eeprom_data[0x42] & 0x01);
3134
3135 if (tuner_make == 0 || tuner_make == 2)
3136 if(tuner_format <=0x0a)
3137 tuner = tuner_0_table[tuner_format];
3138 if (tuner_make == 1)
3139 if(tuner_format <=9)
3140 tuner = tuner_1_table[tuner_format];
3141
3142 if (tuner_make == 4)
3143 if(tuner_format == 0x09)
3144 tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P
3145
3146 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
3147 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
3148 if(tuner) {
3149 btv->tuner_type=tuner;
3150 printk("%d",tuner);
3151 } else
3152 printk("Unknown type");
3153 printk(" radio:%s remote control:%s\n",
3154 tuner_tv_fm ? "yes" : "no",
3155 btv->has_remote ? "yes" : "no");
3156}
3157
3158/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
3159void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3160{
3161 // fix up our card entry
3162 if(norm==VIDEO_MODE_NTSC) {
3163 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
3164 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
3165 dprintk("bttv_tda9880_setnorm to NTSC\n");
3166 }
3167 else {
3168 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff;
3169 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
3170 dprintk("bttv_tda9880_setnorm to PAL\n");
3171 }
3172 // set GPIO according
3173 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
3174 bttv_tvcards[btv->c.type].audiomux[btv->audio]);
3175}
3176
3177
3178/*
3179 * reset/enable the MSP on some Hauppauge cards
3180 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3181 *
3182 * Hauppauge: pin 5
3183 * Voodoo: pin 20
3184 */
3185static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3186{
3187 int mask = (1 << pin);
3188
3189 gpio_inout(mask,mask);
3190 gpio_bits(mask,0);
3191 udelay(2500);
3192 gpio_bits(mask,mask);
3193
3194 if (bttv_gpio)
3195 bttv_gpio_tracking(btv,"msp34xx");
3196 if (bttv_verbose)
3197 printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line "
3198 "init [%d]\n", btv->c.nr, pin);
3199}
3200
3201static void __devinit boot_bt832(struct bttv *btv)
3202{
3203#if 0 /* not working yet */
3204 int resetbit=0;
3205
3206 switch (btv->c.type) {
3207 case BTTV_PXELVWPLTVPAK:
3208 resetbit = 0x400000;
3209 break;
3210 case BTTV_MODTEC_205:
3211 resetbit = 1<<9;
3212 break;
3213 default:
3214 BUG();
3215 }
3216
3217 request_module("bt832");
3218 bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL);
3219
3220 printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->c.nr,resetbit);
3221 gpio_write(0);
3222 gpio_inout(resetbit, resetbit);
3223 udelay(5);
3224 gpio_bits(resetbit, resetbit);
3225 udelay(5);
3226 gpio_bits(resetbit, 0);
3227 udelay(5);
3228
3229 // bt832 on pixelview changes from i2c 0x8a to 0x88 after
3230 // being reset as above. So we must follow by this:
3231 bttv_call_i2c_clients(btv, BT832_REATTACH, NULL);
3232#endif
3233}
3234
3235/* ----------------------------------------------------------------------- */
3236/* Imagenation L-Model PXC200 Framegrabber */
3237/* This is basically the same procedure as
3238 * used by Alessandro Rubini in his pxc200
3239 * driver, but using BTTV functions */
3240
3241static void __devinit init_PXC200(struct bttv *btv)
3242{
3243 static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
3244 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
3245 0x00 };
3246 unsigned int i;
3247 int tmp;
3248 u32 val;
3249
3250 /* Initialise GPIO-connevted stuff */
3251 gpio_inout(0xffffff, (1<<13));
3252 gpio_write(0);
3253 udelay(3);
3254 gpio_write(1<<13);
3255 /* GPIO inputs are pulled up, so no need to drive
3256 * reset pin any longer */
3257 gpio_bits(0xffffff, 0);
3258 if (bttv_gpio)
3259 bttv_gpio_tracking(btv,"pxc200");
3260
3261 /* we could/should try and reset/control the AD pots? but
3262 right now we simply turned off the crushing. Without
3263 this the AGC drifts drifts
3264 remember the EN is reverse logic -->
3265 setting BT848_ADC_AGC_EN disable the AGC
3266 tboult@eecs.lehigh.edu
3267 */
3268
3269 btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC);
3270
3271 /* Initialise MAX517 DAC */
3272 printk(KERN_INFO "Setting DAC reference voltage level ...\n");
3273 bttv_I2CWrite(btv,0x5E,0,0x80,1);
3274
3275 /* Initialise 12C508 PIC */
3276 /* The I2CWrite and I2CRead commmands are actually to the
3277 * same chips - but the R/W bit is included in the address
3278 * argument so the numbers are different */
3279
3280
3281 printk(KERN_INFO "Initialising 12C508 PIC chip ...\n");
3282
3283 /* First of all, enable the clock line. This is used in the PXC200-F */
3284 val = btread(BT848_GPIO_DMA_CTL);
3285 val |= BT848_GPIO_DMA_CTL_GPCLKMODE;
3286 btwrite(val, BT848_GPIO_DMA_CTL);
3287
3288 /* Then, push to 0 the reset pin long enough to reset the *
3289 * device same as above for the reset line, but not the same
3290 * value sent to the GPIO-connected stuff
3291 * which one is the good one? */
3292 gpio_inout(0xffffff,(1<<2));
3293 gpio_write(0);
3294 udelay(10);
3295 gpio_write(1<<2);
3296
3297 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3298 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3299 if (tmp != -1) {
3300 printk(KERN_INFO
3301 "I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n",
3302 vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL));
3303 }
3304 }
3305
3306 printk(KERN_INFO "PXC200 Initialised.\n");
3307}
3308
3309
3310/* ----------------------------------------------------------------------- */
3311/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
3312/*
3313 * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
3314 * This code is placed under the terms of the GNU General Public License
3315 *
3316 * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
3317 */
3318
3319static void bus_low(struct bttv *btv, int bit)
3320{
3321 if (btv->mbox_ior) {
3322 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3323 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3324 udelay(5);
3325 }
3326
3327 gpio_bits(bit,0);
3328 udelay(5);
3329
3330 if (btv->mbox_ior) {
3331 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3332 udelay(5);
3333 }
3334}
3335
3336static void bus_high(struct bttv *btv, int bit)
3337{
3338 if (btv->mbox_ior) {
3339 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3340 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3341 udelay(5);
3342 }
3343
3344 gpio_bits(bit,bit);
3345 udelay(5);
3346
3347 if (btv->mbox_ior) {
3348 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3349 udelay(5);
3350 }
3351}
3352
3353static int bus_in(struct bttv *btv, int bit)
3354{
3355 if (btv->mbox_ior) {
3356 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3357 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3358 udelay(5);
3359
3360 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3361 udelay(5);
3362 }
3363 return gpio_read() & (bit);
3364}
3365
3366/* TEA5757 register bits */
3367#define TEA_FREQ 0:14
3368#define TEA_BUFFER 15:15
3369
3370#define TEA_SIGNAL_STRENGTH 16:17
3371
3372#define TEA_PORT1 18:18
3373#define TEA_PORT0 19:19
3374
3375#define TEA_BAND 20:21
3376#define TEA_BAND_FM 0
3377#define TEA_BAND_MW 1
3378#define TEA_BAND_LW 2
3379#define TEA_BAND_SW 3
3380
3381#define TEA_MONO 22:22
3382#define TEA_ALLOW_STEREO 0
3383#define TEA_FORCE_MONO 1
3384
3385#define TEA_SEARCH_DIRECTION 23:23
3386#define TEA_SEARCH_DOWN 0
3387#define TEA_SEARCH_UP 1
3388
3389#define TEA_STATUS 24:24
3390#define TEA_STATUS_TUNED 0
3391#define TEA_STATUS_SEARCHING 1
3392
3393/* Low-level stuff */
3394static int tea5757_read(struct bttv *btv)
3395{
3396 unsigned long timeout;
3397 int value = 0;
3398 int i;
3399
3400 /* better safe than sorry */
3401 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we);
3402
3403 if (btv->mbox_ior) {
3404 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3405 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3406 udelay(5);
3407 }
3408
3409 if (bttv_gpio)
3410 bttv_gpio_tracking(btv,"tea5757 read");
3411
3412 bus_low(btv,btv->mbox_we);
3413 bus_low(btv,btv->mbox_clk);
3414
3415 udelay(10);
3416 timeout= jiffies + HZ;
3417
3418 // wait for DATA line to go low; error if it doesn't
3419 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
3420 schedule();
3421 if (bus_in(btv,btv->mbox_data)) {
3422 printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->c.nr);
3423 return -1;
3424 }
3425
3426 dprintk("bttv%d: tea5757:",btv->c.nr);
3427 for(i = 0; i < 24; i++)
3428 {
3429 udelay(5);
3430 bus_high(btv,btv->mbox_clk);
3431 udelay(5);
3432 dprintk("%c",(bus_in(btv,btv->mbox_most) == 0)?'T':'-');
3433 bus_low(btv,btv->mbox_clk);
3434 value <<= 1;
3435 value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */
3436 dprintk("%c", (bus_in(btv,btv->mbox_most) == 0)?'S':'M');
3437 }
3438 dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->c.nr, value);
3439 return value;
3440}
3441
3442static int tea5757_write(struct bttv *btv, int value)
3443{
3444 int i;
3445 int reg = value;
3446
3447 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data);
3448
3449 if (btv->mbox_ior) {
3450 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3451 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3452 udelay(5);
3453 }
3454 if (bttv_gpio)
3455 bttv_gpio_tracking(btv,"tea5757 write");
3456
3457 dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
3458 bus_low(btv,btv->mbox_clk);
3459 bus_high(btv,btv->mbox_we);
3460 for(i = 0; i < 25; i++)
3461 {
3462 if (reg & 0x1000000)
3463 bus_high(btv,btv->mbox_data);
3464 else
3465 bus_low(btv,btv->mbox_data);
3466 reg <<= 1;
3467 bus_high(btv,btv->mbox_clk);
3468 udelay(10);
3469 bus_low(btv,btv->mbox_clk);
3470 udelay(10);
3471 }
3472 bus_low(btv,btv->mbox_we); /* unmute !!! */
3473 return 0;
3474}
3475
3476void tea5757_set_freq(struct bttv *btv, unsigned short freq)
3477{
3478 dprintk("tea5757_set_freq %d\n",freq);
3479 tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
3480#if 0
3481 /* breaks Miro PCTV */
3482 value = tea5757_read(btv);
3483 dprintk("bttv%d: tea5757 readback=0x%x\n",btv->c.nr,value);
3484#endif
3485}
3486
3487
3488/* ----------------------------------------------------------------------- */
3489/* winview */
3490
3491void winview_audio(struct bttv *btv, struct video_audio *v, int set)
3492{
3493 /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
3494 int bits_out, loops, vol, data;
3495
3496 if (!set) {
3497 /* Fixed by Leandro Lucarella <luca@linuxmendoza.org.ar (07/31/01) */
3498 v->flags |= VIDEO_AUDIO_VOLUME;
3499 return;
3500 }
3501
3502 /* 32 levels logarithmic */
3503 vol = 32 - ((v->volume>>11));
3504 /* units */
3505 bits_out = (PT2254_DBS_IN_2>>(vol%5));
3506 /* tens */
3507 bits_out |= (PT2254_DBS_IN_10>>(vol/5));
3508 bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
3509 data = gpio_read();
3510 data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
3511 WINVIEW_PT2254_STROBE);
3512 for (loops = 17; loops >= 0 ; loops--) {
3513 if (bits_out & (1<<loops))
3514 data |= WINVIEW_PT2254_DATA;
3515 else
3516 data &= ~WINVIEW_PT2254_DATA;
3517 gpio_write(data);
3518 udelay(5);
3519 data |= WINVIEW_PT2254_CLK;
3520 gpio_write(data);
3521 udelay(5);
3522 data &= ~WINVIEW_PT2254_CLK;
3523 gpio_write(data);
3524 }
3525 data |= WINVIEW_PT2254_STROBE;
3526 data &= ~WINVIEW_PT2254_DATA;
3527 gpio_write(data);
3528 udelay(10);
3529 data &= ~WINVIEW_PT2254_STROBE;
3530 gpio_write(data);
3531}
3532
3533/* ----------------------------------------------------------------------- */
3534/* mono/stereo control for various cards (which don't use i2c chips but */
3535/* connect something to the GPIO pins */
3536
3537static void
3538gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
3539{
3540 unsigned int con = 0;
3541
3542 if (set) {
3543 gpio_inout(0x300, 0x300);
3544 if (v->mode & VIDEO_SOUND_LANG1)
3545 con = 0x000;
3546 if (v->mode & VIDEO_SOUND_LANG2)
3547 con = 0x300;
3548 if (v->mode & VIDEO_SOUND_STEREO)
3549 con = 0x200;
3550// if (v->mode & VIDEO_SOUND_MONO)
3551// con = 0x100;
3552 gpio_bits(0x300, con);
3553 } else {
3554 v->mode = VIDEO_SOUND_STEREO |
3555 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3556 }
3557}
3558
3559static void
3560gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
3561{
3562 unsigned int val, con;
3563
3564#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3565 if (btv->radio_user)
3566 return;
3567#else
3568 if (btv->radio)
3569 return;
3570#endif
3571
3572 val = gpio_read();
3573 if (set) {
3574 con = 0x000;
3575 if (v->mode & VIDEO_SOUND_LANG2) {
3576 if (v->mode & VIDEO_SOUND_LANG1) {
3577 /* LANG1 + LANG2 */
3578 con = 0x100;
3579 }
3580 else {
3581 /* LANG2 */
3582 con = 0x300;
3583 }
3584 }
3585 if (con != (val & 0x300)) {
3586 gpio_bits(0x300, con);
3587 if (bttv_gpio)
3588 bttv_gpio_tracking(btv,"gvbctv5pci");
3589 }
3590 } else {
3591 switch (val & 0x70) {
3592 case 0x10:
3593 v->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3594 break;
3595 case 0x30:
3596 v->mode = VIDEO_SOUND_LANG2;
3597 break;
3598 case 0x50:
3599 v->mode = VIDEO_SOUND_LANG1;
3600 break;
3601 case 0x60:
3602 v->mode = VIDEO_SOUND_STEREO;
3603 break;
3604 case 0x70:
3605 v->mode = VIDEO_SOUND_MONO;
3606 break;
3607 default:
3608 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3609 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3610 }
3611 }
3612}
3613
3614/*
3615 * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
3616 * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
3617 * 0xdde enables mono and 0xccd enables sap
3618 *
3619 * Petr Vandrovec <VANDROVE@vc.cvut.cz>
3620 * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
3621 * input/output sound connection, so both must be set for output mode.
3622 *
3623 * Looks like it's needed only for the "tvphone", the "tvphone 98"
3624 * handles this with a tda9840
3625 *
3626 */
3627static void
3628avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set)
3629{
3630 int val = 0;
3631
3632 if (set) {
3633 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3634 val = 0x02;
3635 if (v->mode & VIDEO_SOUND_STEREO)
3636 val = 0x01;
3637 if (val) {
3638 gpio_bits(0x03,val);
3639 if (bttv_gpio)
3640 bttv_gpio_tracking(btv,"avermedia");
3641 }
3642 } else {
3643 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3644 VIDEO_SOUND_LANG1;
3645 return;
3646 }
3647}
3648
3649static void
3650avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3651{
3652 int val = 0;
3653
3654 if (set) {
3655 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3656 val = 0x01;
3657 if (v->mode & VIDEO_SOUND_STEREO) /* STEREO */
3658 val = 0x02;
3659 btaor(val, ~0x03, BT848_GPIO_DATA);
3660 if (bttv_gpio)
3661 bttv_gpio_tracking(btv,"avermedia");
3662 } else {
3663 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3664 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3665 return;
3666 }
3667}
3668
3669/* Lifetec 9415 handling */
3670static void
3671lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3672{
3673 int val = 0;
3674
3675 if (gpio_read() & 0x4000) {
3676 v->mode = VIDEO_SOUND_MONO;
3677 return;
3678 }
3679
3680 if (set) {
3681 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3682 val = 0x0080;
3683 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3684 val = 0x0880;
3685 if ((v->mode & VIDEO_SOUND_LANG1) ||
3686 (v->mode & VIDEO_SOUND_MONO))
3687 val = 0;
3688 gpio_bits(0x0880, val);
3689 if (bttv_gpio)
3690 bttv_gpio_tracking(btv,"lt9415");
3691 } else {
3692 /* autodetect doesn't work with this card :-( */
3693 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3694 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3695 return;
3696 }
3697}
3698
3699// TDA9821 on TerraTV+ Bt848, Bt878
3700static void
3701terratv_audio(struct bttv *btv, struct video_audio *v, int set)
3702{
3703 unsigned int con = 0;
3704
3705 if (set) {
3706 gpio_inout(0x180000,0x180000);
3707 if (v->mode & VIDEO_SOUND_LANG2)
3708 con = 0x080000;
3709 if (v->mode & VIDEO_SOUND_STEREO)
3710 con = 0x180000;
3711 gpio_bits(0x180000, con);
3712 if (bttv_gpio)
3713 bttv_gpio_tracking(btv,"terratv");
3714 } else {
3715 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3716 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3717 }
3718}
3719
3720static void
3721winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
3722{
3723 unsigned long val = 0;
3724
3725 if (set) {
3726 /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
3727 if (v->mode & VIDEO_SOUND_MONO) /* Mono */
3728 val = 0x420000;
3729 if (v->mode & VIDEO_SOUND_LANG1) /* Mono */
3730 val = 0x420000;
3731 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3732 val = 0x410000;
3733 if (v->mode & VIDEO_SOUND_STEREO) /* Stereo */
3734 val = 0x020000;
3735 if (val) {
3736 gpio_bits(0x430000, val);
3737 if (bttv_gpio)
3738 bttv_gpio_tracking(btv,"winfast2000");
3739 }
3740 } else {
3741 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3742 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3743 }
3744}
3745
3746/*
3747 * Dariusz Kowalewski <darekk@automex.pl>
3748 * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
3749 * revision 9B has on-board TDA9874A sound decoder).
3750 *
3751 * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
3752 * will mute this cards.
3753 */
3754static void
3755pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
3756{
3757 unsigned int val = 0;
3758
3759#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3760 if (btv->radio_user)
3761 return;
3762#else
3763 if (btv->radio)
3764 return;
3765#endif
3766
3767 if (set) {
3768 if (v->mode & VIDEO_SOUND_MONO) {
3769 val = 0x01;
3770 }
3771 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
3772 || (v->mode & VIDEO_SOUND_STEREO)) {
3773 val = 0x02;
3774 }
3775 if (val) {
3776 gpio_bits(0x03,val);
3777 if (bttv_gpio)
3778 bttv_gpio_tracking(btv,"pvbt878p9b");
3779 }
3780 } else {
3781 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3782 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3783 }
3784}
3785
3786/*
3787 * Dariusz Kowalewski <darekk@automex.pl>
3788 * sound control for FlyVideo 2000S (with tda9874 decoder)
3789 * based on pvbt878p9b_audio() - this is not tested, please fix!!!
3790 */
3791static void
3792fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
3793{
3794 unsigned int val = 0xffff;
3795
3796#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3797 if (btv->radio_user)
3798 return;
3799#else
3800 if (btv->radio)
3801 return;
3802#endif
3803 if (set) {
3804 if (v->mode & VIDEO_SOUND_MONO) {
3805 val = 0x0000;
3806 }
3807 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
3808 || (v->mode & VIDEO_SOUND_STEREO)) {
3809 val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ...
3810 }
3811 if (val != 0xffff) {
3812 gpio_bits(0x1800, val);
3813 if (bttv_gpio)
3814 bttv_gpio_tracking(btv,"fv2000s");
3815 }
3816 } else {
3817 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3818 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3819 }
3820}
3821
3822/*
3823 * sound control for Canopus WinDVR PCI
3824 * Masaki Suzuki <masaki@btree.org>
3825 */
3826static void
3827windvr_audio(struct bttv *btv, struct video_audio *v, int set)
3828{
3829 unsigned long val = 0;
3830
3831 if (set) {
3832 if (v->mode & VIDEO_SOUND_MONO)
3833 val = 0x040000;
3834 if (v->mode & VIDEO_SOUND_LANG1)
3835 val = 0;
3836 if (v->mode & VIDEO_SOUND_LANG2)
3837 val = 0x100000;
3838 if (v->mode & VIDEO_SOUND_STEREO)
3839 val = 0;
3840 if (val) {
3841 gpio_bits(0x140000, val);
3842 if (bttv_gpio)
3843 bttv_gpio_tracking(btv,"windvr");
3844 }
3845 } else {
3846 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3847 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3848 }
3849}
3850
3851/*
3852 * sound control for AD-TVK503
3853 * Hiroshi Takekawa <sian@big.or.jp>
3854 */
3855static void
3856adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
3857{
3858 unsigned int con = 0xffffff;
3859
3860 //btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN);
3861
3862 if (set) {
3863 //btor(***, BT848_GPIO_OUT_EN);
3864 if (v->mode & VIDEO_SOUND_LANG1)
3865 con = 0x00000000;
3866 if (v->mode & VIDEO_SOUND_LANG2)
3867 con = 0x00180000;
3868 if (v->mode & VIDEO_SOUND_STEREO)
3869 con = 0x00000000;
3870 if (v->mode & VIDEO_SOUND_MONO)
3871 con = 0x00060000;
3872 if (con != 0xffffff) {
3873 gpio_bits(0x1e0000,con);
3874 if (bttv_gpio)
3875 bttv_gpio_tracking(btv, "adtvk503");
3876 }
3877 } else {
3878 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3879 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3880 }
3881}
3882
3883/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
3884 *
3885 * This is needed because rv605 don't use a normal multiplex, but a crosspoint
3886 * switch instead (CD22M3494E). This IC can have multiple active connections
3887 * between Xn (input) and Yn (output) pins. We need to clear any existing
3888 * connection prior to establish a new one, pulsing the STROBE pin.
3889 *
3890 * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
3891 * GPIO pins are wired as:
3892 * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
3893 * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
3894 * GPIO[7] - DATA (xpoint) - P1[7] (microcontroler)
3895 * GPIO[8] - - P3[5] (microcontroler)
3896 * GPIO[9] - RESET (xpoint) - P3[6] (microcontroler)
3897 * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroler)
3898 * GPINTR - - P3[4] (microcontroler)
3899 *
3900 * The microcontroler is a 80C32 like. It should be possible to change xpoint
3901 * configuration either directly (as we are doing) or using the microcontroler
3902 * which is also wired to I2C interface. I have no further info on the
3903 * microcontroler features, one would need to disassembly the firmware.
3904 * note: the vendor refused to give any information on this product, all
3905 * that stuff was found using a multimeter! :)
3906 */
3907static void rv605_muxsel(struct bttv *btv, unsigned int input)
3908{
3909 /* reset all conections */
3910 gpio_bits(0x200,0x200);
3911 mdelay(1);
3912 gpio_bits(0x200,0x000);
3913 mdelay(1);
3914
3915 /* create a new conection */
3916 gpio_bits(0x480,0x080);
3917 gpio_bits(0x480,0x480);
3918 mdelay(1);
3919 gpio_bits(0x480,0x080);
3920 mdelay(1);
3921}
3922
3923/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
3924 *
3925 * The CS16 (available on eBay cheap) is a PCI board with four Fusion
3926 * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
3927 * chips, ten eight input analog multiplexors, a not chip and a few
3928 * other components.
3929 *
3930 * 16 inputs on a secondary bracket are provided and can be selected
3931 * from each of the four capture chips. Two of the eight input
3932 * multiplexors are used to select from any of the 16 input signals.
3933 *
3934 * Unsupported hardware capabilities:
3935 * . A video output monitor on the secondary bracket can be selected from
3936 * one of the 878A chips.
3937 * . Another passthrough but I haven't spent any time investigating it.
3938 * . Digital I/O (logic level connected to GPIO) is available from an
3939 * onboard header.
3940 *
3941 * The on chip input mux should always be set to 2.
3942 * GPIO[16:19] - Video input selection
3943 * GPIO[0:3] - Video output monitor select (only available from one 878A)
3944 * GPIO[?:?] - Digital I/O.
3945 *
3946 * There is an ATMEL microcontroller with an 8031 core on board. I have not
3947 * determined what function (if any) it provides. With the microcontroller
3948 * and sync seperator chips a guess is that it might have to do with video
3949 * switching and maybe some digital I/O.
3950 */
3951static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
3952{
3953 /* video mux */
3954 gpio_bits(0x0f0000, input << 16);
3955}
3956
3957static void tibetCS16_init(struct bttv *btv)
3958{
3959 /* enable gpio bits, mask obtained via btSpy */
3960 gpio_inout(0xffffff, 0x0f7fff);
3961 gpio_write(0x0f7fff);
3962}
3963
3964/*
3965 * The following routines for the Kodicom-4400r get a little mind-twisting.
3966 * There is a "master" controller and three "slave" controllers, together
3967 * an analog switch which connects any of 16 cameras to any of the BT87A's.
3968 * The analog switch is controlled by the "master", but the detection order
3969 * of the four BT878A chips is in an order which I just don't understand.
3970 * The "master" is actually the second controller to be detected. The
3971 * logic on the board uses logical numbers for the 4 controlers, but
3972 * those numbers are different from the detection sequence. When working
3973 * with the analog switch, we need to "map" from the detection sequence
3974 * over to the board's logical controller number. This mapping sequence
3975 * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical
3976 * unit 3, the second (which is the master) is logical unit 0, etc.
3977 * We need to maintain the status of the analog switch (which of the 16
3978 * cameras is connected to which of the 4 controllers). Rather than
3979 * add to the bttv structure for this, we use the data reserved for
3980 * the mbox (unused for this card type).
3981 */
3982
3983/*
3984 * First a routine to set the analog switch, which controls which camera
3985 * is routed to which controller. The switch comprises an X-address
3986 * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
3987 * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
3988 * A data value (gpio bit 7) of '1' enables the switch, and '0' disables
3989 * the switch. A STROBE bit (gpio bit 8) latches the data value into the
3990 * specified address. The idea is to set the address and data, then bring
3991 * STROBE high, and finally bring STROBE back to low.
3992 */
3993static void kodicom4400r_write(struct bttv *btv,
3994 unsigned char xaddr,
3995 unsigned char yaddr,
3996 unsigned char data) {
3997 unsigned int udata;
3998
3999 udata = (data << 7) | ((yaddr&3) << 4) | (xaddr&0xf);
4000 gpio_bits(0x1ff, udata); /* write ADDR and DAT */
4001 gpio_bits(0x1ff, udata | (1 << 8)); /* strobe high */
4002 gpio_bits(0x1ff, udata); /* strobe low */
4003}
4004
4005/*
4006 * Next the mux select. Both the "master" and "slave" 'cards' (controllers)
4007 * use this routine. The routine finds the "master" for the card, maps
4008 * the controller number from the detected position over to the logical
4009 * number, writes the appropriate data to the analog switch, and housekeeps
4010 * the local copy of the switch information. The parameter 'input' is the
4011 * requested camera number (0 - 15).
4012 */
4013static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input)
4014{
4015 char *sw_status;
4016 int xaddr, yaddr;
4017 struct bttv *mctlr;
4018 static unsigned char map[4] = {3, 0, 2, 1};
4019
4020 mctlr = master[btv->c.nr];
4021 if (mctlr == NULL) { /* ignore if master not yet detected */
4022 return;
4023 }
4024 yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */
4025 yaddr = map[yaddr];
4026 sw_status = (char *)(&mctlr->mbox_we);
4027 xaddr = input & 0xf;
4028 /* Check if the controller/camera pair has changed, else ignore */
4029 if (sw_status[yaddr] != xaddr)
4030 {
4031 /* "open" the old switch, "close" the new one, save the new */
4032 kodicom4400r_write(mctlr, sw_status[yaddr], yaddr, 0);
4033 sw_status[yaddr] = xaddr;
4034 kodicom4400r_write(mctlr, xaddr, yaddr, 1);
4035 }
4036}
4037
4038/*
4039 * During initialisation, we need to reset the analog switch. We
4040 * also preset the switch to map the 4 connectors on the card to the
4041 * *user's* (see above description of kodicom4400r_muxsel) channels
4042 * 0 through 3
4043 */
4044static void kodicom4400r_init(struct bttv *btv)
4045{
4046 char *sw_status = (char *)(&btv->mbox_we);
4047 int ix;
4048
4049 gpio_inout(0x0003ff, 0x0003ff);
4050 gpio_write(1 << 9); /* reset MUX */
4051 gpio_write(0);
4052 /* Preset camera 0 to the 4 controllers */
4053 for (ix=0; ix<4; ix++) {
4054 sw_status[ix] = ix;
4055 kodicom4400r_write(btv, ix, ix, 1);
4056 }
4057 /*
4058 * Since this is the "master", we need to set up the
4059 * other three controller chips' pointers to this structure
4060 * for later use in the muxsel routine.
4061 */
4062 if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3))
4063 return;
4064 master[btv->c.nr-1] = btv;
4065 master[btv->c.nr] = btv;
4066 master[btv->c.nr+1] = btv;
4067 master[btv->c.nr+2] = btv;
4068}
4069
4070// The Grandtec X-Guard framegrabber card uses two Dual 4-channel
4071// video multiplexers to provide up to 16 video inputs. These
4072// multiplexers are controlled by the lower 8 GPIO pins of the
4073// bt878. The multiplexers probably Pericom PI5V331Q or similar.
4074
4075// xxx0 is pin xxx of multiplexer U5,
4076// yyy1 is pin yyy of multiplexer U2
4077
4078#define ENA0 0x01
4079#define ENB0 0x02
4080#define ENA1 0x04
4081#define ENB1 0x08
4082
4083#define IN10 0x10
4084#define IN00 0x20
4085#define IN11 0x40
4086#define IN01 0x80
4087
4088static void xguard_muxsel(struct bttv *btv, unsigned int input)
4089{
4090 static const int masks[] = {
4091 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4092 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4093 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4094 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4095 };
4096 gpio_write(masks[input%16]);
4097}
4098static void picolo_tetra_init(struct bttv *btv)
4099{
4100 /*This is the video input redirection fonctionality : I DID NOT USED IT. */
4101 btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
4102 btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/
4103}
4104static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
4105{
4106
4107 dprintk (KERN_DEBUG "bttv%d : picolo_tetra_muxsel => input = %d\n",btv->c.nr,input);
4108 /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/
4109 /*GPIO[20]&GPIO[21] used to choose the right input*/
4110 btwrite (input<<20,BT848_GPIO_DATA);
4111
4112}
4113
4114/*
4115 * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>]
4116 *
4117 * The IVC120G security card has 4 i2c controlled TDA8540 matrix
4118 * swichers to provide 16 channels to MUX0. The TDA8540's have
4119 * 4 indepedant outputs and as such the IVC120G also has the
4120 * optional "Monitor Out" bus. This allows the card to be looking
4121 * at one input while the monitor is looking at another.
4122 *
4123 * Since I've couldn't be bothered figuring out how to add an
4124 * independant muxsel for the monitor bus, I've just set it to
4125 * whatever the card is looking at.
4126 *
4127 * OUT0 of the TDA8540's is connected to MUX0 (0x03)
4128 * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C)
4129 *
4130 * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03)
4131 * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03)
4132 * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03)
4133 * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03)
4134 *
4135 */
4136
4137/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */
4138#define I2C_TDA8540 0x90
4139#define I2C_TDA8540_ALT1 0x92
4140#define I2C_TDA8540_ALT2 0x94
4141#define I2C_TDA8540_ALT3 0x96
4142#define I2C_TDA8540_ALT4 0x98
4143#define I2C_TDA8540_ALT5 0x9a
4144#define I2C_TDA8540_ALT6 0x9c
4145
4146static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4147{
4148 // Simple maths
4149 int key = input % 4;
4150 int matrix = input / 4;
4151
4152 dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
4153 btv->c.nr, input, matrix, key);
4154
4155 // Handles the input selection on the TDA8540's
4156 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
4157 ((matrix == 3) ? (key | key << 2) : 0x00), 1);
4158 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
4159 ((matrix == 0) ? (key | key << 2) : 0x00), 1);
4160 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x00,
4161 ((matrix == 1) ? (key | key << 2) : 0x00), 1);
4162 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
4163 ((matrix == 2) ? (key | key << 2) : 0x00), 1);
4164
4165 // Handles the output enables on the TDA8540's
4166 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
4167 ((matrix == 3) ? 0x03 : 0x00), 1); // 13 - 16
4168 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
4169 ((matrix == 0) ? 0x03 : 0x00), 1); // 1-4
4170 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
4171 ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8
4172 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
4173 ((matrix == 2) ? 0x03 : 0x00), 1); // 9-12
4174
4175 // Selects MUX0 for input on the 878
4176 btaor((0)<<5, ~(3<<5), BT848_IFORM);
4177}
4178
4179
4180/* PXC200 muxsel helper
4181 * luke@syseng.anu.edu.au
4182 * another transplant
4183 * from Alessandro Rubini (rubini@linux.it)
4184 *
4185 * There are 4 kinds of cards:
4186 * PXC200L which is bt848
4187 * PXC200F which is bt848 with PIC controlling mux
4188 * PXC200AL which is bt878
4189 * PXC200AF which is bt878 with PIC controlling mux
4190 */
4191#define PX_CFG_PXC200F 0x01
4192#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */
4193#define PX_I2C_PIC 0x0f
4194#define PX_PXC200A_CARDID 0x200a1295
4195#define PX_I2C_CMD_CFG 0x00
4196
4197static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4198{
4199 int rc;
4200 long mux;
4201 int bitmask;
4202 unsigned char buf[2];
4203
4204 /* Read PIC config to determine if this is a PXC200F */
4205 /* PX_I2C_CMD_CFG*/
4206 buf[0]=0;
4207 buf[1]=0;
4208 rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1);
4209 if (rc) {
4210 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: pic cfg write failed:%d\n", btv->c.nr,rc);
4211 /* not PXC ? do nothing */
4212 return;
4213 }
4214
4215 rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL);
4216 if (!(rc & PX_CFG_PXC200F)) {
4217 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: not PXC200F rc:%d \n", btv->c.nr,rc);
4218 return;
4219 }
4220
4221
4222 /* The multiplexer in the 200F is handled by the GPIO port */
4223 /* get correct mapping between inputs */
4224 /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */
4225 /* ** not needed!? */
4226 mux = input;
4227
4228 /* make sure output pins are enabled */
4229 /* bitmask=0x30f; */
4230 bitmask=0x302;
4231 /* check whether we have a PXC200A */
4232 if (btv->cardid == PX_PXC200A_CARDID) {
4233 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4234 bitmask |= 7<<4; /* the DAC */
4235 }
4236 btwrite(bitmask, BT848_GPIO_OUT_EN);
4237
4238 bitmask = btread(BT848_GPIO_DATA);
4239 if (btv->cardid == PX_PXC200A_CARDID)
4240 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4241 else /* older device */
4242 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
4243 btwrite(bitmask,BT848_GPIO_DATA);
4244
4245 /*
4246 * Was "to be safe, set the bt848 to input 0"
4247 * Actually, since it's ok at load time, better not messing
4248 * with these bits (on PXC200AF you need to set mux 2 here)
4249 *
4250 * needed because bttv-driver sets mux before calling this function
4251 */
4252 if (btv->cardid == PX_PXC200A_CARDID)
4253 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4254 else /* older device */
4255 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
4256
4257 printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
4258}
4259
4260/* ----------------------------------------------------------------------- */
4261/* motherboard chipset specific stuff */
4262
4263void __devinit bttv_check_chipset(void)
4264{
4265 int pcipci_fail = 0;
4266 struct pci_dev *dev = NULL;
4267
4268 if (pci_pci_problems & PCIPCI_FAIL)
4269 pcipci_fail = 1;
4270 if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
4271 triton1 = 1;
4272 if (pci_pci_problems & PCIPCI_VSFX)
4273 vsfx = 1;
4274#ifdef PCIPCI_ALIMAGIK
4275 if (pci_pci_problems & PCIPCI_ALIMAGIK)
4276 latency = 0x0A;
4277#endif
4278
4279#if 0
4280 /* print which chipset we have */
4281 while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
4282 printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
4283#endif
4284
4285 /* print warnings about any quirks found */
4286 if (triton1)
4287 printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n");
4288 if (vsfx)
4289 printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
4290 if (pcipci_fail) {
4291 printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
4292 if (UNSET == no_overlay) {
4293 printk(KERN_WARNING "bttv: going to disable overlay.\n");
4294 no_overlay = 1;
4295 }
4296 }
4297 if (UNSET != latency)
4298 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4299
4300 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4301 PCI_DEVICE_ID_INTEL_82441, dev))) {
4302 unsigned char b;
4303 pci_read_config_byte(dev, 0x53, &b);
4304 if (bttv_debug)
4305 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
4306 "bufcon=0x%02x\n",b);
4307 }
4308}
4309
4310int __devinit bttv_handle_chipset(struct bttv *btv)
4311{
4312 unsigned char command;
4313
4314 if (!triton1 && !vsfx && UNSET == latency)
4315 return 0;
4316
4317 if (bttv_verbose) {
4318 if (triton1)
4319 printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->c.nr);
4320 if (vsfx && btv->id >= 878)
4321 printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->c.nr);
4322 if (UNSET != latency)
4323 printk(KERN_INFO "bttv%d: setting pci timer to %d\n",
4324 btv->c.nr,latency);
4325 }
4326
4327 if (btv->id < 878) {
4328 /* bt848 (mis)uses a bit in the irq mask for etbf */
4329 if (triton1)
4330 btv->triton1 = BT848_INT_ETBF;
4331 } else {
4332 /* bt878 has a bit in the pci config space for it */
4333 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4334 if (triton1)
4335 command |= BT878_EN_TBFX;
4336 if (vsfx)
4337 command |= BT878_EN_VSFX;
4338 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4339 }
4340 if (UNSET != latency)
4341 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4342 return 0;
4343}
4344
4345
4346/*
4347 * Local variables:
4348 * c-basic-offset: 8
4349 * End:
4350 */
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
new file mode 100644
index 000000000000..c13f222fe6bd
--- /dev/null
+++ b/drivers/media/video/bttv-driver.c
@@ -0,0 +1,4116 @@
1/*
2 $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5
6 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
7 & Marcus Metzler <mocm@thp.uni-koeln.de>
8 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
9
10 some v4l2 code lines are taken from Justin's bttv2 driver which is
11 (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/delay.h>
32#include <linux/errno.h>
33#include <linux/fs.h>
34#include <linux/kernel.h>
35#include <linux/sched.h>
36#include <linux/interrupt.h>
37#include <linux/kdev_t.h>
38
39#include <asm/io.h>
40#include <asm/byteorder.h>
41
42#include "bttvp.h"
43
44unsigned int bttv_num; /* number of Bt848s in use */
45struct bttv bttvs[BTTV_MAX];
46
47unsigned int bttv_debug = 0;
48unsigned int bttv_verbose = 1;
49unsigned int bttv_gpio = 0;
50
51/* config variables */
52#ifdef __BIG_ENDIAN
53static unsigned int bigendian=1;
54#else
55static unsigned int bigendian=0;
56#endif
57static unsigned int radio[BTTV_MAX];
58static unsigned int irq_debug = 0;
59static unsigned int gbuffers = 8;
60static unsigned int gbufsize = 0x208000;
61
62static int video_nr = -1;
63static int radio_nr = -1;
64static int vbi_nr = -1;
65static int debug_latency = 0;
66
67static unsigned int fdsr = 0;
68
69/* options */
70static unsigned int combfilter = 0;
71static unsigned int lumafilter = 0;
72static unsigned int automute = 1;
73static unsigned int chroma_agc = 0;
74static unsigned int adc_crush = 1;
75static unsigned int whitecrush_upper = 0xCF;
76static unsigned int whitecrush_lower = 0x7F;
77static unsigned int vcr_hack = 0;
78static unsigned int irq_iswitch = 0;
79
80/* API features (turn on/off stuff for testing) */
81static unsigned int v4l2 = 1;
82
83
84/* insmod args */
85module_param(bttv_verbose, int, 0644);
86module_param(bttv_gpio, int, 0644);
87module_param(bttv_debug, int, 0644);
88module_param(irq_debug, int, 0644);
89module_param(debug_latency, int, 0644);
90
91module_param(fdsr, int, 0444);
92module_param(video_nr, int, 0444);
93module_param(radio_nr, int, 0444);
94module_param(vbi_nr, int, 0444);
95module_param(gbuffers, int, 0444);
96module_param(gbufsize, int, 0444);
97
98module_param(v4l2, int, 0644);
99module_param(bigendian, int, 0644);
100module_param(irq_iswitch, int, 0644);
101module_param(combfilter, int, 0444);
102module_param(lumafilter, int, 0444);
103module_param(automute, int, 0444);
104module_param(chroma_agc, int, 0444);
105module_param(adc_crush, int, 0444);
106module_param(whitecrush_upper, int, 0444);
107module_param(whitecrush_lower, int, 0444);
108module_param(vcr_hack, int, 0444);
109
110module_param_array(radio, int, NULL, 0444);
111
112MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
113MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
114MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
115MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
116MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
117MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
118MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
119MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
120MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
121MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
122MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
123MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");
124MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
125MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
126MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
127
128MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
129MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
130MODULE_LICENSE("GPL");
131
132/* ----------------------------------------------------------------------- */
133/* sysfs */
134
135static ssize_t show_card(struct class_device *cd, char *buf)
136{
137 struct video_device *vfd = to_video_device(cd);
138 struct bttv *btv = dev_get_drvdata(vfd->dev);
139 return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
140}
141static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
142
143/* ----------------------------------------------------------------------- */
144/* static data */
145
146/* special timing tables from conexant... */
147static u8 SRAM_Table[][60] =
148{
149 /* PAL digital input over GPIO[7:0] */
150 {
151 45, // 45 bytes following
152 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
153 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
154 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
155 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
156 0x37,0x00,0xAF,0x21,0x00
157 },
158 /* NTSC digital input over GPIO[7:0] */
159 {
160 51, // 51 bytes following
161 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
162 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
163 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
164 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
165 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
166 0x00,
167 },
168 // TGB_NTSC392 // quartzsight
169 // This table has been modified to be used for Fusion Rev D
170 {
171 0x2A, // size of table = 42
172 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
173 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
174 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
175 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
176 0x20, 0x00
177 }
178};
179
180const struct bttv_tvnorm bttv_tvnorms[] = {
181 /* PAL-BDGHI */
182 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
183 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
184 {
185 .v4l2_id = V4L2_STD_PAL,
186 .name = "PAL",
187 .Fsc = 35468950,
188 .swidth = 924,
189 .sheight = 576,
190 .totalwidth = 1135,
191 .adelay = 0x7f,
192 .bdelay = 0x72,
193 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
194 .scaledtwidth = 1135,
195 .hdelayx1 = 186,
196 .hactivex1 = 924,
197 .vdelay = 0x20,
198 .vbipack = 255,
199 .sram = 0,
200 },{
201 .v4l2_id = V4L2_STD_NTSC_M,
202 .name = "NTSC",
203 .Fsc = 28636363,
204 .swidth = 768,
205 .sheight = 480,
206 .totalwidth = 910,
207 .adelay = 0x68,
208 .bdelay = 0x5d,
209 .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
210 .scaledtwidth = 910,
211 .hdelayx1 = 128,
212 .hactivex1 = 910,
213 .vdelay = 0x1a,
214 .vbipack = 144,
215 .sram = 1,
216 },{
217 .v4l2_id = V4L2_STD_SECAM,
218 .name = "SECAM",
219 .Fsc = 35468950,
220 .swidth = 924,
221 .sheight = 576,
222 .totalwidth = 1135,
223 .adelay = 0x7f,
224 .bdelay = 0xb0,
225 .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
226 .scaledtwidth = 1135,
227 .hdelayx1 = 186,
228 .hactivex1 = 922,
229 .vdelay = 0x20,
230 .vbipack = 255,
231 .sram = 0, /* like PAL, correct? */
232 },{
233 .v4l2_id = V4L2_STD_PAL_Nc,
234 .name = "PAL-Nc",
235 .Fsc = 28636363,
236 .swidth = 640,
237 .sheight = 576,
238 .totalwidth = 910,
239 .adelay = 0x68,
240 .bdelay = 0x5d,
241 .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
242 .scaledtwidth = 780,
243 .hdelayx1 = 130,
244 .hactivex1 = 734,
245 .vdelay = 0x1a,
246 .vbipack = 144,
247 .sram = -1,
248 },{
249 .v4l2_id = V4L2_STD_PAL_M,
250 .name = "PAL-M",
251 .Fsc = 28636363,
252 .swidth = 640,
253 .sheight = 480,
254 .totalwidth = 910,
255 .adelay = 0x68,
256 .bdelay = 0x5d,
257 .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
258 .scaledtwidth = 780,
259 .hdelayx1 = 135,
260 .hactivex1 = 754,
261 .vdelay = 0x1a,
262 .vbipack = 144,
263 .sram = -1,
264 },{
265 .v4l2_id = V4L2_STD_PAL_N,
266 .name = "PAL-N",
267 .Fsc = 35468950,
268 .swidth = 768,
269 .sheight = 576,
270 .totalwidth = 1135,
271 .adelay = 0x7f,
272 .bdelay = 0x72,
273 .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
274 .scaledtwidth = 944,
275 .hdelayx1 = 186,
276 .hactivex1 = 922,
277 .vdelay = 0x20,
278 .vbipack = 144,
279 .sram = -1,
280 },{
281 .v4l2_id = V4L2_STD_NTSC_M_JP,
282 .name = "NTSC-JP",
283 .Fsc = 28636363,
284 .swidth = 640,
285 .sheight = 480,
286 .totalwidth = 910,
287 .adelay = 0x68,
288 .bdelay = 0x5d,
289 .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
290 .scaledtwidth = 780,
291 .hdelayx1 = 135,
292 .hactivex1 = 754,
293 .vdelay = 0x16,
294 .vbipack = 144,
295 .sram = -1,
296 },{
297 /* that one hopefully works with the strange timing
298 * which video recorders produce when playing a NTSC
299 * tape on a PAL TV ... */
300 .v4l2_id = V4L2_STD_PAL_60,
301 .name = "PAL-60",
302 .Fsc = 35468950,
303 .swidth = 924,
304 .sheight = 480,
305 .totalwidth = 1135,
306 .adelay = 0x7f,
307 .bdelay = 0x72,
308 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
309 .scaledtwidth = 1135,
310 .hdelayx1 = 186,
311 .hactivex1 = 924,
312 .vdelay = 0x1a,
313 .vbipack = 255,
314 .vtotal = 524,
315 .sram = -1,
316 }
317};
318static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
319
320/* ----------------------------------------------------------------------- */
321/* bttv format list
322 packed pixel formats must come first */
323static const struct bttv_format bttv_formats[] = {
324 {
325 .name = "8 bpp, gray",
326 .palette = VIDEO_PALETTE_GREY,
327 .fourcc = V4L2_PIX_FMT_GREY,
328 .btformat = BT848_COLOR_FMT_Y8,
329 .depth = 8,
330 .flags = FORMAT_FLAGS_PACKED,
331 },{
332 .name = "8 bpp, dithered color",
333 .palette = VIDEO_PALETTE_HI240,
334 .fourcc = V4L2_PIX_FMT_HI240,
335 .btformat = BT848_COLOR_FMT_RGB8,
336 .depth = 8,
337 .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
338 },{
339 .name = "15 bpp RGB, le",
340 .palette = VIDEO_PALETTE_RGB555,
341 .fourcc = V4L2_PIX_FMT_RGB555,
342 .btformat = BT848_COLOR_FMT_RGB15,
343 .depth = 16,
344 .flags = FORMAT_FLAGS_PACKED,
345 },{
346 .name = "15 bpp RGB, be",
347 .palette = -1,
348 .fourcc = V4L2_PIX_FMT_RGB555X,
349 .btformat = BT848_COLOR_FMT_RGB15,
350 .btswap = 0x03, /* byteswap */
351 .depth = 16,
352 .flags = FORMAT_FLAGS_PACKED,
353 },{
354 .name = "16 bpp RGB, le",
355 .palette = VIDEO_PALETTE_RGB565,
356 .fourcc = V4L2_PIX_FMT_RGB565,
357 .btformat = BT848_COLOR_FMT_RGB16,
358 .depth = 16,
359 .flags = FORMAT_FLAGS_PACKED,
360 },{
361 .name = "16 bpp RGB, be",
362 .palette = -1,
363 .fourcc = V4L2_PIX_FMT_RGB565X,
364 .btformat = BT848_COLOR_FMT_RGB16,
365 .btswap = 0x03, /* byteswap */
366 .depth = 16,
367 .flags = FORMAT_FLAGS_PACKED,
368 },{
369 .name = "24 bpp RGB, le",
370 .palette = VIDEO_PALETTE_RGB24,
371 .fourcc = V4L2_PIX_FMT_BGR24,
372 .btformat = BT848_COLOR_FMT_RGB24,
373 .depth = 24,
374 .flags = FORMAT_FLAGS_PACKED,
375 },{
376 .name = "32 bpp RGB, le",
377 .palette = VIDEO_PALETTE_RGB32,
378 .fourcc = V4L2_PIX_FMT_BGR32,
379 .btformat = BT848_COLOR_FMT_RGB32,
380 .depth = 32,
381 .flags = FORMAT_FLAGS_PACKED,
382 },{
383 .name = "32 bpp RGB, be",
384 .palette = -1,
385 .fourcc = V4L2_PIX_FMT_RGB32,
386 .btformat = BT848_COLOR_FMT_RGB32,
387 .btswap = 0x0f, /* byte+word swap */
388 .depth = 32,
389 .flags = FORMAT_FLAGS_PACKED,
390 },{
391 .name = "4:2:2, packed, YUYV",
392 .palette = VIDEO_PALETTE_YUV422,
393 .fourcc = V4L2_PIX_FMT_YUYV,
394 .btformat = BT848_COLOR_FMT_YUY2,
395 .depth = 16,
396 .flags = FORMAT_FLAGS_PACKED,
397 },{
398 .name = "4:2:2, packed, YUYV",
399 .palette = VIDEO_PALETTE_YUYV,
400 .fourcc = V4L2_PIX_FMT_YUYV,
401 .btformat = BT848_COLOR_FMT_YUY2,
402 .depth = 16,
403 .flags = FORMAT_FLAGS_PACKED,
404 },{
405 .name = "4:2:2, packed, UYVY",
406 .palette = VIDEO_PALETTE_UYVY,
407 .fourcc = V4L2_PIX_FMT_UYVY,
408 .btformat = BT848_COLOR_FMT_YUY2,
409 .btswap = 0x03, /* byteswap */
410 .depth = 16,
411 .flags = FORMAT_FLAGS_PACKED,
412 },{
413 .name = "4:2:2, planar, Y-Cb-Cr",
414 .palette = VIDEO_PALETTE_YUV422P,
415 .fourcc = V4L2_PIX_FMT_YUV422P,
416 .btformat = BT848_COLOR_FMT_YCrCb422,
417 .depth = 16,
418 .flags = FORMAT_FLAGS_PLANAR,
419 .hshift = 1,
420 .vshift = 0,
421 },{
422 .name = "4:2:0, planar, Y-Cb-Cr",
423 .palette = VIDEO_PALETTE_YUV420P,
424 .fourcc = V4L2_PIX_FMT_YUV420,
425 .btformat = BT848_COLOR_FMT_YCrCb422,
426 .depth = 12,
427 .flags = FORMAT_FLAGS_PLANAR,
428 .hshift = 1,
429 .vshift = 1,
430 },{
431 .name = "4:2:0, planar, Y-Cr-Cb",
432 .palette = -1,
433 .fourcc = V4L2_PIX_FMT_YVU420,
434 .btformat = BT848_COLOR_FMT_YCrCb422,
435 .depth = 12,
436 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
437 .hshift = 1,
438 .vshift = 1,
439 },{
440 .name = "4:1:1, planar, Y-Cb-Cr",
441 .palette = VIDEO_PALETTE_YUV411P,
442 .fourcc = V4L2_PIX_FMT_YUV411P,
443 .btformat = BT848_COLOR_FMT_YCrCb411,
444 .depth = 12,
445 .flags = FORMAT_FLAGS_PLANAR,
446 .hshift = 2,
447 .vshift = 0,
448 },{
449 .name = "4:1:0, planar, Y-Cb-Cr",
450 .palette = VIDEO_PALETTE_YUV410P,
451 .fourcc = V4L2_PIX_FMT_YUV410,
452 .btformat = BT848_COLOR_FMT_YCrCb411,
453 .depth = 9,
454 .flags = FORMAT_FLAGS_PLANAR,
455 .hshift = 2,
456 .vshift = 2,
457 },{
458 .name = "4:1:0, planar, Y-Cr-Cb",
459 .palette = -1,
460 .fourcc = V4L2_PIX_FMT_YVU410,
461 .btformat = BT848_COLOR_FMT_YCrCb411,
462 .depth = 9,
463 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
464 .hshift = 2,
465 .vshift = 2,
466 },{
467 .name = "raw scanlines",
468 .palette = VIDEO_PALETTE_RAW,
469 .fourcc = -1,
470 .btformat = BT848_COLOR_FMT_RAW,
471 .depth = 8,
472 .flags = FORMAT_FLAGS_RAW,
473 }
474};
475static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
476
477/* ----------------------------------------------------------------------- */
478
479#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0)
480#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1)
481#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2)
482#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3)
483#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4)
484#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
485#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
486#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
487#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8)
488
489static const struct v4l2_queryctrl no_ctl = {
490 .name = "42",
491 .flags = V4L2_CTRL_FLAG_DISABLED,
492};
493static const struct v4l2_queryctrl bttv_ctls[] = {
494 /* --- video --- */
495 {
496 .id = V4L2_CID_BRIGHTNESS,
497 .name = "Brightness",
498 .minimum = 0,
499 .maximum = 65535,
500 .step = 256,
501 .default_value = 32768,
502 .type = V4L2_CTRL_TYPE_INTEGER,
503 },{
504 .id = V4L2_CID_CONTRAST,
505 .name = "Contrast",
506 .minimum = 0,
507 .maximum = 65535,
508 .step = 128,
509 .default_value = 32768,
510 .type = V4L2_CTRL_TYPE_INTEGER,
511 },{
512 .id = V4L2_CID_SATURATION,
513 .name = "Saturation",
514 .minimum = 0,
515 .maximum = 65535,
516 .step = 128,
517 .default_value = 32768,
518 .type = V4L2_CTRL_TYPE_INTEGER,
519 },{
520 .id = V4L2_CID_HUE,
521 .name = "Hue",
522 .minimum = 0,
523 .maximum = 65535,
524 .step = 256,
525 .default_value = 32768,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 },
528 /* --- audio --- */
529 {
530 .id = V4L2_CID_AUDIO_MUTE,
531 .name = "Mute",
532 .minimum = 0,
533 .maximum = 1,
534 .type = V4L2_CTRL_TYPE_BOOLEAN,
535 },{
536 .id = V4L2_CID_AUDIO_VOLUME,
537 .name = "Volume",
538 .minimum = 0,
539 .maximum = 65535,
540 .step = 65535/100,
541 .default_value = 65535,
542 .type = V4L2_CTRL_TYPE_INTEGER,
543 },{
544 .id = V4L2_CID_AUDIO_BALANCE,
545 .name = "Balance",
546 .minimum = 0,
547 .maximum = 65535,
548 .step = 65535/100,
549 .default_value = 32768,
550 .type = V4L2_CTRL_TYPE_INTEGER,
551 },{
552 .id = V4L2_CID_AUDIO_BASS,
553 .name = "Bass",
554 .minimum = 0,
555 .maximum = 65535,
556 .step = 65535/100,
557 .default_value = 32768,
558 .type = V4L2_CTRL_TYPE_INTEGER,
559 },{
560 .id = V4L2_CID_AUDIO_TREBLE,
561 .name = "Treble",
562 .minimum = 0,
563 .maximum = 65535,
564 .step = 65535/100,
565 .default_value = 32768,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 },
568 /* --- private --- */
569 {
570 .id = V4L2_CID_PRIVATE_CHROMA_AGC,
571 .name = "chroma agc",
572 .minimum = 0,
573 .maximum = 1,
574 .type = V4L2_CTRL_TYPE_BOOLEAN,
575 },{
576 .id = V4L2_CID_PRIVATE_COMBFILTER,
577 .name = "combfilter",
578 .minimum = 0,
579 .maximum = 1,
580 .type = V4L2_CTRL_TYPE_BOOLEAN,
581 },{
582 .id = V4L2_CID_PRIVATE_AUTOMUTE,
583 .name = "automute",
584 .minimum = 0,
585 .maximum = 1,
586 .type = V4L2_CTRL_TYPE_BOOLEAN,
587 },{
588 .id = V4L2_CID_PRIVATE_LUMAFILTER,
589 .name = "luma decimation filter",
590 .minimum = 0,
591 .maximum = 1,
592 .type = V4L2_CTRL_TYPE_BOOLEAN,
593 },{
594 .id = V4L2_CID_PRIVATE_AGC_CRUSH,
595 .name = "agc crush",
596 .minimum = 0,
597 .maximum = 1,
598 .type = V4L2_CTRL_TYPE_BOOLEAN,
599 },{
600 .id = V4L2_CID_PRIVATE_VCR_HACK,
601 .name = "vcr hack",
602 .minimum = 0,
603 .maximum = 1,
604 .type = V4L2_CTRL_TYPE_BOOLEAN,
605 },{
606 .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER,
607 .name = "whitecrush upper",
608 .minimum = 0,
609 .maximum = 255,
610 .step = 1,
611 .default_value = 0xCF,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 },{
614 .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER,
615 .name = "whitecrush lower",
616 .minimum = 0,
617 .maximum = 255,
618 .step = 1,
619 .default_value = 0x7F,
620 .type = V4L2_CTRL_TYPE_INTEGER,
621 }
622
623};
624static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
625
626/* ----------------------------------------------------------------------- */
627/* resource management */
628
629static
630int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit)
631{
632 if (fh->resources & bit)
633 /* have it already allocated */
634 return 1;
635
636 /* is it free? */
637 down(&btv->reslock);
638 if (btv->resources & bit) {
639 /* no, someone else uses it */
640 up(&btv->reslock);
641 return 0;
642 }
643 /* it's free, grab it */
644 fh->resources |= bit;
645 btv->resources |= bit;
646 up(&btv->reslock);
647 return 1;
648}
649
650static
651int check_btres(struct bttv_fh *fh, int bit)
652{
653 return (fh->resources & bit);
654}
655
656static
657int locked_btres(struct bttv *btv, int bit)
658{
659 return (btv->resources & bit);
660}
661
662static
663void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
664{
665#if 1 /* DEBUG */
666 if ((fh->resources & bits) != bits) {
667 /* trying to free ressources not allocated by us ... */
668 printk("bttv: BUG! (btres)\n");
669 }
670#endif
671 down(&btv->reslock);
672 fh->resources &= ~bits;
673 btv->resources &= ~bits;
674 up(&btv->reslock);
675}
676
677/* ----------------------------------------------------------------------- */
678/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */
679
680/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
681 PLL_X = Reference pre-divider (0=1, 1=2)
682 PLL_C = Post divider (0=6, 1=4)
683 PLL_I = Integer input
684 PLL_F = Fractional input
685
686 F_input = 28.636363 MHz:
687 PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
688*/
689
690static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
691{
692 unsigned char fl, fh, fi;
693
694 /* prevent overflows */
695 fin/=4;
696 fout/=4;
697
698 fout*=12;
699 fi=fout/fin;
700
701 fout=(fout%fin)*256;
702 fh=fout/fin;
703
704 fout=(fout%fin)*256;
705 fl=fout/fin;
706
707 btwrite(fl, BT848_PLL_F_LO);
708 btwrite(fh, BT848_PLL_F_HI);
709 btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
710}
711
712static void set_pll(struct bttv *btv)
713{
714 int i;
715
716 if (!btv->pll.pll_crystal)
717 return;
718
719 if (btv->pll.pll_ofreq == btv->pll.pll_current) {
720 dprintk("bttv%d: PLL: no change required\n",btv->c.nr);
721 return;
722 }
723
724 if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
725 /* no PLL needed */
726 if (btv->pll.pll_current == 0)
727 return;
728 vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
729 btv->c.nr,btv->pll.pll_ifreq);
730 btwrite(0x00,BT848_TGCTRL);
731 btwrite(0x00,BT848_PLL_XCI);
732 btv->pll.pll_current = 0;
733 return;
734 }
735
736 vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
737 btv->pll.pll_ifreq, btv->pll.pll_ofreq);
738 set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
739
740 for (i=0; i<10; i++) {
741 /* Let other people run while the PLL stabilizes */
742 vprintk(".");
743 msleep(10);
744
745 if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
746 btwrite(0,BT848_DSTATUS);
747 } else {
748 btwrite(0x08,BT848_TGCTRL);
749 btv->pll.pll_current = btv->pll.pll_ofreq;
750 vprintk(" ok\n");
751 return;
752 }
753 }
754 btv->pll.pll_current = -1;
755 vprintk("failed\n");
756 return;
757}
758
759/* used to switch between the bt848's analog/digital video capture modes */
760static void bt848A_set_timing(struct bttv *btv)
761{
762 int i, len;
763 int table_idx = bttv_tvnorms[btv->tvnorm].sram;
764 int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
765
766 if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
767 dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
768 btv->c.nr,table_idx);
769
770 /* timing change...reset timing generator address */
771 btwrite(0x00, BT848_TGCTRL);
772 btwrite(0x02, BT848_TGCTRL);
773 btwrite(0x00, BT848_TGCTRL);
774
775 len=SRAM_Table[table_idx][0];
776 for(i = 1; i <= len; i++)
777 btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
778 btv->pll.pll_ofreq = 27000000;
779
780 set_pll(btv);
781 btwrite(0x11, BT848_TGCTRL);
782 btwrite(0x41, BT848_DVSIF);
783 } else {
784 btv->pll.pll_ofreq = fsc;
785 set_pll(btv);
786 btwrite(0x0, BT848_DVSIF);
787 }
788}
789
790/* ----------------------------------------------------------------------- */
791
792static void bt848_bright(struct bttv *btv, int bright)
793{
794 int value;
795
796 // printk("bttv: set bright: %d\n",bright); // DEBUG
797 btv->bright = bright;
798
799 /* We want -128 to 127 we get 0-65535 */
800 value = (bright >> 8) - 128;
801 btwrite(value & 0xff, BT848_BRIGHT);
802}
803
804static void bt848_hue(struct bttv *btv, int hue)
805{
806 int value;
807
808 btv->hue = hue;
809
810 /* -128 to 127 */
811 value = (hue >> 8) - 128;
812 btwrite(value & 0xff, BT848_HUE);
813}
814
815static void bt848_contrast(struct bttv *btv, int cont)
816{
817 int value,hibit;
818
819 btv->contrast = cont;
820
821 /* 0-511 */
822 value = (cont >> 7);
823 hibit = (value >> 6) & 4;
824 btwrite(value & 0xff, BT848_CONTRAST_LO);
825 btaor(hibit, ~4, BT848_E_CONTROL);
826 btaor(hibit, ~4, BT848_O_CONTROL);
827}
828
829static void bt848_sat(struct bttv *btv, int color)
830{
831 int val_u,val_v,hibits;
832
833 btv->saturation = color;
834
835 /* 0-511 for the color */
836 val_u = color >> 7;
837 val_v = ((color>>7)*180L)/254;
838 hibits = (val_u >> 7) & 2;
839 hibits |= (val_v >> 8) & 1;
840 btwrite(val_u & 0xff, BT848_SAT_U_LO);
841 btwrite(val_v & 0xff, BT848_SAT_V_LO);
842 btaor(hibits, ~3, BT848_E_CONTROL);
843 btaor(hibits, ~3, BT848_O_CONTROL);
844}
845
846/* ----------------------------------------------------------------------- */
847
848static int
849video_mux(struct bttv *btv, unsigned int input)
850{
851 int mux,mask2;
852
853 if (input >= bttv_tvcards[btv->c.type].video_inputs)
854 return -EINVAL;
855
856 /* needed by RemoteVideo MX */
857 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
858 if (mask2)
859 gpio_inout(mask2,mask2);
860
861 if (input == btv->svhs) {
862 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
863 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
864 } else {
865 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
866 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
867 }
868 mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
869 btaor(mux<<5, ~(3<<5), BT848_IFORM);
870 dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
871 btv->c.nr,input,mux);
872
873 /* card specific hook */
874 if(bttv_tvcards[btv->c.type].muxsel_hook)
875 bttv_tvcards[btv->c.type].muxsel_hook (btv, input);
876 return 0;
877}
878
879static char *audio_modes[] = {
880 "audio: tuner", "audio: radio", "audio: extern",
881 "audio: intern", "audio: off"
882};
883
884static int
885audio_mux(struct bttv *btv, int mode)
886{
887 int val,mux,i2c_mux,signal;
888
889 gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
890 bttv_tvcards[btv->c.type].gpiomask);
891 signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
892
893 switch (mode) {
894 case AUDIO_MUTE:
895 btv->audio |= AUDIO_MUTE;
896 break;
897 case AUDIO_UNMUTE:
898 btv->audio &= ~AUDIO_MUTE;
899 break;
900 case AUDIO_TUNER:
901 case AUDIO_RADIO:
902 case AUDIO_EXTERN:
903 case AUDIO_INTERN:
904 btv->audio &= AUDIO_MUTE;
905 btv->audio |= mode;
906 }
907 i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
908 if (btv->opt_automute && !signal && !btv->radio_user)
909 mux = AUDIO_OFF;
910#if 0
911 printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
912 btv->c.nr, mode, btv->audio, signal ? "yes" : "no",
913 mux, i2c_mux, in_interrupt() ? "yes" : "no");
914#endif
915
916 val = bttv_tvcards[btv->c.type].audiomux[mux];
917 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
918 if (bttv_gpio)
919 bttv_gpio_tracking(btv,audio_modes[mux]);
920 if (!in_interrupt())
921 bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
922 return 0;
923}
924
925static void
926i2c_vidiocschan(struct bttv *btv)
927{
928 struct video_channel c;
929
930 memset(&c,0,sizeof(c));
931 c.norm = btv->tvnorm;
932 c.channel = btv->input;
933 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
934 if (btv->c.type == BTTV_VOODOOTV_FM)
935 bttv_tda9880_setnorm(btv,c.norm);
936}
937
938static int
939set_tvnorm(struct bttv *btv, unsigned int norm)
940{
941 const struct bttv_tvnorm *tvnorm;
942
943 if (norm < 0 || norm >= BTTV_TVNORMS)
944 return -EINVAL;
945
946 btv->tvnorm = norm;
947 tvnorm = &bttv_tvnorms[norm];
948
949 btwrite(tvnorm->adelay, BT848_ADELAY);
950 btwrite(tvnorm->bdelay, BT848_BDELAY);
951 btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH),
952 BT848_IFORM);
953 btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
954 btwrite(1, BT848_VBI_PACK_DEL);
955 bt848A_set_timing(btv);
956
957 switch (btv->c.type) {
958 case BTTV_VOODOOTV_FM:
959 bttv_tda9880_setnorm(btv,norm);
960 break;
961#if 0
962 case BTTV_OSPREY540:
963 osprey_540_set_norm(btv,norm);
964 break;
965#endif
966 }
967 return 0;
968}
969
970static void
971set_input(struct bttv *btv, unsigned int input)
972{
973 unsigned long flags;
974
975 btv->input = input;
976 if (irq_iswitch) {
977 spin_lock_irqsave(&btv->s_lock,flags);
978 if (btv->curr.frame_irq) {
979 /* active capture -> delayed input switch */
980 btv->new_input = input;
981 } else {
982 video_mux(btv,input);
983 }
984 spin_unlock_irqrestore(&btv->s_lock,flags);
985 } else {
986 video_mux(btv,input);
987 }
988 audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
989 AUDIO_TUNER : AUDIO_EXTERN));
990 set_tvnorm(btv,btv->tvnorm);
991 i2c_vidiocschan(btv);
992}
993
994static void init_irqreg(struct bttv *btv)
995{
996 /* clear status */
997 btwrite(0xfffffUL, BT848_INT_STAT);
998
999 if (bttv_tvcards[btv->c.type].no_video) {
1000 /* i2c only */
1001 btwrite(BT848_INT_I2CDONE,
1002 BT848_INT_MASK);
1003 } else {
1004 /* full video */
1005 btwrite((btv->triton1) |
1006 (btv->gpioirq ? BT848_INT_GPINT : 0) |
1007 BT848_INT_SCERR |
1008 (fdsr ? BT848_INT_FDSR : 0) |
1009 BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
1010 BT848_INT_FMTCHG|BT848_INT_HLOCK|
1011 BT848_INT_I2CDONE,
1012 BT848_INT_MASK);
1013 }
1014}
1015
1016static void init_bt848(struct bttv *btv)
1017{
1018 int val;
1019
1020 if (bttv_tvcards[btv->c.type].no_video) {
1021 /* very basic init only */
1022 init_irqreg(btv);
1023 return;
1024 }
1025
1026 btwrite(0x00, BT848_CAP_CTL);
1027 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1028 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1029
1030 /* set planar and packed mode trigger points and */
1031 /* set rising edge of inverted GPINTR pin as irq trigger */
1032 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1033 BT848_GPIO_DMA_CTL_PLTP1_16|
1034 BT848_GPIO_DMA_CTL_PLTP23_16|
1035 BT848_GPIO_DMA_CTL_GPINTC|
1036 BT848_GPIO_DMA_CTL_GPINTI,
1037 BT848_GPIO_DMA_CTL);
1038
1039 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1040 btwrite(val, BT848_E_SCLOOP);
1041 btwrite(val, BT848_O_SCLOOP);
1042
1043 btwrite(0x20, BT848_E_VSCALE_HI);
1044 btwrite(0x20, BT848_O_VSCALE_HI);
1045 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1046 BT848_ADC);
1047
1048 btwrite(whitecrush_upper, BT848_WC_UP);
1049 btwrite(whitecrush_lower, BT848_WC_DOWN);
1050
1051 if (btv->opt_lumafilter) {
1052 btwrite(0, BT848_E_CONTROL);
1053 btwrite(0, BT848_O_CONTROL);
1054 } else {
1055 btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1056 btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1057 }
1058
1059 bt848_bright(btv, btv->bright);
1060 bt848_hue(btv, btv->hue);
1061 bt848_contrast(btv, btv->contrast);
1062 bt848_sat(btv, btv->saturation);
1063
1064 /* interrupt */
1065 init_irqreg(btv);
1066}
1067
1068static void bttv_reinit_bt848(struct bttv *btv)
1069{
1070 unsigned long flags;
1071
1072 if (bttv_verbose)
1073 printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);
1074 spin_lock_irqsave(&btv->s_lock,flags);
1075 btv->errors=0;
1076 bttv_set_dma(btv,0);
1077 spin_unlock_irqrestore(&btv->s_lock,flags);
1078
1079 init_bt848(btv);
1080 btv->pll.pll_current = -1;
1081 set_input(btv,btv->input);
1082}
1083
1084static int get_control(struct bttv *btv, struct v4l2_control *c)
1085{
1086 struct video_audio va;
1087 int i;
1088
1089 for (i = 0; i < BTTV_CTLS; i++)
1090 if (bttv_ctls[i].id == c->id)
1091 break;
1092 if (i == BTTV_CTLS)
1093 return -EINVAL;
1094 if (i >= 4 && i <= 8) {
1095 memset(&va,0,sizeof(va));
1096 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1097 if (btv->audio_hook)
1098 btv->audio_hook(btv,&va,0);
1099 }
1100 switch (c->id) {
1101 case V4L2_CID_BRIGHTNESS:
1102 c->value = btv->bright;
1103 break;
1104 case V4L2_CID_HUE:
1105 c->value = btv->hue;
1106 break;
1107 case V4L2_CID_CONTRAST:
1108 c->value = btv->contrast;
1109 break;
1110 case V4L2_CID_SATURATION:
1111 c->value = btv->saturation;
1112 break;
1113
1114 case V4L2_CID_AUDIO_MUTE:
1115 c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
1116 break;
1117 case V4L2_CID_AUDIO_VOLUME:
1118 c->value = va.volume;
1119 break;
1120 case V4L2_CID_AUDIO_BALANCE:
1121 c->value = va.balance;
1122 break;
1123 case V4L2_CID_AUDIO_BASS:
1124 c->value = va.bass;
1125 break;
1126 case V4L2_CID_AUDIO_TREBLE:
1127 c->value = va.treble;
1128 break;
1129
1130 case V4L2_CID_PRIVATE_CHROMA_AGC:
1131 c->value = btv->opt_chroma_agc;
1132 break;
1133 case V4L2_CID_PRIVATE_COMBFILTER:
1134 c->value = btv->opt_combfilter;
1135 break;
1136 case V4L2_CID_PRIVATE_LUMAFILTER:
1137 c->value = btv->opt_lumafilter;
1138 break;
1139 case V4L2_CID_PRIVATE_AUTOMUTE:
1140 c->value = btv->opt_automute;
1141 break;
1142 case V4L2_CID_PRIVATE_AGC_CRUSH:
1143 c->value = btv->opt_adc_crush;
1144 break;
1145 case V4L2_CID_PRIVATE_VCR_HACK:
1146 c->value = btv->opt_vcr_hack;
1147 break;
1148 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1149 c->value = btv->opt_whitecrush_upper;
1150 break;
1151 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1152 c->value = btv->opt_whitecrush_lower;
1153 break;
1154 default:
1155 return -EINVAL;
1156 }
1157 return 0;
1158}
1159
1160static int set_control(struct bttv *btv, struct v4l2_control *c)
1161{
1162 struct video_audio va;
1163 int i,val;
1164
1165 for (i = 0; i < BTTV_CTLS; i++)
1166 if (bttv_ctls[i].id == c->id)
1167 break;
1168 if (i == BTTV_CTLS)
1169 return -EINVAL;
1170 if (i >= 4 && i <= 8) {
1171 memset(&va,0,sizeof(va));
1172 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1173 if (btv->audio_hook)
1174 btv->audio_hook(btv,&va,0);
1175 }
1176 switch (c->id) {
1177 case V4L2_CID_BRIGHTNESS:
1178 bt848_bright(btv,c->value);
1179 break;
1180 case V4L2_CID_HUE:
1181 bt848_hue(btv,c->value);
1182 break;
1183 case V4L2_CID_CONTRAST:
1184 bt848_contrast(btv,c->value);
1185 break;
1186 case V4L2_CID_SATURATION:
1187 bt848_sat(btv,c->value);
1188 break;
1189 case V4L2_CID_AUDIO_MUTE:
1190 if (c->value) {
1191 va.flags |= VIDEO_AUDIO_MUTE;
1192 audio_mux(btv, AUDIO_MUTE);
1193 } else {
1194 va.flags &= ~VIDEO_AUDIO_MUTE;
1195 audio_mux(btv, AUDIO_UNMUTE);
1196 }
1197 break;
1198
1199 case V4L2_CID_AUDIO_VOLUME:
1200 va.volume = c->value;
1201 break;
1202 case V4L2_CID_AUDIO_BALANCE:
1203 va.balance = c->value;
1204 break;
1205 case V4L2_CID_AUDIO_BASS:
1206 va.bass = c->value;
1207 break;
1208 case V4L2_CID_AUDIO_TREBLE:
1209 va.treble = c->value;
1210 break;
1211
1212 case V4L2_CID_PRIVATE_CHROMA_AGC:
1213 btv->opt_chroma_agc = c->value;
1214 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1215 btwrite(val, BT848_E_SCLOOP);
1216 btwrite(val, BT848_O_SCLOOP);
1217 break;
1218 case V4L2_CID_PRIVATE_COMBFILTER:
1219 btv->opt_combfilter = c->value;
1220 break;
1221 case V4L2_CID_PRIVATE_LUMAFILTER:
1222 btv->opt_lumafilter = c->value;
1223 if (btv->opt_lumafilter) {
1224 btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);
1225 btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);
1226 } else {
1227 btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1228 btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1229 }
1230 break;
1231 case V4L2_CID_PRIVATE_AUTOMUTE:
1232 btv->opt_automute = c->value;
1233 break;
1234 case V4L2_CID_PRIVATE_AGC_CRUSH:
1235 btv->opt_adc_crush = c->value;
1236 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1237 BT848_ADC);
1238 break;
1239 case V4L2_CID_PRIVATE_VCR_HACK:
1240 btv->opt_vcr_hack = c->value;
1241 break;
1242 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1243 btv->opt_whitecrush_upper = c->value;
1244 btwrite(c->value, BT848_WC_UP);
1245 break;
1246 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1247 btv->opt_whitecrush_lower = c->value;
1248 btwrite(c->value, BT848_WC_DOWN);
1249 break;
1250 default:
1251 return -EINVAL;
1252 }
1253 if (i >= 4 && i <= 8) {
1254 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1255 if (btv->audio_hook)
1256 btv->audio_hook(btv,&va,1);
1257 }
1258 return 0;
1259}
1260
1261/* ----------------------------------------------------------------------- */
1262
1263void bttv_gpio_tracking(struct bttv *btv, char *comment)
1264{
1265 unsigned int outbits, data;
1266 outbits = btread(BT848_GPIO_OUT_EN);
1267 data = btread(BT848_GPIO_DATA);
1268 printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",
1269 btv->c.nr,outbits,data & outbits, data & ~outbits, comment);
1270}
1271
1272static void bttv_field_count(struct bttv *btv)
1273{
1274 int need_count = 0;
1275
1276 if (btv->users)
1277 need_count++;
1278
1279 if (need_count) {
1280 /* start field counter */
1281 btor(BT848_INT_VSYNC,BT848_INT_MASK);
1282 } else {
1283 /* stop field counter */
1284 btand(~BT848_INT_VSYNC,BT848_INT_MASK);
1285 btv->field_count = 0;
1286 }
1287}
1288
1289static const struct bttv_format*
1290format_by_palette(int palette)
1291{
1292 unsigned int i;
1293
1294 for (i = 0; i < BTTV_FORMATS; i++) {
1295 if (-1 == bttv_formats[i].palette)
1296 continue;
1297 if (bttv_formats[i].palette == palette)
1298 return bttv_formats+i;
1299 }
1300 return NULL;
1301}
1302
1303static const struct bttv_format*
1304format_by_fourcc(int fourcc)
1305{
1306 unsigned int i;
1307
1308 for (i = 0; i < BTTV_FORMATS; i++) {
1309 if (-1 == bttv_formats[i].fourcc)
1310 continue;
1311 if (bttv_formats[i].fourcc == fourcc)
1312 return bttv_formats+i;
1313 }
1314 return NULL;
1315}
1316
1317/* ----------------------------------------------------------------------- */
1318/* misc helpers */
1319
1320static int
1321bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1322 struct bttv_buffer *new)
1323{
1324 struct bttv_buffer *old;
1325 unsigned long flags;
1326 int retval = 0;
1327
1328 dprintk("switch_overlay: enter [new=%p]\n",new);
1329 if (new)
1330 new->vb.state = STATE_DONE;
1331 spin_lock_irqsave(&btv->s_lock,flags);
1332 old = btv->screen;
1333 btv->screen = new;
1334 btv->loop_irq |= 1;
1335 bttv_set_dma(btv, 0x03);
1336 spin_unlock_irqrestore(&btv->s_lock,flags);
1337 if (NULL == new)
1338 free_btres(btv,fh,RESOURCE_OVERLAY);
1339 if (NULL != old) {
1340 dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
1341 bttv_dma_free(btv, old);
1342 kfree(old);
1343 }
1344 dprintk("switch_overlay: done\n");
1345 return retval;
1346}
1347
1348/* ----------------------------------------------------------------------- */
1349/* video4linux (1) interface */
1350
1351static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1352 const struct bttv_format *fmt,
1353 unsigned int width, unsigned int height,
1354 enum v4l2_field field)
1355{
1356 int redo_dma_risc = 0;
1357 int rc;
1358
1359 /* check settings */
1360 if (NULL == fmt)
1361 return -EINVAL;
1362 if (fmt->btformat == BT848_COLOR_FMT_RAW) {
1363 width = RAW_BPL;
1364 height = RAW_LINES*2;
1365 if (width*height > buf->vb.bsize)
1366 return -EINVAL;
1367 buf->vb.size = buf->vb.bsize;
1368 } else {
1369 if (width < 48 ||
1370 height < 32 ||
1371 width > bttv_tvnorms[btv->tvnorm].swidth ||
1372 height > bttv_tvnorms[btv->tvnorm].sheight)
1373 return -EINVAL;
1374 buf->vb.size = (width * height * fmt->depth) >> 3;
1375 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
1376 return -EINVAL;
1377 }
1378
1379 /* alloc + fill struct bttv_buffer (if changed) */
1380 if (buf->vb.width != width || buf->vb.height != height ||
1381 buf->vb.field != field ||
1382 buf->tvnorm != btv->tvnorm || buf->fmt != fmt) {
1383 buf->vb.width = width;
1384 buf->vb.height = height;
1385 buf->vb.field = field;
1386 buf->tvnorm = btv->tvnorm;
1387 buf->fmt = fmt;
1388 redo_dma_risc = 1;
1389 }
1390
1391 /* alloc risc memory */
1392 if (STATE_NEEDS_INIT == buf->vb.state) {
1393 redo_dma_risc = 1;
1394 if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
1395 goto fail;
1396 }
1397
1398 if (redo_dma_risc)
1399 if (0 != (rc = bttv_buffer_risc(btv,buf)))
1400 goto fail;
1401
1402 buf->vb.state = STATE_PREPARED;
1403 return 0;
1404
1405 fail:
1406 bttv_dma_free(btv,buf);
1407 return rc;
1408}
1409
1410static int
1411buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1412{
1413 struct bttv_fh *fh = q->priv_data;
1414
1415 *size = fh->fmt->depth*fh->width*fh->height >> 3;
1416 if (0 == *count)
1417 *count = gbuffers;
1418 while (*size * *count > gbuffers * gbufsize)
1419 (*count)--;
1420 return 0;
1421}
1422
1423static int
1424buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
1425 enum v4l2_field field)
1426{
1427 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1428 struct bttv_fh *fh = q->priv_data;
1429
1430 return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
1431 fh->width, fh->height, field);
1432}
1433
1434static void
1435buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1436{
1437 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1438 struct bttv_fh *fh = q->priv_data;
1439 struct bttv *btv = fh->btv;
1440
1441 buf->vb.state = STATE_QUEUED;
1442 list_add_tail(&buf->vb.queue,&btv->capture);
1443 if (!btv->curr.frame_irq) {
1444 btv->loop_irq |= 1;
1445 bttv_set_dma(btv, 0x03);
1446 }
1447}
1448
1449static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1450{
1451 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1452 struct bttv_fh *fh = q->priv_data;
1453
1454 bttv_dma_free(fh->btv,buf);
1455}
1456
1457static struct videobuf_queue_ops bttv_video_qops = {
1458 .buf_setup = buffer_setup,
1459 .buf_prepare = buffer_prepare,
1460 .buf_queue = buffer_queue,
1461 .buf_release = buffer_release,
1462};
1463
1464static const char *v4l1_ioctls[] = {
1465 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
1466 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
1467 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
1468 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
1469 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
1470#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
1471
1472static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1473{
1474 switch (cmd) {
1475 case BTTV_VERSION:
1476 return BTTV_VERSION_CODE;
1477
1478 /* *** v4l1 *** ************************************************ */
1479 case VIDIOCGFREQ:
1480 {
1481 unsigned long *freq = arg;
1482 *freq = btv->freq;
1483 return 0;
1484 }
1485 case VIDIOCSFREQ:
1486 {
1487 unsigned long *freq = arg;
1488 down(&btv->lock);
1489 btv->freq=*freq;
1490 bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
1491 if (btv->has_matchbox && btv->radio_user)
1492 tea5757_set_freq(btv,*freq);
1493 up(&btv->lock);
1494 return 0;
1495 }
1496
1497 case VIDIOCGTUNER:
1498 {
1499 struct video_tuner *v = arg;
1500
1501 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1502 return -EINVAL;
1503 if (v->tuner) /* Only tuner 0 */
1504 return -EINVAL;
1505 strcpy(v->name, "Television");
1506 v->rangelow = 0;
1507 v->rangehigh = 0x7FFFFFFF;
1508 v->flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1509 v->mode = btv->tvnorm;
1510 v->signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
1511 bttv_call_i2c_clients(btv,cmd,v);
1512 return 0;
1513 }
1514 case VIDIOCSTUNER:
1515 {
1516 struct video_tuner *v = arg;
1517
1518 if (v->tuner) /* Only tuner 0 */
1519 return -EINVAL;
1520 if (v->mode >= BTTV_TVNORMS)
1521 return -EINVAL;
1522
1523 down(&btv->lock);
1524 set_tvnorm(btv,v->mode);
1525 bttv_call_i2c_clients(btv,cmd,v);
1526 up(&btv->lock);
1527 return 0;
1528 }
1529
1530 case VIDIOCGCHAN:
1531 {
1532 struct video_channel *v = arg;
1533 unsigned int channel = v->channel;
1534
1535 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1536 return -EINVAL;
1537 v->tuners=0;
1538 v->flags = VIDEO_VC_AUDIO;
1539 v->type = VIDEO_TYPE_CAMERA;
1540 v->norm = btv->tvnorm;
1541 if (channel == bttv_tvcards[btv->c.type].tuner) {
1542 strcpy(v->name,"Television");
1543 v->flags|=VIDEO_VC_TUNER;
1544 v->type=VIDEO_TYPE_TV;
1545 v->tuners=1;
1546 } else if (channel == btv->svhs) {
1547 strcpy(v->name,"S-Video");
1548 } else {
1549 sprintf(v->name,"Composite%d",channel);
1550 }
1551 return 0;
1552 }
1553 case VIDIOCSCHAN:
1554 {
1555 struct video_channel *v = arg;
1556 unsigned int channel = v->channel;
1557
1558 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1559 return -EINVAL;
1560 if (v->norm >= BTTV_TVNORMS)
1561 return -EINVAL;
1562
1563 down(&btv->lock);
1564 if (channel == btv->input &&
1565 v->norm == btv->tvnorm) {
1566 /* nothing to do */
1567 up(&btv->lock);
1568 return 0;
1569 }
1570
1571 btv->tvnorm = v->norm;
1572 set_input(btv,v->channel);
1573 up(&btv->lock);
1574 return 0;
1575 }
1576
1577 case VIDIOCGAUDIO:
1578 {
1579 struct video_audio *v = arg;
1580
1581 memset(v,0,sizeof(*v));
1582 strcpy(v->name,"Television");
1583 v->flags |= VIDEO_AUDIO_MUTABLE;
1584 v->mode = VIDEO_SOUND_MONO;
1585
1586 down(&btv->lock);
1587 bttv_call_i2c_clients(btv,cmd,v);
1588
1589 /* card specific hooks */
1590 if (btv->audio_hook)
1591 btv->audio_hook(btv,v,0);
1592
1593 up(&btv->lock);
1594 return 0;
1595 }
1596 case VIDIOCSAUDIO:
1597 {
1598 struct video_audio *v = arg;
1599 unsigned int audio = v->audio;
1600
1601 if (audio >= bttv_tvcards[btv->c.type].audio_inputs)
1602 return -EINVAL;
1603
1604 down(&btv->lock);
1605 audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
1606 bttv_call_i2c_clients(btv,cmd,v);
1607
1608 /* card specific hooks */
1609 if (btv->audio_hook)
1610 btv->audio_hook(btv,v,1);
1611
1612 up(&btv->lock);
1613 return 0;
1614 }
1615
1616 /* *** v4l2 *** ************************************************ */
1617 case VIDIOC_ENUMSTD:
1618 {
1619 struct v4l2_standard *e = arg;
1620 unsigned int index = e->index;
1621
1622 if (index >= BTTV_TVNORMS)
1623 return -EINVAL;
1624 v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
1625 bttv_tvnorms[e->index].name);
1626 e->index = index;
1627 return 0;
1628 }
1629 case VIDIOC_G_STD:
1630 {
1631 v4l2_std_id *id = arg;
1632 *id = bttv_tvnorms[btv->tvnorm].v4l2_id;
1633 return 0;
1634 }
1635 case VIDIOC_S_STD:
1636 {
1637 v4l2_std_id *id = arg;
1638 unsigned int i;
1639
1640 for (i = 0; i < BTTV_TVNORMS; i++)
1641 if (*id & bttv_tvnorms[i].v4l2_id)
1642 break;
1643 if (i == BTTV_TVNORMS)
1644 return -EINVAL;
1645
1646 down(&btv->lock);
1647 set_tvnorm(btv,i);
1648 i2c_vidiocschan(btv);
1649 up(&btv->lock);
1650 return 0;
1651 }
1652 case VIDIOC_QUERYSTD:
1653 {
1654 v4l2_std_id *id = arg;
1655
1656 if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
1657 *id = V4L2_STD_625_50;
1658 else
1659 *id = V4L2_STD_525_60;
1660 return 0;
1661 }
1662
1663 case VIDIOC_ENUMINPUT:
1664 {
1665 struct v4l2_input *i = arg;
1666 unsigned int n;
1667
1668 n = i->index;
1669 if (n >= bttv_tvcards[btv->c.type].video_inputs)
1670 return -EINVAL;
1671 memset(i,0,sizeof(*i));
1672 i->index = n;
1673 i->type = V4L2_INPUT_TYPE_CAMERA;
1674 i->audioset = 1;
1675 if (i->index == bttv_tvcards[btv->c.type].tuner) {
1676 sprintf(i->name, "Television");
1677 i->type = V4L2_INPUT_TYPE_TUNER;
1678 i->tuner = 0;
1679 } else if (i->index == btv->svhs) {
1680 sprintf(i->name, "S-Video");
1681 } else {
1682 sprintf(i->name,"Composite%d",i->index);
1683 }
1684 if (i->index == btv->input) {
1685 __u32 dstatus = btread(BT848_DSTATUS);
1686 if (0 == (dstatus & BT848_DSTATUS_PRES))
1687 i->status |= V4L2_IN_ST_NO_SIGNAL;
1688 if (0 == (dstatus & BT848_DSTATUS_HLOC))
1689 i->status |= V4L2_IN_ST_NO_H_LOCK;
1690 }
1691 for (n = 0; n < BTTV_TVNORMS; n++)
1692 i->std |= bttv_tvnorms[n].v4l2_id;
1693 return 0;
1694 }
1695 case VIDIOC_G_INPUT:
1696 {
1697 int *i = arg;
1698 *i = btv->input;
1699 return 0;
1700 }
1701 case VIDIOC_S_INPUT:
1702 {
1703 unsigned int *i = arg;
1704
1705 if (*i > bttv_tvcards[btv->c.type].video_inputs)
1706 return -EINVAL;
1707 down(&btv->lock);
1708 set_input(btv,*i);
1709 up(&btv->lock);
1710 return 0;
1711 }
1712
1713 case VIDIOC_G_TUNER:
1714 {
1715 struct v4l2_tuner *t = arg;
1716
1717 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1718 return -EINVAL;
1719 if (0 != t->index)
1720 return -EINVAL;
1721 down(&btv->lock);
1722 memset(t,0,sizeof(*t));
1723 strcpy(t->name, "Television");
1724 t->type = V4L2_TUNER_ANALOG_TV;
1725 t->rangehigh = 0xffffffffUL;
1726 t->capability = V4L2_TUNER_CAP_NORM;
1727 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1728 if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
1729 t->signal = 0xffff;
1730 {
1731 /* Hmmm ... */
1732 struct video_audio va;
1733 memset(&va, 0, sizeof(struct video_audio));
1734 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1735 if (btv->audio_hook)
1736 btv->audio_hook(btv,&va,0);
1737 if(va.mode & VIDEO_SOUND_STEREO) {
1738 t->audmode = V4L2_TUNER_MODE_STEREO;
1739 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1740 }
1741 if(va.mode & VIDEO_SOUND_LANG1) {
1742 t->audmode = V4L2_TUNER_MODE_LANG1;
1743 t->rxsubchans = V4L2_TUNER_SUB_LANG1
1744 | V4L2_TUNER_SUB_LANG2;
1745 }
1746 }
1747 /* FIXME: fill capability+audmode */
1748 up(&btv->lock);
1749 return 0;
1750 }
1751 case VIDIOC_S_TUNER:
1752 {
1753 struct v4l2_tuner *t = arg;
1754
1755 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1756 return -EINVAL;
1757 if (0 != t->index)
1758 return -EINVAL;
1759 down(&btv->lock);
1760 {
1761 struct video_audio va;
1762 memset(&va, 0, sizeof(struct video_audio));
1763 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1764 if (t->audmode == V4L2_TUNER_MODE_MONO)
1765 va.mode = VIDEO_SOUND_MONO;
1766 else if (t->audmode == V4L2_TUNER_MODE_STEREO)
1767 va.mode = VIDEO_SOUND_STEREO;
1768 else if (t->audmode == V4L2_TUNER_MODE_LANG1)
1769 va.mode = VIDEO_SOUND_LANG1;
1770 else if (t->audmode == V4L2_TUNER_MODE_LANG2)
1771 va.mode = VIDEO_SOUND_LANG2;
1772 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1773 if (btv->audio_hook)
1774 btv->audio_hook(btv,&va,1);
1775 }
1776 up(&btv->lock);
1777 return 0;
1778 }
1779
1780 case VIDIOC_G_FREQUENCY:
1781 {
1782 struct v4l2_frequency *f = arg;
1783
1784 memset(f,0,sizeof(*f));
1785 f->type = V4L2_TUNER_ANALOG_TV;
1786 f->frequency = btv->freq;
1787 return 0;
1788 }
1789 case VIDIOC_S_FREQUENCY:
1790 {
1791 struct v4l2_frequency *f = arg;
1792
1793 if (unlikely(f->tuner != 0))
1794 return -EINVAL;
1795 if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1796 return -EINVAL;
1797 down(&btv->lock);
1798 btv->freq = f->frequency;
1799 bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
1800 if (btv->has_matchbox && btv->radio_user)
1801 tea5757_set_freq(btv,btv->freq);
1802 up(&btv->lock);
1803 return 0;
1804 }
1805
1806 default:
1807 return -ENOIOCTLCMD;
1808
1809 }
1810 return 0;
1811}
1812
1813static int verify_window(const struct bttv_tvnorm *tvn,
1814 struct v4l2_window *win, int fixup)
1815{
1816 enum v4l2_field field;
1817 int maxw, maxh;
1818
1819 if (win->w.width < 48 || win->w.height < 32)
1820 return -EINVAL;
1821 if (win->clipcount > 2048)
1822 return -EINVAL;
1823
1824 field = win->field;
1825 maxw = tvn->swidth;
1826 maxh = tvn->sheight;
1827
1828 if (V4L2_FIELD_ANY == field) {
1829 field = (win->w.height > maxh/2)
1830 ? V4L2_FIELD_INTERLACED
1831 : V4L2_FIELD_TOP;
1832 }
1833 switch (field) {
1834 case V4L2_FIELD_TOP:
1835 case V4L2_FIELD_BOTTOM:
1836 maxh = maxh / 2;
1837 break;
1838 case V4L2_FIELD_INTERLACED:
1839 break;
1840 default:
1841 return -EINVAL;
1842 }
1843
1844 if (!fixup && (win->w.width > maxw || win->w.height > maxh))
1845 return -EINVAL;
1846
1847 if (win->w.width > maxw)
1848 win->w.width = maxw;
1849 if (win->w.height > maxh)
1850 win->w.height = maxh;
1851 win->field = field;
1852 return 0;
1853}
1854
1855static int setup_window(struct bttv_fh *fh, struct bttv *btv,
1856 struct v4l2_window *win, int fixup)
1857{
1858 struct v4l2_clip *clips = NULL;
1859 int n,size,retval = 0;
1860
1861 if (NULL == fh->ovfmt)
1862 return -EINVAL;
1863 if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
1864 return -EINVAL;
1865 retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
1866 if (0 != retval)
1867 return retval;
1868
1869 /* copy clips -- luckily v4l1 + v4l2 are binary
1870 compatible here ...*/
1871 n = win->clipcount;
1872 size = sizeof(*clips)*(n+4);
1873 clips = kmalloc(size,GFP_KERNEL);
1874 if (NULL == clips)
1875 return -ENOMEM;
1876 if (n > 0) {
1877 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
1878 kfree(clips);
1879 return -EFAULT;
1880 }
1881 }
1882 /* clip against screen */
1883 if (NULL != btv->fbuf.base)
1884 n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
1885 &win->w, clips, n);
1886 btcx_sort_clips(clips,n);
1887
1888 /* 4-byte alignments */
1889 switch (fh->ovfmt->depth) {
1890 case 8:
1891 case 24:
1892 btcx_align(&win->w, clips, n, 3);
1893 break;
1894 case 16:
1895 btcx_align(&win->w, clips, n, 1);
1896 break;
1897 case 32:
1898 /* no alignment fixups needed */
1899 break;
1900 default:
1901 BUG();
1902 }
1903
1904 down(&fh->cap.lock);
1905 if (fh->ov.clips)
1906 kfree(fh->ov.clips);
1907 fh->ov.clips = clips;
1908 fh->ov.nclips = n;
1909
1910 fh->ov.w = win->w;
1911 fh->ov.field = win->field;
1912 fh->ov.setup_ok = 1;
1913 btv->init.ov.w.width = win->w.width;
1914 btv->init.ov.w.height = win->w.height;
1915 btv->init.ov.field = win->field;
1916
1917 /* update overlay if needed */
1918 retval = 0;
1919 if (check_btres(fh, RESOURCE_OVERLAY)) {
1920 struct bttv_buffer *new;
1921
1922 new = videobuf_alloc(sizeof(*new));
1923 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
1924 retval = bttv_switch_overlay(btv,fh,new);
1925 }
1926 up(&fh->cap.lock);
1927 return retval;
1928}
1929
1930/* ----------------------------------------------------------------------- */
1931
1932static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
1933{
1934 struct videobuf_queue* q = NULL;
1935
1936 switch (fh->type) {
1937 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1938 q = &fh->cap;
1939 break;
1940 case V4L2_BUF_TYPE_VBI_CAPTURE:
1941 q = &fh->vbi;
1942 break;
1943 default:
1944 BUG();
1945 }
1946 return q;
1947}
1948
1949static int bttv_resource(struct bttv_fh *fh)
1950{
1951 int res = 0;
1952
1953 switch (fh->type) {
1954 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1955 res = RESOURCE_VIDEO;
1956 break;
1957 case V4L2_BUF_TYPE_VBI_CAPTURE:
1958 res = RESOURCE_VBI;
1959 break;
1960 default:
1961 BUG();
1962 }
1963 return res;
1964}
1965
1966static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
1967{
1968 struct videobuf_queue *q = bttv_queue(fh);
1969 int res = bttv_resource(fh);
1970
1971 if (check_btres(fh,res))
1972 return -EBUSY;
1973 if (videobuf_queue_is_busy(q))
1974 return -EBUSY;
1975 fh->type = type;
1976 return 0;
1977}
1978
1979static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
1980{
1981 switch (f->type) {
1982 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1983 memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
1984 f->fmt.pix.width = fh->width;
1985 f->fmt.pix.height = fh->height;
1986 f->fmt.pix.field = fh->cap.field;
1987 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1988 f->fmt.pix.bytesperline =
1989 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1990 f->fmt.pix.sizeimage =
1991 f->fmt.pix.height * f->fmt.pix.bytesperline;
1992 return 0;
1993 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1994 memset(&f->fmt.win,0,sizeof(struct v4l2_window));
1995 f->fmt.win.w = fh->ov.w;
1996 f->fmt.win.field = fh->ov.field;
1997 return 0;
1998 case V4L2_BUF_TYPE_VBI_CAPTURE:
1999 bttv_vbi_get_fmt(fh,f);
2000 return 0;
2001 default:
2002 return -EINVAL;
2003 }
2004}
2005
2006static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv,
2007 struct v4l2_format *f)
2008{
2009 switch (f->type) {
2010 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2011 {
2012 const struct bttv_format *fmt;
2013 enum v4l2_field field;
2014 unsigned int maxw,maxh;
2015
2016 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2017 if (NULL == fmt)
2018 return -EINVAL;
2019
2020 /* fixup format */
2021 maxw = bttv_tvnorms[btv->tvnorm].swidth;
2022 maxh = bttv_tvnorms[btv->tvnorm].sheight;
2023 field = f->fmt.pix.field;
2024 if (V4L2_FIELD_ANY == field)
2025 field = (f->fmt.pix.height > maxh/2)
2026 ? V4L2_FIELD_INTERLACED
2027 : V4L2_FIELD_BOTTOM;
2028 if (V4L2_FIELD_SEQ_BT == field)
2029 field = V4L2_FIELD_SEQ_TB;
2030 switch (field) {
2031 case V4L2_FIELD_TOP:
2032 case V4L2_FIELD_BOTTOM:
2033 case V4L2_FIELD_ALTERNATE:
2034 maxh = maxh/2;
2035 break;
2036 case V4L2_FIELD_INTERLACED:
2037 break;
2038 case V4L2_FIELD_SEQ_TB:
2039 if (fmt->flags & FORMAT_FLAGS_PLANAR)
2040 return -EINVAL;
2041 break;
2042 default:
2043 return -EINVAL;
2044 }
2045
2046 /* update data for the application */
2047 f->fmt.pix.field = field;
2048 if (f->fmt.pix.width < 48)
2049 f->fmt.pix.width = 48;
2050 if (f->fmt.pix.height < 32)
2051 f->fmt.pix.height = 32;
2052 if (f->fmt.pix.width > maxw)
2053 f->fmt.pix.width = maxw;
2054 if (f->fmt.pix.height > maxh)
2055 f->fmt.pix.height = maxh;
2056 f->fmt.pix.width &= ~0x03;
2057 f->fmt.pix.bytesperline =
2058 (f->fmt.pix.width * fmt->depth) >> 3;
2059 f->fmt.pix.sizeimage =
2060 f->fmt.pix.height * f->fmt.pix.bytesperline;
2061
2062 return 0;
2063 }
2064 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2065 return verify_window(&bttv_tvnorms[btv->tvnorm],
2066 &f->fmt.win, 1);
2067 case V4L2_BUF_TYPE_VBI_CAPTURE:
2068 bttv_vbi_try_fmt(fh,f);
2069 return 0;
2070 default:
2071 return -EINVAL;
2072 }
2073}
2074
2075static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2076 struct v4l2_format *f)
2077{
2078 int retval;
2079
2080 switch (f->type) {
2081 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2082 {
2083 const struct bttv_format *fmt;
2084
2085 retval = bttv_switch_type(fh,f->type);
2086 if (0 != retval)
2087 return retval;
2088 retval = bttv_try_fmt(fh,btv,f);
2089 if (0 != retval)
2090 return retval;
2091 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2092
2093 /* update our state informations */
2094 down(&fh->cap.lock);
2095 fh->fmt = fmt;
2096 fh->cap.field = f->fmt.pix.field;
2097 fh->cap.last = V4L2_FIELD_NONE;
2098 fh->width = f->fmt.pix.width;
2099 fh->height = f->fmt.pix.height;
2100 btv->init.fmt = fmt;
2101 btv->init.width = f->fmt.pix.width;
2102 btv->init.height = f->fmt.pix.height;
2103 up(&fh->cap.lock);
2104
2105 return 0;
2106 }
2107 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2108 return setup_window(fh, btv, &f->fmt.win, 1);
2109 case V4L2_BUF_TYPE_VBI_CAPTURE:
2110 retval = bttv_switch_type(fh,f->type);
2111 if (0 != retval)
2112 return retval;
2113 if (locked_btres(fh->btv, RESOURCE_VBI))
2114 return -EBUSY;
2115 bttv_vbi_try_fmt(fh,f);
2116 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2117 bttv_vbi_get_fmt(fh,f);
2118 return 0;
2119 default:
2120 return -EINVAL;
2121 }
2122}
2123
2124static int bttv_do_ioctl(struct inode *inode, struct file *file,
2125 unsigned int cmd, void *arg)
2126{
2127 struct bttv_fh *fh = file->private_data;
2128 struct bttv *btv = fh->btv;
2129 unsigned long flags;
2130 int retval = 0;
2131
2132 if (bttv_debug > 1) {
2133 switch (_IOC_TYPE(cmd)) {
2134 case 'v':
2135 printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
2136 btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
2137 v4l1_ioctls[_IOC_NR(cmd)] : "???");
2138 break;
2139 case 'V':
2140 printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
2141 btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]);
2142 break;
2143 default:
2144 printk("bttv%d: ioctl 0x%x (???)\n",
2145 btv->c.nr, cmd);
2146 }
2147 }
2148 if (btv->errors)
2149 bttv_reinit_bt848(btv);
2150
2151 switch (cmd) {
2152 case VIDIOCSFREQ:
2153 case VIDIOCSTUNER:
2154 case VIDIOCSCHAN:
2155 case VIDIOC_S_CTRL:
2156 case VIDIOC_S_STD:
2157 case VIDIOC_S_INPUT:
2158 case VIDIOC_S_TUNER:
2159 case VIDIOC_S_FREQUENCY:
2160 retval = v4l2_prio_check(&btv->prio,&fh->prio);
2161 if (0 != retval)
2162 return retval;
2163 };
2164
2165 switch (cmd) {
2166
2167 /* *** v4l1 *** ************************************************ */
2168 case VIDIOCGCAP:
2169 {
2170 struct video_capability *cap = arg;
2171
2172 memset(cap,0,sizeof(*cap));
2173 strcpy(cap->name,btv->video_dev->name);
2174 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2175 /* vbi */
2176 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
2177 } else {
2178 /* others */
2179 cap->type = VID_TYPE_CAPTURE|
2180 VID_TYPE_TUNER|
2181 VID_TYPE_OVERLAY|
2182 VID_TYPE_CLIPPING|
2183 VID_TYPE_SCALES;
2184 cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
2185 cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
2186 cap->minwidth = 48;
2187 cap->minheight = 32;
2188 }
2189 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2190 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2191 return 0;
2192 }
2193
2194 case VIDIOCGPICT:
2195 {
2196 struct video_picture *pic = arg;
2197
2198 memset(pic,0,sizeof(*pic));
2199 pic->brightness = btv->bright;
2200 pic->contrast = btv->contrast;
2201 pic->hue = btv->hue;
2202 pic->colour = btv->saturation;
2203 if (fh->fmt) {
2204 pic->depth = fh->fmt->depth;
2205 pic->palette = fh->fmt->palette;
2206 }
2207 return 0;
2208 }
2209 case VIDIOCSPICT:
2210 {
2211 struct video_picture *pic = arg;
2212 const struct bttv_format *fmt;
2213
2214 fmt = format_by_palette(pic->palette);
2215 if (NULL == fmt)
2216 return -EINVAL;
2217 down(&fh->cap.lock);
2218 if (fmt->depth != pic->depth) {
2219 retval = -EINVAL;
2220 goto fh_unlock_and_return;
2221 }
2222 fh->ovfmt = fmt;
2223 fh->fmt = fmt;
2224 btv->init.ovfmt = fmt;
2225 btv->init.fmt = fmt;
2226 if (bigendian) {
2227 /* dirty hack time: swap bytes for overlay if the
2228 display adaptor is big endian (insmod option) */
2229 if (fmt->palette == VIDEO_PALETTE_RGB555 ||
2230 fmt->palette == VIDEO_PALETTE_RGB565 ||
2231 fmt->palette == VIDEO_PALETTE_RGB32) {
2232 fh->ovfmt = fmt+1;
2233 }
2234 }
2235 bt848_bright(btv,pic->brightness);
2236 bt848_contrast(btv,pic->contrast);
2237 bt848_hue(btv,pic->hue);
2238 bt848_sat(btv,pic->colour);
2239 up(&fh->cap.lock);
2240 return 0;
2241 }
2242
2243 case VIDIOCGWIN:
2244 {
2245 struct video_window *win = arg;
2246
2247 memset(win,0,sizeof(*win));
2248 win->x = fh->ov.w.left;
2249 win->y = fh->ov.w.top;
2250 win->width = fh->ov.w.width;
2251 win->height = fh->ov.w.height;
2252 return 0;
2253 }
2254 case VIDIOCSWIN:
2255 {
2256 struct video_window *win = arg;
2257 struct v4l2_window w2;
2258
2259 w2.field = V4L2_FIELD_ANY;
2260 w2.w.left = win->x;
2261 w2.w.top = win->y;
2262 w2.w.width = win->width;
2263 w2.w.height = win->height;
2264 w2.clipcount = win->clipcount;
2265 w2.clips = (struct v4l2_clip __user *)win->clips;
2266 retval = setup_window(fh, btv, &w2, 0);
2267 if (0 == retval) {
2268 /* on v4l1 this ioctl affects the read() size too */
2269 fh->width = fh->ov.w.width;
2270 fh->height = fh->ov.w.height;
2271 btv->init.width = fh->ov.w.width;
2272 btv->init.height = fh->ov.w.height;
2273 }
2274 return retval;
2275 }
2276
2277 case VIDIOCGFBUF:
2278 {
2279 struct video_buffer *fbuf = arg;
2280
2281 fbuf->base = btv->fbuf.base;
2282 fbuf->width = btv->fbuf.fmt.width;
2283 fbuf->height = btv->fbuf.fmt.height;
2284 fbuf->bytesperline = btv->fbuf.fmt.bytesperline;
2285 if (fh->ovfmt)
2286 fbuf->depth = fh->ovfmt->depth;
2287 return 0;
2288 }
2289 case VIDIOCSFBUF:
2290 {
2291 struct video_buffer *fbuf = arg;
2292 const struct bttv_format *fmt;
2293 unsigned long end;
2294
2295 if(!capable(CAP_SYS_ADMIN) &&
2296 !capable(CAP_SYS_RAWIO))
2297 return -EPERM;
2298 end = (unsigned long)fbuf->base +
2299 fbuf->height * fbuf->bytesperline;
2300 down(&fh->cap.lock);
2301 retval = -EINVAL;
2302
2303 switch (fbuf->depth) {
2304 case 8:
2305 fmt = format_by_palette(VIDEO_PALETTE_HI240);
2306 break;
2307 case 16:
2308 fmt = format_by_palette(VIDEO_PALETTE_RGB565);
2309 break;
2310 case 24:
2311 fmt = format_by_palette(VIDEO_PALETTE_RGB24);
2312 break;
2313 case 32:
2314 fmt = format_by_palette(VIDEO_PALETTE_RGB32);
2315 break;
2316 case 15:
2317 fbuf->depth = 16;
2318 fmt = format_by_palette(VIDEO_PALETTE_RGB555);
2319 break;
2320 default:
2321 fmt = NULL;
2322 break;
2323 }
2324 if (NULL == fmt)
2325 goto fh_unlock_and_return;
2326
2327 fh->ovfmt = fmt;
2328 fh->fmt = fmt;
2329 btv->init.ovfmt = fmt;
2330 btv->init.fmt = fmt;
2331 btv->fbuf.base = fbuf->base;
2332 btv->fbuf.fmt.width = fbuf->width;
2333 btv->fbuf.fmt.height = fbuf->height;
2334 if (fbuf->bytesperline)
2335 btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
2336 else
2337 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
2338 up(&fh->cap.lock);
2339 return 0;
2340 }
2341
2342 case VIDIOCCAPTURE:
2343 case VIDIOC_OVERLAY:
2344 {
2345 struct bttv_buffer *new;
2346 int *on = arg;
2347
2348 if (*on) {
2349 /* verify args */
2350 if (NULL == btv->fbuf.base)
2351 return -EINVAL;
2352 if (!fh->ov.setup_ok) {
2353 dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr);
2354 return -EINVAL;
2355 }
2356 }
2357
2358 if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
2359 return -EBUSY;
2360
2361 down(&fh->cap.lock);
2362 if (*on) {
2363 fh->ov.tvnorm = btv->tvnorm;
2364 new = videobuf_alloc(sizeof(*new));
2365 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
2366 } else {
2367 new = NULL;
2368 }
2369
2370 /* switch over */
2371 retval = bttv_switch_overlay(btv,fh,new);
2372 up(&fh->cap.lock);
2373 return retval;
2374 }
2375
2376 case VIDIOCGMBUF:
2377 {
2378 struct video_mbuf *mbuf = arg;
2379 unsigned int i;
2380
2381 down(&fh->cap.lock);
2382 retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
2383 V4L2_MEMORY_MMAP);
2384 if (retval < 0)
2385 goto fh_unlock_and_return;
2386 memset(mbuf,0,sizeof(*mbuf));
2387 mbuf->frames = gbuffers;
2388 mbuf->size = gbuffers * gbufsize;
2389 for (i = 0; i < gbuffers; i++)
2390 mbuf->offsets[i] = i * gbufsize;
2391 up(&fh->cap.lock);
2392 return 0;
2393 }
2394 case VIDIOCMCAPTURE:
2395 {
2396 struct video_mmap *vm = arg;
2397 struct bttv_buffer *buf;
2398 enum v4l2_field field;
2399
2400 if (vm->frame >= VIDEO_MAX_FRAME)
2401 return -EINVAL;
2402
2403 down(&fh->cap.lock);
2404 retval = -EINVAL;
2405 buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
2406 if (NULL == buf)
2407 goto fh_unlock_and_return;
2408 if (0 == buf->vb.baddr)
2409 goto fh_unlock_and_return;
2410 if (buf->vb.state == STATE_QUEUED ||
2411 buf->vb.state == STATE_ACTIVE)
2412 goto fh_unlock_and_return;
2413
2414 field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
2415 ? V4L2_FIELD_INTERLACED
2416 : V4L2_FIELD_BOTTOM;
2417 retval = bttv_prepare_buffer(btv,buf,
2418 format_by_palette(vm->format),
2419 vm->width,vm->height,field);
2420 if (0 != retval)
2421 goto fh_unlock_and_return;
2422 spin_lock_irqsave(&btv->s_lock,flags);
2423 buffer_queue(&fh->cap,&buf->vb);
2424 spin_unlock_irqrestore(&btv->s_lock,flags);
2425 up(&fh->cap.lock);
2426 return 0;
2427 }
2428 case VIDIOCSYNC:
2429 {
2430 int *frame = arg;
2431 struct bttv_buffer *buf;
2432
2433 if (*frame >= VIDEO_MAX_FRAME)
2434 return -EINVAL;
2435
2436 down(&fh->cap.lock);
2437 retval = -EINVAL;
2438 buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
2439 if (NULL == buf)
2440 goto fh_unlock_and_return;
2441 retval = videobuf_waiton(&buf->vb,0,1);
2442 if (0 != retval)
2443 goto fh_unlock_and_return;
2444 switch (buf->vb.state) {
2445 case STATE_ERROR:
2446 retval = -EIO;
2447 /* fall through */
2448 case STATE_DONE:
2449 videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
2450 bttv_dma_free(btv,buf);
2451 break;
2452 default:
2453 retval = -EINVAL;
2454 break;
2455 }
2456 up(&fh->cap.lock);
2457 return retval;
2458 }
2459
2460 case VIDIOCGVBIFMT:
2461 {
2462 struct vbi_format *fmt = (void *) arg;
2463 struct v4l2_format fmt2;
2464
2465 if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) {
2466 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2467 if (0 != retval)
2468 return retval;
2469 }
2470 bttv_vbi_get_fmt(fh, &fmt2);
2471
2472 memset(fmt,0,sizeof(*fmt));
2473 fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate;
2474 fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line;
2475 fmt->sample_format = VIDEO_PALETTE_RAW;
2476 fmt->start[0] = fmt2.fmt.vbi.start[0];
2477 fmt->count[0] = fmt2.fmt.vbi.count[0];
2478 fmt->start[1] = fmt2.fmt.vbi.start[1];
2479 fmt->count[1] = fmt2.fmt.vbi.count[1];
2480 if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
2481 fmt->flags |= V4L2_VBI_UNSYNC;
2482 if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
2483 fmt->flags |= V4L2_VBI_INTERLACED;
2484 return 0;
2485 }
2486 case VIDIOCSVBIFMT:
2487 {
2488 struct vbi_format *fmt = (void *) arg;
2489 struct v4l2_format fmt2;
2490
2491 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2492 if (0 != retval)
2493 return retval;
2494 bttv_vbi_get_fmt(fh, &fmt2);
2495
2496 if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate ||
2497 fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line ||
2498 fmt->sample_format != VIDEO_PALETTE_RAW ||
2499 fmt->start[0] != fmt2.fmt.vbi.start[0] ||
2500 fmt->start[1] != fmt2.fmt.vbi.start[1] ||
2501 fmt->count[0] != fmt->count[1] ||
2502 fmt->count[0] < 1 ||
2503 fmt->count[0] > 32 /* VBI_MAXLINES */)
2504 return -EINVAL;
2505
2506 bttv_vbi_setlines(fh,btv,fmt->count[0]);
2507 return 0;
2508 }
2509
2510 case BTTV_VERSION:
2511 case VIDIOCGFREQ:
2512 case VIDIOCSFREQ:
2513 case VIDIOCGTUNER:
2514 case VIDIOCSTUNER:
2515 case VIDIOCGCHAN:
2516 case VIDIOCSCHAN:
2517 case VIDIOCGAUDIO:
2518 case VIDIOCSAUDIO:
2519 return bttv_common_ioctls(btv,cmd,arg);
2520
2521 /* *** v4l2 *** ************************************************ */
2522 case VIDIOC_QUERYCAP:
2523 {
2524 struct v4l2_capability *cap = arg;
2525
2526 if (0 == v4l2)
2527 return -EINVAL;
2528 strcpy(cap->driver,"bttv");
2529 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2530 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2531 cap->version = BTTV_VERSION_CODE;
2532 cap->capabilities =
2533 V4L2_CAP_VIDEO_CAPTURE |
2534 V4L2_CAP_VIDEO_OVERLAY |
2535 V4L2_CAP_VBI_CAPTURE |
2536 V4L2_CAP_READWRITE |
2537 V4L2_CAP_STREAMING;
2538 if (bttv_tvcards[btv->c.type].tuner != UNSET &&
2539 bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
2540 cap->capabilities |= V4L2_CAP_TUNER;
2541 return 0;
2542 }
2543
2544 case VIDIOC_ENUM_FMT:
2545 {
2546 struct v4l2_fmtdesc *f = arg;
2547 enum v4l2_buf_type type;
2548 unsigned int i;
2549 int index;
2550
2551 type = f->type;
2552 if (V4L2_BUF_TYPE_VBI_CAPTURE == type) {
2553 /* vbi */
2554 index = f->index;
2555 if (0 != index)
2556 return -EINVAL;
2557 memset(f,0,sizeof(*f));
2558 f->index = index;
2559 f->type = type;
2560 f->pixelformat = V4L2_PIX_FMT_GREY;
2561 strcpy(f->description,"vbi data");
2562 return 0;
2563 }
2564
2565 /* video capture + overlay */
2566 index = -1;
2567 for (i = 0; i < BTTV_FORMATS; i++) {
2568 if (bttv_formats[i].fourcc != -1)
2569 index++;
2570 if ((unsigned int)index == f->index)
2571 break;
2572 }
2573 if (BTTV_FORMATS == i)
2574 return -EINVAL;
2575
2576 switch (f->type) {
2577 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2578 break;
2579 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2580 if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
2581 return -EINVAL;
2582 break;
2583 default:
2584 return -EINVAL;
2585 }
2586 memset(f,0,sizeof(*f));
2587 f->index = index;
2588 f->type = type;
2589 f->pixelformat = bttv_formats[i].fourcc;
2590 strlcpy(f->description,bttv_formats[i].name,sizeof(f->description));
2591 return 0;
2592 }
2593
2594 case VIDIOC_TRY_FMT:
2595 {
2596 struct v4l2_format *f = arg;
2597 return bttv_try_fmt(fh,btv,f);
2598 }
2599 case VIDIOC_G_FMT:
2600 {
2601 struct v4l2_format *f = arg;
2602 return bttv_g_fmt(fh,f);
2603 }
2604 case VIDIOC_S_FMT:
2605 {
2606 struct v4l2_format *f = arg;
2607 return bttv_s_fmt(fh,btv,f);
2608 }
2609
2610 case VIDIOC_G_FBUF:
2611 {
2612 struct v4l2_framebuffer *fb = arg;
2613
2614 *fb = btv->fbuf;
2615 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2616 if (fh->ovfmt)
2617 fb->fmt.pixelformat = fh->ovfmt->fourcc;
2618 return 0;
2619 }
2620 case VIDIOC_S_FBUF:
2621 {
2622 struct v4l2_framebuffer *fb = arg;
2623 const struct bttv_format *fmt;
2624
2625 if(!capable(CAP_SYS_ADMIN) &&
2626 !capable(CAP_SYS_RAWIO))
2627 return -EPERM;
2628
2629 /* check args */
2630 fmt = format_by_fourcc(fb->fmt.pixelformat);
2631 if (NULL == fmt)
2632 return -EINVAL;
2633 if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
2634 return -EINVAL;
2635
2636 down(&fh->cap.lock);
2637 retval = -EINVAL;
2638 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2639 if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
2640 goto fh_unlock_and_return;
2641 if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight)
2642 goto fh_unlock_and_return;
2643 }
2644
2645 /* ok, accept it */
2646 btv->fbuf.base = fb->base;
2647 btv->fbuf.fmt.width = fb->fmt.width;
2648 btv->fbuf.fmt.height = fb->fmt.height;
2649 if (0 != fb->fmt.bytesperline)
2650 btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline;
2651 else
2652 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8;
2653
2654 retval = 0;
2655 fh->ovfmt = fmt;
2656 btv->init.ovfmt = fmt;
2657 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2658 fh->ov.w.left = 0;
2659 fh->ov.w.top = 0;
2660 fh->ov.w.width = fb->fmt.width;
2661 fh->ov.w.height = fb->fmt.height;
2662 btv->init.ov.w.width = fb->fmt.width;
2663 btv->init.ov.w.height = fb->fmt.height;
2664 if (fh->ov.clips)
2665 kfree(fh->ov.clips);
2666 fh->ov.clips = NULL;
2667 fh->ov.nclips = 0;
2668
2669 if (check_btres(fh, RESOURCE_OVERLAY)) {
2670 struct bttv_buffer *new;
2671
2672 new = videobuf_alloc(sizeof(*new));
2673 bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
2674 retval = bttv_switch_overlay(btv,fh,new);
2675 }
2676 }
2677 up(&fh->cap.lock);
2678 return retval;
2679 }
2680
2681 case VIDIOC_REQBUFS:
2682 return videobuf_reqbufs(bttv_queue(fh),arg);
2683
2684 case VIDIOC_QUERYBUF:
2685 return videobuf_querybuf(bttv_queue(fh),arg);
2686
2687 case VIDIOC_QBUF:
2688 return videobuf_qbuf(bttv_queue(fh),arg);
2689
2690 case VIDIOC_DQBUF:
2691 return videobuf_dqbuf(bttv_queue(fh),arg,
2692 file->f_flags & O_NONBLOCK);
2693
2694 case VIDIOC_STREAMON:
2695 {
2696 int res = bttv_resource(fh);
2697
2698 if (!check_alloc_btres(btv,fh,res))
2699 return -EBUSY;
2700 return videobuf_streamon(bttv_queue(fh));
2701 }
2702 case VIDIOC_STREAMOFF:
2703 {
2704 int res = bttv_resource(fh);
2705
2706 retval = videobuf_streamoff(bttv_queue(fh));
2707 if (retval < 0)
2708 return retval;
2709 free_btres(btv,fh,res);
2710 return 0;
2711 }
2712
2713 case VIDIOC_QUERYCTRL:
2714 {
2715 struct v4l2_queryctrl *c = arg;
2716 int i;
2717
2718 if ((c->id < V4L2_CID_BASE ||
2719 c->id >= V4L2_CID_LASTP1) &&
2720 (c->id < V4L2_CID_PRIVATE_BASE ||
2721 c->id >= V4L2_CID_PRIVATE_LASTP1))
2722 return -EINVAL;
2723 for (i = 0; i < BTTV_CTLS; i++)
2724 if (bttv_ctls[i].id == c->id)
2725 break;
2726 if (i == BTTV_CTLS) {
2727 *c = no_ctl;
2728 return 0;
2729 }
2730 *c = bttv_ctls[i];
2731 if (i >= 4 && i <= 8) {
2732 struct video_audio va;
2733 memset(&va,0,sizeof(va));
2734 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
2735 if (btv->audio_hook)
2736 btv->audio_hook(btv,&va,0);
2737 switch (bttv_ctls[i].id) {
2738 case V4L2_CID_AUDIO_VOLUME:
2739 if (!(va.flags & VIDEO_AUDIO_VOLUME))
2740 *c = no_ctl;
2741 break;
2742 case V4L2_CID_AUDIO_BALANCE:
2743 if (!(va.flags & VIDEO_AUDIO_BALANCE))
2744 *c = no_ctl;
2745 break;
2746 case V4L2_CID_AUDIO_BASS:
2747 if (!(va.flags & VIDEO_AUDIO_BASS))
2748 *c = no_ctl;
2749 break;
2750 case V4L2_CID_AUDIO_TREBLE:
2751 if (!(va.flags & VIDEO_AUDIO_TREBLE))
2752 *c = no_ctl;
2753 break;
2754 }
2755 }
2756 return 0;
2757 }
2758 case VIDIOC_G_CTRL:
2759 return get_control(btv,arg);
2760 case VIDIOC_S_CTRL:
2761 return set_control(btv,arg);
2762 case VIDIOC_G_PARM:
2763 {
2764 struct v4l2_streamparm *parm = arg;
2765 struct v4l2_standard s;
2766 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2767 return -EINVAL;
2768 memset(parm,0,sizeof(*parm));
2769 v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
2770 bttv_tvnorms[btv->tvnorm].name);
2771 parm->parm.capture.timeperframe = s.frameperiod;
2772 return 0;
2773 }
2774
2775 case VIDIOC_G_PRIORITY:
2776 {
2777 enum v4l2_priority *p = arg;
2778
2779 *p = v4l2_prio_max(&btv->prio);
2780 return 0;
2781 }
2782 case VIDIOC_S_PRIORITY:
2783 {
2784 enum v4l2_priority *prio = arg;
2785
2786 return v4l2_prio_change(&btv->prio, &fh->prio, *prio);
2787 }
2788
2789 case VIDIOC_ENUMSTD:
2790 case VIDIOC_G_STD:
2791 case VIDIOC_S_STD:
2792 case VIDIOC_ENUMINPUT:
2793 case VIDIOC_G_INPUT:
2794 case VIDIOC_S_INPUT:
2795 case VIDIOC_G_TUNER:
2796 case VIDIOC_S_TUNER:
2797 case VIDIOC_G_FREQUENCY:
2798 case VIDIOC_S_FREQUENCY:
2799 return bttv_common_ioctls(btv,cmd,arg);
2800
2801 default:
2802 return -ENOIOCTLCMD;
2803 }
2804 return 0;
2805
2806 fh_unlock_and_return:
2807 up(&fh->cap.lock);
2808 return retval;
2809}
2810
2811static int bttv_ioctl(struct inode *inode, struct file *file,
2812 unsigned int cmd, unsigned long arg)
2813{
2814 struct bttv_fh *fh = file->private_data;
2815
2816 switch (cmd) {
2817 case BTTV_VBISIZE:
2818 bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2819 return fh->lines * 2 * 2048;
2820 default:
2821 return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl);
2822 }
2823}
2824
2825static ssize_t bttv_read(struct file *file, char __user *data,
2826 size_t count, loff_t *ppos)
2827{
2828 struct bttv_fh *fh = file->private_data;
2829 int retval = 0;
2830
2831 if (fh->btv->errors)
2832 bttv_reinit_bt848(fh->btv);
2833 dprintk("bttv%d: read count=%d type=%s\n",
2834 fh->btv->c.nr,(int)count,v4l2_type_names[fh->type]);
2835
2836 switch (fh->type) {
2837 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2838 if (locked_btres(fh->btv,RESOURCE_VIDEO))
2839 return -EBUSY;
2840 retval = videobuf_read_one(&fh->cap, data, count, ppos,
2841 file->f_flags & O_NONBLOCK);
2842 break;
2843 case V4L2_BUF_TYPE_VBI_CAPTURE:
2844 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2845 return -EBUSY;
2846 retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1,
2847 file->f_flags & O_NONBLOCK);
2848 break;
2849 default:
2850 BUG();
2851 }
2852 return retval;
2853}
2854
2855static unsigned int bttv_poll(struct file *file, poll_table *wait)
2856{
2857 struct bttv_fh *fh = file->private_data;
2858 struct bttv_buffer *buf;
2859 enum v4l2_field field;
2860
2861 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2862 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2863 return POLLERR;
2864 return videobuf_poll_stream(file, &fh->vbi, wait);
2865 }
2866
2867 if (check_btres(fh,RESOURCE_VIDEO)) {
2868 /* streaming capture */
2869 if (list_empty(&fh->cap.stream))
2870 return POLLERR;
2871 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
2872 } else {
2873 /* read() capture */
2874 down(&fh->cap.lock);
2875 if (NULL == fh->cap.read_buf) {
2876 /* need to capture a new frame */
2877 if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
2878 up(&fh->cap.lock);
2879 return POLLERR;
2880 }
2881 fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
2882 if (NULL == fh->cap.read_buf) {
2883 up(&fh->cap.lock);
2884 return POLLERR;
2885 }
2886 fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
2887 field = videobuf_next_field(&fh->cap);
2888 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
2889 up(&fh->cap.lock);
2890 return POLLERR;
2891 }
2892 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
2893 fh->cap.read_off = 0;
2894 }
2895 up(&fh->cap.lock);
2896 buf = (struct bttv_buffer*)fh->cap.read_buf;
2897 }
2898
2899 poll_wait(file, &buf->vb.done, wait);
2900 if (buf->vb.state == STATE_DONE ||
2901 buf->vb.state == STATE_ERROR)
2902 return POLLIN|POLLRDNORM;
2903 return 0;
2904}
2905
2906static int bttv_open(struct inode *inode, struct file *file)
2907{
2908 int minor = iminor(inode);
2909 struct bttv *btv = NULL;
2910 struct bttv_fh *fh;
2911 enum v4l2_buf_type type = 0;
2912 unsigned int i;
2913
2914 dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
2915
2916 for (i = 0; i < bttv_num; i++) {
2917 if (bttvs[i].video_dev &&
2918 bttvs[i].video_dev->minor == minor) {
2919 btv = &bttvs[i];
2920 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2921 break;
2922 }
2923 if (bttvs[i].vbi_dev &&
2924 bttvs[i].vbi_dev->minor == minor) {
2925 btv = &bttvs[i];
2926 type = V4L2_BUF_TYPE_VBI_CAPTURE;
2927 break;
2928 }
2929 }
2930 if (NULL == btv)
2931 return -ENODEV;
2932
2933 dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
2934 btv->c.nr,v4l2_type_names[type]);
2935
2936 /* allocate per filehandle data */
2937 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
2938 if (NULL == fh)
2939 return -ENOMEM;
2940 file->private_data = fh;
2941 *fh = btv->init;
2942 fh->type = type;
2943 fh->ov.setup_ok = 0;
2944 v4l2_prio_open(&btv->prio,&fh->prio);
2945
2946 videobuf_queue_init(&fh->cap, &bttv_video_qops,
2947 btv->c.pci, &btv->s_lock,
2948 V4L2_BUF_TYPE_VIDEO_CAPTURE,
2949 V4L2_FIELD_INTERLACED,
2950 sizeof(struct bttv_buffer),
2951 fh);
2952 videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
2953 btv->c.pci, &btv->s_lock,
2954 V4L2_BUF_TYPE_VBI_CAPTURE,
2955 V4L2_FIELD_SEQ_TB,
2956 sizeof(struct bttv_buffer),
2957 fh);
2958 i2c_vidiocschan(btv);
2959
2960 btv->users++;
2961 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
2962 bttv_vbi_setlines(fh,btv,16);
2963 bttv_field_count(btv);
2964 return 0;
2965}
2966
2967static int bttv_release(struct inode *inode, struct file *file)
2968{
2969 struct bttv_fh *fh = file->private_data;
2970 struct bttv *btv = fh->btv;
2971
2972 /* turn off overlay */
2973 if (check_btres(fh, RESOURCE_OVERLAY))
2974 bttv_switch_overlay(btv,fh,NULL);
2975
2976 /* stop video capture */
2977 if (check_btres(fh, RESOURCE_VIDEO)) {
2978 videobuf_streamoff(&fh->cap);
2979 free_btres(btv,fh,RESOURCE_VIDEO);
2980 }
2981 if (fh->cap.read_buf) {
2982 buffer_release(&fh->cap,fh->cap.read_buf);
2983 kfree(fh->cap.read_buf);
2984 }
2985
2986 /* stop vbi capture */
2987 if (check_btres(fh, RESOURCE_VBI)) {
2988 if (fh->vbi.streaming)
2989 videobuf_streamoff(&fh->vbi);
2990 if (fh->vbi.reading)
2991 videobuf_read_stop(&fh->vbi);
2992 free_btres(btv,fh,RESOURCE_VBI);
2993 }
2994
2995 /* free stuff */
2996 videobuf_mmap_free(&fh->cap);
2997 videobuf_mmap_free(&fh->vbi);
2998 v4l2_prio_close(&btv->prio,&fh->prio);
2999 file->private_data = NULL;
3000 kfree(fh);
3001
3002 btv->users--;
3003 bttv_field_count(btv);
3004 return 0;
3005}
3006
3007static int
3008bttv_mmap(struct file *file, struct vm_area_struct *vma)
3009{
3010 struct bttv_fh *fh = file->private_data;
3011
3012 dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n",
3013 fh->btv->c.nr, v4l2_type_names[fh->type],
3014 vma->vm_start, vma->vm_end - vma->vm_start);
3015 return videobuf_mmap_mapper(bttv_queue(fh),vma);
3016}
3017
3018static struct file_operations bttv_fops =
3019{
3020 .owner = THIS_MODULE,
3021 .open = bttv_open,
3022 .release = bttv_release,
3023 .ioctl = bttv_ioctl,
3024 .llseek = no_llseek,
3025 .read = bttv_read,
3026 .mmap = bttv_mmap,
3027 .poll = bttv_poll,
3028};
3029
3030static struct video_device bttv_video_template =
3031{
3032 .name = "UNSET",
3033 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
3034 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3035 .hardware = VID_HARDWARE_BT848,
3036 .fops = &bttv_fops,
3037 .minor = -1,
3038};
3039
3040static struct video_device bttv_vbi_template =
3041{
3042 .name = "bt848/878 vbi",
3043 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
3044 .hardware = VID_HARDWARE_BT848,
3045 .fops = &bttv_fops,
3046 .minor = -1,
3047};
3048
3049/* ----------------------------------------------------------------------- */
3050/* radio interface */
3051
3052static int radio_open(struct inode *inode, struct file *file)
3053{
3054 int minor = iminor(inode);
3055 struct bttv *btv = NULL;
3056 unsigned int i;
3057
3058 dprintk("bttv: open minor=%d\n",minor);
3059
3060 for (i = 0; i < bttv_num; i++) {
3061 if (bttvs[i].radio_dev->minor == minor) {
3062 btv = &bttvs[i];
3063 break;
3064 }
3065 }
3066 if (NULL == btv)
3067 return -ENODEV;
3068
3069 dprintk("bttv%d: open called (radio)\n",btv->c.nr);
3070 down(&btv->lock);
3071 if (btv->radio_user) {
3072 up(&btv->lock);
3073 return -EBUSY;
3074 }
3075 btv->radio_user++;
3076 file->private_data = btv;
3077
3078 i2c_vidiocschan(btv);
3079 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
3080 audio_mux(btv,AUDIO_RADIO);
3081
3082 up(&btv->lock);
3083 return 0;
3084}
3085
3086static int radio_release(struct inode *inode, struct file *file)
3087{
3088 struct bttv *btv = file->private_data;
3089
3090 btv->radio_user--;
3091 return 0;
3092}
3093
3094static int radio_do_ioctl(struct inode *inode, struct file *file,
3095 unsigned int cmd, void *arg)
3096{
3097 struct bttv *btv = file->private_data;
3098
3099 switch (cmd) {
3100 case VIDIOCGCAP:
3101 {
3102 struct video_capability *cap = arg;
3103
3104 memset(cap,0,sizeof(*cap));
3105 strcpy(cap->name,btv->radio_dev->name);
3106 cap->type = VID_TYPE_TUNER;
3107 cap->channels = 1;
3108 cap->audios = 1;
3109 return 0;
3110 }
3111
3112 case VIDIOCGTUNER:
3113 {
3114 struct video_tuner *v = arg;
3115
3116 if(v->tuner)
3117 return -EINVAL;
3118 memset(v,0,sizeof(*v));
3119 strcpy(v->name, "Radio");
3120 /* japan: 76.0 MHz - 89.9 MHz
3121 western europe: 87.5 MHz - 108.0 MHz
3122 russia: 65.0 MHz - 108.0 MHz */
3123 v->rangelow=(int)(65*16);
3124 v->rangehigh=(int)(108*16);
3125 bttv_call_i2c_clients(btv,cmd,v);
3126 return 0;
3127 }
3128 case VIDIOCSTUNER:
3129 /* nothing to do */
3130 return 0;
3131
3132 case BTTV_VERSION:
3133 case VIDIOCGFREQ:
3134 case VIDIOCSFREQ:
3135 case VIDIOCGAUDIO:
3136 case VIDIOCSAUDIO:
3137 return bttv_common_ioctls(btv,cmd,arg);
3138
3139 default:
3140 return -ENOIOCTLCMD;
3141 }
3142 return 0;
3143}
3144
3145static int radio_ioctl(struct inode *inode, struct file *file,
3146 unsigned int cmd, unsigned long arg)
3147{
3148 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
3149}
3150
3151static struct file_operations radio_fops =
3152{
3153 .owner = THIS_MODULE,
3154 .open = radio_open,
3155 .release = radio_release,
3156 .ioctl = radio_ioctl,
3157 .llseek = no_llseek,
3158};
3159
3160static struct video_device radio_template =
3161{
3162 .name = "bt848/878 radio",
3163 .type = VID_TYPE_TUNER,
3164 .hardware = VID_HARDWARE_BT848,
3165 .fops = &radio_fops,
3166 .minor = -1,
3167};
3168
3169/* ----------------------------------------------------------------------- */
3170/* some debug code */
3171
3172int bttv_risc_decode(u32 risc)
3173{
3174 static char *instr[16] = {
3175 [ BT848_RISC_WRITE >> 28 ] = "write",
3176 [ BT848_RISC_SKIP >> 28 ] = "skip",
3177 [ BT848_RISC_WRITEC >> 28 ] = "writec",
3178 [ BT848_RISC_JUMP >> 28 ] = "jump",
3179 [ BT848_RISC_SYNC >> 28 ] = "sync",
3180 [ BT848_RISC_WRITE123 >> 28 ] = "write123",
3181 [ BT848_RISC_SKIP123 >> 28 ] = "skip123",
3182 [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23",
3183 };
3184 static int incr[16] = {
3185 [ BT848_RISC_WRITE >> 28 ] = 2,
3186 [ BT848_RISC_JUMP >> 28 ] = 2,
3187 [ BT848_RISC_SYNC >> 28 ] = 2,
3188 [ BT848_RISC_WRITE123 >> 28 ] = 5,
3189 [ BT848_RISC_SKIP123 >> 28 ] = 2,
3190 [ BT848_RISC_WRITE1S23 >> 28 ] = 3,
3191 };
3192 static char *bits[] = {
3193 "be0", "be1", "be2", "be3/resync",
3194 "set0", "set1", "set2", "set3",
3195 "clr0", "clr1", "clr2", "clr3",
3196 "irq", "res", "eol", "sol",
3197 };
3198 int i;
3199
3200 printk("0x%08x [ %s", risc,
3201 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
3202 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
3203 if (risc & (1 << (i + 12)))
3204 printk(" %s",bits[i]);
3205 printk(" count=%d ]\n", risc & 0xfff);
3206 return incr[risc >> 28] ? incr[risc >> 28] : 1;
3207}
3208
3209void bttv_risc_disasm(struct bttv *btv,
3210 struct btcx_riscmem *risc)
3211{
3212 unsigned int i,j,n;
3213
3214 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
3215 btv->c.name, risc->cpu, (unsigned long)risc->dma);
3216 for (i = 0; i < (risc->size >> 2); i += n) {
3217 printk("%s: 0x%lx: ", btv->c.name,
3218 (unsigned long)(risc->dma + (i<<2)));
3219 n = bttv_risc_decode(risc->cpu[i]);
3220 for (j = 1; j < n; j++)
3221 printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
3222 btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
3223 risc->cpu[i+j], j);
3224 if (0 == risc->cpu[i])
3225 break;
3226 }
3227}
3228
3229static void bttv_print_riscaddr(struct bttv *btv)
3230{
3231 printk(" main: %08Lx\n",
3232 (unsigned long long)btv->main.dma);
3233 printk(" vbi : o=%08Lx e=%08Lx\n",
3234 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
3235 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0);
3236 printk(" cap : o=%08Lx e=%08Lx\n",
3237 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
3238 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
3239 printk(" scr : o=%08Lx e=%08Lx\n",
3240 btv->screen ? (unsigned long long)btv->screen->top.dma : 0,
3241 btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0);
3242 bttv_risc_disasm(btv, &btv->main);
3243}
3244
3245/* ----------------------------------------------------------------------- */
3246/* irq handler */
3247
3248static char *irq_name[] = {
3249 "FMTCHG", // format change detected (525 vs. 625)
3250 "VSYNC", // vertical sync (new field)
3251 "HSYNC", // horizontal sync
3252 "OFLOW", // chroma/luma AGC overflow
3253 "HLOCK", // horizontal lock changed
3254 "VPRES", // video presence changed
3255 "6", "7",
3256 "I2CDONE", // hw irc operation finished
3257 "GPINT", // gpio port triggered irq
3258 "10",
3259 "RISCI", // risc instruction triggered irq
3260 "FBUS", // pixel data fifo dropped data (high pci bus latencies)
3261 "FTRGT", // pixel data fifo overrun
3262 "FDSR", // fifo data stream resyncronisation
3263 "PPERR", // parity error (data transfer)
3264 "RIPERR", // parity error (read risc instructions)
3265 "PABORT", // pci abort
3266 "OCERR", // risc instruction error
3267 "SCERR", // syncronisation error
3268};
3269
3270static void bttv_print_irqbits(u32 print, u32 mark)
3271{
3272 unsigned int i;
3273
3274 printk("bits:");
3275 for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
3276 if (print & (1 << i))
3277 printk(" %s",irq_name[i]);
3278 if (mark & (1 << i))
3279 printk("*");
3280 }
3281}
3282
3283static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
3284{
3285 printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
3286 btv->c.nr,
3287 (unsigned long)btv->main.dma,
3288 (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
3289 (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
3290 (unsigned long)rc);
3291
3292 if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
3293 printk("bttv%d: Oh, there (temporarely?) is no input signal. "
3294 "Ok, then this is harmless, don't worry ;)\n",
3295 btv->c.nr);
3296 return;
3297 }
3298 printk("bttv%d: Uhm. Looks like we have unusual high IRQ latencies.\n",
3299 btv->c.nr);
3300 printk("bttv%d: Lets try to catch the culpit red-handed ...\n",
3301 btv->c.nr);
3302 dump_stack();
3303}
3304
3305static int
3306bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
3307{
3308 struct bttv_buffer *item;
3309
3310 memset(set,0,sizeof(*set));
3311
3312 /* capture request ? */
3313 if (!list_empty(&btv->capture)) {
3314 set->frame_irq = 1;
3315 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3316 if (V4L2_FIELD_HAS_TOP(item->vb.field))
3317 set->top = item;
3318 if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
3319 set->bottom = item;
3320
3321 /* capture request for other field ? */
3322 if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
3323 (item->vb.queue.next != &btv->capture)) {
3324 item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
3325 if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
3326 if (NULL == set->top &&
3327 V4L2_FIELD_TOP == item->vb.field) {
3328 set->top = item;
3329 }
3330 if (NULL == set->bottom &&
3331 V4L2_FIELD_BOTTOM == item->vb.field) {
3332 set->bottom = item;
3333 }
3334 if (NULL != set->top && NULL != set->bottom)
3335 set->top_irq = 2;
3336 }
3337 }
3338 }
3339
3340 /* screen overlay ? */
3341 if (NULL != btv->screen) {
3342 if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
3343 if (NULL == set->top && NULL == set->bottom) {
3344 set->top = btv->screen;
3345 set->bottom = btv->screen;
3346 }
3347 } else {
3348 if (V4L2_FIELD_TOP == btv->screen->vb.field &&
3349 NULL == set->top) {
3350 set->top = btv->screen;
3351 }
3352 if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
3353 NULL == set->bottom) {
3354 set->bottom = btv->screen;
3355 }
3356 }
3357 }
3358
3359 dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
3360 btv->c.nr,set->top, set->bottom,
3361 btv->screen,set->frame_irq,set->top_irq);
3362 return 0;
3363}
3364
3365static void
3366bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
3367 struct bttv_buffer_set *curr, unsigned int state)
3368{
3369 struct timeval ts;
3370
3371 do_gettimeofday(&ts);
3372
3373 if (wakeup->top == wakeup->bottom) {
3374 if (NULL != wakeup->top && curr->top != wakeup->top) {
3375 if (irq_debug > 1)
3376 printk("bttv%d: wakeup: both=%p\n",btv->c.nr,wakeup->top);
3377 wakeup->top->vb.ts = ts;
3378 wakeup->top->vb.field_count = btv->field_count;
3379 wakeup->top->vb.state = state;
3380 wake_up(&wakeup->top->vb.done);
3381 }
3382 } else {
3383 if (NULL != wakeup->top && curr->top != wakeup->top) {
3384 if (irq_debug > 1)
3385 printk("bttv%d: wakeup: top=%p\n",btv->c.nr,wakeup->top);
3386 wakeup->top->vb.ts = ts;
3387 wakeup->top->vb.field_count = btv->field_count;
3388 wakeup->top->vb.state = state;
3389 wake_up(&wakeup->top->vb.done);
3390 }
3391 if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
3392 if (irq_debug > 1)
3393 printk("bttv%d: wakeup: bottom=%p\n",btv->c.nr,wakeup->bottom);
3394 wakeup->bottom->vb.ts = ts;
3395 wakeup->bottom->vb.field_count = btv->field_count;
3396 wakeup->bottom->vb.state = state;
3397 wake_up(&wakeup->bottom->vb.done);
3398 }
3399 }
3400}
3401
3402static void
3403bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
3404 unsigned int state)
3405{
3406 struct timeval ts;
3407
3408 if (NULL == wakeup)
3409 return;
3410
3411 do_gettimeofday(&ts);
3412 wakeup->vb.ts = ts;
3413 wakeup->vb.field_count = btv->field_count;
3414 wakeup->vb.state = state;
3415 wake_up(&wakeup->vb.done);
3416}
3417
3418static void bttv_irq_timeout(unsigned long data)
3419{
3420 struct bttv *btv = (struct bttv *)data;
3421 struct bttv_buffer_set old,new;
3422 struct bttv_buffer *ovbi;
3423 struct bttv_buffer *item;
3424 unsigned long flags;
3425
3426 if (bttv_verbose) {
3427 printk(KERN_INFO "bttv%d: timeout: drop=%d irq=%d/%d, risc=%08x, ",
3428 btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total,
3429 btread(BT848_RISC_COUNT));
3430 bttv_print_irqbits(btread(BT848_INT_STAT),0);
3431 printk("\n");
3432 }
3433
3434 spin_lock_irqsave(&btv->s_lock,flags);
3435
3436 /* deactivate stuff */
3437 memset(&new,0,sizeof(new));
3438 old = btv->curr;
3439 ovbi = btv->cvbi;
3440 btv->curr = new;
3441 btv->cvbi = NULL;
3442 btv->loop_irq = 0;
3443 bttv_buffer_activate_video(btv, &new);
3444 bttv_buffer_activate_vbi(btv, NULL);
3445 bttv_set_dma(btv, 0);
3446
3447 /* wake up */
3448 bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR);
3449 bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR);
3450
3451 /* cancel all outstanding capture / vbi requests */
3452 while (!list_empty(&btv->capture)) {
3453 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3454 list_del(&item->vb.queue);
3455 item->vb.state = STATE_ERROR;
3456 wake_up(&item->vb.done);
3457 }
3458 while (!list_empty(&btv->vcapture)) {
3459 item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3460 list_del(&item->vb.queue);
3461 item->vb.state = STATE_ERROR;
3462 wake_up(&item->vb.done);
3463 }
3464
3465 btv->errors++;
3466 spin_unlock_irqrestore(&btv->s_lock,flags);
3467}
3468
3469static void
3470bttv_irq_wakeup_top(struct bttv *btv)
3471{
3472 struct bttv_buffer *wakeup = btv->curr.top;
3473
3474 if (NULL == wakeup)
3475 return;
3476
3477 spin_lock(&btv->s_lock);
3478 btv->curr.top_irq = 0;
3479 btv->curr.top = NULL;
3480 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
3481
3482 do_gettimeofday(&wakeup->vb.ts);
3483 wakeup->vb.field_count = btv->field_count;
3484 wakeup->vb.state = STATE_DONE;
3485 wake_up(&wakeup->vb.done);
3486 spin_unlock(&btv->s_lock);
3487}
3488
3489static inline int is_active(struct btcx_riscmem *risc, u32 rc)
3490{
3491 if (rc < risc->dma)
3492 return 0;
3493 if (rc > risc->dma + risc->size)
3494 return 0;
3495 return 1;
3496}
3497
3498static void
3499bttv_irq_switch_video(struct bttv *btv)
3500{
3501 struct bttv_buffer_set new;
3502 struct bttv_buffer_set old;
3503 dma_addr_t rc;
3504
3505 spin_lock(&btv->s_lock);
3506
3507 /* new buffer set */
3508 bttv_irq_next_video(btv, &new);
3509 rc = btread(BT848_RISC_COUNT);
3510 if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) ||
3511 (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) {
3512 btv->framedrop++;
3513 if (debug_latency)
3514 bttv_irq_debug_low_latency(btv, rc);
3515 spin_unlock(&btv->s_lock);
3516 return;
3517 }
3518
3519 /* switch over */
3520 old = btv->curr;
3521 btv->curr = new;
3522 btv->loop_irq &= ~1;
3523 bttv_buffer_activate_video(btv, &new);
3524 bttv_set_dma(btv, 0);
3525
3526 /* switch input */
3527 if (UNSET != btv->new_input) {
3528 video_mux(btv,btv->new_input);
3529 btv->new_input = UNSET;
3530 }
3531
3532 /* wake up finished buffers */
3533 bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE);
3534 spin_unlock(&btv->s_lock);
3535}
3536
3537static void
3538bttv_irq_switch_vbi(struct bttv *btv)
3539{
3540 struct bttv_buffer *new = NULL;
3541 struct bttv_buffer *old;
3542 u32 rc;
3543
3544 spin_lock(&btv->s_lock);
3545
3546 if (!list_empty(&btv->vcapture))
3547 new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3548 old = btv->cvbi;
3549
3550 rc = btread(BT848_RISC_COUNT);
3551 if (NULL != old && (is_active(&old->top, rc) ||
3552 is_active(&old->bottom, rc))) {
3553 btv->framedrop++;
3554 if (debug_latency)
3555 bttv_irq_debug_low_latency(btv, rc);
3556 spin_unlock(&btv->s_lock);
3557 return;
3558 }
3559
3560 /* switch */
3561 btv->cvbi = new;
3562 btv->loop_irq &= ~4;
3563 bttv_buffer_activate_vbi(btv, new);
3564 bttv_set_dma(btv, 0);
3565
3566 bttv_irq_wakeup_vbi(btv, old, STATE_DONE);
3567 spin_unlock(&btv->s_lock);
3568}
3569
3570static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3571{
3572 u32 stat,astat;
3573 u32 dstat;
3574 int count;
3575 struct bttv *btv;
3576 int handled = 0;
3577
3578 btv=(struct bttv *)dev_id;
3579 count=0;
3580 while (1) {
3581 /* get/clear interrupt status bits */
3582 stat=btread(BT848_INT_STAT);
3583 astat=stat&btread(BT848_INT_MASK);
3584 if (!astat)
3585 break;
3586 handled = 1;
3587 btwrite(stat,BT848_INT_STAT);
3588
3589 /* get device status bits */
3590 dstat=btread(BT848_DSTATUS);
3591
3592 if (irq_debug) {
3593 printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d "
3594 "riscs=%x, riscc=%08x, ",
3595 btv->c.nr, count, btv->field_count,
3596 stat>>28, btread(BT848_RISC_COUNT));
3597 bttv_print_irqbits(stat,astat);
3598 if (stat & BT848_INT_HLOCK)
3599 printk(" HLOC => %s", (dstat & BT848_DSTATUS_HLOC)
3600 ? "yes" : "no");
3601 if (stat & BT848_INT_VPRES)
3602 printk(" PRES => %s", (dstat & BT848_DSTATUS_PRES)
3603 ? "yes" : "no");
3604 if (stat & BT848_INT_FMTCHG)
3605 printk(" NUML => %s", (dstat & BT848_DSTATUS_NUML)
3606 ? "625" : "525");
3607 printk("\n");
3608 }
3609
3610 if (astat&BT848_INT_VSYNC)
3611 btv->field_count++;
3612
3613 if (astat & BT848_INT_GPINT) {
3614 wake_up(&btv->gpioq);
3615 bttv_gpio_irq(&btv->c);
3616 }
3617
3618 if (astat & BT848_INT_I2CDONE) {
3619 btv->i2c_done = stat;
3620 wake_up(&btv->i2c_queue);
3621 }
3622
3623 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3624 bttv_irq_switch_vbi(btv);
3625
3626 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3627 bttv_irq_wakeup_top(btv);
3628
3629 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3630 bttv_irq_switch_video(btv);
3631
3632 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
3633 audio_mux(btv, -1);
3634
3635 if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
3636 printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
3637 (astat & BT848_INT_SCERR) ? "SCERR" : "",
3638 (astat & BT848_INT_OCERR) ? "OCERR" : "",
3639 btread(BT848_RISC_COUNT));
3640 bttv_print_irqbits(stat,astat);
3641 printk("\n");
3642 if (bttv_debug)
3643 bttv_print_riscaddr(btv);
3644 }
3645 if (fdsr && astat & BT848_INT_FDSR) {
3646 printk(KERN_INFO "bttv%d: FDSR @ %08x\n",
3647 btv->c.nr,btread(BT848_RISC_COUNT));
3648 if (bttv_debug)
3649 bttv_print_riscaddr(btv);
3650 }
3651
3652 count++;
3653 if (count > 4) {
3654 btwrite(0, BT848_INT_MASK);
3655 printk(KERN_ERR
3656 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3657 bttv_print_irqbits(stat,astat);
3658 printk("]\n");
3659 }
3660 }
3661 btv->irq_total++;
3662 if (handled)
3663 btv->irq_me++;
3664 return IRQ_RETVAL(handled);
3665}
3666
3667
3668/* ----------------------------------------------------------------------- */
3669/* initialitation */
3670
3671static struct video_device *vdev_init(struct bttv *btv,
3672 struct video_device *template,
3673 char *type)
3674{
3675 struct video_device *vfd;
3676
3677 vfd = video_device_alloc();
3678 if (NULL == vfd)
3679 return NULL;
3680 *vfd = *template;
3681 vfd->minor = -1;
3682 vfd->dev = &btv->c.pci->dev;
3683 vfd->release = video_device_release;
3684 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
3685 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
3686 type, bttv_tvcards[btv->c.type].name);
3687 return vfd;
3688}
3689
3690static void bttv_unregister_video(struct bttv *btv)
3691{
3692 if (btv->video_dev) {
3693 if (-1 != btv->video_dev->minor)
3694 video_unregister_device(btv->video_dev);
3695 else
3696 video_device_release(btv->video_dev);
3697 btv->video_dev = NULL;
3698 }
3699 if (btv->vbi_dev) {
3700 if (-1 != btv->vbi_dev->minor)
3701 video_unregister_device(btv->vbi_dev);
3702 else
3703 video_device_release(btv->vbi_dev);
3704 btv->vbi_dev = NULL;
3705 }
3706 if (btv->radio_dev) {
3707 if (-1 != btv->radio_dev->minor)
3708 video_unregister_device(btv->radio_dev);
3709 else
3710 video_device_release(btv->radio_dev);
3711 btv->radio_dev = NULL;
3712 }
3713}
3714
3715/* register video4linux devices */
3716static int __devinit bttv_register_video(struct bttv *btv)
3717{
3718 /* video */
3719 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3720 if (NULL == btv->video_dev)
3721 goto err;
3722 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3723 goto err;
3724 printk(KERN_INFO "bttv%d: registered device video%d\n",
3725 btv->c.nr,btv->video_dev->minor & 0x1f);
3726 video_device_create_file(btv->video_dev, &class_device_attr_card);
3727
3728 /* vbi */
3729 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3730 if (NULL == btv->vbi_dev)
3731 goto err;
3732 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3733 goto err;
3734 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3735 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3736
3737 if (!btv->has_radio)
3738 return 0;
3739 /* radio */
3740 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3741 if (NULL == btv->radio_dev)
3742 goto err;
3743 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3744 goto err;
3745 printk(KERN_INFO "bttv%d: registered device radio%d\n",
3746 btv->c.nr,btv->radio_dev->minor & 0x1f);
3747
3748 /* all done */
3749 return 0;
3750
3751 err:
3752 bttv_unregister_video(btv);
3753 return -1;
3754}
3755
3756
3757/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
3758/* response on cards with no firmware is not enabled by OF */
3759static void pci_set_command(struct pci_dev *dev)
3760{
3761#if defined(__powerpc__)
3762 unsigned int cmd;
3763
3764 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3765 cmd = (cmd | PCI_COMMAND_MEMORY );
3766 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3767#endif
3768}
3769
3770static int __devinit bttv_probe(struct pci_dev *dev,
3771 const struct pci_device_id *pci_id)
3772{
3773 int result;
3774 unsigned char lat;
3775 struct bttv *btv;
3776
3777 if (bttv_num == BTTV_MAX)
3778 return -ENOMEM;
3779 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3780 btv=&bttvs[bttv_num];
3781 memset(btv,0,sizeof(*btv));
3782 btv->c.nr = bttv_num;
3783 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3784
3785 /* initialize structs / fill in defaults */
3786 init_MUTEX(&btv->lock);
3787 init_MUTEX(&btv->reslock);
3788 spin_lock_init(&btv->s_lock);
3789 spin_lock_init(&btv->gpio_lock);
3790 init_waitqueue_head(&btv->gpioq);
3791 init_waitqueue_head(&btv->i2c_queue);
3792 INIT_LIST_HEAD(&btv->c.subs);
3793 INIT_LIST_HEAD(&btv->capture);
3794 INIT_LIST_HEAD(&btv->vcapture);
3795 v4l2_prio_init(&btv->prio);
3796
3797 init_timer(&btv->timeout);
3798 btv->timeout.function = bttv_irq_timeout;
3799 btv->timeout.data = (unsigned long)btv;
3800
3801 btv->i2c_rc = -1;
3802 btv->tuner_type = UNSET;
3803 btv->pinnacle_id = UNSET;
3804 btv->new_input = UNSET;
3805 btv->gpioirq = 1;
3806 btv->has_radio=radio[btv->c.nr];
3807
3808 /* pci stuff (init, get irq/mmio, ... */
3809 btv->c.pci = dev;
3810 btv->id = dev->device;
3811 if (pci_enable_device(dev)) {
3812 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3813 btv->c.nr);
3814 return -EIO;
3815 }
3816 if (pci_set_dma_mask(dev, 0xffffffff)) {
3817 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3818 btv->c.nr);
3819 return -EIO;
3820 }
3821 if (!request_mem_region(pci_resource_start(dev,0),
3822 pci_resource_len(dev,0),
3823 btv->c.name)) {
3824 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3825 btv->c.nr, pci_resource_start(dev,0));
3826 return -EBUSY;
3827 }
3828 pci_set_master(dev);
3829 pci_set_command(dev);
3830 pci_set_drvdata(dev,btv);
3831 if (!pci_dma_supported(dev,0xffffffff)) {
3832 printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr);
3833 result = -EIO;
3834 goto fail1;
3835 }
3836
3837 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3838 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3839 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3840 bttv_num,btv->id, btv->revision, pci_name(dev));
3841 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3842 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3843 schedule();
3844
3845 btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000);
3846 if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) {
3847 printk("bttv%d: ioremap() failed\n", btv->c.nr);
3848 result = -EIO;
3849 goto fail1;
3850 }
3851
3852 /* identify card */
3853 bttv_idcard(btv);
3854
3855 /* disable irqs, register irq handler */
3856 btwrite(0, BT848_INT_MASK);
3857 result = request_irq(btv->c.pci->irq, bttv_irq,
3858 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3859 if (result < 0) {
3860 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3861 bttv_num,btv->c.pci->irq);
3862 goto fail1;
3863 }
3864
3865 if (0 != bttv_handle_chipset(btv)) {
3866 result = -EIO;
3867 goto fail2;
3868 }
3869
3870 /* init options from insmod args */
3871 btv->opt_combfilter = combfilter;
3872 btv->opt_lumafilter = lumafilter;
3873 btv->opt_automute = automute;
3874 btv->opt_chroma_agc = chroma_agc;
3875 btv->opt_adc_crush = adc_crush;
3876 btv->opt_vcr_hack = vcr_hack;
3877 btv->opt_whitecrush_upper = whitecrush_upper;
3878 btv->opt_whitecrush_lower = whitecrush_lower;
3879
3880 /* fill struct bttv with some useful defaults */
3881 btv->init.btv = btv;
3882 btv->init.ov.w.width = 320;
3883 btv->init.ov.w.height = 240;
3884 btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24);
3885 btv->init.width = 320;
3886 btv->init.height = 240;
3887 btv->init.lines = 16;
3888 btv->input = 0;
3889
3890 /* initialize hardware */
3891 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"pre-init");
3893
3894 bttv_risc_init_main(btv);
3895 init_bt848(btv);
3896
3897 /* gpio */
3898 btwrite(0x00, BT848_GPIO_REG_INP);
3899 btwrite(0x00, BT848_GPIO_OUT_EN);
3900 if (bttv_verbose)
3901 bttv_gpio_tracking(btv,"init");
3902
3903 /* needs to be done before i2c is registered */
3904 bttv_init_card1(btv);
3905
3906 /* register i2c + gpio */
3907 init_bttv_i2c(btv);
3908
3909 /* some card-specific stuff (needs working i2c) */
3910 bttv_init_card2(btv);
3911 init_irqreg(btv);
3912
3913 /* register video4linux + input */
3914 if (!bttv_tvcards[btv->c.type].no_video) {
3915 bttv_register_video(btv);
3916 bt848_bright(btv,32768);
3917 bt848_contrast(btv,32768);
3918 bt848_hue(btv,32768);
3919 bt848_sat(btv,32768);
3920 audio_mux(btv,AUDIO_MUTE);
3921 set_input(btv,0);
3922 }
3923
3924 /* add subdevices */
3925 if (btv->has_remote)
3926 bttv_sub_add_device(&btv->c, "remote");
3927 if (bttv_tvcards[btv->c.type].has_dvb)
3928 bttv_sub_add_device(&btv->c, "dvb");
3929
3930 /* everything is fine */
3931 bttv_num++;
3932 return 0;
3933
3934 fail2:
3935 free_irq(btv->c.pci->irq,btv);
3936
3937 fail1:
3938 if (btv->bt848_mmio)
3939 iounmap(btv->bt848_mmio);
3940 release_mem_region(pci_resource_start(btv->c.pci,0),
3941 pci_resource_len(btv->c.pci,0));
3942 pci_set_drvdata(dev,NULL);
3943 return result;
3944}
3945
3946static void __devexit bttv_remove(struct pci_dev *pci_dev)
3947{
3948 struct bttv *btv = pci_get_drvdata(pci_dev);
3949
3950 if (bttv_verbose)
3951 printk("bttv%d: unloading\n",btv->c.nr);
3952
3953 /* shutdown everything (DMA+IRQs) */
3954 btand(~15, BT848_GPIO_DMA_CTL);
3955 btwrite(0, BT848_INT_MASK);
3956 btwrite(~0x0, BT848_INT_STAT);
3957 btwrite(0x0, BT848_GPIO_OUT_EN);
3958 if (bttv_gpio)
3959 bttv_gpio_tracking(btv,"cleanup");
3960
3961 /* tell gpio modules we are leaving ... */
3962 btv->shutdown=1;
3963 wake_up(&btv->gpioq);
3964 bttv_sub_del_devices(&btv->c);
3965
3966 /* unregister i2c_bus + input */
3967 fini_bttv_i2c(btv);
3968
3969 /* unregister video4linux */
3970 bttv_unregister_video(btv);
3971
3972 /* free allocated memory */
3973 btcx_riscmem_free(btv->c.pci,&btv->main);
3974
3975 /* free ressources */
3976 free_irq(btv->c.pci->irq,btv);
3977 iounmap(btv->bt848_mmio);
3978 release_mem_region(pci_resource_start(btv->c.pci,0),
3979 pci_resource_len(btv->c.pci,0));
3980
3981 pci_set_drvdata(pci_dev, NULL);
3982 return;
3983}
3984
3985static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
3986{
3987 struct bttv *btv = pci_get_drvdata(pci_dev);
3988 struct bttv_buffer_set idle;
3989 unsigned long flags;
3990
3991 dprintk("bttv%d: suspend %d\n", btv->c.nr, state);
3992
3993 /* stop dma + irqs */
3994 spin_lock_irqsave(&btv->s_lock,flags);
3995 memset(&idle, 0, sizeof(idle));
3996 btv->state.video = btv->curr;
3997 btv->state.vbi = btv->cvbi;
3998 btv->state.loop_irq = btv->loop_irq;
3999 btv->curr = idle;
4000 btv->loop_irq = 0;
4001 bttv_buffer_activate_video(btv, &idle);
4002 bttv_buffer_activate_vbi(btv, NULL);
4003 bttv_set_dma(btv, 0);
4004 btwrite(0, BT848_INT_MASK);
4005 spin_unlock_irqrestore(&btv->s_lock,flags);
4006
4007 /* save bt878 state */
4008 btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
4009 btv->state.gpio_data = gpio_read();
4010
4011 /* save pci state */
4012 pci_save_state(pci_dev);
4013 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
4014 pci_disable_device(pci_dev);
4015 btv->state.disabled = 1;
4016 }
4017 return 0;
4018}
4019
4020static int bttv_resume(struct pci_dev *pci_dev)
4021{
4022 struct bttv *btv = pci_get_drvdata(pci_dev);
4023 unsigned long flags;
4024
4025 dprintk("bttv%d: resume\n", btv->c.nr);
4026
4027 /* restore pci state */
4028 if (btv->state.disabled) {
4029 pci_enable_device(pci_dev);
4030 btv->state.disabled = 0;
4031 }
4032 pci_set_power_state(pci_dev, PCI_D0);
4033 pci_restore_state(pci_dev);
4034
4035 /* restore bt878 state */
4036 bttv_reinit_bt848(btv);
4037 gpio_inout(0xffffff, btv->state.gpio_enable);
4038 gpio_write(btv->state.gpio_data);
4039
4040 /* restart dma */
4041 spin_lock_irqsave(&btv->s_lock,flags);
4042 btv->curr = btv->state.video;
4043 btv->cvbi = btv->state.vbi;
4044 btv->loop_irq = btv->state.loop_irq;
4045 bttv_buffer_activate_video(btv, &btv->curr);
4046 bttv_buffer_activate_vbi(btv, btv->cvbi);
4047 bttv_set_dma(btv, 0);
4048 spin_unlock_irqrestore(&btv->s_lock,flags);
4049 return 0;
4050}
4051
4052static struct pci_device_id bttv_pci_tbl[] = {
4053 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4054 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4055 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4056 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4057 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4058 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4059 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4060 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4061 {0,}
4062};
4063
4064MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4065
4066static struct pci_driver bttv_pci_driver = {
4067 .name = "bttv",
4068 .id_table = bttv_pci_tbl,
4069 .probe = bttv_probe,
4070 .remove = __devexit_p(bttv_remove),
4071 .suspend = bttv_suspend,
4072 .resume = bttv_resume,
4073};
4074
4075static int bttv_init_module(void)
4076{
4077 bttv_num = 0;
4078
4079 printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
4080 (BTTV_VERSION_CODE >> 16) & 0xff,
4081 (BTTV_VERSION_CODE >> 8) & 0xff,
4082 BTTV_VERSION_CODE & 0xff);
4083#ifdef SNAPSHOT
4084 printk(KERN_INFO "bttv: snapshot date %04d-%02d-%02d\n",
4085 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
4086#endif
4087 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
4088 gbuffers = 2;
4089 if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
4090 gbufsize = BTTV_MAX_FBUF;
4091 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
4092 if (bttv_verbose)
4093 printk(KERN_INFO "bttv: using %d buffers with %dk (%d pages) each for capture\n",
4094 gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT);
4095
4096 bttv_check_chipset();
4097
4098 bus_register(&bttv_sub_bus_type);
4099 return pci_module_init(&bttv_pci_driver);
4100}
4101
4102static void bttv_cleanup_module(void)
4103{
4104 pci_unregister_driver(&bttv_pci_driver);
4105 bus_unregister(&bttv_sub_bus_type);
4106 return;
4107}
4108
4109module_init(bttv_init_module);
4110module_exit(bttv_cleanup_module);
4111
4112/*
4113 * Local variables:
4114 * c-basic-offset: 8
4115 * End:
4116 */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
new file mode 100644
index 000000000000..77320cdf205f
--- /dev/null
+++ b/drivers/media/video/bttv-gpio.c
@@ -0,0 +1,190 @@
1/*
2 $Id: bttv-gpio.c,v 1.7 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv-gpio.c -- gpio sub drivers
5
6 sysfs-based sub driver interface for bttv
7 mainly intented for gpio access
8
9
10 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 & Marcus Metzler (mocm@thp.uni-koeln.de)
12 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28*/
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/device.h>
34#include <asm/io.h>
35
36#include "bttvp.h"
37
38/* ----------------------------------------------------------------------- */
39/* internal: the bttv "bus" */
40
41static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
42{
43 struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
44 int len = strlen(sub->wanted);
45
46 if (0 == strncmp(dev->bus_id, sub->wanted, len))
47 return 1;
48 return 0;
49}
50
51struct bus_type bttv_sub_bus_type = {
52 .name = "bttv-sub",
53 .match = &bttv_sub_bus_match,
54};
55EXPORT_SYMBOL(bttv_sub_bus_type);
56
57static void release_sub_device(struct device *dev)
58{
59 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
60 kfree(sub);
61}
62
63int bttv_sub_add_device(struct bttv_core *core, char *name)
64{
65 struct bttv_sub_device *sub;
66 int err;
67
68 sub = kmalloc(sizeof(*sub),GFP_KERNEL);
69 if (NULL == sub)
70 return -ENOMEM;
71 memset(sub,0,sizeof(*sub));
72
73 sub->core = core;
74 sub->dev.parent = &core->pci->dev;
75 sub->dev.bus = &bttv_sub_bus_type;
76 sub->dev.release = release_sub_device;
77 snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d",
78 name, core->nr);
79
80 err = device_register(&sub->dev);
81 if (0 != err) {
82 kfree(sub);
83 return err;
84 }
85 printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id);
86 list_add_tail(&sub->list,&core->subs);
87 return 0;
88}
89
90int bttv_sub_del_devices(struct bttv_core *core)
91{
92 struct bttv_sub_device *sub;
93 struct list_head *item,*save;
94
95 list_for_each_safe(item,save,&core->subs) {
96 sub = list_entry(item,struct bttv_sub_device,list);
97 list_del(&sub->list);
98 device_unregister(&sub->dev);
99 }
100 return 0;
101}
102
103void bttv_gpio_irq(struct bttv_core *core)
104{
105 struct bttv_sub_driver *drv;
106 struct bttv_sub_device *dev;
107 struct list_head *item;
108
109 list_for_each(item,&core->subs) {
110 dev = list_entry(item,struct bttv_sub_device,list);
111 drv = to_bttv_sub_drv(dev->dev.driver);
112 if (drv && drv->gpio_irq)
113 drv->gpio_irq(dev);
114 }
115}
116
117/* ----------------------------------------------------------------------- */
118/* external: sub-driver register/unregister */
119
120int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
121{
122 sub->drv.bus = &bttv_sub_bus_type;
123 snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
124 return driver_register(&sub->drv);
125}
126EXPORT_SYMBOL(bttv_sub_register);
127
128int bttv_sub_unregister(struct bttv_sub_driver *sub)
129{
130 driver_unregister(&sub->drv);
131 return 0;
132}
133EXPORT_SYMBOL(bttv_sub_unregister);
134
135/* ----------------------------------------------------------------------- */
136/* external: gpio access functions */
137
138void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
139{
140 struct bttv *btv = container_of(core, struct bttv, c);
141 unsigned long flags;
142 u32 data;
143
144 spin_lock_irqsave(&btv->gpio_lock,flags);
145 data = btread(BT848_GPIO_OUT_EN);
146 data = data & ~mask;
147 data = data | (mask & outbits);
148 btwrite(data,BT848_GPIO_OUT_EN);
149 spin_unlock_irqrestore(&btv->gpio_lock,flags);
150}
151EXPORT_SYMBOL(bttv_gpio_inout);
152
153u32 bttv_gpio_read(struct bttv_core *core)
154{
155 struct bttv *btv = container_of(core, struct bttv, c);
156 u32 value;
157
158 value = btread(BT848_GPIO_DATA);
159 return value;
160}
161EXPORT_SYMBOL(bttv_gpio_read);
162
163void bttv_gpio_write(struct bttv_core *core, u32 value)
164{
165 struct bttv *btv = container_of(core, struct bttv, c);
166
167 btwrite(value,BT848_GPIO_DATA);
168}
169EXPORT_SYMBOL(bttv_gpio_write);
170
171void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
172{
173 struct bttv *btv = container_of(core, struct bttv, c);
174 unsigned long flags;
175 u32 data;
176
177 spin_lock_irqsave(&btv->gpio_lock,flags);
178 data = btread(BT848_GPIO_DATA);
179 data = data & ~mask;
180 data = data | (mask & bits);
181 btwrite(data,BT848_GPIO_DATA);
182 spin_unlock_irqrestore(&btv->gpio_lock,flags);
183}
184EXPORT_SYMBOL(bttv_gpio_bits);
185
186/*
187 * Local variables:
188 * c-basic-offset: 8
189 * End:
190 */
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
new file mode 100644
index 000000000000..e42f1ec13f3e
--- /dev/null
+++ b/drivers/media/video/bttv-i2c.c
@@ -0,0 +1,461 @@
1/*
2 $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv-i2c.c -- all the i2c code is here
5
6 bttv - Bt848 frame grabber driver
7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <asm/io.h>
33
34#include "bttvp.h"
35
36static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
37static struct i2c_adapter bttv_i2c_adap_sw_template;
38static struct i2c_adapter bttv_i2c_adap_hw_template;
39static struct i2c_client bttv_i2c_client_template;
40
41static int attach_inform(struct i2c_client *client);
42
43static int i2c_debug = 0;
44static int i2c_hw = 0;
45static int i2c_scan = 0;
46module_param(i2c_debug, int, 0644);
47module_param(i2c_hw, int, 0444);
48module_param(i2c_scan, int, 0444);
49MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
50
51/* ----------------------------------------------------------------------- */
52/* I2C functions - bitbanging adapter (software i2c) */
53
54static void bttv_bit_setscl(void *data, int state)
55{
56 struct bttv *btv = (struct bttv*)data;
57
58 if (state)
59 btv->i2c_state |= 0x02;
60 else
61 btv->i2c_state &= ~0x02;
62 btwrite(btv->i2c_state, BT848_I2C);
63 btread(BT848_I2C);
64}
65
66static void bttv_bit_setsda(void *data, int state)
67{
68 struct bttv *btv = (struct bttv*)data;
69
70 if (state)
71 btv->i2c_state |= 0x01;
72 else
73 btv->i2c_state &= ~0x01;
74 btwrite(btv->i2c_state, BT848_I2C);
75 btread(BT848_I2C);
76}
77
78static int bttv_bit_getscl(void *data)
79{
80 struct bttv *btv = (struct bttv*)data;
81 int state;
82
83 state = btread(BT848_I2C) & 0x02 ? 1 : 0;
84 return state;
85}
86
87static int bttv_bit_getsda(void *data)
88{
89 struct bttv *btv = (struct bttv*)data;
90 int state;
91
92 state = btread(BT848_I2C) & 0x01;
93 return state;
94}
95
96static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
97 .setsda = bttv_bit_setsda,
98 .setscl = bttv_bit_setscl,
99 .getsda = bttv_bit_getsda,
100 .getscl = bttv_bit_getscl,
101 .udelay = 16,
102 .mdelay = 10,
103 .timeout = 200,
104};
105
106static struct i2c_adapter bttv_i2c_adap_sw_template = {
107 .owner = THIS_MODULE,
108#ifdef I2C_CLASS_TV_ANALOG
109 .class = I2C_CLASS_TV_ANALOG,
110#endif
111 I2C_DEVNAME("bt848"),
112 .id = I2C_HW_B_BT848,
113 .client_register = attach_inform,
114};
115
116/* ----------------------------------------------------------------------- */
117/* I2C functions - hardware i2c */
118
119static int algo_control(struct i2c_adapter *adapter,
120 unsigned int cmd, unsigned long arg)
121{
122 return 0;
123}
124
125static u32 functionality(struct i2c_adapter *adap)
126{
127 return I2C_FUNC_SMBUS_EMUL;
128}
129
130static int
131bttv_i2c_wait_done(struct bttv *btv)
132{
133 DECLARE_WAITQUEUE(wait, current);
134 int rc = 0;
135
136 add_wait_queue(&btv->i2c_queue, &wait);
137 if (0 == btv->i2c_done)
138 msleep_interruptible(20);
139 remove_wait_queue(&btv->i2c_queue, &wait);
140
141 if (0 == btv->i2c_done)
142 /* timeout */
143 rc = -EIO;
144 if (btv->i2c_done & BT848_INT_RACK)
145 rc = 1;
146 btv->i2c_done = 0;
147 return rc;
148}
149
150#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\
151 BT848_I2C_SCL | BT848_I2C_SDA)
152
153static int
154bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
155{
156 u32 xmit;
157 int retval,cnt;
158
159 /* sanity checks */
160 if (0 == msg->len)
161 return -EINVAL;
162
163 /* start, address + first byte */
164 xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;
165 if (msg->len > 1 || !last)
166 xmit |= BT878_I2C_NOSTOP;
167 btwrite(xmit, BT848_I2C);
168 retval = bttv_i2c_wait_done(btv);
169 if (retval < 0)
170 goto err;
171 if (retval == 0)
172 goto eio;
173 if (i2c_debug) {
174 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
175 if (!(xmit & BT878_I2C_NOSTOP))
176 printk(" >\n");
177 }
178
179 for (cnt = 1; cnt < msg->len; cnt++ ) {
180 /* following bytes */
181 xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;
182 if (cnt < msg->len-1 || !last)
183 xmit |= BT878_I2C_NOSTOP;
184 btwrite(xmit, BT848_I2C);
185 retval = bttv_i2c_wait_done(btv);
186 if (retval < 0)
187 goto err;
188 if (retval == 0)
189 goto eio;
190 if (i2c_debug) {
191 printk(" %02x", msg->buf[cnt]);
192 if (!(xmit & BT878_I2C_NOSTOP))
193 printk(" >\n");
194 }
195 }
196 return msg->len;
197
198 eio:
199 retval = -EIO;
200 err:
201 if (i2c_debug)
202 printk(" ERR: %d\n",retval);
203 return retval;
204}
205
206static int
207bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
208{
209 u32 xmit;
210 u32 cnt;
211 int retval;
212
213 for(cnt = 0; cnt < msg->len; cnt++) {
214 xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;
215 if (cnt < msg->len-1)
216 xmit |= BT848_I2C_W3B;
217 if (cnt < msg->len-1 || !last)
218 xmit |= BT878_I2C_NOSTOP;
219 if (cnt)
220 xmit |= BT878_I2C_NOSTART;
221 btwrite(xmit, BT848_I2C);
222 retval = bttv_i2c_wait_done(btv);
223 if (retval < 0)
224 goto err;
225 if (retval == 0)
226 goto eio;
227 msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;
228 if (i2c_debug) {
229 if (!(xmit & BT878_I2C_NOSTART))
230 printk(" <R %02x", (msg->addr << 1) +1);
231 printk(" =%02x", msg->buf[cnt]);
232 if (!(xmit & BT878_I2C_NOSTOP))
233 printk(" >\n");
234 }
235 }
236 return msg->len;
237
238 eio:
239 retval = -EIO;
240 err:
241 if (i2c_debug)
242 printk(" ERR: %d\n",retval);
243 return retval;
244}
245
246static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
247{
248 struct bttv *btv = i2c_get_adapdata(i2c_adap);
249 int retval = 0;
250 int i;
251
252 if (i2c_debug)
253 printk("bt-i2c:");
254 btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);
255 for (i = 0 ; i < num; i++) {
256 if (msgs[i].flags & I2C_M_RD) {
257 /* read */
258 retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);
259 if (retval < 0)
260 goto err;
261 } else {
262 /* write */
263 retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);
264 if (retval < 0)
265 goto err;
266 }
267 }
268 return num;
269
270 err:
271 return retval;
272}
273
274static struct i2c_algorithm bttv_algo = {
275 .name = "bt878",
276 .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */,
277 .master_xfer = bttv_i2c_xfer,
278 .algo_control = algo_control,
279 .functionality = functionality,
280};
281
282static struct i2c_adapter bttv_i2c_adap_hw_template = {
283 .owner = THIS_MODULE,
284#ifdef I2C_CLASS_TV_ANALOG
285 .class = I2C_CLASS_TV_ANALOG,
286#endif
287 I2C_DEVNAME("bt878"),
288 .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */,
289 .algo = &bttv_algo,
290 .client_register = attach_inform,
291};
292
293/* ----------------------------------------------------------------------- */
294/* I2C functions - common stuff */
295
296static int attach_inform(struct i2c_client *client)
297{
298 struct bttv *btv = i2c_get_adapdata(client->adapter);
299
300 if (btv->tuner_type != UNSET)
301 bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
302 if (btv->pinnacle_id != UNSET)
303 bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
304 &btv->pinnacle_id);
305 if (bttv_debug)
306 printk("bttv%d: i2c attach [client=%s]\n",
307 btv->c.nr, i2c_clientname(client));
308 return 0;
309}
310
311void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
312{
313 if (0 != btv->i2c_rc)
314 return;
315 i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
316}
317
318static struct i2c_client bttv_i2c_client_template = {
319 I2C_DEVNAME("bttv internal"),
320};
321
322
323/* read I2C */
324int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
325{
326 unsigned char buffer = 0;
327
328 if (0 != btv->i2c_rc)
329 return -1;
330 if (bttv_verbose && NULL != probe_for)
331 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
332 btv->c.nr,probe_for,addr);
333 btv->i2c_client.addr = addr >> 1;
334 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
335 if (NULL != probe_for) {
336 if (bttv_verbose)
337 printk("not found\n");
338 } else
339 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
340 btv->c.nr,addr);
341 return -1;
342 }
343 if (bttv_verbose && NULL != probe_for)
344 printk("found\n");
345 return buffer;
346}
347
348/* write I2C */
349int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
350 unsigned char b2, int both)
351{
352 unsigned char buffer[2];
353 int bytes = both ? 2 : 1;
354
355 if (0 != btv->i2c_rc)
356 return -1;
357 btv->i2c_client.addr = addr >> 1;
358 buffer[0] = b1;
359 buffer[1] = b2;
360 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
361 return -1;
362 return 0;
363}
364
365/* read EEPROM content */
366void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
367{
368 btv->i2c_client.addr = addr >> 1;
369 tveeprom_read(&btv->i2c_client, eedata, 256);
370}
371
372static char *i2c_devs[128] = {
373 [ 0x30 >> 1 ] = "IR (hauppauge)",
374 [ 0x80 >> 1 ] = "msp34xx",
375 [ 0x86 >> 1 ] = "tda9887",
376 [ 0xa0 >> 1 ] = "eeprom",
377 [ 0xc0 >> 1 ] = "tuner (analog)",
378 [ 0xc2 >> 1 ] = "tuner (analog)",
379};
380
381static void do_i2c_scan(char *name, struct i2c_client *c)
382{
383 unsigned char buf;
384 int i,rc;
385
386 for (i = 0; i < 128; i++) {
387 c->addr = i;
388 rc = i2c_master_recv(c,&buf,0);
389 if (rc < 0)
390 continue;
391 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
392 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
393 }
394}
395
396/* init + register i2c algo-bit adapter */
397int __devinit init_bttv_i2c(struct bttv *btv)
398{
399 memcpy(&btv->i2c_client, &bttv_i2c_client_template,
400 sizeof(bttv_i2c_client_template));
401
402 if (i2c_hw)
403 btv->use_i2c_hw = 1;
404 if (btv->use_i2c_hw) {
405 /* bt878 */
406 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template,
407 sizeof(bttv_i2c_adap_hw_template));
408 } else {
409 /* bt848 */
410 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
411 sizeof(bttv_i2c_adap_sw_template));
412 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
413 sizeof(bttv_i2c_algo_bit_template));
414 btv->i2c_algo.data = btv;
415 btv->c.i2c_adap.algo_data = &btv->i2c_algo;
416 }
417
418 btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
419 snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
420 "bt%d #%d [%s]", btv->id, btv->c.nr,
421 btv->use_i2c_hw ? "hw" : "sw");
422
423 i2c_set_adapdata(&btv->c.i2c_adap, btv);
424 btv->i2c_client.adapter = &btv->c.i2c_adap;
425
426#ifdef I2C_CLASS_TV_ANALOG
427 if (bttv_tvcards[btv->c.type].no_video)
428 btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
429 if (bttv_tvcards[btv->c.type].has_dvb)
430 btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
431#endif
432
433 if (btv->use_i2c_hw) {
434 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
435 } else {
436 bttv_bit_setscl(btv,1);
437 bttv_bit_setsda(btv,1);
438 btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
439 }
440 if (0 == btv->i2c_rc && i2c_scan)
441 do_i2c_scan(btv->c.name,&btv->i2c_client);
442 return btv->i2c_rc;
443}
444
445int __devexit fini_bttv_i2c(struct bttv *btv)
446{
447 if (0 != btv->i2c_rc)
448 return 0;
449
450 if (btv->use_i2c_hw) {
451 return i2c_del_adapter(&btv->c.i2c_adap);
452 } else {
453 return i2c_bit_del_bus(&btv->c.i2c_adap);
454 }
455}
456
457/*
458 * Local variables:
459 * c-basic-offset: 8
460 * End:
461 */
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
new file mode 100644
index 000000000000..f7b5543a96a1
--- /dev/null
+++ b/drivers/media/video/bttv-if.c
@@ -0,0 +1,160 @@
1/*
2 $Id: bttv-if.c,v 1.4 2004/11/17 18:47:47 kraxel Exp $
3
4 bttv-if.c -- old gpio interface to other kernel modules
5 don't use in new code, will go away in 2.7
6 have a look at bttv-gpio.c instead.
7
8 bttv - Bt848 frame grabber driver
9
10 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 & Marcus Metzler (mocm@thp.uni-koeln.de)
12 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28*/
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <asm/io.h>
34
35#include "bttvp.h"
36
37EXPORT_SYMBOL(bttv_get_cardinfo);
38EXPORT_SYMBOL(bttv_get_pcidev);
39EXPORT_SYMBOL(bttv_get_id);
40EXPORT_SYMBOL(bttv_gpio_enable);
41EXPORT_SYMBOL(bttv_read_gpio);
42EXPORT_SYMBOL(bttv_write_gpio);
43EXPORT_SYMBOL(bttv_get_gpio_queue);
44EXPORT_SYMBOL(bttv_i2c_call);
45
46/* ----------------------------------------------------------------------- */
47/* Exported functions - for other modules which want to access the */
48/* gpio ports (IR for example) */
49/* see bttv.h for comments */
50
51int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid)
52{
53 printk("The bttv_* interface is obsolete and will go away,\n"
54 "please use the new, sysfs based interface instead.\n");
55 if (card >= bttv_num) {
56 return -1;
57 }
58 *type = bttvs[card].c.type;
59 *cardid = bttvs[card].cardid;
60 return 0;
61}
62
63struct pci_dev* bttv_get_pcidev(unsigned int card)
64{
65 if (card >= bttv_num)
66 return NULL;
67 return bttvs[card].c.pci;
68}
69
70int bttv_get_id(unsigned int card)
71{
72 printk("The bttv_* interface is obsolete and will go away,\n"
73 "please use the new, sysfs based interface instead.\n");
74 if (card >= bttv_num) {
75 return -1;
76 }
77 return bttvs[card].c.type;
78}
79
80
81int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
82{
83 struct bttv *btv;
84
85 if (card >= bttv_num) {
86 return -EINVAL;
87 }
88
89 btv = &bttvs[card];
90 gpio_inout(mask,data);
91 if (bttv_gpio)
92 bttv_gpio_tracking(btv,"extern enable");
93 return 0;
94}
95
96int bttv_read_gpio(unsigned int card, unsigned long *data)
97{
98 struct bttv *btv;
99
100 if (card >= bttv_num) {
101 return -EINVAL;
102 }
103
104 btv = &bttvs[card];
105
106 if(btv->shutdown) {
107 return -ENODEV;
108 }
109
110/* prior setting BT848_GPIO_REG_INP is (probably) not needed
111 because we set direct input on init */
112 *data = gpio_read();
113 return 0;
114}
115
116int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
117{
118 struct bttv *btv;
119
120 if (card >= bttv_num) {
121 return -EINVAL;
122 }
123
124 btv = &bttvs[card];
125
126/* prior setting BT848_GPIO_REG_INP is (probably) not needed
127 because direct input is set on init */
128 gpio_bits(mask,data);
129 if (bttv_gpio)
130 bttv_gpio_tracking(btv,"extern write");
131 return 0;
132}
133
134wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
135{
136 struct bttv *btv;
137
138 if (card >= bttv_num) {
139 return NULL;
140 }
141
142 btv = &bttvs[card];
143 if (bttvs[card].shutdown) {
144 return NULL;
145 }
146 return &btv->gpioq;
147}
148
149void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
150{
151 if (card >= bttv_num)
152 return;
153 bttv_call_i2c_clients(&bttvs[card], cmd, arg);
154}
155
156/*
157 * Local variables:
158 * c-basic-offset: 8
159 * End:
160 */
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
new file mode 100644
index 000000000000..bdc5ce6c43b9
--- /dev/null
+++ b/drivers/media/video/bttv-risc.c
@@ -0,0 +1,802 @@
1/*
2 $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
3
4 bttv-risc.c -- interfaces to other kernel modules
5
6 bttv risc code handling
7 - memory management
8 - generation
9
10 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/vmalloc.h>
32#include <linux/interrupt.h>
33#include <asm/page.h>
34#include <asm/pgtable.h>
35
36#include "bttvp.h"
37
38#define VCR_HACK_LINES 4
39
40/* ---------------------------------------------------------- */
41/* risc code generators */
42
43int
44bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
45 struct scatterlist *sglist,
46 unsigned int offset, unsigned int bpl,
47 unsigned int padding, unsigned int lines)
48{
49 u32 instructions,line,todo;
50 struct scatterlist *sg;
51 u32 *rp;
52 int rc;
53
54 /* estimate risc mem: worst case is one write per page border +
55 one write per scan line + sync + jump (all 2 dwords) */
56 instructions = (bpl * lines) / PAGE_SIZE + lines;
57 instructions += 2;
58 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
59 return rc;
60
61 /* sync instruction */
62 rp = risc->cpu;
63 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
64 *(rp++) = cpu_to_le32(0);
65
66 /* scan lines */
67 sg = sglist;
68 for (line = 0; line < lines; line++) {
69 if ((btv->opt_vcr_hack) &&
70 (line >= (lines - VCR_HACK_LINES)))
71 continue;
72 while (offset && offset >= sg_dma_len(sg)) {
73 offset -= sg_dma_len(sg);
74 sg++;
75 }
76 if (bpl <= sg_dma_len(sg)-offset) {
77 /* fits into current chunk */
78 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
79 BT848_RISC_EOL|bpl);
80 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
81 offset+=bpl;
82 } else {
83 /* scanline needs to be splitted */
84 todo = bpl;
85 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
86 (sg_dma_len(sg)-offset));
87 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
88 todo -= (sg_dma_len(sg)-offset);
89 offset = 0;
90 sg++;
91 while (todo > sg_dma_len(sg)) {
92 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
93 sg_dma_len(sg));
94 *(rp++)=cpu_to_le32(sg_dma_address(sg));
95 todo -= sg_dma_len(sg);
96 sg++;
97 }
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
99 todo);
100 *(rp++)=cpu_to_le32(sg_dma_address(sg));
101 offset += todo;
102 }
103 offset += padding;
104 }
105
106 /* save pointer to jmp instruction address */
107 risc->jmp = rp;
108 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
109 return 0;
110}
111
112static int
113bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
114 struct scatterlist *sglist,
115 unsigned int yoffset, unsigned int ybpl,
116 unsigned int ypadding, unsigned int ylines,
117 unsigned int uoffset, unsigned int voffset,
118 unsigned int hshift, unsigned int vshift,
119 unsigned int cpadding)
120{
121 unsigned int instructions,line,todo,ylen,chroma;
122 u32 *rp,ri;
123 struct scatterlist *ysg;
124 struct scatterlist *usg;
125 struct scatterlist *vsg;
126 int topfield = (0 == yoffset);
127 int rc;
128
129 /* estimate risc mem: worst case is one write per page border +
130 one write per scan line (5 dwords)
131 plus sync + jump (2 dwords) */
132 instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
133 instructions += 2;
134 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
135 return rc;
136
137 /* sync instruction */
138 rp = risc->cpu;
139 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
140 *(rp++) = cpu_to_le32(0);
141
142 /* scan lines */
143 ysg = sglist;
144 usg = sglist;
145 vsg = sglist;
146 for (line = 0; line < ylines; line++) {
147 if ((btv->opt_vcr_hack) &&
148 (line >= (ylines - VCR_HACK_LINES)))
149 continue;
150 switch (vshift) {
151 case 0:
152 chroma = 1;
153 break;
154 case 1:
155 if (topfield)
156 chroma = ((line & 1) == 0);
157 else
158 chroma = ((line & 1) == 1);
159 break;
160 case 2:
161 if (topfield)
162 chroma = ((line & 3) == 0);
163 else
164 chroma = ((line & 3) == 2);
165 break;
166 default:
167 chroma = 0;
168 break;
169 }
170
171 for (todo = ybpl; todo > 0; todo -= ylen) {
172 /* go to next sg entry if needed */
173 while (yoffset && yoffset >= sg_dma_len(ysg)) {
174 yoffset -= sg_dma_len(ysg);
175 ysg++;
176 }
177 while (uoffset && uoffset >= sg_dma_len(usg)) {
178 uoffset -= sg_dma_len(usg);
179 usg++;
180 }
181 while (voffset && voffset >= sg_dma_len(vsg)) {
182 voffset -= sg_dma_len(vsg);
183 vsg++;
184 }
185
186 /* calculate max number of bytes we can write */
187 ylen = todo;
188 if (yoffset + ylen > sg_dma_len(ysg))
189 ylen = sg_dma_len(ysg) - yoffset;
190 if (chroma) {
191 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
192 ylen = (sg_dma_len(usg) - uoffset) << hshift;
193 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
194 ylen = (sg_dma_len(vsg) - voffset) << hshift;
195 ri = BT848_RISC_WRITE123;
196 } else {
197 ri = BT848_RISC_WRITE1S23;
198 }
199 if (ybpl == todo)
200 ri |= BT848_RISC_SOL;
201 if (ylen == todo)
202 ri |= BT848_RISC_EOL;
203
204 /* write risc instruction */
205 *(rp++)=cpu_to_le32(ri | ylen);
206 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
207 (ylen >> hshift));
208 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
209 yoffset += ylen;
210 if (chroma) {
211 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
212 uoffset += ylen >> hshift;
213 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
214 voffset += ylen >> hshift;
215 }
216 }
217 yoffset += ypadding;
218 if (chroma) {
219 uoffset += cpadding;
220 voffset += cpadding;
221 }
222 }
223
224 /* save pointer to jmp instruction address */
225 risc->jmp = rp;
226 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
227 return 0;
228}
229
230static int
231bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
232 const struct bttv_format *fmt, struct bttv_overlay *ov,
233 int skip_even, int skip_odd)
234{
235 int instructions,rc,line,maxy,start,end,skip,nskips;
236 struct btcx_skiplist *skips;
237 u32 *rp,ri,ra;
238 u32 addr;
239
240 /* skip list for window clipping */
241 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
242 return -ENOMEM;
243
244 /* estimate risc mem: worst case is (clip+1) * lines instructions
245 + sync + jump (all 2 dwords) */
246 instructions = (ov->nclips + 1) *
247 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
248 instructions += 2;
249 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
250 kfree(skips);
251 return rc;
252 }
253
254 /* sync instruction */
255 rp = risc->cpu;
256 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
257 *(rp++) = cpu_to_le32(0);
258
259 addr = (unsigned long)btv->fbuf.base;
260 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
261 addr += (fmt->depth >> 3) * ov->w.left;
262
263 /* scan lines */
264 for (maxy = -1, line = 0; line < ov->w.height;
265 line++, addr += btv->fbuf.fmt.bytesperline) {
266 if ((btv->opt_vcr_hack) &&
267 (line >= (ov->w.height - VCR_HACK_LINES)))
268 continue;
269 if ((line%2) == 0 && skip_even)
270 continue;
271 if ((line%2) == 1 && skip_odd)
272 continue;
273
274 /* calculate clipping */
275 if (line > maxy)
276 btcx_calc_skips(line, ov->w.width, &maxy,
277 skips, &nskips, ov->clips, ov->nclips);
278
279 /* write out risc code */
280 for (start = 0, skip = 0; start < ov->w.width; start = end) {
281 if (skip >= nskips) {
282 ri = BT848_RISC_WRITE;
283 end = ov->w.width;
284 } else if (start < skips[skip].start) {
285 ri = BT848_RISC_WRITE;
286 end = skips[skip].start;
287 } else {
288 ri = BT848_RISC_SKIP;
289 end = skips[skip].end;
290 skip++;
291 }
292 if (BT848_RISC_WRITE == ri)
293 ra = addr + (fmt->depth>>3)*start;
294 else
295 ra = 0;
296
297 if (0 == start)
298 ri |= BT848_RISC_SOL;
299 if (ov->w.width == end)
300 ri |= BT848_RISC_EOL;
301 ri |= (fmt->depth>>3) * (end-start);
302
303 *(rp++)=cpu_to_le32(ri);
304 if (0 != ra)
305 *(rp++)=cpu_to_le32(ra);
306 }
307 }
308
309 /* save pointer to jmp instruction address */
310 risc->jmp = rp;
311 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
312 kfree(skips);
313 return 0;
314}
315
316/* ---------------------------------------------------------- */
317
318static void
319bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
320 int width, int height, int interleaved, int norm)
321{
322 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
323 u32 xsf, sr;
324 int vdelay;
325
326 int swidth = tvnorm->swidth;
327 int totalwidth = tvnorm->totalwidth;
328 int scaledtwidth = tvnorm->scaledtwidth;
329
330 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
331 swidth = 720;
332 totalwidth = 858;
333 scaledtwidth = 858;
334 }
335
336 vdelay = tvnorm->vdelay;
337#if 0 /* FIXME */
338 if (vdelay < btv->vbi.lines*2)
339 vdelay = btv->vbi.lines*2;
340#endif
341
342 xsf = (width*scaledtwidth)/swidth;
343 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
344 geo->hdelay = tvnorm->hdelayx1;
345 geo->hdelay = (geo->hdelay*width)/swidth;
346 geo->hdelay &= 0x3fe;
347 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
348 geo->vscale = (0x10000UL-sr) & 0x1fff;
349 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
350 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
351 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
352 geo->vdelay = vdelay;
353 geo->width = width;
354 geo->sheight = tvnorm->sheight;
355 geo->vtotal = tvnorm->vtotal;
356
357 if (btv->opt_combfilter) {
358 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
359 geo->comb = (width < 769) ? 1 : 0;
360 } else {
361 geo->vtc = 0;
362 geo->comb = 0;
363 }
364}
365
366static void
367bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
368{
369 int off = odd ? 0x80 : 0x00;
370
371 if (geo->comb)
372 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
373 else
374 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
375
376 btwrite(geo->vtc, BT848_E_VTC+off);
377 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
378 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
379 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
380 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
381 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
382 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
383 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
384 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
385 btwrite(geo->crop, BT848_E_CROP+off);
386 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
387 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
388}
389
390/* ---------------------------------------------------------- */
391/* risc group / risc main loop / dma management */
392
393void
394bttv_set_dma(struct bttv *btv, int override)
395{
396 unsigned long cmd;
397 int capctl;
398
399 btv->cap_ctl = 0;
400 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
401 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
402 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
403
404 capctl = 0;
405 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
406 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
407 capctl |= override;
408
409 d2printk(KERN_DEBUG
410 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
411 btv->c.nr,capctl,btv->loop_irq,
412 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
413 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
414 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
415 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
416
417 cmd = BT848_RISC_JUMP;
418 if (btv->loop_irq) {
419 cmd |= BT848_RISC_IRQ;
420 cmd |= (btv->loop_irq & 0x0f) << 16;
421 cmd |= (~btv->loop_irq & 0x0f) << 20;
422 }
423 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
424 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
425 } else {
426 del_timer(&btv->timeout);
427 }
428 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
429
430 btaor(capctl, ~0x0f, BT848_CAP_CTL);
431 if (capctl) {
432 if (btv->dma_on)
433 return;
434 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
435 btor(3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 1;
437 } else {
438 if (!btv->dma_on)
439 return;
440 btand(~3, BT848_GPIO_DMA_CTL);
441 btv->dma_on = 0;
442 }
443 return;
444}
445
446int
447bttv_risc_init_main(struct bttv *btv)
448{
449 int rc;
450
451 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
452 return rc;
453 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
454 btv->c.nr,(unsigned long long)btv->main.dma);
455
456 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
457 BT848_FIFO_STATUS_VRE);
458 btv->main.cpu[1] = cpu_to_le32(0);
459 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
460 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
461
462 /* top field */
463 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
464 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
465 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
466 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
467
468 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
469 BT848_FIFO_STATUS_VRO);
470 btv->main.cpu[9] = cpu_to_le32(0);
471
472 /* bottom field */
473 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
474 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
475 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
476 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
477
478 /* jump back to top field */
479 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
480 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
481
482 return 0;
483}
484
485int
486bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
487 int irqflags)
488{
489 unsigned long cmd;
490 unsigned long next = btv->main.dma + ((slot+2) << 2);
491
492 if (NULL == risc) {
493 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
494 btv->c.nr,risc,slot);
495 btv->main.cpu[slot+1] = cpu_to_le32(next);
496 } else {
497 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
498 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
499 cmd = BT848_RISC_JUMP;
500 if (irqflags) {
501 cmd |= BT848_RISC_IRQ;
502 cmd |= (irqflags & 0x0f) << 16;
503 cmd |= (~irqflags & 0x0f) << 20;
504 }
505 risc->jmp[0] = cpu_to_le32(cmd);
506 risc->jmp[1] = cpu_to_le32(next);
507 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
508 }
509 return 0;
510}
511
512void
513bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
514{
515 if (in_interrupt())
516 BUG();
517 videobuf_waiton(&buf->vb,0,0);
518 videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
519 videobuf_dma_free(&buf->vb.dma);
520 btcx_riscmem_free(btv->c.pci,&buf->bottom);
521 btcx_riscmem_free(btv->c.pci,&buf->top);
522 buf->vb.state = STATE_NEEDS_INIT;
523}
524
525int
526bttv_buffer_activate_vbi(struct bttv *btv,
527 struct bttv_buffer *vbi)
528{
529 /* vbi capture */
530 if (vbi) {
531 vbi->vb.state = STATE_ACTIVE;
532 list_del(&vbi->vb.queue);
533 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
534 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
535 } else {
536 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
537 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
538 }
539 return 0;
540}
541
542int
543bttv_buffer_activate_video(struct bttv *btv,
544 struct bttv_buffer_set *set)
545{
546 /* video capture */
547 if (NULL != set->top && NULL != set->bottom) {
548 if (set->top == set->bottom) {
549 set->top->vb.state = STATE_ACTIVE;
550 if (set->top->vb.queue.next)
551 list_del(&set->top->vb.queue);
552 } else {
553 set->top->vb.state = STATE_ACTIVE;
554 set->bottom->vb.state = STATE_ACTIVE;
555 if (set->top->vb.queue.next)
556 list_del(&set->top->vb.queue);
557 if (set->bottom->vb.queue.next)
558 list_del(&set->bottom->vb.queue);
559 }
560 bttv_apply_geo(btv, &set->top->geo, 1);
561 bttv_apply_geo(btv, &set->bottom->geo,0);
562 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
563 set->top_irq);
564 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
565 set->frame_irq);
566 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
567 ~0xff, BT848_COLOR_FMT);
568 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
569 ~0x0f, BT848_COLOR_CTL);
570 } else if (NULL != set->top) {
571 set->top->vb.state = STATE_ACTIVE;
572 if (set->top->vb.queue.next)
573 list_del(&set->top->vb.queue);
574 bttv_apply_geo(btv, &set->top->geo,1);
575 bttv_apply_geo(btv, &set->top->geo,0);
576 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
577 set->frame_irq);
578 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
579 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
580 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
581 } else if (NULL != set->bottom) {
582 set->bottom->vb.state = STATE_ACTIVE;
583 if (set->bottom->vb.queue.next)
584 list_del(&set->bottom->vb.queue);
585 bttv_apply_geo(btv, &set->bottom->geo,1);
586 bttv_apply_geo(btv, &set->bottom->geo,0);
587 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
588 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
589 set->frame_irq);
590 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
591 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
592 } else {
593 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
594 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
595 }
596 return 0;
597}
598
599/* ---------------------------------------------------------- */
600
601/* calculate geometry, build risc code */
602int
603bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
604{
605 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
606
607 dprintk(KERN_DEBUG
608 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
609 btv->c.nr, v4l2_field_names[buf->vb.field],
610 buf->fmt->name, buf->vb.width, buf->vb.height);
611
612 /* packed pixel modes */
613 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
614 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
615 int bpf = bpl * (buf->vb.height >> 1);
616
617 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
618 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
619
620 switch (buf->vb.field) {
621 case V4L2_FIELD_TOP:
622 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
623 0,bpl,0,buf->vb.height);
624 break;
625 case V4L2_FIELD_BOTTOM:
626 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
627 0,bpl,0,buf->vb.height);
628 break;
629 case V4L2_FIELD_INTERLACED:
630 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
631 0,bpl,bpl,buf->vb.height >> 1);
632 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
633 bpl,bpl,bpl,buf->vb.height >> 1);
634 break;
635 case V4L2_FIELD_SEQ_TB:
636 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
637 0,bpl,0,buf->vb.height >> 1);
638 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
639 bpf,bpl,0,buf->vb.height >> 1);
640 break;
641 default:
642 BUG();
643 }
644 }
645
646 /* planar modes */
647 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
648 int uoffset, voffset;
649 int ypadding, cpadding, lines;
650
651 /* calculate chroma offsets */
652 uoffset = buf->vb.width * buf->vb.height;
653 voffset = buf->vb.width * buf->vb.height;
654 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
655 /* Y-Cr-Cb plane order */
656 uoffset >>= buf->fmt->hshift;
657 uoffset >>= buf->fmt->vshift;
658 uoffset += voffset;
659 } else {
660 /* Y-Cb-Cr plane order */
661 voffset >>= buf->fmt->hshift;
662 voffset >>= buf->fmt->vshift;
663 voffset += uoffset;
664 }
665
666 switch (buf->vb.field) {
667 case V4L2_FIELD_TOP:
668 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
669 buf->vb.height,0,buf->tvnorm);
670 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
671 0,buf->vb.width,0,buf->vb.height,
672 uoffset,voffset,buf->fmt->hshift,
673 buf->fmt->vshift,0);
674 break;
675 case V4L2_FIELD_BOTTOM:
676 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
677 buf->vb.height,0,buf->tvnorm);
678 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
679 0,buf->vb.width,0,buf->vb.height,
680 uoffset,voffset,buf->fmt->hshift,
681 buf->fmt->vshift,0);
682 break;
683 case V4L2_FIELD_INTERLACED:
684 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
685 buf->vb.height,1,buf->tvnorm);
686 lines = buf->vb.height >> 1;
687 ypadding = buf->vb.width;
688 cpadding = buf->vb.width >> buf->fmt->hshift;
689 bttv_risc_planar(btv,&buf->top,
690 buf->vb.dma.sglist,
691 0,buf->vb.width,ypadding,lines,
692 uoffset,voffset,
693 buf->fmt->hshift,
694 buf->fmt->vshift,
695 cpadding);
696 bttv_risc_planar(btv,&buf->bottom,
697 buf->vb.dma.sglist,
698 ypadding,buf->vb.width,ypadding,lines,
699 uoffset+cpadding,
700 voffset+cpadding,
701 buf->fmt->hshift,
702 buf->fmt->vshift,
703 cpadding);
704 break;
705 case V4L2_FIELD_SEQ_TB:
706 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
707 buf->vb.height,1,buf->tvnorm);
708 lines = buf->vb.height >> 1;
709 ypadding = buf->vb.width;
710 cpadding = buf->vb.width >> buf->fmt->hshift;
711 bttv_risc_planar(btv,&buf->top,
712 buf->vb.dma.sglist,
713 0,buf->vb.width,0,lines,
714 uoffset >> 1,
715 voffset >> 1,
716 buf->fmt->hshift,
717 buf->fmt->vshift,
718 0);
719 bttv_risc_planar(btv,&buf->bottom,
720 buf->vb.dma.sglist,
721 lines * ypadding,buf->vb.width,0,lines,
722 lines * ypadding + (uoffset >> 1),
723 lines * ypadding + (voffset >> 1),
724 buf->fmt->hshift,
725 buf->fmt->vshift,
726 0);
727 break;
728 default:
729 BUG();
730 }
731 }
732
733 /* raw data */
734 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
735 /* build risc code */
736 buf->vb.field = V4L2_FIELD_SEQ_TB;
737 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
738 1,buf->tvnorm);
739 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
740 0, RAW_BPL, 0, RAW_LINES);
741 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
742 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
743 }
744
745 /* copy format info */
746 buf->btformat = buf->fmt->btformat;
747 buf->btswap = buf->fmt->btswap;
748 return 0;
749}
750
751/* ---------------------------------------------------------- */
752
753/* calculate geometry, build risc code */
754int
755bttv_overlay_risc(struct bttv *btv,
756 struct bttv_overlay *ov,
757 const struct bttv_format *fmt,
758 struct bttv_buffer *buf)
759{
760 /* check interleave, bottom+top fields */
761 dprintk(KERN_DEBUG
762 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
763 btv->c.nr, v4l2_field_names[buf->vb.field],
764 fmt->name,ov->w.width,ov->w.height);
765
766 /* calculate geometry */
767 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
768 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
769
770 /* build risc code */
771 switch (ov->field) {
772 case V4L2_FIELD_TOP:
773 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
774 break;
775 case V4L2_FIELD_BOTTOM:
776 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
777 break;
778 case V4L2_FIELD_INTERLACED:
779#if 0
780 bttv_risc_overlay(btv, &buf->top, fmt, ov, 1, 0);
781 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
782#else
783 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
784 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
785#endif
786 break;
787 default:
788 BUG();
789 }
790
791 /* copy format info */
792 buf->btformat = fmt->btformat;
793 buf->btswap = fmt->btswap;
794 buf->vb.field = ov->field;
795 return 0;
796}
797
798/*
799 * Local variables:
800 * c-basic-offset: 8
801 * End:
802 */
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
new file mode 100644
index 000000000000..06f3e62b3e8d
--- /dev/null
+++ b/drivers/media/video/bttv-vbi.c
@@ -0,0 +1,235 @@
1/*
2 $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5 vbi interface
6
7 (c) 2002 Gerd Knorr <kraxel@bytesex.org>
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/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/fs.h>
28#include <linux/kernel.h>
29#include <linux/sched.h>
30#include <linux/interrupt.h>
31#include <linux/kdev_t.h>
32#include <asm/io.h>
33#include "bttvp.h"
34
35#define VBI_DEFLINES 16
36#define VBI_MAXLINES 32
37
38static unsigned int vbibufs = 4;
39static unsigned int vbi_debug = 0;
40
41module_param(vbibufs, int, 0444);
42module_param(vbi_debug, int, 0644);
43MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
44MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
45
46#ifdef dprintk
47# undef dprintk
48#endif
49#define dprintk(fmt, arg...) if (vbi_debug) \
50 printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)
51
52/* ----------------------------------------------------------------------- */
53/* vbi risc code + mm */
54
55static int
56vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
57{
58 int bpl = 2048;
59
60 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
61 0, bpl-4, 4, lines);
62 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
63 lines * bpl, bpl-4, 4, lines);
64 return 0;
65}
66
67static int vbi_buffer_setup(struct videobuf_queue *q,
68 unsigned int *count, unsigned int *size)
69{
70 struct bttv_fh *fh = q->priv_data;
71 struct bttv *btv = fh->btv;
72
73 if (0 == *count)
74 *count = vbibufs;
75 *size = fh->lines * 2 * 2048;
76 dprintk("setup: lines=%d\n",fh->lines);
77 return 0;
78}
79
80static int vbi_buffer_prepare(struct videobuf_queue *q,
81 struct videobuf_buffer *vb,
82 enum v4l2_field field)
83{
84 struct bttv_fh *fh = q->priv_data;
85 struct bttv *btv = fh->btv;
86 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
87 int rc;
88
89 buf->vb.size = fh->lines * 2 * 2048;
90 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
91 return -EINVAL;
92
93 if (STATE_NEEDS_INIT == buf->vb.state) {
94 if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL)))
95 goto fail;
96 if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
97 goto fail;
98 }
99 buf->vb.state = STATE_PREPARED;
100 buf->vb.field = field;
101 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
102 vb, &buf->top, &buf->bottom,
103 v4l2_field_names[buf->vb.field]);
104 return 0;
105
106 fail:
107 bttv_dma_free(btv,buf);
108 return rc;
109}
110
111static void
112vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
113{
114 struct bttv_fh *fh = q->priv_data;
115 struct bttv *btv = fh->btv;
116 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
117
118 dprintk("queue %p\n",vb);
119 buf->vb.state = STATE_QUEUED;
120 list_add_tail(&buf->vb.queue,&btv->vcapture);
121 if (NULL == btv->cvbi) {
122 fh->btv->loop_irq |= 4;
123 bttv_set_dma(btv,0x0c);
124 }
125}
126
127static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
128{
129 struct bttv_fh *fh = q->priv_data;
130 struct bttv *btv = fh->btv;
131 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
132
133 dprintk("free %p\n",vb);
134 bttv_dma_free(fh->btv,buf);
135}
136
137struct videobuf_queue_ops bttv_vbi_qops = {
138 .buf_setup = vbi_buffer_setup,
139 .buf_prepare = vbi_buffer_prepare,
140 .buf_queue = vbi_buffer_queue,
141 .buf_release = vbi_buffer_release,
142};
143
144/* ----------------------------------------------------------------------- */
145
146void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
147{
148 int vdelay;
149
150 if (lines < 1)
151 lines = 1;
152 if (lines > VBI_MAXLINES)
153 lines = VBI_MAXLINES;
154 fh->lines = lines;
155
156 vdelay = btread(BT848_E_VDELAY_LO);
157 if (vdelay < lines*2) {
158 vdelay = lines*2;
159 btwrite(vdelay,BT848_E_VDELAY_LO);
160 btwrite(vdelay,BT848_O_VDELAY_LO);
161 }
162}
163
164void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
165{
166 const struct bttv_tvnorm *tvnorm;
167 u32 start0,start1;
168 s32 count0,count1,count;
169
170 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
171 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
172 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
173 f->fmt.vbi.samples_per_line = 2048;
174 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
175 f->fmt.vbi.offset = 244;
176 f->fmt.vbi.flags = 0;
177 switch (fh->btv->tvnorm) {
178 case 1: /* NTSC */
179 start0 = 10;
180 start1 = 273;
181 break;
182 case 0: /* PAL */
183 case 2: /* SECAM */
184 default:
185 start0 = 7;
186 start1 = 320;
187 }
188
189 count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0;
190 count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1;
191 count = max(count0,count1);
192 if (count > VBI_MAXLINES)
193 count = VBI_MAXLINES;
194 if (count < 1)
195 count = 1;
196
197 f->fmt.vbi.start[0] = start0;
198 f->fmt.vbi.start[1] = start1;
199 f->fmt.vbi.count[0] = count;
200 f->fmt.vbi.count[1] = count;
201}
202
203void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
204{
205 const struct bttv_tvnorm *tvnorm;
206
207 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
208 memset(f,0,sizeof(*f));
209 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
210 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
211 f->fmt.vbi.samples_per_line = 2048;
212 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
213 f->fmt.vbi.offset = 244;
214 f->fmt.vbi.count[0] = fh->lines;
215 f->fmt.vbi.count[1] = fh->lines;
216 f->fmt.vbi.flags = 0;
217 switch (fh->btv->tvnorm) {
218 case 1: /* NTSC */
219 f->fmt.vbi.start[0] = 10;
220 f->fmt.vbi.start[1] = 273;
221 break;
222 case 0: /* PAL */
223 case 2: /* SECAM */
224 default:
225 f->fmt.vbi.start[0] = 7;
226 f->fmt.vbi.start[1] = 319;
227 }
228}
229
230/* ----------------------------------------------------------------------- */
231/*
232 * Local variables:
233 * c-basic-offset: 8
234 * End:
235 */
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
new file mode 100644
index 000000000000..8322b66e0905
--- /dev/null
+++ b/drivers/media/video/bttv.h
@@ -0,0 +1,338 @@
1/*
2 * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $
3 *
4 * bttv - Bt848 frame grabber driver
5 *
6 * card ID's and external interfaces of the bttv driver
7 * basically stuff needed by other drivers (i2c, lirc, ...)
8 * and is supported not to change much over time.
9 *
10 * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
12 *
13 */
14
15#ifndef _BTTV_H_
16#define _BTTV_H_
17
18#include <linux/videodev.h>
19#include <linux/i2c.h>
20
21/* ---------------------------------------------------------- */
22/* exported by bttv-cards.c */
23
24#define BTTV_UNKNOWN 0x00
25#define BTTV_MIRO 0x01
26#define BTTV_HAUPPAUGE 0x02
27#define BTTV_STB 0x03
28#define BTTV_INTEL 0x04
29#define BTTV_DIAMOND 0x05
30#define BTTV_AVERMEDIA 0x06
31#define BTTV_MATRIX_VISION 0x07
32#define BTTV_FLYVIDEO 0x08
33#define BTTV_TURBOTV 0x09
34#define BTTV_HAUPPAUGE878 0x0a
35#define BTTV_MIROPRO 0x0b
36#define BTTV_ADSTECH_TV 0x0c
37#define BTTV_AVERMEDIA98 0x0d
38#define BTTV_VHX 0x0e
39#define BTTV_ZOLTRIX 0x0f
40#define BTTV_PIXVIEWPLAYTV 0x10
41#define BTTV_WINVIEW_601 0x11
42#define BTTV_AVEC_INTERCAP 0x12
43#define BTTV_LIFE_FLYKIT 0x13
44#define BTTV_CEI_RAFFLES 0x14
45#define BTTV_CONFERENCETV 0x15
46#define BTTV_PHOEBE_TVMAS 0x16
47#define BTTV_MODTEC_205 0x17
48#define BTTV_MAGICTVIEW061 0x18
49#define BTTV_VOBIS_BOOSTAR 0x19
50#define BTTV_HAUPPAUG_WCAM 0x1a
51#define BTTV_MAXI 0x1b
52#define BTTV_TERRATV 0x1c
53#define BTTV_PXC200 0x1d
54#define BTTV_FLYVIDEO_98 0x1e
55#define BTTV_IPROTV 0x1f
56#define BTTV_INTEL_C_S_PCI 0x20
57#define BTTV_TERRATVALUE 0x21
58#define BTTV_WINFAST2000 0x22
59#define BTTV_CHRONOS_VS2 0x23
60#define BTTV_TYPHOON_TVIEW 0x24
61#define BTTV_PXELVWPLTVPRO 0x25
62#define BTTV_MAGICTVIEW063 0x26
63#define BTTV_PINNACLE 0x27
64#define BTTV_STB2 0x28
65#define BTTV_AVPHONE98 0x29
66#define BTTV_PV951 0x2a
67#define BTTV_ONAIR_TV 0x2b
68#define BTTV_SIGMA_TVII_FM 0x2c
69#define BTTV_MATRIX_VISION2 0x2d
70#define BTTV_ZOLTRIX_GENIE 0x2e
71#define BTTV_TERRATVRADIO 0x2f
72#define BTTV_DYNALINK 0x30
73#define BTTV_GVBCTV3PCI 0x31
74#define BTTV_PXELVWPLTVPAK 0x32
75#define BTTV_EAGLE 0x33
76#define BTTV_PINNACLEPRO 0x34
77#define BTTV_TVIEW_RDS_FM 0x35
78#define BTTV_LIFETEC_9415 0x36
79#define BTTV_BESTBUY_EASYTV 0x37
80#define BTTV_FLYVIDEO_98FM 0x38
81#define BTTV_GMV1 0x3d
82#define BTTV_BESTBUY_EASYTV2 0x3e
83#define BTTV_ATI_TVWONDER 0x3f
84#define BTTV_ATI_TVWONDERVE 0x40
85#define BTTV_FLYVIDEO2000 0x41
86#define BTTV_TERRATVALUER 0x42
87#define BTTV_GVBCTV4PCI 0x43
88#define BTTV_VOODOOTV_FM 0x44
89#define BTTV_AIMMS 0x45
90#define BTTV_PV_BT878P_PLUS 0x46
91#define BTTV_FLYVIDEO98EZ 0x47
92#define BTTV_PV_BT878P_9B 0x48
93#define BTTV_SENSORAY311 0x49
94#define BTTV_RV605 0x4a
95#define BTTV_WINDVR 0x4c
96#define BTTV_GRANDTEC 0x4d
97#define BTTV_KWORLD 0x4e
98#define BTTV_HAUPPAUGEPVR 0x50
99#define BTTV_GVBCTV5PCI 0x51
100#define BTTV_OSPREY1x0 0x52
101#define BTTV_OSPREY1x0_848 0x53
102#define BTTV_OSPREY101_848 0x54
103#define BTTV_OSPREY1x1 0x55
104#define BTTV_OSPREY1x1_SVID 0x56
105#define BTTV_OSPREY2xx 0x57
106#define BTTV_OSPREY2x0_SVID 0x58
107#define BTTV_OSPREY2x0 0x59
108#define BTTV_OSPREY500 0x5a
109#define BTTV_OSPREY540 0x5b
110#define BTTV_OSPREY2000 0x5c
111#define BTTV_IDS_EAGLE 0x5d
112#define BTTV_PINNACLESAT 0x5e
113#define BTTV_FORMAC_PROTV 0x5f
114#define BTTV_EURESYS_PICOLO 0x61
115#define BTTV_PV150 0x62
116#define BTTV_AD_TVK503 0x63
117#define BTTV_IVC200 0x66
118#define BTTV_XGUARD 0x67
119#define BTTV_NEBULA_DIGITV 0x68
120#define BTTV_PV143 0x69
121#define BTTV_IVC100 0x6e
122#define BTTV_IVC120 0x6f
123#define BTTV_PC_HDTV 0x70
124#define BTTV_TWINHAN_DST 0x71
125#define BTTV_WINFASTVC100 0x72
126#define BTTV_SIMUS_GVC1100 0x74
127#define BTTV_NGSTV_PLUS 0x75
128#define BTTV_LMLBT4 0x76
129#define BTTV_PICOLO_TETRA_CHIP 0x79
130#define BTTV_AVDVBT_771 0x7b
131#define BTTV_AVDVBT_761 0x7c
132#define BTTV_MATRIX_VISIONSQ 0x7d
133#define BTTV_MATRIX_VISIONSLC 0x7e
134#define BTTV_APAC_VIEWCOMP 0x7f
135#define BTTV_DVICO_DVBT_LITE 0x80
136#define BTTV_TIBET_CS16 0x83
137#define BTTV_KODICOM_4400R 0x84
138
139/* i2c address list */
140#define I2C_TSA5522 0xc2
141#define I2C_TDA7432 0x8a
142#define I2C_BT832_ALT1 0x88
143#define I2C_BT832_ALT2 0x8a // alternate setting
144#define I2C_TDA8425 0x82
145#define I2C_TDA9840 0x84
146#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
147#define I2C_TDA9874 0xb0 /* also used by 9875 */
148#define I2C_TDA9875 0xb0
149#define I2C_HAUPEE 0xa0
150#define I2C_STBEE 0xae
151#define I2C_VHX 0xc0
152#define I2C_MSP3400 0x80
153#define I2C_MSP3400_ALT 0x88
154#define I2C_TEA6300 0x80 /* also used by 6320 */
155#define I2C_DPL3518 0x84
156#define I2C_TDA9887 0x86
157
158/* more card-specific defines */
159#define PT2254_L_CHANNEL 0x10
160#define PT2254_R_CHANNEL 0x08
161#define PT2254_DBS_IN_2 0x400
162#define PT2254_DBS_IN_10 0x20000
163#define WINVIEW_PT2254_CLK 0x40
164#define WINVIEW_PT2254_DATA 0x20
165#define WINVIEW_PT2254_STROBE 0x80
166
167/* digital_mode */
168#define DIGITAL_MODE_VIDEO 1
169#define DIGITAL_MODE_CAMERA 2
170
171struct bttv_core {
172 /* device structs */
173 struct pci_dev *pci;
174 struct i2c_adapter i2c_adap;
175 struct list_head subs; /* struct bttv_sub_device */
176
177 /* device config */
178 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
179 unsigned int type; /* card type (pointer into tvcards[]) */
180 char name[8]; /* dev name */
181};
182
183struct bttv;
184
185struct tvcard
186{
187 char *name;
188 unsigned int video_inputs;
189 unsigned int audio_inputs;
190 unsigned int tuner;
191 unsigned int svhs;
192 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
193 u32 gpiomask;
194 u32 muxsel[16];
195 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
196 u32 gpiomask2; /* GPIO MUX mask */
197
198 /* i2c audio flags */
199 unsigned int no_msp34xx:1;
200 unsigned int no_tda9875:1;
201 unsigned int no_tda7432:1;
202 unsigned int needs_tvaudio:1;
203 unsigned int msp34xx_alt:1;
204
205 /* flag: video pci function is unused */
206 unsigned int no_video:1;
207 unsigned int has_dvb:1;
208 unsigned int has_remote:1;
209 unsigned int no_gpioirq:1;
210
211 /* other settings */
212 unsigned int pll;
213#define PLL_NONE 0
214#define PLL_28 1
215#define PLL_35 2
216
217 unsigned int tuner_type;
218 unsigned int has_radio;
219 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
220 void (*muxsel_hook)(struct bttv *btv, unsigned int input);
221};
222
223extern struct tvcard bttv_tvcards[];
224
225/* identification / initialization of the card */
226extern void bttv_idcard(struct bttv *btv);
227extern void bttv_init_card1(struct bttv *btv);
228extern void bttv_init_card2(struct bttv *btv);
229
230/* card-specific funtions */
231extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
232extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
233
234/* extra tweaks for some chipsets */
235extern void bttv_check_chipset(void);
236extern int bttv_handle_chipset(struct bttv *btv);
237
238/* ---------------------------------------------------------- */
239/* exported by bttv-if.c */
240
241/* this obsolete -- please use the sysfs-based
242 interface below for new code */
243
244/* returns card type + card ID (for bt878-based ones)
245 for possible values see lines below beginning with #define BTTV_UNKNOWN
246 returns negative value if error occurred
247*/
248extern int bttv_get_cardinfo(unsigned int card, int *type,
249 unsigned int *cardid);
250extern struct pci_dev* bttv_get_pcidev(unsigned int card);
251
252/* obsolete, use bttv_get_cardinfo instead */
253extern int bttv_get_id(unsigned int card);
254
255/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
256 data | (current_GPOE_value & ~mask)
257 returns negative value if error occurred
258*/
259extern int bttv_gpio_enable(unsigned int card,
260 unsigned long mask, unsigned long data);
261
262/* fills data with GPDATA register contents
263 returns negative value if error occurred
264*/
265extern int bttv_read_gpio(unsigned int card, unsigned long *data);
266
267/* sets GPDATA register to new value:
268 (data & mask) | (current_GPDATA_value & ~mask)
269 returns negative value if error occurred
270*/
271extern int bttv_write_gpio(unsigned int card,
272 unsigned long mask, unsigned long data);
273
274/* returns pointer to task queue which can be used as parameter to
275 interruptible_sleep_on
276 in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated
277 (wake_up_interruptible) and following call to the function bttv_read_gpio
278 should return new value of GPDATA,
279 returns NULL value if error occurred or queue is not available
280 WARNING: because there is no buffer for GPIO data, one MUST
281 process data ASAP
282*/
283extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
284
285/* call i2c clients
286*/
287extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
288
289
290
291/* ---------------------------------------------------------- */
292/* sysfs/driver-moded based gpio access interface */
293
294
295struct bttv_sub_device {
296 struct device dev;
297 struct bttv_core *core;
298 struct list_head list;
299};
300#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev)
301
302struct bttv_sub_driver {
303 struct device_driver drv;
304 char wanted[BUS_ID_SIZE];
305 void (*gpio_irq)(struct bttv_sub_device *sub);
306};
307#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
308
309int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted);
310int bttv_sub_unregister(struct bttv_sub_driver *drv);
311
312/* gpio access functions */
313void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits);
314u32 bttv_gpio_read(struct bttv_core *core);
315void bttv_gpio_write(struct bttv_core *core, u32 value);
316void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
317
318#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits)
319#define gpio_read() bttv_gpio_read(&btv->c)
320#define gpio_write(value) bttv_gpio_write(&btv->c, value)
321#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits)
322
323
324/* ---------------------------------------------------------- */
325/* i2c */
326
327extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
328extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
329extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
330 unsigned char b2, int both);
331extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
332
333#endif /* _BTTV_H_ */
334/*
335 * Local variables:
336 * c-basic-offset: 8
337 * End:
338 */
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
new file mode 100644
index 000000000000..1a9ba7e1cf51
--- /dev/null
+++ b/drivers/media/video/bttvp.h
@@ -0,0 +1,399 @@
1/*
2 $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5
6 bttv's *private* header file -- nobody other than bttv itself
7 should ever include this file.
8
9 (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#ifndef _BTTVP_H_
27#define _BTTVP_H_
28
29#include <linux/version.h>
30#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,15)
31
32#include <linux/types.h>
33#include <linux/wait.h>
34#include <linux/i2c.h>
35#include <linux/i2c-algo-bit.h>
36#include <linux/videodev.h>
37#include <linux/pci.h>
38#include <linux/input.h>
39#include <asm/scatterlist.h>
40#include <asm/io.h>
41
42#include <linux/device.h>
43#include <media/video-buf.h>
44#include <media/audiochip.h>
45#include <media/tuner.h>
46#include <media/tveeprom.h>
47#include <media/ir-common.h>
48
49#include "bt848.h"
50#include "bttv.h"
51#include "btcx-risc.h"
52
53#ifdef __KERNEL__
54
55#define FORMAT_FLAGS_DITHER 0x01
56#define FORMAT_FLAGS_PACKED 0x02
57#define FORMAT_FLAGS_PLANAR 0x04
58#define FORMAT_FLAGS_RAW 0x08
59#define FORMAT_FLAGS_CrCb 0x10
60
61#define RISC_SLOT_O_VBI 4
62#define RISC_SLOT_O_FIELD 6
63#define RISC_SLOT_E_VBI 10
64#define RISC_SLOT_E_FIELD 12
65#define RISC_SLOT_LOOP 14
66
67#define RESOURCE_OVERLAY 1
68#define RESOURCE_VIDEO 2
69#define RESOURCE_VBI 4
70
71#define RAW_LINES 640
72#define RAW_BPL 1024
73
74#define UNSET (-1U)
75
76/* ---------------------------------------------------------- */
77
78struct bttv_tvnorm {
79 int v4l2_id;
80 char *name;
81 u32 Fsc;
82 u16 swidth, sheight; /* scaled standard width, height */
83 u16 totalwidth;
84 u8 adelay, bdelay, iform;
85 u32 scaledtwidth;
86 u16 hdelayx1, hactivex1;
87 u16 vdelay;
88 u8 vbipack;
89 u16 vtotal;
90 int sram;
91};
92extern const struct bttv_tvnorm bttv_tvnorms[];
93
94struct bttv_format {
95 char *name;
96 int palette; /* video4linux 1 */
97 int fourcc; /* video4linux 2 */
98 int btformat; /* BT848_COLOR_FMT_* */
99 int btswap; /* BT848_COLOR_CTL_* */
100 int depth; /* bit/pixel */
101 int flags;
102 int hshift,vshift; /* for planar modes */
103};
104
105/* ---------------------------------------------------------- */
106
107struct bttv_geometry {
108 u8 vtc,crop,comb;
109 u16 width,hscale,hdelay;
110 u16 sheight,vscale,vdelay,vtotal;
111};
112
113struct bttv_buffer {
114 /* common v4l buffer stuff -- must be first */
115 struct videobuf_buffer vb;
116
117 /* bttv specific */
118 const struct bttv_format *fmt;
119 int tvnorm;
120 int btformat;
121 int btswap;
122 struct bttv_geometry geo;
123 struct btcx_riscmem top;
124 struct btcx_riscmem bottom;
125};
126
127struct bttv_buffer_set {
128 struct bttv_buffer *top; /* top field buffer */
129 struct bttv_buffer *bottom; /* bottom field buffer */
130 unsigned int top_irq;
131 unsigned int frame_irq;
132};
133
134struct bttv_overlay {
135 int tvnorm;
136 struct v4l2_rect w;
137 enum v4l2_field field;
138 struct v4l2_clip *clips;
139 int nclips;
140 int setup_ok;
141};
142
143struct bttv_fh {
144 struct bttv *btv;
145 int resources;
146#ifdef VIDIOC_G_PRIORITY
147 enum v4l2_priority prio;
148#endif
149 enum v4l2_buf_type type;
150
151 /* video capture */
152 struct videobuf_queue cap;
153 const struct bttv_format *fmt;
154 int width;
155 int height;
156
157 /* current settings */
158 const struct bttv_format *ovfmt;
159 struct bttv_overlay ov;
160
161 /* video overlay */
162 struct videobuf_queue vbi;
163 int lines;
164};
165
166/* ---------------------------------------------------------- */
167/* bttv-risc.c */
168
169/* risc code generators - capture */
170int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
171 struct scatterlist *sglist,
172 unsigned int offset, unsigned int bpl,
173 unsigned int pitch, unsigned int lines);
174
175/* control dma register + risc main loop */
176void bttv_set_dma(struct bttv *btv, int override);
177int bttv_risc_init_main(struct bttv *btv);
178int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
179 int irqflags);
180
181/* capture buffer handling */
182int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
183int bttv_buffer_activate_video(struct bttv *btv,
184 struct bttv_buffer_set *set);
185int bttv_buffer_activate_vbi(struct bttv *btv,
186 struct bttv_buffer *vbi);
187void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
188
189/* overlay handling */
190int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
191 const struct bttv_format *fmt,
192 struct bttv_buffer *buf);
193
194
195/* ---------------------------------------------------------- */
196/* bttv-vbi.c */
197
198void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f);
199void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f);
200void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
201
202extern struct videobuf_queue_ops bttv_vbi_qops;
203
204/* ---------------------------------------------------------- */
205/* bttv-gpio.c */
206
207
208extern struct bus_type bttv_sub_bus_type;
209int bttv_sub_add_device(struct bttv_core *core, char *name);
210int bttv_sub_del_devices(struct bttv_core *core);
211void bttv_gpio_irq(struct bttv_core *core);
212
213
214/* ---------------------------------------------------------- */
215/* bttv-driver.c */
216
217/* insmod options */
218extern unsigned int bttv_verbose;
219extern unsigned int bttv_debug;
220extern unsigned int bttv_gpio;
221extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
222extern int init_bttv_i2c(struct bttv *btv);
223extern int fini_bttv_i2c(struct bttv *btv);
224
225#define vprintk if (bttv_verbose) printk
226#define dprintk if (bttv_debug >= 1) printk
227#define d2printk if (bttv_debug >= 2) printk
228
229/* our devices */
230#define BTTV_MAX 16
231extern unsigned int bttv_num;
232
233#define BTTV_MAX_FBUF 0x208000
234#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
235#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
236#define BTTV_FREE_IDLE (HZ) /* one second */
237
238
239struct bttv_pll_info {
240 unsigned int pll_ifreq; /* PLL input frequency */
241 unsigned int pll_ofreq; /* PLL output frequency */
242 unsigned int pll_crystal; /* Crystal used for input */
243 unsigned int pll_current; /* Currently programmed ofreq */
244};
245
246/* for gpio-connected remote control */
247struct bttv_input {
248 struct input_dev dev;
249 struct ir_input_state ir;
250 char name[32];
251 char phys[32];
252 u32 mask_keycode;
253 u32 mask_keydown;
254};
255
256struct bttv_suspend_state {
257 u32 gpio_enable;
258 u32 gpio_data;
259 int disabled;
260 int loop_irq;
261 struct bttv_buffer_set video;
262 struct bttv_buffer *vbi;
263};
264
265struct bttv {
266 struct bttv_core c;
267
268 /* pci device config */
269 unsigned short id;
270 unsigned char revision;
271 unsigned char __iomem *bt848_mmio; /* pointer to mmio */
272
273 /* card configuration info */
274 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
275 unsigned int tuner_type; /* tuner chip type */
276 unsigned int pinnacle_id;
277 unsigned int svhs;
278 struct bttv_pll_info pll;
279 int triton1;
280 int gpioirq;
281 int use_i2c_hw;
282
283 /* old gpio interface */
284 wait_queue_head_t gpioq;
285 int shutdown;
286 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
287
288 /* new gpio interface */
289 spinlock_t gpio_lock;
290
291 /* i2c layer */
292 struct i2c_algo_bit_data i2c_algo;
293 struct i2c_client i2c_client;
294 int i2c_state, i2c_rc;
295 int i2c_done;
296 wait_queue_head_t i2c_queue;
297
298 /* video4linux (1) */
299 struct video_device *video_dev;
300 struct video_device *radio_dev;
301 struct video_device *vbi_dev;
302
303 /* infrared remote */
304 int has_remote;
305 struct bttv_input *remote;
306
307 /* locking */
308 spinlock_t s_lock;
309 struct semaphore lock;
310 int resources;
311 struct semaphore reslock;
312#ifdef VIDIOC_G_PRIORITY
313 struct v4l2_prio_state prio;
314#endif
315
316 /* video state */
317 unsigned int input;
318 unsigned int audio;
319 unsigned long freq;
320 int tvnorm,hue,contrast,bright,saturation;
321 struct v4l2_framebuffer fbuf;
322 unsigned int field_count;
323
324 /* various options */
325 int opt_combfilter;
326 int opt_lumafilter;
327 int opt_automute;
328 int opt_chroma_agc;
329 int opt_adc_crush;
330 int opt_vcr_hack;
331 int opt_whitecrush_upper;
332 int opt_whitecrush_lower;
333
334 /* radio data/state */
335 int has_radio;
336 int radio_user;
337
338 /* miro/pinnacle + Aimslab VHX
339 philips matchbox (tea5757 radio tuner) support */
340 int has_matchbox;
341 int mbox_we;
342 int mbox_data;
343 int mbox_clk;
344 int mbox_most;
345 int mbox_mask;
346
347 /* ISA stuff (Terratec Active Radio Upgrade) */
348 int mbox_ior;
349 int mbox_iow;
350 int mbox_csel;
351
352 /* risc memory management data
353 - must aquire s_lock before changing these
354 - only the irq handler is supported to touch top + bottom + vcurr */
355 struct btcx_riscmem main;
356 struct bttv_buffer *screen; /* overlay */
357 struct list_head capture; /* video capture queue */
358 struct list_head vcapture; /* vbi capture queue */
359 struct bttv_buffer_set curr; /* active buffers */
360 struct bttv_buffer *cvbi; /* active vbi buffer */
361 int loop_irq;
362 int new_input;
363
364 unsigned long cap_ctl;
365 unsigned long dma_on;
366 struct timer_list timeout;
367 struct bttv_suspend_state state;
368
369 /* stats */
370 unsigned int errors;
371 unsigned int framedrop;
372 unsigned int irq_total;
373 unsigned int irq_me;
374
375 unsigned int users;
376 struct bttv_fh init;
377};
378extern struct bttv bttvs[BTTV_MAX];
379
380/* private ioctls */
381#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int)
382#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
383
384#endif
385
386#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr))
387#define btread(adr) readl(btv->bt848_mmio+(adr))
388
389#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
390#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
391#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
392
393#endif /* _BTTVP_H_ */
394
395/*
396 * Local variables:
397 * c-basic-offset: 8
398 * End:
399 */
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
new file mode 100644
index 000000000000..0065d0c240d1
--- /dev/null
+++ b/drivers/media/video/bw-qcam.c
@@ -0,0 +1,1027 @@
1/*
2 * QuickCam Driver For Video4Linux.
3 *
4 * Video4Linux conversion work by Alan Cox.
5 * Parport compatibility by Phil Blundell.
6 * Busy loop avoidance by Mark Cooke.
7 *
8 * Module parameters:
9 *
10 * maxpoll=<1 - 5000>
11 *
12 * When polling the QuickCam for a response, busy-wait for a
13 * maximum of this many loops. The default of 250 gives little
14 * impact on interactive response.
15 *
16 * NOTE: If this parameter is set too high, the processor
17 * will busy wait until this loop times out, and then
18 * slowly poll for a further 5 seconds before failing
19 * the transaction. You have been warned.
20 *
21 * yieldlines=<1 - 250>
22 *
23 * When acquiring a frame from the camera, the data gathering
24 * loop will yield back to the scheduler after completing
25 * this many lines. The default of 4 provides a trade-off
26 * between increased frame acquisition time and impact on
27 * interactive response.
28 */
29
30/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
31 * See the included documentation for usage instructions and details
32 * of the protocol involved. */
33
34
35/* Version 0.5, August 4, 1996 */
36/* Version 0.7, August 27, 1996 */
37/* Version 0.9, November 17, 1996 */
38
39
40/******************************************************************
41
42Copyright (C) 1996 by Scott Laird
43
44Permission is hereby granted, free of charge, to any person obtaining
45a copy of this software and associated documentation files (the
46"Software"), to deal in the Software without restriction, including
47without limitation the rights to use, copy, modify, merge, publish,
48distribute, sublicense, and/or sell copies of the Software, and to
49permit persons to whom the Software is furnished to do so, subject to
50the following conditions:
51
52The above copyright notice and this permission notice shall be
53included in all copies or substantial portions of the Software.
54
55THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
59OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
60ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
61OTHER DEALINGS IN THE SOFTWARE.
62
63******************************************************************/
64
65#include <linux/module.h>
66#include <linux/delay.h>
67#include <linux/errno.h>
68#include <linux/fs.h>
69#include <linux/init.h>
70#include <linux/kernel.h>
71#include <linux/slab.h>
72#include <linux/mm.h>
73#include <linux/parport.h>
74#include <linux/sched.h>
75#include <linux/videodev.h>
76#include <asm/semaphore.h>
77#include <asm/uaccess.h>
78
79#include "bw-qcam.h"
80
81static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
82static unsigned int yieldlines=4; /* Yield after this many during capture */
83static int video_nr = -1;
84
85module_param(maxpoll, int, 0);
86module_param(yieldlines, int, 0);
87module_param(video_nr, int, 0);
88
89static inline int read_lpstatus(struct qcam_device *q)
90{
91 return parport_read_status(q->pport);
92}
93
94static inline int read_lpdata(struct qcam_device *q)
95{
96 return parport_read_data(q->pport);
97}
98
99static inline void write_lpdata(struct qcam_device *q, int d)
100{
101 parport_write_data(q->pport, d);
102}
103
104static inline void write_lpcontrol(struct qcam_device *q, int d)
105{
106 parport_write_control(q->pport, d);
107}
108
109static int qc_waithand(struct qcam_device *q, int val);
110static int qc_command(struct qcam_device *q, int command);
111static int qc_readparam(struct qcam_device *q);
112static int qc_setscanmode(struct qcam_device *q);
113static int qc_readbytes(struct qcam_device *q, char buffer[]);
114
115static struct video_device qcam_template;
116
117static int qc_calibrate(struct qcam_device *q)
118{
119 /*
120 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
121 * The white balance is an individiual value for each
122 * quickcam.
123 */
124
125 int value;
126 int count = 0;
127
128 qc_command(q, 27); /* AutoAdjustOffset */
129 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
130
131 /* GetOffset (33) will read 255 until autocalibration */
132 /* is finished. After that, a value of 1-254 will be */
133 /* returned. */
134
135 do {
136 qc_command(q, 33);
137 value = qc_readparam(q);
138 mdelay(1);
139 schedule();
140 count++;
141 } while (value == 0xff && count<2048);
142
143 q->whitebal = value;
144 return value;
145}
146
147/* Initialize the QuickCam driver control structure. This is where
148 * defaults are set for people who don't have a config file.*/
149
150static struct qcam_device *qcam_init(struct parport *port)
151{
152 struct qcam_device *q;
153
154 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
155 if(q==NULL)
156 return NULL;
157
158 q->pport = port;
159 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
160 NULL, 0, NULL);
161 if (q->pdev == NULL)
162 {
163 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
164 port->name);
165 kfree(q);
166 return NULL;
167 }
168
169 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
170
171 init_MUTEX(&q->lock);
172
173 q->port_mode = (QC_ANY | QC_NOTSET);
174 q->width = 320;
175 q->height = 240;
176 q->bpp = 4;
177 q->transfer_scale = 2;
178 q->contrast = 192;
179 q->brightness = 180;
180 q->whitebal = 105;
181 q->top = 1;
182 q->left = 14;
183 q->mode = -1;
184 q->status = QC_PARAM_CHANGE;
185 return q;
186}
187
188
189/* qc_command is probably a bit of a misnomer -- it's used to send
190 * bytes *to* the camera. Generally, these bytes are either commands
191 * or arguments to commands, so the name fits, but it still bugs me a
192 * bit. See the documentation for a list of commands. */
193
194static int qc_command(struct qcam_device *q, int command)
195{
196 int n1, n2;
197 int cmd;
198
199 write_lpdata(q, command);
200 write_lpcontrol(q, 6);
201
202 n1 = qc_waithand(q, 1);
203
204 write_lpcontrol(q, 0xe);
205 n2 = qc_waithand(q, 0);
206
207 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
208 return cmd;
209}
210
211static int qc_readparam(struct qcam_device *q)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpcontrol(q, 6);
217 n1 = qc_waithand(q, 1);
218
219 write_lpcontrol(q, 0xe);
220 n2 = qc_waithand(q, 0);
221
222 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
223 return cmd;
224}
225
226/* qc_waithand busy-waits for a handshake signal from the QuickCam.
227 * Almost all communication with the camera requires handshaking. */
228
229static int qc_waithand(struct qcam_device *q, int val)
230{
231 int status;
232 int runs=0;
233
234 if (val)
235 {
236 while (!((status = read_lpstatus(q)) & 8))
237 {
238 /* 1000 is enough spins on the I/O for all normal
239 cases, at that point we start to poll slowly
240 until the camera wakes up. However, we are
241 busy blocked until the camera responds, so
242 setting it lower is much better for interactive
243 response. */
244
245 if(runs++>maxpoll)
246 {
247 msleep_interruptible(5);
248 }
249 if(runs>(maxpoll+1000)) /* 5 seconds */
250 return -1;
251 }
252 }
253 else
254 {
255 while (((status = read_lpstatus(q)) & 8))
256 {
257 /* 1000 is enough spins on the I/O for all normal
258 cases, at that point we start to poll slowly
259 until the camera wakes up. However, we are
260 busy blocked until the camera responds, so
261 setting it lower is much better for interactive
262 response. */
263
264 if(runs++>maxpoll)
265 {
266 msleep_interruptible(5);
267 }
268 if(runs++>(maxpoll+1000)) /* 5 seconds */
269 return -1;
270 }
271 }
272
273 return status;
274}
275
276/* Waithand2 is used when the qcam is in bidirectional mode, and the
277 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
278 * (bit 3 of status register). It also returns the last value read,
279 * since this data is useful. */
280
281static unsigned int qc_waithand2(struct qcam_device *q, int val)
282{
283 unsigned int status;
284 int runs=0;
285
286 do
287 {
288 status = read_lpdata(q);
289 /* 1000 is enough spins on the I/O for all normal
290 cases, at that point we start to poll slowly
291 until the camera wakes up. However, we are
292 busy blocked until the camera responds, so
293 setting it lower is much better for interactive
294 response. */
295
296 if(runs++>maxpoll)
297 {
298 msleep_interruptible(5);
299 }
300 if(runs++>(maxpoll+1000)) /* 5 seconds */
301 return 0;
302 }
303 while ((status & 1) != val);
304
305 return status;
306}
307
308
309/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
310 the status register at 5-10 Hz. This is only used in the autoprobe
311 code. Be aware that this isn't the way Connectix detects the
312 camera (they send a reset and try to handshake), but this should be
313 almost completely safe, while their method screws up my printer if
314 I plug it in before the camera. */
315
316static int qc_detect(struct qcam_device *q)
317{
318 int reg, lastreg;
319 int count = 0;
320 int i;
321
322 lastreg = reg = read_lpstatus(q) & 0xf0;
323
324 for (i = 0; i < 500; i++)
325 {
326 reg = read_lpstatus(q) & 0xf0;
327 if (reg != lastreg)
328 count++;
329 lastreg = reg;
330 mdelay(2);
331 }
332
333
334#if 0
335 /* Force camera detection during testing. Sometimes the camera
336 won't be flashing these bits. Possibly unloading the module
337 in the middle of a grab? Or some timeout condition?
338 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
339 printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
340 return 1;
341#endif
342
343 /* Be (even more) liberal in what you accept... */
344
345/* if (count > 30 && count < 200) */
346 if (count > 20 && count < 300)
347 return 1; /* found */
348 else
349 return 0; /* not found */
350}
351
352
353/* Reset the QuickCam. This uses the same sequence the Windows
354 * QuickPic program uses. Someone with a bi-directional port should
355 * check that bi-directional mode is detected right, and then
356 * implement bi-directional mode in qc_readbyte(). */
357
358static void qc_reset(struct qcam_device *q)
359{
360 switch (q->port_mode & QC_FORCE_MASK)
361 {
362 case QC_FORCE_UNIDIR:
363 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
364 break;
365
366 case QC_FORCE_BIDIR:
367 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
368 break;
369
370 case QC_ANY:
371 write_lpcontrol(q, 0x20);
372 write_lpdata(q, 0x75);
373
374 if (read_lpdata(q) != 0x75) {
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 } else {
377 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
378 }
379 break;
380 }
381
382 write_lpcontrol(q, 0xb);
383 udelay(250);
384 write_lpcontrol(q, 0xe);
385 qc_setscanmode(q); /* in case port_mode changed */
386}
387
388
389/* Decide which scan mode to use. There's no real requirement that
390 * the scanmode match the resolution in q->height and q-> width -- the
391 * camera takes the picture at the resolution specified in the
392 * "scanmode" and then returns the image at the resolution specified
393 * with the resolution commands. If the scan is bigger than the
394 * requested resolution, the upper-left hand corner of the scan is
395 * returned. If the scan is smaller, then the rest of the image
396 * returned contains garbage. */
397
398static int qc_setscanmode(struct qcam_device *q)
399{
400 int old_mode = q->mode;
401
402 switch (q->transfer_scale)
403 {
404 case 1:
405 q->mode = 0;
406 break;
407 case 2:
408 q->mode = 4;
409 break;
410 case 4:
411 q->mode = 8;
412 break;
413 }
414
415 switch (q->bpp)
416 {
417 case 4:
418 break;
419 case 6:
420 q->mode += 2;
421 break;
422 }
423
424 switch (q->port_mode & QC_MODE_MASK)
425 {
426 case QC_BIDIR:
427 q->mode += 1;
428 break;
429 case QC_NOTSET:
430 case QC_UNIDIR:
431 break;
432 }
433
434 if (q->mode != old_mode)
435 q->status |= QC_PARAM_CHANGE;
436
437 return 0;
438}
439
440
441/* Reset the QuickCam and program for brightness, contrast,
442 * white-balance, and resolution. */
443
444static void qc_set(struct qcam_device *q)
445{
446 int val;
447 int val2;
448
449 qc_reset(q);
450
451 /* Set the brightness. Yes, this is repetitive, but it works.
452 * Shorter versions seem to fail subtly. Feel free to try :-). */
453 /* I think the problem was in qc_command, not here -- bls */
454
455 qc_command(q, 0xb);
456 qc_command(q, q->brightness);
457
458 val = q->height / q->transfer_scale;
459 qc_command(q, 0x11);
460 qc_command(q, val);
461 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
462 /* The normal "transfers per line" calculation doesn't seem to work
463 as expected here (and yet it works fine in qc_scan). No idea
464 why this case is the odd man out. Fortunately, Laird's original
465 working version gives me a good way to guess at working values.
466 -- bls */
467 val = q->width;
468 val2 = q->transfer_scale * 4;
469 } else {
470 val = q->width * q->bpp;
471 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
472 q->transfer_scale;
473 }
474 val = (val + val2 - 1) / val2;
475 qc_command(q, 0x13);
476 qc_command(q, val);
477
478 /* Setting top and left -- bls */
479 qc_command(q, 0xd);
480 qc_command(q, q->top);
481 qc_command(q, 0xf);
482 qc_command(q, q->left / 2);
483
484 qc_command(q, 0x19);
485 qc_command(q, q->contrast);
486 qc_command(q, 0x1f);
487 qc_command(q, q->whitebal);
488
489 /* Clear flag that we must update the grabbing parameters on the camera
490 before we grab the next frame */
491 q->status &= (~QC_PARAM_CHANGE);
492}
493
494/* Qc_readbytes reads some bytes from the QC and puts them in
495 the supplied buffer. It returns the number of bytes read,
496 or -1 on error. */
497
498static inline int qc_readbytes(struct qcam_device *q, char buffer[])
499{
500 int ret=1;
501 unsigned int hi, lo;
502 unsigned int hi2, lo2;
503 static int state = 0;
504
505 if (buffer == NULL)
506 {
507 state = 0;
508 return 0;
509 }
510
511 switch (q->port_mode & QC_MODE_MASK)
512 {
513 case QC_BIDIR: /* Bi-directional Port */
514 write_lpcontrol(q, 0x26);
515 lo = (qc_waithand2(q, 1) >> 1);
516 hi = (read_lpstatus(q) >> 3) & 0x1f;
517 write_lpcontrol(q, 0x2e);
518 lo2 = (qc_waithand2(q, 0) >> 1);
519 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
520 switch (q->bpp)
521 {
522 case 4:
523 buffer[0] = lo & 0xf;
524 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
525 buffer[2] = (hi & 0x1e) >> 1;
526 buffer[3] = lo2 & 0xf;
527 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
528 buffer[5] = (hi2 & 0x1e) >> 1;
529 ret = 6;
530 break;
531 case 6:
532 buffer[0] = lo & 0x3f;
533 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
534 buffer[2] = lo2 & 0x3f;
535 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
536 ret = 4;
537 break;
538 }
539 break;
540
541 case QC_UNIDIR: /* Unidirectional Port */
542 write_lpcontrol(q, 6);
543 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
544 write_lpcontrol(q, 0xe);
545 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
546
547 switch (q->bpp)
548 {
549 case 4:
550 buffer[0] = lo;
551 buffer[1] = hi;
552 ret = 2;
553 break;
554 case 6:
555 switch (state)
556 {
557 case 0:
558 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
559 q->saved_bits = (hi & 3) << 4;
560 state = 1;
561 ret = 1;
562 break;
563 case 1:
564 buffer[0] = lo | q->saved_bits;
565 q->saved_bits = hi << 2;
566 state = 2;
567 ret = 1;
568 break;
569 case 2:
570 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
571 buffer[1] = ((lo & 3) << 4) | hi;
572 state = 0;
573 ret = 2;
574 break;
575 }
576 break;
577 }
578 break;
579 }
580 return ret;
581}
582
583/* requests a scan from the camera. It sends the correct instructions
584 * to the camera and then reads back the correct number of bytes. In
585 * previous versions of this routine the return structure contained
586 * the raw output from the camera, and there was a 'qc_convertscan'
587 * function that converted that to a useful format. In version 0.3 I
588 * rolled qc_convertscan into qc_scan and now I only return the
589 * converted scan. The format is just an one-dimensional array of
590 * characters, one for each pixel, with 0=black up to n=white, where
591 * n=2^(bit depth)-1. Ask me for more details if you don't understand
592 * this. */
593
594static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
595{
596 int i, j, k, yield;
597 int bytes;
598 int linestotrans, transperline;
599 int divisor;
600 int pixels_per_line;
601 int pixels_read = 0;
602 int got=0;
603 char buffer[6];
604 int shift=8-q->bpp;
605 char invert;
606
607 if (q->mode == -1)
608 return -ENXIO;
609
610 qc_command(q, 0x7);
611 qc_command(q, q->mode);
612
613 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
614 {
615 write_lpcontrol(q, 0x2e); /* turn port around */
616 write_lpcontrol(q, 0x26);
617 (void) qc_waithand(q, 1);
618 write_lpcontrol(q, 0x2e);
619 (void) qc_waithand(q, 0);
620 }
621
622 /* strange -- should be 15:63 below, but 4bpp is odd */
623 invert = (q->bpp == 4) ? 16 : 63;
624
625 linestotrans = q->height / q->transfer_scale;
626 pixels_per_line = q->width / q->transfer_scale;
627 transperline = q->width * q->bpp;
628 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
629 q->transfer_scale;
630 transperline = (transperline + divisor - 1) / divisor;
631
632 for (i = 0, yield = yieldlines; i < linestotrans; i++)
633 {
634 for (pixels_read = j = 0; j < transperline; j++)
635 {
636 bytes = qc_readbytes(q, buffer);
637 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
638 {
639 int o;
640 if (buffer[k] == 0 && invert == 16)
641 {
642 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
643 must be 0-15 -- bls */
644 buffer[k] = 16;
645 }
646 o=i*pixels_per_line + pixels_read + k;
647 if(o<len)
648 {
649 got++;
650 put_user((invert - buffer[k])<<shift, buf+o);
651 }
652 }
653 pixels_read += bytes;
654 }
655 (void) qc_readbytes(q, NULL); /* reset state machine */
656
657 /* Grabbing an entire frame from the quickcam is a lengthy
658 process. We don't (usually) want to busy-block the
659 processor for the entire frame. yieldlines is a module
660 parameter. If we yield every line, the minimum frame
661 time will be 240 / 200 = 1.2 seconds. The compile-time
662 default is to yield every 4 lines. */
663 if (i >= yield) {
664 msleep_interruptible(5);
665 yield = i + yieldlines;
666 }
667 }
668
669 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
670 {
671 write_lpcontrol(q, 2);
672 write_lpcontrol(q, 6);
673 udelay(3);
674 write_lpcontrol(q, 0xe);
675 }
676 if(got<len)
677 return got;
678 return len;
679}
680
681/*
682 * Video4linux interfacing
683 */
684
685static int qcam_do_ioctl(struct inode *inode, struct file *file,
686 unsigned int cmd, void *arg)
687{
688 struct video_device *dev = video_devdata(file);
689 struct qcam_device *qcam=(struct qcam_device *)dev;
690
691 switch(cmd)
692 {
693 case VIDIOCGCAP:
694 {
695 struct video_capability *b = arg;
696 strcpy(b->name, "Quickcam");
697 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
698 b->channels = 1;
699 b->audios = 0;
700 b->maxwidth = 320;
701 b->maxheight = 240;
702 b->minwidth = 80;
703 b->minheight = 60;
704 return 0;
705 }
706 case VIDIOCGCHAN:
707 {
708 struct video_channel *v = arg;
709 if(v->channel!=0)
710 return -EINVAL;
711 v->flags=0;
712 v->tuners=0;
713 /* Good question.. its composite or SVHS so.. */
714 v->type = VIDEO_TYPE_CAMERA;
715 strcpy(v->name, "Camera");
716 return 0;
717 }
718 case VIDIOCSCHAN:
719 {
720 struct video_channel *v = arg;
721 if(v->channel!=0)
722 return -EINVAL;
723 return 0;
724 }
725 case VIDIOCGTUNER:
726 {
727 struct video_tuner *v = arg;
728 if(v->tuner)
729 return -EINVAL;
730 strcpy(v->name, "Format");
731 v->rangelow=0;
732 v->rangehigh=0;
733 v->flags= 0;
734 v->mode = VIDEO_MODE_AUTO;
735 return 0;
736 }
737 case VIDIOCSTUNER:
738 {
739 struct video_tuner *v = arg;
740 if(v->tuner)
741 return -EINVAL;
742 if(v->mode!=VIDEO_MODE_AUTO)
743 return -EINVAL;
744 return 0;
745 }
746 case VIDIOCGPICT:
747 {
748 struct video_picture *p = arg;
749 p->colour=0x8000;
750 p->hue=0x8000;
751 p->brightness=qcam->brightness<<8;
752 p->contrast=qcam->contrast<<8;
753 p->whiteness=qcam->whitebal<<8;
754 p->depth=qcam->bpp;
755 p->palette=VIDEO_PALETTE_GREY;
756 return 0;
757 }
758 case VIDIOCSPICT:
759 {
760 struct video_picture *p = arg;
761 if(p->palette!=VIDEO_PALETTE_GREY)
762 return -EINVAL;
763 if(p->depth!=4 && p->depth!=6)
764 return -EINVAL;
765
766 /*
767 * Now load the camera.
768 */
769
770 qcam->brightness = p->brightness>>8;
771 qcam->contrast = p->contrast>>8;
772 qcam->whitebal = p->whiteness>>8;
773 qcam->bpp = p->depth;
774
775 down(&qcam->lock);
776 qc_setscanmode(qcam);
777 up(&qcam->lock);
778 qcam->status |= QC_PARAM_CHANGE;
779
780 return 0;
781 }
782 case VIDIOCSWIN:
783 {
784 struct video_window *vw = arg;
785 if(vw->flags)
786 return -EINVAL;
787 if(vw->clipcount)
788 return -EINVAL;
789 if(vw->height<60||vw->height>240)
790 return -EINVAL;
791 if(vw->width<80||vw->width>320)
792 return -EINVAL;
793
794 qcam->width = 320;
795 qcam->height = 240;
796 qcam->transfer_scale = 4;
797
798 if(vw->width>=160 && vw->height>=120)
799 {
800 qcam->transfer_scale = 2;
801 }
802 if(vw->width>=320 && vw->height>=240)
803 {
804 qcam->width = 320;
805 qcam->height = 240;
806 qcam->transfer_scale = 1;
807 }
808 down(&qcam->lock);
809 qc_setscanmode(qcam);
810 up(&qcam->lock);
811
812 /* We must update the camera before we grab. We could
813 just have changed the grab size */
814 qcam->status |= QC_PARAM_CHANGE;
815
816 /* Ok we figured out what to use from our wide choice */
817 return 0;
818 }
819 case VIDIOCGWIN:
820 {
821 struct video_window *vw = arg;
822 memset(vw, 0, sizeof(*vw));
823 vw->width=qcam->width/qcam->transfer_scale;
824 vw->height=qcam->height/qcam->transfer_scale;
825 return 0;
826 }
827 case VIDIOCKEY:
828 return 0;
829 case VIDIOCCAPTURE:
830 case VIDIOCGFBUF:
831 case VIDIOCSFBUF:
832 case VIDIOCGFREQ:
833 case VIDIOCSFREQ:
834 case VIDIOCGAUDIO:
835 case VIDIOCSAUDIO:
836 return -EINVAL;
837 default:
838 return -ENOIOCTLCMD;
839 }
840 return 0;
841}
842
843static int qcam_ioctl(struct inode *inode, struct file *file,
844 unsigned int cmd, unsigned long arg)
845{
846 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
847}
848
849static ssize_t qcam_read(struct file *file, char __user *buf,
850 size_t count, loff_t *ppos)
851{
852 struct video_device *v = video_devdata(file);
853 struct qcam_device *qcam=(struct qcam_device *)v;
854 int len;
855 parport_claim_or_block(qcam->pdev);
856
857 down(&qcam->lock);
858
859 qc_reset(qcam);
860
861 /* Update the camera parameters if we need to */
862 if (qcam->status & QC_PARAM_CHANGE)
863 qc_set(qcam);
864
865 len=qc_capture(qcam, buf,count);
866
867 up(&qcam->lock);
868
869 parport_release(qcam->pdev);
870 return len;
871}
872
873static struct file_operations qcam_fops = {
874 .owner = THIS_MODULE,
875 .open = video_exclusive_open,
876 .release = video_exclusive_release,
877 .ioctl = qcam_ioctl,
878 .read = qcam_read,
879 .llseek = no_llseek,
880};
881static struct video_device qcam_template=
882{
883 .owner = THIS_MODULE,
884 .name = "Connectix Quickcam",
885 .type = VID_TYPE_CAPTURE,
886 .hardware = VID_HARDWARE_QCAM_BW,
887 .fops = &qcam_fops,
888};
889
890#define MAX_CAMS 4
891static struct qcam_device *qcams[MAX_CAMS];
892static unsigned int num_cams = 0;
893
894static int init_bwqcam(struct parport *port)
895{
896 struct qcam_device *qcam;
897
898 if (num_cams == MAX_CAMS)
899 {
900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
901 return -ENOSPC;
902 }
903
904 qcam=qcam_init(port);
905 if(qcam==NULL)
906 return -ENODEV;
907
908 parport_claim_or_block(qcam->pdev);
909
910 qc_reset(qcam);
911
912 if(qc_detect(qcam)==0)
913 {
914 parport_release(qcam->pdev);
915 parport_unregister_device(qcam->pdev);
916 kfree(qcam);
917 return -ENODEV;
918 }
919 qc_calibrate(qcam);
920
921 parport_release(qcam->pdev);
922
923 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
924
925 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
926 {
927 parport_unregister_device(qcam->pdev);
928 kfree(qcam);
929 return -ENODEV;
930 }
931
932 qcams[num_cams++] = qcam;
933
934 return 0;
935}
936
937static void close_bwqcam(struct qcam_device *qcam)
938{
939 video_unregister_device(&qcam->vdev);
940 parport_unregister_device(qcam->pdev);
941 kfree(qcam);
942}
943
944/* The parport parameter controls which parports will be scanned.
945 * Scanning all parports causes some printers to print a garbage page.
946 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
947#ifdef MODULE
948static char *parport[MAX_CAMS] = { NULL, };
949module_param_array(parport, charp, NULL, 0);
950#endif
951
952static int accept_bwqcam(struct parport *port)
953{
954#ifdef MODULE
955 int n;
956
957 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
958 /* user gave parport parameters */
959 for(n=0; parport[n] && n<MAX_CAMS; n++){
960 char *ep;
961 unsigned long r;
962 r = simple_strtoul(parport[n], &ep, 0);
963 if (ep == parport[n]) {
964 printk(KERN_ERR
965 "bw-qcam: bad port specifier \"%s\"\n",
966 parport[n]);
967 continue;
968 }
969 if (r == port->number)
970 return 1;
971 }
972 return 0;
973 }
974#endif
975 return 1;
976}
977
978static void bwqcam_attach(struct parport *port)
979{
980 if (accept_bwqcam(port))
981 init_bwqcam(port);
982}
983
984static void bwqcam_detach(struct parport *port)
985{
986 int i;
987 for (i = 0; i < num_cams; i++) {
988 struct qcam_device *qcam = qcams[i];
989 if (qcam && qcam->pdev->port == port) {
990 qcams[i] = NULL;
991 close_bwqcam(qcam);
992 }
993 }
994}
995
996static struct parport_driver bwqcam_driver = {
997 .name = "bw-qcam",
998 .attach = bwqcam_attach,
999 .detach = bwqcam_detach,
1000};
1001
1002static void __exit exit_bw_qcams(void)
1003{
1004 parport_unregister_driver(&bwqcam_driver);
1005}
1006
1007static int __init init_bw_qcams(void)
1008{
1009#ifdef MODULE
1010 /* Do some sanity checks on the module parameters. */
1011 if (maxpoll > 5000) {
1012 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1013 maxpoll = 5000;
1014 }
1015
1016 if (yieldlines < 1) {
1017 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1018 yieldlines = 1;
1019 }
1020#endif
1021 return parport_register_driver(&bwqcam_driver);
1022}
1023
1024module_init(init_bw_qcams);
1025module_exit(exit_bw_qcams);
1026
1027MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h
new file mode 100644
index 000000000000..723e8ad9e56a
--- /dev/null
+++ b/drivers/media/video/bw-qcam.h
@@ -0,0 +1,68 @@
1/*
2 * Video4Linux bw-qcam driver
3 *
4 * Derived from code..
5 */
6
7/******************************************************************
8
9Copyright (C) 1996 by Scott Laird
10
11Permission is hereby granted, free of charge, to any person obtaining
12a copy of this software and associated documentation files (the
13"Software"), to deal in the Software without restriction, including
14without limitation the rights to use, copy, modify, merge, publish,
15distribute, sublicense, and/or sell copies of the Software, and to
16permit persons to whom the Software is furnished to do so, subject to
17the following conditions:
18
19The above copyright notice and this permission notice shall be
20included in all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
26OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28OTHER DEALINGS IN THE SOFTWARE.
29
30******************************************************************/
31
32/* One from column A... */
33#define QC_NOTSET 0
34#define QC_UNIDIR 1
35#define QC_BIDIR 2
36#define QC_SERIAL 3
37
38/* ... and one from column B */
39#define QC_ANY 0x00
40#define QC_FORCE_UNIDIR 0x10
41#define QC_FORCE_BIDIR 0x20
42#define QC_FORCE_SERIAL 0x30
43/* in the port_mode member */
44
45#define QC_MODE_MASK 0x07
46#define QC_FORCE_MASK 0x70
47
48#define MAX_HEIGHT 243
49#define MAX_WIDTH 336
50
51/* Bit fields for status flags */
52#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
53
54struct qcam_device {
55 struct video_device vdev;
56 struct pardevice *pdev;
57 struct parport *pport;
58 struct semaphore lock;
59 int width, height;
60 int bpp;
61 int mode;
62 int contrast, brightness, whitebal;
63 int port_mode;
64 int transfer_scale;
65 int top, left;
66 int status;
67 unsigned int saved_bits;
68};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
new file mode 100644
index 000000000000..75442ec49f35
--- /dev/null
+++ b/drivers/media/video/c-qcam.c
@@ -0,0 +1,855 @@
1/*
2 * Video4Linux Colour QuickCam driver
3 * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
4 *
5 * Module parameters:
6 *
7 * parport=auto -- probe all parports (default)
8 * parport=0 -- parport0 becomes qcam1
9 * parport=2,0,1 -- parports 2,0,1 are tried in that order
10 *
11 * probe=0 -- do no probing, assume camera is present
12 * probe=1 -- use IEEE-1284 autoprobe data only (default)
13 * probe=2 -- probe aggressively for cameras
14 *
15 * force_rgb=1 -- force data format to RGB (default is BGR)
16 *
17 * The parport parameter controls which parports will be scanned.
18 * Scanning all parports causes some printers to print a garbage page.
19 * -- March 14, 1999 Billy Donahue <billy@escape.com>
20 *
21 * Fixed data format to BGR, added force_rgb parameter. Added missing
22 * parport_unregister_driver() on module removal.
23 * -- May 28, 2000 Claudio Matsuoka <claudio@conectiva.com>
24 */
25
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/mm.h>
34#include <linux/parport.h>
35#include <linux/sched.h>
36#include <linux/videodev.h>
37#include <asm/semaphore.h>
38#include <asm/uaccess.h>
39
40struct qcam_device {
41 struct video_device vdev;
42 struct pardevice *pdev;
43 struct parport *pport;
44 int width, height;
45 int ccd_width, ccd_height;
46 int mode;
47 int contrast, brightness, whitebal;
48 int top, left;
49 unsigned int bidirectional;
50 struct semaphore lock;
51};
52
53/* cameras maximum */
54#define MAX_CAMS 4
55
56/* The three possible QuickCam modes */
57#define QC_MILLIONS 0x18
58#define QC_BILLIONS 0x10
59#define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
60
61/* The three possible decimations */
62#define QC_DECIMATION_1 0
63#define QC_DECIMATION_2 2
64#define QC_DECIMATION_4 4
65
66#define BANNER "Colour QuickCam for Video4Linux v0.05"
67
68static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
69static int probe = 2;
70static int force_rgb = 0;
71static int video_nr = -1;
72
73static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
74{
75 /* note: the QC specs refer to the PCAck pin by voltage, not
76 software level. PC ports have builtin inverters. */
77 parport_frob_control(qcam->pport, 8, i?8:0);
78}
79
80static inline unsigned int qcam_ready1(struct qcam_device *qcam)
81{
82 return (parport_read_status(qcam->pport) & 0x8)?1:0;
83}
84
85static inline unsigned int qcam_ready2(struct qcam_device *qcam)
86{
87 return (parport_read_data(qcam->pport) & 0x1)?1:0;
88}
89
90static unsigned int qcam_await_ready1(struct qcam_device *qcam,
91 int value)
92{
93 unsigned long oldjiffies = jiffies;
94 unsigned int i;
95
96 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
97 if (qcam_ready1(qcam) == value)
98 return 0;
99
100 /* If the camera didn't respond within 1/25 second, poll slowly
101 for a while. */
102 for (i = 0; i < 50; i++)
103 {
104 if (qcam_ready1(qcam) == value)
105 return 0;
106 msleep_interruptible(100);
107 }
108
109 /* Probably somebody pulled the plug out. Not much we can do. */
110 printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
111 parport_read_status(qcam->pport),
112 parport_read_control(qcam->pport));
113 return 1;
114}
115
116static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
117{
118 unsigned long oldjiffies = jiffies;
119 unsigned int i;
120
121 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
122 if (qcam_ready2(qcam) == value)
123 return 0;
124
125 /* If the camera didn't respond within 1/25 second, poll slowly
126 for a while. */
127 for (i = 0; i < 50; i++)
128 {
129 if (qcam_ready2(qcam) == value)
130 return 0;
131 msleep_interruptible(100);
132 }
133
134 /* Probably somebody pulled the plug out. Not much we can do. */
135 printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
136 parport_read_status(qcam->pport),
137 parport_read_control(qcam->pport),
138 parport_read_data(qcam->pport));
139 return 1;
140}
141
142static int qcam_read_data(struct qcam_device *qcam)
143{
144 unsigned int idata;
145 qcam_set_ack(qcam, 0);
146 if (qcam_await_ready1(qcam, 1)) return -1;
147 idata = parport_read_status(qcam->pport) & 0xf0;
148 qcam_set_ack(qcam, 1);
149 if (qcam_await_ready1(qcam, 0)) return -1;
150 idata |= (parport_read_status(qcam->pport) >> 4);
151 return idata;
152}
153
154static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
155{
156 unsigned int idata;
157 parport_write_data(qcam->pport, data);
158 idata = qcam_read_data(qcam);
159 if (data != idata)
160 {
161 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
162 idata);
163 return 1;
164 }
165 return 0;
166}
167
168static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
169{
170 if (qcam_write_data(qcam, cmd))
171 return -1;
172 if (qcam_write_data(qcam, data))
173 return -1;
174 return 0;
175}
176
177static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
178{
179 if (qcam_write_data(qcam, cmd))
180 return -1;
181 return qcam_read_data(qcam);
182}
183
184static int qc_detect(struct qcam_device *qcam)
185{
186 unsigned int stat, ostat, i, count = 0;
187
188 /* The probe routine below is not very reliable. The IEEE-1284
189 probe takes precedence. */
190 /* XXX Currently parport provides no way to distinguish between
191 "the IEEE probe was not done" and "the probe was done, but
192 no device was found". Fix this one day. */
193 if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
194 && qcam->pport->probe_info[0].model
195 && !strcmp(qcam->pdev->port->probe_info[0].model,
196 "Color QuickCam 2.0")) {
197 printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
198 return 1;
199 }
200
201 if (probe < 2)
202 return 0;
203
204 parport_write_control(qcam->pport, 0xc);
205
206 /* look for a heartbeat */
207 ostat = stat = parport_read_status(qcam->pport);
208 for (i=0; i<250; i++)
209 {
210 mdelay(1);
211 stat = parport_read_status(qcam->pport);
212 if (ostat != stat)
213 {
214 if (++count >= 3) return 1;
215 ostat = stat;
216 }
217 }
218
219 /* Reset the camera and try again */
220 parport_write_control(qcam->pport, 0xc);
221 parport_write_control(qcam->pport, 0x8);
222 mdelay(1);
223 parport_write_control(qcam->pport, 0xc);
224 mdelay(1);
225 count = 0;
226
227 ostat = stat = parport_read_status(qcam->pport);
228 for (i=0; i<250; i++)
229 {
230 mdelay(1);
231 stat = parport_read_status(qcam->pport);
232 if (ostat != stat)
233 {
234 if (++count >= 3) return 1;
235 ostat = stat;
236 }
237 }
238
239 /* no (or flatline) camera, give up */
240 return 0;
241}
242
243static void qc_reset(struct qcam_device *qcam)
244{
245 parport_write_control(qcam->pport, 0xc);
246 parport_write_control(qcam->pport, 0x8);
247 mdelay(1);
248 parport_write_control(qcam->pport, 0xc);
249 mdelay(1);
250}
251
252/* Reset the QuickCam and program for brightness, contrast,
253 * white-balance, and resolution. */
254
255static void qc_setup(struct qcam_device *q)
256{
257 qc_reset(q);
258
259 /* Set the brightness. */
260 qcam_set(q, 11, q->brightness);
261
262 /* Set the height and width. These refer to the actual
263 CCD area *before* applying the selected decimation. */
264 qcam_set(q, 17, q->ccd_height);
265 qcam_set(q, 19, q->ccd_width / 2);
266
267 /* Set top and left. */
268 qcam_set(q, 0xd, q->top);
269 qcam_set(q, 0xf, q->left);
270
271 /* Set contrast and white balance. */
272 qcam_set(q, 0x19, q->contrast);
273 qcam_set(q, 0x1f, q->whitebal);
274
275 /* Set the speed. */
276 qcam_set(q, 45, 2);
277}
278
279/* Read some bytes from the camera and put them in the buffer.
280 nbytes should be a multiple of 3, because bidirectional mode gives
281 us three bytes at a time. */
282
283static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
284{
285 unsigned int bytes = 0;
286
287 qcam_set_ack(q, 0);
288 if (q->bidirectional)
289 {
290 /* It's a bidirectional port */
291 while (bytes < nbytes)
292 {
293 unsigned int lo1, hi1, lo2, hi2;
294 unsigned char r, g, b;
295
296 if (qcam_await_ready2(q, 1)) return bytes;
297 lo1 = parport_read_data(q->pport) >> 1;
298 hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
299 qcam_set_ack(q, 1);
300 if (qcam_await_ready2(q, 0)) return bytes;
301 lo2 = parport_read_data(q->pport) >> 1;
302 hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
303 qcam_set_ack(q, 0);
304 r = (lo1 | ((hi1 & 1)<<7));
305 g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
306 b = (lo2 | ((hi2 & 1)<<7));
307 if (force_rgb) {
308 buf[bytes++] = r;
309 buf[bytes++] = g;
310 buf[bytes++] = b;
311 } else {
312 buf[bytes++] = b;
313 buf[bytes++] = g;
314 buf[bytes++] = r;
315 }
316 }
317 }
318 else
319 {
320 /* It's a unidirectional port */
321 int i = 0, n = bytes;
322 unsigned char rgb[3];
323
324 while (bytes < nbytes)
325 {
326 unsigned int hi, lo;
327
328 if (qcam_await_ready1(q, 1)) return bytes;
329 hi = (parport_read_status(q->pport) & 0xf0);
330 qcam_set_ack(q, 1);
331 if (qcam_await_ready1(q, 0)) return bytes;
332 lo = (parport_read_status(q->pport) & 0xf0);
333 qcam_set_ack(q, 0);
334 /* flip some bits */
335 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
336 if (i >= 2) {
337get_fragment:
338 if (force_rgb) {
339 buf[n++] = rgb[0];
340 buf[n++] = rgb[1];
341 buf[n++] = rgb[2];
342 } else {
343 buf[n++] = rgb[2];
344 buf[n++] = rgb[1];
345 buf[n++] = rgb[0];
346 }
347 }
348 }
349 if (i) {
350 i = 0;
351 goto get_fragment;
352 }
353 }
354 return bytes;
355}
356
357#define BUFSZ 150
358
359static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
360{
361 unsigned lines, pixelsperline, bitsperxfer;
362 unsigned int is_bi_dir = q->bidirectional;
363 size_t wantlen, outptr = 0;
364 char tmpbuf[BUFSZ];
365
366 if (!access_ok(VERIFY_WRITE, buf, len))
367 return -EFAULT;
368
369 /* Wait for camera to become ready */
370 for (;;)
371 {
372 int i = qcam_get(q, 41);
373 if (i == -1) {
374 qc_setup(q);
375 return -EIO;
376 }
377 if ((i & 0x80) == 0)
378 break;
379 else
380 schedule();
381 }
382
383 if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
384 return -EIO;
385
386 lines = q->height;
387 pixelsperline = q->width;
388 bitsperxfer = (is_bi_dir) ? 24 : 8;
389
390 if (is_bi_dir)
391 {
392 /* Turn the port around */
393 parport_data_reverse(q->pport);
394 mdelay(3);
395 qcam_set_ack(q, 0);
396 if (qcam_await_ready1(q, 1)) {
397 qc_setup(q);
398 return -EIO;
399 }
400 qcam_set_ack(q, 1);
401 if (qcam_await_ready1(q, 0)) {
402 qc_setup(q);
403 return -EIO;
404 }
405 }
406
407 wantlen = lines * pixelsperline * 24 / 8;
408
409 while (wantlen)
410 {
411 size_t t, s;
412 s = (wantlen > BUFSZ)?BUFSZ:wantlen;
413 t = qcam_read_bytes(q, tmpbuf, s);
414 if (outptr < len)
415 {
416 size_t sz = len - outptr;
417 if (sz > t) sz = t;
418 if (__copy_to_user(buf+outptr, tmpbuf, sz))
419 break;
420 outptr += sz;
421 }
422 wantlen -= t;
423 if (t < s)
424 break;
425 cond_resched();
426 }
427
428 len = outptr;
429
430 if (wantlen)
431 {
432 printk("qcam: short read.\n");
433 if (is_bi_dir)
434 parport_data_forward(q->pport);
435 qc_setup(q);
436 return len;
437 }
438
439 if (is_bi_dir)
440 {
441 int l;
442 do {
443 l = qcam_read_bytes(q, tmpbuf, 3);
444 cond_resched();
445 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
446 if (force_rgb) {
447 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
448 printk("qcam: bad EOF\n");
449 } else {
450 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
451 printk("qcam: bad EOF\n");
452 }
453 qcam_set_ack(q, 0);
454 if (qcam_await_ready1(q, 1))
455 {
456 printk("qcam: no ack after EOF\n");
457 parport_data_forward(q->pport);
458 qc_setup(q);
459 return len;
460 }
461 parport_data_forward(q->pport);
462 mdelay(3);
463 qcam_set_ack(q, 1);
464 if (qcam_await_ready1(q, 0))
465 {
466 printk("qcam: no ack to port turnaround\n");
467 qc_setup(q);
468 return len;
469 }
470 }
471 else
472 {
473 int l;
474 do {
475 l = qcam_read_bytes(q, tmpbuf, 1);
476 cond_resched();
477 } while (l && tmpbuf[0] == 0x7e);
478 l = qcam_read_bytes(q, tmpbuf+1, 2);
479 if (force_rgb) {
480 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
481 printk("qcam: bad EOF\n");
482 } else {
483 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
484 printk("qcam: bad EOF\n");
485 }
486 }
487
488 qcam_write_data(q, 0);
489 return len;
490}
491
492/*
493 * Video4linux interfacing
494 */
495
496static int qcam_do_ioctl(struct inode *inode, struct file *file,
497 unsigned int cmd, void *arg)
498{
499 struct video_device *dev = video_devdata(file);
500 struct qcam_device *qcam=(struct qcam_device *)dev;
501
502 switch(cmd)
503 {
504 case VIDIOCGCAP:
505 {
506 struct video_capability *b = arg;
507 strcpy(b->name, "Quickcam");
508 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
509 b->channels = 1;
510 b->audios = 0;
511 b->maxwidth = 320;
512 b->maxheight = 240;
513 b->minwidth = 80;
514 b->minheight = 60;
515 return 0;
516 }
517 case VIDIOCGCHAN:
518 {
519 struct video_channel *v = arg;
520 if(v->channel!=0)
521 return -EINVAL;
522 v->flags=0;
523 v->tuners=0;
524 /* Good question.. its composite or SVHS so.. */
525 v->type = VIDEO_TYPE_CAMERA;
526 strcpy(v->name, "Camera");
527 return 0;
528 }
529 case VIDIOCSCHAN:
530 {
531 struct video_channel *v = arg;
532 if(v->channel!=0)
533 return -EINVAL;
534 return 0;
535 }
536 case VIDIOCGTUNER:
537 {
538 struct video_tuner *v = arg;
539 if(v->tuner)
540 return -EINVAL;
541 memset(v,0,sizeof(*v));
542 strcpy(v->name, "Format");
543 v->mode = VIDEO_MODE_AUTO;
544 return 0;
545 }
546 case VIDIOCSTUNER:
547 {
548 struct video_tuner *v = arg;
549 if(v->tuner)
550 return -EINVAL;
551 if(v->mode!=VIDEO_MODE_AUTO)
552 return -EINVAL;
553 return 0;
554 }
555 case VIDIOCGPICT:
556 {
557 struct video_picture *p = arg;
558 p->colour=0x8000;
559 p->hue=0x8000;
560 p->brightness=qcam->brightness<<8;
561 p->contrast=qcam->contrast<<8;
562 p->whiteness=qcam->whitebal<<8;
563 p->depth=24;
564 p->palette=VIDEO_PALETTE_RGB24;
565 return 0;
566 }
567 case VIDIOCSPICT:
568 {
569 struct video_picture *p = arg;
570
571 /*
572 * Sanity check args
573 */
574 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
575 return -EINVAL;
576
577 /*
578 * Now load the camera.
579 */
580 qcam->brightness = p->brightness>>8;
581 qcam->contrast = p->contrast>>8;
582 qcam->whitebal = p->whiteness>>8;
583
584 down(&qcam->lock);
585 parport_claim_or_block(qcam->pdev);
586 qc_setup(qcam);
587 parport_release(qcam->pdev);
588 up(&qcam->lock);
589 return 0;
590 }
591 case VIDIOCSWIN:
592 {
593 struct video_window *vw = arg;
594
595 if(vw->flags)
596 return -EINVAL;
597 if(vw->clipcount)
598 return -EINVAL;
599 if(vw->height<60||vw->height>240)
600 return -EINVAL;
601 if(vw->width<80||vw->width>320)
602 return -EINVAL;
603
604 qcam->width = 80;
605 qcam->height = 60;
606 qcam->mode = QC_DECIMATION_4;
607
608 if(vw->width>=160 && vw->height>=120)
609 {
610 qcam->width = 160;
611 qcam->height = 120;
612 qcam->mode = QC_DECIMATION_2;
613 }
614 if(vw->width>=320 && vw->height>=240)
615 {
616 qcam->width = 320;
617 qcam->height = 240;
618 qcam->mode = QC_DECIMATION_1;
619 }
620 qcam->mode |= QC_MILLIONS;
621#if 0
622 if(vw->width>=640 && vw->height>=480)
623 {
624 qcam->width = 640;
625 qcam->height = 480;
626 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
627 }
628#endif
629 /* Ok we figured out what to use from our
630 wide choice */
631 down(&qcam->lock);
632 parport_claim_or_block(qcam->pdev);
633 qc_setup(qcam);
634 parport_release(qcam->pdev);
635 up(&qcam->lock);
636 return 0;
637 }
638 case VIDIOCGWIN:
639 {
640 struct video_window *vw = arg;
641 memset(vw, 0, sizeof(*vw));
642 vw->width=qcam->width;
643 vw->height=qcam->height;
644 return 0;
645 }
646 case VIDIOCKEY:
647 return 0;
648 case VIDIOCCAPTURE:
649 case VIDIOCGFBUF:
650 case VIDIOCSFBUF:
651 case VIDIOCGFREQ:
652 case VIDIOCSFREQ:
653 case VIDIOCGAUDIO:
654 case VIDIOCSAUDIO:
655 return -EINVAL;
656 default:
657 return -ENOIOCTLCMD;
658 }
659 return 0;
660}
661
662static int qcam_ioctl(struct inode *inode, struct file *file,
663 unsigned int cmd, unsigned long arg)
664{
665 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
666}
667
668static ssize_t qcam_read(struct file *file, char __user *buf,
669 size_t count, loff_t *ppos)
670{
671 struct video_device *v = video_devdata(file);
672 struct qcam_device *qcam=(struct qcam_device *)v;
673 int len;
674
675 down(&qcam->lock);
676 parport_claim_or_block(qcam->pdev);
677 /* Probably should have a semaphore against multiple users */
678 len = qc_capture(qcam, buf,count);
679 parport_release(qcam->pdev);
680 up(&qcam->lock);
681 return len;
682}
683
684/* video device template */
685static struct file_operations qcam_fops = {
686 .owner = THIS_MODULE,
687 .open = video_exclusive_open,
688 .release = video_exclusive_release,
689 .ioctl = qcam_ioctl,
690 .read = qcam_read,
691 .llseek = no_llseek,
692};
693
694static struct video_device qcam_template=
695{
696 .owner = THIS_MODULE,
697 .name = "Colour QuickCam",
698 .type = VID_TYPE_CAPTURE,
699 .hardware = VID_HARDWARE_QCAM_C,
700 .fops = &qcam_fops,
701};
702
703/* Initialize the QuickCam driver control structure. */
704
705static struct qcam_device *qcam_init(struct parport *port)
706{
707 struct qcam_device *q;
708
709 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
710 if(q==NULL)
711 return NULL;
712
713 q->pport = port;
714 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
715 NULL, 0, NULL);
716
717 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
718
719 if (q->pdev == NULL)
720 {
721 printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
722 port->name);
723 kfree(q);
724 return NULL;
725 }
726
727 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
728
729 init_MUTEX(&q->lock);
730 q->width = q->ccd_width = 320;
731 q->height = q->ccd_height = 240;
732 q->mode = QC_MILLIONS | QC_DECIMATION_1;
733 q->contrast = 192;
734 q->brightness = 240;
735 q->whitebal = 128;
736 q->top = 1;
737 q->left = 14;
738 return q;
739}
740
741static struct qcam_device *qcams[MAX_CAMS];
742static unsigned int num_cams = 0;
743
744static int init_cqcam(struct parport *port)
745{
746 struct qcam_device *qcam;
747
748 if (parport[0] != -1)
749 {
750 /* The user gave specific instructions */
751 int i, found = 0;
752 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
753 {
754 if (parport[0] == port->number)
755 found = 1;
756 }
757 if (!found)
758 return -ENODEV;
759 }
760
761 if (num_cams == MAX_CAMS)
762 return -ENOSPC;
763
764 qcam = qcam_init(port);
765 if (qcam==NULL)
766 return -ENODEV;
767
768 parport_claim_or_block(qcam->pdev);
769
770 qc_reset(qcam);
771
772 if (probe && qc_detect(qcam)==0)
773 {
774 parport_release(qcam->pdev);
775 parport_unregister_device(qcam->pdev);
776 kfree(qcam);
777 return -ENODEV;
778 }
779
780 qc_setup(qcam);
781
782 parport_release(qcam->pdev);
783
784 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
785 {
786 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
787 qcam->pport->name);
788 parport_unregister_device(qcam->pdev);
789 kfree(qcam);
790 return -ENODEV;
791 }
792
793 printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
794 qcam->vdev.minor, qcam->pport->name);
795
796 qcams[num_cams++] = qcam;
797
798 return 0;
799}
800
801static void close_cqcam(struct qcam_device *qcam)
802{
803 video_unregister_device(&qcam->vdev);
804 parport_unregister_device(qcam->pdev);
805 kfree(qcam);
806}
807
808static void cq_attach(struct parport *port)
809{
810 init_cqcam(port);
811}
812
813static void cq_detach(struct parport *port)
814{
815 /* Write this some day. */
816}
817
818static struct parport_driver cqcam_driver = {
819 .name = "cqcam",
820 .attach = cq_attach,
821 .detach = cq_detach,
822};
823
824static int __init cqcam_init (void)
825{
826 printk(BANNER "\n");
827
828 return parport_register_driver(&cqcam_driver);
829}
830
831static void __exit cqcam_cleanup (void)
832{
833 unsigned int i;
834
835 for (i = 0; i < num_cams; i++)
836 close_cqcam(qcams[i]);
837
838 parport_unregister_driver(&cqcam_driver);
839}
840
841MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
842MODULE_DESCRIPTION(BANNER);
843MODULE_LICENSE("GPL");
844
845/* FIXME: parport=auto would never have worked, surely? --RR */
846MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
847probe=<0|1|2> for camera detection method\n\
848force_rgb=<0|1> for RGB data format (default BGR)");
849module_param_array(parport, int, NULL, 0);
850module_param(probe, int, 0);
851module_param(force_rgb, bool, 0);
852module_param(video_nr, int, 0);
853
854module_init(cqcam_init);
855module_exit(cqcam_cleanup);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
new file mode 100644
index 000000000000..8c08b7f1ad23
--- /dev/null
+++ b/drivers/media/video/cpia.c
@@ -0,0 +1,4073 @@
1/*
2 * cpia CPiA driver
3 *
4 * Supports CPiA based Video Camera's.
5 *
6 * (C) Copyright 1999-2000 Peter Pregler
7 * (C) Copyright 1999-2000 Scott J. Bertin
8 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
9 * (C) Copyright 2000 STMicroelectronics
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
27/* #define _CPIA_DEBUG_ 1 */
28
29#include <linux/config.h>
30
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/init.h>
34#include <linux/fs.h>
35#include <linux/vmalloc.h>
36#include <linux/slab.h>
37#include <linux/proc_fs.h>
38#include <linux/ctype.h>
39#include <linux/pagemap.h>
40#include <linux/delay.h>
41#include <asm/io.h>
42#include <asm/semaphore.h>
43
44#ifdef CONFIG_KMOD
45#include <linux/kmod.h>
46#endif
47
48#include "cpia.h"
49
50#ifdef CONFIG_VIDEO_CPIA_PP
51extern int cpia_pp_init(void);
52#endif
53#ifdef CONFIG_VIDEO_CPIA_USB
54extern int cpia_usb_init(void);
55#endif
56
57static int video_nr = -1;
58
59#ifdef MODULE
60module_param(video_nr, int, 0);
61MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");
62MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
63MODULE_LICENSE("GPL");
64MODULE_SUPPORTED_DEVICE("video");
65#endif
66
67static unsigned short colorspace_conv = 0;
68module_param(colorspace_conv, ushort, 0444);
69MODULE_PARM_DESC(colorspace_conv,
70 "\n<n> Colorspace conversion:"
71 "\n0 = disable"
72 "\n1 = enable"
73 "\nDefault value is 0"
74 "\n");
75
76#define ABOUT "V4L-Driver for Vision CPiA based cameras"
77
78#ifndef VID_HARDWARE_CPIA
79#define VID_HARDWARE_CPIA 24 /* FIXME -> from linux/videodev.h */
80#endif
81
82#define CPIA_MODULE_CPIA (0<<5)
83#define CPIA_MODULE_SYSTEM (1<<5)
84#define CPIA_MODULE_VP_CTRL (5<<5)
85#define CPIA_MODULE_CAPTURE (6<<5)
86#define CPIA_MODULE_DEBUG (7<<5)
87
88#define INPUT (DATA_IN << 8)
89#define OUTPUT (DATA_OUT << 8)
90
91#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
92#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
93#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
94#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
95#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
96#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
97#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
98#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
99
100#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
101#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
102#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
103#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
104#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
105#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
106#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
107#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
108#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
109#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
110#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
111#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
112#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
113
114#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
115#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
116#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
117#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
118#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
119#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
120#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
121#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
122#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
123#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
124#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
125#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
126#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
127#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
128#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
129#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
130#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
131
132#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
133#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
134#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
135#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
136#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
137#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
138#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
139#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
140#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
141#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
142#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
143#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
144#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
145#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
146#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
147
148#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
149#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
150#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
151#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
152#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
153#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
154#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
155#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
156
157enum {
158 FRAME_READY, /* Ready to grab into */
159 FRAME_GRABBING, /* In the process of being grabbed into */
160 FRAME_DONE, /* Finished grabbing, but not been synced yet */
161 FRAME_UNUSED, /* Unused (no MCAPTURE) */
162};
163
164#define COMMAND_NONE 0x0000
165#define COMMAND_SETCOMPRESSION 0x0001
166#define COMMAND_SETCOMPRESSIONTARGET 0x0002
167#define COMMAND_SETCOLOURPARAMS 0x0004
168#define COMMAND_SETFORMAT 0x0008
169#define COMMAND_PAUSE 0x0010
170#define COMMAND_RESUME 0x0020
171#define COMMAND_SETYUVTHRESH 0x0040
172#define COMMAND_SETECPTIMING 0x0080
173#define COMMAND_SETCOMPRESSIONPARAMS 0x0100
174#define COMMAND_SETEXPOSURE 0x0200
175#define COMMAND_SETCOLOURBALANCE 0x0400
176#define COMMAND_SETSENSORFPS 0x0800
177#define COMMAND_SETAPCOR 0x1000
178#define COMMAND_SETFLICKERCTRL 0x2000
179#define COMMAND_SETVLOFFSET 0x4000
180#define COMMAND_SETLIGHTS 0x8000
181
182#define ROUND_UP_EXP_FOR_FLICKER 15
183
184/* Constants for automatic frame rate adjustment */
185#define MAX_EXP 302
186#define MAX_EXP_102 255
187#define LOW_EXP 140
188#define VERY_LOW_EXP 70
189#define TC 94
190#define EXP_ACC_DARK 50
191#define EXP_ACC_LIGHT 90
192#define HIGH_COMP_102 160
193#define MAX_COMP 239
194#define DARK_TIME 3
195#define LIGHT_TIME 3
196
197/* Maximum number of 10ms loops to wait for the stream to become ready */
198#define READY_TIMEOUT 100
199
200/* Developer's Guide Table 5 p 3-34
201 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
202static u8 flicker_jumps[2][2][4] =
203{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
204 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
205};
206
207/* forward declaration of local function */
208static void reset_camera_struct(struct cam_data *cam);
209static int find_over_exposure(int brightness);
210static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
211 int on);
212
213
214/**********************************************************************
215 *
216 * Memory management
217 *
218 **********************************************************************/
219static void *rvmalloc(unsigned long size)
220{
221 void *mem;
222 unsigned long adr;
223
224 size = PAGE_ALIGN(size);
225 mem = vmalloc_32(size);
226 if (!mem)
227 return NULL;
228
229 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
230 adr = (unsigned long) mem;
231 while (size > 0) {
232 SetPageReserved(vmalloc_to_page((void *)adr));
233 adr += PAGE_SIZE;
234 size -= PAGE_SIZE;
235 }
236
237 return mem;
238}
239
240static void rvfree(void *mem, unsigned long size)
241{
242 unsigned long adr;
243
244 if (!mem)
245 return;
246
247 adr = (unsigned long) mem;
248 while ((long) size > 0) {
249 ClearPageReserved(vmalloc_to_page((void *)adr));
250 adr += PAGE_SIZE;
251 size -= PAGE_SIZE;
252 }
253 vfree(mem);
254}
255
256/**********************************************************************
257 *
258 * /proc interface
259 *
260 **********************************************************************/
261#ifdef CONFIG_PROC_FS
262static struct proc_dir_entry *cpia_proc_root=NULL;
263
264static int cpia_read_proc(char *page, char **start, off_t off,
265 int count, int *eof, void *data)
266{
267 char *out = page;
268 int len, tmp;
269 struct cam_data *cam = data;
270 char tmpstr[29];
271
272 /* IMPORTANT: This output MUST be kept under PAGE_SIZE
273 * or we need to get more sophisticated. */
274
275 out += sprintf(out, "read-only\n-----------------------\n");
276 out += sprintf(out, "V4L Driver version: %d.%d.%d\n",
277 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
278 out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n",
279 cam->params.version.firmwareVersion,
280 cam->params.version.firmwareRevision,
281 cam->params.version.vcVersion,
282 cam->params.version.vcRevision);
283 out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n",
284 cam->params.pnpID.vendor, cam->params.pnpID.product,
285 cam->params.pnpID.deviceRevision);
286 out += sprintf(out, "VP-Version: %d.%d %04x\n",
287 cam->params.vpVersion.vpVersion,
288 cam->params.vpVersion.vpRevision,
289 cam->params.vpVersion.cameraHeadID);
290
291 out += sprintf(out, "system_state: %#04x\n",
292 cam->params.status.systemState);
293 out += sprintf(out, "grab_state: %#04x\n",
294 cam->params.status.grabState);
295 out += sprintf(out, "stream_state: %#04x\n",
296 cam->params.status.streamState);
297 out += sprintf(out, "fatal_error: %#04x\n",
298 cam->params.status.fatalError);
299 out += sprintf(out, "cmd_error: %#04x\n",
300 cam->params.status.cmdError);
301 out += sprintf(out, "debug_flags: %#04x\n",
302 cam->params.status.debugFlags);
303 out += sprintf(out, "vp_status: %#04x\n",
304 cam->params.status.vpStatus);
305 out += sprintf(out, "error_code: %#04x\n",
306 cam->params.status.errorCode);
307 /* QX3 specific entries */
308 if (cam->params.qx3.qx3_detected) {
309 out += sprintf(out, "button: %4d\n",
310 cam->params.qx3.button);
311 out += sprintf(out, "cradled: %4d\n",
312 cam->params.qx3.cradled);
313 }
314 out += sprintf(out, "video_size: %s\n",
315 cam->params.format.videoSize == VIDEOSIZE_CIF ?
316 "CIF " : "QCIF");
317 out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n",
318 cam->params.roi.colStart*8,
319 cam->params.roi.rowStart*4,
320 cam->params.roi.colEnd*8,
321 cam->params.roi.rowEnd*4);
322 out += sprintf(out, "actual_fps: %3d\n", cam->fps);
323 out += sprintf(out, "transfer_rate: %4dkB/s\n",
324 cam->transfer_rate);
325
326 out += sprintf(out, "\nread-write\n");
327 out += sprintf(out, "----------------------- current min"
328 " max default comment\n");
329 out += sprintf(out, "brightness: %8d %8d %8d %8d\n",
330 cam->params.colourParams.brightness, 0, 100, 50);
331 if (cam->params.version.firmwareVersion == 1 &&
332 cam->params.version.firmwareRevision == 2)
333 /* 1-02 firmware limits contrast to 80 */
334 tmp = 80;
335 else
336 tmp = 96;
337
338 out += sprintf(out, "contrast: %8d %8d %8d %8d"
339 " steps of 8\n",
340 cam->params.colourParams.contrast, 0, tmp, 48);
341 out += sprintf(out, "saturation: %8d %8d %8d %8d\n",
342 cam->params.colourParams.saturation, 0, 100, 50);
343 tmp = (25000+5000*cam->params.sensorFps.baserate)/
344 (1<<cam->params.sensorFps.divisor);
345 out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n",
346 tmp/1000, tmp%1000, 3, 30, 15);
347 out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n",
348 2*cam->params.streamStartLine, 0,
349 cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
350 cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
351 out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n",
352 cam->params.format.subSample == SUBSAMPLE_420 ?
353 "420" : "422", "420", "422", "422");
354 out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n",
355 cam->params.format.yuvOrder == YUVORDER_YUYV ?
356 "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
357 out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n",
358 cam->params.ecpTiming ? "slow" : "normal", "slow",
359 "normal", "normal");
360
361 if (cam->params.colourBalance.balanceMode == 2) {
362 sprintf(tmpstr, "auto");
363 } else {
364 sprintf(tmpstr, "manual");
365 }
366 out += sprintf(out, "color_balance_mode: %8s %8s %8s"
367 " %8s\n", tmpstr, "manual", "auto", "auto");
368 out += sprintf(out, "red_gain: %8d %8d %8d %8d\n",
369 cam->params.colourBalance.redGain, 0, 212, 32);
370 out += sprintf(out, "green_gain: %8d %8d %8d %8d\n",
371 cam->params.colourBalance.greenGain, 0, 212, 6);
372 out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n",
373 cam->params.colourBalance.blueGain, 0, 212, 92);
374
375 if (cam->params.version.firmwareVersion == 1 &&
376 cam->params.version.firmwareRevision == 2)
377 /* 1-02 firmware limits gain to 2 */
378 sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2);
379 else
380 sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
381
382 if (cam->params.exposure.gainMode == 0)
383 out += sprintf(out, "max_gain: unknown %28s"
384 " powers of 2\n", tmpstr);
385 else
386 out += sprintf(out, "max_gain: %8d %28s"
387 " 1,2,4 or 8 \n",
388 1<<(cam->params.exposure.gainMode-1), tmpstr);
389
390 switch(cam->params.exposure.expMode) {
391 case 1:
392 case 3:
393 sprintf(tmpstr, "manual");
394 break;
395 case 2:
396 sprintf(tmpstr, "auto");
397 break;
398 default:
399 sprintf(tmpstr, "unknown");
400 break;
401 }
402 out += sprintf(out, "exposure_mode: %8s %8s %8s"
403 " %8s\n", tmpstr, "manual", "auto", "auto");
404 out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n",
405 (2-cam->params.exposure.centreWeight) ? "on" : "off",
406 "off", "on", "on");
407 out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
408 1<<cam->params.exposure.gain, 1, 1);
409 if (cam->params.version.firmwareVersion == 1 &&
410 cam->params.version.firmwareRevision == 2)
411 /* 1-02 firmware limits fineExp/2 to 127 */
412 tmp = 254;
413 else
414 tmp = 510;
415
416 out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n",
417 cam->params.exposure.fineExp*2, 0, tmp, 0);
418 if (cam->params.version.firmwareVersion == 1 &&
419 cam->params.version.firmwareRevision == 2)
420 /* 1-02 firmware limits coarseExpHi to 0 */
421 tmp = MAX_EXP_102;
422 else
423 tmp = MAX_EXP;
424
425 out += sprintf(out, "coarse_exp: %8d %8d %8d"
426 " %8d\n", cam->params.exposure.coarseExpLo+
427 256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
428 out += sprintf(out, "red_comp: %8d %8d %8d %8d\n",
429 cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
430 out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n",
431 cam->params.exposure.green1Comp, COMP_GREEN1, 255,
432 COMP_GREEN1);
433 out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n",
434 cam->params.exposure.green2Comp, COMP_GREEN2, 255,
435 COMP_GREEN2);
436 out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n",
437 cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
438
439 out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
440 cam->params.apcor.gain1, 0, 0xff, 0x1c);
441 out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
442 cam->params.apcor.gain2, 0, 0xff, 0x1a);
443 out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
444 cam->params.apcor.gain4, 0, 0xff, 0x2d);
445 out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
446 cam->params.apcor.gain8, 0, 0xff, 0x2a);
447 out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n",
448 cam->params.vlOffset.gain1, 0, 255, 24);
449 out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n",
450 cam->params.vlOffset.gain2, 0, 255, 28);
451 out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n",
452 cam->params.vlOffset.gain4, 0, 255, 30);
453 out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n",
454 cam->params.vlOffset.gain8, 0, 255, 30);
455 out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n",
456 cam->params.flickerControl.flickerMode ? "on" : "off",
457 "off", "on", "off");
458 out += sprintf(out, "mains_frequency: %8d %8d %8d %8d"
459 " only 50/60\n",
460 cam->mainsFreq ? 60 : 50, 50, 60, 50);
461 if(cam->params.flickerControl.allowableOverExposure < 0)
462 out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n",
463 -cam->params.flickerControl.allowableOverExposure,
464 255);
465 else
466 out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n",
467 cam->params.flickerControl.allowableOverExposure,
468 255);
469 out += sprintf(out, "compression_mode: ");
470 switch(cam->params.compression.mode) {
471 case CPIA_COMPRESSION_NONE:
472 out += sprintf(out, "%8s", "none");
473 break;
474 case CPIA_COMPRESSION_AUTO:
475 out += sprintf(out, "%8s", "auto");
476 break;
477 case CPIA_COMPRESSION_MANUAL:
478 out += sprintf(out, "%8s", "manual");
479 break;
480 default:
481 out += sprintf(out, "%8s", "unknown");
482 break;
483 }
484 out += sprintf(out, " none,auto,manual auto\n");
485 out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n",
486 cam->params.compression.decimation ==
487 DECIMATION_ENAB ? "on":"off", "off", "on",
488 "off");
489 out += sprintf(out, "compression_target: %9s %9s %9s %9s\n",
490 cam->params.compressionTarget.frTargeting ==
491 CPIA_COMPRESSION_TARGET_FRAMERATE ?
492 "framerate":"quality",
493 "framerate", "quality", "quality");
494 out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n",
495 cam->params.compressionTarget.targetFR, 1, 30, 15);
496 out += sprintf(out, "target_quality: %8d %8d %8d %8d\n",
497 cam->params.compressionTarget.targetQ, 1, 64, 5);
498 out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n",
499 cam->params.yuvThreshold.yThreshold, 0, 31, 6);
500 out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n",
501 cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
502 out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n",
503 cam->params.compressionParams.hysteresis, 0, 255, 3);
504 out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n",
505 cam->params.compressionParams.threshMax, 0, 255, 11);
506 out += sprintf(out, "small_step: %8d %8d %8d %8d\n",
507 cam->params.compressionParams.smallStep, 0, 255, 1);
508 out += sprintf(out, "large_step: %8d %8d %8d %8d\n",
509 cam->params.compressionParams.largeStep, 0, 255, 3);
510 out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n",
511 cam->params.compressionParams.decimationHysteresis,
512 0, 255, 2);
513 out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
514 cam->params.compressionParams.frDiffStepThresh,
515 0, 255, 5);
516 out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n",
517 cam->params.compressionParams.qDiffStepThresh,
518 0, 255, 3);
519 out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
520 cam->params.compressionParams.decimationThreshMod,
521 0, 255, 2);
522 /* QX3 specific entries */
523 if (cam->params.qx3.qx3_detected) {
524 out += sprintf(out, "toplight: %8s %8s %8s %8s\n",
525 cam->params.qx3.toplight ? "on" : "off",
526 "off", "on", "off");
527 out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n",
528 cam->params.qx3.bottomlight ? "on" : "off",
529 "off", "on", "off");
530 }
531
532 len = out - page;
533 len -= off;
534 if (len < count) {
535 *eof = 1;
536 if (len <= 0) return 0;
537 } else
538 len = count;
539
540 *start = page + off;
541 return len;
542}
543
544
545static int match(char *checkstr, char **buffer, unsigned long *count,
546 int *find_colon, int *err)
547{
548 int ret, colon_found = 1;
549 int len = strlen(checkstr);
550 ret = (len <= *count && strncmp(*buffer, checkstr, len) == 0);
551 if (ret) {
552 *buffer += len;
553 *count -= len;
554 if (*find_colon) {
555 colon_found = 0;
556 while (*count && (**buffer == ' ' || **buffer == '\t' ||
557 (!colon_found && **buffer == ':'))) {
558 if (**buffer == ':')
559 colon_found = 1;
560 --*count;
561 ++*buffer;
562 }
563 if (!*count || !colon_found)
564 *err = -EINVAL;
565 *find_colon = 0;
566 }
567 }
568 return ret;
569}
570
571static unsigned long int value(char **buffer, unsigned long *count, int *err)
572{
573 char *p;
574 unsigned long int ret;
575 ret = simple_strtoul(*buffer, &p, 0);
576 if (p == *buffer)
577 *err = -EINVAL;
578 else {
579 *count -= p - *buffer;
580 *buffer = p;
581 }
582 return ret;
583}
584
585static int cpia_write_proc(struct file *file, const char __user *buf,
586 unsigned long count, void *data)
587{
588 struct cam_data *cam = data;
589 struct cam_params new_params;
590 char *page, *buffer;
591 int retval, find_colon;
592 int size = count;
593 unsigned long val = 0;
594 u32 command_flags = 0;
595 u8 new_mains;
596
597 /*
598 * This code to copy from buf to page is shamelessly copied
599 * from the comx driver
600 */
601 if (count > PAGE_SIZE) {
602 printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
603 return -ENOSPC;
604 }
605
606 if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
607
608 if(copy_from_user(page, buf, count))
609 {
610 retval = -EFAULT;
611 goto out;
612 }
613
614 if (page[count-1] == '\n')
615 page[count-1] = '\0';
616 else if (count < PAGE_SIZE)
617 page[count] = '\0';
618 else if (page[count]) {
619 retval = -EINVAL;
620 goto out;
621 }
622
623 buffer = page;
624
625 if (down_interruptible(&cam->param_lock))
626 return -ERESTARTSYS;
627
628 /*
629 * Skip over leading whitespace
630 */
631 while (count && isspace(*buffer)) {
632 --count;
633 ++buffer;
634 }
635
636 memcpy(&new_params, &cam->params, sizeof(struct cam_params));
637 new_mains = cam->mainsFreq;
638
639#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
640#define VALUE (value(&buffer,&count, &retval))
641#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
642 new_params.version.firmwareRevision == (y))
643
644 retval = 0;
645 while (count && !retval) {
646 find_colon = 1;
647 if (MATCH("brightness")) {
648 if (!retval)
649 val = VALUE;
650
651 if (!retval) {
652 if (val <= 100)
653 new_params.colourParams.brightness = val;
654 else
655 retval = -EINVAL;
656 }
657 command_flags |= COMMAND_SETCOLOURPARAMS;
658 if(new_params.flickerControl.allowableOverExposure < 0)
659 new_params.flickerControl.allowableOverExposure =
660 -find_over_exposure(new_params.colourParams.brightness);
661 if(new_params.flickerControl.flickerMode != 0)
662 command_flags |= COMMAND_SETFLICKERCTRL;
663
664 } else if (MATCH("contrast")) {
665 if (!retval)
666 val = VALUE;
667
668 if (!retval) {
669 if (val <= 100) {
670 /* contrast is in steps of 8, so round*/
671 val = ((val + 3) / 8) * 8;
672 /* 1-02 firmware limits contrast to 80*/
673 if (FIRMWARE_VERSION(1,2) && val > 80)
674 val = 80;
675
676 new_params.colourParams.contrast = val;
677 } else
678 retval = -EINVAL;
679 }
680 command_flags |= COMMAND_SETCOLOURPARAMS;
681 } else if (MATCH("saturation")) {
682 if (!retval)
683 val = VALUE;
684
685 if (!retval) {
686 if (val <= 100)
687 new_params.colourParams.saturation = val;
688 else
689 retval = -EINVAL;
690 }
691 command_flags |= COMMAND_SETCOLOURPARAMS;
692 } else if (MATCH("sensor_fps")) {
693 if (!retval)
694 val = VALUE;
695
696 if (!retval) {
697 /* find values so that sensorFPS is minimized,
698 * but >= val */
699 if (val > 30)
700 retval = -EINVAL;
701 else if (val > 25) {
702 new_params.sensorFps.divisor = 0;
703 new_params.sensorFps.baserate = 1;
704 } else if (val > 15) {
705 new_params.sensorFps.divisor = 0;
706 new_params.sensorFps.baserate = 0;
707 } else if (val > 12) {
708 new_params.sensorFps.divisor = 1;
709 new_params.sensorFps.baserate = 1;
710 } else if (val > 7) {
711 new_params.sensorFps.divisor = 1;
712 new_params.sensorFps.baserate = 0;
713 } else if (val > 6) {
714 new_params.sensorFps.divisor = 2;
715 new_params.sensorFps.baserate = 1;
716 } else if (val > 3) {
717 new_params.sensorFps.divisor = 2;
718 new_params.sensorFps.baserate = 0;
719 } else {
720 new_params.sensorFps.divisor = 3;
721 /* Either base rate would work here */
722 new_params.sensorFps.baserate = 1;
723 }
724 new_params.flickerControl.coarseJump =
725 flicker_jumps[new_mains]
726 [new_params.sensorFps.baserate]
727 [new_params.sensorFps.divisor];
728 if (new_params.flickerControl.flickerMode)
729 command_flags |= COMMAND_SETFLICKERCTRL;
730 }
731 command_flags |= COMMAND_SETSENSORFPS;
732 cam->exposure_status = EXPOSURE_NORMAL;
733 } else if (MATCH("stream_start_line")) {
734 if (!retval)
735 val = VALUE;
736
737 if (!retval) {
738 int max_line = 288;
739
740 if (new_params.format.videoSize == VIDEOSIZE_QCIF)
741 max_line = 144;
742 if (val <= max_line)
743 new_params.streamStartLine = val/2;
744 else
745 retval = -EINVAL;
746 }
747 } else if (MATCH("sub_sample")) {
748 if (!retval && MATCH("420"))
749 new_params.format.subSample = SUBSAMPLE_420;
750 else if (!retval && MATCH("422"))
751 new_params.format.subSample = SUBSAMPLE_422;
752 else
753 retval = -EINVAL;
754
755 command_flags |= COMMAND_SETFORMAT;
756 } else if (MATCH("yuv_order")) {
757 if (!retval && MATCH("YUYV"))
758 new_params.format.yuvOrder = YUVORDER_YUYV;
759 else if (!retval && MATCH("UYVY"))
760 new_params.format.yuvOrder = YUVORDER_UYVY;
761 else
762 retval = -EINVAL;
763
764 command_flags |= COMMAND_SETFORMAT;
765 } else if (MATCH("ecp_timing")) {
766 if (!retval && MATCH("normal"))
767 new_params.ecpTiming = 0;
768 else if (!retval && MATCH("slow"))
769 new_params.ecpTiming = 1;
770 else
771 retval = -EINVAL;
772
773 command_flags |= COMMAND_SETECPTIMING;
774 } else if (MATCH("color_balance_mode")) {
775 if (!retval && MATCH("manual"))
776 new_params.colourBalance.balanceMode = 3;
777 else if (!retval && MATCH("auto"))
778 new_params.colourBalance.balanceMode = 2;
779 else
780 retval = -EINVAL;
781
782 command_flags |= COMMAND_SETCOLOURBALANCE;
783 } else if (MATCH("red_gain")) {
784 if (!retval)
785 val = VALUE;
786
787 if (!retval) {
788 if (val <= 212) {
789 new_params.colourBalance.redGain = val;
790 new_params.colourBalance.balanceMode = 1;
791 } else
792 retval = -EINVAL;
793 }
794 command_flags |= COMMAND_SETCOLOURBALANCE;
795 } else if (MATCH("green_gain")) {
796 if (!retval)
797 val = VALUE;
798
799 if (!retval) {
800 if (val <= 212) {
801 new_params.colourBalance.greenGain = val;
802 new_params.colourBalance.balanceMode = 1;
803 } else
804 retval = -EINVAL;
805 }
806 command_flags |= COMMAND_SETCOLOURBALANCE;
807 } else if (MATCH("blue_gain")) {
808 if (!retval)
809 val = VALUE;
810
811 if (!retval) {
812 if (val <= 212) {
813 new_params.colourBalance.blueGain = val;
814 new_params.colourBalance.balanceMode = 1;
815 } else
816 retval = -EINVAL;
817 }
818 command_flags |= COMMAND_SETCOLOURBALANCE;
819 } else if (MATCH("max_gain")) {
820 if (!retval)
821 val = VALUE;
822
823 if (!retval) {
824 /* 1-02 firmware limits gain to 2 */
825 if (FIRMWARE_VERSION(1,2) && val > 2)
826 val = 2;
827 switch(val) {
828 case 1:
829 new_params.exposure.gainMode = 1;
830 break;
831 case 2:
832 new_params.exposure.gainMode = 2;
833 break;
834 case 4:
835 new_params.exposure.gainMode = 3;
836 break;
837 case 8:
838 new_params.exposure.gainMode = 4;
839 break;
840 default:
841 retval = -EINVAL;
842 break;
843 }
844 }
845 command_flags |= COMMAND_SETEXPOSURE;
846 } else if (MATCH("exposure_mode")) {
847 if (!retval && MATCH("auto"))
848 new_params.exposure.expMode = 2;
849 else if (!retval && MATCH("manual")) {
850 if (new_params.exposure.expMode == 2)
851 new_params.exposure.expMode = 3;
852 if(new_params.flickerControl.flickerMode != 0)
853 command_flags |= COMMAND_SETFLICKERCTRL;
854 new_params.flickerControl.flickerMode = 0;
855 } else
856 retval = -EINVAL;
857
858 command_flags |= COMMAND_SETEXPOSURE;
859 } else if (MATCH("centre_weight")) {
860 if (!retval && MATCH("on"))
861 new_params.exposure.centreWeight = 1;
862 else if (!retval && MATCH("off"))
863 new_params.exposure.centreWeight = 2;
864 else
865 retval = -EINVAL;
866
867 command_flags |= COMMAND_SETEXPOSURE;
868 } else if (MATCH("gain")) {
869 if (!retval)
870 val = VALUE;
871
872 if (!retval) {
873 switch(val) {
874 case 1:
875 new_params.exposure.gain = 0;
876 break;
877 case 2:
878 new_params.exposure.gain = 1;
879 break;
880 case 4:
881 new_params.exposure.gain = 2;
882 break;
883 case 8:
884 new_params.exposure.gain = 3;
885 break;
886 default:
887 retval = -EINVAL;
888 break;
889 }
890 new_params.exposure.expMode = 1;
891 if(new_params.flickerControl.flickerMode != 0)
892 command_flags |= COMMAND_SETFLICKERCTRL;
893 new_params.flickerControl.flickerMode = 0;
894 command_flags |= COMMAND_SETEXPOSURE;
895 if (new_params.exposure.gain >
896 new_params.exposure.gainMode-1)
897 retval = -EINVAL;
898 }
899 } else if (MATCH("fine_exp")) {
900 if (!retval)
901 val = VALUE/2;
902
903 if (!retval) {
904 if (val < 256) {
905 /* 1-02 firmware limits fineExp/2 to 127*/
906 if (FIRMWARE_VERSION(1,2) && val > 127)
907 val = 127;
908 new_params.exposure.fineExp = val;
909 new_params.exposure.expMode = 1;
910 command_flags |= COMMAND_SETEXPOSURE;
911 if(new_params.flickerControl.flickerMode != 0)
912 command_flags |= COMMAND_SETFLICKERCTRL;
913 new_params.flickerControl.flickerMode = 0;
914 command_flags |= COMMAND_SETFLICKERCTRL;
915 } else
916 retval = -EINVAL;
917 }
918 } else if (MATCH("coarse_exp")) {
919 if (!retval)
920 val = VALUE;
921
922 if (!retval) {
923 if (val <= MAX_EXP) {
924 if (FIRMWARE_VERSION(1,2) &&
925 val > MAX_EXP_102)
926 val = MAX_EXP_102;
927 new_params.exposure.coarseExpLo =
928 val & 0xff;
929 new_params.exposure.coarseExpHi =
930 val >> 8;
931 new_params.exposure.expMode = 1;
932 command_flags |= COMMAND_SETEXPOSURE;
933 if(new_params.flickerControl.flickerMode != 0)
934 command_flags |= COMMAND_SETFLICKERCTRL;
935 new_params.flickerControl.flickerMode = 0;
936 command_flags |= COMMAND_SETFLICKERCTRL;
937 } else
938 retval = -EINVAL;
939 }
940 } else if (MATCH("red_comp")) {
941 if (!retval)
942 val = VALUE;
943
944 if (!retval) {
945 if (val >= COMP_RED && val <= 255) {
946 new_params.exposure.redComp = val;
947 new_params.exposure.compMode = 1;
948 command_flags |= COMMAND_SETEXPOSURE;
949 } else
950 retval = -EINVAL;
951 }
952 } else if (MATCH("green1_comp")) {
953 if (!retval)
954 val = VALUE;
955
956 if (!retval) {
957 if (val >= COMP_GREEN1 && val <= 255) {
958 new_params.exposure.green1Comp = val;
959 new_params.exposure.compMode = 1;
960 command_flags |= COMMAND_SETEXPOSURE;
961 } else
962 retval = -EINVAL;
963 }
964 } else if (MATCH("green2_comp")) {
965 if (!retval)
966 val = VALUE;
967
968 if (!retval) {
969 if (val >= COMP_GREEN2 && val <= 255) {
970 new_params.exposure.green2Comp = val;
971 new_params.exposure.compMode = 1;
972 command_flags |= COMMAND_SETEXPOSURE;
973 } else
974 retval = -EINVAL;
975 }
976 } else if (MATCH("blue_comp")) {
977 if (!retval)
978 val = VALUE;
979
980 if (!retval) {
981 if (val >= COMP_BLUE && val <= 255) {
982 new_params.exposure.blueComp = val;
983 new_params.exposure.compMode = 1;
984 command_flags |= COMMAND_SETEXPOSURE;
985 } else
986 retval = -EINVAL;
987 }
988 } else if (MATCH("apcor_gain1")) {
989 if (!retval)
990 val = VALUE;
991
992 if (!retval) {
993 command_flags |= COMMAND_SETAPCOR;
994 if (val <= 0xff)
995 new_params.apcor.gain1 = val;
996 else
997 retval = -EINVAL;
998 }
999 } else if (MATCH("apcor_gain2")) {
1000 if (!retval)
1001 val = VALUE;
1002
1003 if (!retval) {
1004 command_flags |= COMMAND_SETAPCOR;
1005 if (val <= 0xff)
1006 new_params.apcor.gain2 = val;
1007 else
1008 retval = -EINVAL;
1009 }
1010 } else if (MATCH("apcor_gain4")) {
1011 if (!retval)
1012 val = VALUE;
1013
1014 if (!retval) {
1015 command_flags |= COMMAND_SETAPCOR;
1016 if (val <= 0xff)
1017 new_params.apcor.gain4 = val;
1018 else
1019 retval = -EINVAL;
1020 }
1021 } else if (MATCH("apcor_gain8")) {
1022 if (!retval)
1023 val = VALUE;
1024
1025 if (!retval) {
1026 command_flags |= COMMAND_SETAPCOR;
1027 if (val <= 0xff)
1028 new_params.apcor.gain8 = val;
1029 else
1030 retval = -EINVAL;
1031 }
1032 } else if (MATCH("vl_offset_gain1")) {
1033 if (!retval)
1034 val = VALUE;
1035
1036 if (!retval) {
1037 if (val <= 0xff)
1038 new_params.vlOffset.gain1 = val;
1039 else
1040 retval = -EINVAL;
1041 }
1042 command_flags |= COMMAND_SETVLOFFSET;
1043 } else if (MATCH("vl_offset_gain2")) {
1044 if (!retval)
1045 val = VALUE;
1046
1047 if (!retval) {
1048 if (val <= 0xff)
1049 new_params.vlOffset.gain2 = val;
1050 else
1051 retval = -EINVAL;
1052 }
1053 command_flags |= COMMAND_SETVLOFFSET;
1054 } else if (MATCH("vl_offset_gain4")) {
1055 if (!retval)
1056 val = VALUE;
1057
1058 if (!retval) {
1059 if (val <= 0xff)
1060 new_params.vlOffset.gain4 = val;
1061 else
1062 retval = -EINVAL;
1063 }
1064 command_flags |= COMMAND_SETVLOFFSET;
1065 } else if (MATCH("vl_offset_gain8")) {
1066 if (!retval)
1067 val = VALUE;
1068
1069 if (!retval) {
1070 if (val <= 0xff)
1071 new_params.vlOffset.gain8 = val;
1072 else
1073 retval = -EINVAL;
1074 }
1075 command_flags |= COMMAND_SETVLOFFSET;
1076 } else if (MATCH("flicker_control")) {
1077 if (!retval && MATCH("on")) {
1078 set_flicker(&new_params, &command_flags, 1);
1079 } else if (!retval && MATCH("off")) {
1080 set_flicker(&new_params, &command_flags, 0);
1081 } else
1082 retval = -EINVAL;
1083
1084 command_flags |= COMMAND_SETFLICKERCTRL;
1085 } else if (MATCH("mains_frequency")) {
1086 if (!retval && MATCH("50")) {
1087 new_mains = 0;
1088 new_params.flickerControl.coarseJump =
1089 flicker_jumps[new_mains]
1090 [new_params.sensorFps.baserate]
1091 [new_params.sensorFps.divisor];
1092 if (new_params.flickerControl.flickerMode)
1093 command_flags |= COMMAND_SETFLICKERCTRL;
1094 } else if (!retval && MATCH("60")) {
1095 new_mains = 1;
1096 new_params.flickerControl.coarseJump =
1097 flicker_jumps[new_mains]
1098 [new_params.sensorFps.baserate]
1099 [new_params.sensorFps.divisor];
1100 if (new_params.flickerControl.flickerMode)
1101 command_flags |= COMMAND_SETFLICKERCTRL;
1102 } else
1103 retval = -EINVAL;
1104 } else if (MATCH("allowable_overexposure")) {
1105 if (!retval && MATCH("auto")) {
1106 new_params.flickerControl.allowableOverExposure =
1107 -find_over_exposure(new_params.colourParams.brightness);
1108 if(new_params.flickerControl.flickerMode != 0)
1109 command_flags |= COMMAND_SETFLICKERCTRL;
1110 } else {
1111 if (!retval)
1112 val = VALUE;
1113
1114 if (!retval) {
1115 if (val <= 0xff) {
1116 new_params.flickerControl.
1117 allowableOverExposure = val;
1118 if(new_params.flickerControl.flickerMode != 0)
1119 command_flags |= COMMAND_SETFLICKERCTRL;
1120 } else
1121 retval = -EINVAL;
1122 }
1123 }
1124 } else if (MATCH("compression_mode")) {
1125 if (!retval && MATCH("none"))
1126 new_params.compression.mode =
1127 CPIA_COMPRESSION_NONE;
1128 else if (!retval && MATCH("auto"))
1129 new_params.compression.mode =
1130 CPIA_COMPRESSION_AUTO;
1131 else if (!retval && MATCH("manual"))
1132 new_params.compression.mode =
1133 CPIA_COMPRESSION_MANUAL;
1134 else
1135 retval = -EINVAL;
1136
1137 command_flags |= COMMAND_SETCOMPRESSION;
1138 } else if (MATCH("decimation_enable")) {
1139 if (!retval && MATCH("off"))
1140 new_params.compression.decimation = 0;
1141 else if (!retval && MATCH("on"))
1142 new_params.compression.decimation = 1;
1143 else
1144 retval = -EINVAL;
1145
1146 command_flags |= COMMAND_SETCOMPRESSION;
1147 } else if (MATCH("compression_target")) {
1148 if (!retval && MATCH("quality"))
1149 new_params.compressionTarget.frTargeting =
1150 CPIA_COMPRESSION_TARGET_QUALITY;
1151 else if (!retval && MATCH("framerate"))
1152 new_params.compressionTarget.frTargeting =
1153 CPIA_COMPRESSION_TARGET_FRAMERATE;
1154 else
1155 retval = -EINVAL;
1156
1157 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1158 } else if (MATCH("target_framerate")) {
1159 if (!retval)
1160 val = VALUE;
1161
1162 if (!retval) {
1163 if(val > 0 && val <= 30)
1164 new_params.compressionTarget.targetFR = val;
1165 else
1166 retval = -EINVAL;
1167 }
1168 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1169 } else if (MATCH("target_quality")) {
1170 if (!retval)
1171 val = VALUE;
1172
1173 if (!retval) {
1174 if(val > 0 && val <= 64)
1175 new_params.compressionTarget.targetQ = val;
1176 else
1177 retval = -EINVAL;
1178 }
1179 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1180 } else if (MATCH("y_threshold")) {
1181 if (!retval)
1182 val = VALUE;
1183
1184 if (!retval) {
1185 if (val < 32)
1186 new_params.yuvThreshold.yThreshold = val;
1187 else
1188 retval = -EINVAL;
1189 }
1190 command_flags |= COMMAND_SETYUVTHRESH;
1191 } else if (MATCH("uv_threshold")) {
1192 if (!retval)
1193 val = VALUE;
1194
1195 if (!retval) {
1196 if (val < 32)
1197 new_params.yuvThreshold.uvThreshold = val;
1198 else
1199 retval = -EINVAL;
1200 }
1201 command_flags |= COMMAND_SETYUVTHRESH;
1202 } else if (MATCH("hysteresis")) {
1203 if (!retval)
1204 val = VALUE;
1205
1206 if (!retval) {
1207 if (val <= 0xff)
1208 new_params.compressionParams.hysteresis = val;
1209 else
1210 retval = -EINVAL;
1211 }
1212 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1213 } else if (MATCH("threshold_max")) {
1214 if (!retval)
1215 val = VALUE;
1216
1217 if (!retval) {
1218 if (val <= 0xff)
1219 new_params.compressionParams.threshMax = val;
1220 else
1221 retval = -EINVAL;
1222 }
1223 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1224 } else if (MATCH("small_step")) {
1225 if (!retval)
1226 val = VALUE;
1227
1228 if (!retval) {
1229 if (val <= 0xff)
1230 new_params.compressionParams.smallStep = val;
1231 else
1232 retval = -EINVAL;
1233 }
1234 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1235 } else if (MATCH("large_step")) {
1236 if (!retval)
1237 val = VALUE;
1238
1239 if (!retval) {
1240 if (val <= 0xff)
1241 new_params.compressionParams.largeStep = val;
1242 else
1243 retval = -EINVAL;
1244 }
1245 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1246 } else if (MATCH("decimation_hysteresis")) {
1247 if (!retval)
1248 val = VALUE;
1249
1250 if (!retval) {
1251 if (val <= 0xff)
1252 new_params.compressionParams.decimationHysteresis = val;
1253 else
1254 retval = -EINVAL;
1255 }
1256 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1257 } else if (MATCH("fr_diff_step_thresh")) {
1258 if (!retval)
1259 val = VALUE;
1260
1261 if (!retval) {
1262 if (val <= 0xff)
1263 new_params.compressionParams.frDiffStepThresh = val;
1264 else
1265 retval = -EINVAL;
1266 }
1267 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1268 } else if (MATCH("q_diff_step_thresh")) {
1269 if (!retval)
1270 val = VALUE;
1271
1272 if (!retval) {
1273 if (val <= 0xff)
1274 new_params.compressionParams.qDiffStepThresh = val;
1275 else
1276 retval = -EINVAL;
1277 }
1278 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1279 } else if (MATCH("decimation_thresh_mod")) {
1280 if (!retval)
1281 val = VALUE;
1282
1283 if (!retval) {
1284 if (val <= 0xff)
1285 new_params.compressionParams.decimationThreshMod = val;
1286 else
1287 retval = -EINVAL;
1288 }
1289 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1290 } else if (MATCH("toplight")) {
1291 if (!retval && MATCH("on"))
1292 new_params.qx3.toplight = 1;
1293 else if (!retval && MATCH("off"))
1294 new_params.qx3.toplight = 0;
1295 else
1296 retval = -EINVAL;
1297 command_flags |= COMMAND_SETLIGHTS;
1298 } else if (MATCH("bottomlight")) {
1299 if (!retval && MATCH("on"))
1300 new_params.qx3.bottomlight = 1;
1301 else if (!retval && MATCH("off"))
1302 new_params.qx3.bottomlight = 0;
1303 else
1304 retval = -EINVAL;
1305 command_flags |= COMMAND_SETLIGHTS;
1306 } else {
1307 DBG("No match found\n");
1308 retval = -EINVAL;
1309 }
1310
1311 if (!retval) {
1312 while (count && isspace(*buffer) && *buffer != '\n') {
1313 --count;
1314 ++buffer;
1315 }
1316 if (count) {
1317 if (*buffer == '\0' && count != 1)
1318 retval = -EINVAL;
1319 else if (*buffer != '\n' && *buffer != ';' &&
1320 *buffer != '\0')
1321 retval = -EINVAL;
1322 else {
1323 --count;
1324 ++buffer;
1325 }
1326 }
1327 }
1328 }
1329#undef MATCH
1330#undef VALUE
1331#undef FIRMWARE_VERSION
1332 if (!retval) {
1333 if (command_flags & COMMAND_SETCOLOURPARAMS) {
1334 /* Adjust cam->vp to reflect these changes */
1335 cam->vp.brightness =
1336 new_params.colourParams.brightness*65535/100;
1337 cam->vp.contrast =
1338 new_params.colourParams.contrast*65535/100;
1339 cam->vp.colour =
1340 new_params.colourParams.saturation*65535/100;
1341 }
1342 if((command_flags & COMMAND_SETEXPOSURE) &&
1343 new_params.exposure.expMode == 2)
1344 cam->exposure_status = EXPOSURE_NORMAL;
1345
1346 memcpy(&cam->params, &new_params, sizeof(struct cam_params));
1347 cam->mainsFreq = new_mains;
1348 cam->cmd_queue |= command_flags;
1349 retval = size;
1350 } else
1351 DBG("error: %d\n", retval);
1352
1353 up(&cam->param_lock);
1354
1355out:
1356 free_page((unsigned long)page);
1357 return retval;
1358}
1359
1360static void create_proc_cpia_cam(struct cam_data *cam)
1361{
1362 char name[7];
1363 struct proc_dir_entry *ent;
1364
1365 if (!cpia_proc_root || !cam)
1366 return;
1367
1368 sprintf(name, "video%d", cam->vdev.minor);
1369
1370 ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
1371 if (!ent)
1372 return;
1373
1374 ent->data = cam;
1375 ent->read_proc = cpia_read_proc;
1376 ent->write_proc = cpia_write_proc;
1377 /*
1378 size of the proc entry is 3736 bytes for the standard webcam;
1379 the extra features of the QX3 microscope add 189 bytes.
1380 (we have not yet probed the camera to see which type it is).
1381 */
1382 ent->size = 3736 + 189;
1383 cam->proc_entry = ent;
1384}
1385
1386static void destroy_proc_cpia_cam(struct cam_data *cam)
1387{
1388 char name[7];
1389
1390 if (!cam || !cam->proc_entry)
1391 return;
1392
1393 sprintf(name, "video%d", cam->vdev.minor);
1394 remove_proc_entry(name, cpia_proc_root);
1395 cam->proc_entry = NULL;
1396}
1397
1398static void proc_cpia_create(void)
1399{
1400 cpia_proc_root = create_proc_entry("cpia", S_IFDIR, NULL);
1401
1402 if (cpia_proc_root)
1403 cpia_proc_root->owner = THIS_MODULE;
1404 else
1405 LOG("Unable to initialise /proc/cpia\n");
1406}
1407
1408static void __exit proc_cpia_destroy(void)
1409{
1410 remove_proc_entry("cpia", NULL);
1411}
1412#endif /* CONFIG_PROC_FS */
1413
1414/* ----------------------- debug functions ---------------------- */
1415
1416#define printstatus(cam) \
1417 DBG("%02x %02x %02x %02x %02x %02x %02x %02x\n",\
1418 cam->params.status.systemState, cam->params.status.grabState, \
1419 cam->params.status.streamState, cam->params.status.fatalError, \
1420 cam->params.status.cmdError, cam->params.status.debugFlags, \
1421 cam->params.status.vpStatus, cam->params.status.errorCode);
1422
1423/* ----------------------- v4l helpers -------------------------- */
1424
1425/* supported frame palettes and depths */
1426static inline int valid_mode(u16 palette, u16 depth)
1427{
1428 if ((palette == VIDEO_PALETTE_YUV422 && depth == 16) ||
1429 (palette == VIDEO_PALETTE_YUYV && depth == 16))
1430 return 1;
1431
1432 if (colorspace_conv)
1433 return (palette == VIDEO_PALETTE_GREY && depth == 8) ||
1434 (palette == VIDEO_PALETTE_RGB555 && depth == 16) ||
1435 (palette == VIDEO_PALETTE_RGB565 && depth == 16) ||
1436 (palette == VIDEO_PALETTE_RGB24 && depth == 24) ||
1437 (palette == VIDEO_PALETTE_RGB32 && depth == 32) ||
1438 (palette == VIDEO_PALETTE_UYVY && depth == 16);
1439
1440 return 0;
1441}
1442
1443static int match_videosize( int width, int height )
1444{
1445 /* return the best match, where 'best' is as always
1446 * the largest that is not bigger than what is requested. */
1447 if (width>=352 && height>=288)
1448 return VIDEOSIZE_352_288; /* CIF */
1449
1450 if (width>=320 && height>=240)
1451 return VIDEOSIZE_320_240; /* SIF */
1452
1453 if (width>=288 && height>=216)
1454 return VIDEOSIZE_288_216;
1455
1456 if (width>=256 && height>=192)
1457 return VIDEOSIZE_256_192;
1458
1459 if (width>=224 && height>=168)
1460 return VIDEOSIZE_224_168;
1461
1462 if (width>=192 && height>=144)
1463 return VIDEOSIZE_192_144;
1464
1465 if (width>=176 && height>=144)
1466 return VIDEOSIZE_176_144; /* QCIF */
1467
1468 if (width>=160 && height>=120)
1469 return VIDEOSIZE_160_120; /* QSIF */
1470
1471 if (width>=128 && height>=96)
1472 return VIDEOSIZE_128_96;
1473
1474 if (width>=88 && height>=72)
1475 return VIDEOSIZE_88_72;
1476
1477 if (width>=64 && height>=48)
1478 return VIDEOSIZE_64_48;
1479
1480 if (width>=48 && height>=48)
1481 return VIDEOSIZE_48_48;
1482
1483 return -1;
1484}
1485
1486/* these are the capture sizes we support */
1487static void set_vw_size(struct cam_data *cam)
1488{
1489 /* the col/row/start/end values are the result of simple math */
1490 /* study the SetROI-command in cpia developers guide p 2-22 */
1491 /* streamStartLine is set to the recommended value in the cpia */
1492 /* developers guide p 3-37 */
1493 switch(cam->video_size) {
1494 case VIDEOSIZE_CIF:
1495 cam->vw.width = 352;
1496 cam->vw.height = 288;
1497 cam->params.format.videoSize=VIDEOSIZE_CIF;
1498 cam->params.roi.colStart=0;
1499 cam->params.roi.rowStart=0;
1500 cam->params.streamStartLine = 120;
1501 break;
1502 case VIDEOSIZE_SIF:
1503 cam->vw.width = 320;
1504 cam->vw.height = 240;
1505 cam->params.format.videoSize=VIDEOSIZE_CIF;
1506 cam->params.roi.colStart=2;
1507 cam->params.roi.rowStart=6;
1508 cam->params.streamStartLine = 120;
1509 break;
1510 case VIDEOSIZE_288_216:
1511 cam->vw.width = 288;
1512 cam->vw.height = 216;
1513 cam->params.format.videoSize=VIDEOSIZE_CIF;
1514 cam->params.roi.colStart=4;
1515 cam->params.roi.rowStart=9;
1516 cam->params.streamStartLine = 120;
1517 break;
1518 case VIDEOSIZE_256_192:
1519 cam->vw.width = 256;
1520 cam->vw.height = 192;
1521 cam->params.format.videoSize=VIDEOSIZE_CIF;
1522 cam->params.roi.colStart=6;
1523 cam->params.roi.rowStart=12;
1524 cam->params.streamStartLine = 120;
1525 break;
1526 case VIDEOSIZE_224_168:
1527 cam->vw.width = 224;
1528 cam->vw.height = 168;
1529 cam->params.format.videoSize=VIDEOSIZE_CIF;
1530 cam->params.roi.colStart=8;
1531 cam->params.roi.rowStart=15;
1532 cam->params.streamStartLine = 120;
1533 break;
1534 case VIDEOSIZE_192_144:
1535 cam->vw.width = 192;
1536 cam->vw.height = 144;
1537 cam->params.format.videoSize=VIDEOSIZE_CIF;
1538 cam->params.roi.colStart=10;
1539 cam->params.roi.rowStart=18;
1540 cam->params.streamStartLine = 120;
1541 break;
1542 case VIDEOSIZE_QCIF:
1543 cam->vw.width = 176;
1544 cam->vw.height = 144;
1545 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1546 cam->params.roi.colStart=0;
1547 cam->params.roi.rowStart=0;
1548 cam->params.streamStartLine = 60;
1549 break;
1550 case VIDEOSIZE_QSIF:
1551 cam->vw.width = 160;
1552 cam->vw.height = 120;
1553 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1554 cam->params.roi.colStart=1;
1555 cam->params.roi.rowStart=3;
1556 cam->params.streamStartLine = 60;
1557 break;
1558 case VIDEOSIZE_128_96:
1559 cam->vw.width = 128;
1560 cam->vw.height = 96;
1561 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1562 cam->params.roi.colStart=3;
1563 cam->params.roi.rowStart=6;
1564 cam->params.streamStartLine = 60;
1565 break;
1566 case VIDEOSIZE_88_72:
1567 cam->vw.width = 88;
1568 cam->vw.height = 72;
1569 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1570 cam->params.roi.colStart=5;
1571 cam->params.roi.rowStart=9;
1572 cam->params.streamStartLine = 60;
1573 break;
1574 case VIDEOSIZE_64_48:
1575 cam->vw.width = 64;
1576 cam->vw.height = 48;
1577 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1578 cam->params.roi.colStart=7;
1579 cam->params.roi.rowStart=12;
1580 cam->params.streamStartLine = 60;
1581 break;
1582 case VIDEOSIZE_48_48:
1583 cam->vw.width = 48;
1584 cam->vw.height = 48;
1585 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1586 cam->params.roi.colStart=8;
1587 cam->params.roi.rowStart=6;
1588 cam->params.streamStartLine = 60;
1589 break;
1590 default:
1591 LOG("bad videosize value: %d\n", cam->video_size);
1592 return;
1593 }
1594
1595 if(cam->vc.width == 0)
1596 cam->vc.width = cam->vw.width;
1597 if(cam->vc.height == 0)
1598 cam->vc.height = cam->vw.height;
1599
1600 cam->params.roi.colStart += cam->vc.x >> 3;
1601 cam->params.roi.colEnd = cam->params.roi.colStart +
1602 (cam->vc.width >> 3);
1603 cam->params.roi.rowStart += cam->vc.y >> 2;
1604 cam->params.roi.rowEnd = cam->params.roi.rowStart +
1605 (cam->vc.height >> 2);
1606
1607 return;
1608}
1609
1610static int allocate_frame_buf(struct cam_data *cam)
1611{
1612 int i;
1613
1614 cam->frame_buf = rvmalloc(FRAME_NUM * CPIA_MAX_FRAME_SIZE);
1615 if (!cam->frame_buf)
1616 return -ENOBUFS;
1617
1618 for (i = 0; i < FRAME_NUM; i++)
1619 cam->frame[i].data = cam->frame_buf + i * CPIA_MAX_FRAME_SIZE;
1620
1621 return 0;
1622}
1623
1624static int free_frame_buf(struct cam_data *cam)
1625{
1626 int i;
1627
1628 rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);
1629 cam->frame_buf = NULL;
1630 for (i=0; i < FRAME_NUM; i++)
1631 cam->frame[i].data = NULL;
1632
1633 return 0;
1634}
1635
1636
1637static inline void free_frames(struct cpia_frame frame[FRAME_NUM])
1638{
1639 int i;
1640
1641 for (i=0; i < FRAME_NUM; i++)
1642 frame[i].state = FRAME_UNUSED;
1643 return;
1644}
1645
1646/**********************************************************************
1647 *
1648 * General functions
1649 *
1650 **********************************************************************/
1651/* send an arbitrary command to the camera */
1652static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
1653{
1654 int retval, datasize;
1655 u8 cmd[8], data[8];
1656
1657 switch(command) {
1658 case CPIA_COMMAND_GetCPIAVersion:
1659 case CPIA_COMMAND_GetPnPID:
1660 case CPIA_COMMAND_GetCameraStatus:
1661 case CPIA_COMMAND_GetVPVersion:
1662 datasize=8;
1663 break;
1664 case CPIA_COMMAND_GetColourParams:
1665 case CPIA_COMMAND_GetColourBalance:
1666 case CPIA_COMMAND_GetExposure:
1667 down(&cam->param_lock);
1668 datasize=8;
1669 break;
1670 case CPIA_COMMAND_ReadMCPorts:
1671 case CPIA_COMMAND_ReadVCRegs:
1672 datasize = 4;
1673 break;
1674 default:
1675 datasize=0;
1676 break;
1677 }
1678
1679 cmd[0] = command>>8;
1680 cmd[1] = command&0xff;
1681 cmd[2] = a;
1682 cmd[3] = b;
1683 cmd[4] = c;
1684 cmd[5] = d;
1685 cmd[6] = datasize;
1686 cmd[7] = 0;
1687
1688 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1689 if (retval) {
1690 DBG("%x - failed, retval=%d\n", command, retval);
1691 if (command == CPIA_COMMAND_GetColourParams ||
1692 command == CPIA_COMMAND_GetColourBalance ||
1693 command == CPIA_COMMAND_GetExposure)
1694 up(&cam->param_lock);
1695 } else {
1696 switch(command) {
1697 case CPIA_COMMAND_GetCPIAVersion:
1698 cam->params.version.firmwareVersion = data[0];
1699 cam->params.version.firmwareRevision = data[1];
1700 cam->params.version.vcVersion = data[2];
1701 cam->params.version.vcRevision = data[3];
1702 break;
1703 case CPIA_COMMAND_GetPnPID:
1704 cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);
1705 cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);
1706 cam->params.pnpID.deviceRevision =
1707 data[4]+(((u16)data[5])<<8);
1708 break;
1709 case CPIA_COMMAND_GetCameraStatus:
1710 cam->params.status.systemState = data[0];
1711 cam->params.status.grabState = data[1];
1712 cam->params.status.streamState = data[2];
1713 cam->params.status.fatalError = data[3];
1714 cam->params.status.cmdError = data[4];
1715 cam->params.status.debugFlags = data[5];
1716 cam->params.status.vpStatus = data[6];
1717 cam->params.status.errorCode = data[7];
1718 break;
1719 case CPIA_COMMAND_GetVPVersion:
1720 cam->params.vpVersion.vpVersion = data[0];
1721 cam->params.vpVersion.vpRevision = data[1];
1722 cam->params.vpVersion.cameraHeadID =
1723 data[2]+(((u16)data[3])<<8);
1724 break;
1725 case CPIA_COMMAND_GetColourParams:
1726 cam->params.colourParams.brightness = data[0];
1727 cam->params.colourParams.contrast = data[1];
1728 cam->params.colourParams.saturation = data[2];
1729 up(&cam->param_lock);
1730 break;
1731 case CPIA_COMMAND_GetColourBalance:
1732 cam->params.colourBalance.redGain = data[0];
1733 cam->params.colourBalance.greenGain = data[1];
1734 cam->params.colourBalance.blueGain = data[2];
1735 up(&cam->param_lock);
1736 break;
1737 case CPIA_COMMAND_GetExposure:
1738 cam->params.exposure.gain = data[0];
1739 cam->params.exposure.fineExp = data[1];
1740 cam->params.exposure.coarseExpLo = data[2];
1741 cam->params.exposure.coarseExpHi = data[3];
1742 cam->params.exposure.redComp = data[4];
1743 cam->params.exposure.green1Comp = data[5];
1744 cam->params.exposure.green2Comp = data[6];
1745 cam->params.exposure.blueComp = data[7];
1746 up(&cam->param_lock);
1747 break;
1748
1749 case CPIA_COMMAND_ReadMCPorts:
1750 if (!cam->params.qx3.qx3_detected)
1751 break;
1752 /* test button press */
1753 cam->params.qx3.button = ((data[1] & 0x02) == 0);
1754 if (cam->params.qx3.button) {
1755 /* button pressed - unlock the latch */
1756 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);
1757 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);
1758 }
1759
1760 /* test whether microscope is cradled */
1761 cam->params.qx3.cradled = ((data[2] & 0x40) == 0);
1762 break;
1763
1764 default:
1765 break;
1766 }
1767 }
1768 return retval;
1769}
1770
1771/* send a command to the camera with an additional data transaction */
1772static int do_command_extended(struct cam_data *cam, u16 command,
1773 u8 a, u8 b, u8 c, u8 d,
1774 u8 e, u8 f, u8 g, u8 h,
1775 u8 i, u8 j, u8 k, u8 l)
1776{
1777 int retval;
1778 u8 cmd[8], data[8];
1779
1780 cmd[0] = command>>8;
1781 cmd[1] = command&0xff;
1782 cmd[2] = a;
1783 cmd[3] = b;
1784 cmd[4] = c;
1785 cmd[5] = d;
1786 cmd[6] = 8;
1787 cmd[7] = 0;
1788 data[0] = e;
1789 data[1] = f;
1790 data[2] = g;
1791 data[3] = h;
1792 data[4] = i;
1793 data[5] = j;
1794 data[6] = k;
1795 data[7] = l;
1796
1797 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1798 if (retval)
1799 DBG("%x - failed\n", command);
1800
1801 return retval;
1802}
1803
1804/**********************************************************************
1805 *
1806 * Colorspace conversion
1807 *
1808 **********************************************************************/
1809#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
1810
1811static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1812 int linesize, int mmap_kludge)
1813{
1814 int y, u, v, r, g, b, y1;
1815
1816 /* Odd lines use the same u and v as the previous line.
1817 * Because of compression, it is necessary to get this
1818 * information from the decoded image. */
1819 switch(out_fmt) {
1820 case VIDEO_PALETTE_RGB555:
1821 y = (*yuv++ - 16) * 76310;
1822 y1 = (*yuv - 16) * 76310;
1823 r = ((*(rgb+1-linesize)) & 0x7c) << 1;
1824 g = ((*(rgb-linesize)) & 0xe0) >> 4 |
1825 ((*(rgb+1-linesize)) & 0x03) << 6;
1826 b = ((*(rgb-linesize)) & 0x1f) << 3;
1827 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1828 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1829 r = 104635 * v;
1830 g = -25690 * u - 53294 * v;
1831 b = 132278 * u;
1832 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1833 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1834 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1835 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1836 return 4;
1837 case VIDEO_PALETTE_RGB565:
1838 y = (*yuv++ - 16) * 76310;
1839 y1 = (*yuv - 16) * 76310;
1840 r = (*(rgb+1-linesize)) & 0xf8;
1841 g = ((*(rgb-linesize)) & 0xe0) >> 3 |
1842 ((*(rgb+1-linesize)) & 0x07) << 5;
1843 b = ((*(rgb-linesize)) & 0x1f) << 3;
1844 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1845 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1846 r = 104635 * v;
1847 g = -25690 * u - 53294 * v;
1848 b = 132278 * u;
1849 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1850 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1851 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1852 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1853 return 4;
1854 break;
1855 case VIDEO_PALETTE_RGB24:
1856 case VIDEO_PALETTE_RGB32:
1857 y = (*yuv++ - 16) * 76310;
1858 y1 = (*yuv - 16) * 76310;
1859 if (mmap_kludge) {
1860 r = *(rgb+2-linesize);
1861 g = *(rgb+1-linesize);
1862 b = *(rgb-linesize);
1863 } else {
1864 r = *(rgb-linesize);
1865 g = *(rgb+1-linesize);
1866 b = *(rgb+2-linesize);
1867 }
1868 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1869 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1870 r = 104635 * v;
1871 g = -25690 * u + -53294 * v;
1872 b = 132278 * u;
1873 if (mmap_kludge) {
1874 *rgb++ = LIMIT(b+y);
1875 *rgb++ = LIMIT(g+y);
1876 *rgb++ = LIMIT(r+y);
1877 if(out_fmt == VIDEO_PALETTE_RGB32)
1878 rgb++;
1879 *rgb++ = LIMIT(b+y1);
1880 *rgb++ = LIMIT(g+y1);
1881 *rgb = LIMIT(r+y1);
1882 } else {
1883 *rgb++ = LIMIT(r+y);
1884 *rgb++ = LIMIT(g+y);
1885 *rgb++ = LIMIT(b+y);
1886 if(out_fmt == VIDEO_PALETTE_RGB32)
1887 rgb++;
1888 *rgb++ = LIMIT(r+y1);
1889 *rgb++ = LIMIT(g+y1);
1890 *rgb = LIMIT(b+y1);
1891 }
1892 if(out_fmt == VIDEO_PALETTE_RGB32)
1893 return 8;
1894 return 6;
1895 case VIDEO_PALETTE_YUV422:
1896 case VIDEO_PALETTE_YUYV:
1897 y = *yuv++;
1898 u = *(rgb+1-linesize);
1899 y1 = *yuv;
1900 v = *(rgb+3-linesize);
1901 *rgb++ = y;
1902 *rgb++ = u;
1903 *rgb++ = y1;
1904 *rgb = v;
1905 return 4;
1906 case VIDEO_PALETTE_UYVY:
1907 u = *(rgb-linesize);
1908 y = *yuv++;
1909 v = *(rgb+2-linesize);
1910 y1 = *yuv;
1911 *rgb++ = u;
1912 *rgb++ = y;
1913 *rgb++ = v;
1914 *rgb = y1;
1915 return 4;
1916 case VIDEO_PALETTE_GREY:
1917 *rgb++ = *yuv++;
1918 *rgb = *yuv;
1919 return 2;
1920 default:
1921 DBG("Empty: %d\n", out_fmt);
1922 return 0;
1923 }
1924}
1925
1926
1927static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1928 int in_uyvy, int mmap_kludge)
1929{
1930 int y, u, v, r, g, b, y1;
1931
1932 switch(out_fmt) {
1933 case VIDEO_PALETTE_RGB555:
1934 case VIDEO_PALETTE_RGB565:
1935 case VIDEO_PALETTE_RGB24:
1936 case VIDEO_PALETTE_RGB32:
1937 if (in_uyvy) {
1938 u = *yuv++ - 128;
1939 y = (*yuv++ - 16) * 76310;
1940 v = *yuv++ - 128;
1941 y1 = (*yuv - 16) * 76310;
1942 } else {
1943 y = (*yuv++ - 16) * 76310;
1944 u = *yuv++ - 128;
1945 y1 = (*yuv++ - 16) * 76310;
1946 v = *yuv - 128;
1947 }
1948 r = 104635 * v;
1949 g = -25690 * u + -53294 * v;
1950 b = 132278 * u;
1951 break;
1952 default:
1953 y = *yuv++;
1954 u = *yuv++;
1955 y1 = *yuv++;
1956 v = *yuv;
1957 /* Just to avoid compiler warnings */
1958 r = 0;
1959 g = 0;
1960 b = 0;
1961 break;
1962 }
1963 switch(out_fmt) {
1964 case VIDEO_PALETTE_RGB555:
1965 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1966 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1967 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1968 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1969 return 4;
1970 case VIDEO_PALETTE_RGB565:
1971 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1972 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1973 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1974 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1975 return 4;
1976 case VIDEO_PALETTE_RGB24:
1977 if (mmap_kludge) {
1978 *rgb++ = LIMIT(b+y);
1979 *rgb++ = LIMIT(g+y);
1980 *rgb++ = LIMIT(r+y);
1981 *rgb++ = LIMIT(b+y1);
1982 *rgb++ = LIMIT(g+y1);
1983 *rgb = LIMIT(r+y1);
1984 } else {
1985 *rgb++ = LIMIT(r+y);
1986 *rgb++ = LIMIT(g+y);
1987 *rgb++ = LIMIT(b+y);
1988 *rgb++ = LIMIT(r+y1);
1989 *rgb++ = LIMIT(g+y1);
1990 *rgb = LIMIT(b+y1);
1991 }
1992 return 6;
1993 case VIDEO_PALETTE_RGB32:
1994 if (mmap_kludge) {
1995 *rgb++ = LIMIT(b+y);
1996 *rgb++ = LIMIT(g+y);
1997 *rgb++ = LIMIT(r+y);
1998 rgb++;
1999 *rgb++ = LIMIT(b+y1);
2000 *rgb++ = LIMIT(g+y1);
2001 *rgb = LIMIT(r+y1);
2002 } else {
2003 *rgb++ = LIMIT(r+y);
2004 *rgb++ = LIMIT(g+y);
2005 *rgb++ = LIMIT(b+y);
2006 rgb++;
2007 *rgb++ = LIMIT(r+y1);
2008 *rgb++ = LIMIT(g+y1);
2009 *rgb = LIMIT(b+y1);
2010 }
2011 return 8;
2012 case VIDEO_PALETTE_GREY:
2013 *rgb++ = y;
2014 *rgb = y1;
2015 return 2;
2016 case VIDEO_PALETTE_YUV422:
2017 case VIDEO_PALETTE_YUYV:
2018 *rgb++ = y;
2019 *rgb++ = u;
2020 *rgb++ = y1;
2021 *rgb = v;
2022 return 4;
2023 case VIDEO_PALETTE_UYVY:
2024 *rgb++ = u;
2025 *rgb++ = y;
2026 *rgb++ = v;
2027 *rgb = y1;
2028 return 4;
2029 default:
2030 DBG("Empty: %d\n", out_fmt);
2031 return 0;
2032 }
2033}
2034
2035static int skipcount(int count, int fmt)
2036{
2037 switch(fmt) {
2038 case VIDEO_PALETTE_GREY:
2039 return count;
2040 case VIDEO_PALETTE_RGB555:
2041 case VIDEO_PALETTE_RGB565:
2042 case VIDEO_PALETTE_YUV422:
2043 case VIDEO_PALETTE_YUYV:
2044 case VIDEO_PALETTE_UYVY:
2045 return 2*count;
2046 case VIDEO_PALETTE_RGB24:
2047 return 3*count;
2048 case VIDEO_PALETTE_RGB32:
2049 return 4*count;
2050 default:
2051 return 0;
2052 }
2053}
2054
2055static int parse_picture(struct cam_data *cam, int size)
2056{
2057 u8 *obuf, *ibuf, *end_obuf;
2058 int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt;
2059 int rows, cols, linesize, subsample_422;
2060
2061 /* make sure params don't change while we are decoding */
2062 down(&cam->param_lock);
2063
2064 obuf = cam->decompressed_frame.data;
2065 end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
2066 ibuf = cam->raw_image;
2067 origsize = size;
2068 out_fmt = cam->vp.palette;
2069
2070 if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
2071 LOG("header not found\n");
2072 up(&cam->param_lock);
2073 return -1;
2074 }
2075
2076 if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
2077 LOG("wrong video size\n");
2078 up(&cam->param_lock);
2079 return -1;
2080 }
2081
2082 if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) {
2083 LOG("illegal subtype %d\n",ibuf[17]);
2084 up(&cam->param_lock);
2085 return -1;
2086 }
2087 subsample_422 = ibuf[17] == SUBSAMPLE_422;
2088
2089 if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
2090 LOG("illegal yuvorder %d\n",ibuf[18]);
2091 up(&cam->param_lock);
2092 return -1;
2093 }
2094 in_uyvy = ibuf[18] == YUVORDER_UYVY;
2095
2096 if ((ibuf[24] != cam->params.roi.colStart) ||
2097 (ibuf[25] != cam->params.roi.colEnd) ||
2098 (ibuf[26] != cam->params.roi.rowStart) ||
2099 (ibuf[27] != cam->params.roi.rowEnd)) {
2100 LOG("ROI mismatch\n");
2101 up(&cam->param_lock);
2102 return -1;
2103 }
2104 cols = 8*(ibuf[25] - ibuf[24]);
2105 rows = 4*(ibuf[27] - ibuf[26]);
2106
2107
2108 if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
2109 LOG("illegal compression %d\n",ibuf[28]);
2110 up(&cam->param_lock);
2111 return -1;
2112 }
2113 compressed = (ibuf[28] == COMPRESSED);
2114
2115 if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) {
2116 LOG("illegal decimation %d\n",ibuf[29]);
2117 up(&cam->param_lock);
2118 return -1;
2119 }
2120 decimation = (ibuf[29] == DECIMATION_ENAB);
2121
2122 cam->params.yuvThreshold.yThreshold = ibuf[30];
2123 cam->params.yuvThreshold.uvThreshold = ibuf[31];
2124 cam->params.status.systemState = ibuf[32];
2125 cam->params.status.grabState = ibuf[33];
2126 cam->params.status.streamState = ibuf[34];
2127 cam->params.status.fatalError = ibuf[35];
2128 cam->params.status.cmdError = ibuf[36];
2129 cam->params.status.debugFlags = ibuf[37];
2130 cam->params.status.vpStatus = ibuf[38];
2131 cam->params.status.errorCode = ibuf[39];
2132 cam->fps = ibuf[41];
2133 up(&cam->param_lock);
2134
2135 linesize = skipcount(cols, out_fmt);
2136 ibuf += FRAME_HEADER_SIZE;
2137 size -= FRAME_HEADER_SIZE;
2138 ll = ibuf[0] | (ibuf[1] << 8);
2139 ibuf += 2;
2140 even_line = 1;
2141
2142 while (size > 0) {
2143 size -= (ll+2);
2144 if (size < 0) {
2145 LOG("Insufficient data in buffer\n");
2146 return -1;
2147 }
2148
2149 while (ll > 1) {
2150 if (!compressed || (compressed && !(*ibuf & 1))) {
2151 if(subsample_422 || even_line) {
2152 obuf += yuvconvert(ibuf, obuf, out_fmt,
2153 in_uyvy, cam->mmap_kludge);
2154 ibuf += 4;
2155 ll -= 4;
2156 } else {
2157 /* SUBSAMPLE_420 on an odd line */
2158 obuf += convert420(ibuf, obuf,
2159 out_fmt, linesize,
2160 cam->mmap_kludge);
2161 ibuf += 2;
2162 ll -= 2;
2163 }
2164 } else {
2165 /*skip compressed interval from previous frame*/
2166 obuf += skipcount(*ibuf >> 1, out_fmt);
2167 if (obuf > end_obuf) {
2168 LOG("Insufficient buffer size\n");
2169 return -1;
2170 }
2171 ++ibuf;
2172 ll--;
2173 }
2174 }
2175 if (ll == 1) {
2176 if (*ibuf != EOL) {
2177 DBG("EOL not found giving up after %d/%d"
2178 " bytes\n", origsize-size, origsize);
2179 return -1;
2180 }
2181
2182 ++ibuf; /* skip over EOL */
2183
2184 if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) &&
2185 (ibuf[2] == EOI) && (ibuf[3] == EOI)) {
2186 size -= 4;
2187 break;
2188 }
2189
2190 if(decimation) {
2191 /* skip the odd lines for now */
2192 obuf += linesize;
2193 }
2194
2195 if (size > 1) {
2196 ll = ibuf[0] | (ibuf[1] << 8);
2197 ibuf += 2; /* skip over line length */
2198 }
2199 if(!decimation)
2200 even_line = !even_line;
2201 } else {
2202 LOG("line length was not 1 but %d after %d/%d bytes\n",
2203 ll, origsize-size, origsize);
2204 return -1;
2205 }
2206 }
2207
2208 if(decimation) {
2209 /* interpolate odd rows */
2210 int i, j;
2211 u8 *prev, *next;
2212 prev = cam->decompressed_frame.data;
2213 obuf = prev+linesize;
2214 next = obuf+linesize;
2215 for(i=1; i<rows-1; i+=2) {
2216 for(j=0; j<linesize; ++j) {
2217 *obuf++ = ((int)*prev++ + *next++) / 2;
2218 }
2219 prev += linesize;
2220 obuf += linesize;
2221 next += linesize;
2222 }
2223 /* last row is odd, just copy previous row */
2224 memcpy(obuf, prev, linesize);
2225 }
2226
2227 cam->decompressed_frame.count = obuf-cam->decompressed_frame.data;
2228
2229 return cam->decompressed_frame.count;
2230}
2231
2232/* InitStreamCap wrapper to select correct start line */
2233static inline int init_stream_cap(struct cam_data *cam)
2234{
2235 return do_command(cam, CPIA_COMMAND_InitStreamCap,
2236 0, cam->params.streamStartLine, 0, 0);
2237}
2238
2239
2240/* find_over_exposure
2241 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
2242 * Some calculation is required because this value changes with the brightness
2243 * set with SetColourParameters
2244 *
2245 * Parameters: Brightness - last brightness value set with SetColourParameters
2246 *
2247 * Returns: OverExposure value to use with SetFlickerCtrl
2248 */
2249#define FLICKER_MAX_EXPOSURE 250
2250#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
2251#define FLICKER_BRIGHTNESS_CONSTANT 59
2252static int find_over_exposure(int brightness)
2253{
2254 int MaxAllowableOverExposure, OverExposure;
2255
2256 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
2257 FLICKER_BRIGHTNESS_CONSTANT;
2258
2259 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) {
2260 OverExposure = MaxAllowableOverExposure;
2261 } else {
2262 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
2263 }
2264
2265 return OverExposure;
2266}
2267#undef FLICKER_MAX_EXPOSURE
2268#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
2269#undef FLICKER_BRIGHTNESS_CONSTANT
2270
2271/* update various camera modes and settings */
2272static void dispatch_commands(struct cam_data *cam)
2273{
2274 down(&cam->param_lock);
2275 if (cam->cmd_queue==COMMAND_NONE) {
2276 up(&cam->param_lock);
2277 return;
2278 }
2279 DEB_BYTE(cam->cmd_queue);
2280 DEB_BYTE(cam->cmd_queue>>8);
2281 if (cam->cmd_queue & COMMAND_SETFORMAT) {
2282 do_command(cam, CPIA_COMMAND_SetFormat,
2283 cam->params.format.videoSize,
2284 cam->params.format.subSample,
2285 cam->params.format.yuvOrder, 0);
2286 do_command(cam, CPIA_COMMAND_SetROI,
2287 cam->params.roi.colStart, cam->params.roi.colEnd,
2288 cam->params.roi.rowStart, cam->params.roi.rowEnd);
2289 cam->first_frame = 1;
2290 }
2291
2292 if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS)
2293 do_command(cam, CPIA_COMMAND_SetColourParams,
2294 cam->params.colourParams.brightness,
2295 cam->params.colourParams.contrast,
2296 cam->params.colourParams.saturation, 0);
2297
2298 if (cam->cmd_queue & COMMAND_SETAPCOR)
2299 do_command(cam, CPIA_COMMAND_SetApcor,
2300 cam->params.apcor.gain1,
2301 cam->params.apcor.gain2,
2302 cam->params.apcor.gain4,
2303 cam->params.apcor.gain8);
2304
2305 if (cam->cmd_queue & COMMAND_SETVLOFFSET)
2306 do_command(cam, CPIA_COMMAND_SetVLOffset,
2307 cam->params.vlOffset.gain1,
2308 cam->params.vlOffset.gain2,
2309 cam->params.vlOffset.gain4,
2310 cam->params.vlOffset.gain8);
2311
2312 if (cam->cmd_queue & COMMAND_SETEXPOSURE) {
2313 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2314 cam->params.exposure.gainMode,
2315 1,
2316 cam->params.exposure.compMode,
2317 cam->params.exposure.centreWeight,
2318 cam->params.exposure.gain,
2319 cam->params.exposure.fineExp,
2320 cam->params.exposure.coarseExpLo,
2321 cam->params.exposure.coarseExpHi,
2322 cam->params.exposure.redComp,
2323 cam->params.exposure.green1Comp,
2324 cam->params.exposure.green2Comp,
2325 cam->params.exposure.blueComp);
2326 if(cam->params.exposure.expMode != 1) {
2327 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2328 0,
2329 cam->params.exposure.expMode,
2330 0, 0,
2331 cam->params.exposure.gain,
2332 cam->params.exposure.fineExp,
2333 cam->params.exposure.coarseExpLo,
2334 cam->params.exposure.coarseExpHi,
2335 0, 0, 0, 0);
2336 }
2337 }
2338
2339 if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) {
2340 if (cam->params.colourBalance.balanceMode == 1) {
2341 do_command(cam, CPIA_COMMAND_SetColourBalance,
2342 1,
2343 cam->params.colourBalance.redGain,
2344 cam->params.colourBalance.greenGain,
2345 cam->params.colourBalance.blueGain);
2346 do_command(cam, CPIA_COMMAND_SetColourBalance,
2347 3, 0, 0, 0);
2348 }
2349 if (cam->params.colourBalance.balanceMode == 2) {
2350 do_command(cam, CPIA_COMMAND_SetColourBalance,
2351 2, 0, 0, 0);
2352 }
2353 if (cam->params.colourBalance.balanceMode == 3) {
2354 do_command(cam, CPIA_COMMAND_SetColourBalance,
2355 3, 0, 0, 0);
2356 }
2357 }
2358
2359 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET)
2360 do_command(cam, CPIA_COMMAND_SetCompressionTarget,
2361 cam->params.compressionTarget.frTargeting,
2362 cam->params.compressionTarget.targetFR,
2363 cam->params.compressionTarget.targetQ, 0);
2364
2365 if (cam->cmd_queue & COMMAND_SETYUVTHRESH)
2366 do_command(cam, CPIA_COMMAND_SetYUVThresh,
2367 cam->params.yuvThreshold.yThreshold,
2368 cam->params.yuvThreshold.uvThreshold, 0, 0);
2369
2370 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS)
2371 do_command_extended(cam, CPIA_COMMAND_SetCompressionParams,
2372 0, 0, 0, 0,
2373 cam->params.compressionParams.hysteresis,
2374 cam->params.compressionParams.threshMax,
2375 cam->params.compressionParams.smallStep,
2376 cam->params.compressionParams.largeStep,
2377 cam->params.compressionParams.decimationHysteresis,
2378 cam->params.compressionParams.frDiffStepThresh,
2379 cam->params.compressionParams.qDiffStepThresh,
2380 cam->params.compressionParams.decimationThreshMod);
2381
2382 if (cam->cmd_queue & COMMAND_SETCOMPRESSION)
2383 do_command(cam, CPIA_COMMAND_SetCompression,
2384 cam->params.compression.mode,
2385 cam->params.compression.decimation, 0, 0);
2386
2387 if (cam->cmd_queue & COMMAND_SETSENSORFPS)
2388 do_command(cam, CPIA_COMMAND_SetSensorFPS,
2389 cam->params.sensorFps.divisor,
2390 cam->params.sensorFps.baserate, 0, 0);
2391
2392 if (cam->cmd_queue & COMMAND_SETFLICKERCTRL)
2393 do_command(cam, CPIA_COMMAND_SetFlickerCtrl,
2394 cam->params.flickerControl.flickerMode,
2395 cam->params.flickerControl.coarseJump,
2396 abs(cam->params.flickerControl.allowableOverExposure),
2397 0);
2398
2399 if (cam->cmd_queue & COMMAND_SETECPTIMING)
2400 do_command(cam, CPIA_COMMAND_SetECPTiming,
2401 cam->params.ecpTiming, 0, 0, 0);
2402
2403 if (cam->cmd_queue & COMMAND_PAUSE)
2404 do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
2405
2406 if (cam->cmd_queue & COMMAND_RESUME)
2407 init_stream_cap(cam);
2408
2409 if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected)
2410 {
2411 int p1 = (cam->params.qx3.bottomlight == 0) << 1;
2412 int p2 = (cam->params.qx3.toplight == 0) << 3;
2413 do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0);
2414 do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0);
2415 }
2416
2417 cam->cmd_queue = COMMAND_NONE;
2418 up(&cam->param_lock);
2419 return;
2420}
2421
2422
2423
2424static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
2425 int on)
2426{
2427 /* Everything in here is from the Windows driver */
2428#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
2429 params->version.firmwareRevision == (y))
2430/* define for compgain calculation */
2431#if 0
2432#define COMPGAIN(base, curexp, newexp) \
2433 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
2434#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2435 (u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
2436#else
2437 /* equivalent functions without floating point math */
2438#define COMPGAIN(base, curexp, newexp) \
2439 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2* newexp)) )
2440#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2441 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
2442#endif
2443
2444
2445 int currentexp = params->exposure.coarseExpLo +
2446 params->exposure.coarseExpHi*256;
2447 int startexp;
2448 if (on) {
2449 int cj = params->flickerControl.coarseJump;
2450 params->flickerControl.flickerMode = 1;
2451 params->flickerControl.disabled = 0;
2452 if(params->exposure.expMode != 2)
2453 *command_flags |= COMMAND_SETEXPOSURE;
2454 params->exposure.expMode = 2;
2455 currentexp = currentexp << params->exposure.gain;
2456 params->exposure.gain = 0;
2457 /* round down current exposure to nearest value */
2458 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
2459 if(startexp < 1)
2460 startexp = 1;
2461 startexp = (startexp * cj) - 1;
2462 if(FIRMWARE_VERSION(1,2))
2463 while(startexp > MAX_EXP_102)
2464 startexp -= cj;
2465 else
2466 while(startexp > MAX_EXP)
2467 startexp -= cj;
2468 params->exposure.coarseExpLo = startexp & 0xff;
2469 params->exposure.coarseExpHi = startexp >> 8;
2470 if (currentexp > startexp) {
2471 if (currentexp > (2 * startexp))
2472 currentexp = 2 * startexp;
2473 params->exposure.redComp = COMPGAIN (COMP_RED, currentexp, startexp);
2474 params->exposure.green1Comp = COMPGAIN (COMP_GREEN1, currentexp, startexp);
2475 params->exposure.green2Comp = COMPGAIN (COMP_GREEN2, currentexp, startexp);
2476 params->exposure.blueComp = COMPGAIN (COMP_BLUE, currentexp, startexp);
2477 } else {
2478 params->exposure.redComp = COMP_RED;
2479 params->exposure.green1Comp = COMP_GREEN1;
2480 params->exposure.green2Comp = COMP_GREEN2;
2481 params->exposure.blueComp = COMP_BLUE;
2482 }
2483 if(FIRMWARE_VERSION(1,2))
2484 params->exposure.compMode = 0;
2485 else
2486 params->exposure.compMode = 1;
2487
2488 params->apcor.gain1 = 0x18;
2489 params->apcor.gain2 = 0x18;
2490 params->apcor.gain4 = 0x16;
2491 params->apcor.gain8 = 0x14;
2492 *command_flags |= COMMAND_SETAPCOR;
2493 } else {
2494 params->flickerControl.flickerMode = 0;
2495 params->flickerControl.disabled = 1;
2496 /* Coarse = average of equivalent coarse for each comp channel */
2497 startexp = EXP_FROM_COMP(COMP_RED, params->exposure.redComp, currentexp);
2498 startexp += EXP_FROM_COMP(COMP_GREEN1, params->exposure.green1Comp, currentexp);
2499 startexp += EXP_FROM_COMP(COMP_GREEN2, params->exposure.green2Comp, currentexp);
2500 startexp += EXP_FROM_COMP(COMP_BLUE, params->exposure.blueComp, currentexp);
2501 startexp = startexp >> 2;
2502 while(startexp > MAX_EXP &&
2503 params->exposure.gain < params->exposure.gainMode-1) {
2504 startexp = startexp >> 1;
2505 ++params->exposure.gain;
2506 }
2507 if(FIRMWARE_VERSION(1,2) && startexp > MAX_EXP_102)
2508 startexp = MAX_EXP_102;
2509 if(startexp > MAX_EXP)
2510 startexp = MAX_EXP;
2511 params->exposure.coarseExpLo = startexp&0xff;
2512 params->exposure.coarseExpHi = startexp >> 8;
2513 params->exposure.redComp = COMP_RED;
2514 params->exposure.green1Comp = COMP_GREEN1;
2515 params->exposure.green2Comp = COMP_GREEN2;
2516 params->exposure.blueComp = COMP_BLUE;
2517 params->exposure.compMode = 1;
2518 *command_flags |= COMMAND_SETEXPOSURE;
2519 params->apcor.gain1 = 0x18;
2520 params->apcor.gain2 = 0x16;
2521 params->apcor.gain4 = 0x24;
2522 params->apcor.gain8 = 0x34;
2523 *command_flags |= COMMAND_SETAPCOR;
2524 }
2525 params->vlOffset.gain1 = 20;
2526 params->vlOffset.gain2 = 24;
2527 params->vlOffset.gain4 = 26;
2528 params->vlOffset.gain8 = 26;
2529 *command_flags |= COMMAND_SETVLOFFSET;
2530#undef FIRMWARE_VERSION
2531#undef EXP_FROM_COMP
2532#undef COMPGAIN
2533}
2534
2535#define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \
2536 cam->params.version.firmwareRevision == (y))
2537/* monitor the exposure and adjust the sensor frame rate if needed */
2538static void monitor_exposure(struct cam_data *cam)
2539{
2540 u8 exp_acc, bcomp, gain, coarseL, cmd[8], data[8];
2541 int retval, light_exp, dark_exp, very_dark_exp;
2542 int old_exposure, new_exposure, framerate;
2543
2544 /* get necessary stats and register settings from camera */
2545 /* do_command can't handle this, so do it ourselves */
2546 cmd[0] = CPIA_COMMAND_ReadVPRegs>>8;
2547 cmd[1] = CPIA_COMMAND_ReadVPRegs&0xff;
2548 cmd[2] = 30;
2549 cmd[3] = 4;
2550 cmd[4] = 9;
2551 cmd[5] = 8;
2552 cmd[6] = 8;
2553 cmd[7] = 0;
2554 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
2555 if (retval) {
2556 LOG("ReadVPRegs(30,4,9,8) - failed, retval=%d\n",
2557 retval);
2558 return;
2559 }
2560 exp_acc = data[0];
2561 bcomp = data[1];
2562 gain = data[2];
2563 coarseL = data[3];
2564
2565 down(&cam->param_lock);
2566 light_exp = cam->params.colourParams.brightness +
2567 TC - 50 + EXP_ACC_LIGHT;
2568 if(light_exp > 255)
2569 light_exp = 255;
2570 dark_exp = cam->params.colourParams.brightness +
2571 TC - 50 - EXP_ACC_DARK;
2572 if(dark_exp < 0)
2573 dark_exp = 0;
2574 very_dark_exp = dark_exp/2;
2575
2576 old_exposure = cam->params.exposure.coarseExpHi * 256 +
2577 cam->params.exposure.coarseExpLo;
2578
2579 if(!cam->params.flickerControl.disabled) {
2580 /* Flicker control on */
2581 int max_comp = FIRMWARE_VERSION(1,2) ? MAX_COMP : HIGH_COMP_102;
2582 bcomp += 128; /* decode */
2583 if(bcomp >= max_comp && exp_acc < dark_exp) {
2584 /* dark */
2585 if(exp_acc < very_dark_exp) {
2586 /* very dark */
2587 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2588 ++cam->exposure_count;
2589 else {
2590 cam->exposure_status = EXPOSURE_VERY_DARK;
2591 cam->exposure_count = 1;
2592 }
2593 } else {
2594 /* just dark */
2595 if(cam->exposure_status == EXPOSURE_DARK)
2596 ++cam->exposure_count;
2597 else {
2598 cam->exposure_status = EXPOSURE_DARK;
2599 cam->exposure_count = 1;
2600 }
2601 }
2602 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2603 /* light */
2604 if(old_exposure <= VERY_LOW_EXP) {
2605 /* very light */
2606 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2607 ++cam->exposure_count;
2608 else {
2609 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2610 cam->exposure_count = 1;
2611 }
2612 } else {
2613 /* just light */
2614 if(cam->exposure_status == EXPOSURE_LIGHT)
2615 ++cam->exposure_count;
2616 else {
2617 cam->exposure_status = EXPOSURE_LIGHT;
2618 cam->exposure_count = 1;
2619 }
2620 }
2621 } else {
2622 /* not dark or light */
2623 cam->exposure_status = EXPOSURE_NORMAL;
2624 }
2625 } else {
2626 /* Flicker control off */
2627 if(old_exposure >= MAX_EXP && exp_acc < dark_exp) {
2628 /* dark */
2629 if(exp_acc < very_dark_exp) {
2630 /* very dark */
2631 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2632 ++cam->exposure_count;
2633 else {
2634 cam->exposure_status = EXPOSURE_VERY_DARK;
2635 cam->exposure_count = 1;
2636 }
2637 } else {
2638 /* just dark */
2639 if(cam->exposure_status == EXPOSURE_DARK)
2640 ++cam->exposure_count;
2641 else {
2642 cam->exposure_status = EXPOSURE_DARK;
2643 cam->exposure_count = 1;
2644 }
2645 }
2646 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2647 /* light */
2648 if(old_exposure <= VERY_LOW_EXP) {
2649 /* very light */
2650 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2651 ++cam->exposure_count;
2652 else {
2653 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2654 cam->exposure_count = 1;
2655 }
2656 } else {
2657 /* just light */
2658 if(cam->exposure_status == EXPOSURE_LIGHT)
2659 ++cam->exposure_count;
2660 else {
2661 cam->exposure_status = EXPOSURE_LIGHT;
2662 cam->exposure_count = 1;
2663 }
2664 }
2665 } else {
2666 /* not dark or light */
2667 cam->exposure_status = EXPOSURE_NORMAL;
2668 }
2669 }
2670
2671 framerate = cam->fps;
2672 if(framerate > 30 || framerate < 1)
2673 framerate = 1;
2674
2675 if(!cam->params.flickerControl.disabled) {
2676 /* Flicker control on */
2677 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2678 cam->exposure_status == EXPOSURE_DARK) &&
2679 cam->exposure_count >= DARK_TIME*framerate &&
2680 cam->params.sensorFps.divisor < 3) {
2681
2682 /* dark for too long */
2683 ++cam->params.sensorFps.divisor;
2684 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2685
2686 cam->params.flickerControl.coarseJump =
2687 flicker_jumps[cam->mainsFreq]
2688 [cam->params.sensorFps.baserate]
2689 [cam->params.sensorFps.divisor];
2690 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
2691
2692 new_exposure = cam->params.flickerControl.coarseJump-1;
2693 while(new_exposure < old_exposure/2)
2694 new_exposure += cam->params.flickerControl.coarseJump;
2695 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2696 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2697 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2698 cam->exposure_status = EXPOSURE_NORMAL;
2699 LOG("Automatically decreasing sensor_fps\n");
2700
2701 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2702 cam->exposure_status == EXPOSURE_LIGHT) &&
2703 cam->exposure_count >= LIGHT_TIME*framerate &&
2704 cam->params.sensorFps.divisor > 0) {
2705
2706 /* light for too long */
2707 int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ;
2708
2709 --cam->params.sensorFps.divisor;
2710 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2711
2712 cam->params.flickerControl.coarseJump =
2713 flicker_jumps[cam->mainsFreq]
2714 [cam->params.sensorFps.baserate]
2715 [cam->params.sensorFps.divisor];
2716 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
2717
2718 new_exposure = cam->params.flickerControl.coarseJump-1;
2719 while(new_exposure < 2*old_exposure &&
2720 new_exposure+
2721 cam->params.flickerControl.coarseJump < max_exp)
2722 new_exposure += cam->params.flickerControl.coarseJump;
2723 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2724 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2725 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2726 cam->exposure_status = EXPOSURE_NORMAL;
2727 LOG("Automatically increasing sensor_fps\n");
2728 }
2729 } else {
2730 /* Flicker control off */
2731 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2732 cam->exposure_status == EXPOSURE_DARK) &&
2733 cam->exposure_count >= DARK_TIME*framerate &&
2734 cam->params.sensorFps.divisor < 3) {
2735
2736 /* dark for too long */
2737 ++cam->params.sensorFps.divisor;
2738 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2739
2740 if(cam->params.exposure.gain > 0) {
2741 --cam->params.exposure.gain;
2742 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2743 }
2744 cam->exposure_status = EXPOSURE_NORMAL;
2745 LOG("Automatically decreasing sensor_fps\n");
2746
2747 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2748 cam->exposure_status == EXPOSURE_LIGHT) &&
2749 cam->exposure_count >= LIGHT_TIME*framerate &&
2750 cam->params.sensorFps.divisor > 0) {
2751
2752 /* light for too long */
2753 --cam->params.sensorFps.divisor;
2754 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2755
2756 if(cam->params.exposure.gain <
2757 cam->params.exposure.gainMode-1) {
2758 ++cam->params.exposure.gain;
2759 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2760 }
2761 cam->exposure_status = EXPOSURE_NORMAL;
2762 LOG("Automatically increasing sensor_fps\n");
2763 }
2764 }
2765 up(&cam->param_lock);
2766}
2767
2768/*-----------------------------------------------------------------*/
2769/* if flicker is switched off, this function switches it back on.It checks,
2770 however, that conditions are suitable before restarting it.
2771 This should only be called for firmware version 1.2.
2772
2773 It also adjust the colour balance when an exposure step is detected - as
2774 long as flicker is running
2775*/
2776static void restart_flicker(struct cam_data *cam)
2777{
2778 int cam_exposure, old_exp;
2779 if(!FIRMWARE_VERSION(1,2))
2780 return;
2781 down(&cam->param_lock);
2782 if(cam->params.flickerControl.flickerMode == 0 ||
2783 cam->raw_image[39] == 0) {
2784 up(&cam->param_lock);
2785 return;
2786 }
2787 cam_exposure = cam->raw_image[39]*2;
2788 old_exp = cam->params.exposure.coarseExpLo +
2789 cam->params.exposure.coarseExpHi*256;
2790 /*
2791 see how far away camera exposure is from a valid
2792 flicker exposure value
2793 */
2794 cam_exposure %= cam->params.flickerControl.coarseJump;
2795 if(!cam->params.flickerControl.disabled &&
2796 cam_exposure <= cam->params.flickerControl.coarseJump - 3) {
2797 /* Flicker control auto-disabled */
2798 cam->params.flickerControl.disabled = 1;
2799 }
2800
2801 if(cam->params.flickerControl.disabled &&
2802 cam->params.flickerControl.flickerMode &&
2803 old_exp > cam->params.flickerControl.coarseJump +
2804 ROUND_UP_EXP_FOR_FLICKER) {
2805 /* exposure is now high enough to switch
2806 flicker control back on */
2807 set_flicker(&cam->params, &cam->cmd_queue, 1);
2808 if((cam->cmd_queue & COMMAND_SETEXPOSURE) &&
2809 cam->params.exposure.expMode == 2)
2810 cam->exposure_status = EXPOSURE_NORMAL;
2811
2812 }
2813 up(&cam->param_lock);
2814}
2815#undef FIRMWARE_VERSION
2816
2817static int clear_stall(struct cam_data *cam)
2818{
2819 /* FIXME: Does this actually work? */
2820 LOG("Clearing stall\n");
2821
2822 cam->ops->streamRead(cam->lowlevel_data, cam->raw_image, 0);
2823 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2824 return cam->params.status.streamState != STREAM_PAUSED;
2825}
2826
2827/* kernel thread function to read image from camera */
2828static int fetch_frame(void *data)
2829{
2830 int image_size, retry;
2831 struct cam_data *cam = (struct cam_data *)data;
2832 unsigned long oldjif, rate, diff;
2833
2834 /* Allow up to two bad images in a row to be read and
2835 * ignored before an error is reported */
2836 for (retry = 0; retry < 3; ++retry) {
2837 if (retry)
2838 DBG("retry=%d\n", retry);
2839
2840 if (!cam->ops)
2841 continue;
2842
2843 /* load first frame always uncompressed */
2844 if (cam->first_frame &&
2845 cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
2846 do_command(cam, CPIA_COMMAND_SetCompression,
2847 CPIA_COMPRESSION_NONE,
2848 NO_DECIMATION, 0, 0);
2849 /* Trial & error - Discarding a frame prevents the
2850 first frame from having an error in the data. */
2851 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
2852 }
2853
2854 /* init camera upload */
2855 if (do_command(cam, CPIA_COMMAND_GrabFrame, 0,
2856 cam->params.streamStartLine, 0, 0))
2857 continue;
2858
2859 if (cam->ops->wait_for_stream_ready) {
2860 /* loop until image ready */
2861 int count = 0;
2862 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2863 while (cam->params.status.streamState != STREAM_READY) {
2864 if(++count > READY_TIMEOUT)
2865 break;
2866 if(cam->params.status.streamState ==
2867 STREAM_PAUSED) {
2868 /* Bad news */
2869 if(!clear_stall(cam))
2870 return -EIO;
2871 }
2872
2873 cond_resched();
2874
2875 /* sleep for 10 ms, hopefully ;) */
2876 msleep_interruptible(10);
2877 if (signal_pending(current))
2878 return -EINTR;
2879
2880 do_command(cam, CPIA_COMMAND_GetCameraStatus,
2881 0, 0, 0, 0);
2882 }
2883 if(cam->params.status.streamState != STREAM_READY) {
2884 continue;
2885 }
2886 }
2887
2888 cond_resched();
2889
2890 /* grab image from camera */
2891 oldjif = jiffies;
2892 image_size = cam->ops->streamRead(cam->lowlevel_data,
2893 cam->raw_image, 0);
2894 if (image_size <= 0) {
2895 DBG("streamRead failed: %d\n", image_size);
2896 continue;
2897 }
2898
2899 rate = image_size * HZ / 1024;
2900 diff = jiffies-oldjif;
2901 cam->transfer_rate = diff==0 ? rate : rate/diff;
2902 /* diff==0 ? unlikely but possible */
2903
2904 /* Switch flicker control back on if it got turned off */
2905 restart_flicker(cam);
2906
2907 /* If AEC is enabled, monitor the exposure and
2908 adjust the sensor frame rate if needed */
2909 if(cam->params.exposure.expMode == 2)
2910 monitor_exposure(cam);
2911
2912 /* camera idle now so dispatch queued commands */
2913 dispatch_commands(cam);
2914
2915 /* Update our knowledge of the camera state */
2916 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
2917 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
2918 do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
2919
2920 /* decompress and convert image to by copying it from
2921 * raw_image to decompressed_frame
2922 */
2923
2924 cond_resched();
2925
2926 cam->image_size = parse_picture(cam, image_size);
2927 if (cam->image_size <= 0) {
2928 DBG("parse_picture failed %d\n", cam->image_size);
2929 if(cam->params.compression.mode !=
2930 CPIA_COMPRESSION_NONE) {
2931 /* Compression may not work right if we
2932 had a bad frame, get the next one
2933 uncompressed. */
2934 cam->first_frame = 1;
2935 do_command(cam, CPIA_COMMAND_SetGrabMode,
2936 CPIA_GRAB_SINGLE, 0, 0, 0);
2937 /* FIXME: Trial & error - need up to 70ms for
2938 the grab mode change to complete ? */
2939 msleep_interruptible(70);
2940 if (signal_pending(current))
2941 return -EINTR;
2942 }
2943 } else
2944 break;
2945 }
2946
2947 if (retry < 3) {
2948 /* FIXME: this only works for double buffering */
2949 if (cam->frame[cam->curframe].state == FRAME_READY) {
2950 memcpy(cam->frame[cam->curframe].data,
2951 cam->decompressed_frame.data,
2952 cam->decompressed_frame.count);
2953 cam->frame[cam->curframe].state = FRAME_DONE;
2954 } else
2955 cam->decompressed_frame.state = FRAME_DONE;
2956
2957 if (cam->first_frame) {
2958 cam->first_frame = 0;
2959 do_command(cam, CPIA_COMMAND_SetCompression,
2960 cam->params.compression.mode,
2961 cam->params.compression.decimation, 0, 0);
2962
2963 /* Switch from single-grab to continuous grab */
2964 do_command(cam, CPIA_COMMAND_SetGrabMode,
2965 CPIA_GRAB_CONTINUOUS, 0, 0, 0);
2966 }
2967 return 0;
2968 }
2969 return -EIO;
2970}
2971
2972static int capture_frame(struct cam_data *cam, struct video_mmap *vm)
2973{
2974 if (!cam->frame_buf) {
2975 /* we do lazy allocation */
2976 int err;
2977 if ((err = allocate_frame_buf(cam)))
2978 return err;
2979 }
2980
2981 cam->curframe = vm->frame;
2982 cam->frame[cam->curframe].state = FRAME_READY;
2983 return fetch_frame(cam);
2984}
2985
2986static int goto_high_power(struct cam_data *cam)
2987{
2988 if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0))
2989 return -EIO;
2990 msleep_interruptible(40); /* windows driver does it too */
2991 if(signal_pending(current))
2992 return -EINTR;
2993 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
2994 return -EIO;
2995 if (cam->params.status.systemState == HI_POWER_STATE) {
2996 DBG("camera now in HIGH power state\n");
2997 return 0;
2998 }
2999 printstatus(cam);
3000 return -EIO;
3001}
3002
3003static int goto_low_power(struct cam_data *cam)
3004{
3005 if (do_command(cam, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0))
3006 return -1;
3007 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
3008 return -1;
3009 if (cam->params.status.systemState == LO_POWER_STATE) {
3010 DBG("camera now in LOW power state\n");
3011 return 0;
3012 }
3013 printstatus(cam);
3014 return -1;
3015}
3016
3017static void save_camera_state(struct cam_data *cam)
3018{
3019 if(!(cam->cmd_queue & COMMAND_SETCOLOURBALANCE))
3020 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
3021 if(!(cam->cmd_queue & COMMAND_SETEXPOSURE))
3022 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
3023
3024 DBG("%d/%d/%d/%d/%d/%d/%d/%d\n",
3025 cam->params.exposure.gain,
3026 cam->params.exposure.fineExp,
3027 cam->params.exposure.coarseExpLo,
3028 cam->params.exposure.coarseExpHi,
3029 cam->params.exposure.redComp,
3030 cam->params.exposure.green1Comp,
3031 cam->params.exposure.green2Comp,
3032 cam->params.exposure.blueComp);
3033 DBG("%d/%d/%d\n",
3034 cam->params.colourBalance.redGain,
3035 cam->params.colourBalance.greenGain,
3036 cam->params.colourBalance.blueGain);
3037}
3038
3039static int set_camera_state(struct cam_data *cam)
3040{
3041 cam->cmd_queue = COMMAND_SETCOMPRESSION |
3042 COMMAND_SETCOMPRESSIONTARGET |
3043 COMMAND_SETCOLOURPARAMS |
3044 COMMAND_SETFORMAT |
3045 COMMAND_SETYUVTHRESH |
3046 COMMAND_SETECPTIMING |
3047 COMMAND_SETCOMPRESSIONPARAMS |
3048 COMMAND_SETEXPOSURE |
3049 COMMAND_SETCOLOURBALANCE |
3050 COMMAND_SETSENSORFPS |
3051 COMMAND_SETAPCOR |
3052 COMMAND_SETFLICKERCTRL |
3053 COMMAND_SETVLOFFSET;
3054
3055 do_command(cam, CPIA_COMMAND_SetGrabMode, CPIA_GRAB_SINGLE,0,0,0);
3056 dispatch_commands(cam);
3057
3058 /* Wait 6 frames for the sensor to get all settings and
3059 AEC/ACB to settle */
3060 msleep_interruptible(6*(cam->params.sensorFps.baserate ? 33 : 40) *
3061 (1 << cam->params.sensorFps.divisor) + 10);
3062
3063 if(signal_pending(current))
3064 return -EINTR;
3065
3066 save_camera_state(cam);
3067
3068 return 0;
3069}
3070
3071static void get_version_information(struct cam_data *cam)
3072{
3073 /* GetCPIAVersion */
3074 do_command(cam, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
3075
3076 /* GetPnPID */
3077 do_command(cam, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
3078}
3079
3080/* initialize camera */
3081static int reset_camera(struct cam_data *cam)
3082{
3083 int err;
3084 /* Start the camera in low power mode */
3085 if (goto_low_power(cam)) {
3086 if (cam->params.status.systemState != WARM_BOOT_STATE)
3087 return -ENODEV;
3088
3089 /* FIXME: this is just dirty trial and error */
3090 err = goto_high_power(cam);
3091 if(err)
3092 return err;
3093 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
3094 if (goto_low_power(cam))
3095 return -ENODEV;
3096 }
3097
3098 /* procedure described in developer's guide p3-28 */
3099
3100 /* Check the firmware version. */
3101 cam->params.version.firmwareVersion = 0;
3102 get_version_information(cam);
3103 if (cam->params.version.firmwareVersion != 1)
3104 return -ENODEV;
3105
3106 /* A bug in firmware 1-02 limits gainMode to 2 */
3107 if(cam->params.version.firmwareRevision <= 2 &&
3108 cam->params.exposure.gainMode > 2) {
3109 cam->params.exposure.gainMode = 2;
3110 }
3111
3112 /* set QX3 detected flag */
3113 cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 &&
3114 cam->params.pnpID.product == 0x0001);
3115
3116 /* The fatal error checking should be done after
3117 * the camera powers up (developer's guide p 3-38) */
3118
3119 /* Set streamState before transition to high power to avoid bug
3120 * in firmware 1-02 */
3121 do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0,
3122 STREAM_NOT_READY, 0);
3123
3124 /* GotoHiPower */
3125 err = goto_high_power(cam);
3126 if (err)
3127 return err;
3128
3129 /* Check the camera status */
3130 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
3131 return -EIO;
3132
3133 if (cam->params.status.fatalError) {
3134 DBG("fatal_error: %#04x\n",
3135 cam->params.status.fatalError);
3136 DBG("vp_status: %#04x\n",
3137 cam->params.status.vpStatus);
3138 if (cam->params.status.fatalError & ~(COM_FLAG|CPIA_FLAG)) {
3139 /* Fatal error in camera */
3140 return -EIO;
3141 } else if (cam->params.status.fatalError & (COM_FLAG|CPIA_FLAG)) {
3142 /* Firmware 1-02 may do this for parallel port cameras,
3143 * just clear the flags (developer's guide p 3-38) */
3144 do_command(cam, CPIA_COMMAND_ModifyCameraStatus,
3145 FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0);
3146 }
3147 }
3148
3149 /* Check the camera status again */
3150 if (cam->params.status.fatalError) {
3151 if (cam->params.status.fatalError)
3152 return -EIO;
3153 }
3154
3155 /* VPVersion can't be retrieved before the camera is in HiPower,
3156 * so get it here instead of in get_version_information. */
3157 do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
3158
3159 /* set camera to a known state */
3160 return set_camera_state(cam);
3161}
3162
3163static void put_cam(struct cpia_camera_ops* ops)
3164{
3165 if (ops->owner)
3166 module_put(ops->owner);
3167}
3168
3169/* ------------------------- V4L interface --------------------- */
3170static int cpia_open(struct inode *inode, struct file *file)
3171{
3172 struct video_device *dev = video_devdata(file);
3173 struct cam_data *cam = dev->priv;
3174 int err;
3175
3176 if (!cam) {
3177 DBG("Internal error, cam_data not found!\n");
3178 return -ENODEV;
3179 }
3180
3181 if (cam->open_count > 0) {
3182 DBG("Camera already open\n");
3183 return -EBUSY;
3184 }
3185
3186 if (!try_module_get(cam->ops->owner))
3187 return -ENODEV;
3188
3189 down(&cam->busy_lock);
3190 err = -ENOMEM;
3191 if (!cam->raw_image) {
3192 cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
3193 if (!cam->raw_image)
3194 goto oops;
3195 }
3196
3197 if (!cam->decompressed_frame.data) {
3198 cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE);
3199 if (!cam->decompressed_frame.data)
3200 goto oops;
3201 }
3202
3203 /* open cpia */
3204 err = -ENODEV;
3205 if (cam->ops->open(cam->lowlevel_data))
3206 goto oops;
3207
3208 /* reset the camera */
3209 if ((err = reset_camera(cam)) != 0) {
3210 cam->ops->close(cam->lowlevel_data);
3211 goto oops;
3212 }
3213
3214 err = -EINTR;
3215 if(signal_pending(current))
3216 goto oops;
3217
3218 /* Set ownership of /proc/cpia/videoX to current user */
3219 if(cam->proc_entry)
3220 cam->proc_entry->uid = current->uid;
3221
3222 /* set mark for loading first frame uncompressed */
3223 cam->first_frame = 1;
3224
3225 /* init it to something */
3226 cam->mmap_kludge = 0;
3227
3228 ++cam->open_count;
3229 file->private_data = dev;
3230 up(&cam->busy_lock);
3231 return 0;
3232
3233 oops:
3234 if (cam->decompressed_frame.data) {
3235 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3236 cam->decompressed_frame.data = NULL;
3237 }
3238 if (cam->raw_image) {
3239 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3240 cam->raw_image = NULL;
3241 }
3242 up(&cam->busy_lock);
3243 put_cam(cam->ops);
3244 return err;
3245}
3246
3247static int cpia_close(struct inode *inode, struct file *file)
3248{
3249 struct video_device *dev = file->private_data;
3250 struct cam_data *cam = dev->priv;
3251
3252 if (cam->ops) {
3253 /* Return ownership of /proc/cpia/videoX to root */
3254 if(cam->proc_entry)
3255 cam->proc_entry->uid = 0;
3256
3257 /* save camera state for later open (developers guide ch 3.5.3) */
3258 save_camera_state(cam);
3259
3260 /* GotoLoPower */
3261 goto_low_power(cam);
3262
3263 /* Update the camera status */
3264 do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
3265
3266 /* cleanup internal state stuff */
3267 free_frames(cam->frame);
3268
3269 /* close cpia */
3270 cam->ops->close(cam->lowlevel_data);
3271
3272 put_cam(cam->ops);
3273 }
3274
3275 if (--cam->open_count == 0) {
3276 /* clean up capture-buffers */
3277 if (cam->raw_image) {
3278 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3279 cam->raw_image = NULL;
3280 }
3281
3282 if (cam->decompressed_frame.data) {
3283 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3284 cam->decompressed_frame.data = NULL;
3285 }
3286
3287 if (cam->frame_buf)
3288 free_frame_buf(cam);
3289
3290 if (!cam->ops)
3291 kfree(cam);
3292 }
3293 file->private_data = NULL;
3294
3295 return 0;
3296}
3297
3298static ssize_t cpia_read(struct file *file, char __user *buf,
3299 size_t count, loff_t *ppos)
3300{
3301 struct video_device *dev = file->private_data;
3302 struct cam_data *cam = dev->priv;
3303 int err;
3304
3305 /* make this _really_ smp and multithread-safe */
3306 if (down_interruptible(&cam->busy_lock))
3307 return -EINTR;
3308
3309 if (!buf) {
3310 DBG("buf NULL\n");
3311 up(&cam->busy_lock);
3312 return -EINVAL;
3313 }
3314
3315 if (!count) {
3316 DBG("count 0\n");
3317 up(&cam->busy_lock);
3318 return 0;
3319 }
3320
3321 if (!cam->ops) {
3322 DBG("ops NULL\n");
3323 up(&cam->busy_lock);
3324 return -ENODEV;
3325 }
3326
3327 /* upload frame */
3328 cam->decompressed_frame.state = FRAME_READY;
3329 cam->mmap_kludge=0;
3330 if((err = fetch_frame(cam)) != 0) {
3331 DBG("ERROR from fetch_frame: %d\n", err);
3332 up(&cam->busy_lock);
3333 return err;
3334 }
3335 cam->decompressed_frame.state = FRAME_UNUSED;
3336
3337 /* copy data to user space */
3338 if (cam->decompressed_frame.count > count) {
3339 DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
3340 (unsigned long) count);
3341 up(&cam->busy_lock);
3342 return -EFAULT;
3343 }
3344 if (copy_to_user(buf, cam->decompressed_frame.data,
3345 cam->decompressed_frame.count)) {
3346 DBG("copy_to_user failed\n");
3347 up(&cam->busy_lock);
3348 return -EFAULT;
3349 }
3350
3351 up(&cam->busy_lock);
3352 return cam->decompressed_frame.count;
3353}
3354
3355static int cpia_do_ioctl(struct inode *inode, struct file *file,
3356 unsigned int ioctlnr, void *arg)
3357{
3358 struct video_device *dev = file->private_data;
3359 struct cam_data *cam = dev->priv;
3360 int retval = 0;
3361
3362 if (!cam || !cam->ops)
3363 return -ENODEV;
3364
3365 /* make this _really_ smp-safe */
3366 if (down_interruptible(&cam->busy_lock))
3367 return -EINTR;
3368
3369 //DBG("cpia_ioctl: %u\n", ioctlnr);
3370
3371 switch (ioctlnr) {
3372 /* query capabilites */
3373 case VIDIOCGCAP:
3374 {
3375 struct video_capability *b = arg;
3376
3377 DBG("VIDIOCGCAP\n");
3378 strcpy(b->name, "CPiA Camera");
3379 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
3380 b->channels = 1;
3381 b->audios = 0;
3382 b->maxwidth = 352; /* VIDEOSIZE_CIF */
3383 b->maxheight = 288;
3384 b->minwidth = 48; /* VIDEOSIZE_48_48 */
3385 b->minheight = 48;
3386 break;
3387 }
3388
3389 /* get/set video source - we are a camera and nothing else */
3390 case VIDIOCGCHAN:
3391 {
3392 struct video_channel *v = arg;
3393
3394 DBG("VIDIOCGCHAN\n");
3395 if (v->channel != 0) {
3396 retval = -EINVAL;
3397 break;
3398 }
3399
3400 v->channel = 0;
3401 strcpy(v->name, "Camera");
3402 v->tuners = 0;
3403 v->flags = 0;
3404 v->type = VIDEO_TYPE_CAMERA;
3405 v->norm = 0;
3406 break;
3407 }
3408
3409 case VIDIOCSCHAN:
3410 {
3411 struct video_channel *v = arg;
3412
3413 DBG("VIDIOCSCHAN\n");
3414 if (v->channel != 0)
3415 retval = -EINVAL;
3416 break;
3417 }
3418
3419 /* image properties */
3420 case VIDIOCGPICT:
3421 {
3422 struct video_picture *pic = arg;
3423 DBG("VIDIOCGPICT\n");
3424 *pic = cam->vp;
3425 break;
3426 }
3427
3428 case VIDIOCSPICT:
3429 {
3430 struct video_picture *vp = arg;
3431
3432 DBG("VIDIOCSPICT\n");
3433
3434 /* check validity */
3435 DBG("palette: %d\n", vp->palette);
3436 DBG("depth: %d\n", vp->depth);
3437 if (!valid_mode(vp->palette, vp->depth)) {
3438 retval = -EINVAL;
3439 break;
3440 }
3441
3442 down(&cam->param_lock);
3443 /* brightness, colour, contrast need no check 0-65535 */
3444 cam->vp = *vp;
3445 /* update cam->params.colourParams */
3446 cam->params.colourParams.brightness = vp->brightness*100/65535;
3447 cam->params.colourParams.contrast = vp->contrast*100/65535;
3448 cam->params.colourParams.saturation = vp->colour*100/65535;
3449 /* contrast is in steps of 8, so round */
3450 cam->params.colourParams.contrast =
3451 ((cam->params.colourParams.contrast + 3) / 8) * 8;
3452 if (cam->params.version.firmwareVersion == 1 &&
3453 cam->params.version.firmwareRevision == 2 &&
3454 cam->params.colourParams.contrast > 80) {
3455 /* 1-02 firmware limits contrast to 80 */
3456 cam->params.colourParams.contrast = 80;
3457 }
3458
3459 /* Adjust flicker control if necessary */
3460 if(cam->params.flickerControl.allowableOverExposure < 0)
3461 cam->params.flickerControl.allowableOverExposure =
3462 -find_over_exposure(cam->params.colourParams.brightness);
3463 if(cam->params.flickerControl.flickerMode != 0)
3464 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
3465
3466
3467 /* queue command to update camera */
3468 cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
3469 up(&cam->param_lock);
3470 DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
3471 vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour,
3472 vp->contrast);
3473 break;
3474 }
3475
3476 /* get/set capture window */
3477 case VIDIOCGWIN:
3478 {
3479 struct video_window *vw = arg;
3480 DBG("VIDIOCGWIN\n");
3481
3482 *vw = cam->vw;
3483 break;
3484 }
3485
3486 case VIDIOCSWIN:
3487 {
3488 /* copy_from_user, check validity, copy to internal structure */
3489 struct video_window *vw = arg;
3490 DBG("VIDIOCSWIN\n");
3491
3492 if (vw->clipcount != 0) { /* clipping not supported */
3493 retval = -EINVAL;
3494 break;
3495 }
3496 if (vw->clips != NULL) { /* clipping not supported */
3497 retval = -EINVAL;
3498 break;
3499 }
3500
3501 /* we set the video window to something smaller or equal to what
3502 * is requested by the user???
3503 */
3504 down(&cam->param_lock);
3505 if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
3506 int video_size = match_videosize(vw->width, vw->height);
3507
3508 if (video_size < 0) {
3509 retval = -EINVAL;
3510 up(&cam->param_lock);
3511 break;
3512 }
3513 cam->video_size = video_size;
3514
3515 /* video size is changing, reset the subcapture area */
3516 memset(&cam->vc, 0, sizeof(cam->vc));
3517
3518 set_vw_size(cam);
3519 DBG("%d / %d\n", cam->vw.width, cam->vw.height);
3520 cam->cmd_queue |= COMMAND_SETFORMAT;
3521 }
3522
3523 up(&cam->param_lock);
3524
3525 /* setformat ignored by camera during streaming,
3526 * so stop/dispatch/start */
3527 if (cam->cmd_queue & COMMAND_SETFORMAT) {
3528 DBG("\n");
3529 dispatch_commands(cam);
3530 }
3531 DBG("%d/%d:%d\n", cam->video_size,
3532 cam->vw.width, cam->vw.height);
3533 break;
3534 }
3535
3536 /* mmap interface */
3537 case VIDIOCGMBUF:
3538 {
3539 struct video_mbuf *vm = arg;
3540 int i;
3541
3542 DBG("VIDIOCGMBUF\n");
3543 memset(vm, 0, sizeof(*vm));
3544 vm->size = CPIA_MAX_FRAME_SIZE*FRAME_NUM;
3545 vm->frames = FRAME_NUM;
3546 for (i = 0; i < FRAME_NUM; i++)
3547 vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i;
3548 break;
3549 }
3550
3551 case VIDIOCMCAPTURE:
3552 {
3553 struct video_mmap *vm = arg;
3554 int video_size;
3555
3556 DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame,
3557 vm->width, vm->height);
3558 if (vm->frame<0||vm->frame>=FRAME_NUM) {
3559 retval = -EINVAL;
3560 break;
3561 }
3562
3563 /* set video format */
3564 cam->vp.palette = vm->format;
3565 switch(vm->format) {
3566 case VIDEO_PALETTE_GREY:
3567 cam->vp.depth=8;
3568 break;
3569 case VIDEO_PALETTE_RGB555:
3570 case VIDEO_PALETTE_RGB565:
3571 case VIDEO_PALETTE_YUV422:
3572 case VIDEO_PALETTE_YUYV:
3573 case VIDEO_PALETTE_UYVY:
3574 cam->vp.depth = 16;
3575 break;
3576 case VIDEO_PALETTE_RGB24:
3577 cam->vp.depth = 24;
3578 break;
3579 case VIDEO_PALETTE_RGB32:
3580 cam->vp.depth = 32;
3581 break;
3582 default:
3583 retval = -EINVAL;
3584 break;
3585 }
3586 if (retval)
3587 break;
3588
3589 /* set video size */
3590 video_size = match_videosize(vm->width, vm->height);
3591 if (video_size < 0) {
3592 retval = -EINVAL;
3593 break;
3594 }
3595 if (video_size != cam->video_size) {
3596 cam->video_size = video_size;
3597
3598 /* video size is changing, reset the subcapture area */
3599 memset(&cam->vc, 0, sizeof(cam->vc));
3600
3601 set_vw_size(cam);
3602 cam->cmd_queue |= COMMAND_SETFORMAT;
3603 dispatch_commands(cam);
3604 }
3605 /* according to v4l-spec we must start streaming here */
3606 cam->mmap_kludge = 1;
3607 retval = capture_frame(cam, vm);
3608
3609 break;
3610 }
3611
3612 case VIDIOCSYNC:
3613 {
3614 int *frame = arg;
3615
3616 //DBG("VIDIOCSYNC: %d\n", *frame);
3617
3618 if (*frame<0 || *frame >= FRAME_NUM) {
3619 retval = -EINVAL;
3620 break;
3621 }
3622
3623 switch (cam->frame[*frame].state) {
3624 case FRAME_UNUSED:
3625 case FRAME_READY:
3626 case FRAME_GRABBING:
3627 DBG("sync to unused frame %d\n", *frame);
3628 retval = -EINVAL;
3629 break;
3630
3631 case FRAME_DONE:
3632 cam->frame[*frame].state = FRAME_UNUSED;
3633 //DBG("VIDIOCSYNC: %d synced\n", *frame);
3634 break;
3635 }
3636 if (retval == -EINTR) {
3637 /* FIXME - xawtv does not handle this nice */
3638 retval = 0;
3639 }
3640 break;
3641 }
3642
3643 case VIDIOCGCAPTURE:
3644 {
3645 struct video_capture *vc = arg;
3646
3647 DBG("VIDIOCGCAPTURE\n");
3648
3649 *vc = cam->vc;
3650
3651 break;
3652 }
3653
3654 case VIDIOCSCAPTURE:
3655 {
3656 struct video_capture *vc = arg;
3657
3658 DBG("VIDIOCSCAPTURE\n");
3659
3660 if (vc->decimation != 0) { /* How should this be used? */
3661 retval = -EINVAL;
3662 break;
3663 }
3664 if (vc->flags != 0) { /* Even/odd grab not supported */
3665 retval = -EINVAL;
3666 break;
3667 }
3668
3669 /* Clip to the resolution we can set for the ROI
3670 (every 8 columns and 4 rows) */
3671 vc->x = vc->x & ~(__u32)7;
3672 vc->y = vc->y & ~(__u32)3;
3673 vc->width = vc->width & ~(__u32)7;
3674 vc->height = vc->height & ~(__u32)3;
3675
3676 if(vc->width == 0 || vc->height == 0 ||
3677 vc->x + vc->width > cam->vw.width ||
3678 vc->y + vc->height > cam->vw.height) {
3679 retval = -EINVAL;
3680 break;
3681 }
3682
3683 DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
3684
3685 down(&cam->param_lock);
3686
3687 cam->vc.x = vc->x;
3688 cam->vc.y = vc->y;
3689 cam->vc.width = vc->width;
3690 cam->vc.height = vc->height;
3691
3692 set_vw_size(cam);
3693 cam->cmd_queue |= COMMAND_SETFORMAT;
3694
3695 up(&cam->param_lock);
3696
3697 /* setformat ignored by camera during streaming,
3698 * so stop/dispatch/start */
3699 dispatch_commands(cam);
3700 break;
3701 }
3702
3703 case VIDIOCGUNIT:
3704 {
3705 struct video_unit *vu = arg;
3706
3707 DBG("VIDIOCGUNIT\n");
3708
3709 vu->video = cam->vdev.minor;
3710 vu->vbi = VIDEO_NO_UNIT;
3711 vu->radio = VIDEO_NO_UNIT;
3712 vu->audio = VIDEO_NO_UNIT;
3713 vu->teletext = VIDEO_NO_UNIT;
3714
3715 break;
3716 }
3717
3718
3719 /* pointless to implement overlay with this camera */
3720 case VIDIOCCAPTURE:
3721 case VIDIOCGFBUF:
3722 case VIDIOCSFBUF:
3723 case VIDIOCKEY:
3724 /* tuner interface - we have none */
3725 case VIDIOCGTUNER:
3726 case VIDIOCSTUNER:
3727 case VIDIOCGFREQ:
3728 case VIDIOCSFREQ:
3729 /* audio interface - we have none */
3730 case VIDIOCGAUDIO:
3731 case VIDIOCSAUDIO:
3732 retval = -EINVAL;
3733 break;
3734 default:
3735 retval = -ENOIOCTLCMD;
3736 break;
3737 }
3738
3739 up(&cam->busy_lock);
3740 return retval;
3741}
3742
3743static int cpia_ioctl(struct inode *inode, struct file *file,
3744 unsigned int cmd, unsigned long arg)
3745{
3746 return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl);
3747}
3748
3749
3750/* FIXME */
3751static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
3752{
3753 struct video_device *dev = file->private_data;
3754 unsigned long start = vma->vm_start;
3755 unsigned long size = vma->vm_end - vma->vm_start;
3756 unsigned long page, pos;
3757 struct cam_data *cam = dev->priv;
3758 int retval;
3759
3760 if (!cam || !cam->ops)
3761 return -ENODEV;
3762
3763 DBG("cpia_mmap: %ld\n", size);
3764
3765 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
3766 return -EINVAL;
3767
3768 if (!cam || !cam->ops)
3769 return -ENODEV;
3770
3771 /* make this _really_ smp-safe */
3772 if (down_interruptible(&cam->busy_lock))
3773 return -EINTR;
3774
3775 if (!cam->frame_buf) { /* we do lazy allocation */
3776 if ((retval = allocate_frame_buf(cam))) {
3777 up(&cam->busy_lock);
3778 return retval;
3779 }
3780 }
3781
3782 pos = (unsigned long)(cam->frame_buf);
3783 while (size > 0) {
3784 page = vmalloc_to_pfn((void *)pos);
3785 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
3786 up(&cam->busy_lock);
3787 return -EAGAIN;
3788 }
3789 start += PAGE_SIZE;
3790 pos += PAGE_SIZE;
3791 if (size > PAGE_SIZE)
3792 size -= PAGE_SIZE;
3793 else
3794 size = 0;
3795 }
3796
3797 DBG("cpia_mmap: %ld\n", size);
3798 up(&cam->busy_lock);
3799
3800 return 0;
3801}
3802
3803static struct file_operations cpia_fops = {
3804 .owner = THIS_MODULE,
3805 .open = cpia_open,
3806 .release = cpia_close,
3807 .read = cpia_read,
3808 .mmap = cpia_mmap,
3809 .ioctl = cpia_ioctl,
3810 .llseek = no_llseek,
3811};
3812
3813static struct video_device cpia_template = {
3814 .owner = THIS_MODULE,
3815 .name = "CPiA Camera",
3816 .type = VID_TYPE_CAPTURE,
3817 .hardware = VID_HARDWARE_CPIA,
3818 .fops = &cpia_fops,
3819};
3820
3821/* initialise cam_data structure */
3822static void reset_camera_struct(struct cam_data *cam)
3823{
3824 /* The following parameter values are the defaults from
3825 * "Software Developer's Guide for CPiA Cameras". Any changes
3826 * to the defaults are noted in comments. */
3827 cam->params.colourParams.brightness = 50;
3828 cam->params.colourParams.contrast = 48;
3829 cam->params.colourParams.saturation = 50;
3830 cam->params.exposure.gainMode = 4;
3831 cam->params.exposure.expMode = 2; /* AEC */
3832 cam->params.exposure.compMode = 1;
3833 cam->params.exposure.centreWeight = 1;
3834 cam->params.exposure.gain = 0;
3835 cam->params.exposure.fineExp = 0;
3836 cam->params.exposure.coarseExpLo = 185;
3837 cam->params.exposure.coarseExpHi = 0;
3838 cam->params.exposure.redComp = COMP_RED;
3839 cam->params.exposure.green1Comp = COMP_GREEN1;
3840 cam->params.exposure.green2Comp = COMP_GREEN2;
3841 cam->params.exposure.blueComp = COMP_BLUE;
3842 cam->params.colourBalance.balanceMode = 2; /* ACB */
3843 cam->params.colourBalance.redGain = 32;
3844 cam->params.colourBalance.greenGain = 6;
3845 cam->params.colourBalance.blueGain = 92;
3846 cam->params.apcor.gain1 = 0x18;
3847 cam->params.apcor.gain2 = 0x16;
3848 cam->params.apcor.gain4 = 0x24;
3849 cam->params.apcor.gain8 = 0x34;
3850 cam->params.flickerControl.flickerMode = 0;
3851 cam->params.flickerControl.disabled = 1;
3852
3853 cam->params.flickerControl.coarseJump =
3854 flicker_jumps[cam->mainsFreq]
3855 [cam->params.sensorFps.baserate]
3856 [cam->params.sensorFps.divisor];
3857 cam->params.flickerControl.allowableOverExposure =
3858 -find_over_exposure(cam->params.colourParams.brightness);
3859 cam->params.vlOffset.gain1 = 20;
3860 cam->params.vlOffset.gain2 = 24;
3861 cam->params.vlOffset.gain4 = 26;
3862 cam->params.vlOffset.gain8 = 26;
3863 cam->params.compressionParams.hysteresis = 3;
3864 cam->params.compressionParams.threshMax = 11;
3865 cam->params.compressionParams.smallStep = 1;
3866 cam->params.compressionParams.largeStep = 3;
3867 cam->params.compressionParams.decimationHysteresis = 2;
3868 cam->params.compressionParams.frDiffStepThresh = 5;
3869 cam->params.compressionParams.qDiffStepThresh = 3;
3870 cam->params.compressionParams.decimationThreshMod = 2;
3871 /* End of default values from Software Developer's Guide */
3872
3873 cam->transfer_rate = 0;
3874 cam->exposure_status = EXPOSURE_NORMAL;
3875
3876 /* Set Sensor FPS to 15fps. This seems better than 30fps
3877 * for indoor lighting. */
3878 cam->params.sensorFps.divisor = 1;
3879 cam->params.sensorFps.baserate = 1;
3880
3881 cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */
3882 cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */
3883
3884 cam->params.format.subSample = SUBSAMPLE_422;
3885 cam->params.format.yuvOrder = YUVORDER_YUYV;
3886
3887 cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
3888 cam->params.compressionTarget.frTargeting =
3889 CPIA_COMPRESSION_TARGET_QUALITY;
3890 cam->params.compressionTarget.targetFR = 15; /* From windows driver */
3891 cam->params.compressionTarget.targetQ = 5; /* From windows driver */
3892
3893 cam->params.qx3.qx3_detected = 0;
3894 cam->params.qx3.toplight = 0;
3895 cam->params.qx3.bottomlight = 0;
3896 cam->params.qx3.button = 0;
3897 cam->params.qx3.cradled = 0;
3898
3899 cam->video_size = VIDEOSIZE_CIF;
3900
3901 cam->vp.colour = 32768; /* 50% */
3902 cam->vp.hue = 32768; /* 50% */
3903 cam->vp.brightness = 32768; /* 50% */
3904 cam->vp.contrast = 32768; /* 50% */
3905 cam->vp.whiteness = 0; /* not used -> grayscale only */
3906 cam->vp.depth = 24; /* to be set by user */
3907 cam->vp.palette = VIDEO_PALETTE_RGB24; /* to be set by user */
3908
3909 cam->vc.x = 0;
3910 cam->vc.y = 0;
3911 cam->vc.width = 0;
3912 cam->vc.height = 0;
3913
3914 cam->vw.x = 0;
3915 cam->vw.y = 0;
3916 set_vw_size(cam);
3917 cam->vw.chromakey = 0;
3918 cam->vw.flags = 0;
3919 cam->vw.clipcount = 0;
3920 cam->vw.clips = NULL;
3921
3922 cam->cmd_queue = COMMAND_NONE;
3923 cam->first_frame = 1;
3924
3925 return;
3926}
3927
3928/* initialize cam_data structure */
3929static void init_camera_struct(struct cam_data *cam,
3930 struct cpia_camera_ops *ops )
3931{
3932 int i;
3933
3934 /* Default everything to 0 */
3935 memset(cam, 0, sizeof(struct cam_data));
3936
3937 cam->ops = ops;
3938 init_MUTEX(&cam->param_lock);
3939 init_MUTEX(&cam->busy_lock);
3940
3941 reset_camera_struct(cam);
3942
3943 cam->proc_entry = NULL;
3944
3945 memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template));
3946 cam->vdev.priv = cam;
3947
3948 cam->curframe = 0;
3949 for (i = 0; i < FRAME_NUM; i++) {
3950 cam->frame[i].width = 0;
3951 cam->frame[i].height = 0;
3952 cam->frame[i].state = FRAME_UNUSED;
3953 cam->frame[i].data = NULL;
3954 }
3955 cam->decompressed_frame.width = 0;
3956 cam->decompressed_frame.height = 0;
3957 cam->decompressed_frame.state = FRAME_UNUSED;
3958 cam->decompressed_frame.data = NULL;
3959}
3960
3961struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel)
3962{
3963 struct cam_data *camera;
3964
3965 if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL)
3966 return NULL;
3967
3968
3969 init_camera_struct( camera, ops );
3970 camera->lowlevel_data = lowlevel;
3971
3972 /* register v4l device */
3973 if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
3974 kfree(camera);
3975 printk(KERN_DEBUG "video_register_device failed\n");
3976 return NULL;
3977 }
3978
3979 /* get version information from camera: open/reset/close */
3980
3981 /* open cpia */
3982 if (camera->ops->open(camera->lowlevel_data))
3983 return camera;
3984
3985 /* reset the camera */
3986 if (reset_camera(camera) != 0) {
3987 camera->ops->close(camera->lowlevel_data);
3988 return camera;
3989 }
3990
3991 /* close cpia */
3992 camera->ops->close(camera->lowlevel_data);
3993
3994#ifdef CONFIG_PROC_FS
3995 create_proc_cpia_cam(camera);
3996#endif
3997
3998 printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
3999 camera->params.version.firmwareVersion,
4000 camera->params.version.firmwareRevision,
4001 camera->params.version.vcVersion,
4002 camera->params.version.vcRevision);
4003 printk(KERN_INFO " CPiA PnP-ID: %04x:%04x:%04x\n",
4004 camera->params.pnpID.vendor,
4005 camera->params.pnpID.product,
4006 camera->params.pnpID.deviceRevision);
4007 printk(KERN_INFO " VP-Version: %d.%d %04x\n",
4008 camera->params.vpVersion.vpVersion,
4009 camera->params.vpVersion.vpRevision,
4010 camera->params.vpVersion.cameraHeadID);
4011
4012 return camera;
4013}
4014
4015void cpia_unregister_camera(struct cam_data *cam)
4016{
4017 DBG("unregistering video\n");
4018 video_unregister_device(&cam->vdev);
4019 if (cam->open_count) {
4020 put_cam(cam->ops);
4021 DBG("camera open -- setting ops to NULL\n");
4022 cam->ops = NULL;
4023 }
4024
4025#ifdef CONFIG_PROC_FS
4026 DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor);
4027 destroy_proc_cpia_cam(cam);
4028#endif
4029 if (!cam->open_count) {
4030 DBG("freeing camera\n");
4031 kfree(cam);
4032 }
4033}
4034
4035static int __init cpia_init(void)
4036{
4037 printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
4038 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
4039
4040 printk(KERN_WARNING "Since in-kernel colorspace conversion is not "
4041 "allowed, it is disabled by default now. Users should fix the "
4042 "applications in case they don't work without conversion "
4043 "reenabled by setting the 'colorspace_conv' module "
4044 "parameter to 1");
4045
4046#ifdef CONFIG_PROC_FS
4047 proc_cpia_create();
4048#endif
4049
4050#ifdef CONFIG_VIDEO_CPIA_PP
4051 cpia_pp_init();
4052#endif
4053#ifdef CONFIG_VIDEO_CPIA_USB
4054 cpia_usb_init();
4055#endif
4056
4057 return 0;
4058}
4059
4060static void __exit cpia_exit(void)
4061{
4062#ifdef CONFIG_PROC_FS
4063 proc_cpia_destroy();
4064#endif
4065}
4066
4067module_init(cpia_init);
4068module_exit(cpia_exit);
4069
4070/* Exported symbols for modules. */
4071
4072EXPORT_SYMBOL(cpia_register_camera);
4073EXPORT_SYMBOL(cpia_unregister_camera);
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
new file mode 100644
index 000000000000..f629b693ee65
--- /dev/null
+++ b/drivers/media/video/cpia.h
@@ -0,0 +1,430 @@
1#ifndef cpia_h
2#define cpia_h
3
4/*
5 * CPiA Parallel Port Video4Linux driver
6 *
7 * Supports CPiA based parallel port Video Camera's.
8 *
9 * (C) Copyright 1999 Bas Huisman,
10 * Peter Pregler,
11 * Scott J. Bertin,
12 * VLSI Vision Ltd.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#define CPIA_MAJ_VER 1
30#define CPIA_MIN_VER 2
31#define CPIA_PATCH_VER 3
32
33#define CPIA_PP_MAJ_VER CPIA_MAJ_VER
34#define CPIA_PP_MIN_VER CPIA_MIN_VER
35#define CPIA_PP_PATCH_VER CPIA_PATCH_VER
36
37#define CPIA_USB_MAJ_VER CPIA_MAJ_VER
38#define CPIA_USB_MIN_VER CPIA_MIN_VER
39#define CPIA_USB_PATCH_VER CPIA_PATCH_VER
40
41#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */
42#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
43
44#ifdef __KERNEL__
45
46#include <asm/uaccess.h>
47#include <linux/videodev.h>
48#include <linux/list.h>
49#include <linux/smp_lock.h>
50
51struct cpia_camera_ops
52{
53 /* open sets privdata to point to structure for this camera.
54 * Returns negative value on error, otherwise 0.
55 */
56 int (*open)(void *privdata);
57
58 /* Registers callback function cb to be called with cbdata
59 * when an image is ready. If cb is NULL, only single image grabs
60 * should be used. cb should immediately call streamRead to read
61 * the data or data may be lost. Returns negative value on error,
62 * otherwise 0.
63 */
64 int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
65 void *cbdata);
66
67 /* transferCmd sends commands to the camera. command MUST point to
68 * an 8 byte buffer in kernel space. data can be NULL if no extra
69 * data is needed. The size of the data is given by the last 2
70 * bytes of command. data must also point to memory in kernel space.
71 * Returns negative value on error, otherwise 0.
72 */
73 int (*transferCmd)(void *privdata, u8 *command, u8 *data);
74
75 /* streamStart initiates stream capture mode.
76 * Returns negative value on error, otherwise 0.
77 */
78 int (*streamStart)(void *privdata);
79
80 /* streamStop terminates stream capture mode.
81 * Returns negative value on error, otherwise 0.
82 */
83 int (*streamStop)(void *privdata);
84
85 /* streamRead reads a frame from the camera. buffer points to a
86 * buffer large enough to hold a complete frame in kernel space.
87 * noblock indicates if this should be a non blocking read.
88 * Returns the number of bytes read, or negative value on error.
89 */
90 int (*streamRead)(void *privdata, u8 *buffer, int noblock);
91
92 /* close disables the device until open() is called again.
93 * Returns negative value on error, otherwise 0.
94 */
95 int (*close)(void *privdata);
96
97 /* If wait_for_stream_ready is non-zero, wait until the streamState
98 * is STREAM_READY before calling streamRead.
99 */
100 int wait_for_stream_ready;
101
102 /*
103 * Used to maintain lowlevel module usage counts
104 */
105 struct module *owner;
106};
107
108struct cpia_frame {
109 u8 *data;
110 int count;
111 int width;
112 int height;
113 volatile int state;
114};
115
116struct cam_params {
117 struct {
118 u8 firmwareVersion;
119 u8 firmwareRevision;
120 u8 vcVersion;
121 u8 vcRevision;
122 } version;
123 struct {
124 u16 vendor;
125 u16 product;
126 u16 deviceRevision;
127 } pnpID;
128 struct {
129 u8 vpVersion;
130 u8 vpRevision;
131 u16 cameraHeadID;
132 } vpVersion;
133 struct {
134 u8 systemState;
135 u8 grabState;
136 u8 streamState;
137 u8 fatalError;
138 u8 cmdError;
139 u8 debugFlags;
140 u8 vpStatus;
141 u8 errorCode;
142 } status;
143 struct {
144 u8 brightness;
145 u8 contrast;
146 u8 saturation;
147 } colourParams;
148 struct {
149 u8 gainMode;
150 u8 expMode;
151 u8 compMode;
152 u8 centreWeight;
153 u8 gain;
154 u8 fineExp;
155 u8 coarseExpLo;
156 u8 coarseExpHi;
157 u8 redComp;
158 u8 green1Comp;
159 u8 green2Comp;
160 u8 blueComp;
161 } exposure;
162 struct {
163 u8 balanceMode;
164 u8 redGain;
165 u8 greenGain;
166 u8 blueGain;
167 } colourBalance;
168 struct {
169 u8 divisor;
170 u8 baserate;
171 } sensorFps;
172 struct {
173 u8 gain1;
174 u8 gain2;
175 u8 gain4;
176 u8 gain8;
177 } apcor;
178 struct {
179 u8 disabled;
180 u8 flickerMode;
181 u8 coarseJump;
182 int allowableOverExposure;
183 } flickerControl;
184 struct {
185 u8 gain1;
186 u8 gain2;
187 u8 gain4;
188 u8 gain8;
189 } vlOffset;
190 struct {
191 u8 mode;
192 u8 decimation;
193 } compression;
194 struct {
195 u8 frTargeting;
196 u8 targetFR;
197 u8 targetQ;
198 } compressionTarget;
199 struct {
200 u8 yThreshold;
201 u8 uvThreshold;
202 } yuvThreshold;
203 struct {
204 u8 hysteresis;
205 u8 threshMax;
206 u8 smallStep;
207 u8 largeStep;
208 u8 decimationHysteresis;
209 u8 frDiffStepThresh;
210 u8 qDiffStepThresh;
211 u8 decimationThreshMod;
212 } compressionParams;
213 struct {
214 u8 videoSize; /* CIF/QCIF */
215 u8 subSample;
216 u8 yuvOrder;
217 } format;
218 struct { /* Intel QX3 specific data */
219 u8 qx3_detected; /* a QX3 is present */
220 u8 toplight; /* top light lit , R/W */
221 u8 bottomlight; /* bottom light lit, R/W */
222 u8 button; /* snapshot button pressed (R/O) */
223 u8 cradled; /* microscope is in cradle (R/O) */
224 } qx3;
225 struct {
226 u8 colStart; /* skip first 8*colStart pixels */
227 u8 colEnd; /* finish at 8*colEnd pixels */
228 u8 rowStart; /* skip first 4*rowStart lines */
229 u8 rowEnd; /* finish at 4*rowEnd lines */
230 } roi;
231 u8 ecpTiming;
232 u8 streamStartLine;
233};
234
235enum v4l_camstates {
236 CPIA_V4L_IDLE = 0,
237 CPIA_V4L_ERROR,
238 CPIA_V4L_COMMAND,
239 CPIA_V4L_GRABBING,
240 CPIA_V4L_STREAMING,
241 CPIA_V4L_STREAMING_PAUSED,
242};
243
244#define FRAME_NUM 2 /* double buffering for now */
245
246struct cam_data {
247 struct list_head cam_data_list;
248
249 struct semaphore busy_lock; /* guard against SMP multithreading */
250 struct cpia_camera_ops *ops; /* lowlevel driver operations */
251 void *lowlevel_data; /* private data for lowlevel driver */
252 u8 *raw_image; /* buffer for raw image data */
253 struct cpia_frame decompressed_frame;
254 /* buffer to hold decompressed frame */
255 int image_size; /* sizeof last decompressed image */
256 int open_count; /* # of process that have camera open */
257
258 /* camera status */
259 int fps; /* actual fps reported by the camera */
260 int transfer_rate; /* transfer rate from camera in kB/s */
261 u8 mainsFreq; /* for flicker control */
262
263 /* proc interface */
264 struct semaphore param_lock; /* params lock for this camera */
265 struct cam_params params; /* camera settings */
266 struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
267
268 /* v4l */
269 int video_size; /* VIDEO_SIZE_ */
270 volatile enum v4l_camstates camstate; /* v4l layer status */
271 struct video_device vdev; /* v4l videodev */
272 struct video_picture vp; /* v4l camera settings */
273 struct video_window vw; /* v4l capture area */
274 struct video_capture vc; /* v4l subcapture area */
275
276 /* mmap interface */
277 int curframe; /* the current frame to grab into */
278 u8 *frame_buf; /* frame buffer data */
279 struct cpia_frame frame[FRAME_NUM];
280 /* FRAME_NUM-buffering, so we need a array */
281
282 int first_frame;
283 int mmap_kludge; /* 'wrong' byte order for mmap */
284 volatile u32 cmd_queue; /* queued commands */
285 int exposure_status; /* EXPOSURE_* */
286 int exposure_count; /* number of frames at this status */
287};
288
289/* cpia_register_camera is called by low level driver for each camera.
290 * A unique camera number is returned, or a negative value on error */
291struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
292
293/* cpia_unregister_camera is called by low level driver when a camera
294 * is removed. This must not fail. */
295void cpia_unregister_camera(struct cam_data *cam);
296
297/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
298 * one byte 16bit DMA alignment
299 */
300#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
301
302/* constant value's */
303#define MAGIC_0 0x19
304#define MAGIC_1 0x68
305#define DATA_IN 0xC0
306#define DATA_OUT 0x40
307#define VIDEOSIZE_QCIF 0 /* 176x144 */
308#define VIDEOSIZE_CIF 1 /* 352x288 */
309#define VIDEOSIZE_SIF 2 /* 320x240 */
310#define VIDEOSIZE_QSIF 3 /* 160x120 */
311#define VIDEOSIZE_48_48 4 /* where no one has gone before, iconsize! */
312#define VIDEOSIZE_64_48 5
313#define VIDEOSIZE_128_96 6
314#define VIDEOSIZE_160_120 VIDEOSIZE_QSIF
315#define VIDEOSIZE_176_144 VIDEOSIZE_QCIF
316#define VIDEOSIZE_192_144 7
317#define VIDEOSIZE_224_168 8
318#define VIDEOSIZE_256_192 9
319#define VIDEOSIZE_288_216 10
320#define VIDEOSIZE_320_240 VIDEOSIZE_SIF
321#define VIDEOSIZE_352_288 VIDEOSIZE_CIF
322#define VIDEOSIZE_88_72 11 /* quarter CIF */
323#define SUBSAMPLE_420 0
324#define SUBSAMPLE_422 1
325#define YUVORDER_YUYV 0
326#define YUVORDER_UYVY 1
327#define NOT_COMPRESSED 0
328#define COMPRESSED 1
329#define NO_DECIMATION 0
330#define DECIMATION_ENAB 1
331#define EOI 0xff /* End Of Image */
332#define EOL 0xfd /* End Of Line */
333#define FRAME_HEADER_SIZE 64
334
335/* Image grab modes */
336#define CPIA_GRAB_SINGLE 0
337#define CPIA_GRAB_CONTINUOUS 1
338
339/* Compression parameters */
340#define CPIA_COMPRESSION_NONE 0
341#define CPIA_COMPRESSION_AUTO 1
342#define CPIA_COMPRESSION_MANUAL 2
343#define CPIA_COMPRESSION_TARGET_QUALITY 0
344#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
345
346/* Return offsets for GetCameraState */
347#define SYSTEMSTATE 0
348#define GRABSTATE 1
349#define STREAMSTATE 2
350#define FATALERROR 3
351#define CMDERROR 4
352#define DEBUGFLAGS 5
353#define VPSTATUS 6
354#define ERRORCODE 7
355
356/* SystemState */
357#define UNINITIALISED_STATE 0
358#define PASS_THROUGH_STATE 1
359#define LO_POWER_STATE 2
360#define HI_POWER_STATE 3
361#define WARM_BOOT_STATE 4
362
363/* GrabState */
364#define GRAB_IDLE 0
365#define GRAB_ACTIVE 1
366#define GRAB_DONE 2
367
368/* StreamState */
369#define STREAM_NOT_READY 0
370#define STREAM_READY 1
371#define STREAM_OPEN 2
372#define STREAM_PAUSED 3
373#define STREAM_FINISHED 4
374
375/* Fatal Error, CmdError, and DebugFlags */
376#define CPIA_FLAG 1
377#define SYSTEM_FLAG 2
378#define INT_CTRL_FLAG 4
379#define PROCESS_FLAG 8
380#define COM_FLAG 16
381#define VP_CTRL_FLAG 32
382#define CAPTURE_FLAG 64
383#define DEBUG_FLAG 128
384
385/* VPStatus */
386#define VP_STATE_OK 0x00
387
388#define VP_STATE_FAILED_VIDEOINIT 0x01
389#define VP_STATE_FAILED_AECACBINIT 0x02
390#define VP_STATE_AEC_MAX 0x04
391#define VP_STATE_ACB_BMAX 0x08
392
393#define VP_STATE_ACB_RMIN 0x10
394#define VP_STATE_ACB_GMIN 0x20
395#define VP_STATE_ACB_RMAX 0x40
396#define VP_STATE_ACB_GMAX 0x80
397
398/* default (minimum) compensation values */
399#define COMP_RED 220
400#define COMP_GREEN1 214
401#define COMP_GREEN2 COMP_GREEN1
402#define COMP_BLUE 230
403
404/* exposure status */
405#define EXPOSURE_VERY_LIGHT 0
406#define EXPOSURE_LIGHT 1
407#define EXPOSURE_NORMAL 2
408#define EXPOSURE_DARK 3
409#define EXPOSURE_VERY_DARK 4
410
411/* ErrorCode */
412#define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */
413#define ALOG(fmt,args...) printk(fmt, ##args)
414#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args)
415
416#ifdef _CPIA_DEBUG_
417#define ADBG(fmt,args...) printk(fmt, jiffies, ##args)
418#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __FUNCTION__, __LINE__ , ##args)
419#else
420#define DBG(fmn,args...) do {} while(0)
421#endif
422
423#define DEB_BYTE(p)\
424 DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
425 (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
426 (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
427
428#endif /* __KERNEL__ */
429
430#endif /* cpia_h */
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
new file mode 100644
index 000000000000..ddf184f95d80
--- /dev/null
+++ b/drivers/media/video/cpia_pp.c
@@ -0,0 +1,886 @@
1/*
2 * cpia_pp CPiA Parallel Port driver
3 *
4 * Supports CPiA based parallel port Video Camera's.
5 *
6 * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
7 * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>,
8 * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
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/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
26/* #define _CPIA_DEBUG_ 1 */
27
28#include <linux/config.h>
29
30#include <linux/module.h>
31#include <linux/init.h>
32
33#include <linux/kernel.h>
34#include <linux/parport.h>
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/workqueue.h>
38#include <linux/smp_lock.h>
39#include <linux/sched.h>
40
41#include <linux/kmod.h>
42
43/* #define _CPIA_DEBUG_ define for verbose debug output */
44#include "cpia.h"
45
46static int cpia_pp_open(void *privdata);
47static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
48 void *cbdata);
49static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
50static int cpia_pp_streamStart(void *privdata);
51static int cpia_pp_streamStop(void *privdata);
52static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
53static int cpia_pp_close(void *privdata);
54
55
56#define ABOUT "Parallel port driver for Vision CPiA based cameras"
57
58#define PACKET_LENGTH 8
59
60/* Magic numbers for defining port-device mappings */
61#define PPCPIA_PARPORT_UNSPEC -4
62#define PPCPIA_PARPORT_AUTO -3
63#define PPCPIA_PARPORT_OFF -2
64#define PPCPIA_PARPORT_NONE -1
65
66#ifdef MODULE
67static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
68static char *parport[PARPORT_MAX] = {NULL,};
69
70MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
71MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
72MODULE_LICENSE("GPL");
73
74module_param_array(parport, charp, NULL, 0);
75MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
76#else
77static int parport_nr[PARPORT_MAX] __initdata =
78 {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
79static int parport_ptr = 0;
80#endif
81
82struct pp_cam_entry {
83 struct pardevice *pdev;
84 struct parport *port;
85 struct work_struct cb_task;
86 int open_count;
87 wait_queue_head_t wq_stream;
88 /* image state flags */
89 int image_ready; /* we got an interrupt */
90 int image_complete; /* we have seen 4 EOI */
91
92 int streaming; /* we are in streaming mode */
93 int stream_irq;
94};
95
96static struct cpia_camera_ops cpia_pp_ops =
97{
98 cpia_pp_open,
99 cpia_pp_registerCallback,
100 cpia_pp_transferCmd,
101 cpia_pp_streamStart,
102 cpia_pp_streamStop,
103 cpia_pp_streamRead,
104 cpia_pp_close,
105 1,
106 THIS_MODULE
107};
108
109static LIST_HEAD(cam_list);
110static spinlock_t cam_list_lock_pp;
111
112/* FIXME */
113static void cpia_parport_enable_irq( struct parport *port ) {
114 parport_enable_irq(port);
115 mdelay(10);
116 return;
117}
118
119static void cpia_parport_disable_irq( struct parport *port ) {
120 parport_disable_irq(port);
121 mdelay(10);
122 return;
123}
124
125/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
126 * Link Flag during negotiation */
127#define UPLOAD_FLAG 0x08
128#define NIBBLE_TRANSFER 0x01
129#define ECP_TRANSFER 0x03
130
131#define PARPORT_CHUNK_SIZE PAGE_SIZE
132
133
134/****************************************************************************
135 *
136 * CPiA-specific low-level parport functions for nibble uploads
137 *
138 ***************************************************************************/
139/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
140/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
141
142static size_t cpia_read_nibble (struct parport *port,
143 void *buffer, size_t len,
144 int flags)
145{
146 /* adapted verbatim, with one change, from
147 parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
148
149 unsigned char *buf = buffer;
150 int i;
151 unsigned char byte = 0;
152
153 len *= 2; /* in nibbles */
154 for (i=0; i < len; i++) {
155 unsigned char nibble;
156
157 /* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
158 * after every second nibble to signal that more
159 * data is available. (the total number of Bytes that
160 * should be sent is known; if too few are received, an error
161 * will be recorded after a timeout).
162 * This is incompatible with parport_ieee1284_read_nibble(),
163 * which expects to find nFault LO after every second nibble.
164 */
165
166 /* Solution: modify cpia_read_nibble to only check for
167 * nDataAvail before the first nibble is sent.
168 */
169
170 /* Does the error line indicate end of data? */
171 if (((i /*& 1*/) == 0) &&
172 (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
173 port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
174 DBG("%s: No more nibble data (%d bytes)\n",
175 port->name, i/2);
176
177 /* Go to reverse idle phase. */
178 parport_frob_control (port,
179 PARPORT_CONTROL_AUTOFD,
180 PARPORT_CONTROL_AUTOFD);
181 port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
182 break;
183 }
184
185 /* Event 7: Set nAutoFd low. */
186 parport_frob_control (port,
187 PARPORT_CONTROL_AUTOFD,
188 PARPORT_CONTROL_AUTOFD);
189
190 /* Event 9: nAck goes low. */
191 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
192 if (parport_wait_peripheral (port,
193 PARPORT_STATUS_ACK, 0)) {
194 /* Timeout -- no more data? */
195 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
196 port->name, i/2);
197 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
198 break;
199 }
200
201
202 /* Read a nibble. */
203 nibble = parport_read_status (port) >> 3;
204 nibble &= ~8;
205 if ((nibble & 0x10) == 0)
206 nibble |= 8;
207 nibble &= 0xf;
208
209 /* Event 10: Set nAutoFd high. */
210 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
211
212 /* Event 11: nAck goes high. */
213 if (parport_wait_peripheral (port,
214 PARPORT_STATUS_ACK,
215 PARPORT_STATUS_ACK)) {
216 /* Timeout -- no more data? */
217 DBG("%s: Nibble timeout at event 11\n",
218 port->name);
219 break;
220 }
221
222 if (i & 1) {
223 /* Second nibble */
224 byte |= nibble << 4;
225 *buf++ = byte;
226 } else
227 byte = nibble;
228 }
229
230 i /= 2; /* i is now in bytes */
231
232 if (i == len) {
233 /* Read the last nibble without checking data avail. */
234 port = port->physport;
235 if (parport_read_status (port) & PARPORT_STATUS_ERROR)
236 port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
237 else
238 port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
239 }
240
241 return i;
242}
243
244/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
245 * (See CPiA Data sheet p. 31)
246 *
247 * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
248 * nonstandard variant of nibble mode which allows the same (mediocre)
249 * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
250 * parallel ports, but works also for non-TRISTATE-capable ports.
251 * (Standard nibble mode only send 4 bits per cycle)
252 *
253 */
254
255static size_t cpia_read_nibble_stream(struct parport *port,
256 void *buffer, size_t len,
257 int flags)
258{
259 int i;
260 unsigned char *buf = buffer;
261 int endseen = 0;
262
263 for (i=0; i < len; i++) {
264 unsigned char nibble[2], byte = 0;
265 int j;
266
267 /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
268 if (endseen > 3 )
269 break;
270
271 /* Event 7: Set nAutoFd low. */
272 parport_frob_control (port,
273 PARPORT_CONTROL_AUTOFD,
274 PARPORT_CONTROL_AUTOFD);
275
276 /* Event 9: nAck goes low. */
277 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
278 if (parport_wait_peripheral (port,
279 PARPORT_STATUS_ACK, 0)) {
280 /* Timeout -- no more data? */
281 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
282 port->name, i/2);
283 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
284 break;
285 }
286
287 /* Read lower nibble */
288 nibble[0] = parport_read_status (port) >>3;
289
290 /* Event 10: Set nAutoFd high. */
291 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
292
293 /* Event 11: nAck goes high. */
294 if (parport_wait_peripheral (port,
295 PARPORT_STATUS_ACK,
296 PARPORT_STATUS_ACK)) {
297 /* Timeout -- no more data? */
298 DBG("%s: Nibble timeout at event 11\n",
299 port->name);
300 break;
301 }
302
303 /* Read upper nibble */
304 nibble[1] = parport_read_status (port) >>3;
305
306 /* reassemble the byte */
307 for (j = 0; j < 2 ; j++ ) {
308 nibble[j] &= ~8;
309 if ((nibble[j] & 0x10) == 0)
310 nibble[j] |= 8;
311 nibble[j] &= 0xf;
312 }
313 byte = (nibble[0] |(nibble[1] << 4));
314 *buf++ = byte;
315
316 if(byte == EOI)
317 endseen++;
318 else
319 endseen = 0;
320 }
321 return i;
322}
323
324/****************************************************************************
325 *
326 * EndTransferMode
327 *
328 ***************************************************************************/
329static void EndTransferMode(struct pp_cam_entry *cam)
330{
331 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
332}
333
334/****************************************************************************
335 *
336 * ForwardSetup
337 *
338 ***************************************************************************/
339static int ForwardSetup(struct pp_cam_entry *cam)
340{
341 int retry;
342
343 /* The CPiA uses ECP protocol for Downloads from the Host to the camera.
344 * This will be software-emulated if ECP hardware is not present
345 */
346
347 /* the usual camera maximum response time is 10ms, but after receiving
348 * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
349
350 for(retry = 0; retry < 4; ++retry) {
351 if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
352 break;
353 }
354 mdelay(10);
355 }
356 if(retry == 4) {
357 DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
358 return -1;
359 }
360 return 0;
361}
362/****************************************************************************
363 *
364 * ReverseSetup
365 *
366 ***************************************************************************/
367static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
368{
369 int retry;
370 int upload_mode, mode = IEEE1284_MODE_ECP;
371 int transfer_mode = ECP_TRANSFER;
372
373 if (!(cam->port->modes & PARPORT_MODE_ECP) &&
374 !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
375 mode = IEEE1284_MODE_NIBBLE;
376 transfer_mode = NIBBLE_TRANSFER;
377 }
378
379 upload_mode = mode;
380 if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
381
382 /* the usual camera maximum response time is 10ms, but after
383 * receiving some commands, it needs up to 40ms. */
384
385 for(retry = 0; retry < 4; ++retry) {
386 if(!parport_negotiate(cam->port, mode)) {
387 break;
388 }
389 mdelay(10);
390 }
391 if(retry == 4) {
392 if(extensibility)
393 DBG("Unable to negotiate upload extensibility mode\n");
394 else
395 DBG("Unable to negotiate upload mode\n");
396 return -1;
397 }
398 if(extensibility) cam->port->ieee1284.mode = upload_mode;
399 return 0;
400}
401
402/****************************************************************************
403 *
404 * WritePacket
405 *
406 ***************************************************************************/
407static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
408{
409 int retval=0;
410 int size_written;
411
412 if (packet == NULL) {
413 return -EINVAL;
414 }
415 if (ForwardSetup(cam)) {
416 DBG("Write failed in setup\n");
417 return -EIO;
418 }
419 size_written = parport_write(cam->port, packet, size);
420 if(size_written != size) {
421 DBG("Write failed, wrote %d/%d\n", size_written, size);
422 retval = -EIO;
423 }
424 EndTransferMode(cam);
425 return retval;
426}
427
428/****************************************************************************
429 *
430 * ReadPacket
431 *
432 ***************************************************************************/
433static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
434{
435 int retval=0;
436
437 if (packet == NULL) {
438 return -EINVAL;
439 }
440 if (ReverseSetup(cam, 0)) {
441 return -EIO;
442 }
443
444 /* support for CPiA variant nibble reads */
445 if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
446 if(cpia_read_nibble(cam->port, packet, size, 0) != size)
447 retval = -EIO;
448 } else {
449 if(parport_read(cam->port, packet, size) != size)
450 retval = -EIO;
451 }
452 EndTransferMode(cam);
453 return retval;
454}
455
456/****************************************************************************
457 *
458 * cpia_pp_streamStart
459 *
460 ***************************************************************************/
461static int cpia_pp_streamStart(void *privdata)
462{
463 struct pp_cam_entry *cam = privdata;
464 DBG("\n");
465 cam->streaming=1;
466 cam->image_ready=0;
467 //if (ReverseSetup(cam,1)) return -EIO;
468 if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
469 return 0;
470}
471
472/****************************************************************************
473 *
474 * cpia_pp_streamStop
475 *
476 ***************************************************************************/
477static int cpia_pp_streamStop(void *privdata)
478{
479 struct pp_cam_entry *cam = privdata;
480
481 DBG("\n");
482 cam->streaming=0;
483 cpia_parport_disable_irq(cam->port);
484 //EndTransferMode(cam);
485
486 return 0;
487}
488
489/****************************************************************************
490 *
491 * cpia_pp_streamRead
492 *
493 ***************************************************************************/
494static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
495{
496 int bytes_read;
497
498 /* support for CPiA variant "nibble stream" reads */
499 if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
500 bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
501 else {
502 int new_bytes;
503 for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
504 new_bytes = parport_read(port, buffer+bytes_read,
505 len-bytes_read);
506 if(new_bytes < 0) break;
507 }
508 }
509 return bytes_read;
510}
511
512static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
513{
514 struct pp_cam_entry *cam = privdata;
515 int read_bytes = 0;
516 int i, endseen, block_size, new_bytes;
517
518 if(cam == NULL) {
519 DBG("Internal driver error: cam is NULL\n");
520 return -EINVAL;
521 }
522 if(buffer == NULL) {
523 DBG("Internal driver error: buffer is NULL\n");
524 return -EINVAL;
525 }
526 //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
527 if( cam->stream_irq ) {
528 DBG("%d\n", cam->image_ready);
529 cam->image_ready--;
530 }
531 cam->image_complete=0;
532 if (0/*cam->streaming*/) {
533 if(!cam->image_ready) {
534 if(noblock) return -EWOULDBLOCK;
535 interruptible_sleep_on(&cam->wq_stream);
536 if( signal_pending(current) ) return -EINTR;
537 DBG("%d\n", cam->image_ready);
538 }
539 } else {
540 if (ReverseSetup(cam, 1)) {
541 DBG("unable to ReverseSetup\n");
542 return -EIO;
543 }
544 }
545 endseen = 0;
546 block_size = PARPORT_CHUNK_SIZE;
547 while( !cam->image_complete ) {
548 cond_resched();
549
550 new_bytes = cpia_pp_read(cam->port, buffer, block_size );
551 if( new_bytes <= 0 ) {
552 break;
553 }
554 i=-1;
555 while(++i<new_bytes && endseen<4) {
556 if(*buffer==EOI) {
557 endseen++;
558 } else {
559 endseen=0;
560 }
561 buffer++;
562 }
563 read_bytes += i;
564 if( endseen==4 ) {
565 cam->image_complete=1;
566 break;
567 }
568 if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
569 block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
570 }
571 }
572 EndTransferMode(cam);
573 return cam->image_complete ? read_bytes : -EIO;
574}
575/****************************************************************************
576 *
577 * cpia_pp_transferCmd
578 *
579 ***************************************************************************/
580static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
581{
582 int err;
583 int retval=0;
584 int databytes;
585 struct pp_cam_entry *cam = privdata;
586
587 if(cam == NULL) {
588 DBG("Internal driver error: cam is NULL\n");
589 return -EINVAL;
590 }
591 if(command == NULL) {
592 DBG("Internal driver error: command is NULL\n");
593 return -EINVAL;
594 }
595 databytes = (((int)command[7])<<8) | command[6];
596 if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
597 DBG("Error writing command\n");
598 return err;
599 }
600 if(command[0] == DATA_IN) {
601 u8 buffer[8];
602 if(data == NULL) {
603 DBG("Internal driver error: data is NULL\n");
604 return -EINVAL;
605 }
606 if((err = ReadPacket(cam, buffer, 8)) < 0) {
607 DBG("Error reading command result\n");
608 return err;
609 }
610 memcpy(data, buffer, databytes);
611 } else if(command[0] == DATA_OUT) {
612 if(databytes > 0) {
613 if(data == NULL) {
614 DBG("Internal driver error: data is NULL\n");
615 retval = -EINVAL;
616 } else {
617 if((err=WritePacket(cam, data, databytes)) < 0){
618 DBG("Error writing command data\n");
619 return err;
620 }
621 }
622 }
623 } else {
624 DBG("Unexpected first byte of command: %x\n", command[0]);
625 retval = -EINVAL;
626 }
627 return retval;
628}
629
630/****************************************************************************
631 *
632 * cpia_pp_open
633 *
634 ***************************************************************************/
635static int cpia_pp_open(void *privdata)
636{
637 struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
638
639 if (cam == NULL)
640 return -EINVAL;
641
642 if(cam->open_count == 0) {
643 if (parport_claim(cam->pdev)) {
644 DBG("failed to claim the port\n");
645 return -EBUSY;
646 }
647 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
648 parport_data_forward(cam->port);
649 parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
650 udelay(50);
651 parport_write_control(cam->port,
652 PARPORT_CONTROL_SELECT
653 | PARPORT_CONTROL_INIT);
654 }
655
656 ++cam->open_count;
657
658 return 0;
659}
660
661/****************************************************************************
662 *
663 * cpia_pp_registerCallback
664 *
665 ***************************************************************************/
666static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
667{
668 struct pp_cam_entry *cam = privdata;
669 int retval = 0;
670
671 if(cam->port->irq != PARPORT_IRQ_NONE) {
672 INIT_WORK(&cam->cb_task, cb, cbdata);
673 } else {
674 retval = -1;
675 }
676 return retval;
677}
678
679/****************************************************************************
680 *
681 * cpia_pp_close
682 *
683 ***************************************************************************/
684static int cpia_pp_close(void *privdata)
685{
686 struct pp_cam_entry *cam = privdata;
687 if (--cam->open_count == 0) {
688 parport_release(cam->pdev);
689 }
690 return 0;
691}
692
693/****************************************************************************
694 *
695 * cpia_pp_register
696 *
697 ***************************************************************************/
698static int cpia_pp_register(struct parport *port)
699{
700 struct pardevice *pdev = NULL;
701 struct pp_cam_entry *cam;
702 struct cam_data *cpia;
703
704 if (!(port->modes & PARPORT_MODE_PCSPP)) {
705 LOG("port is not supported by CPiA driver\n");
706 return -ENXIO;
707 }
708
709 cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
710 if (cam == NULL) {
711 LOG("failed to allocate camera structure\n");
712 return -ENOMEM;
713 }
714 memset(cam,0,sizeof(struct pp_cam_entry));
715
716 pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
717 NULL, 0, cam);
718
719 if (!pdev) {
720 LOG("failed to parport_register_device\n");
721 kfree(cam);
722 return -ENXIO;
723 }
724
725 cam->pdev = pdev;
726 cam->port = port;
727 init_waitqueue_head(&cam->wq_stream);
728
729 cam->streaming = 0;
730 cam->stream_irq = 0;
731
732 if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
733 LOG("failed to cpia_register_camera\n");
734 parport_unregister_device(pdev);
735 kfree(cam);
736 return -ENXIO;
737 }
738 spin_lock( &cam_list_lock_pp );
739 list_add( &cpia->cam_data_list, &cam_list );
740 spin_unlock( &cam_list_lock_pp );
741
742 return 0;
743}
744
745static void cpia_pp_detach (struct parport *port)
746{
747 struct list_head *tmp;
748 struct cam_data *cpia = NULL;
749 struct pp_cam_entry *cam;
750
751 spin_lock( &cam_list_lock_pp );
752 list_for_each (tmp, &cam_list) {
753 cpia = list_entry(tmp, struct cam_data, cam_data_list);
754 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
755 if (cam && cam->port->number == port->number) {
756 list_del(&cpia->cam_data_list);
757 break;
758 }
759 cpia = NULL;
760 }
761 spin_unlock( &cam_list_lock_pp );
762
763 if (!cpia) {
764 DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
765 return;
766 }
767
768 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
769 cpia_unregister_camera(cpia);
770 if(cam->open_count > 0)
771 cpia_pp_close(cam);
772 parport_unregister_device(cam->pdev);
773 cpia->lowlevel_data = NULL;
774 kfree(cam);
775}
776
777static void cpia_pp_attach (struct parport *port)
778{
779 unsigned int i;
780
781 switch (parport_nr[0])
782 {
783 case PPCPIA_PARPORT_UNSPEC:
784 case PPCPIA_PARPORT_AUTO:
785 if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
786 port->probe_info[0].cmdset == NULL ||
787 strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
788 return;
789
790 cpia_pp_register(port);
791
792 break;
793
794 default:
795 for (i = 0; i < PARPORT_MAX; ++i) {
796 if (port->number == parport_nr[i]) {
797 cpia_pp_register(port);
798 break;
799 }
800 }
801 break;
802 }
803}
804
805static struct parport_driver cpia_pp_driver = {
806 .name = "cpia_pp",
807 .attach = cpia_pp_attach,
808 .detach = cpia_pp_detach,
809};
810
811int cpia_pp_init(void)
812{
813 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
814 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
815
816 if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
817 printk(" disabled\n");
818 return 0;
819 }
820
821 spin_lock_init( &cam_list_lock_pp );
822
823 if (parport_register_driver (&cpia_pp_driver)) {
824 LOG ("unable to register with parport\n");
825 return -EIO;
826 }
827 return 0;
828}
829
830#ifdef MODULE
831int init_module(void)
832{
833 if (parport[0]) {
834 /* The user gave some parameters. Let's see what they were. */
835 if (!strncmp(parport[0], "auto", 4)) {
836 parport_nr[0] = PPCPIA_PARPORT_AUTO;
837 } else {
838 int n;
839 for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
840 if (!strncmp(parport[n], "none", 4)) {
841 parport_nr[n] = PPCPIA_PARPORT_NONE;
842 } else {
843 char *ep;
844 unsigned long r = simple_strtoul(parport[n], &ep, 0);
845 if (ep != parport[n]) {
846 parport_nr[n] = r;
847 } else {
848 LOG("bad port specifier `%s'\n", parport[n]);
849 return -ENODEV;
850 }
851 }
852 }
853 }
854 }
855 return cpia_pp_init();
856}
857
858void cleanup_module(void)
859{
860 parport_unregister_driver (&cpia_pp_driver);
861 return;
862}
863
864#else /* !MODULE */
865
866static int __init cpia_pp_setup(char *str)
867{
868 if (!strncmp(str, "parport", 7)) {
869 int n = simple_strtoul(str + 7, NULL, 10);
870 if (parport_ptr < PARPORT_MAX) {
871 parport_nr[parport_ptr++] = n;
872 } else {
873 LOG("too many ports, %s ignored.\n", str);
874 }
875 } else if (!strcmp(str, "auto")) {
876 parport_nr[0] = PPCPIA_PARPORT_AUTO;
877 } else if (!strcmp(str, "none")) {
878 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
879 }
880
881 return 0;
882}
883
884__setup("cpia_pp=", cpia_pp_setup);
885
886#endif /* !MODULE */
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
new file mode 100644
index 000000000000..cdda423386c5
--- /dev/null
+++ b/drivers/media/video/cpia_usb.c
@@ -0,0 +1,662 @@
1/*
2 * cpia_usb CPiA USB driver
3 *
4 * Supports CPiA based parallel port Video Camera's.
5 *
6 * Copyright (C) 1999 Jochen Scharrlach <Jochen.Scharrlach@schwaben.de>
7 * Copyright (C) 1999, 2000 Johannes Erdfelt <johannes@erdfelt.com>
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/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
25/* #define _CPIA_DEBUG_ 1 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/wait.h>
31#include <linux/list.h>
32#include <linux/slab.h>
33#include <linux/vmalloc.h>
34#include <linux/usb.h>
35
36#include "cpia.h"
37
38#define USB_REQ_CPIA_GRAB_FRAME 0xC1
39#define USB_REQ_CPIA_UPLOAD_FRAME 0xC2
40#define WAIT_FOR_NEXT_FRAME 0
41#define FORCE_FRAME_UPLOAD 1
42
43#define FRAMES_PER_DESC 10
44#define FRAME_SIZE_PER_DESC 960 /* Shouldn't be hardcoded */
45#define CPIA_NUMSBUF 2
46#define STREAM_BUF_SIZE (PAGE_SIZE * 4)
47#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2)
48
49struct cpia_sbuf {
50 char *data;
51 struct urb *urb;
52};
53
54#define FRAMEBUF_LEN (CPIA_MAX_FRAME_SIZE+100)
55enum framebuf_status {
56 FRAME_EMPTY,
57 FRAME_READING,
58 FRAME_READY,
59 FRAME_ERROR,
60};
61
62struct framebuf {
63 int length;
64 enum framebuf_status status;
65 u8 data[FRAMEBUF_LEN];
66 struct framebuf *next;
67};
68
69struct usb_cpia {
70 /* Device structure */
71 struct usb_device *dev;
72
73 unsigned char iface;
74 wait_queue_head_t wq_stream;
75
76 int cursbuf; /* Current receiving sbuf */
77 struct cpia_sbuf sbuf[CPIA_NUMSBUF]; /* Double buffering */
78
79 int streaming;
80 int open;
81 int present;
82 struct framebuf *buffers[3];
83 struct framebuf *curbuff, *workbuff;
84};
85
86static int cpia_usb_open(void *privdata);
87static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
88 void *cbdata);
89static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
90static int cpia_usb_streamStart(void *privdata);
91static int cpia_usb_streamStop(void *privdata);
92static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock);
93static int cpia_usb_close(void *privdata);
94
95#define ABOUT "USB driver for Vision CPiA based cameras"
96
97static struct cpia_camera_ops cpia_usb_ops = {
98 cpia_usb_open,
99 cpia_usb_registerCallback,
100 cpia_usb_transferCmd,
101 cpia_usb_streamStart,
102 cpia_usb_streamStop,
103 cpia_usb_streamRead,
104 cpia_usb_close,
105 0,
106 THIS_MODULE
107};
108
109static LIST_HEAD(cam_list);
110static spinlock_t cam_list_lock_usb;
111
112static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
113{
114 int i;
115 char *cdata;
116 struct usb_cpia *ucpia;
117
118 if (!urb || !urb->context)
119 return;
120
121 ucpia = (struct usb_cpia *) urb->context;
122
123 if (!ucpia->dev || !ucpia->streaming || !ucpia->present || !ucpia->open)
124 return;
125
126 if (ucpia->workbuff->status == FRAME_EMPTY) {
127 ucpia->workbuff->status = FRAME_READING;
128 ucpia->workbuff->length = 0;
129 }
130
131 for (i = 0; i < urb->number_of_packets; i++) {
132 int n = urb->iso_frame_desc[i].actual_length;
133 int st = urb->iso_frame_desc[i].status;
134
135 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
136
137 if (st)
138 printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n", i, n, st);
139
140 if (FRAMEBUF_LEN < ucpia->workbuff->length + n) {
141 printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
142 return;
143 }
144
145 if (n) {
146 if ((ucpia->workbuff->length > 0) ||
147 (0x19 == cdata[0] && 0x68 == cdata[1])) {
148 memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
149 ucpia->workbuff->length += n;
150 } else
151 DBG("Ignoring packet!\n");
152 } else {
153 if (ucpia->workbuff->length > 4 &&
154 0xff == ucpia->workbuff->data[ucpia->workbuff->length-1] &&
155 0xff == ucpia->workbuff->data[ucpia->workbuff->length-2] &&
156 0xff == ucpia->workbuff->data[ucpia->workbuff->length-3] &&
157 0xff == ucpia->workbuff->data[ucpia->workbuff->length-4]) {
158 ucpia->workbuff->status = FRAME_READY;
159 ucpia->curbuff = ucpia->workbuff;
160 ucpia->workbuff = ucpia->workbuff->next;
161 ucpia->workbuff->status = FRAME_EMPTY;
162 ucpia->workbuff->length = 0;
163
164 if (waitqueue_active(&ucpia->wq_stream))
165 wake_up_interruptible(&ucpia->wq_stream);
166 }
167 }
168 }
169
170 /* resubmit */
171 urb->dev = ucpia->dev;
172 if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
173 printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __FUNCTION__, i);
174}
175
176static int cpia_usb_open(void *privdata)
177{
178 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
179 struct urb *urb;
180 int ret, retval = 0, fx, err;
181
182 if (!ucpia)
183 return -EINVAL;
184
185 ucpia->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
186 if (!ucpia->sbuf[0].data)
187 return -EINVAL;
188
189 ucpia->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
190 if (!ucpia->sbuf[1].data) {
191 retval = -EINVAL;
192 goto error_0;
193 }
194
195 ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
196 if (ret < 0) {
197 printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
198 retval = -EBUSY;
199 goto error_1;
200 }
201
202 ucpia->buffers[0]->status = FRAME_EMPTY;
203 ucpia->buffers[0]->length = 0;
204 ucpia->buffers[1]->status = FRAME_EMPTY;
205 ucpia->buffers[1]->length = 0;
206 ucpia->buffers[2]->status = FRAME_EMPTY;
207 ucpia->buffers[2]->length = 0;
208 ucpia->curbuff = ucpia->buffers[0];
209 ucpia->workbuff = ucpia->buffers[1];
210
211 /* We double buffer the Iso lists, and also know the polling
212 * interval is every frame (1 == (1 << (bInterval -1))).
213 */
214 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
215 if (!urb) {
216 printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
217 retval = -ENOMEM;
218 goto error_1;
219 }
220
221 ucpia->sbuf[0].urb = urb;
222 urb->dev = ucpia->dev;
223 urb->context = ucpia;
224 urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
225 urb->transfer_flags = URB_ISO_ASAP;
226 urb->transfer_buffer = ucpia->sbuf[0].data;
227 urb->complete = cpia_usb_complete;
228 urb->number_of_packets = FRAMES_PER_DESC;
229 urb->interval = 1;
230 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
231 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
232 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
233 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
234 }
235
236 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
237 if (!urb) {
238 printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 1\n");
239 retval = -ENOMEM;
240 goto error_urb0;
241 }
242
243 ucpia->sbuf[1].urb = urb;
244 urb->dev = ucpia->dev;
245 urb->context = ucpia;
246 urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
247 urb->transfer_flags = URB_ISO_ASAP;
248 urb->transfer_buffer = ucpia->sbuf[1].data;
249 urb->complete = cpia_usb_complete;
250 urb->number_of_packets = FRAMES_PER_DESC;
251 urb->interval = 1;
252 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
253 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
254 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
255 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
256 }
257
258 /* queue the ISO urbs, and resubmit in the completion handler */
259 err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL);
260 if (err) {
261 printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
262 err);
263 goto error_urb1;
264 }
265 err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL);
266 if (err) {
267 printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
268 err);
269 goto error_urb1;
270 }
271
272 ucpia->streaming = 1;
273 ucpia->open = 1;
274
275 return 0;
276
277error_urb1: /* free urb 1 */
278 usb_free_urb(ucpia->sbuf[1].urb);
279 ucpia->sbuf[1].urb = NULL;
280error_urb0: /* free urb 0 */
281 usb_free_urb(ucpia->sbuf[0].urb);
282 ucpia->sbuf[0].urb = NULL;
283error_1:
284 kfree (ucpia->sbuf[1].data);
285 ucpia->sbuf[1].data = NULL;
286error_0:
287 kfree (ucpia->sbuf[0].data);
288 ucpia->sbuf[0].data = NULL;
289
290 return retval;
291}
292
293//
294// convenience functions
295//
296
297/****************************************************************************
298 *
299 * WritePacket
300 *
301 ***************************************************************************/
302static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_t size)
303{
304 if (!packet)
305 return -EINVAL;
306
307 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
308 packet[1] + (packet[0] << 8),
309 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
310 packet[2] + (packet[3] << 8),
311 packet[4] + (packet[5] << 8), buf, size, 1000);
312}
313
314/****************************************************************************
315 *
316 * ReadPacket
317 *
318 ***************************************************************************/
319static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size)
320{
321 if (!packet || size <= 0)
322 return -EINVAL;
323
324 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
325 packet[1] + (packet[0] << 8),
326 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
327 packet[2] + (packet[3] << 8),
328 packet[4] + (packet[5] << 8), buf, size, 1000);
329}
330
331static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data)
332{
333 int err = 0;
334 int databytes;
335 struct usb_cpia *ucpia = (struct usb_cpia *)privdata;
336 struct usb_device *udev = ucpia->dev;
337
338 if (!udev) {
339 DBG("Internal driver error: udev is NULL\n");
340 return -EINVAL;
341 }
342
343 if (!command) {
344 DBG("Internal driver error: command is NULL\n");
345 return -EINVAL;
346 }
347
348 databytes = (((int)command[7])<<8) | command[6];
349
350 if (command[0] == DATA_IN) {
351 u8 buffer[8];
352
353 if (!data) {
354 DBG("Internal driver error: data is NULL\n");
355 return -EINVAL;
356 }
357
358 err = ReadPacket(udev, command, buffer, 8);
359 if (err < 0)
360 return err;
361
362 memcpy(data, buffer, databytes);
363 } else if(command[0] == DATA_OUT)
364 WritePacket(udev, command, data, databytes);
365 else {
366 DBG("Unexpected first byte of command: %x\n", command[0]);
367 err = -EINVAL;
368 }
369
370 return 0;
371}
372
373static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
374 void *cbdata)
375{
376 return -ENODEV;
377}
378
379static int cpia_usb_streamStart(void *privdata)
380{
381 return -ENODEV;
382}
383
384static int cpia_usb_streamStop(void *privdata)
385{
386 return -ENODEV;
387}
388
389static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
390{
391 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
392 struct framebuf *mybuff;
393
394 if (!ucpia || !ucpia->present)
395 return -1;
396
397 if (ucpia->curbuff->status != FRAME_READY)
398 interruptible_sleep_on(&ucpia->wq_stream);
399 else
400 DBG("Frame already waiting!\n");
401
402 mybuff = ucpia->curbuff;
403
404 if (!mybuff)
405 return -1;
406
407 if (mybuff->status != FRAME_READY || mybuff->length < 4) {
408 DBG("Something went wrong!\n");
409 return -1;
410 }
411
412 memcpy(frame, mybuff->data, mybuff->length);
413 mybuff->status = FRAME_EMPTY;
414
415/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
416/* mybuff->length, frame[0], frame[1], */
417/* frame[mybuff->length-4], frame[mybuff->length-3], */
418/* frame[mybuff->length-2], frame[mybuff->length-1]); */
419
420 return mybuff->length;
421}
422
423static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
424{
425 if (!ucpia->streaming)
426 return;
427
428 ucpia->streaming = 0;
429
430 /* Set packet size to 0 */
431 if (try) {
432 int ret;
433
434 ret = usb_set_interface(ucpia->dev, ucpia->iface, 0);
435 if (ret < 0) {
436 printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret);
437 return;
438 }
439 }
440
441 /* Unschedule all of the iso td's */
442 if (ucpia->sbuf[1].urb) {
443 usb_kill_urb(ucpia->sbuf[1].urb);
444 usb_free_urb(ucpia->sbuf[1].urb);
445 ucpia->sbuf[1].urb = NULL;
446 }
447
448 if (ucpia->sbuf[1].data) {
449 kfree(ucpia->sbuf[1].data);
450 ucpia->sbuf[1].data = NULL;
451 }
452
453 if (ucpia->sbuf[0].urb) {
454 usb_kill_urb(ucpia->sbuf[0].urb);
455 usb_free_urb(ucpia->sbuf[0].urb);
456 ucpia->sbuf[0].urb = NULL;
457 }
458
459 if (ucpia->sbuf[0].data) {
460 kfree(ucpia->sbuf[0].data);
461 ucpia->sbuf[0].data = NULL;
462 }
463}
464
465static int cpia_usb_close(void *privdata)
466{
467 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
468
469 if(!ucpia)
470 return -ENODEV;
471
472 ucpia->open = 0;
473
474 /* ucpia->present = 0 protects against trying to reset the
475 * alt setting if camera is physically disconnected while open */
476 cpia_usb_free_resources(ucpia, ucpia->present);
477
478 return 0;
479}
480
481int cpia_usb_init(void)
482{
483 /* return -ENODEV; */
484 return 0;
485}
486
487/* Probing and initializing */
488
489static int cpia_probe(struct usb_interface *intf,
490 const struct usb_device_id *id)
491{
492 struct usb_device *udev = interface_to_usbdev(intf);
493 struct usb_host_interface *interface;
494 struct usb_cpia *ucpia;
495 struct cam_data *cam;
496 int ret;
497
498 /* A multi-config CPiA camera? */
499 if (udev->descriptor.bNumConfigurations != 1)
500 return -ENODEV;
501
502 interface = intf->cur_altsetting;
503
504 printk(KERN_INFO "USB CPiA camera found\n");
505
506 ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL);
507 if (!ucpia) {
508 printk(KERN_ERR "couldn't kmalloc cpia struct\n");
509 return -ENOMEM;
510 }
511
512 memset(ucpia, 0, sizeof(*ucpia));
513
514 ucpia->dev = udev;
515 ucpia->iface = interface->desc.bInterfaceNumber;
516 init_waitqueue_head(&ucpia->wq_stream);
517
518 ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));
519 if (!ucpia->buffers[0]) {
520 printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");
521 goto fail_alloc_0;
522 }
523
524 ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));
525 if (!ucpia->buffers[1]) {
526 printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");
527 goto fail_alloc_1;
528 }
529
530 ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));
531 if (!ucpia->buffers[2]) {
532 printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");
533 goto fail_alloc_2;
534 }
535
536 ucpia->buffers[0]->next = ucpia->buffers[1];
537 ucpia->buffers[1]->next = ucpia->buffers[2];
538 ucpia->buffers[2]->next = ucpia->buffers[0];
539
540 ret = usb_set_interface(udev, ucpia->iface, 0);
541 if (ret < 0) {
542 printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);
543 /* goto fail_all; */
544 }
545
546 /* Before register_camera, important */
547 ucpia->present = 1;
548
549 cam = cpia_register_camera(&cpia_usb_ops, ucpia);
550 if (!cam) {
551 LOG("failed to cpia_register_camera\n");
552 goto fail_all;
553 }
554
555 spin_lock( &cam_list_lock_usb );
556 list_add( &cam->cam_data_list, &cam_list );
557 spin_unlock( &cam_list_lock_usb );
558
559 usb_set_intfdata(intf, cam);
560 return 0;
561
562fail_all:
563 vfree(ucpia->buffers[2]);
564 ucpia->buffers[2] = NULL;
565fail_alloc_2:
566 vfree(ucpia->buffers[1]);
567 ucpia->buffers[1] = NULL;
568fail_alloc_1:
569 vfree(ucpia->buffers[0]);
570 ucpia->buffers[0] = NULL;
571fail_alloc_0:
572 kfree(ucpia);
573 return -EIO;
574}
575
576static void cpia_disconnect(struct usb_interface *intf);
577
578static struct usb_device_id cpia_id_table [] = {
579 { USB_DEVICE(0x0553, 0x0002) },
580 { USB_DEVICE(0x0813, 0x0001) },
581 { } /* Terminating entry */
582};
583
584MODULE_DEVICE_TABLE (usb, cpia_id_table);
585MODULE_LICENSE("GPL");
586
587
588static struct usb_driver cpia_driver = {
589 .owner = THIS_MODULE,
590 .name = "cpia",
591 .probe = cpia_probe,
592 .disconnect = cpia_disconnect,
593 .id_table = cpia_id_table,
594};
595
596static void cpia_disconnect(struct usb_interface *intf)
597{
598 struct cam_data *cam = usb_get_intfdata(intf);
599 struct usb_cpia *ucpia;
600 struct usb_device *udev;
601
602 usb_set_intfdata(intf, NULL);
603 if (!cam)
604 return;
605
606 ucpia = (struct usb_cpia *) cam->lowlevel_data;
607 spin_lock( &cam_list_lock_usb );
608 list_del(&cam->cam_data_list);
609 spin_unlock( &cam_list_lock_usb );
610
611 ucpia->present = 0;
612
613 cpia_unregister_camera(cam);
614 if(ucpia->open)
615 cpia_usb_close(cam->lowlevel_data);
616
617 ucpia->curbuff->status = FRAME_ERROR;
618
619 if (waitqueue_active(&ucpia->wq_stream))
620 wake_up_interruptible(&ucpia->wq_stream);
621
622 udev = interface_to_usbdev(intf);
623
624 ucpia->curbuff = ucpia->workbuff = NULL;
625
626 if (ucpia->buffers[2]) {
627 vfree(ucpia->buffers[2]);
628 ucpia->buffers[2] = NULL;
629 }
630
631 if (ucpia->buffers[1]) {
632 vfree(ucpia->buffers[1]);
633 ucpia->buffers[1] = NULL;
634 }
635
636 if (ucpia->buffers[0]) {
637 vfree(ucpia->buffers[0]);
638 ucpia->buffers[0] = NULL;
639 }
640
641 cam->lowlevel_data = NULL;
642 kfree(ucpia);
643}
644
645static int __init usb_cpia_init(void)
646{
647 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
648 CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
649
650 spin_lock_init(&cam_list_lock_usb);
651 return usb_register(&cpia_driver);
652}
653
654static void __exit usb_cpia_cleanup(void)
655{
656 usb_deregister(&cpia_driver);
657}
658
659
660module_init (usb_cpia_init);
661module_exit (usb_cpia_cleanup);
662
diff --git a/drivers/media/video/cs8420.h b/drivers/media/video/cs8420.h
new file mode 100644
index 000000000000..2b22f3a38de5
--- /dev/null
+++ b/drivers/media/video/cs8420.h
@@ -0,0 +1,50 @@
1/* cs8420.h - cs8420 initializations
2 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19#ifndef __CS8420_H__
20#define __CS8420_H__
21
22/* Initialization Sequence */
23
24static __u8 init8420[] = {
25 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
26 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
27};
28
29#define INIT8420LEN (sizeof(init8420)/2)
30
31static __u8 mode8420pro[] = { /* professional output mode */
32 32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00,
33 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
34 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
35 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
36 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
37 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
38};
39#define MODE8420LEN (sizeof(mode8420pro)/2)
40
41static __u8 mode8420con[] = { /* consumer output mode */
42 32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48,
43 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
44 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
45 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
46 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
47 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
48};
49
50#endif
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
new file mode 100644
index 000000000000..606d0348da2c
--- /dev/null
+++ b/drivers/media/video/cx88/Makefile
@@ -0,0 +1,11 @@
1cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
2 cx88-input.o
3cx8800-objs := cx88-video.o cx88-vbi.o
4cx8802-objs := cx88-mpeg.o
5
6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
8
9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
new file mode 100644
index 000000000000..46d6778b863b
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -0,0 +1,911 @@
1/*
2 * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * Support for a cx23416 mpeg encoder via cx2388x host port.
5 * "blackbird" reference design.
6 *
7 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
9 *
10 * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/fs.h>
31#include <linux/delay.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34
35#include "cx88.h"
36
37MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL");
41
42static unsigned int mpegbufs = 8;
43module_param(mpegbufs,int,0644);
44MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
45
46static unsigned int debug = 0;
47module_param(debug,int,0644);
48MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
49
50#define dprintk(level,fmt, arg...) if (debug >= level) \
51 printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
52
53static LIST_HEAD(cx8802_devlist);
54
55/* ------------------------------------------------------------------ */
56
57#define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin"
58#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024
59
60/* defines below are from ivtv-driver.h */
61
62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63
64/*Firmware API commands*/
65#define IVTV_API_ENC_PING_FW 0x00000080
66#define IVTV_API_ENC_GETVER 0x000000C4
67#define IVTV_API_ENC_HALT_FW 0x000000C3
68#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/
69//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7
70#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9
71#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb
72#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f
73#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091
74#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099
75#define IVTV_API_ASSIGN_BITRATES 0x00000095
76#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097
77#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1
78#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5
79#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd
80#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b
81#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d
82#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f
83#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1
84#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0
85#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8
86#define IVTV_API_MUTE_VIDEO 0x000000d9
87#define IVTV_API_MUTE_AUDIO 0x000000da
88#define IVTV_API_INITIALIZE_INPUT 0x000000cd
89#define IVTV_API_REFRESH_INPUT 0x000000d3
90#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6
91#define IVTV_API_BEGIN_CAPTURE 0x00000081
92//#define IVTV_API_PAUSE_ENCODER 0x000000d2
93//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5
94#define IVTV_API_END_CAPTURE 0x00000082
95
96/* Registers */
97#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
98#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
99#define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
100#define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
101#define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
102#define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
103
104/* ------------------------------------------------------------------ */
105
106static void host_setup(struct cx88_core *core)
107{
108 /* toggle reset of the host */
109 cx_write(MO_GPHST_SOFT_RST, 1);
110 udelay(100);
111 cx_write(MO_GPHST_SOFT_RST, 0);
112 udelay(100);
113
114 /* host port setup */
115 cx_write(MO_GPHST_WSC, 0x44444444U);
116 cx_write(MO_GPHST_XFR, 0);
117 cx_write(MO_GPHST_WDTH, 15);
118 cx_write(MO_GPHST_HDSHK, 0);
119 cx_write(MO_GPHST_MUX16, 0x44448888U);
120 cx_write(MO_GPHST_MODE, 0);
121}
122
123/* ------------------------------------------------------------------ */
124
125#define P1_MDATA0 0x390000
126#define P1_MDATA1 0x390001
127#define P1_MDATA2 0x390002
128#define P1_MDATA3 0x390003
129#define P1_MADDR2 0x390004
130#define P1_MADDR1 0x390005
131#define P1_MADDR0 0x390006
132#define P1_RDATA0 0x390008
133#define P1_RDATA1 0x390009
134#define P1_RDATA2 0x39000A
135#define P1_RDATA3 0x39000B
136#define P1_RADDR0 0x39000C
137#define P1_RADDR1 0x39000D
138#define P1_RRDWR 0x39000E
139
140static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state)
141{
142 unsigned long timeout = jiffies + msecs_to_jiffies(1);
143 u32 gpio0,need;
144
145 need = state ? 2 : 0;
146 for (;;) {
147 gpio0 = cx_read(MO_GP0_IO) & 2;
148 if (need == gpio0)
149 return 0;
150 if (time_after(jiffies,timeout))
151 return -1;
152 udelay(1);
153 }
154}
155
156static int memory_write(struct cx88_core *core, u32 address, u32 value)
157{
158 /* Warning: address is dword address (4 bytes) */
159 cx_writeb(P1_MDATA0, (unsigned int)value);
160 cx_writeb(P1_MDATA1, (unsigned int)(value >> 8));
161 cx_writeb(P1_MDATA2, (unsigned int)(value >> 16));
162 cx_writeb(P1_MDATA3, (unsigned int)(value >> 24));
163 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40);
164 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
165 cx_writeb(P1_MADDR0, (unsigned int)address);
166 cx_read(P1_MDATA0);
167 cx_read(P1_MADDR0);
168
169 return wait_ready_gpio0_bit1(core,1);
170}
171
172static int memory_read(struct cx88_core *core, u32 address, u32 *value)
173{
174 int retval;
175 u32 val;
176
177 /* Warning: address is dword address (4 bytes) */
178 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0);
179 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
180 cx_writeb(P1_MADDR0, (unsigned int)address);
181 cx_read(P1_MADDR0);
182
183 retval = wait_ready_gpio0_bit1(core,1);
184
185 cx_writeb(P1_MDATA3, 0);
186 val = (unsigned char)cx_read(P1_MDATA3) << 24;
187 cx_writeb(P1_MDATA2, 0);
188 val |= (unsigned char)cx_read(P1_MDATA2) << 16;
189 cx_writeb(P1_MDATA1, 0);
190 val |= (unsigned char)cx_read(P1_MDATA1) << 8;
191 cx_writeb(P1_MDATA0, 0);
192 val |= (unsigned char)cx_read(P1_MDATA0);
193
194 *value = val;
195 return retval;
196}
197
198static int register_write(struct cx88_core *core, u32 address, u32 value)
199{
200 cx_writeb(P1_RDATA0, (unsigned int)value);
201 cx_writeb(P1_RDATA1, (unsigned int)(value >> 8));
202 cx_writeb(P1_RDATA2, (unsigned int)(value >> 16));
203 cx_writeb(P1_RDATA3, (unsigned int)(value >> 24));
204 cx_writeb(P1_RADDR0, (unsigned int)address);
205 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
206 cx_writeb(P1_RRDWR, 1);
207 cx_read(P1_RDATA0);
208 cx_read(P1_RADDR0);
209
210 return wait_ready_gpio0_bit1(core,1);
211}
212
213
214static int register_read(struct cx88_core *core, u32 address, u32 *value)
215{
216 int retval;
217 u32 val;
218
219 cx_writeb(P1_RADDR0, (unsigned int)address);
220 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
221 cx_writeb(P1_RRDWR, 0);
222 cx_read(P1_RADDR0);
223
224 retval = wait_ready_gpio0_bit1(core,1);
225 val = (unsigned char)cx_read(P1_RDATA0);
226 val |= (unsigned char)cx_read(P1_RDATA1) << 8;
227 val |= (unsigned char)cx_read(P1_RDATA2) << 16;
228 val |= (unsigned char)cx_read(P1_RDATA3) << 24;
229
230 *value = val;
231 return retval;
232}
233
234/* ------------------------------------------------------------------ */
235
236/* We don't need to call the API often, so using just one mailbox will probably suffice */
237static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
238 u32 inputcnt, u32 outputcnt, ...)
239{
240 unsigned long timeout;
241 u32 value, flag, retval;
242 int i;
243 va_list args;
244 va_start(args, outputcnt);
245
246 dprintk(1,"%s: 0x%X\n", __FUNCTION__, command);
247
248 /* this may not be 100% safe if we can't read any memory location
249 without side effects */
250 memory_read(dev->core, dev->mailbox - 4, &value);
251 if (value != 0x12345678) {
252 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
253 return -1;
254 }
255
256 memory_read(dev->core, dev->mailbox, &flag);
257 if (flag) {
258 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
259 return -1;
260 }
261
262 flag |= 1; /* tell 'em we're working on it */
263 memory_write(dev->core, dev->mailbox, flag);
264
265 /* write command + args + fill remaining with zeros */
266 memory_write(dev->core, dev->mailbox + 1, command); /* command code */
267 memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
268 for (i = 0; i < inputcnt ; i++) {
269 value = va_arg(args, int);
270 memory_write(dev->core, dev->mailbox + 4 + i, value);
271 dprintk(1, "API Input %d = %d\n", i, value);
272 }
273 for (; i < 16 ; i++)
274 memory_write(dev->core, dev->mailbox + 4 + i, 0);
275
276 flag |= 3; /* tell 'em we're done writing */
277 memory_write(dev->core, dev->mailbox, flag);
278
279 /* wait for firmware to handle the API command */
280 timeout = jiffies + msecs_to_jiffies(10);
281 for (;;) {
282 memory_read(dev->core, dev->mailbox, &flag);
283 if (0 != (flag & 4))
284 break;
285 if (time_after(jiffies,timeout)) {
286 dprintk(0, "ERROR: API Mailbox timeout\n");
287 return -1;
288 }
289 udelay(10);
290 }
291
292 /* read output values */
293 for (i = 0; i < outputcnt ; i++) {
294 int *vptr = va_arg(args, int *);
295 memory_read(dev->core, dev->mailbox + 4 + i, vptr);
296 dprintk(1, "API Output %d = %d\n", i, *vptr);
297 }
298 va_end(args);
299
300 memory_read(dev->core, dev->mailbox + 2, &retval);
301 dprintk(1, "API result = %d\n",retval);
302
303 flag = 0;
304 memory_write(dev->core, dev->mailbox, flag);
305 return retval;
306}
307
308
309static int blackbird_find_mailbox(struct cx8802_dev *dev)
310{
311 u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
312 int signaturecnt=0;
313 u32 value;
314 int i;
315
316 for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
317 memory_read(dev->core, i, &value);
318 if (value == signature[signaturecnt])
319 signaturecnt++;
320 else
321 signaturecnt = 0;
322 if (4 == signaturecnt) {
323 dprintk(1, "Mailbox signature found\n");
324 return i+1;
325 }
326 }
327 dprintk(0, "Mailbox signature values not found!\n");
328 return -1;
329}
330
331static int blackbird_load_firmware(struct cx8802_dev *dev)
332{
333 static const unsigned char magic[8] = {
334 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
335 };
336 const struct firmware *firmware;
337 int i, retval = 0;
338 u32 value = 0;
339 u32 checksum = 0;
340 u32 *dataptr;
341
342 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
343 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
344 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
345 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
346 msleep(1);
347 retval |= register_write(dev->core, IVTV_REG_APU, 0);
348
349 if (retval < 0)
350 dprintk(0, "Error with register_write\n");
351
352 retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME,
353 &dev->pci->dev);
354 if (retval != 0) {
355 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
356 BLACKBIRD_FIRM_ENC_FILENAME);
357 dprintk(0, "Please fix your hotplug setup, the board will "
358 "not work without firmware loaded!\n");
359 return -1;
360 }
361
362 if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
363 dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
364 firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
365 return -1;
366 }
367
368 if (0 != memcmp(firmware->data, magic, 8)) {
369 dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
370 return -1;
371 }
372
373 /* transfer to the chip */
374 dprintk(1,"Loading firmware ...\n");
375 dataptr = (u32*)firmware->data;
376 for (i = 0; i < (firmware->size >> 2); i++) {
377 value = *dataptr;
378 checksum += ~value;
379 memory_write(dev->core, i, value);
380 dataptr++;
381 }
382
383 /* read back to verify with the checksum */
384 for (i--; i >= 0; i--) {
385 memory_read(dev->core, i, &value);
386 checksum -= ~value;
387 }
388 if (checksum) {
389 dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
390 return -1;
391 }
392 release_firmware(firmware);
393 dprintk(0, "Firmware upload successful.\n");
394
395 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
396 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
397 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
398 msleep(1);
399
400 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
401 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
402
403 if (retval < 0)
404 dprintk(0, "Error with register_write\n");
405 return 0;
406}
407
408static void blackbird_codec_settings(struct cx8802_dev *dev)
409{
410 int bitrate_mode = 1;
411 int bitrate = 7500000;
412 int bitrate_peak = 7500000;
413
414 /* assign stream type */
415 blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
416 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
417 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
418 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
419
420 /* assign output port */
421 blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
422
423 /* assign framerate */
424 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
425
426 /* assign frame size */
427 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0,
428 dev->height, dev->width);
429
430 /* assign aspect ratio */
431 blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
432
433 /* assign bitrates */
434 blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
435 bitrate_mode, /* mode */
436 bitrate, /* bps */
437 bitrate_peak / 400, /* peak/400 */
438 0, 0x70); /* encoding buffer, ckennedy */
439
440 /* assign gop properties */
441 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
442 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
443
444 /* assign 3 2 pulldown */
445 blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
446
447 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
448 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
449
450 /* assign gop closure */
451 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
452
453 /* assign audio properties */
454 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
455
456 /* assign dnr filter mode */
457 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
458
459 /* assign dnr filter props*/
460 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
461
462 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
463 blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
464
465 /* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */
466 blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
467
468 /* assign frame drop rate */
469 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
470}
471
472static int blackbird_initialize_codec(struct cx8802_dev *dev)
473{
474 struct cx88_core *core = dev->core;
475 int version;
476 int retval;
477
478 dprintk(1,"Initialize codec\n");
479 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
480 if (retval < 0) {
481 /* ping was not successful, reset and upload firmware */
482 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
483 msleep(1);
484 cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
485 msleep(1);
486 retval = blackbird_load_firmware(dev);
487 if (retval < 0)
488 return retval;
489
490 dev->mailbox = blackbird_find_mailbox(dev);
491 if (dev->mailbox < 0)
492 return -1;
493
494 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
495 if (retval < 0) {
496 dprintk(0, "ERROR: Firmware ping failed!\n");
497 return -1;
498 }
499
500 retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version);
501 if (retval < 0) {
502 dprintk(0, "ERROR: Firmware get encoder version failed!\n");
503 return -1;
504 }
505 dprintk(0, "Firmware version is 0x%08x\n", version);
506 }
507 msleep(1);
508
509 cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
510 cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
511 cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
512 cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
513
514#if 0 /* FIXME */
515 set_scale(dev, 720, 480, V4L2_FIELD_INTERLACED);
516#endif
517 blackbird_codec_settings(dev);
518 msleep(1);
519
520 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
521 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
522 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
523 blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
524
525 blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
526
527 msleep(1);
528
529 blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
530 msleep(1);
531 blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
532 msleep(1);
533
534 blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
535 //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
536 msleep(1);
537
538 blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
539 return 0;
540}
541
542/* ------------------------------------------------------------------ */
543
544static int bb_buf_setup(struct videobuf_queue *q,
545 unsigned int *count, unsigned int *size)
546{
547 struct cx8802_fh *fh = q->priv_data;
548
549 fh->dev->ts_packet_size = 512;
550 fh->dev->ts_packet_count = 100;
551
552 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
553 if (0 == *count)
554 *count = mpegbufs;
555 if (*count < 2)
556 *count = 2;
557 if (*count > 32)
558 *count = 32;
559 return 0;
560}
561
562static int
563bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
564 enum v4l2_field field)
565{
566 struct cx8802_fh *fh = q->priv_data;
567 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb);
568}
569
570static void
571bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
572{
573 struct cx8802_fh *fh = q->priv_data;
574 cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb);
575}
576
577static void
578bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
579{
580 struct cx8802_fh *fh = q->priv_data;
581 cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
582}
583
584static struct videobuf_queue_ops blackbird_qops = {
585 .buf_setup = bb_buf_setup,
586 .buf_prepare = bb_buf_prepare,
587 .buf_queue = bb_buf_queue,
588 .buf_release = bb_buf_release,
589};
590
591/* ------------------------------------------------------------------ */
592
593static int mpeg_do_ioctl(struct inode *inode, struct file *file,
594 unsigned int cmd, void *arg)
595{
596 struct cx8802_fh *fh = file->private_data;
597 struct cx8802_dev *dev = fh->dev;
598
599 if (debug > 1)
600 cx88_print_ioctl(dev->core->name,cmd);
601
602 switch (cmd) {
603
604 /* --- capture ioctls ---------------------------------------- */
605 case VIDIOC_ENUM_FMT:
606 {
607 struct v4l2_fmtdesc *f = arg;
608 int index;
609
610 index = f->index;
611 if (index != 0)
612 return -EINVAL;
613
614 memset(f,0,sizeof(*f));
615 f->index = index;
616 strlcpy(f->description, "MPEG TS", sizeof(f->description));
617 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
618 f->pixelformat = V4L2_PIX_FMT_MPEG;
619 return 0;
620 }
621 case VIDIOC_G_FMT:
622 case VIDIOC_S_FMT:
623 case VIDIOC_TRY_FMT:
624 {
625 /* FIXME -- quick'n'dirty for exactly one size ... */
626 struct v4l2_format *f = arg;
627
628 memset(f,0,sizeof(*f));
629 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
630 f->fmt.pix.width = dev->width;
631 f->fmt.pix.height = dev->height;
632 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
633 f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */;
634 }
635
636 /* --- streaming capture ------------------------------------- */
637 case VIDIOC_REQBUFS:
638 return videobuf_reqbufs(&fh->mpegq, arg);
639
640 case VIDIOC_QUERYBUF:
641 return videobuf_querybuf(&fh->mpegq, arg);
642
643 case VIDIOC_QBUF:
644 return videobuf_qbuf(&fh->mpegq, arg);
645
646 case VIDIOC_DQBUF:
647 return videobuf_dqbuf(&fh->mpegq, arg,
648 file->f_flags & O_NONBLOCK);
649
650 case VIDIOC_STREAMON:
651 return videobuf_streamon(&fh->mpegq);
652
653 case VIDIOC_STREAMOFF:
654 return videobuf_streamoff(&fh->mpegq);
655
656 default:
657 return -EINVAL;
658 }
659 return 0;
660}
661
662static int mpeg_ioctl(struct inode *inode, struct file *file,
663 unsigned int cmd, unsigned long arg)
664{
665 return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl);
666}
667
668static int mpeg_open(struct inode *inode, struct file *file)
669{
670 int minor = iminor(inode);
671 struct cx8802_dev *h,*dev = NULL;
672 struct cx8802_fh *fh;
673 struct list_head *list;
674
675 list_for_each(list,&cx8802_devlist) {
676 h = list_entry(list, struct cx8802_dev, devlist);
677 if (h->mpeg_dev->minor == minor)
678 dev = h;
679 }
680 if (NULL == dev)
681 return -ENODEV;
682
683 if (blackbird_initialize_codec(dev) < 0)
684 return -EINVAL;
685 dprintk(1,"open minor=%d\n",minor);
686
687 /* allocate + initialize per filehandle data */
688 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
689 if (NULL == fh)
690 return -ENOMEM;
691 memset(fh,0,sizeof(*fh));
692 file->private_data = fh;
693 fh->dev = dev;
694
695 /* FIXME: locking against other video device */
696 cx88_set_scale(dev->core, dev->width, dev->height,
697 V4L2_FIELD_INTERLACED);
698
699 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
700 dev->pci, &dev->slock,
701 V4L2_BUF_TYPE_VIDEO_CAPTURE,
702 V4L2_FIELD_TOP,
703 sizeof(struct cx88_buffer),
704 fh);
705 return 0;
706}
707
708static int mpeg_release(struct inode *inode, struct file *file)
709{
710 struct cx8802_fh *fh = file->private_data;
711
712 blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
713
714 /* stop mpeg capture */
715 if (fh->mpegq.streaming)
716 videobuf_streamoff(&fh->mpegq);
717 if (fh->mpegq.reading)
718 videobuf_read_stop(&fh->mpegq);
719
720 videobuf_mmap_free(&fh->mpegq);
721 file->private_data = NULL;
722 kfree(fh);
723 return 0;
724}
725
726static ssize_t
727mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
728{
729 struct cx8802_fh *fh = file->private_data;
730
731 return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
732 file->f_flags & O_NONBLOCK);
733}
734
735static unsigned int
736mpeg_poll(struct file *file, struct poll_table_struct *wait)
737{
738 struct cx8802_fh *fh = file->private_data;
739
740 return videobuf_poll_stream(file, &fh->mpegq, wait);
741}
742
743static int
744mpeg_mmap(struct file *file, struct vm_area_struct * vma)
745{
746 struct cx8802_fh *fh = file->private_data;
747
748 return videobuf_mmap_mapper(&fh->mpegq, vma);
749}
750
751static struct file_operations mpeg_fops =
752{
753 .owner = THIS_MODULE,
754 .open = mpeg_open,
755 .release = mpeg_release,
756 .read = mpeg_read,
757 .poll = mpeg_poll,
758 .mmap = mpeg_mmap,
759 .ioctl = mpeg_ioctl,
760 .llseek = no_llseek,
761};
762
763static struct video_device cx8802_mpeg_template =
764{
765 .name = "cx8802",
766 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER,
767 .hardware = 0,
768 .fops = &mpeg_fops,
769 .minor = -1,
770};
771
772/* ------------------------------------------------------------------ */
773
774static void blackbird_unregister_video(struct cx8802_dev *dev)
775{
776 if (dev->mpeg_dev) {
777 if (-1 != dev->mpeg_dev->minor)
778 video_unregister_device(dev->mpeg_dev);
779 else
780 video_device_release(dev->mpeg_dev);
781 dev->mpeg_dev = NULL;
782 }
783}
784
785static int blackbird_register_video(struct cx8802_dev *dev)
786{
787 int err;
788
789 dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
790 &cx8802_mpeg_template,"mpeg");
791 err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
792 if (err < 0) {
793 printk(KERN_INFO "%s/2: can't register mpeg device\n",
794 dev->core->name);
795 return err;
796 }
797 printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n",
798 dev->core->name,dev->mpeg_dev->minor & 0x1f);
799 return 0;
800}
801
802/* ----------------------------------------------------------- */
803
804static int __devinit blackbird_probe(struct pci_dev *pci_dev,
805 const struct pci_device_id *pci_id)
806{
807 struct cx8802_dev *dev;
808 struct cx88_core *core;
809 int err;
810
811 /* general setup */
812 core = cx88_core_get(pci_dev);
813 if (NULL == core)
814 return -EINVAL;
815
816 err = -ENODEV;
817 if (!cx88_boards[core->board].blackbird)
818 goto fail_core;
819
820 err = -ENOMEM;
821 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
822 if (NULL == dev)
823 goto fail_core;
824 memset(dev,0,sizeof(*dev));
825 dev->pci = pci_dev;
826 dev->core = core;
827 dev->width = 720;
828 dev->height = 480;
829
830 err = cx8802_init_common(dev);
831 if (0 != err)
832 goto fail_free;
833
834 /* blackbird stuff */
835 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
836 core->name);
837 host_setup(dev->core);
838
839 list_add_tail(&dev->devlist,&cx8802_devlist);
840 blackbird_register_video(dev);
841 return 0;
842
843 fail_free:
844 kfree(dev);
845 fail_core:
846 cx88_core_put(core,pci_dev);
847 return err;
848}
849
850static void __devexit blackbird_remove(struct pci_dev *pci_dev)
851{
852 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
853
854 /* blackbird */
855 blackbird_unregister_video(dev);
856 list_del(&dev->devlist);
857
858 /* common */
859 cx8802_fini_common(dev);
860 cx88_core_put(dev->core,dev->pci);
861 kfree(dev);
862}
863
864static struct pci_device_id cx8802_pci_tbl[] = {
865 {
866 .vendor = 0x14f1,
867 .device = 0x8802,
868 .subvendor = PCI_ANY_ID,
869 .subdevice = PCI_ANY_ID,
870 },{
871 /* --- end of list --- */
872 }
873};
874MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
875
876static struct pci_driver blackbird_pci_driver = {
877 .name = "cx88-blackbird",
878 .id_table = cx8802_pci_tbl,
879 .probe = blackbird_probe,
880 .remove = __devexit_p(blackbird_remove),
881 .suspend = cx8802_suspend_common,
882 .resume = cx8802_resume_common,
883};
884
885static int blackbird_init(void)
886{
887 printk(KERN_INFO "cx2388x blackbird driver version %d.%d.%d loaded\n",
888 (CX88_VERSION_CODE >> 16) & 0xff,
889 (CX88_VERSION_CODE >> 8) & 0xff,
890 CX88_VERSION_CODE & 0xff);
891#ifdef SNAPSHOT
892 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
893 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
894#endif
895 return pci_register_driver(&blackbird_pci_driver);
896}
897
898static void blackbird_fini(void)
899{
900 pci_unregister_driver(&blackbird_pci_driver);
901}
902
903module_init(blackbird_init);
904module_exit(blackbird_fini);
905
906/* ----------------------------------------------------------- */
907/*
908 * Local variables:
909 * c-basic-offset: 8
910 * End:
911 */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
new file mode 100644
index 000000000000..367624822d77
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -0,0 +1,938 @@
1/*
2 * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * card-specific stuff.
6 *
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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
29#include "cx88.h"
30
31/* ------------------------------------------------------------------ */
32/* board config info */
33
34struct cx88_board cx88_boards[] = {
35 [CX88_BOARD_UNKNOWN] = {
36 .name = "UNKNOWN/GENERIC",
37 .tuner_type = UNSET,
38 .input = {{
39 .type = CX88_VMUX_COMPOSITE1,
40 .vmux = 0,
41 },{
42 .type = CX88_VMUX_COMPOSITE2,
43 .vmux = 1,
44 },{
45 .type = CX88_VMUX_COMPOSITE3,
46 .vmux = 2,
47 },{
48 .type = CX88_VMUX_COMPOSITE4,
49 .vmux = 3,
50 }},
51 },
52 [CX88_BOARD_HAUPPAUGE] = {
53 .name = "Hauppauge WinTV 34xxx models",
54 .tuner_type = UNSET,
55 .tda9887_conf = TDA9887_PRESENT,
56 .input = {{
57 .type = CX88_VMUX_TELEVISION,
58 .vmux = 0,
59 .gpio0 = 0xff00, // internal decoder
60 },{
61 .type = CX88_VMUX_DEBUG,
62 .vmux = 0,
63 .gpio0 = 0xff01, // mono from tuner chip
64 },{
65 .type = CX88_VMUX_COMPOSITE1,
66 .vmux = 1,
67 .gpio0 = 0xff02,
68 },{
69 .type = CX88_VMUX_SVIDEO,
70 .vmux = 2,
71 .gpio0 = 0xff02,
72 }},
73 .radio = {
74 .type = CX88_RADIO,
75 .gpio0 = 0xff01,
76 },
77 },
78 [CX88_BOARD_GDI] = {
79 .name = "GDI Black Gold",
80 .tuner_type = UNSET,
81 .input = {{
82 .type = CX88_VMUX_TELEVISION,
83 .vmux = 0,
84 }},
85 },
86 [CX88_BOARD_PIXELVIEW] = {
87 .name = "PixelView",
88 .tuner_type = 5,
89 .input = {{
90 .type = CX88_VMUX_TELEVISION,
91 .vmux = 0,
92 .gpio0 = 0xff00, // internal decoder
93 },{
94 .type = CX88_VMUX_COMPOSITE1,
95 .vmux = 1,
96 },{
97 .type = CX88_VMUX_SVIDEO,
98 .vmux = 2,
99 }},
100 .radio = {
101 .type = CX88_RADIO,
102 .gpio0 = 0xff10,
103 },
104 },
105 [CX88_BOARD_ATI_WONDER_PRO] = {
106 .name = "ATI TV Wonder Pro",
107 .tuner_type = 44,
108 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
109 .input = {{
110 .type = CX88_VMUX_TELEVISION,
111 .vmux = 0,
112 .gpio0 = 0x03ff,
113 },{
114 .type = CX88_VMUX_COMPOSITE1,
115 .vmux = 1,
116 .gpio0 = 0x03fe,
117 },{
118 .type = CX88_VMUX_SVIDEO,
119 .vmux = 2,
120 .gpio0 = 0x03fe,
121 }},
122 },
123 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
124 .name = "Leadtek Winfast 2000XP Expert",
125 .tuner_type = 44,
126 .tda9887_conf = TDA9887_PRESENT,
127 .input = {{
128 .type = CX88_VMUX_TELEVISION,
129 .vmux = 0,
130 .gpio0 = 0x00F5e700,
131 .gpio1 = 0x00003004,
132 .gpio2 = 0x00F5e700,
133 .gpio3 = 0x02000000,
134 },{
135 .type = CX88_VMUX_COMPOSITE1,
136 .vmux = 1,
137 .gpio0 = 0x00F5c700,
138 .gpio1 = 0x00003004,
139 .gpio2 = 0x00F5c700,
140 .gpio3 = 0x02000000,
141 },{
142 .type = CX88_VMUX_SVIDEO,
143 .vmux = 2,
144 .gpio0 = 0x00F5c700,
145 .gpio1 = 0x00003004,
146 .gpio2 = 0x00F5c700,
147 .gpio3 = 0x02000000,
148 }},
149 .radio = {
150 .type = CX88_RADIO,
151 .gpio0 = 0x00F5d700,
152 .gpio1 = 0x00003004,
153 .gpio2 = 0x00F5d700,
154 .gpio3 = 0x02000000,
155 },
156 },
157 [CX88_BOARD_AVERTV_303] = {
158 .name = "AverTV Studio 303 (M126)",
159 .tuner_type = 38,
160 .tda9887_conf = TDA9887_PRESENT,
161 .input = {{
162 .type = CX88_VMUX_TELEVISION,
163 .vmux = 0,
164 .gpio1 = 0x309f,
165 },{
166 .type = CX88_VMUX_COMPOSITE1,
167 .vmux = 1,
168 .gpio1 = 0x305f,
169 },{
170 .type = CX88_VMUX_SVIDEO,
171 .vmux = 2,
172 .gpio1 = 0x305f,
173 }},
174 .radio = {
175 .type = CX88_RADIO,
176 },
177 },
178 [CX88_BOARD_MSI_TVANYWHERE_MASTER] = {
179 // added gpio values thanks to Michal
180 // values for PAL from DScaler
181 .name = "MSI TV-@nywhere Master",
182 .tuner_type = 33,
183 .tda9887_conf = TDA9887_PRESENT,
184 .input = {{
185 .type = CX88_VMUX_TELEVISION,
186 .vmux = 0,
187 .gpio0 = 0x000040bf,
188 .gpio1 = 0x000080c0,
189 .gpio2 = 0x0000ff40,
190 },{
191 .type = CX88_VMUX_COMPOSITE1,
192 .vmux = 1,
193 .gpio0 = 0x000040bf,
194 .gpio1 = 0x000080c0,
195 .gpio2 = 0x0000ff40,
196 },{
197 .type = CX88_VMUX_SVIDEO,
198 .vmux = 2,
199 .gpio0 = 0x000040bf,
200 .gpio1 = 0x000080c0,
201 .gpio2 = 0x0000ff40,
202 }},
203 .radio = {
204 .type = CX88_RADIO,
205 },
206 },
207 [CX88_BOARD_WINFAST_DV2000] = {
208 .name = "Leadtek Winfast DV2000",
209 .tuner_type = 38,
210 .tda9887_conf = TDA9887_PRESENT,
211 .input = {{
212 .type = CX88_VMUX_TELEVISION,
213 .vmux = 0,
214 .gpio0 = 0x0035e700,
215 .gpio1 = 0x00003004,
216 .gpio2 = 0x0035e700,
217 .gpio3 = 0x02000000,
218 },{
219
220 .type = CX88_VMUX_COMPOSITE1,
221 .vmux = 1,
222 .gpio0 = 0x0035c700,
223 .gpio1 = 0x00003004,
224 .gpio2 = 0x0035c700,
225 .gpio3 = 0x02000000,
226 },{
227 .type = CX88_VMUX_SVIDEO,
228 .vmux = 2,
229 .gpio0 = 0x0035c700,
230 .gpio1 = 0x0035c700,
231 .gpio2 = 0x02000000,
232 .gpio3 = 0x02000000,
233 }},
234 .radio = {
235 .type = CX88_RADIO,
236 .gpio0 = 0x0035d700,
237 .gpio1 = 0x00007004,
238 .gpio2 = 0x0035d700,
239 .gpio3 = 0x02000000,
240 },
241 },
242 [CX88_BOARD_LEADTEK_PVR2000] = {
243 // gpio values for PAL version from regspy by DScaler
244 .name = "Leadtek PVR 2000",
245 .tuner_type = 38,
246 .tda9887_conf = TDA9887_PRESENT,
247 .input = {{
248 .type = CX88_VMUX_TELEVISION,
249 .vmux = 0,
250 .gpio0 = 0x0000bde6,
251 },{
252 .type = CX88_VMUX_COMPOSITE1,
253 .vmux = 1,
254 .gpio0 = 0x0000bde6,
255 },{
256 .type = CX88_VMUX_SVIDEO,
257 .vmux = 2,
258 .gpio0 = 0x0000bde6,
259 }},
260 .radio = {
261 .type = CX88_RADIO,
262 .gpio0 = 0x0000bd62,
263 },
264 .blackbird = 1,
265 },
266 [CX88_BOARD_IODATA_GVVCP3PCI] = {
267 .name = "IODATA GV-VCP3/PCI",
268 .tuner_type = TUNER_ABSENT,
269 .input = {{
270 .type = CX88_VMUX_COMPOSITE1,
271 .vmux = 0,
272 },{
273 .type = CX88_VMUX_COMPOSITE2,
274 .vmux = 1,
275 },{
276 .type = CX88_VMUX_SVIDEO,
277 .vmux = 2,
278 }},
279 },
280 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
281 .name = "Prolink PlayTV PVR",
282 .tuner_type = 43,
283 .tda9887_conf = TDA9887_PRESENT,
284 .input = {{
285 .type = CX88_VMUX_TELEVISION,
286 .vmux = 0,
287 .gpio0 = 0xff00,
288 },{
289 .type = CX88_VMUX_COMPOSITE1,
290 .vmux = 1,
291 .gpio0 = 0xff03,
292 },{
293 .type = CX88_VMUX_SVIDEO,
294 .vmux = 2,
295 .gpio0 = 0xff03,
296 }},
297 .radio = {
298 .type = CX88_RADIO,
299 .gpio0 = 0xff00,
300 },
301 },
302 [CX88_BOARD_ASUS_PVR_416] = {
303 .name = "ASUS PVR-416",
304 .tuner_type = 43,
305 .tda9887_conf = TDA9887_PRESENT,
306 .input = {{
307 .type = CX88_VMUX_TELEVISION,
308 .vmux = 0,
309 .gpio0 = 0x0000fde6,
310 },{
311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2,
313 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
314 }},
315 .radio = {
316 .type = CX88_RADIO,
317 .gpio0 = 0x0000fde2,
318 },
319 .blackbird = 1,
320 },
321 [CX88_BOARD_MSI_TVANYWHERE] = {
322 .name = "MSI TV-@nywhere",
323 .tuner_type = 33,
324 .tda9887_conf = TDA9887_PRESENT,
325 .input = {{
326 .type = CX88_VMUX_TELEVISION,
327 .vmux = 0,
328 .gpio0 = 0x00000fbf,
329 .gpio2 = 0x0000fc08,
330 },{
331 .type = CX88_VMUX_COMPOSITE1,
332 .vmux = 1,
333 .gpio0 = 0x00000fbf,
334 .gpio2 = 0x0000fc68,
335 },{
336 .type = CX88_VMUX_SVIDEO,
337 .vmux = 2,
338 .gpio0 = 0x00000fbf,
339 .gpio2 = 0x0000fc68,
340 }},
341 },
342 [CX88_BOARD_KWORLD_DVB_T] = {
343 .name = "KWorld/VStream XPert DVB-T",
344 .tuner_type = TUNER_ABSENT,
345 .input = {{
346 .type = CX88_VMUX_COMPOSITE1,
347 .vmux = 1,
348 .gpio0 = 0x0700,
349 .gpio2 = 0x0101,
350 },{
351 .type = CX88_VMUX_SVIDEO,
352 .vmux = 2,
353 .gpio0 = 0x0700,
354 .gpio2 = 0x0101,
355 }},
356 .dvb = 1,
357 },
358 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
359 .name = "DVICO FusionHDTV DVB-T1",
360 .tuner_type = TUNER_ABSENT, /* No analog tuner */
361 .input = {{
362 .type = CX88_VMUX_COMPOSITE1,
363 .vmux = 1,
364 .gpio0 = 0x000027df,
365 },{
366 .type = CX88_VMUX_SVIDEO,
367 .vmux = 2,
368 .gpio0 = 0x000027df,
369 }},
370 .dvb = 1,
371 },
372 [CX88_BOARD_KWORLD_LTV883] = {
373 .name = "KWorld LTV883RF",
374 .tuner_type = 48,
375 .input = {{
376 .type = CX88_VMUX_TELEVISION,
377 .vmux = 0,
378 .gpio0 = 0x07f8,
379 },{
380 .type = CX88_VMUX_DEBUG,
381 .vmux = 0,
382 .gpio0 = 0x07f9, // mono from tuner chip
383 },{
384 .type = CX88_VMUX_COMPOSITE1,
385 .vmux = 1,
386 .gpio0 = 0x000007fa,
387 },{
388 .type = CX88_VMUX_SVIDEO,
389 .vmux = 2,
390 .gpio0 = 0x000007fa,
391 }},
392 .radio = {
393 .type = CX88_RADIO,
394 .gpio0 = 0x000007f8,
395 },
396 },
397 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
398 .name = "DViCO - FusionHDTV 3 Gold",
399 .tuner_type = TUNER_MICROTUNE_4042FI5,
400 /*
401 GPIO[0] resets DT3302 DTV receiver
402 0 - reset asserted
403 1 - normal operation
404 GPIO[1] mutes analog audio output connector
405 0 - enable selected source
406 1 - mute
407 GPIO[2] selects source for analog audio output connector
408 0 - analog audio input connector on tab
409 1 - analog DAC output from CX23881 chip
410 GPIO[3] selects RF input connector on tuner module
411 0 - RF connector labeled CABLE
412 1 - RF connector labeled ANT
413 */
414 .input = {{
415 .type = CX88_VMUX_TELEVISION,
416 .vmux = 0,
417 .gpio0 = 0x0f0d,
418 },{
419 .type = CX88_VMUX_CABLE,
420 .vmux = 0,
421 .gpio0 = 0x0f05,
422 },{
423 .type = CX88_VMUX_COMPOSITE1,
424 .vmux = 1,
425 .gpio0 = 0x0f00,
426 },{
427 .type = CX88_VMUX_SVIDEO,
428 .vmux = 2,
429 .gpio0 = 0x0f00,
430 }},
431#if 0
432 .ts = {
433 .type = CX88_TS,
434 .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */
435 }
436#endif
437 },
438 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
439 .name = "Hauppauge Nova-T DVB-T",
440 .tuner_type = TUNER_ABSENT,
441 .input = {{
442 .type = CX88_VMUX_DVB,
443 .vmux = 0,
444 }},
445 .dvb = 1,
446 },
447 [CX88_BOARD_CONEXANT_DVB_T1] = {
448 .name = "Conexant DVB-T reference design",
449 .tuner_type = TUNER_ABSENT,
450 .input = {{
451 .type = CX88_VMUX_DVB,
452 .vmux = 0,
453 }},
454 .dvb = 1,
455 },
456 [CX88_BOARD_PROVIDEO_PV259] = {
457 .name = "Provideo PV259",
458 .tuner_type = TUNER_PHILIPS_FQ1216ME,
459 .input = {{
460 .type = CX88_VMUX_TELEVISION,
461 .vmux = 0,
462 }},
463 .blackbird = 1,
464 },
465 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
466 .name = "DVICO FusionHDTV DVB-T Plus",
467 .tuner_type = TUNER_ABSENT, /* No analog tuner */
468 .input = {{
469 .type = CX88_VMUX_COMPOSITE1,
470 .vmux = 1,
471 .gpio0 = 0x000027df,
472 },{
473 .type = CX88_VMUX_SVIDEO,
474 .vmux = 2,
475 .gpio0 = 0x000027df,
476 }},
477 .dvb = 1,
478 },
479 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
480 .name = "digitalnow DNTV Live! DVB-T",
481 .tuner_type = TUNER_ABSENT,
482 .input = {{
483 .type = CX88_VMUX_COMPOSITE1,
484 .vmux = 1,
485 .gpio0 = 0x00000700,
486 .gpio2 = 0x00000101,
487 },{
488 .type = CX88_VMUX_SVIDEO,
489 .vmux = 2,
490 .gpio0 = 0x00000700,
491 .gpio2 = 0x00000101,
492 }},
493 .dvb = 1,
494 },
495 [CX88_BOARD_PCHDTV_HD3000] = {
496 .name = "pcHDTV HD3000 HDTV",
497 .tuner_type = TUNER_THOMSON_DTT7610,
498 .input = {{
499 .type = CX88_VMUX_TELEVISION,
500 .vmux = 0,
501 .gpio0 = 0x00008484,
502 .gpio1 = 0x00000000,
503 .gpio2 = 0x00000000,
504 .gpio3 = 0x00000000,
505 },{
506 .type = CX88_VMUX_COMPOSITE1,
507 .vmux = 1,
508 .gpio0 = 0x00008400,
509 .gpio1 = 0x00000000,
510 .gpio2 = 0x00000000,
511 .gpio3 = 0x00000000,
512 },{
513 .type = CX88_VMUX_SVIDEO,
514 .vmux = 2,
515 .gpio0 = 0x00008400,
516 .gpio1 = 0x00000000,
517 .gpio2 = 0x00000000,
518 .gpio3 = 0x00000000,
519 }},
520 .radio = {
521 .type = CX88_RADIO,
522 .vmux = 2,
523 .gpio0 = 0x00008400,
524 .gpio1 = 0x00000000,
525 .gpio2 = 0x00000000,
526 .gpio3 = 0x00000000,
527 },
528 .dvb = 1,
529 },
530 [CX88_BOARD_HAUPPAUGE_ROSLYN] = {
531 // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
532 // GPIO values obtained from regspy, courtesy Sean Covel
533 .name = "Hauppauge WinTV 28xxx (Roslyn) models",
534 .tuner_type = UNSET,
535 .input = {{
536 .type = CX88_VMUX_TELEVISION,
537 .vmux = 0,
538 .gpio0 = 0xed12, // internal decoder
539 .gpio2 = 0x00ff,
540 },{
541 .type = CX88_VMUX_DEBUG,
542 .vmux = 0,
543 .gpio0 = 0xff01, // mono from tuner chip
544 },{
545 .type = CX88_VMUX_COMPOSITE1,
546 .vmux = 1,
547 .gpio0 = 0xff02,
548 },{
549 .type = CX88_VMUX_SVIDEO,
550 .vmux = 2,
551 .gpio0 = 0xed92,
552 .gpio2 = 0x00ff,
553 }},
554 .radio = {
555 .type = CX88_RADIO,
556 .gpio0 = 0xed96,
557 .gpio2 = 0x00ff,
558 },
559 .blackbird = 1,
560 },
561 [CX88_BOARD_DIGITALLOGIC_MEC] = {
562 /* params copied over from Leadtek PVR 2000 */
563 .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
564 /* not sure yet about the tuner type */
565 .tuner_type = 38,
566 .tda9887_conf = TDA9887_PRESENT,
567 .input = {{
568 .type = CX88_VMUX_TELEVISION,
569 .vmux = 0,
570 .gpio0 = 0x0000bde6,
571 },{
572 .type = CX88_VMUX_COMPOSITE1,
573 .vmux = 1,
574 .gpio0 = 0x0000bde6,
575 },{
576 .type = CX88_VMUX_SVIDEO,
577 .vmux = 2,
578 .gpio0 = 0x0000bde6,
579 }},
580 .radio = {
581 .type = CX88_RADIO,
582 .gpio0 = 0x0000bd62,
583 },
584 .blackbird = 1,
585 },
586 [CX88_BOARD_IODATA_GVBCTV7E] = {
587 .name = "IODATA GV/BCTV7E",
588 .tuner_type = TUNER_PHILIPS_FQ1286,
589 .tda9887_conf = TDA9887_PRESENT,
590 .input = {{
591 .type = CX88_VMUX_TELEVISION,
592 .vmux = 1,
593 .gpio1 = 0x0000e03f,
594 },{
595 .type = CX88_VMUX_COMPOSITE1,
596 .vmux = 2,
597 .gpio1 = 0x0000e07f,
598 },{
599 .type = CX88_VMUX_SVIDEO,
600 .vmux = 3,
601 .gpio1 = 0x0000e07f,
602 }}
603 },
604};
605const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
606
607/* ------------------------------------------------------------------ */
608/* PCI subsystem IDs */
609
610struct cx88_subid cx88_subids[] = {
611 {
612 .subvendor = 0x0070,
613 .subdevice = 0x3400,
614 .card = CX88_BOARD_HAUPPAUGE,
615 },{
616 .subvendor = 0x0070,
617 .subdevice = 0x3401,
618 .card = CX88_BOARD_HAUPPAUGE,
619 },{
620 .subvendor = 0x14c7,
621 .subdevice = 0x0106,
622 .card = CX88_BOARD_GDI,
623 },{
624 .subvendor = 0x14c7,
625 .subdevice = 0x0107, /* with mpeg encoder */
626 .card = CX88_BOARD_GDI,
627 },{
628 .subvendor = PCI_VENDOR_ID_ATI,
629 .subdevice = 0x00f8,
630 .card = CX88_BOARD_ATI_WONDER_PRO,
631 },{
632 .subvendor = 0x107d,
633 .subdevice = 0x6611,
634 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
635 },{
636 .subvendor = 0x107d,
637 .subdevice = 0x6613, /* NTSC */
638 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
639 },{
640 .subvendor = 0x107d,
641 .subdevice = 0x6620,
642 .card = CX88_BOARD_WINFAST_DV2000,
643 },{
644 .subvendor = 0x107d,
645 .subdevice = 0x663b,
646 .card = CX88_BOARD_LEADTEK_PVR2000,
647 },{
648 .subvendor = 0x107d,
649 .subdevice = 0x663C,
650 .card = CX88_BOARD_LEADTEK_PVR2000,
651 },{
652 .subvendor = 0x1461,
653 .subdevice = 0x000b,
654 .card = CX88_BOARD_AVERTV_303,
655 },{
656 .subvendor = 0x1462,
657 .subdevice = 0x8606,
658 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
659 },{
660 .subvendor = 0x10fc,
661 .subdevice = 0xd003,
662 .card = CX88_BOARD_IODATA_GVVCP3PCI,
663 },{
664 .subvendor = 0x1043,
665 .subdevice = 0x4823, /* with mpeg encoder */
666 .card = CX88_BOARD_ASUS_PVR_416,
667 },{
668 .subvendor = 0x17de,
669 .subdevice = 0x08a6,
670 .card = CX88_BOARD_KWORLD_DVB_T,
671 },{
672 .subvendor = 0x18ac,
673 .subdevice = 0xd810,
674 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
675 },{
676 .subvendor = 0x18AC,
677 .subdevice = 0xDB00,
678 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
679 },{
680 .subvendor = 0x0070,
681 .subdevice = 0x9002,
682 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
683 },{
684 .subvendor = 0x14f1,
685 .subdevice = 0x0187,
686 .card = CX88_BOARD_CONEXANT_DVB_T1,
687 },{
688 .subvendor = 0x1540,
689 .subdevice = 0x2580,
690 .card = CX88_BOARD_PROVIDEO_PV259,
691 },{
692 .subvendor = 0x18AC,
693 .subdevice = 0xDB10,
694 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
695 },{
696 .subvendor = 0x1554,
697 .subdevice = 0x4811,
698 .card = CX88_BOARD_PIXELVIEW,
699 },{
700 .subvendor = 0x7063,
701 .subdevice = 0x3000, /* HD-3000 card */
702 .card = CX88_BOARD_PCHDTV_HD3000,
703 },{
704 .subvendor = 0x17DE,
705 .subdevice = 0xA8A6,
706 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
707 },{
708 .subvendor = 0x0070,
709 .subdevice = 0x2801,
710 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
711 },{
712 .subvendor = 0x14F1,
713 .subdevice = 0x0342,
714 .card = CX88_BOARD_DIGITALLOGIC_MEC,
715 },{
716 .subvendor = 0x10fc,
717 .subdevice = 0xd035,
718 .card = CX88_BOARD_IODATA_GVBCTV7E,
719 }
720};
721const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
722
723/* ----------------------------------------------------------------------- */
724/* some leadtek specific stuff */
725
726static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
727{
728 /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
729 * any others.
730 *
731 * Byte 0 is 1 on the NTSC board.
732 */
733
734 if (eeprom_data[4] != 0x7d ||
735 eeprom_data[5] != 0x10 ||
736 eeprom_data[7] != 0x66) {
737 printk(KERN_WARNING "%s: Leadtek eeprom invalid.\n",
738 core->name);
739 return;
740 }
741
742 core->has_radio = 1;
743 core->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38;
744
745 printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: "
746 "tuner=%d, eeprom[0]=0x%02x\n",
747 core->name, core->tuner_type, eeprom_data[0]);
748}
749
750
751/* ----------------------------------------------------------------------- */
752
753static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
754{
755 struct tveeprom tv;
756
757 tveeprom_hauppauge_analog(&tv, eeprom_data);
758 core->tuner_type = tv.tuner_type;
759 core->has_radio = tv.has_radio;
760}
761
762static int hauppauge_eeprom_dvb(struct cx88_core *core, u8 *ee)
763{
764 int model;
765 int tuner;
766
767 /* Make sure we support the board model */
768 model = ee[0x1f] << 24 | ee[0x1e] << 16 | ee[0x1d] << 8 | ee[0x1c];
769 switch(model) {
770 case 90002:
771 case 90500:
772 case 90501:
773 /* known */
774 break;
775 default:
776 printk("%s: warning: unknown hauppauge model #%d\n",
777 core->name, model);
778 break;
779 }
780
781 /* Make sure we support the tuner */
782 tuner = ee[0x2d];
783 switch(tuner) {
784 case 0x4B: /* dtt 7595 */
785 case 0x4C: /* dtt 7592 */
786 break;
787 default:
788 printk("%s: error: unknown hauppauge tuner 0x%02x\n",
789 core->name, tuner);
790 return -ENODEV;
791 }
792 printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%d\n",
793 core->name, model, tuner);
794 return 0;
795}
796
797/* ----------------------------------------------------------------------- */
798/* some GDI (was: Modular Technology) specific stuff */
799
800static struct {
801 int id;
802 int fm;
803 char *name;
804} gdi_tuner[] = {
805 [ 0x01 ] = { .id = TUNER_ABSENT,
806 .name = "NTSC_M" },
807 [ 0x02 ] = { .id = TUNER_ABSENT,
808 .name = "PAL_B" },
809 [ 0x03 ] = { .id = TUNER_ABSENT,
810 .name = "PAL_I" },
811 [ 0x04 ] = { .id = TUNER_ABSENT,
812 .name = "PAL_D" },
813 [ 0x05 ] = { .id = TUNER_ABSENT,
814 .name = "SECAM" },
815
816 [ 0x10 ] = { .id = TUNER_ABSENT,
817 .fm = 1,
818 .name = "TEMIC_4049" },
819 [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5,
820 .name = "TEMIC_4136" },
821 [ 0x12 ] = { .id = TUNER_ABSENT,
822 .name = "TEMIC_4146" },
823
824 [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME,
825 .fm = 1,
826 .name = "PHILIPS_FQ1216_MK3" },
827 [ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1,
828 .name = "PHILIPS_FQ1236_MK3" },
829 [ 0x22 ] = { .id = TUNER_ABSENT,
830 .name = "PHILIPS_FI1236_MK3" },
831 [ 0x23 ] = { .id = TUNER_ABSENT,
832 .name = "PHILIPS_FI1216_MK3" },
833};
834
835static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
836{
837 char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
838 ? gdi_tuner[eeprom_data[0x0d]].name : NULL;
839
840 printk(KERN_INFO "%s: GDI: tuner=%s\n", core->name,
841 name ? name : "unknown");
842 if (NULL == name)
843 return;
844 core->tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
845 core->has_radio = gdi_tuner[eeprom_data[0x0d]].fm;
846}
847
848/* ----------------------------------------------------------------------- */
849
850void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
851{
852 int i;
853
854 if (0 == pci->subsystem_vendor &&
855 0 == pci->subsystem_device) {
856 printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n"
857 "%s: be autodetected. Please pass card=<n> insmod option to\n"
858 "%s: workaround that. Redirect complaints to the vendor of\n"
859 "%s: the TV card. Best regards,\n"
860 "%s: -- tux\n",
861 core->name,core->name,core->name,core->name,core->name);
862 } else {
863 printk("%s: Your board isn't known (yet) to the driver. You can\n"
864 "%s: try to pick one of the existing card configs via\n"
865 "%s: card=<n> insmod option. Updating to the latest\n"
866 "%s: version might help as well.\n",
867 core->name,core->name,core->name,core->name);
868 }
869 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
870 core->name);
871 for (i = 0; i < cx88_bcount; i++)
872 printk("%s: card=%d -> %s\n",
873 core->name, i, cx88_boards[i].name);
874}
875
876void cx88_card_setup(struct cx88_core *core)
877{
878 static u8 eeprom[128];
879
880 if (0 == core->i2c_rc) {
881 core->i2c_client.addr = 0xa0 >> 1;
882 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));
883 }
884
885 switch (core->board) {
886 case CX88_BOARD_HAUPPAUGE:
887 case CX88_BOARD_HAUPPAUGE_ROSLYN:
888 if (0 == core->i2c_rc)
889 hauppauge_eeprom(core,eeprom+8);
890 break;
891 case CX88_BOARD_GDI:
892 if (0 == core->i2c_rc)
893 gdi_eeprom(core,eeprom);
894 break;
895 case CX88_BOARD_WINFAST2000XP_EXPERT:
896 if (0 == core->i2c_rc)
897 leadtek_eeprom(core,eeprom);
898 break;
899 case CX88_BOARD_HAUPPAUGE_DVB_T1:
900 if (0 == core->i2c_rc)
901 hauppauge_eeprom_dvb(core,eeprom);
902 break;
903 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
904 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
905 /* GPIO0:0 is hooked to mt352 reset pin */
906 cx_set(MO_GP0_IO, 0x00000101);
907 cx_clear(MO_GP0_IO, 0x00000001);
908 msleep(1);
909 cx_set(MO_GP0_IO, 0x00000101);
910 break;
911 case CX88_BOARD_KWORLD_DVB_T:
912 case CX88_BOARD_DNTV_LIVE_DVB_T:
913 cx_set(MO_GP0_IO, 0x00000707);
914 cx_set(MO_GP2_IO, 0x00000101);
915 cx_clear(MO_GP2_IO, 0x00000001);
916 msleep(1);
917 cx_clear(MO_GP0_IO, 0x00000007);
918 cx_set(MO_GP2_IO, 0x00000101);
919 break;
920 }
921 if (cx88_boards[core->board].radio.type == CX88_RADIO)
922 core->has_radio = 1;
923}
924
925/* ------------------------------------------------------------------ */
926
927EXPORT_SYMBOL(cx88_boards);
928EXPORT_SYMBOL(cx88_bcount);
929EXPORT_SYMBOL(cx88_subids);
930EXPORT_SYMBOL(cx88_idcount);
931EXPORT_SYMBOL(cx88_card_list);
932EXPORT_SYMBOL(cx88_card_setup);
933
934/*
935 * Local variables:
936 * c-basic-offset: 8
937 * End:
938 */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
new file mode 100644
index 000000000000..26a6138015cb
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -0,0 +1,1239 @@
1/*
2 * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * driver core
6 *
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30#include <linux/kmod.h>
31#include <linux/sound.h>
32#include <linux/interrupt.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/videodev.h>
36
37#include "cx88.h"
38
39MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43/* ------------------------------------------------------------------ */
44
45static unsigned int core_debug = 0;
46module_param(core_debug,int,0644);
47MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
48
49static unsigned int latency = UNSET;
50module_param(latency,int,0444);
51MODULE_PARM_DESC(latency,"pci latency timer");
52
53static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
54static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
55
56module_param_array(tuner, int, NULL, 0444);
57module_param_array(card, int, NULL, 0444);
58
59MODULE_PARM_DESC(tuner,"tuner type");
60MODULE_PARM_DESC(card,"card type");
61
62static unsigned int nicam = 0;
63module_param(nicam,int,0644);
64MODULE_PARM_DESC(nicam,"tv audio is nicam");
65
66static unsigned int nocomb = 0;
67module_param(nocomb,int,0644);
68MODULE_PARM_DESC(nocomb,"disable comb filter");
69
70#define dprintk(level,fmt, arg...) if (core_debug >= level) \
71 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
72
73static unsigned int cx88_devcount;
74static LIST_HEAD(cx88_devlist);
75static DECLARE_MUTEX(devlist);
76
77/* ------------------------------------------------------------------ */
78/* debug help functions */
79
80static const char *v4l1_ioctls[] = {
81 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
82 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
83 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
84 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
85 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
86#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
87
88static const char *v4l2_ioctls[] = {
89 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
90 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
91 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
92 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
93 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
94 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
95 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
96 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
97 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
98 "S_MODULATOR"
99};
100#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
101
102void cx88_print_ioctl(char *name, unsigned int cmd)
103{
104 char *dir;
105
106 switch (_IOC_DIR(cmd)) {
107 case _IOC_NONE: dir = "--"; break;
108 case _IOC_READ: dir = "r-"; break;
109 case _IOC_WRITE: dir = "-w"; break;
110 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
111 default: dir = "??"; break;
112 }
113 switch (_IOC_TYPE(cmd)) {
114 case 'v':
115 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
116 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
117 v4l1_ioctls[_IOC_NR(cmd)] : "???");
118 break;
119 case 'V':
120 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
121 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
122 v4l2_ioctls[_IOC_NR(cmd)] : "???");
123 break;
124 default:
125 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
126 name, cmd, dir, _IOC_NR(cmd));
127 }
128}
129
130/* ------------------------------------------------------------------ */
131#define NO_SYNC_LINE (-1U)
132
133static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
134 unsigned int offset, u32 sync_line,
135 unsigned int bpl, unsigned int padding,
136 unsigned int lines)
137{
138 struct scatterlist *sg;
139 unsigned int line,todo;
140
141 /* sync instruction */
142 if (sync_line != NO_SYNC_LINE)
143 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
144
145 /* scan lines */
146 sg = sglist;
147 for (line = 0; line < lines; line++) {
148 while (offset && offset >= sg_dma_len(sg)) {
149 offset -= sg_dma_len(sg);
150 sg++;
151 }
152 if (bpl <= sg_dma_len(sg)-offset) {
153 /* fits into current chunk */
154 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
155 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
156 offset+=bpl;
157 } else {
158 /* scanline needs to be splitted */
159 todo = bpl;
160 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
161 (sg_dma_len(sg)-offset));
162 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
163 todo -= (sg_dma_len(sg)-offset);
164 offset = 0;
165 sg++;
166 while (todo > sg_dma_len(sg)) {
167 *(rp++)=cpu_to_le32(RISC_WRITE|
168 sg_dma_len(sg));
169 *(rp++)=cpu_to_le32(sg_dma_address(sg));
170 todo -= sg_dma_len(sg);
171 sg++;
172 }
173 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
174 *(rp++)=cpu_to_le32(sg_dma_address(sg));
175 offset += todo;
176 }
177 offset += padding;
178 }
179
180 return rp;
181}
182
183int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
184 struct scatterlist *sglist,
185 unsigned int top_offset, unsigned int bottom_offset,
186 unsigned int bpl, unsigned int padding, unsigned int lines)
187{
188 u32 instructions,fields;
189 u32 *rp;
190 int rc;
191
192 fields = 0;
193 if (UNSET != top_offset)
194 fields++;
195 if (UNSET != bottom_offset)
196 fields++;
197
198 /* estimate risc mem: worst case is one write per page border +
199 one write per scan line + syncs + jump (all 2 dwords) */
200 instructions = (bpl * lines * fields) / PAGE_SIZE + lines * fields;
201 instructions += 3 + 4;
202 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
203 return rc;
204
205 /* write risc instructions */
206 rp = risc->cpu;
207 if (UNSET != top_offset)
208 rp = cx88_risc_field(rp, sglist, top_offset, 0,
209 bpl, padding, lines);
210 if (UNSET != bottom_offset)
211 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
212 bpl, padding, lines);
213
214 /* save pointer to jmp instruction address */
215 risc->jmp = rp;
216 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
217 return 0;
218}
219
220int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
221 struct scatterlist *sglist, unsigned int bpl,
222 unsigned int lines)
223{
224 u32 instructions;
225 u32 *rp;
226 int rc;
227
228 /* estimate risc mem: worst case is one write per page border +
229 one write per scan line + syncs + jump (all 2 dwords) */
230 instructions = (bpl * lines) / PAGE_SIZE + lines;
231 instructions += 3 + 4;
232 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
233 return rc;
234
235 /* write risc instructions */
236 rp = risc->cpu;
237 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
238
239 /* save pointer to jmp instruction address */
240 risc->jmp = rp;
241 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
242 return 0;
243}
244
245int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
246 u32 reg, u32 mask, u32 value)
247{
248 u32 *rp;
249 int rc;
250
251 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
252 return rc;
253
254 /* write risc instructions */
255 rp = risc->cpu;
256 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
257 *(rp++) = cpu_to_le32(reg);
258 *(rp++) = cpu_to_le32(value);
259 *(rp++) = cpu_to_le32(mask);
260 *(rp++) = cpu_to_le32(RISC_JUMP);
261 *(rp++) = cpu_to_le32(risc->dma);
262 return 0;
263}
264
265void
266cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
267{
268 if (in_interrupt())
269 BUG();
270 videobuf_waiton(&buf->vb,0,0);
271 videobuf_dma_pci_unmap(pci, &buf->vb.dma);
272 videobuf_dma_free(&buf->vb.dma);
273 btcx_riscmem_free(pci, &buf->risc);
274 buf->vb.state = STATE_NEEDS_INIT;
275}
276
277/* ------------------------------------------------------------------ */
278/* our SRAM memory layout */
279
280/* we are going to put all thr risc programs into host memory, so we
281 * can use the whole SDRAM for the DMA fifos. To simplify things, we
282 * use a static memory layout. That surely will waste memory in case
283 * we don't use all DMA channels at the same time (which will be the
284 * case most of the time). But that still gives us enougth FIFO space
285 * to be able to deal with insane long pci latencies ...
286 *
287 * FIFO space allocations:
288 * channel 21 (y video) - 10.0k
289 * channel 22 (u video) - 2.0k
290 * channel 23 (v video) - 2.0k
291 * channel 24 (vbi) - 4.0k
292 * channels 25+26 (audio) - 0.5k
293 * channel 28 (mpeg) - 4.0k
294 * TOTAL = 25.5k
295 *
296 * Every channel has 160 bytes control data (64 bytes instruction
297 * queue and 6 CDT entries), which is close to 2k total.
298 *
299 * Address layout:
300 * 0x0000 - 0x03ff CMDs / reserved
301 * 0x0400 - 0x0bff instruction queues + CDs
302 * 0x0c00 - FIFOs
303 */
304
305struct sram_channel cx88_sram_channels[] = {
306 [SRAM_CH21] = {
307 .name = "video y / packed",
308 .cmds_start = 0x180040,
309 .ctrl_start = 0x180400,
310 .cdt = 0x180400 + 64,
311 .fifo_start = 0x180c00,
312 .fifo_size = 0x002800,
313 .ptr1_reg = MO_DMA21_PTR1,
314 .ptr2_reg = MO_DMA21_PTR2,
315 .cnt1_reg = MO_DMA21_CNT1,
316 .cnt2_reg = MO_DMA21_CNT2,
317 },
318 [SRAM_CH22] = {
319 .name = "video u",
320 .cmds_start = 0x180080,
321 .ctrl_start = 0x1804a0,
322 .cdt = 0x1804a0 + 64,
323 .fifo_start = 0x183400,
324 .fifo_size = 0x000800,
325 .ptr1_reg = MO_DMA22_PTR1,
326 .ptr2_reg = MO_DMA22_PTR2,
327 .cnt1_reg = MO_DMA22_CNT1,
328 .cnt2_reg = MO_DMA22_CNT2,
329 },
330 [SRAM_CH23] = {
331 .name = "video v",
332 .cmds_start = 0x1800c0,
333 .ctrl_start = 0x180540,
334 .cdt = 0x180540 + 64,
335 .fifo_start = 0x183c00,
336 .fifo_size = 0x000800,
337 .ptr1_reg = MO_DMA23_PTR1,
338 .ptr2_reg = MO_DMA23_PTR2,
339 .cnt1_reg = MO_DMA23_CNT1,
340 .cnt2_reg = MO_DMA23_CNT2,
341 },
342 [SRAM_CH24] = {
343 .name = "vbi",
344 .cmds_start = 0x180100,
345 .ctrl_start = 0x1805e0,
346 .cdt = 0x1805e0 + 64,
347 .fifo_start = 0x184400,
348 .fifo_size = 0x001000,
349 .ptr1_reg = MO_DMA24_PTR1,
350 .ptr2_reg = MO_DMA24_PTR2,
351 .cnt1_reg = MO_DMA24_CNT1,
352 .cnt2_reg = MO_DMA24_CNT2,
353 },
354 [SRAM_CH25] = {
355 .name = "audio from",
356 .cmds_start = 0x180140,
357 .ctrl_start = 0x180680,
358 .cdt = 0x180680 + 64,
359 .fifo_start = 0x185400,
360 .fifo_size = 0x000200,
361 .ptr1_reg = MO_DMA25_PTR1,
362 .ptr2_reg = MO_DMA25_PTR2,
363 .cnt1_reg = MO_DMA25_CNT1,
364 .cnt2_reg = MO_DMA25_CNT2,
365 },
366 [SRAM_CH26] = {
367 .name = "audio to",
368 .cmds_start = 0x180180,
369 .ctrl_start = 0x180720,
370 .cdt = 0x180680 + 64, /* same as audio IN */
371 .fifo_start = 0x185400, /* same as audio IN */
372 .fifo_size = 0x000200, /* same as audio IN */
373 .ptr1_reg = MO_DMA26_PTR1,
374 .ptr2_reg = MO_DMA26_PTR2,
375 .cnt1_reg = MO_DMA26_CNT1,
376 .cnt2_reg = MO_DMA26_CNT2,
377 },
378 [SRAM_CH28] = {
379 .name = "mpeg",
380 .cmds_start = 0x180200,
381 .ctrl_start = 0x1807C0,
382 .cdt = 0x1807C0 + 64,
383 .fifo_start = 0x185600,
384 .fifo_size = 0x001000,
385 .ptr1_reg = MO_DMA28_PTR1,
386 .ptr2_reg = MO_DMA28_PTR2,
387 .cnt1_reg = MO_DMA28_CNT1,
388 .cnt2_reg = MO_DMA28_CNT2,
389 },
390};
391
392int cx88_sram_channel_setup(struct cx88_core *core,
393 struct sram_channel *ch,
394 unsigned int bpl, u32 risc)
395{
396 unsigned int i,lines;
397 u32 cdt;
398
399 bpl = (bpl + 7) & ~7; /* alignment */
400 cdt = ch->cdt;
401 lines = ch->fifo_size / bpl;
402 if (lines > 6)
403 lines = 6;
404 BUG_ON(lines < 2);
405
406 /* write CDT */
407 for (i = 0; i < lines; i++)
408 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
409
410 /* write CMDS */
411 cx_write(ch->cmds_start + 0, risc);
412 cx_write(ch->cmds_start + 4, cdt);
413 cx_write(ch->cmds_start + 8, (lines*16) >> 3);
414 cx_write(ch->cmds_start + 12, ch->ctrl_start);
415 cx_write(ch->cmds_start + 16, 64 >> 2);
416 for (i = 20; i < 64; i += 4)
417 cx_write(ch->cmds_start + i, 0);
418
419 /* fill registers */
420 cx_write(ch->ptr1_reg, ch->fifo_start);
421 cx_write(ch->ptr2_reg, cdt);
422 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
423 cx_write(ch->cnt2_reg, (lines*16) >> 3);
424
425 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
426 return 0;
427}
428
429/* ------------------------------------------------------------------ */
430/* debug helper code */
431
432int cx88_risc_decode(u32 risc)
433{
434 static char *instr[16] = {
435 [ RISC_SYNC >> 28 ] = "sync",
436 [ RISC_WRITE >> 28 ] = "write",
437 [ RISC_WRITEC >> 28 ] = "writec",
438 [ RISC_READ >> 28 ] = "read",
439 [ RISC_READC >> 28 ] = "readc",
440 [ RISC_JUMP >> 28 ] = "jump",
441 [ RISC_SKIP >> 28 ] = "skip",
442 [ RISC_WRITERM >> 28 ] = "writerm",
443 [ RISC_WRITECM >> 28 ] = "writecm",
444 [ RISC_WRITECR >> 28 ] = "writecr",
445 };
446 static int incr[16] = {
447 [ RISC_WRITE >> 28 ] = 2,
448 [ RISC_JUMP >> 28 ] = 2,
449 [ RISC_WRITERM >> 28 ] = 3,
450 [ RISC_WRITECM >> 28 ] = 3,
451 [ RISC_WRITECR >> 28 ] = 4,
452 };
453 static char *bits[] = {
454 "12", "13", "14", "resync",
455 "cnt0", "cnt1", "18", "19",
456 "20", "21", "22", "23",
457 "irq1", "irq2", "eol", "sol",
458 };
459 int i;
460
461 printk("0x%08x [ %s", risc,
462 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
463 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
464 if (risc & (1 << (i + 12)))
465 printk(" %s",bits[i]);
466 printk(" count=%d ]\n", risc & 0xfff);
467 return incr[risc >> 28] ? incr[risc >> 28] : 1;
468}
469
470#if 0 /* currently unused, but useful for debugging */
471void cx88_risc_disasm(struct cx88_core *core,
472 struct btcx_riscmem *risc)
473{
474 unsigned int i,j,n;
475
476 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
477 core->name, risc->cpu, (unsigned long)risc->dma);
478 for (i = 0; i < (risc->size >> 2); i += n) {
479 printk("%s: %04d: ", core->name, i);
480 n = cx88_risc_decode(risc->cpu[i]);
481 for (j = 1; j < n; j++)
482 printk("%s: %04d: 0x%08x [ arg #%d ]\n",
483 core->name, i+j, risc->cpu[i+j], j);
484 if (risc->cpu[i] == RISC_JUMP)
485 break;
486 }
487}
488#endif
489
490void cx88_sram_channel_dump(struct cx88_core *core,
491 struct sram_channel *ch)
492{
493 static char *name[] = {
494 "initial risc",
495 "cdt base",
496 "cdt size",
497 "iq base",
498 "iq size",
499 "risc pc",
500 "iq wr ptr",
501 "iq rd ptr",
502 "cdt current",
503 "pci target",
504 "line / byte",
505 };
506 u32 risc;
507 unsigned int i,j,n;
508
509 printk("%s: %s - dma channel status dump\n",
510 core->name,ch->name);
511 for (i = 0; i < ARRAY_SIZE(name); i++)
512 printk("%s: cmds: %-12s: 0x%08x\n",
513 core->name,name[i],
514 cx_read(ch->cmds_start + 4*i));
515 for (i = 0; i < 4; i++) {
516 risc = cx_read(ch->cmds_start + 4 * (i+11));
517 printk("%s: risc%d: ", core->name, i);
518 cx88_risc_decode(risc);
519 }
520 for (i = 0; i < 16; i += n) {
521 risc = cx_read(ch->ctrl_start + 4 * i);
522 printk("%s: iq %x: ", core->name, i);
523 n = cx88_risc_decode(risc);
524 for (j = 1; j < n; j++) {
525 risc = cx_read(ch->ctrl_start + 4 * (i+j));
526 printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
527 core->name, i+j, risc, j);
528 }
529 }
530
531 printk("%s: fifo: 0x%08x -> 0x%x\n",
532 core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
533 printk("%s: ctrl: 0x%08x -> 0x%x\n",
534 core->name, ch->ctrl_start, ch->ctrl_start+6*16);
535 printk("%s: ptr1_reg: 0x%08x\n",
536 core->name,cx_read(ch->ptr1_reg));
537 printk("%s: ptr2_reg: 0x%08x\n",
538 core->name,cx_read(ch->ptr2_reg));
539 printk("%s: cnt1_reg: 0x%08x\n",
540 core->name,cx_read(ch->cnt1_reg));
541 printk("%s: cnt2_reg: 0x%08x\n",
542 core->name,cx_read(ch->cnt2_reg));
543}
544
545char *cx88_pci_irqs[32] = {
546 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
547 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
548 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
549 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
550};
551char *cx88_vid_irqs[32] = {
552 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
553 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
554 "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
555 "y_sync", "u_sync", "v_sync", "vbi_sync",
556 "opc_err", "par_err", "rip_err", "pci_abort",
557};
558char *cx88_mpeg_irqs[32] = {
559 "ts_risci1", NULL, NULL, NULL,
560 "ts_risci2", NULL, NULL, NULL,
561 "ts_oflow", NULL, NULL, NULL,
562 "ts_sync", NULL, NULL, NULL,
563 "opc_err", "par_err", "rip_err", "pci_abort",
564 "ts_err?",
565};
566
567void cx88_print_irqbits(char *name, char *tag, char **strings,
568 u32 bits, u32 mask)
569{
570 unsigned int i;
571
572 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
573 for (i = 0; i < 32; i++) {
574 if (!(bits & (1 << i)))
575 continue;
576 if (strings[i])
577 printk(" %s", strings[i]);
578 else
579 printk(" %d", i);
580 if (!(mask & (1 << i)))
581 continue;
582 printk("*");
583 }
584 printk("\n");
585}
586
587/* ------------------------------------------------------------------ */
588
589int cx88_core_irq(struct cx88_core *core, u32 status)
590{
591 int handled = 0;
592
593 if (status & (1<<18)) {
594 cx88_ir_irq(core);
595 handled++;
596 }
597 if (!handled)
598 cx88_print_irqbits(core->name, "irq pci",
599 cx88_pci_irqs, status,
600 core->pci_irqmask);
601 return handled;
602}
603
604void cx88_wakeup(struct cx88_core *core,
605 struct cx88_dmaqueue *q, u32 count)
606{
607 struct cx88_buffer *buf;
608 int bc;
609
610 for (bc = 0;; bc++) {
611 if (list_empty(&q->active))
612 break;
613 buf = list_entry(q->active.next,
614 struct cx88_buffer, vb.queue);
615#if 0
616 if (buf->count > count)
617 break;
618#else
619 /* count comes from the hw and is is 16bit wide --
620 * this trick handles wrap-arounds correctly for
621 * up to 32767 buffers in flight... */
622 if ((s16) (count - buf->count) < 0)
623 break;
624#endif
625 do_gettimeofday(&buf->vb.ts);
626 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
627 count, buf->count);
628 buf->vb.state = STATE_DONE;
629 list_del(&buf->vb.queue);
630 wake_up(&buf->vb.done);
631 }
632 if (list_empty(&q->active)) {
633 del_timer(&q->timeout);
634 } else {
635 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
636 }
637 if (bc != 1)
638 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
639}
640
641void cx88_shutdown(struct cx88_core *core)
642{
643 /* disable RISC controller + IRQs */
644 cx_write(MO_DEV_CNTRL2, 0);
645
646 /* stop dma transfers */
647 cx_write(MO_VID_DMACNTRL, 0x0);
648 cx_write(MO_AUD_DMACNTRL, 0x0);
649 cx_write(MO_TS_DMACNTRL, 0x0);
650 cx_write(MO_VIP_DMACNTRL, 0x0);
651 cx_write(MO_GPHST_DMACNTRL, 0x0);
652
653 /* stop interrupts */
654 cx_write(MO_PCI_INTMSK, 0x0);
655 cx_write(MO_VID_INTMSK, 0x0);
656 cx_write(MO_AUD_INTMSK, 0x0);
657 cx_write(MO_TS_INTMSK, 0x0);
658 cx_write(MO_VIP_INTMSK, 0x0);
659 cx_write(MO_GPHST_INTMSK, 0x0);
660
661 /* stop capturing */
662 cx_write(VID_CAPTURE_CONTROL, 0);
663}
664
665int cx88_reset(struct cx88_core *core)
666{
667 dprintk(1,"%s\n",__FUNCTION__);
668 cx88_shutdown(core);
669
670 /* clear irq status */
671 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
672 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
673 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
674
675 /* wait a bit */
676 msleep(100);
677
678 /* init sram */
679 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
680 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
681 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
682 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
683 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
684 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
685 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
686
687 /* misc init ... */
688 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
689 (1 << 12) | // agc gain
690 (1 << 11) | // adaptibe agc
691 (0 << 10) | // chroma agc
692 (0 << 9) | // ckillen
693 (7)));
694
695 /* setup image format */
696 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
697
698 /* setup FIFO Threshholds */
699 cx_write(MO_PDMA_STHRSH, 0x0807);
700 cx_write(MO_PDMA_DTHRSH, 0x0807);
701
702 /* fixes flashing of image */
703 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
704 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
705
706 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
707 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
708 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
709
710 /* Reset on-board parts */
711 cx_write(MO_SRST_IO, 0);
712 msleep(10);
713 cx_write(MO_SRST_IO, 1);
714
715 return 0;
716}
717
718/* ------------------------------------------------------------------ */
719
720static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
721{
722 return (norm->id & V4L2_STD_625_50) ? 922 : 754;
723}
724
725static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
726{
727 return (norm->id & V4L2_STD_625_50) ? 186 : 135;
728}
729
730static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
731{
732 return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
733}
734
735static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
736{
737 static const unsigned int ntsc = 28636360;
738 static const unsigned int pal = 35468950;
739
740 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
741}
742
743static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
744{
745 return (norm->id & V4L2_STD_625_50)
746 ? HLNotchFilter135PAL
747 : HLNotchFilter135NTSC;
748}
749
750static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
751{
752 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
753}
754
755static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
756{
757 return (norm->id & V4L2_STD_625_50) ? 511 : 288;
758}
759
760int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
761 enum v4l2_field field)
762{
763 unsigned int swidth = norm_swidth(core->tvnorm);
764 unsigned int sheight = norm_maxh(core->tvnorm);
765 u32 value;
766
767 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
768 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
769 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
770 core->tvnorm->name);
771 if (!V4L2_FIELD_HAS_BOTH(field))
772 height *= 2;
773
774 // recalc H delay and scale registers
775 value = (width * norm_hdelay(core->tvnorm)) / swidth;
776 value &= 0x3fe;
777 cx_write(MO_HDELAY_EVEN, value);
778 cx_write(MO_HDELAY_ODD, value);
779 dprintk(1,"set_scale: hdelay 0x%04x\n", value);
780
781 value = (swidth * 4096 / width) - 4096;
782 cx_write(MO_HSCALE_EVEN, value);
783 cx_write(MO_HSCALE_ODD, value);
784 dprintk(1,"set_scale: hscale 0x%04x\n", value);
785
786 cx_write(MO_HACTIVE_EVEN, width);
787 cx_write(MO_HACTIVE_ODD, width);
788 dprintk(1,"set_scale: hactive 0x%04x\n", width);
789
790 // recalc V scale Register (delay is constant)
791 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
792 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
793 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
794
795 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
796 cx_write(MO_VSCALE_EVEN, value);
797 cx_write(MO_VSCALE_ODD, value);
798 dprintk(1,"set_scale: vscale 0x%04x\n", value);
799
800 cx_write(MO_VACTIVE_EVEN, sheight);
801 cx_write(MO_VACTIVE_ODD, sheight);
802 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
803
804 // setup filters
805 value = 0;
806 value |= (1 << 19); // CFILT (default)
807 if (core->tvnorm->id & V4L2_STD_SECAM) {
808 value |= (1 << 15);
809 value |= (1 << 16);
810 }
811 if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
812 value |= (1 << 13) | (1 << 5);
813 if (V4L2_FIELD_INTERLACED == field)
814 value |= (1 << 3); // VINT (interlaced vertical scaling)
815 if (width < 385)
816 value |= (1 << 0); // 3-tap interpolation
817 if (width < 193)
818 value |= (1 << 1); // 5-tap interpolation
819 if (nocomb)
820 value |= (3 << 5); // disable comb filter
821
822 cx_write(MO_FILTER_EVEN, value);
823 cx_write(MO_FILTER_ODD, value);
824 dprintk(1,"set_scale: filter 0x%04x\n", value);
825
826 return 0;
827}
828
829static const u32 xtal = 28636363;
830
831static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
832{
833 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
834 u64 pll;
835 u32 reg;
836 int i;
837
838 if (prescale < 2)
839 prescale = 2;
840 if (prescale > 5)
841 prescale = 5;
842
843 pll = ofreq * 8 * prescale * (u64)(1 << 20);
844 do_div(pll,xtal);
845 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
846 if (((reg >> 20) & 0x3f) < 14) {
847 printk("%s/0: pll out of range\n",core->name);
848 return -1;
849 }
850
851 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
852 reg, cx_read(MO_PLL_REG), ofreq);
853 cx_write(MO_PLL_REG, reg);
854 for (i = 0; i < 100; i++) {
855 reg = cx_read(MO_DEVICE_STATUS);
856 if (reg & (1<<2)) {
857 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
858 prescale,ofreq);
859 return 0;
860 }
861 dprintk(1,"pll not locked yet, waiting ...\n");
862 msleep(10);
863 }
864 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
865 return -1;
866}
867
868static int set_tvaudio(struct cx88_core *core)
869{
870 struct cx88_tvnorm *norm = core->tvnorm;
871
872 if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
873 return 0;
874
875 if (V4L2_STD_PAL_BG & norm->id) {
876 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
877
878 } else if (V4L2_STD_PAL_DK & norm->id) {
879 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
880
881 } else if (V4L2_STD_PAL_I & norm->id) {
882 core->tvaudio = WW_NICAM_I;
883
884 } else if (V4L2_STD_SECAM_L & norm->id) {
885 core->tvaudio = WW_SYSTEM_L_AM;
886
887 } else if (V4L2_STD_SECAM_DK & norm->id) {
888 core->tvaudio = WW_A2_DK;
889
890 } else if ((V4L2_STD_NTSC_M & norm->id) ||
891 (V4L2_STD_PAL_M & norm->id)) {
892 core->tvaudio = WW_BTSC;
893
894 } else if (V4L2_STD_NTSC_M_JP & norm->id) {
895 core->tvaudio = WW_EIAJ;
896
897 } else {
898 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
899 core->name, norm->name);
900 core->tvaudio = 0;
901 return 0;
902 }
903
904 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
905 cx88_set_tvaudio(core);
906 // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
907
908 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
909 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
910 cx_write(MO_AUD_DMACNTRL, 0x03); /* need audio fifo */
911 return 0;
912}
913
914int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
915{
916 u32 fsc8;
917 u32 adc_clock;
918 u32 vdec_clock;
919 u32 step_db,step_dr;
920 u64 tmp64;
921 u32 bdelay,agcdelay,htotal;
922
923 core->tvnorm = norm;
924 fsc8 = norm_fsc8(norm);
925 adc_clock = xtal;
926 vdec_clock = fsc8;
927 step_db = fsc8;
928 step_dr = fsc8;
929
930 if (norm->id & V4L2_STD_SECAM) {
931 step_db = 4250000 * 8;
932 step_dr = 4406250 * 8;
933 }
934
935 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
936 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
937 set_pll(core,2,vdec_clock);
938
939 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
940 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
941 cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
942
943#if 1
944 // FIXME: as-is from DScaler
945 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
946 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
947 cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
948#endif
949
950 // MO_SCONV_REG = adc clock / video dec clock * 2^17
951 tmp64 = adc_clock * (u64)(1 << 17);
952 do_div(tmp64, vdec_clock);
953 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
954 (u32)tmp64, cx_read(MO_SCONV_REG));
955 cx_write(MO_SCONV_REG, (u32)tmp64);
956
957 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
958 tmp64 = step_db * (u64)(1 << 22);
959 do_div(tmp64, vdec_clock);
960 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
961 (u32)tmp64, cx_read(MO_SUB_STEP));
962 cx_write(MO_SUB_STEP, (u32)tmp64);
963
964 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
965 tmp64 = step_dr * (u64)(1 << 22);
966 do_div(tmp64, vdec_clock);
967 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
968 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
969 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
970
971 // bdelay + agcdelay
972 bdelay = vdec_clock * 65 / 20000000 + 21;
973 agcdelay = vdec_clock * 68 / 20000000 + 15;
974 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
975 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
976 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
977
978 // htotal
979 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
980 do_div(tmp64, fsc8);
981 htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
982 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
983 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
984 cx_write(MO_HTOTAL, htotal);
985
986 // vbi stuff
987 cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */
988 norm_vbipack(norm)));
989
990 // this is needed as well to set all tvnorm parameter
991 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
992
993 // audio
994 set_tvaudio(core);
995
996 // tell i2c chips
997#ifdef V4L2_I2C_CLIENTS
998 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
999#else
1000 {
1001 struct video_channel c;
1002 memset(&c,0,sizeof(c));
1003 c.channel = core->input;
1004 c.norm = VIDEO_MODE_PAL;
1005 if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
1006 c.norm = VIDEO_MODE_NTSC;
1007 if (norm->id & V4L2_STD_SECAM)
1008 c.norm = VIDEO_MODE_SECAM;
1009 cx88_call_i2c_clients(core,VIDIOCSCHAN,&c);
1010 }
1011#endif
1012
1013 // done
1014 return 0;
1015}
1016
1017/* ------------------------------------------------------------------ */
1018
1019static int cx88_pci_quirks(char *name, struct pci_dev *pci)
1020{
1021 unsigned int lat = UNSET;
1022 u8 ctrl = 0;
1023 u8 value;
1024
1025 /* check pci quirks */
1026 if (pci_pci_problems & PCIPCI_TRITON) {
1027 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
1028 name);
1029 ctrl |= CX88X_EN_TBFX;
1030 }
1031 if (pci_pci_problems & PCIPCI_NATOMA) {
1032 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
1033 name);
1034 ctrl |= CX88X_EN_TBFX;
1035 }
1036 if (pci_pci_problems & PCIPCI_VIAETBF) {
1037 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
1038 name);
1039 ctrl |= CX88X_EN_TBFX;
1040 }
1041 if (pci_pci_problems & PCIPCI_VSFX) {
1042 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
1043 name);
1044 ctrl |= CX88X_EN_VSFX;
1045 }
1046#ifdef PCIPCI_ALIMAGIK
1047 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
1048 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
1049 name);
1050 lat = 0x0A;
1051 }
1052#endif
1053
1054 /* check insmod options */
1055 if (UNSET != latency)
1056 lat = latency;
1057
1058 /* apply stuff */
1059 if (ctrl) {
1060 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
1061 value |= ctrl;
1062 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1063 }
1064 if (UNSET != lat) {
1065 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1066 name, latency);
1067 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1068 }
1069 return 0;
1070}
1071
1072/* ------------------------------------------------------------------ */
1073
1074struct video_device *cx88_vdev_init(struct cx88_core *core,
1075 struct pci_dev *pci,
1076 struct video_device *template,
1077 char *type)
1078{
1079 struct video_device *vfd;
1080
1081 vfd = video_device_alloc();
1082 if (NULL == vfd)
1083 return NULL;
1084 *vfd = *template;
1085 vfd->minor = -1;
1086 vfd->dev = &pci->dev;
1087 vfd->release = video_device_release;
1088 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1089 core->name, type, cx88_boards[core->board].name);
1090 return vfd;
1091}
1092
1093static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1094{
1095 if (request_mem_region(pci_resource_start(pci,0),
1096 pci_resource_len(pci,0),
1097 core->name))
1098 return 0;
1099 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
1100 core->name,pci_resource_start(pci,0));
1101 return -EBUSY;
1102}
1103
1104struct cx88_core* cx88_core_get(struct pci_dev *pci)
1105{
1106 struct cx88_core *core;
1107 struct list_head *item;
1108 int i;
1109
1110 down(&devlist);
1111 list_for_each(item,&cx88_devlist) {
1112 core = list_entry(item, struct cx88_core, devlist);
1113 if (pci->bus->number != core->pci_bus)
1114 continue;
1115 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1116 continue;
1117
1118 if (0 != get_ressources(core,pci))
1119 goto fail_unlock;
1120 atomic_inc(&core->refcount);
1121 up(&devlist);
1122 return core;
1123 }
1124 core = kmalloc(sizeof(*core),GFP_KERNEL);
1125 if (NULL == core)
1126 goto fail_unlock;
1127
1128 memset(core,0,sizeof(*core));
1129 atomic_inc(&core->refcount);
1130 core->pci_bus = pci->bus->number;
1131 core->pci_slot = PCI_SLOT(pci->devfn);
1132 core->pci_irqmask = 0x00fc00;
1133
1134 core->nr = cx88_devcount++;
1135 sprintf(core->name,"cx88[%d]",core->nr);
1136 if (0 != get_ressources(core,pci)) {
1137 cx88_devcount--;
1138 goto fail_free;
1139 }
1140 list_add_tail(&core->devlist,&cx88_devlist);
1141
1142 /* PCI stuff */
1143 cx88_pci_quirks(core->name, pci);
1144 core->lmmio = ioremap(pci_resource_start(pci,0),
1145 pci_resource_len(pci,0));
1146 core->bmmio = (u8 __iomem *)core->lmmio;
1147
1148 /* board config */
1149 core->board = UNSET;
1150 if (card[core->nr] < cx88_bcount)
1151 core->board = card[core->nr];
1152 for (i = 0; UNSET == core->board && i < cx88_idcount; i++)
1153 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1154 pci->subsystem_device == cx88_subids[i].subdevice)
1155 core->board = cx88_subids[i].card;
1156 if (UNSET == core->board) {
1157 core->board = CX88_BOARD_UNKNOWN;
1158 cx88_card_list(core,pci);
1159 }
1160 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1161 core->name,pci->subsystem_vendor,
1162 pci->subsystem_device,cx88_boards[core->board].name,
1163 core->board, card[core->nr] == core->board ?
1164 "insmod option" : "autodetected");
1165
1166 core->tuner_type = tuner[core->nr];
1167 if (UNSET == core->tuner_type)
1168 core->tuner_type = cx88_boards[core->board].tuner_type;
1169 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1170
1171 /* init hardware */
1172 cx88_reset(core);
1173 cx88_i2c_init(core,pci);
1174 cx88_card_setup(core);
1175 cx88_ir_init(core,pci);
1176
1177 up(&devlist);
1178 return core;
1179
1180fail_free:
1181 kfree(core);
1182fail_unlock:
1183 up(&devlist);
1184 return NULL;
1185}
1186
1187void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1188{
1189 release_mem_region(pci_resource_start(pci,0),
1190 pci_resource_len(pci,0));
1191
1192 if (!atomic_dec_and_test(&core->refcount))
1193 return;
1194
1195 down(&devlist);
1196 cx88_ir_fini(core);
1197 if (0 == core->i2c_rc)
1198 i2c_bit_del_bus(&core->i2c_adap);
1199 list_del(&core->devlist);
1200 iounmap(core->lmmio);
1201 cx88_devcount--;
1202 up(&devlist);
1203 kfree(core);
1204}
1205
1206/* ------------------------------------------------------------------ */
1207
1208EXPORT_SYMBOL(cx88_print_ioctl);
1209EXPORT_SYMBOL(cx88_pci_irqs);
1210EXPORT_SYMBOL(cx88_vid_irqs);
1211EXPORT_SYMBOL(cx88_mpeg_irqs);
1212EXPORT_SYMBOL(cx88_print_irqbits);
1213
1214EXPORT_SYMBOL(cx88_core_irq);
1215EXPORT_SYMBOL(cx88_wakeup);
1216EXPORT_SYMBOL(cx88_reset);
1217EXPORT_SYMBOL(cx88_shutdown);
1218
1219EXPORT_SYMBOL(cx88_risc_buffer);
1220EXPORT_SYMBOL(cx88_risc_databuffer);
1221EXPORT_SYMBOL(cx88_risc_stopper);
1222EXPORT_SYMBOL(cx88_free_buffer);
1223
1224EXPORT_SYMBOL(cx88_sram_channels);
1225EXPORT_SYMBOL(cx88_sram_channel_setup);
1226EXPORT_SYMBOL(cx88_sram_channel_dump);
1227
1228EXPORT_SYMBOL(cx88_set_tvnorm);
1229EXPORT_SYMBOL(cx88_set_scale);
1230
1231EXPORT_SYMBOL(cx88_vdev_init);
1232EXPORT_SYMBOL(cx88_core_get);
1233EXPORT_SYMBOL(cx88_core_put);
1234
1235/*
1236 * Local variables:
1237 * c-basic-offset: 8
1238 * End:
1239 */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
new file mode 100644
index 000000000000..bc6f18c45357
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -0,0 +1,381 @@
1/*
2 * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines
6 *
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/device.h>
28#include <linux/fs.h>
29#include <linux/kthread.h>
30#include <linux/file.h>
31#include <linux/suspend.h>
32
33/* those two frontends need merging via linuxtv cvs ... */
34#define HAVE_CX22702 0
35#define HAVE_OR51132 1
36
37#include "cx88.h"
38#include "dvb-pll.h"
39#include "mt352.h"
40#include "mt352_priv.h"
41#if HAVE_CX22702
42# include "cx22702.h"
43#endif
44#if HAVE_OR51132
45# include "or51132.h"
46#endif
47
48MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
49MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
50MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
51MODULE_LICENSE("GPL");
52
53static unsigned int debug = 0;
54module_param(debug, int, 0644);
55MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
56
57#define dprintk(level,fmt, arg...) if (debug >= level) \
58 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
59
60/* ------------------------------------------------------------------ */
61
62static int dvb_buf_setup(struct videobuf_queue *q,
63 unsigned int *count, unsigned int *size)
64{
65 struct cx8802_dev *dev = q->priv_data;
66
67 dev->ts_packet_size = 188 * 4;
68 dev->ts_packet_count = 32;
69
70 *size = dev->ts_packet_size * dev->ts_packet_count;
71 *count = 32;
72 return 0;
73}
74
75static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
76 enum v4l2_field field)
77{
78 struct cx8802_dev *dev = q->priv_data;
79 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb);
80}
81
82static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
83{
84 struct cx8802_dev *dev = q->priv_data;
85 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
86}
87
88static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
89{
90 struct cx8802_dev *dev = q->priv_data;
91 cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
92}
93
94struct videobuf_queue_ops dvb_qops = {
95 .buf_setup = dvb_buf_setup,
96 .buf_prepare = dvb_buf_prepare,
97 .buf_queue = dvb_buf_queue,
98 .buf_release = dvb_buf_release,
99};
100
101/* ------------------------------------------------------------------ */
102
103static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
104{
105 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
106 static u8 reset [] = { RESET, 0x80 };
107 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
108 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
109 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
110 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
111
112 mt352_write(fe, clock_config, sizeof(clock_config));
113 udelay(200);
114 mt352_write(fe, reset, sizeof(reset));
115 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
116
117 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
118 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
119 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
120 return 0;
121}
122
123static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
124{
125 static u8 clock_config [] = { 0x89, 0x38, 0x39 };
126 static u8 reset [] = { 0x50, 0x80 };
127 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
128 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
129 0x00, 0xFF, 0x00, 0x40, 0x40 };
130 static u8 dntv_extra[] = { 0xB5, 0x7A };
131 static u8 capt_range_cfg[] = { 0x75, 0x32 };
132
133 mt352_write(fe, clock_config, sizeof(clock_config));
134 udelay(2000);
135 mt352_write(fe, reset, sizeof(reset));
136 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
137
138 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
139 udelay(2000);
140 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
141 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
142
143 return 0;
144}
145
146static int mt352_pll_set(struct dvb_frontend* fe,
147 struct dvb_frontend_parameters* params,
148 u8* pllbuf)
149{
150 struct cx8802_dev *dev= fe->dvb->priv;
151
152 pllbuf[0] = dev->core->pll_addr << 1;
153 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
154 params->frequency,
155 params->u.ofdm.bandwidth);
156 return 0;
157}
158
159static struct mt352_config dvico_fusionhdtv = {
160 .demod_address = 0x0F,
161 .demod_init = dvico_fusionhdtv_demod_init,
162 .pll_set = mt352_pll_set,
163};
164
165static struct mt352_config dntv_live_dvbt_config = {
166 .demod_address = 0x0f,
167 .demod_init = dntv_live_dvbt_demod_init,
168 .pll_set = mt352_pll_set,
169};
170
171#if HAVE_CX22702
172static struct cx22702_config connexant_refboard_config = {
173 .demod_address = 0x43,
174 .pll_address = 0x60,
175 .pll_desc = &dvb_pll_thomson_dtt7579,
176};
177
178static struct cx22702_config hauppauge_novat_config = {
179 .demod_address = 0x43,
180 .pll_address = 0x61,
181 .pll_desc = &dvb_pll_thomson_dtt759x,
182};
183#endif
184
185#if HAVE_OR51132
186static int or51132_set_ts_param(struct dvb_frontend* fe,
187 int is_punctured)
188{
189 struct cx8802_dev *dev= fe->dvb->priv;
190 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
191 return 0;
192}
193
194struct or51132_config pchdtv_hd3000 = {
195 .demod_address = 0x15,
196 .pll_address = 0x61,
197 .pll_desc = &dvb_pll_thomson_dtt7610,
198 .set_ts_params = or51132_set_ts_param,
199};
200#endif
201
202static int dvb_register(struct cx8802_dev *dev)
203{
204 /* init struct videobuf_dvb */
205 dev->dvb.name = dev->core->name;
206 dev->ts_gen_cntrl = 0x0c;
207
208 /* init frontend */
209 switch (dev->core->board) {
210#if HAVE_CX22702
211 case CX88_BOARD_HAUPPAUGE_DVB_T1:
212 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
213 &dev->core->i2c_adap);
214 break;
215 case CX88_BOARD_CONEXANT_DVB_T1:
216 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
217 &dev->core->i2c_adap);
218 break;
219#endif
220 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
221 dev->core->pll_addr = 0x61;
222 dev->core->pll_desc = &dvb_pll_lg_z201;
223 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
224 &dev->core->i2c_adap);
225 break;
226 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
227 dev->core->pll_addr = 0x60;
228 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
229 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
230 &dev->core->i2c_adap);
231 break;
232 case CX88_BOARD_KWORLD_DVB_T:
233 case CX88_BOARD_DNTV_LIVE_DVB_T:
234 dev->core->pll_addr = 0x61;
235 dev->core->pll_desc = &dvb_pll_unknown_1;
236 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
237 &dev->core->i2c_adap);
238 break;
239#if HAVE_OR51132
240 case CX88_BOARD_PCHDTV_HD3000:
241 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
242 &dev->core->i2c_adap);
243 break;
244#endif
245 default:
246 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n"
247 "%s: you might want to look out for patches here:\n"
248 "%s: http://dl.bytesex.org/patches/\n",
249 dev->core->name, dev->core->name, dev->core->name);
250 break;
251 }
252 if (NULL == dev->dvb.frontend) {
253 printk("%s: frontend initialization failed\n",dev->core->name);
254 return -1;
255 }
256
257 if (dev->core->pll_desc) {
258 dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
259 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
260 }
261
262 /* Copy the board name into the DVB structure */
263 strlcpy(dev->dvb.frontend->ops->info.name,
264 cx88_boards[dev->core->board].name,
265 sizeof(dev->dvb.frontend->ops->info.name));
266
267 /* register everything */
268 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
269}
270
271/* ----------------------------------------------------------- */
272
273static int __devinit dvb_probe(struct pci_dev *pci_dev,
274 const struct pci_device_id *pci_id)
275{
276 struct cx8802_dev *dev;
277 struct cx88_core *core;
278 int err;
279
280 /* general setup */
281 core = cx88_core_get(pci_dev);
282 if (NULL == core)
283 return -EINVAL;
284
285 err = -ENODEV;
286 if (!cx88_boards[core->board].dvb)
287 goto fail_core;
288
289 err = -ENOMEM;
290 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
291 if (NULL == dev)
292 goto fail_core;
293 memset(dev,0,sizeof(*dev));
294 dev->pci = pci_dev;
295 dev->core = core;
296
297 err = cx8802_init_common(dev);
298 if (0 != err)
299 goto fail_free;
300
301 /* dvb stuff */
302 printk("%s/2: cx2388x based dvb card\n", core->name);
303 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
304 dev->pci, &dev->slock,
305 V4L2_BUF_TYPE_VIDEO_CAPTURE,
306 V4L2_FIELD_TOP,
307 sizeof(struct cx88_buffer),
308 dev);
309 err = dvb_register(dev);
310 if (0 != err)
311 goto fail_free;
312 return 0;
313
314 fail_free:
315 kfree(dev);
316 fail_core:
317 cx88_core_put(core,pci_dev);
318 return err;
319}
320
321static void __devexit dvb_remove(struct pci_dev *pci_dev)
322{
323 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
324
325 /* dvb */
326 videobuf_dvb_unregister(&dev->dvb);
327
328 /* common */
329 cx8802_fini_common(dev);
330 cx88_core_put(dev->core,dev->pci);
331 kfree(dev);
332}
333
334static struct pci_device_id cx8802_pci_tbl[] = {
335 {
336 .vendor = 0x14f1,
337 .device = 0x8802,
338 .subvendor = PCI_ANY_ID,
339 .subdevice = PCI_ANY_ID,
340 },{
341 /* --- end of list --- */
342 }
343};
344MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
345
346static struct pci_driver dvb_pci_driver = {
347 .name = "cx88-dvb",
348 .id_table = cx8802_pci_tbl,
349 .probe = dvb_probe,
350 .remove = __devexit_p(dvb_remove),
351 .suspend = cx8802_suspend_common,
352 .resume = cx8802_resume_common,
353};
354
355static int dvb_init(void)
356{
357 printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
358 (CX88_VERSION_CODE >> 16) & 0xff,
359 (CX88_VERSION_CODE >> 8) & 0xff,
360 CX88_VERSION_CODE & 0xff);
361#ifdef SNAPSHOT
362 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
363 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
364#endif
365 return pci_register_driver(&dvb_pci_driver);
366}
367
368static void dvb_fini(void)
369{
370 pci_unregister_driver(&dvb_pci_driver);
371}
372
373module_init(dvb_init);
374module_exit(dvb_fini);
375
376/*
377 * Local variables:
378 * c-basic-offset: 8
379 * compile-command: "make DVB=1"
380 * End:
381 */
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
new file mode 100644
index 000000000000..60800172c026
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -0,0 +1,213 @@
1/*
2 $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $
3
4 cx88-i2c.c -- all the i2c code is here
5
6 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
7 & Marcus Metzler (mocm@thp.uni-koeln.de)
8 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30
31#include <asm/io.h>
32
33#include "cx88.h"
34
35static unsigned int i2c_debug = 0;
36module_param(i2c_debug, int, 0644);
37MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
38
39static unsigned int i2c_scan = 0;
40module_param(i2c_scan, int, 0444);
41MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
42
43#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
44 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
45
46/* ----------------------------------------------------------------------- */
47
48void cx8800_bit_setscl(void *data, int state)
49{
50 struct cx88_core *core = data;
51
52 if (state)
53 core->i2c_state |= 0x02;
54 else
55 core->i2c_state &= ~0x02;
56 cx_write(MO_I2C, core->i2c_state);
57 cx_read(MO_I2C);
58}
59
60void cx8800_bit_setsda(void *data, int state)
61{
62 struct cx88_core *core = data;
63
64 if (state)
65 core->i2c_state |= 0x01;
66 else
67 core->i2c_state &= ~0x01;
68 cx_write(MO_I2C, core->i2c_state);
69 cx_read(MO_I2C);
70}
71
72static int cx8800_bit_getscl(void *data)
73{
74 struct cx88_core *core = data;
75 u32 state;
76
77 state = cx_read(MO_I2C);
78 return state & 0x02 ? 1 : 0;
79}
80
81static int cx8800_bit_getsda(void *data)
82{
83 struct cx88_core *core = data;
84 u32 state;
85
86 state = cx_read(MO_I2C);
87 return state & 0x01;
88}
89
90/* ----------------------------------------------------------------------- */
91
92static int attach_inform(struct i2c_client *client)
93{
94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95
96 dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
97 client->addr, i2c_clientname(client));
98 if (!client->driver->command)
99 return 0;
100
101 if (core->tuner_type != UNSET)
102 client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type);
103 if (core->tda9887_conf)
104 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
105 return 0;
106}
107
108static int detach_inform(struct i2c_client *client)
109{
110 struct cx88_core *core = i2c_get_adapdata(client->adapter);
111
112 dprintk(1, "i2c detach [client=%s]\n", i2c_clientname(client));
113 return 0;
114}
115
116void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
117{
118 if (0 != core->i2c_rc)
119 return;
120 i2c_clients_command(&core->i2c_adap, cmd, arg);
121}
122
123static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
124 .setsda = cx8800_bit_setsda,
125 .setscl = cx8800_bit_setscl,
126 .getsda = cx8800_bit_getsda,
127 .getscl = cx8800_bit_getscl,
128 .udelay = 16,
129 .mdelay = 10,
130 .timeout = 200,
131};
132
133/* ----------------------------------------------------------------------- */
134
135static struct i2c_adapter cx8800_i2c_adap_template = {
136 I2C_DEVNAME("cx2388x"),
137 .owner = THIS_MODULE,
138 .id = I2C_HW_B_CX2388x,
139 .client_register = attach_inform,
140 .client_unregister = detach_inform,
141};
142
143static struct i2c_client cx8800_i2c_client_template = {
144 I2C_DEVNAME("cx88xx internal"),
145};
146
147static char *i2c_devs[128] = {
148 [ 0x86 >> 1 ] = "tda9887/cx22702",
149 [ 0xa0 >> 1 ] = "eeprom",
150 [ 0xc0 >> 1 ] = "tuner (analog)",
151 [ 0xc2 >> 1 ] = "tuner (analog/dvb)",
152};
153
154static void do_i2c_scan(char *name, struct i2c_client *c)
155{
156 unsigned char buf;
157 int i,rc;
158
159 for (i = 0; i < 128; i++) {
160 c->addr = i;
161 rc = i2c_master_recv(c,&buf,0);
162 if (rc < 0)
163 continue;
164 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
165 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
166 }
167}
168
169/* init + register i2c algo-bit adapter */
170int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
171{
172 memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,
173 sizeof(core->i2c_adap));
174 memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
175 sizeof(core->i2c_algo));
176 memcpy(&core->i2c_client, &cx8800_i2c_client_template,
177 sizeof(core->i2c_client));
178
179 if (core->tuner_type != TUNER_ABSENT)
180 core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
181 if (cx88_boards[core->board].dvb)
182 core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
183
184 core->i2c_adap.dev.parent = &pci->dev;
185 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
186 core->i2c_algo.data = core;
187 i2c_set_adapdata(&core->i2c_adap,core);
188 core->i2c_adap.algo_data = &core->i2c_algo;
189 core->i2c_client.adapter = &core->i2c_adap;
190
191 cx8800_bit_setscl(core,1);
192 cx8800_bit_setsda(core,1);
193
194 core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
195 if (0 == core->i2c_rc) {
196 dprintk(1, "i2c register ok\n");
197 if (i2c_scan)
198 do_i2c_scan(core->name,&core->i2c_client);
199 } else
200 printk("%s: i2c register FAILED\n", core->name);
201 return core->i2c_rc;
202}
203
204/* ----------------------------------------------------------------------- */
205
206EXPORT_SYMBOL(cx88_call_i2c_clients);
207EXPORT_SYMBOL(cx88_i2c_init);
208
209/*
210 * Local variables:
211 * c-basic-offset: 8
212 * End:
213 */
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
new file mode 100644
index 000000000000..af6ad8cdbdb7
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -0,0 +1,396 @@
1/*
2 * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * Device driver for GPIO attached remote control interfaces
5 * on Conexant 2388x based TV/DVB cards.
6 *
7 * Copyright (c) 2003 Pavel Machek
8 * Copyright (c) 2004 Gerd Knorr
9 * Copyright (c) 2004 Chris Pascoe
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/input.h>
29#include <linux/pci.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32
33#include <media/ir-common.h>
34
35#include "cx88.h"
36
37/* ---------------------------------------------------------------------- */
38
39/* DigitalNow DNTV Live DVB-T Remote */
40static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
41 [ 0x00 ] = KEY_ESC, // 'go up a level?'
42 [ 0x01 ] = KEY_KP1, // '1'
43 [ 0x02 ] = KEY_KP2, // '2'
44 [ 0x03 ] = KEY_KP3, // '3'
45 [ 0x04 ] = KEY_KP4, // '4'
46 [ 0x05 ] = KEY_KP5, // '5'
47 [ 0x06 ] = KEY_KP6, // '6'
48 [ 0x07 ] = KEY_KP7, // '7'
49 [ 0x08 ] = KEY_KP8, // '8'
50 [ 0x09 ] = KEY_KP9, // '9'
51 [ 0x0a ] = KEY_KP0, // '0'
52 [ 0x0b ] = KEY_TUNER, // 'tv/fm'
53 [ 0x0c ] = KEY_SEARCH, // 'scan'
54 [ 0x0d ] = KEY_STOP, // 'stop'
55 [ 0x0e ] = KEY_PAUSE, // 'pause'
56 [ 0x0f ] = KEY_LIST, // 'source'
57
58 [ 0x10 ] = KEY_MUTE, // 'mute'
59 [ 0x11 ] = KEY_REWIND, // 'backward <<'
60 [ 0x12 ] = KEY_POWER, // 'power'
61 [ 0x13 ] = KEY_S, // 'snap'
62 [ 0x14 ] = KEY_AUDIO, // 'stereo'
63 [ 0x15 ] = KEY_CLEAR, // 'reset'
64 [ 0x16 ] = KEY_PLAY, // 'play'
65 [ 0x17 ] = KEY_ENTER, // 'enter'
66 [ 0x18 ] = KEY_ZOOM, // 'full screen'
67 [ 0x19 ] = KEY_FASTFORWARD, // 'forward >>'
68 [ 0x1a ] = KEY_CHANNELUP, // 'channel +'
69 [ 0x1b ] = KEY_VOLUMEUP, // 'volume +'
70 [ 0x1c ] = KEY_INFO, // 'preview'
71 [ 0x1d ] = KEY_RECORD, // 'record'
72 [ 0x1e ] = KEY_CHANNELDOWN, // 'channel -'
73 [ 0x1f ] = KEY_VOLUMEDOWN, // 'volume -'
74};
75
76/* ---------------------------------------------------------------------- */
77
78/* IO-DATA BCTV7E Remote */
79static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
80 [ 0x40 ] = KEY_TV, // TV
81 [ 0x20 ] = KEY_RADIO, // FM
82 [ 0x60 ] = KEY_EPG, // EPG
83 [ 0x00 ] = KEY_POWER, // power
84
85 [ 0x50 ] = KEY_KP1, // 1
86 [ 0x30 ] = KEY_KP2, // 2
87 [ 0x70 ] = KEY_KP3, // 3
88 [ 0x10 ] = KEY_L, // Live
89
90 [ 0x48 ] = KEY_KP4, // 4
91 [ 0x28 ] = KEY_KP5, // 5
92 [ 0x68 ] = KEY_KP6, // 6
93 [ 0x08 ] = KEY_T, // Time Shift
94
95 [ 0x58 ] = KEY_KP7, // 7
96 [ 0x38 ] = KEY_KP8, // 8
97 [ 0x78 ] = KEY_KP9, // 9
98 [ 0x18 ] = KEY_PLAYPAUSE, // Play
99
100 [ 0x44 ] = KEY_KP0, // 10
101 [ 0x24 ] = KEY_ENTER, // 11
102 [ 0x64 ] = KEY_ESC, // 12
103 [ 0x04 ] = KEY_M, // Multi
104
105 [ 0x54 ] = KEY_VIDEO, // VIDEO
106 [ 0x34 ] = KEY_CHANNELUP, // channel +
107 [ 0x74 ] = KEY_VOLUMEUP, // volume +
108 [ 0x14 ] = KEY_MUTE, // Mute
109
110 [ 0x4c ] = KEY_S, // SVIDEO
111 [ 0x2c ] = KEY_CHANNELDOWN, // channel -
112 [ 0x6c ] = KEY_VOLUMEDOWN, // volume -
113 [ 0x0c ] = KEY_ZOOM, // Zoom
114
115 [ 0x5c ] = KEY_PAUSE, // pause
116 [ 0x3c ] = KEY_C, // || (red)
117 [ 0x7c ] = KEY_RECORD, // recording
118 [ 0x1c ] = KEY_STOP, // stop
119
120 [ 0x41 ] = KEY_REWIND, // backward <<
121 [ 0x21 ] = KEY_PLAY, // play
122 [ 0x61 ] = KEY_FASTFORWARD, // forward >>
123 [ 0x01 ] = KEY_NEXT, // skip >|
124};
125
126/* ---------------------------------------------------------------------- */
127
128struct cx88_IR {
129 struct cx88_core *core;
130 struct input_dev input;
131 struct ir_input_state ir;
132 char name[32];
133 char phys[32];
134
135 /* sample from gpio pin 16 */
136 int sampling;
137 u32 samples[16];
138 int scount;
139 unsigned long release;
140
141 /* poll external decoder */
142 int polling;
143 struct work_struct work;
144 struct timer_list timer;
145 u32 gpio_addr;
146 u32 last_gpio;
147 u32 mask_keycode;
148 u32 mask_keydown;
149 u32 mask_keyup;
150};
151
152static int ir_debug = 0;
153module_param(ir_debug, int, 0644); /* debug level [IR] */
154MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
155
156#define ir_dprintk(fmt, arg...) if (ir_debug) \
157 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg)
158
159/* ---------------------------------------------------------------------- */
160
161static void cx88_ir_handle_key(struct cx88_IR *ir)
162{
163 struct cx88_core *core = ir->core;
164 u32 gpio, data;
165
166 /* read gpio value */
167 gpio = cx_read(ir->gpio_addr);
168 if (ir->polling) {
169 if (ir->last_gpio == gpio)
170 return;
171 ir->last_gpio = gpio;
172 }
173
174 /* extract data */
175 data = ir_extract_bits(gpio, ir->mask_keycode);
176 ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
177 gpio, data,
178 ir->polling ? "poll" : "irq",
179 (gpio & ir->mask_keydown) ? " down" : "",
180 (gpio & ir->mask_keyup) ? " up" : "");
181
182 if (ir->mask_keydown) {
183 /* bit set on keydown */
184 if (gpio & ir->mask_keydown) {
185 ir_input_keydown(&ir->input,&ir->ir,data,data);
186 } else {
187 ir_input_nokey(&ir->input,&ir->ir);
188 }
189
190 } else if (ir->mask_keyup) {
191 /* bit cleared on keydown */
192 if (0 == (gpio & ir->mask_keyup)) {
193 ir_input_keydown(&ir->input,&ir->ir,data,data);
194 } else {
195 ir_input_nokey(&ir->input,&ir->ir);
196 }
197
198 } else {
199 /* can't distinguish keydown/up :-/ */
200 ir_input_keydown(&ir->input,&ir->ir,data,data);
201 ir_input_nokey(&ir->input,&ir->ir);
202 }
203}
204
205static void ir_timer(unsigned long data)
206{
207 struct cx88_IR *ir = (struct cx88_IR*)data;
208
209 schedule_work(&ir->work);
210}
211
212static void cx88_ir_work(void *data)
213{
214 struct cx88_IR *ir = data;
215 unsigned long timeout;
216
217 cx88_ir_handle_key(ir);
218 timeout = jiffies + (ir->polling * HZ / 1000);
219 mod_timer(&ir->timer, timeout);
220}
221
222/* ---------------------------------------------------------------------- */
223
224int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
225{
226 struct cx88_IR *ir;
227 IR_KEYTAB_TYPE *ir_codes = NULL;
228 int ir_type = IR_TYPE_OTHER;
229
230 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
231 if (NULL == ir)
232 return -ENOMEM;
233 memset(ir,0,sizeof(*ir));
234
235 /* detect & configure */
236 switch (core->board) {
237 case CX88_BOARD_DNTV_LIVE_DVB_T:
238 ir_codes = ir_codes_dntv_live_dvb_t;
239 ir->gpio_addr = MO_GP1_IO;
240 ir->mask_keycode = 0x1f;
241 ir->mask_keyup = 0x60;
242 ir->polling = 50; // ms
243 break;
244 case CX88_BOARD_HAUPPAUGE:
245 case CX88_BOARD_HAUPPAUGE_DVB_T1:
246 ir_codes = ir_codes_hauppauge_new;
247 ir_type = IR_TYPE_RC5;
248 ir->sampling = 1;
249 break;
250 case CX88_BOARD_WINFAST2000XP_EXPERT:
251 ir_codes = ir_codes_winfast;
252 ir->gpio_addr = MO_GP0_IO;
253 ir->mask_keycode = 0x8f8;
254 ir->mask_keyup = 0x100;
255 ir->polling = 1; // ms
256 break;
257 case CX88_BOARD_IODATA_GVBCTV7E:
258 ir_codes = ir_codes_iodata_bctv7e;
259 ir->gpio_addr = MO_GP0_IO;
260 ir->mask_keycode = 0xfd;
261 ir->mask_keydown = 0x02;
262 ir->polling = 5; // ms
263 break;
264 }
265 if (NULL == ir_codes) {
266 kfree(ir);
267 return -ENODEV;
268 }
269
270 /* init input device */
271 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)",
272 cx88_boards[core->board].name);
273 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
274 pci_name(pci));
275
276 ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
277 ir->input.name = ir->name;
278 ir->input.phys = ir->phys;
279 ir->input.id.bustype = BUS_PCI;
280 ir->input.id.version = 1;
281 if (pci->subsystem_vendor) {
282 ir->input.id.vendor = pci->subsystem_vendor;
283 ir->input.id.product = pci->subsystem_device;
284 } else {
285 ir->input.id.vendor = pci->vendor;
286 ir->input.id.product = pci->device;
287 }
288
289 /* record handles to ourself */
290 ir->core = core;
291 core->ir = ir;
292
293 if (ir->polling) {
294 INIT_WORK(&ir->work, cx88_ir_work, ir);
295 init_timer(&ir->timer);
296 ir->timer.function = ir_timer;
297 ir->timer.data = (unsigned long)ir;
298 schedule_work(&ir->work);
299 }
300 if (ir->sampling) {
301 core->pci_irqmask |= (1<<18); // IR_SMP_INT
302 cx_write(MO_DDS_IO, 0xa80a80); // 4 kHz sample rate
303 cx_write(MO_DDSCFG_IO, 0x5); // enable
304 }
305
306 /* all done */
307 input_register_device(&ir->input);
308 printk("%s: registered IR remote control\n", core->name);
309
310 return 0;
311}
312
313int cx88_ir_fini(struct cx88_core *core)
314{
315 struct cx88_IR *ir = core->ir;
316
317 /* skip detach on non attached boards */
318 if (NULL == ir)
319 return 0;
320
321 if (ir->polling) {
322 del_timer(&ir->timer);
323 flush_scheduled_work();
324 }
325
326 input_unregister_device(&ir->input);
327 kfree(ir);
328
329 /* done */
330 core->ir = NULL;
331 return 0;
332}
333
334/* ---------------------------------------------------------------------- */
335
336void cx88_ir_irq(struct cx88_core *core)
337{
338 struct cx88_IR *ir = core->ir;
339 u32 samples,rc5;
340 int i;
341
342 if (NULL == ir)
343 return;
344 if (!ir->sampling)
345 return;
346
347 samples = cx_read(MO_SAMPLE_IO);
348 if (0 != samples && 0xffffffff != samples) {
349 /* record sample data */
350 if (ir->scount < ARRAY_SIZE(ir->samples))
351 ir->samples[ir->scount++] = samples;
352 return;
353 }
354 if (!ir->scount) {
355 /* nothing to sample */
356 if (ir->ir.keypressed && time_after(jiffies,ir->release))
357 ir_input_nokey(&ir->input,&ir->ir);
358 return;
359 }
360
361 /* have a complete sample */
362 if (ir->scount < ARRAY_SIZE(ir->samples))
363 ir->samples[ir->scount++] = samples;
364 for (i = 0; i < ir->scount; i++)
365 ir->samples[i] = ~ir->samples[i];
366 if (ir_debug)
367 ir_dump_samples(ir->samples,ir->scount);
368
369 /* decode it */
370 switch (core->board) {
371 case CX88_BOARD_HAUPPAUGE:
372 case CX88_BOARD_HAUPPAUGE_DVB_T1:
373 rc5 = ir_decode_biphase(ir->samples,ir->scount,5,7);
374 ir_dprintk("biphase decoded: %x\n",rc5);
375 if ((rc5 & 0xfffff000) != 0x3000)
376 break;
377 ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5);
378 ir->release = jiffies + msecs_to_jiffies(120);
379 break;
380 }
381
382 ir->scount = 0;
383 return;
384}
385
386/* ---------------------------------------------------------------------- */
387
388MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe");
389MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls");
390MODULE_LICENSE("GPL");
391
392/*
393 * Local variables:
394 * c-basic-offset: 8
395 * End:
396 */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
new file mode 100644
index 000000000000..07aae1899e17
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -0,0 +1,466 @@
1/*
2 * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $
3 *
4 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x.
6 *
7 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
8 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
9 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/device.h>
30#include <linux/interrupt.h>
31#include <asm/delay.h>
32
33#include "cx88.h"
34
35/* ------------------------------------------------------------------ */
36
37MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
39MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43static unsigned int debug = 0;
44module_param(debug,int,0644);
45MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
46
47#define dprintk(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/2: " fmt, dev->core->name , ## arg)
49
50/* ------------------------------------------------------------------ */
51
52static int cx8802_start_dma(struct cx8802_dev *dev,
53 struct cx88_dmaqueue *q,
54 struct cx88_buffer *buf)
55{
56 struct cx88_core *core = dev->core;
57
58 dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width);
59
60 /* setup fifo + format */
61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
62 dev->ts_packet_size, buf->risc.dma);
63
64 /* write TS length to chip */
65 cx_write(MO_TS_LNGTH, buf->vb.width);
66
67#if 1
68 /* FIXME: this needs a review.
69 * also: move to cx88-blackbird + cx88-dvb source files? */
70
71 if (cx88_boards[core->board].dvb) {
72 /* negedge driven & software reset */
73 cx_write(TS_GEN_CNTRL, 0x40);
74 udelay(100);
75 cx_write(MO_PINMUX_IO, 0x00);
76 cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00);
77 cx_write(TS_SOP_STAT,0x00);
78 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
79 udelay(100);
80 }
81
82 if (cx88_boards[core->board].blackbird) {
83 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
84
85 // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */
86 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
87 udelay(100);
88
89 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
90 //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */
91 cx_write(TS_VALERR_CNTRL, 0x2000);
92
93 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
94 udelay(100);
95 }
96#endif
97
98 /* reset counter */
99 cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
100 q->count = 1;
101
102 /* enable irqs */
103 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
104 cx_write(MO_TS_INTMSK, 0x1f0011);
105
106 /* start dma */
107 cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */
108 cx_write(MO_TS_DMACNTRL, 0x11);
109 return 0;
110}
111
112static int cx8802_stop_dma(struct cx8802_dev *dev)
113{
114 struct cx88_core *core = dev->core;
115
116 /* stop dma */
117 cx_clear(MO_TS_DMACNTRL, 0x11);
118
119 /* disable irqs */
120 cx_clear(MO_PCI_INTMSK, 0x000004);
121 cx_clear(MO_TS_INTMSK, 0x1f0011);
122
123 /* Reset the controller */
124 cx_write(TS_GEN_CNTRL, 0xcd);
125 return 0;
126}
127
128static int cx8802_restart_queue(struct cx8802_dev *dev,
129 struct cx88_dmaqueue *q)
130{
131 struct cx88_buffer *buf;
132 struct list_head *item;
133
134 if (list_empty(&q->active))
135 return 0;
136
137 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
138 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
139 buf, buf->vb.i);
140 cx8802_start_dma(dev, q, buf);
141 list_for_each(item,&q->active) {
142 buf = list_entry(item, struct cx88_buffer, vb.queue);
143 buf->count = q->count++;
144 }
145 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
146 return 0;
147}
148
149/* ------------------------------------------------------------------ */
150
151int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
152{
153 int size = dev->ts_packet_size * dev->ts_packet_count;
154 int rc;
155
156 dprintk(1, "%s: %p\n", __FUNCTION__, buf);
157 if (0 != buf->vb.baddr && buf->vb.bsize < size)
158 return -EINVAL;
159
160 if (STATE_NEEDS_INIT == buf->vb.state) {
161 buf->vb.width = dev->ts_packet_size;
162 buf->vb.height = dev->ts_packet_count;
163 buf->vb.size = size;
164 buf->vb.field = V4L2_FIELD_TOP;
165
166 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
167 goto fail;
168 cx88_risc_databuffer(dev->pci, &buf->risc,
169 buf->vb.dma.sglist,
170 buf->vb.width, buf->vb.height);
171 }
172 buf->vb.state = STATE_PREPARED;
173 return 0;
174
175 fail:
176 cx88_free_buffer(dev->pci,buf);
177 return rc;
178}
179
180void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
181{
182 struct cx88_buffer *prev;
183 struct cx88_dmaqueue *q = &dev->mpegq;
184
185 /* add jump to stopper */
186 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
187 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
188
189 if (list_empty(&q->active)) {
190 list_add_tail(&buf->vb.queue,&q->active);
191 cx8802_start_dma(dev, q, buf);
192 buf->vb.state = STATE_ACTIVE;
193 buf->count = q->count++;
194 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
195 dprintk(2,"[%p/%d] %s - first active\n",
196 buf, buf->vb.i, __FUNCTION__);
197
198 } else {
199 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
200 list_add_tail(&buf->vb.queue,&q->active);
201 buf->vb.state = STATE_ACTIVE;
202 buf->count = q->count++;
203 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
204 dprintk(2,"[%p/%d] %s - append to active\n",
205 buf, buf->vb.i, __FUNCTION__);
206 }
207}
208
209/* ----------------------------------------------------------- */
210
211static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
212{
213 struct cx88_dmaqueue *q = &dev->mpegq;
214 struct cx88_buffer *buf;
215 unsigned long flags;
216
217 spin_lock_irqsave(&dev->slock,flags);
218 while (!list_empty(&q->active)) {
219 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
220 list_del(&buf->vb.queue);
221 buf->vb.state = STATE_ERROR;
222 wake_up(&buf->vb.done);
223 dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
224 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
225 }
226 if (restart)
227 cx8802_restart_queue(dev,q);
228 spin_unlock_irqrestore(&dev->slock,flags);
229}
230
231void cx8802_cancel_buffers(struct cx8802_dev *dev)
232{
233 struct cx88_dmaqueue *q = &dev->mpegq;
234
235 del_timer_sync(&q->timeout);
236 cx8802_stop_dma(dev);
237 do_cancel_buffers(dev,"cancel",0);
238}
239
240static void cx8802_timeout(unsigned long data)
241{
242 struct cx8802_dev *dev = (struct cx8802_dev*)data;
243
244 dprintk(1, "%s\n",__FUNCTION__);
245
246 if (debug)
247 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
248 cx8802_stop_dma(dev);
249 do_cancel_buffers(dev,"timeout",1);
250}
251
252static void cx8802_mpeg_irq(struct cx8802_dev *dev)
253{
254 struct cx88_core *core = dev->core;
255 u32 status, mask, count;
256
257 status = cx_read(MO_TS_INTSTAT);
258 mask = cx_read(MO_TS_INTMSK);
259 if (0 == (status & mask))
260 return;
261
262 cx_write(MO_TS_INTSTAT, status);
263 if (debug || (status & mask & ~0xff))
264 cx88_print_irqbits(core->name, "irq mpeg ",
265 cx88_mpeg_irqs, status, mask);
266
267 /* risc op code error */
268 if (status & (1 << 16)) {
269 printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name);
270 cx_clear(MO_TS_DMACNTRL, 0x11);
271 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
272 }
273
274 /* risc1 y */
275 if (status & 0x01) {
276 spin_lock(&dev->slock);
277 count = cx_read(MO_TS_GPCNT);
278 cx88_wakeup(dev->core, &dev->mpegq, count);
279 spin_unlock(&dev->slock);
280 }
281
282 /* risc2 y */
283 if (status & 0x10) {
284 spin_lock(&dev->slock);
285 cx8802_restart_queue(dev,&dev->mpegq);
286 spin_unlock(&dev->slock);
287 }
288
289 /* other general errors */
290 if (status & 0x1f0100) {
291 spin_lock(&dev->slock);
292 cx8802_stop_dma(dev);
293 cx8802_restart_queue(dev,&dev->mpegq);
294 spin_unlock(&dev->slock);
295 }
296}
297
298static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
299{
300 struct cx8802_dev *dev = dev_id;
301 struct cx88_core *core = dev->core;
302 u32 status;
303 int loop, handled = 0;
304
305 for (loop = 0; loop < 10; loop++) {
306 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
307 if (0 == status)
308 goto out;
309 handled = 1;
310 cx_write(MO_PCI_INTSTAT, status);
311
312 if (status & core->pci_irqmask)
313 cx88_core_irq(core,status);
314 if (status & 0x04)
315 cx8802_mpeg_irq(dev);
316 };
317 if (10 == loop) {
318 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
319 core->name);
320 cx_write(MO_PCI_INTMSK,0);
321 }
322
323 out:
324 return IRQ_RETVAL(handled);
325}
326
327/* ----------------------------------------------------------- */
328/* exported stuff */
329
330int cx8802_init_common(struct cx8802_dev *dev)
331{
332 struct cx88_core *core = dev->core;
333 int err;
334
335 /* pci init */
336 if (pci_enable_device(dev->pci))
337 return -EIO;
338 pci_set_master(dev->pci);
339 if (!pci_dma_supported(dev->pci,0xffffffff)) {
340 printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
341 return -EIO;
342 }
343
344 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
345 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
346 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
347 "latency: %d, mmio: 0x%lx\n", dev->core->name,
348 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
349 dev->pci_lat,pci_resource_start(dev->pci,0));
350
351 /* initialize driver struct */
352 init_MUTEX(&dev->lock);
353 spin_lock_init(&dev->slock);
354
355 /* init dma queue */
356 INIT_LIST_HEAD(&dev->mpegq.active);
357 INIT_LIST_HEAD(&dev->mpegq.queued);
358 dev->mpegq.timeout.function = cx8802_timeout;
359 dev->mpegq.timeout.data = (unsigned long)dev;
360 init_timer(&dev->mpegq.timeout);
361 cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
362 MO_TS_DMACNTRL,0x11,0x00);
363
364 /* get irq */
365 err = request_irq(dev->pci->irq, cx8802_irq,
366 SA_SHIRQ | SA_INTERRUPT, dev->core->name, dev);
367 if (err < 0) {
368 printk(KERN_ERR "%s: can't get IRQ %d\n",
369 dev->core->name, dev->pci->irq);
370 return err;
371 }
372 cx_set(MO_PCI_INTMSK, core->pci_irqmask);
373
374 /* everything worked */
375 pci_set_drvdata(dev->pci,dev);
376 return 0;
377}
378
379void cx8802_fini_common(struct cx8802_dev *dev)
380{
381 cx8802_stop_dma(dev);
382 pci_disable_device(dev->pci);
383
384 /* unregister stuff */
385 free_irq(dev->pci->irq, dev);
386 pci_set_drvdata(dev->pci, NULL);
387
388 /* free memory */
389 btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
390}
391
392/* ----------------------------------------------------------- */
393
394int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
395{
396 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
397 struct cx88_core *core = dev->core;
398
399 /* stop mpeg dma */
400 spin_lock(&dev->slock);
401 if (!list_empty(&dev->mpegq.active)) {
402 printk("%s: suspend mpeg\n", core->name);
403 cx8802_stop_dma(dev);
404 del_timer(&dev->mpegq.timeout);
405 }
406 spin_unlock(&dev->slock);
407
408#if 1
409 /* FIXME -- shutdown device */
410 cx88_shutdown(dev->core);
411#endif
412
413 pci_save_state(pci_dev);
414 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
415 pci_disable_device(pci_dev);
416 dev->state.disabled = 1;
417 }
418 return 0;
419}
420
421int cx8802_resume_common(struct pci_dev *pci_dev)
422{
423 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
424 struct cx88_core *core = dev->core;
425
426 if (dev->state.disabled) {
427 pci_enable_device(pci_dev);
428 dev->state.disabled = 0;
429 }
430 pci_set_power_state(pci_dev, PCI_D0);
431 pci_restore_state(pci_dev);
432
433#if 1
434 /* FIXME: re-initialize hardware */
435 cx88_reset(dev->core);
436#endif
437
438 /* restart video+vbi capture */
439 spin_lock(&dev->slock);
440 if (!list_empty(&dev->mpegq.active)) {
441 printk("%s: resume mpeg\n", core->name);
442 cx8802_restart_queue(dev,&dev->mpegq);
443 }
444 spin_unlock(&dev->slock);
445
446 return 0;
447}
448
449/* ----------------------------------------------------------- */
450
451EXPORT_SYMBOL(cx8802_buf_prepare);
452EXPORT_SYMBOL(cx8802_buf_queue);
453EXPORT_SYMBOL(cx8802_cancel_buffers);
454
455EXPORT_SYMBOL(cx8802_init_common);
456EXPORT_SYMBOL(cx8802_fini_common);
457
458EXPORT_SYMBOL(cx8802_suspend_common);
459EXPORT_SYMBOL(cx8802_resume_common);
460
461/* ----------------------------------------------------------- */
462/*
463 * Local variables:
464 * c-basic-offset: 8
465 * End:
466 */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
new file mode 100644
index 000000000000..8638ce57d84c
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -0,0 +1,787 @@
1/*
2 $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $
3
4 cx88x-hw.h - CX2388x register offsets
5
6 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
7 2001 Michael Eskin
8 2002 Yurij Sysoev <yurij@naturesoft.net>
9 2003 Gerd Knorr <kraxel@bytesex.org>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#ifndef _CX88_REG_H_
27#define _CX88_REG_H_
28
29/* ---------------------------------------------------------------------- */
30/* PCI IDs and config space */
31
32#ifndef PCI_VENDOR_ID_CONEXANT
33# define PCI_VENDOR_ID_CONEXANT 0x14F1
34#endif
35#ifndef PCI_DEVICE_ID_CX2300_VID
36# define PCI_DEVICE_ID_CX2300_VID 0x8800
37#endif
38
39#define CX88X_DEVCTRL 0x40
40#define CX88X_EN_TBFX 0x02
41#define CX88X_EN_VSFX 0x04
42
43
44/* ---------------------------------------------------------------------- */
45/* DMA Controller registers */
46
47#define MO_PDMA_STHRSH 0x200000 // Source threshold
48#define MO_PDMA_STADRS 0x200004 // Source target address
49#define MO_PDMA_SIADRS 0x200008 // Source internal address
50#define MO_PDMA_SCNTRL 0x20000C // Source control
51#define MO_PDMA_DTHRSH 0x200010 // Destination threshold
52#define MO_PDMA_DTADRS 0x200014 // Destination target address
53#define MO_PDMA_DIADRS 0x200018 // Destination internal address
54#define MO_PDMA_DCNTRL 0x20001C // Destination control
55#define MO_LD_SSID 0x200030 // Load subsystem ID
56#define MO_DEV_CNTRL2 0x200034 // Device control
57#define MO_PCI_INTMSK 0x200040 // PCI interrupt mask
58#define MO_PCI_INTSTAT 0x200044 // PCI interrupt status
59#define MO_PCI_INTMSTAT 0x200048 // PCI interrupt masked status
60#define MO_VID_INTMSK 0x200050 // Video interrupt mask
61#define MO_VID_INTSTAT 0x200054 // Video interrupt status
62#define MO_VID_INTMSTAT 0x200058 // Video interrupt masked status
63#define MO_VID_INTSSTAT 0x20005C // Video interrupt set status
64#define MO_AUD_INTMSK 0x200060 // Audio interrupt mask
65#define MO_AUD_INTSTAT 0x200064 // Audio interrupt status
66#define MO_AUD_INTMSTAT 0x200068 // Audio interrupt masked status
67#define MO_AUD_INTSSTAT 0x20006C // Audio interrupt set status
68#define MO_TS_INTMSK 0x200070 // Transport stream interrupt mask
69#define MO_TS_INTSTAT 0x200074 // Transport stream interrupt status
70#define MO_TS_INTMSTAT 0x200078 // Transport stream interrupt mask status
71#define MO_TS_INTSSTAT 0x20007C // Transport stream interrupt set status
72#define MO_VIP_INTMSK 0x200080 // VIP interrupt mask
73#define MO_VIP_INTSTAT 0x200084 // VIP interrupt status
74#define MO_VIP_INTMSTAT 0x200088 // VIP interrupt masked status
75#define MO_VIP_INTSSTAT 0x20008C // VIP interrupt set status
76#define MO_GPHST_INTMSK 0x200090 // Host interrupt mask
77#define MO_GPHST_INTSTAT 0x200094 // Host interrupt status
78#define MO_GPHST_INTMSTAT 0x200098 // Host interrupt masked status
79#define MO_GPHST_INTSSTAT 0x20009C // Host interrupt set status
80
81// DMA Channels 1-6 belong to SPIPE
82#define MO_DMA7_PTR1 0x300018 // {24}RW* DMA Current Ptr : Ch#7
83#define MO_DMA8_PTR1 0x30001C // {24}RW* DMA Current Ptr : Ch#8
84
85// DMA Channels 9-20 belong to SPIPE
86#define MO_DMA21_PTR1 0x300080 // {24}R0* DMA Current Ptr : Ch#21
87#define MO_DMA22_PTR1 0x300084 // {24}R0* DMA Current Ptr : Ch#22
88#define MO_DMA23_PTR1 0x300088 // {24}R0* DMA Current Ptr : Ch#23
89#define MO_DMA24_PTR1 0x30008C // {24}R0* DMA Current Ptr : Ch#24
90#define MO_DMA25_PTR1 0x300090 // {24}R0* DMA Current Ptr : Ch#25
91#define MO_DMA26_PTR1 0x300094 // {24}R0* DMA Current Ptr : Ch#26
92#define MO_DMA27_PTR1 0x300098 // {24}R0* DMA Current Ptr : Ch#27
93#define MO_DMA28_PTR1 0x30009C // {24}R0* DMA Current Ptr : Ch#28
94#define MO_DMA29_PTR1 0x3000A0 // {24}R0* DMA Current Ptr : Ch#29
95#define MO_DMA30_PTR1 0x3000A4 // {24}R0* DMA Current Ptr : Ch#30
96#define MO_DMA31_PTR1 0x3000A8 // {24}R0* DMA Current Ptr : Ch#31
97#define MO_DMA32_PTR1 0x3000AC // {24}R0* DMA Current Ptr : Ch#32
98
99#define MO_DMA21_PTR2 0x3000C0 // {24}RW* DMA Tab Ptr : Ch#21
100#define MO_DMA22_PTR2 0x3000C4 // {24}RW* DMA Tab Ptr : Ch#22
101#define MO_DMA23_PTR2 0x3000C8 // {24}RW* DMA Tab Ptr : Ch#23
102#define MO_DMA24_PTR2 0x3000CC // {24}RW* DMA Tab Ptr : Ch#24
103#define MO_DMA25_PTR2 0x3000D0 // {24}RW* DMA Tab Ptr : Ch#25
104#define MO_DMA26_PTR2 0x3000D4 // {24}RW* DMA Tab Ptr : Ch#26
105#define MO_DMA27_PTR2 0x3000D8 // {24}RW* DMA Tab Ptr : Ch#27
106#define MO_DMA28_PTR2 0x3000DC // {24}RW* DMA Tab Ptr : Ch#28
107#define MO_DMA29_PTR2 0x3000E0 // {24}RW* DMA Tab Ptr : Ch#29
108#define MO_DMA30_PTR2 0x3000E4 // {24}RW* DMA Tab Ptr : Ch#30
109#define MO_DMA31_PTR2 0x3000E8 // {24}RW* DMA Tab Ptr : Ch#31
110#define MO_DMA32_PTR2 0x3000EC // {24}RW* DMA Tab Ptr : Ch#32
111
112#define MO_DMA21_CNT1 0x300100 // {11}RW* DMA Buffer Size : Ch#21
113#define MO_DMA22_CNT1 0x300104 // {11}RW* DMA Buffer Size : Ch#22
114#define MO_DMA23_CNT1 0x300108 // {11}RW* DMA Buffer Size : Ch#23
115#define MO_DMA24_CNT1 0x30010C // {11}RW* DMA Buffer Size : Ch#24
116#define MO_DMA25_CNT1 0x300110 // {11}RW* DMA Buffer Size : Ch#25
117#define MO_DMA26_CNT1 0x300114 // {11}RW* DMA Buffer Size : Ch#26
118#define MO_DMA27_CNT1 0x300118 // {11}RW* DMA Buffer Size : Ch#27
119#define MO_DMA28_CNT1 0x30011C // {11}RW* DMA Buffer Size : Ch#28
120#define MO_DMA29_CNT1 0x300120 // {11}RW* DMA Buffer Size : Ch#29
121#define MO_DMA30_CNT1 0x300124 // {11}RW* DMA Buffer Size : Ch#30
122#define MO_DMA31_CNT1 0x300128 // {11}RW* DMA Buffer Size : Ch#31
123#define MO_DMA32_CNT1 0x30012C // {11}RW* DMA Buffer Size : Ch#32
124
125#define MO_DMA21_CNT2 0x300140 // {11}RW* DMA Table Size : Ch#21
126#define MO_DMA22_CNT2 0x300144 // {11}RW* DMA Table Size : Ch#22
127#define MO_DMA23_CNT2 0x300148 // {11}RW* DMA Table Size : Ch#23
128#define MO_DMA24_CNT2 0x30014C // {11}RW* DMA Table Size : Ch#24
129#define MO_DMA25_CNT2 0x300150 // {11}RW* DMA Table Size : Ch#25
130#define MO_DMA26_CNT2 0x300154 // {11}RW* DMA Table Size : Ch#26
131#define MO_DMA27_CNT2 0x300158 // {11}RW* DMA Table Size : Ch#27
132#define MO_DMA28_CNT2 0x30015C // {11}RW* DMA Table Size : Ch#28
133#define MO_DMA29_CNT2 0x300160 // {11}RW* DMA Table Size : Ch#29
134#define MO_DMA30_CNT2 0x300164 // {11}RW* DMA Table Size : Ch#30
135#define MO_DMA31_CNT2 0x300168 // {11}RW* DMA Table Size : Ch#31
136#define MO_DMA32_CNT2 0x30016C // {11}RW* DMA Table Size : Ch#32
137
138
139/* ---------------------------------------------------------------------- */
140/* Video registers */
141
142#define MO_VIDY_DMA 0x310000 // {64}RWp Video Y
143#define MO_VIDU_DMA 0x310008 // {64}RWp Video U
144#define MO_VIDV_DMA 0x310010 // {64}RWp Video V
145#define MO_VBI_DMA 0x310018 // {64}RWp VBI (Vertical blanking interval)
146
147#define MO_DEVICE_STATUS 0x310100
148#define MO_INPUT_FORMAT 0x310104
149#define MO_AGC_BURST 0x31010c
150#define MO_CONTR_BRIGHT 0x310110
151#define MO_UV_SATURATION 0x310114
152#define MO_HUE 0x310118
153#define MO_HTOTAL 0x310120
154#define MO_HDELAY_EVEN 0x310124
155#define MO_HDELAY_ODD 0x310128
156#define MO_VDELAY_ODD 0x31012c
157#define MO_VDELAY_EVEN 0x310130
158#define MO_HACTIVE_EVEN 0x31013c
159#define MO_HACTIVE_ODD 0x310140
160#define MO_VACTIVE_EVEN 0x310144
161#define MO_VACTIVE_ODD 0x310148
162#define MO_HSCALE_EVEN 0x31014c
163#define MO_HSCALE_ODD 0x310150
164#define MO_VSCALE_EVEN 0x310154
165#define MO_FILTER_EVEN 0x31015c
166#define MO_VSCALE_ODD 0x310158
167#define MO_FILTER_ODD 0x310160
168#define MO_OUTPUT_FORMAT 0x310164
169
170#define MO_PLL_REG 0x310168 // PLL register
171#define MO_PLL_ADJ_CTRL 0x31016c // PLL adjust control register
172#define MO_SCONV_REG 0x310170 // sample rate conversion register
173#define MO_SCONV_FIFO 0x310174 // sample rate conversion fifo
174#define MO_SUB_STEP 0x310178 // subcarrier step size
175#define MO_SUB_STEP_DR 0x31017c // subcarrier step size for DR line
176
177#define MO_CAPTURE_CTRL 0x310180 // capture control
178#define MO_COLOR_CTRL 0x310184
179#define MO_VBI_PACKET 0x310188 // vbi packet size / delay
180#define MO_FIELD_COUNT 0x310190 // field counter
181#define MO_VIP_CONFIG 0x310194
182#define MO_VBOS_CONTROL 0x3101a8
183
184#define MO_AGC_BACK_VBI 0x310200
185#define MO_AGC_SYNC_TIP1 0x310208
186
187#define MO_VIDY_GPCNT 0x31C020 // {16}RO Video Y general purpose counter
188#define MO_VIDU_GPCNT 0x31C024 // {16}RO Video U general purpose counter
189#define MO_VIDV_GPCNT 0x31C028 // {16}RO Video V general purpose counter
190#define MO_VBI_GPCNT 0x31C02C // {16}RO VBI general purpose counter
191#define MO_VIDY_GPCNTRL 0x31C030 // {2}WO Video Y general purpose control
192#define MO_VIDU_GPCNTRL 0x31C034 // {2}WO Video U general purpose control
193#define MO_VIDV_GPCNTRL 0x31C038 // {2}WO Video V general purpose control
194#define MO_VBI_GPCNTRL 0x31C03C // {2}WO VBI general purpose counter
195#define MO_VID_DMACNTRL 0x31C040 // {8}RW Video DMA control
196#define MO_VID_XFR_STAT 0x31C044 // {1}RO Video transfer status
197
198
199/* ---------------------------------------------------------------------- */
200/* audio registers */
201
202#define MO_AUDD_DMA 0x320000 // {64}RWp Audio downstream
203#define MO_AUDU_DMA 0x320008 // {64}RWp Audio upstream
204#define MO_AUDR_DMA 0x320010 // {64}RWp Audio RDS (downstream)
205#define MO_AUDD_GPCNT 0x32C020 // {16}RO Audio down general purpose counter
206#define MO_AUDU_GPCNT 0x32C024 // {16}RO Audio up general purpose counter
207#define MO_AUDR_GPCNT 0x32C028 // {16}RO Audio RDS general purpose counter
208#define MO_AUDD_GPCNTRL 0x32C030 // {2}WO Audio down general purpose control
209#define MO_AUDU_GPCNTRL 0x32C034 // {2}WO Audio up general purpose control
210#define MO_AUDR_GPCNTRL 0x32C038 // {2}WO Audio RDS general purpose control
211#define MO_AUD_DMACNTRL 0x32C040 // {6}RW Audio DMA control
212#define MO_AUD_XFR_STAT 0x32C044 // {1}RO Audio transfer status
213#define MO_AUDD_LNGTH 0x32C048 // {12}RW Audio down line length
214#define MO_AUDR_LNGTH 0x32C04C // {12}RW Audio RDS line length
215
216#define AUD_INIT 0x320100
217#define AUD_INIT_LD 0x320104
218#define AUD_SOFT_RESET 0x320108
219#define AUD_I2SINPUTCNTL 0x320120
220#define AUD_BAUDRATE 0x320124
221#define AUD_I2SOUTPUTCNTL 0x320128
222#define AAGC_HYST 0x320134
223#define AAGC_GAIN 0x320138
224#define AAGC_DEF 0x32013c
225#define AUD_IIR1_0_SEL 0x320150
226#define AUD_IIR1_0_SHIFT 0x320154
227#define AUD_IIR1_1_SEL 0x320158
228#define AUD_IIR1_1_SHIFT 0x32015c
229#define AUD_IIR1_2_SEL 0x320160
230#define AUD_IIR1_2_SHIFT 0x320164
231#define AUD_IIR1_3_SEL 0x320168
232#define AUD_IIR1_3_SHIFT 0x32016c
233#define AUD_IIR1_4_SEL 0x320170
234#define AUD_IIR1_4_SHIFT 0x32017c
235#define AUD_IIR1_5_SEL 0x320180
236#define AUD_IIR1_5_SHIFT 0x320184
237#define AUD_IIR2_0_SEL 0x320190
238#define AUD_IIR2_0_SHIFT 0x320194
239#define AUD_IIR2_1_SEL 0x320198
240#define AUD_IIR2_1_SHIFT 0x32019c
241#define AUD_IIR2_2_SEL 0x3201a0
242#define AUD_IIR2_2_SHIFT 0x3201a4
243#define AUD_IIR2_3_SEL 0x3201a8
244#define AUD_IIR2_3_SHIFT 0x3201ac
245#define AUD_IIR3_0_SEL 0x3201c0
246#define AUD_IIR3_0_SHIFT 0x3201c4
247#define AUD_IIR3_1_SEL 0x3201c8
248#define AUD_IIR3_1_SHIFT 0x3201cc
249#define AUD_IIR3_2_SEL 0x3201d0
250#define AUD_IIR3_2_SHIFT 0x3201d4
251#define AUD_IIR4_0_SEL 0x3201e0
252#define AUD_IIR4_0_SHIFT 0x3201e4
253#define AUD_IIR4_1_SEL 0x3201e8
254#define AUD_IIR4_1_SHIFT 0x3201ec
255#define AUD_IIR4_2_SEL 0x3201f0
256#define AUD_IIR4_2_SHIFT 0x3201f4
257#define AUD_IIR4_0_CA0 0x320200
258#define AUD_IIR4_0_CA1 0x320204
259#define AUD_IIR4_0_CA2 0x320208
260#define AUD_IIR4_0_CB0 0x32020c
261#define AUD_IIR4_0_CB1 0x320210
262#define AUD_IIR4_1_CA0 0x320214
263#define AUD_IIR4_1_CA1 0x320218
264#define AUD_IIR4_1_CA2 0x32021c
265#define AUD_IIR4_1_CB0 0x320220
266#define AUD_IIR4_1_CB1 0x320224
267#define AUD_IIR4_2_CA0 0x320228
268#define AUD_IIR4_2_CA1 0x32022c
269#define AUD_IIR4_2_CA2 0x320230
270#define AUD_IIR4_2_CB0 0x320234
271#define AUD_IIR4_2_CB1 0x320238
272#define AUD_HP_MD_IIR4_1 0x320250
273#define AUD_HP_PROG_IIR4_1 0x320254
274#define AUD_FM_MODE_ENABLE 0x320258
275#define AUD_POLY0_DDS_CONSTANT 0x320270
276#define AUD_DN0_FREQ 0x320274
277#define AUD_DN1_FREQ 0x320278
278#define AUD_DN1_FREQ_SHIFT 0x32027c
279#define AUD_DN1_AFC 0x320280
280#define AUD_DN1_SRC_SEL 0x320284
281#define AUD_DN1_SHFT 0x320288
282#define AUD_DN2_FREQ 0x32028c
283#define AUD_DN2_FREQ_SHIFT 0x320290
284#define AUD_DN2_AFC 0x320294
285#define AUD_DN2_SRC_SEL 0x320298
286#define AUD_DN2_SHFT 0x32029c
287#define AUD_CRDC0_SRC_SEL 0x320300
288#define AUD_CRDC0_SHIFT 0x320304
289#define AUD_CORDIC_SHIFT_0 0x320308
290#define AUD_CRDC1_SRC_SEL 0x32030c
291#define AUD_CRDC1_SHIFT 0x320310
292#define AUD_CORDIC_SHIFT_1 0x320314
293#define AUD_DCOC_0_SRC 0x320320
294#define AUD_DCOC0_SHIFT 0x320324
295#define AUD_DCOC_0_SHIFT_IN0 0x320328
296#define AUD_DCOC_0_SHIFT_IN1 0x32032c
297#define AUD_DCOC_1_SRC 0x320330
298#define AUD_DCOC1_SHIFT 0x320334
299#define AUD_DCOC_1_SHIFT_IN0 0x320338
300#define AUD_DCOC_1_SHIFT_IN1 0x32033c
301#define AUD_DCOC_2_SRC 0x320340
302#define AUD_DCOC2_SHIFT 0x320344
303#define AUD_DCOC_2_SHIFT_IN0 0x320348
304#define AUD_DCOC_2_SHIFT_IN1 0x32034c
305#define AUD_DCOC_PASS_IN 0x320350
306#define AUD_PDET_SRC 0x320370
307#define AUD_PDET_SHIFT 0x320374
308#define AUD_PILOT_BQD_1_K0 0x320380
309#define AUD_PILOT_BQD_1_K1 0x320384
310#define AUD_PILOT_BQD_1_K2 0x320388
311#define AUD_PILOT_BQD_1_K3 0x32038c
312#define AUD_PILOT_BQD_1_K4 0x320390
313#define AUD_PILOT_BQD_2_K0 0x320394
314#define AUD_PILOT_BQD_2_K1 0x320398
315#define AUD_PILOT_BQD_2_K2 0x32039c
316#define AUD_PILOT_BQD_2_K3 0x3203a0
317#define AUD_PILOT_BQD_2_K4 0x3203a4
318#define AUD_THR_FR 0x3203c0
319#define AUD_X_PROG 0x3203c4
320#define AUD_Y_PROG 0x3203c8
321#define AUD_HARMONIC_MULT 0x3203cc
322#define AUD_C1_UP_THR 0x3203d0
323#define AUD_C1_LO_THR 0x3203d4
324#define AUD_C2_UP_THR 0x3203d8
325#define AUD_C2_LO_THR 0x3203dc
326#define AUD_PLL_EN 0x320400
327#define AUD_PLL_SRC 0x320404
328#define AUD_PLL_SHIFT 0x320408
329#define AUD_PLL_IF_SEL 0x32040c
330#define AUD_PLL_IF_SHIFT 0x320410
331#define AUD_BIQUAD_PLL_K0 0x320414
332#define AUD_BIQUAD_PLL_K1 0x320418
333#define AUD_BIQUAD_PLL_K2 0x32041c
334#define AUD_BIQUAD_PLL_K3 0x320420
335#define AUD_BIQUAD_PLL_K4 0x320424
336#define AUD_DEEMPH0_SRC_SEL 0x320440
337#define AUD_DEEMPH0_SHIFT 0x320444
338#define AUD_DEEMPH0_G0 0x320448
339#define AUD_DEEMPH0_A0 0x32044c
340#define AUD_DEEMPH0_B0 0x320450
341#define AUD_DEEMPH0_A1 0x320454
342#define AUD_DEEMPH0_B1 0x320458
343#define AUD_DEEMPH1_SRC_SEL 0x32045c
344#define AUD_DEEMPH1_SHIFT 0x320460
345#define AUD_DEEMPH1_G0 0x320464
346#define AUD_DEEMPH1_A0 0x320468
347#define AUD_DEEMPH1_B0 0x32046c
348#define AUD_DEEMPH1_A1 0x320470
349#define AUD_DEEMPH1_B1 0x320474
350#define AUD_OUT0_SEL 0x320490
351#define AUD_OUT0_SHIFT 0x320494
352#define AUD_OUT1_SEL 0x320498
353#define AUD_OUT1_SHIFT 0x32049c
354#define AUD_RDSI_SEL 0x3204a0
355#define AUD_RDSI_SHIFT 0x3204a4
356#define AUD_RDSQ_SEL 0x3204a8
357#define AUD_RDSQ_SHIFT 0x3204ac
358#define AUD_DBX_IN_GAIN 0x320500
359#define AUD_DBX_WBE_GAIN 0x320504
360#define AUD_DBX_SE_GAIN 0x320508
361#define AUD_DBX_RMS_WBE 0x32050c
362#define AUD_DBX_RMS_SE 0x320510
363#define AUD_DBX_SE_BYPASS 0x320514
364#define AUD_FAWDETCTL 0x320530
365#define AUD_FAWDETWINCTL 0x320534
366#define AUD_DEEMPHGAIN_R 0x320538
367#define AUD_DEEMPHNUMER1_R 0x32053c
368#define AUD_DEEMPHNUMER2_R 0x320540
369#define AUD_DEEMPHDENOM1_R 0x320544
370#define AUD_DEEMPHDENOM2_R 0x320548
371#define AUD_ERRLOGPERIOD_R 0x32054c
372#define AUD_ERRINTRPTTHSHLD1_R 0x320550
373#define AUD_ERRINTRPTTHSHLD2_R 0x320554
374#define AUD_ERRINTRPTTHSHLD3_R 0x320558
375#define AUD_NICAM_STATUS1 0x32055c
376#define AUD_NICAM_STATUS2 0x320560
377#define AUD_ERRLOG1 0x320564
378#define AUD_ERRLOG2 0x320568
379#define AUD_ERRLOG3 0x32056c
380#define AUD_DAC_BYPASS_L 0x320580
381#define AUD_DAC_BYPASS_R 0x320584
382#define AUD_DAC_BYPASS_CTL 0x320588
383#define AUD_CTL 0x32058c
384#define AUD_STATUS 0x320590
385#define AUD_VOL_CTL 0x320594
386#define AUD_BAL_CTL 0x320598
387#define AUD_START_TIMER 0x3205b0
388#define AUD_MODE_CHG_TIMER 0x3205b4
389#define AUD_POLYPH80SCALEFAC 0x3205b8
390#define AUD_DMD_RA_DDS 0x3205bc
391#define AUD_I2S_RA_DDS 0x3205c0
392#define AUD_RATE_THRES_DMD 0x3205d0
393#define AUD_RATE_THRES_I2S 0x3205d4
394#define AUD_RATE_ADJ1 0x3205d8
395#define AUD_RATE_ADJ2 0x3205dc
396#define AUD_RATE_ADJ3 0x3205e0
397#define AUD_RATE_ADJ4 0x3205e4
398#define AUD_RATE_ADJ5 0x3205e8
399#define AUD_APB_IN_RATE_ADJ 0x3205ec
400#define AUD_PHASE_FIX_CTL 0x3205f0
401#define AUD_PLL_PRESCALE 0x320600
402#define AUD_PLL_DDS 0x320604
403#define AUD_PLL_INT 0x320608
404#define AUD_PLL_FRAC 0x32060c
405#define AUD_PLL_JTAG 0x320620
406#define AUD_PLL_SPMP 0x320624
407#define AUD_AFE_12DB_EN 0x320628
408
409// Audio QAM Register Addresses
410#define AUD_PDF_DDS_CNST_BYTE2 0x320d01
411#define AUD_PDF_DDS_CNST_BYTE1 0x320d02
412#define AUD_PDF_DDS_CNST_BYTE0 0x320d03
413#define AUD_PHACC_FREQ_8MSB 0x320d2a
414#define AUD_PHACC_FREQ_8LSB 0x320d2b
415#define AUD_QAM_MODE 0x320d04
416
417
418/* ---------------------------------------------------------------------- */
419/* transport stream registers */
420
421#define MO_TS_DMA 0x330000 // {64}RWp Transport stream downstream
422#define MO_TS_GPCNT 0x33C020 // {16}RO TS general purpose counter
423#define MO_TS_GPCNTRL 0x33C030 // {2}WO TS general purpose control
424#define MO_TS_DMACNTRL 0x33C040 // {6}RW TS DMA control
425#define MO_TS_XFR_STAT 0x33C044 // {1}RO TS transfer status
426#define MO_TS_LNGTH 0x33C048 // {12}RW TS line length
427
428#define TS_HW_SOP_CNTRL 0x33C04C
429#define TS_GEN_CNTRL 0x33C050
430#define TS_BD_PKT_STAT 0x33C054
431#define TS_SOP_STAT 0x33C058
432#define TS_FIFO_OVFL_STAT 0x33C05C
433#define TS_VALERR_CNTRL 0x33C060
434
435
436/* ---------------------------------------------------------------------- */
437/* VIP registers */
438
439#define MO_VIPD_DMA 0x340000 // {64}RWp VIP downstream
440#define MO_VIPU_DMA 0x340008 // {64}RWp VIP upstream
441#define MO_VIPD_GPCNT 0x34C020 // {16}RO VIP down general purpose counter
442#define MO_VIPU_GPCNT 0x34C024 // {16}RO VIP up general purpose counter
443#define MO_VIPD_GPCNTRL 0x34C030 // {2}WO VIP down general purpose control
444#define MO_VIPU_GPCNTRL 0x34C034 // {2}WO VIP up general purpose control
445#define MO_VIP_DMACNTRL 0x34C040 // {6}RW VIP DMA control
446#define MO_VIP_XFR_STAT 0x34C044 // {1}RO VIP transfer status
447#define MO_VIP_CFG 0x340048 // VIP configuration
448#define MO_VIPU_CNTRL 0x34004C // VIP upstream control #1
449#define MO_VIPD_CNTRL 0x340050 // VIP downstream control #2
450#define MO_VIPD_LNGTH 0x340054 // VIP downstream line length
451#define MO_VIP_BRSTLN 0x340058 // VIP burst length
452#define MO_VIP_INTCNTRL 0x34C05C // VIP Interrupt Control
453#define MO_VIP_XFTERM 0x340060 // VIP transfer terminate
454
455
456/* ---------------------------------------------------------------------- */
457/* misc registers */
458
459#define MO_M2M_DMA 0x350000 // {64}RWp Mem2Mem DMA Bfr
460#define MO_GP0_IO 0x350010 // {32}RW* GPIOoutput enablesdata I/O
461#define MO_GP1_IO 0x350014 // {32}RW* GPIOoutput enablesdata I/O
462#define MO_GP2_IO 0x350018 // {32}RW* GPIOoutput enablesdata I/O
463#define MO_GP3_IO 0x35001C // {32}RW* GPIO Mode/Ctrloutput enables
464#define MO_GPIO 0x350020 // {32}RW* GPIO I2C Ctrldata I/O
465#define MO_GPOE 0x350024 // {32}RW GPIO I2C Ctrloutput enables
466#define MO_GP_ISM 0x350028 // {16}WO GPIO Intr Sens/Pol
467
468#define MO_PLL_B 0x35C008 // {32}RW* PLL Control for ASB bus clks
469#define MO_M2M_CNT 0x35C024 // {32}RW Mem2Mem DMA Cnt
470#define MO_M2M_XSUM 0x35C028 // {32}RO M2M XOR-Checksum
471#define MO_CRC 0x35C02C // {16}RW CRC16 init/result
472#define MO_CRC_D 0x35C030 // {32}WO CRC16 new data in
473#define MO_TM_CNT_LDW 0x35C034 // {32}RO Timer : Counter low dword
474#define MO_TM_CNT_UW 0x35C038 // {16}RO Timer : Counter high word
475#define MO_TM_LMT_LDW 0x35C03C // {32}RW Timer : Limit low dword
476#define MO_TM_LMT_UW 0x35C040 // {32}RW Timer : Limit high word
477#define MO_PINMUX_IO 0x35C044 // {8}RW Pin Mux Control
478#define MO_TSTSEL_IO 0x35C048 // {2}RW Pin Mux Control
479#define MO_AFECFG_IO 0x35C04C // AFE configuration reg
480#define MO_DDS_IO 0x35C050 // DDS Increment reg
481#define MO_DDSCFG_IO 0x35C054 // DDS Configuration reg
482#define MO_SAMPLE_IO 0x35C058 // IRIn sample reg
483#define MO_SRST_IO 0x35C05C // Output system reset reg
484
485#define MO_INT1_MSK 0x35C060 // DMA RISC interrupt mask
486#define MO_INT1_STAT 0x35C064 // DMA RISC interrupt status
487#define MO_INT1_MSTAT 0x35C068 // DMA RISC interrupt masked status
488
489
490/* ---------------------------------------------------------------------- */
491/* i2c bus registers */
492
493#define MO_I2C 0x368000 // I2C data/control
494#define MO_I2C_DIV (0xf<<4)
495#define MO_I2C_SYNC (1<<3)
496#define MO_I2C_W3B (1<<2)
497#define MO_I2C_SCL (1<<1)
498#define MO_I2C_SDA (1<<0)
499
500
501/* ---------------------------------------------------------------------- */
502/* general purpose host registers */
503/* FIXME: tyops? s/0x35/0x38/ ?? */
504
505#define MO_GPHSTD_DMA 0x350000 // {64}RWp Host downstream
506#define MO_GPHSTU_DMA 0x350008 // {64}RWp Host upstream
507#define MO_GPHSTU_CNTRL 0x380048 // Host upstream control #1
508#define MO_GPHSTD_CNTRL 0x38004C // Host downstream control #2
509#define MO_GPHSTD_LNGTH 0x380050 // Host downstream line length
510#define MO_GPHST_WSC 0x380054 // Host wait state control
511#define MO_GPHST_XFR 0x380058 // Host transfer control
512#define MO_GPHST_WDTH 0x38005C // Host interface width
513#define MO_GPHST_HDSHK 0x380060 // Host peripheral handshake
514#define MO_GPHST_MUX16 0x380064 // Host muxed 16-bit transfer parameters
515#define MO_GPHST_MODE 0x380068 // Host mode select
516
517#define MO_GPHSTD_GPCNT 0x35C020 // Host down general purpose counter
518#define MO_GPHSTU_GPCNT 0x35C024 // Host up general purpose counter
519#define MO_GPHSTD_GPCNTRL 0x38C030 // Host down general purpose control
520#define MO_GPHSTU_GPCNTRL 0x38C034 // Host up general purpose control
521#define MO_GPHST_DMACNTRL 0x38C040 // Host DMA control
522#define MO_GPHST_XFR_STAT 0x38C044 // Host transfer status
523#define MO_GPHST_SOFT_RST 0x38C06C // Host software reset
524
525
526/* ---------------------------------------------------------------------- */
527/* RISC instructions */
528
529#define RISC_SYNC 0x80000000
530#define RISC_SYNC_ODD 0x80000000
531#define RISC_SYNC_EVEN 0x80000200
532#define RISC_RESYNC 0x80008000
533#define RISC_RESYNC_ODD 0x80008000
534#define RISC_RESYNC_EVEN 0x80008200
535#define RISC_WRITE 0x10000000
536#define RISC_WRITEC 0x50000000
537#define RISC_READ 0x90000000
538#define RISC_READC 0xA0000000
539#define RISC_JUMP 0x70000000
540#define RISC_SKIP 0x20000000
541#define RISC_WRITERM 0xB0000000
542#define RISC_WRITECM 0xC0000000
543#define RISC_WRITECR 0xD0000000
544#define RISC_IMM 0x00000001
545
546#define RISC_SOL 0x08000000
547#define RISC_EOL 0x04000000
548
549#define RISC_IRQ2 0x02000000
550#define RISC_IRQ1 0x01000000
551
552#define RISC_CNT_NONE 0x00000000
553#define RISC_CNT_INC 0x00010000
554#define RISC_CNT_RSVR 0x00020000
555#define RISC_CNT_RESET 0x00030000
556#define RISC_JMP_SRP 0x01
557
558
559/* ---------------------------------------------------------------------- */
560/* various constants */
561
562#define SEL_BTSC 0x01
563#define SEL_EIAJ 0x02
564#define SEL_A2 0x04
565#define SEL_SAP 0x08
566#define SEL_NICAM 0x10
567#define SEL_FMRADIO 0x20
568
569// AUD_CTL
570#define EN_BTSC_FORCE_MONO 0
571#define EN_BTSC_FORCE_STEREO 1
572#define EN_BTSC_FORCE_SAP 2
573#define EN_BTSC_AUTO_STEREO 3
574#define EN_BTSC_AUTO_SAP 4
575
576#define EN_A2_FORCE_MONO1 8
577#define EN_A2_FORCE_MONO2 9
578#define EN_A2_FORCE_STEREO 10
579#define EN_A2_AUTO_MONO2 11
580#define EN_A2_AUTO_STEREO 12
581
582#define EN_EIAJ_FORCE_MONO1 16
583#define EN_EIAJ_FORCE_MONO2 17
584#define EN_EIAJ_FORCE_STEREO 18
585#define EN_EIAJ_AUTO_MONO2 19
586#define EN_EIAJ_AUTO_STEREO 20
587
588#define EN_NICAM_FORCE_MONO1 32
589#define EN_NICAM_FORCE_MONO2 33
590#define EN_NICAM_FORCE_STEREO 34
591#define EN_NICAM_AUTO_MONO2 35
592#define EN_NICAM_AUTO_STEREO 36
593
594#define EN_FMRADIO_FORCE_MONO 24
595#define EN_FMRADIO_FORCE_STEREO 25
596#define EN_FMRADIO_AUTO_STEREO 26
597
598#define EN_NICAM_AUTO_FALLBACK 0x00000040
599#define EN_FMRADIO_EN_RDS 0x00000200
600#define EN_NICAM_TRY_AGAIN_BIT 0x00000400
601#define EN_DAC_ENABLE 0x00001000
602#define EN_I2SOUT_ENABLE 0x00002000
603#define EN_I2SIN_STR2DAC 0x00004000
604#define EN_I2SIN_ENABLE 0x00008000
605
606#if 0
607/* old */
608#define EN_DMTRX_SUMDIFF 0x00000800
609#define EN_DMTRX_SUMR 0x00000880
610#define EN_DMTRX_LR 0x00000900
611#define EN_DMTRX_MONO 0x00000980
612#else
613/* dscaler cvs */
614#define EN_DMTRX_SUMDIFF (0 << 7)
615#define EN_DMTRX_SUMR (1 << 7)
616#define EN_DMTRX_LR (2 << 7)
617#define EN_DMTRX_MONO (3 << 7)
618#define EN_DMTRX_BYPASS (1 << 11)
619#endif
620
621// Video
622#define VID_CAPTURE_CONTROL 0x310180
623
624#define CX23880_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
625#define CX23880_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
626#define CX23880_CAP_CTL_CAPTURE_ODD (1<<1)
627#define CX23880_CAP_CTL_CAPTURE_EVEN (1<<0)
628
629#define VideoInputMux0 0x0
630#define VideoInputMux1 0x1
631#define VideoInputMux2 0x2
632#define VideoInputMux3 0x3
633#define VideoInputTuner 0x0
634#define VideoInputComposite 0x1
635#define VideoInputSVideo 0x2
636#define VideoInputOther 0x3
637
638#define Xtal0 0x1
639#define Xtal1 0x2
640#define XtalAuto 0x3
641
642#define VideoFormatAuto 0x0
643#define VideoFormatNTSC 0x1
644#define VideoFormatNTSCJapan 0x2
645#define VideoFormatNTSC443 0x3
646#define VideoFormatPAL 0x4
647#define VideoFormatPALB 0x4
648#define VideoFormatPALD 0x4
649#define VideoFormatPALG 0x4
650#define VideoFormatPALH 0x4
651#define VideoFormatPALI 0x4
652#define VideoFormatPALBDGHI 0x4
653#define VideoFormatPALM 0x5
654#define VideoFormatPALN 0x6
655#define VideoFormatPALNC 0x7
656#define VideoFormatPAL60 0x8
657#define VideoFormatSECAM 0x9
658
659#define VideoFormatAuto27MHz 0x10
660#define VideoFormatNTSC27MHz 0x11
661#define VideoFormatNTSCJapan27MHz 0x12
662#define VideoFormatNTSC44327MHz 0x13
663#define VideoFormatPAL27MHz 0x14
664#define VideoFormatPALB27MHz 0x14
665#define VideoFormatPALD27MHz 0x14
666#define VideoFormatPALG27MHz 0x14
667#define VideoFormatPALH27MHz 0x14
668#define VideoFormatPALI27MHz 0x14
669#define VideoFormatPALBDGHI27MHz 0x14
670#define VideoFormatPALM27MHz 0x15
671#define VideoFormatPALN27MHz 0x16
672#define VideoFormatPALNC27MHz 0x17
673#define VideoFormatPAL6027MHz 0x18
674#define VideoFormatSECAM27MHz 0x19
675
676#define NominalUSECAM 0x87
677#define NominalVSECAM 0x85
678#define NominalUNTSC 0xFE
679#define NominalVNTSC 0xB4
680
681#define NominalContrast 0xD8
682
683#define HFilterAutoFormat 0x0
684#define HFilterCIF 0x1
685#define HFilterQCIF 0x2
686#define HFilterICON 0x3
687
688#define VFilter2TapInterpolate 0
689#define VFilter3TapInterpolate 1
690#define VFilter4TapInterpolate 2
691#define VFilter5TapInterpolate 3
692#define VFilter2TapNoInterpolate 4
693#define VFilter3TapNoInterpolate 5
694#define VFilter4TapNoInterpolate 6
695#define VFilter5TapNoInterpolate 7
696
697#define ColorFormatRGB32 0x0000
698#define ColorFormatRGB24 0x0011
699#define ColorFormatRGB16 0x0022
700#define ColorFormatRGB15 0x0033
701#define ColorFormatYUY2 0x0044
702#define ColorFormatBTYUV 0x0055
703#define ColorFormatY8 0x0066
704#define ColorFormatRGB8 0x0077
705#define ColorFormatPL422 0x0088
706#define ColorFormatPL411 0x0099
707#define ColorFormatYUV12 0x00AA
708#define ColorFormatYUV9 0x00BB
709#define ColorFormatRAW 0x00EE
710#define ColorFormatBSWAP 0x0300
711#define ColorFormatWSWAP 0x0c00
712#define ColorFormatEvenMask 0x050f
713#define ColorFormatOddMask 0x0af0
714#define ColorFormatGamma 0x1000
715
716#define Interlaced 0x1
717#define NonInterlaced 0x0
718
719#define FieldEven 0x1
720#define FieldOdd 0x0
721
722#define TGReadWriteMode 0x0
723#define TGEnableMode 0x1
724
725#define DV_CbAlign 0x0
726#define DV_Y0Align 0x1
727#define DV_CrAlign 0x2
728#define DV_Y1Align 0x3
729
730#define DVF_Analog 0x0
731#define DVF_CCIR656 0x1
732#define DVF_ByteStream 0x2
733#define DVF_ExtVSYNC 0x4
734#define DVF_ExtField 0x5
735
736#define CHANNEL_VID_Y 0x1
737#define CHANNEL_VID_U 0x2
738#define CHANNEL_VID_V 0x3
739#define CHANNEL_VID_VBI 0x4
740#define CHANNEL_AUD_DN 0x5
741#define CHANNEL_AUD_UP 0x6
742#define CHANNEL_AUD_RDS_DN 0x7
743#define CHANNEL_MPEG_DN 0x8
744#define CHANNEL_VIP_DN 0x9
745#define CHANNEL_VIP_UP 0xA
746#define CHANNEL_HOST_DN 0xB
747#define CHANNEL_HOST_UP 0xC
748#define CHANNEL_FIRST 0x1
749#define CHANNEL_LAST 0xC
750
751#define GP_COUNT_CONTROL_NONE 0x0
752#define GP_COUNT_CONTROL_INC 0x1
753#define GP_COUNT_CONTROL_RESERVED 0x2
754#define GP_COUNT_CONTROL_RESET 0x3
755
756#define PLL_PRESCALE_BY_2 2
757#define PLL_PRESCALE_BY_3 3
758#define PLL_PRESCALE_BY_4 4
759#define PLL_PRESCALE_BY_5 5
760
761#define HLNotchFilter4xFsc 0
762#define HLNotchFilterSquare 1
763#define HLNotchFilter135NTSC 2
764#define HLNotchFilter135PAL 3
765
766#define NTSC_8x_SUB_CARRIER 28.63636E6
767#define PAL_8x_SUB_CARRIER 35.46895E6
768
769// Default analog settings
770#define DEFAULT_HUE_NTSC 0x00
771#define DEFAULT_BRIGHTNESS_NTSC 0x00
772#define DEFAULT_CONTRAST_NTSC 0x39
773#define DEFAULT_SAT_U_NTSC 0x7F
774#define DEFAULT_SAT_V_NTSC 0x5A
775
776typedef enum
777{
778 SOURCE_TUNER = 0,
779 SOURCE_COMPOSITE,
780 SOURCE_SVIDEO,
781 SOURCE_OTHER1,
782 SOURCE_OTHER2,
783 SOURCE_COMPVIASVIDEO,
784 SOURCE_CCIR656
785} VIDEOSOURCETYPE;
786
787#endif /* _CX88_REG_H_ */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
new file mode 100644
index 000000000000..f2a9475a2fee
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -0,0 +1,1032 @@
1/*
2 $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $
3
4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
5
6 (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version]
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 2003 Gerd Knorr <kraxel@bytesex.org>
9
10 -----------------------------------------------------------------------
11
12 Lot of voodoo here. Even the data sheet doesn't help to
13 understand what is going on here, the documentation for the audio
14 part of the cx2388x chip is *very* bad.
15
16 Some of this comes from party done linux driver sources I got from
17 [undocumented].
18
19 Some comes from the dscaler sources, one of the dscaler driver guy works
20 for Conexant ...
21
22 -----------------------------------------------------------------------
23
24 This program is free software; you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation; either version 2 of the License, or
27 (at your option) any later version.
28
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37*/
38
39#include <linux/module.h>
40#include <linux/moduleparam.h>
41#include <linux/errno.h>
42#include <linux/kernel.h>
43#include <linux/slab.h>
44#include <linux/mm.h>
45#include <linux/poll.h>
46#include <linux/pci.h>
47#include <linux/signal.h>
48#include <linux/ioport.h>
49#include <linux/sched.h>
50#include <linux/types.h>
51#include <linux/interrupt.h>
52#include <linux/vmalloc.h>
53#include <linux/init.h>
54#include <linux/smp_lock.h>
55#include <linux/delay.h>
56#include <linux/kthread.h>
57
58#include "cx88.h"
59
60static unsigned int audio_debug = 0;
61module_param(audio_debug,int,0644);
62MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]");
63
64#define dprintk(fmt, arg...) if (audio_debug) \
65 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
66
67/* ----------------------------------------------------------- */
68
69static char *aud_ctl_names[64] =
70{
71 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO",
72 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO",
73 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP",
74 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO",
75 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP",
76 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1",
77 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2",
78 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO",
79 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2",
80 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO",
81 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1",
82 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2",
83 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO",
84 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2",
85 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO",
86 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1",
87 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2",
88 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO",
89 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2",
90 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO",
91 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO",
92 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO",
93 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
94};
95
96struct rlist {
97 u32 reg;
98 u32 val;
99};
100
101static void set_audio_registers(struct cx88_core *core,
102 const struct rlist *l)
103{
104 int i;
105
106 for (i = 0; l[i].reg; i++) {
107 switch (l[i].reg) {
108 case AUD_PDF_DDS_CNST_BYTE2:
109 case AUD_PDF_DDS_CNST_BYTE1:
110 case AUD_PDF_DDS_CNST_BYTE0:
111 case AUD_QAM_MODE:
112 case AUD_PHACC_FREQ_8MSB:
113 case AUD_PHACC_FREQ_8LSB:
114 cx_writeb(l[i].reg, l[i].val);
115 break;
116 default:
117 cx_write(l[i].reg, l[i].val);
118 break;
119 }
120 }
121}
122
123static void set_audio_start(struct cx88_core *core,
124 u32 mode, u32 ctl)
125{
126 // mute
127 cx_write(AUD_VOL_CTL, (1 << 6));
128
129 // increase level of input by 12dB
130 cx_write(AUD_AFE_12DB_EN, 0x0001);
131
132 // start programming
133 cx_write(AUD_CTL, 0x0000);
134 cx_write(AUD_INIT, mode);
135 cx_write(AUD_INIT_LD, 0x0001);
136 cx_write(AUD_SOFT_RESET, 0x0001);
137
138 cx_write(AUD_CTL, ctl);
139}
140
141static void set_audio_finish(struct cx88_core *core)
142{
143 u32 volume;
144
145 if (cx88_boards[core->board].blackbird) {
146 // 'pass-thru mode': this enables the i2s output to the mpeg encoder
147 cx_set(AUD_CTL, 0x2000);
148 cx_write(AUD_I2SOUTPUTCNTL, 1);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 }
151
152 // finish programming
153 cx_write(AUD_SOFT_RESET, 0x0000);
154
155 // start audio processing
156 cx_set(AUD_CTL, EN_DAC_ENABLE);
157
158 // unmute
159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
160 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
161}
162
163/* ----------------------------------------------------------- */
164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
166{
167 static const struct rlist btsc[] = {
168 /* from dscaler */
169 { AUD_OUT1_SEL, 0x00000013 },
170 { AUD_OUT1_SHIFT, 0x00000000 },
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
172 { AUD_DMD_RA_DDS, 0x00c3e7aa },
173 { AUD_DBX_IN_GAIN, 0x00004734 },
174 { AUD_DBX_WBE_GAIN, 0x00004640 },
175 { AUD_DBX_SE_GAIN, 0x00008d31 },
176 { AUD_DCOC_0_SRC, 0x0000001a },
177 { AUD_IIR1_4_SEL, 0x00000021 },
178 { AUD_DCOC_PASS_IN, 0x00000003 },
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
183 { AUD_DN0_FREQ, 0x0000283b },
184 { AUD_DN2_SRC_SEL, 0x00000008 },
185 { AUD_DN2_FREQ, 0x00003000 },
186 { AUD_DN2_AFC, 0x00000002 },
187 { AUD_DN2_SHFT, 0x00000000 },
188 { AUD_IIR2_2_SEL, 0x00000020 },
189 { AUD_IIR2_2_SHIFT, 0x00000000 },
190 { AUD_IIR2_3_SEL, 0x0000001f },
191 { AUD_IIR2_3_SHIFT, 0x00000000 },
192 { AUD_CRDC1_SRC_SEL, 0x000003ce },
193 { AUD_CRDC1_SHIFT, 0x00000000 },
194 { AUD_CORDIC_SHIFT_1, 0x00000007 },
195 { AUD_DCOC_1_SRC, 0x0000001b },
196 { AUD_DCOC1_SHIFT, 0x00000000 },
197 { AUD_RDSI_SEL, 0x00000008 },
198 { AUD_RDSQ_SEL, 0x00000008 },
199 { AUD_RDSI_SHIFT, 0x00000000 },
200 { AUD_RDSQ_SHIFT, 0x00000000 },
201 { AUD_POLYPH80SCALEFAC, 0x00000003 },
202 { /* end of list */ },
203 };
204 static const struct rlist btsc_sap[] = {
205 { AUD_DBX_IN_GAIN, 0x00007200 },
206 { AUD_DBX_WBE_GAIN, 0x00006200 },
207 { AUD_DBX_SE_GAIN, 0x00006200 },
208 { AUD_IIR1_1_SEL, 0x00000000 },
209 { AUD_IIR1_3_SEL, 0x00000001 },
210 { AUD_DN1_SRC_SEL, 0x00000007 },
211 { AUD_IIR1_4_SHIFT, 0x00000006 },
212 { AUD_IIR2_1_SHIFT, 0x00000000 },
213 { AUD_IIR2_2_SHIFT, 0x00000000 },
214 { AUD_IIR3_0_SHIFT, 0x00000000 },
215 { AUD_IIR3_1_SHIFT, 0x00000000 },
216 { AUD_IIR3_0_SEL, 0x0000000d },
217 { AUD_IIR3_1_SEL, 0x0000000e },
218 { AUD_DEEMPH1_SRC_SEL, 0x00000014 },
219 { AUD_DEEMPH1_SHIFT, 0x00000000 },
220 { AUD_DEEMPH1_G0, 0x00004000 },
221 { AUD_DEEMPH1_A0, 0x00000000 },
222 { AUD_DEEMPH1_B0, 0x00000000 },
223 { AUD_DEEMPH1_A1, 0x00000000 },
224 { AUD_DEEMPH1_B1, 0x00000000 },
225 { AUD_OUT0_SEL, 0x0000003f },
226 { AUD_OUT1_SEL, 0x0000003f },
227 { AUD_DN1_AFC, 0x00000002 },
228 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
229 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
230 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
231 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
232 { AUD_IIR1_0_SEL, 0x0000001d },
233 { AUD_IIR1_2_SEL, 0x0000001e },
234 { AUD_IIR2_1_SEL, 0x00000002 },
235 { AUD_IIR2_2_SEL, 0x00000004 },
236 { AUD_IIR3_2_SEL, 0x0000000f },
237 { AUD_DCOC2_SHIFT, 0x00000001 },
238 { AUD_IIR3_2_SHIFT, 0x00000001 },
239 { AUD_DEEMPH0_SRC_SEL, 0x00000014 },
240 { AUD_CORDIC_SHIFT_1, 0x00000006 },
241 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
242 { AUD_DMD_RA_DDS, 0x00f696e6 },
243 { AUD_IIR2_3_SEL, 0x00000025 },
244 { AUD_IIR1_4_SEL, 0x00000021 },
245 { AUD_DN1_FREQ, 0x0000c965 },
246 { AUD_DCOC_PASS_IN, 0x00000003 },
247 { AUD_DCOC_0_SRC, 0x0000001a },
248 { AUD_DCOC_1_SRC, 0x0000001b },
249 { AUD_DCOC1_SHIFT, 0x00000000 },
250 { AUD_RDSI_SEL, 0x00000009 },
251 { AUD_RDSQ_SEL, 0x00000009 },
252 { AUD_RDSI_SHIFT, 0x00000000 },
253 { AUD_RDSQ_SHIFT, 0x00000000 },
254 { AUD_POLYPH80SCALEFAC, 0x00000003 },
255 { /* end of list */ },
256 };
257
258 // dscaler: exactly taken from driver,
259 // dscaler: don't know why to set EN_FMRADIO_EN_RDS
260 if (sap) {
261 dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
262 set_audio_start(core, 0x0001,
263 EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
264 set_audio_registers(core, btsc_sap);
265 } else {
266 dprintk("%s (status: known-good)\n",__FUNCTION__);
267 set_audio_start(core, 0x0001,
268 EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
269 set_audio_registers(core, btsc);
270 }
271 set_audio_finish(core);
272}
273
274#if 0
275static void set_audio_standard_NICAM(struct cx88_core *core)
276{
277 static const struct rlist nicam_common[] = {
278 /* from dscaler */
279 { AUD_RATE_ADJ1, 0x00000010 },
280 { AUD_RATE_ADJ2, 0x00000040 },
281 { AUD_RATE_ADJ3, 0x00000100 },
282 { AUD_RATE_ADJ4, 0x00000400 },
283 { AUD_RATE_ADJ5, 0x00001000 },
284 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
285
286 // Deemphasis 1:
287 { AUD_DEEMPHGAIN_R, 0x000023c2 },
288 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
289 { AUD_DEEMPHNUMER2_R, 0x0003023e },
290 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
291 { AUD_DEEMPHDENOM2_R, 0x00000000 },
292
293#if 0
294 // Deemphasis 2: (other tv norm?)
295 { AUD_DEEMPHGAIN_R, 0x0000c600 },
296 { AUD_DEEMPHNUMER1_R, 0x00066738 },
297 { AUD_DEEMPHNUMER2_R, 0x00066739 },
298 { AUD_DEEMPHDENOM1_R, 0x0001e88c },
299 { AUD_DEEMPHDENOM2_R, 0x0001e88c },
300#endif
301
302 { AUD_DEEMPHDENOM2_R, 0x00000000 },
303 { AUD_ERRLOGPERIOD_R, 0x00000fff },
304 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
305 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
306 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
307 { AUD_POLYPH80SCALEFAC, 0x00000003 },
308
309 // setup QAM registers
310 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
311 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
312 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
313 { AUD_QAM_MODE, 0x05 },
314
315 { /* end of list */ },
316 };
317 static const struct rlist nicam_pal_i[] = {
318 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
319 { AUD_PHACC_FREQ_8MSB, 0x3a },
320 { AUD_PHACC_FREQ_8LSB, 0x93 },
321
322 { /* end of list */ },
323 };
324 static const struct rlist nicam_default[] = {
325 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
326 { AUD_PHACC_FREQ_8MSB, 0x34 },
327 { AUD_PHACC_FREQ_8LSB, 0x4c },
328
329 { /* end of list */ },
330 };
331
332 set_audio_start(core, 0x0010,
333 EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
334 set_audio_registers(core, nicam_common);
335 switch (core->tvaudio) {
336 case WW_NICAM_I:
337 dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
338 set_audio_registers(core, nicam_pal_i);
339 break;
340 case WW_NICAM_BGDKL:
341 dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__);
342 set_audio_registers(core, nicam_default);
343 break;
344 };
345 set_audio_finish(core);
346}
347#endif
348
349static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
350{
351 /* This is probably weird..
352 * Let's operate and find out. */
353
354 static const struct rlist nicam_l_mono[] = {
355 { AUD_ERRLOGPERIOD_R, 0x00000064 },
356 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
357 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
358 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
359
360 { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
361 { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
362 { AUD_QAM_MODE, 0x00 },
363 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
364 { AUD_PHACC_FREQ_8MSB, 0x3a },
365 { AUD_PHACC_FREQ_8LSB, 0x4a },
366
367 { AUD_DEEMPHGAIN_R, 0x6680 },
368 { AUD_DEEMPHNUMER1_R, 0x353DE },
369 { AUD_DEEMPHNUMER2_R, 0x1B1 },
370 { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
371 { AUD_DEEMPHDENOM2_R, 0x0 },
372 { AUD_FM_MODE_ENABLE, 0x7 },
373 { AUD_POLYPH80SCALEFAC, 0x3 },
374 { AUD_AFE_12DB_EN, 0x1 },
375 { AAGC_GAIN, 0x0 },
376 { AAGC_HYST, 0x18 },
377 { AAGC_DEF, 0x20 },
378 { AUD_DN0_FREQ, 0x0 },
379 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
380 { AUD_DCOC_0_SRC, 0x21 },
381 { AUD_IIR1_0_SEL, 0x0 },
382 { AUD_IIR1_0_SHIFT, 0x7 },
383 { AUD_IIR1_1_SEL, 0x2 },
384 { AUD_IIR1_1_SHIFT, 0x0 },
385 { AUD_DCOC_1_SRC, 0x3 },
386 { AUD_DCOC1_SHIFT, 0x0 },
387 { AUD_DCOC_PASS_IN, 0x0 },
388 { AUD_IIR1_2_SEL, 0x23 },
389 { AUD_IIR1_2_SHIFT, 0x0 },
390 { AUD_IIR1_3_SEL, 0x4 },
391 { AUD_IIR1_3_SHIFT, 0x7 },
392 { AUD_IIR1_4_SEL, 0x5 },
393 { AUD_IIR1_4_SHIFT, 0x7 },
394 { AUD_IIR3_0_SEL, 0x7 },
395 { AUD_IIR3_0_SHIFT, 0x0 },
396 { AUD_DEEMPH0_SRC_SEL, 0x11 },
397 { AUD_DEEMPH0_SHIFT, 0x0 },
398 { AUD_DEEMPH0_G0, 0x7000 },
399 { AUD_DEEMPH0_A0, 0x0 },
400 { AUD_DEEMPH0_B0, 0x0 },
401 { AUD_DEEMPH0_A1, 0x0 },
402 { AUD_DEEMPH0_B1, 0x0 },
403 { AUD_DEEMPH1_SRC_SEL, 0x11 },
404 { AUD_DEEMPH1_SHIFT, 0x0 },
405 { AUD_DEEMPH1_G0, 0x7000 },
406 { AUD_DEEMPH1_A0, 0x0 },
407 { AUD_DEEMPH1_B0, 0x0 },
408 { AUD_DEEMPH1_A1, 0x0 },
409 { AUD_DEEMPH1_B1, 0x0 },
410 { AUD_OUT0_SEL, 0x3F },
411 { AUD_OUT1_SEL, 0x3F },
412 { AUD_DMD_RA_DDS, 0x0F5C285 },
413 { AUD_PLL_INT, 0x1E },
414 { AUD_PLL_DDS, 0x0 },
415 { AUD_PLL_FRAC, 0x0E542 },
416
417 // setup QAM registers
418 { AUD_RATE_ADJ1, 0x00000100 },
419 { AUD_RATE_ADJ2, 0x00000200 },
420 { AUD_RATE_ADJ3, 0x00000300 },
421 { AUD_RATE_ADJ4, 0x00000400 },
422 { AUD_RATE_ADJ5, 0x00000500 },
423 { AUD_RATE_THRES_DMD, 0x000000C0 },
424 { /* end of list */ },
425 };
426
427 static const struct rlist nicam_l[] = {
428 // setup QAM registers
429 { AUD_RATE_ADJ1, 0x00000060 },
430 { AUD_RATE_ADJ2, 0x000000F9 },
431 { AUD_RATE_ADJ3, 0x000001CC },
432 { AUD_RATE_ADJ4, 0x000002B3 },
433 { AUD_RATE_ADJ5, 0x00000726 },
434 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
435 { AUD_DEEMPHDENOM2_R, 0x00000000 },
436 { AUD_ERRLOGPERIOD_R, 0x00000064 },
437 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
438 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
439 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
440 { AUD_POLYPH80SCALEFAC, 0x00000003 },
441 { AUD_DMD_RA_DDS, 0x00C00000 },
442 { AUD_PLL_INT, 0x0000001E },
443 { AUD_PLL_DDS, 0x00000000 },
444 { AUD_PLL_FRAC, 0x0000E542 },
445 { AUD_START_TIMER, 0x00000000 },
446 { AUD_DEEMPHNUMER1_R, 0x000353DE },
447 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
448 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
449 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
450 { AUD_QAM_MODE, 0x05 },
451 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
452 { AUD_PHACC_FREQ_8MSB, 0x34 },
453 { AUD_PHACC_FREQ_8LSB, 0x4C },
454 { AUD_DEEMPHGAIN_R, 0x00006680 },
455 { AUD_RATE_THRES_DMD, 0x000000C0 },
456 { /* end of list */ },
457 } ;
458 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
459
460 if (!stereo) {
461 /* AM mono sound */
462 set_audio_start(core, 0x0004,
463 0x100c /* FIXME again */);
464 set_audio_registers(core, nicam_l_mono);
465 } else {
466 set_audio_start(core, 0x0010,
467 0x1924 /* FIXME again */);
468 set_audio_registers(core, nicam_l);
469 }
470 set_audio_finish(core);
471
472}
473
474static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
475{
476 static const struct rlist pal_i_fm_mono[] = {
477 {AUD_ERRLOGPERIOD_R, 0x00000064},
478 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
479 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
480 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
481 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
482 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
483 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
484 {AUD_QAM_MODE, 0x05},
485 {AUD_PHACC_FREQ_8MSB, 0x3a},
486 {AUD_PHACC_FREQ_8LSB, 0x93},
487 {AUD_DMD_RA_DDS, 0x002a4f2f},
488 {AUD_PLL_INT, 0x0000001e},
489 {AUD_PLL_DDS, 0x00000004},
490 {AUD_PLL_FRAC, 0x0000e542},
491 {AUD_RATE_ADJ1, 0x00000100},
492 {AUD_RATE_ADJ2, 0x00000200},
493 {AUD_RATE_ADJ3, 0x00000300},
494 {AUD_RATE_ADJ4, 0x00000400},
495 {AUD_RATE_ADJ5, 0x00000500},
496 {AUD_THR_FR, 0x00000000},
497 {AUD_PILOT_BQD_1_K0, 0x0000755b},
498 {AUD_PILOT_BQD_1_K1, 0x00551340},
499 {AUD_PILOT_BQD_1_K2, 0x006d30be},
500 {AUD_PILOT_BQD_1_K3, 0xffd394af},
501 {AUD_PILOT_BQD_1_K4, 0x00400000},
502 {AUD_PILOT_BQD_2_K0, 0x00040000},
503 {AUD_PILOT_BQD_2_K1, 0x002a4841},
504 {AUD_PILOT_BQD_2_K2, 0x00400000},
505 {AUD_PILOT_BQD_2_K3, 0x00000000},
506 {AUD_PILOT_BQD_2_K4, 0x00000000},
507 {AUD_MODE_CHG_TIMER, 0x00000060},
508 {AUD_AFE_12DB_EN, 0x00000001},
509 {AAGC_HYST, 0x0000000a},
510 {AUD_CORDIC_SHIFT_0, 0x00000007},
511 {AUD_CORDIC_SHIFT_1, 0x00000007},
512 {AUD_C1_UP_THR, 0x00007000},
513 {AUD_C1_LO_THR, 0x00005400},
514 {AUD_C2_UP_THR, 0x00005400},
515 {AUD_C2_LO_THR, 0x00003000},
516 {AUD_DCOC_0_SRC, 0x0000001a},
517 {AUD_DCOC0_SHIFT, 0x00000000},
518 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
519 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
520 {AUD_DCOC_PASS_IN, 0x00000003},
521 {AUD_IIR3_0_SEL, 0x00000021},
522 {AUD_DN2_AFC, 0x00000002},
523 {AUD_DCOC_1_SRC, 0x0000001b},
524 {AUD_DCOC1_SHIFT, 0x00000000},
525 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
526 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
527 {AUD_IIR3_1_SEL, 0x00000023},
528 {AUD_DN0_FREQ, 0x000035a3},
529 {AUD_DN2_FREQ, 0x000029c7},
530 {AUD_CRDC0_SRC_SEL, 0x00000511},
531 {AUD_IIR1_0_SEL, 0x00000001},
532 {AUD_IIR1_1_SEL, 0x00000000},
533 {AUD_IIR3_2_SEL, 0x00000003},
534 {AUD_IIR3_2_SHIFT, 0x00000000},
535 {AUD_IIR3_0_SEL, 0x00000002},
536 {AUD_IIR2_0_SEL, 0x00000021},
537 {AUD_IIR2_0_SHIFT, 0x00000002},
538 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
539 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
540 {AUD_POLYPH80SCALEFAC, 0x00000001},
541 {AUD_START_TIMER, 0x00000000},
542 { /* end of list */ },
543 };
544
545 static const struct rlist pal_i_nicam[] = {
546 { AUD_RATE_ADJ1, 0x00000010 },
547 { AUD_RATE_ADJ2, 0x00000040 },
548 { AUD_RATE_ADJ3, 0x00000100 },
549 { AUD_RATE_ADJ4, 0x00000400 },
550 { AUD_RATE_ADJ5, 0x00001000 },
551 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
552 { AUD_DEEMPHGAIN_R, 0x000023c2 },
553 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
554 { AUD_DEEMPHNUMER2_R, 0x0003023e },
555 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
556 { AUD_DEEMPHDENOM2_R, 0x00000000 },
557 { AUD_DEEMPHDENOM2_R, 0x00000000 },
558 { AUD_ERRLOGPERIOD_R, 0x00000fff },
559 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
560 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
561 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
562 { AUD_POLYPH80SCALEFAC, 0x00000003 },
563 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
564 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
565 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
566 { AUD_QAM_MODE, 0x05 },
567 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
568 { AUD_PHACC_FREQ_8MSB, 0x3a },
569 { AUD_PHACC_FREQ_8LSB, 0x93 },
570 { /* end of list */ },
571 };
572
573 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
574
575 if (!stereo) {
576 // FM mono
577 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
578 set_audio_registers(core, pal_i_fm_mono);
579 } else {
580 // Nicam Stereo
581 set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
582 set_audio_registers(core, pal_i_nicam);
583 }
584 set_audio_finish(core);
585}
586
587static void set_audio_standard_A2(struct cx88_core *core)
588{
589 /* from dscaler cvs */
590 static const struct rlist a2_common[] = {
591 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
592 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
593 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
594 { AUD_QAM_MODE, 0x05 },
595 { AUD_PHACC_FREQ_8MSB, 0x34 },
596 { AUD_PHACC_FREQ_8LSB, 0x4c },
597
598 { AUD_RATE_ADJ1, 0x00001000 },
599 { AUD_RATE_ADJ2, 0x00002000 },
600 { AUD_RATE_ADJ3, 0x00003000 },
601 { AUD_RATE_ADJ4, 0x00004000 },
602 { AUD_RATE_ADJ5, 0x00005000 },
603 { AUD_THR_FR, 0x00000000 },
604 { AAGC_HYST, 0x0000001a },
605 { AUD_PILOT_BQD_1_K0, 0x0000755b },
606 { AUD_PILOT_BQD_1_K1, 0x00551340 },
607 { AUD_PILOT_BQD_1_K2, 0x006d30be },
608 { AUD_PILOT_BQD_1_K3, 0xffd394af },
609 { AUD_PILOT_BQD_1_K4, 0x00400000 },
610 { AUD_PILOT_BQD_2_K0, 0x00040000 },
611 { AUD_PILOT_BQD_2_K1, 0x002a4841 },
612 { AUD_PILOT_BQD_2_K2, 0x00400000 },
613 { AUD_PILOT_BQD_2_K3, 0x00000000 },
614 { AUD_PILOT_BQD_2_K4, 0x00000000 },
615 { AUD_MODE_CHG_TIMER, 0x00000040 },
616 { AUD_START_TIMER, 0x00000200 },
617 { AUD_AFE_12DB_EN, 0x00000000 },
618 { AUD_CORDIC_SHIFT_0, 0x00000007 },
619 { AUD_CORDIC_SHIFT_1, 0x00000007 },
620 { AUD_DEEMPH0_G0, 0x00000380 },
621 { AUD_DEEMPH1_G0, 0x00000380 },
622 { AUD_DCOC_0_SRC, 0x0000001a },
623 { AUD_DCOC0_SHIFT, 0x00000000 },
624 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
625 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
626 { AUD_DCOC_PASS_IN, 0x00000003 },
627 { AUD_IIR3_0_SEL, 0x00000021 },
628 { AUD_DN2_AFC, 0x00000002 },
629 { AUD_DCOC_1_SRC, 0x0000001b },
630 { AUD_DCOC1_SHIFT, 0x00000000 },
631 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
632 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
633 { AUD_IIR3_1_SEL, 0x00000023 },
634 { AUD_RDSI_SEL, 0x00000017 },
635 { AUD_RDSI_SHIFT, 0x00000000 },
636 { AUD_RDSQ_SEL, 0x00000017 },
637 { AUD_RDSQ_SHIFT, 0x00000000 },
638 { AUD_POLYPH80SCALEFAC, 0x00000001 },
639
640 { /* end of list */ },
641 };
642
643 static const struct rlist a2_table1[] = {
644 // PAL-BG
645 { AUD_DMD_RA_DDS, 0x002a73bd },
646 { AUD_C1_UP_THR, 0x00007000 },
647 { AUD_C1_LO_THR, 0x00005400 },
648 { AUD_C2_UP_THR, 0x00005400 },
649 { AUD_C2_LO_THR, 0x00003000 },
650 { /* end of list */ },
651 };
652 static const struct rlist a2_table2[] = {
653 // PAL-DK
654 { AUD_DMD_RA_DDS, 0x002a73bd },
655 { AUD_C1_UP_THR, 0x00007000 },
656 { AUD_C1_LO_THR, 0x00005400 },
657 { AUD_C2_UP_THR, 0x00005400 },
658 { AUD_C2_LO_THR, 0x00003000 },
659 { AUD_DN0_FREQ, 0x00003a1c },
660 { AUD_DN2_FREQ, 0x0000d2e0 },
661 { /* end of list */ },
662 };
663 static const struct rlist a2_table3[] = {
664 // unknown, probably NTSC-M
665 { AUD_DMD_RA_DDS, 0x002a2873 },
666 { AUD_C1_UP_THR, 0x00003c00 },
667 { AUD_C1_LO_THR, 0x00003000 },
668 { AUD_C2_UP_THR, 0x00006000 },
669 { AUD_C2_LO_THR, 0x00003c00 },
670 { AUD_DN0_FREQ, 0x00002836 },
671 { AUD_DN1_FREQ, 0x00003418 },
672 { AUD_DN2_FREQ, 0x000029c7 },
673 { AUD_POLY0_DDS_CONSTANT, 0x000a7540 },
674 { /* end of list */ },
675 };
676
677 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
678 set_audio_registers(core, a2_common);
679 switch (core->tvaudio) {
680 case WW_A2_BG:
681 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
682 set_audio_registers(core, a2_table1);
683 break;
684 case WW_A2_DK:
685 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
686 set_audio_registers(core, a2_table2);
687 break;
688 case WW_A2_M:
689 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
690 set_audio_registers(core, a2_table3);
691 break;
692 };
693 set_audio_finish(core);
694}
695
696static void set_audio_standard_EIAJ(struct cx88_core *core)
697{
698 static const struct rlist eiaj[] = {
699 /* TODO: eiaj register settings are not there yet ... */
700
701 { /* end of list */ },
702 };
703 dprintk("%s (status: unknown)\n",__FUNCTION__);
704
705 set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO);
706 set_audio_registers(core, eiaj);
707 set_audio_finish(core);
708}
709
710static void set_audio_standard_FM(struct cx88_core *core)
711{
712#if 0 /* FIXME */
713 switch (dev->audio_properties.FM_deemphasis)
714 {
715 case WW_FM_DEEMPH_50:
716 //Set De-emphasis filter coefficients for 50 usec
717 cx_write(AUD_DEEMPH0_G0, 0x0C45);
718 cx_write(AUD_DEEMPH0_A0, 0x6262);
719 cx_write(AUD_DEEMPH0_B0, 0x1C29);
720 cx_write(AUD_DEEMPH0_A1, 0x3FC66);
721 cx_write(AUD_DEEMPH0_B1, 0x399A);
722
723 cx_write(AUD_DEEMPH1_G0, 0x0D80);
724 cx_write(AUD_DEEMPH1_A0, 0x6262);
725 cx_write(AUD_DEEMPH1_B0, 0x1C29);
726 cx_write(AUD_DEEMPH1_A1, 0x3FC66);
727 cx_write(AUD_DEEMPH1_B1, 0x399A);
728
729 break;
730
731 case WW_FM_DEEMPH_75:
732 //Set De-emphasis filter coefficients for 75 usec
733 cx_write(AUD_DEEMPH0_G0, 0x91B );
734 cx_write(AUD_DEEMPH0_A0, 0x6B68);
735 cx_write(AUD_DEEMPH0_B0, 0x11EC);
736 cx_write(AUD_DEEMPH0_A1, 0x3FC66);
737 cx_write(AUD_DEEMPH0_B1, 0x399A);
738
739 cx_write(AUD_DEEMPH1_G0, 0xAA0 );
740 cx_write(AUD_DEEMPH1_A0, 0x6B68);
741 cx_write(AUD_DEEMPH1_B0, 0x11EC);
742 cx_write(AUD_DEEMPH1_A1, 0x3FC66);
743 cx_write(AUD_DEEMPH1_B1, 0x399A);
744
745 break;
746 }
747#endif
748
749 dprintk("%s (status: unknown)\n",__FUNCTION__);
750 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
751
752 // AB: 10/2/01: this register is not being reset appropriately on occasion.
753 cx_write(AUD_POLYPH80SCALEFAC,3);
754
755 set_audio_finish(core);
756}
757
758/* ----------------------------------------------------------- */
759
760void cx88_set_tvaudio(struct cx88_core *core)
761{
762 switch (core->tvaudio) {
763 case WW_BTSC:
764 set_audio_standard_BTSC(core,0);
765 break;
766 case WW_NICAM_BGDKL:
767 set_audio_standard_NICAM_L(core,0);
768 break;
769 case WW_NICAM_I:
770 set_audio_standard_PAL_I(core,0);
771 break;
772 case WW_A2_BG:
773 case WW_A2_DK:
774 case WW_A2_M:
775 set_audio_standard_A2(core);
776 break;
777 case WW_EIAJ:
778 set_audio_standard_EIAJ(core);
779 break;
780 case WW_FM:
781 set_audio_standard_FM(core);
782 break;
783 case WW_SYSTEM_L_AM:
784 set_audio_standard_NICAM_L(core, 1);
785 break;
786 case WW_NONE:
787 default:
788 printk("%s/0: unknown tv audio mode [%d]\n",
789 core->name, core->tvaudio);
790 break;
791 }
792 return;
793}
794
795void cx88_newstation(struct cx88_core *core)
796{
797 core->audiomode_manual = UNSET;
798
799 switch (core->tvaudio) {
800 case WW_SYSTEM_L_AM:
801 /* try nicam ... */
802 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
803 set_audio_standard_NICAM_L(core, 1);
804 break;
805 }
806}
807
808void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
809{
810 static char *m[] = {"stereo", "dual mono", "mono", "sap"};
811 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"};
812 u32 reg,mode,pilot;
813
814 reg = cx_read(AUD_STATUS);
815 mode = reg & 0x03;
816 pilot = (reg >> 2) & 0x03;
817
818 if (core->astat != reg)
819 dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
820 reg, m[mode], p[pilot],
821 aud_ctl_names[cx_read(AUD_CTL) & 63]);
822 core->astat = reg;
823
824 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
825 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
826 t->rxsubchans = V4L2_TUNER_SUB_MONO;
827 t->audmode = V4L2_TUNER_MODE_MONO;
828
829 switch (core->tvaudio) {
830 case WW_BTSC:
831 t->capability = V4L2_TUNER_CAP_STEREO |
832 V4L2_TUNER_CAP_SAP;
833 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
834 if (1 == pilot) {
835 /* SAP */
836 t->rxsubchans |= V4L2_TUNER_SUB_SAP;
837 }
838 break;
839 case WW_A2_BG:
840 case WW_A2_DK:
841 case WW_A2_M:
842 if (1 == pilot) {
843 /* stereo */
844 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
845 if (0 == mode)
846 t->audmode = V4L2_TUNER_MODE_STEREO;
847 }
848 if (2 == pilot) {
849 /* dual language -- FIXME */
850 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
851 t->audmode = V4L2_TUNER_MODE_LANG1;
852 }
853 break;
854 case WW_NICAM_BGDKL:
855 if (0 == mode) {
856 t->audmode = V4L2_TUNER_MODE_STEREO;
857 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
858 }
859 break;
860 case WW_SYSTEM_L_AM:
861 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
862 t->audmode = V4L2_TUNER_MODE_STEREO;
863 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
864 }
865 break ;
866 default:
867 /* nothing */
868 break;
869 }
870 return;
871}
872
873void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
874{
875 u32 ctl = UNSET;
876 u32 mask = UNSET;
877
878 if (manual) {
879 core->audiomode_manual = mode;
880 } else {
881 if (UNSET != core->audiomode_manual)
882 return;
883 }
884 core->audiomode_current = mode;
885
886 switch (core->tvaudio) {
887 case WW_BTSC:
888 switch (mode) {
889 case V4L2_TUNER_MODE_MONO:
890 ctl = EN_BTSC_FORCE_MONO;
891 mask = 0x3f;
892 break;
893 case V4L2_TUNER_MODE_SAP:
894 ctl = EN_BTSC_FORCE_SAP;
895 mask = 0x3f;
896 break;
897 case V4L2_TUNER_MODE_STEREO:
898 ctl = EN_BTSC_AUTO_STEREO;
899 mask = 0x3f;
900 break;
901 }
902 break;
903 case WW_A2_BG:
904 case WW_A2_DK:
905 case WW_A2_M:
906 switch (mode) {
907 case V4L2_TUNER_MODE_MONO:
908 case V4L2_TUNER_MODE_LANG1:
909 ctl = EN_A2_FORCE_MONO1;
910 mask = 0x3f;
911 break;
912 case V4L2_TUNER_MODE_LANG2:
913 ctl = EN_A2_AUTO_MONO2;
914 mask = 0x3f;
915 break;
916 case V4L2_TUNER_MODE_STEREO:
917 ctl = EN_A2_AUTO_STEREO | EN_DMTRX_SUMR;
918 mask = 0x8bf;
919 break;
920 }
921 break;
922 case WW_NICAM_BGDKL:
923 switch (mode) {
924 case V4L2_TUNER_MODE_MONO:
925 ctl = EN_NICAM_FORCE_MONO1;
926 mask = 0x3f;
927 break;
928 case V4L2_TUNER_MODE_LANG1:
929 ctl = EN_NICAM_AUTO_MONO2;
930 mask = 0x3f;
931 break;
932 case V4L2_TUNER_MODE_STEREO:
933 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR;
934 mask = 0x93f;
935 break;
936 }
937 break;
938 case WW_SYSTEM_L_AM:
939 switch (mode) {
940 case V4L2_TUNER_MODE_MONO:
941 case V4L2_TUNER_MODE_LANG1: /* FIXME */
942 set_audio_standard_NICAM_L(core, 0);
943 break;
944 case V4L2_TUNER_MODE_STEREO:
945 set_audio_standard_NICAM_L(core, 1);
946 break;
947 }
948 break;
949 case WW_NICAM_I:
950 switch (mode) {
951 case V4L2_TUNER_MODE_MONO:
952 case V4L2_TUNER_MODE_LANG1:
953 set_audio_standard_PAL_I(core, 0);
954 break;
955 case V4L2_TUNER_MODE_STEREO:
956 set_audio_standard_PAL_I(core, 1);
957 break;
958 }
959 break;
960 case WW_FM:
961 switch (mode) {
962 case V4L2_TUNER_MODE_MONO:
963 ctl = EN_FMRADIO_FORCE_MONO;
964 mask = 0x3f;
965 break;
966 case V4L2_TUNER_MODE_STEREO:
967 ctl = EN_FMRADIO_AUTO_STEREO;
968 mask = 0x3f;
969 break;
970 }
971 break;
972 }
973
974 if (UNSET != ctl) {
975 dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x "
976 "[status=0x%x,ctl=0x%x,vol=0x%x]\n",
977 mask, ctl, cx_read(AUD_STATUS),
978 cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL));
979 cx_andor(AUD_CTL, mask, ctl);
980 }
981 return;
982}
983
984int cx88_audio_thread(void *data)
985{
986 struct cx88_core *core = data;
987 struct v4l2_tuner t;
988 u32 mode = 0;
989
990 dprintk("cx88: tvaudio thread started\n");
991 for (;;) {
992 msleep_interruptible(1000);
993 if (kthread_should_stop())
994 break;
995
996 /* just monitor the audio status for now ... */
997 memset(&t,0,sizeof(t));
998 cx88_get_stereo(core,&t);
999
1000 if (UNSET != core->audiomode_manual)
1001 /* manually set, don't do anything. */
1002 continue;
1003
1004 /* monitor signal */
1005 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
1006 mode = V4L2_TUNER_MODE_STEREO;
1007 else
1008 mode = V4L2_TUNER_MODE_MONO;
1009 if (mode == core->audiomode_current)
1010 continue;
1011
1012 /* automatically switch to best available mode */
1013 cx88_set_stereo(core, mode, 0);
1014 }
1015
1016 dprintk("cx88: tvaudio thread exiting\n");
1017 return 0;
1018}
1019
1020/* ----------------------------------------------------------- */
1021
1022EXPORT_SYMBOL(cx88_set_tvaudio);
1023EXPORT_SYMBOL(cx88_newstation);
1024EXPORT_SYMBOL(cx88_set_stereo);
1025EXPORT_SYMBOL(cx88_get_stereo);
1026EXPORT_SYMBOL(cx88_audio_thread);
1027
1028/*
1029 * Local variables:
1030 * c-basic-offset: 8
1031 * End:
1032 */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
new file mode 100644
index 000000000000..471e508b0746
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -0,0 +1,248 @@
1/*
2 * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
3 */
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/moduleparam.h>
7#include <linux/init.h>
8#include <linux/slab.h>
9
10#include "cx88.h"
11
12static unsigned int vbibufs = 4;
13module_param(vbibufs,int,0644);
14MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
15
16static unsigned int vbi_debug = 0;
17module_param(vbi_debug,int,0644);
18MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
19
20#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \
21 printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
22
23/* ------------------------------------------------------------------ */
24
25void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
26{
27 memset(&f->fmt.vbi,0,sizeof(f->fmt.vbi));
28
29 f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
30 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
31 f->fmt.vbi.offset = 244;
32 f->fmt.vbi.count[0] = VBI_LINE_COUNT;
33 f->fmt.vbi.count[1] = VBI_LINE_COUNT;
34
35 if (dev->core->tvnorm->id & V4L2_STD_525_60) {
36 /* ntsc */
37 f->fmt.vbi.sampling_rate = 28636363;
38 f->fmt.vbi.start[0] = 10 -1;
39 f->fmt.vbi.start[1] = 273 -1;
40
41 } else if (dev->core->tvnorm->id & V4L2_STD_625_50) {
42 /* pal */
43 f->fmt.vbi.sampling_rate = 35468950;
44 f->fmt.vbi.start[0] = 7 -1;
45 f->fmt.vbi.start[1] = 319 -1;
46 }
47}
48
49int cx8800_start_vbi_dma(struct cx8800_dev *dev,
50 struct cx88_dmaqueue *q,
51 struct cx88_buffer *buf)
52{
53 struct cx88_core *core = dev->core;
54
55 /* setup fifo + format */
56 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24],
57 buf->vb.width, buf->risc.dma);
58
59 cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup
60 (1 << 15) | // enable vbi capture
61 (1 << 11) ));
62
63 /* reset counter */
64 cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET);
65 q->count = 1;
66
67 /* enable irqs */
68 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
69 cx_set(MO_VID_INTMSK, 0x0f0088);
70
71 /* enable capture */
72 cx_set(VID_CAPTURE_CONTROL,0x18);
73
74 /* start dma */
75 cx_set(MO_DEV_CNTRL2, (1<<5));
76 cx_set(MO_VID_DMACNTRL, 0x88);
77
78 return 0;
79}
80
81int cx8800_stop_vbi_dma(struct cx8800_dev *dev)
82{
83 struct cx88_core *core = dev->core;
84
85 /* stop dma */
86 cx_clear(MO_VID_DMACNTRL, 0x88);
87
88 /* disable capture */
89 cx_clear(VID_CAPTURE_CONTROL,0x18);
90
91 /* disable irqs */
92 cx_clear(MO_PCI_INTMSK, 0x000001);
93 cx_clear(MO_VID_INTMSK, 0x0f0088);
94 return 0;
95}
96
97int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
98 struct cx88_dmaqueue *q)
99{
100 struct cx88_buffer *buf;
101 struct list_head *item;
102
103 if (list_empty(&q->active))
104 return 0;
105
106 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
107 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
108 buf, buf->vb.i);
109 cx8800_start_vbi_dma(dev, q, buf);
110 list_for_each(item,&q->active) {
111 buf = list_entry(item, struct cx88_buffer, vb.queue);
112 buf->count = q->count++;
113 }
114 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
115 return 0;
116}
117
118void cx8800_vbi_timeout(unsigned long data)
119{
120 struct cx8800_dev *dev = (struct cx8800_dev*)data;
121 struct cx88_core *core = dev->core;
122 struct cx88_dmaqueue *q = &dev->vbiq;
123 struct cx88_buffer *buf;
124 unsigned long flags;
125
126 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH24]);
127
128 cx_clear(MO_VID_DMACNTRL, 0x88);
129 cx_clear(VID_CAPTURE_CONTROL, 0x18);
130
131 spin_lock_irqsave(&dev->slock,flags);
132 while (!list_empty(&q->active)) {
133 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
134 list_del(&buf->vb.queue);
135 buf->vb.state = STATE_ERROR;
136 wake_up(&buf->vb.done);
137 printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name,
138 buf, buf->vb.i, (unsigned long)buf->risc.dma);
139 }
140 cx8800_restart_vbi_queue(dev,q);
141 spin_unlock_irqrestore(&dev->slock,flags);
142}
143
144/* ------------------------------------------------------------------ */
145
146static int
147vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
148{
149 *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
150 if (0 == *count)
151 *count = vbibufs;
152 if (*count < 2)
153 *count = 2;
154 if (*count > 32)
155 *count = 32;
156 return 0;
157}
158
159static int
160vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
161 enum v4l2_field field)
162{
163 struct cx8800_fh *fh = q->priv_data;
164 struct cx8800_dev *dev = fh->dev;
165 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
166 unsigned int size;
167 int rc;
168
169 size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
170 if (0 != buf->vb.baddr && buf->vb.bsize < size)
171 return -EINVAL;
172
173 if (STATE_NEEDS_INIT == buf->vb.state) {
174 buf->vb.width = VBI_LINE_LENGTH;
175 buf->vb.height = VBI_LINE_COUNT;
176 buf->vb.size = size;
177 buf->vb.field = V4L2_FIELD_SEQ_TB;
178
179 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
180 goto fail;
181 cx88_risc_buffer(dev->pci, &buf->risc,
182 buf->vb.dma.sglist,
183 0, buf->vb.width * buf->vb.height,
184 buf->vb.width, 0,
185 buf->vb.height);
186 }
187 buf->vb.state = STATE_PREPARED;
188 return 0;
189
190 fail:
191 cx88_free_buffer(dev->pci,buf);
192 return rc;
193}
194
195static void
196vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
197{
198 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
199 struct cx88_buffer *prev;
200 struct cx8800_fh *fh = vq->priv_data;
201 struct cx8800_dev *dev = fh->dev;
202 struct cx88_dmaqueue *q = &dev->vbiq;
203
204 /* add jump to stopper */
205 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
206 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
207
208 if (list_empty(&q->active)) {
209 list_add_tail(&buf->vb.queue,&q->active);
210 cx8800_start_vbi_dma(dev, q, buf);
211 buf->vb.state = STATE_ACTIVE;
212 buf->count = q->count++;
213 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
214 dprintk(2,"[%p/%d] vbi_queue - first active\n",
215 buf, buf->vb.i);
216
217 } else {
218 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
219 list_add_tail(&buf->vb.queue,&q->active);
220 buf->vb.state = STATE_ACTIVE;
221 buf->count = q->count++;
222 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
223 dprintk(2,"[%p/%d] buffer_queue - append to active\n",
224 buf, buf->vb.i);
225 }
226}
227
228static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
229{
230 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
231 struct cx8800_fh *fh = q->priv_data;
232
233 cx88_free_buffer(fh->dev->pci,buf);
234}
235
236struct videobuf_queue_ops cx8800_vbi_qops = {
237 .buf_setup = vbi_setup,
238 .buf_prepare = vbi_prepare,
239 .buf_queue = vbi_queue,
240 .buf_release = vbi_release,
241};
242
243/* ------------------------------------------------------------------ */
244/*
245 * Local variables:
246 * c-basic-offset: 8
247 * End:
248 */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
new file mode 100644
index 000000000000..701f594e1816
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -0,0 +1,2277 @@
1/*
2 * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface
6 *
7 * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kmod.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/interrupt.h>
32#include <linux/delay.h>
33#include <linux/kthread.h>
34#include <asm/div64.h>
35
36#include "cx88.h"
37
38MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL");
41
42/* ------------------------------------------------------------------ */
43
44static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
45static unsigned int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
46static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
47
48module_param_array(video_nr, int, NULL, 0444);
49module_param_array(vbi_nr, int, NULL, 0444);
50module_param_array(radio_nr, int, NULL, 0444);
51
52MODULE_PARM_DESC(video_nr,"video device numbers");
53MODULE_PARM_DESC(vbi_nr,"vbi device numbers");
54MODULE_PARM_DESC(radio_nr,"radio device numbers");
55
56static unsigned int video_debug = 0;
57module_param(video_debug,int,0644);
58MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
59
60static unsigned int irq_debug = 0;
61module_param(irq_debug,int,0644);
62MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
63
64static unsigned int vid_limit = 16;
65module_param(vid_limit,int,0644);
66MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
67
68#define dprintk(level,fmt, arg...) if (video_debug >= level) \
69 printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg)
70
71/* ------------------------------------------------------------------ */
72
73static LIST_HEAD(cx8800_devlist);
74
75/* ------------------------------------------------------------------- */
76/* static data */
77
78static struct cx88_tvnorm tvnorms[] = {
79 {
80 .name = "NTSC-M",
81 .id = V4L2_STD_NTSC_M,
82 .cxiformat = VideoFormatNTSC,
83 .cxoformat = 0x181f0008,
84 },{
85 .name = "NTSC-JP",
86 .id = V4L2_STD_NTSC_M_JP,
87 .cxiformat = VideoFormatNTSCJapan,
88 .cxoformat = 0x181f0008,
89#if 0
90 },{
91 .name = "NTSC-4.43",
92 .id = FIXME,
93 .cxiformat = VideoFormatNTSC443,
94 .cxoformat = 0x181f0008,
95#endif
96 },{
97 .name = "PAL-BG",
98 .id = V4L2_STD_PAL_BG,
99 .cxiformat = VideoFormatPAL,
100 .cxoformat = 0x181f0008,
101 },{
102 .name = "PAL-DK",
103 .id = V4L2_STD_PAL_DK,
104 .cxiformat = VideoFormatPAL,
105 .cxoformat = 0x181f0008,
106 },{
107 .name = "PAL-I",
108 .id = V4L2_STD_PAL_I,
109 .cxiformat = VideoFormatPAL,
110 .cxoformat = 0x181f0008,
111 },{
112 .name = "PAL-M",
113 .id = V4L2_STD_PAL_M,
114 .cxiformat = VideoFormatPALM,
115 .cxoformat = 0x1c1f0008,
116 },{
117 .name = "PAL-N",
118 .id = V4L2_STD_PAL_N,
119 .cxiformat = VideoFormatPALN,
120 .cxoformat = 0x1c1f0008,
121 },{
122 .name = "PAL-Nc",
123 .id = V4L2_STD_PAL_Nc,
124 .cxiformat = VideoFormatPALNC,
125 .cxoformat = 0x1c1f0008,
126 },{
127 .name = "PAL-60",
128 .id = V4L2_STD_PAL_60,
129 .cxiformat = VideoFormatPAL60,
130 .cxoformat = 0x181f0008,
131 },{
132 .name = "SECAM-L",
133 .id = V4L2_STD_SECAM_L,
134 .cxiformat = VideoFormatSECAM,
135 .cxoformat = 0x181f0008,
136 },{
137 .name = "SECAM-DK",
138 .id = V4L2_STD_SECAM_DK,
139 .cxiformat = VideoFormatSECAM,
140 .cxoformat = 0x181f0008,
141 }
142};
143
144static struct cx8800_fmt formats[] = {
145 {
146 .name = "8 bpp, gray",
147 .fourcc = V4L2_PIX_FMT_GREY,
148 .cxformat = ColorFormatY8,
149 .depth = 8,
150 .flags = FORMAT_FLAGS_PACKED,
151 },{
152 .name = "15 bpp RGB, le",
153 .fourcc = V4L2_PIX_FMT_RGB555,
154 .cxformat = ColorFormatRGB15,
155 .depth = 16,
156 .flags = FORMAT_FLAGS_PACKED,
157 },{
158 .name = "15 bpp RGB, be",
159 .fourcc = V4L2_PIX_FMT_RGB555X,
160 .cxformat = ColorFormatRGB15 | ColorFormatBSWAP,
161 .depth = 16,
162 .flags = FORMAT_FLAGS_PACKED,
163 },{
164 .name = "16 bpp RGB, le",
165 .fourcc = V4L2_PIX_FMT_RGB565,
166 .cxformat = ColorFormatRGB16,
167 .depth = 16,
168 .flags = FORMAT_FLAGS_PACKED,
169 },{
170 .name = "16 bpp RGB, be",
171 .fourcc = V4L2_PIX_FMT_RGB565X,
172 .cxformat = ColorFormatRGB16 | ColorFormatBSWAP,
173 .depth = 16,
174 .flags = FORMAT_FLAGS_PACKED,
175 },{
176 .name = "24 bpp RGB, le",
177 .fourcc = V4L2_PIX_FMT_BGR24,
178 .cxformat = ColorFormatRGB24,
179 .depth = 24,
180 .flags = FORMAT_FLAGS_PACKED,
181 },{
182 .name = "32 bpp RGB, le",
183 .fourcc = V4L2_PIX_FMT_BGR32,
184 .cxformat = ColorFormatRGB32,
185 .depth = 32,
186 .flags = FORMAT_FLAGS_PACKED,
187 },{
188 .name = "32 bpp RGB, be",
189 .fourcc = V4L2_PIX_FMT_RGB32,
190 .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | ColorFormatWSWAP,
191 .depth = 32,
192 .flags = FORMAT_FLAGS_PACKED,
193 },{
194 .name = "4:2:2, packed, YUYV",
195 .fourcc = V4L2_PIX_FMT_YUYV,
196 .cxformat = ColorFormatYUY2,
197 .depth = 16,
198 .flags = FORMAT_FLAGS_PACKED,
199 },{
200 .name = "4:2:2, packed, UYVY",
201 .fourcc = V4L2_PIX_FMT_UYVY,
202 .cxformat = ColorFormatYUY2 | ColorFormatBSWAP,
203 .depth = 16,
204 .flags = FORMAT_FLAGS_PACKED,
205 },
206};
207
208static struct cx8800_fmt* format_by_fourcc(unsigned int fourcc)
209{
210 unsigned int i;
211
212 for (i = 0; i < ARRAY_SIZE(formats); i++)
213 if (formats[i].fourcc == fourcc)
214 return formats+i;
215 return NULL;
216}
217
218/* ------------------------------------------------------------------- */
219
220static const struct v4l2_queryctrl no_ctl = {
221 .name = "42",
222 .flags = V4L2_CTRL_FLAG_DISABLED,
223};
224
225static struct cx88_ctrl cx8800_ctls[] = {
226 /* --- video --- */
227 {
228 .v = {
229 .id = V4L2_CID_BRIGHTNESS,
230 .name = "Brightness",
231 .minimum = 0x00,
232 .maximum = 0xff,
233 .step = 1,
234 .default_value = 0,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 },
237 .off = 128,
238 .reg = MO_CONTR_BRIGHT,
239 .mask = 0x00ff,
240 .shift = 0,
241 },{
242 .v = {
243 .id = V4L2_CID_CONTRAST,
244 .name = "Contrast",
245 .minimum = 0,
246 .maximum = 0xff,
247 .step = 1,
248 .default_value = 0,
249 .type = V4L2_CTRL_TYPE_INTEGER,
250 },
251 .reg = MO_CONTR_BRIGHT,
252 .mask = 0xff00,
253 .shift = 8,
254 },{
255 .v = {
256 .id = V4L2_CID_HUE,
257 .name = "Hue",
258 .minimum = 0,
259 .maximum = 0xff,
260 .step = 1,
261 .default_value = 0,
262 .type = V4L2_CTRL_TYPE_INTEGER,
263 },
264 .off = 0,
265 .reg = MO_HUE,
266 .mask = 0x00ff,
267 .shift = 0,
268 },{
269 /* strictly, this only describes only U saturation.
270 * V saturation is handled specially through code.
271 */
272 .v = {
273 .id = V4L2_CID_SATURATION,
274 .name = "Saturation",
275 .minimum = 0,
276 .maximum = 0xff,
277 .step = 1,
278 .default_value = 0,
279 .type = V4L2_CTRL_TYPE_INTEGER,
280 },
281 .off = 0,
282 .reg = MO_UV_SATURATION,
283 .mask = 0x00ff,
284 .shift = 0,
285 },{
286 /* --- audio --- */
287 .v = {
288 .id = V4L2_CID_AUDIO_MUTE,
289 .name = "Mute",
290 .minimum = 0,
291 .maximum = 1,
292 .type = V4L2_CTRL_TYPE_BOOLEAN,
293 },
294 .reg = AUD_VOL_CTL,
295 .sreg = SHADOW_AUD_VOL_CTL,
296 .mask = (1 << 6),
297 .shift = 6,
298 },{
299 .v = {
300 .id = V4L2_CID_AUDIO_VOLUME,
301 .name = "Volume",
302 .minimum = 0,
303 .maximum = 0x3f,
304 .step = 1,
305 .default_value = 0,
306 .type = V4L2_CTRL_TYPE_INTEGER,
307 },
308 .reg = AUD_VOL_CTL,
309 .sreg = SHADOW_AUD_VOL_CTL,
310 .mask = 0x3f,
311 .shift = 0,
312 },{
313 .v = {
314 .id = V4L2_CID_AUDIO_BALANCE,
315 .name = "Balance",
316 .minimum = 0,
317 .maximum = 0x7f,
318 .step = 1,
319 .default_value = 0x40,
320 .type = V4L2_CTRL_TYPE_INTEGER,
321 },
322 .reg = AUD_BAL_CTL,
323 .sreg = SHADOW_AUD_BAL_CTL,
324 .mask = 0x7f,
325 .shift = 0,
326 }
327};
328const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
329
330/* ------------------------------------------------------------------- */
331/* resource management */
332
333static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
334{
335 if (fh->resources & bit)
336 /* have it already allocated */
337 return 1;
338
339 /* is it free? */
340 down(&dev->lock);
341 if (dev->resources & bit) {
342 /* no, someone else uses it */
343 up(&dev->lock);
344 return 0;
345 }
346 /* it's free, grab it */
347 fh->resources |= bit;
348 dev->resources |= bit;
349 dprintk(1,"res: get %d\n",bit);
350 up(&dev->lock);
351 return 1;
352}
353
354static
355int res_check(struct cx8800_fh *fh, unsigned int bit)
356{
357 return (fh->resources & bit);
358}
359
360static
361int res_locked(struct cx8800_dev *dev, unsigned int bit)
362{
363 return (dev->resources & bit);
364}
365
366static
367void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
368{
369 if ((fh->resources & bits) != bits)
370 BUG();
371
372 down(&dev->lock);
373 fh->resources &= ~bits;
374 dev->resources &= ~bits;
375 dprintk(1,"res: put %d\n",bits);
376 up(&dev->lock);
377}
378
379/* ------------------------------------------------------------------ */
380
381static int video_mux(struct cx8800_dev *dev, unsigned int input)
382{
383 struct cx88_core *core = dev->core;
384
385 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
386 input, INPUT(input)->vmux,
387 INPUT(input)->gpio0,INPUT(input)->gpio1,
388 INPUT(input)->gpio2,INPUT(input)->gpio3);
389 dev->core->input = input;
390 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
391 cx_write(MO_GP3_IO, INPUT(input)->gpio3);
392 cx_write(MO_GP0_IO, INPUT(input)->gpio0);
393 cx_write(MO_GP1_IO, INPUT(input)->gpio1);
394 cx_write(MO_GP2_IO, INPUT(input)->gpio2);
395
396 switch (INPUT(input)->type) {
397 case CX88_VMUX_SVIDEO:
398 cx_set(MO_AFECFG_IO, 0x00000001);
399 cx_set(MO_INPUT_FORMAT, 0x00010010);
400 cx_set(MO_FILTER_EVEN, 0x00002020);
401 cx_set(MO_FILTER_ODD, 0x00002020);
402 break;
403 default:
404 cx_clear(MO_AFECFG_IO, 0x00000001);
405 cx_clear(MO_INPUT_FORMAT, 0x00010010);
406 cx_clear(MO_FILTER_EVEN, 0x00002020);
407 cx_clear(MO_FILTER_ODD, 0x00002020);
408 break;
409 }
410 return 0;
411}
412
413/* ------------------------------------------------------------------ */
414
415static int start_video_dma(struct cx8800_dev *dev,
416 struct cx88_dmaqueue *q,
417 struct cx88_buffer *buf)
418{
419 struct cx88_core *core = dev->core;
420
421 /* setup fifo + format */
422 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21],
423 buf->bpl, buf->risc.dma);
424 cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field);
425 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
426
427 /* reset counter */
428 cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET);
429 q->count = 1;
430
431 /* enable irqs */
432 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
433 cx_set(MO_VID_INTMSK, 0x0f0011);
434
435 /* enable capture */
436 cx_set(VID_CAPTURE_CONTROL,0x06);
437
438 /* start dma */
439 cx_set(MO_DEV_CNTRL2, (1<<5));
440 cx_set(MO_VID_DMACNTRL, 0x11);
441
442 return 0;
443}
444
445static int stop_video_dma(struct cx8800_dev *dev)
446{
447 struct cx88_core *core = dev->core;
448
449 /* stop dma */
450 cx_clear(MO_VID_DMACNTRL, 0x11);
451
452 /* disable capture */
453 cx_clear(VID_CAPTURE_CONTROL,0x06);
454
455 /* disable irqs */
456 cx_clear(MO_PCI_INTMSK, 0x000001);
457 cx_clear(MO_VID_INTMSK, 0x0f0011);
458 return 0;
459}
460
461static int restart_video_queue(struct cx8800_dev *dev,
462 struct cx88_dmaqueue *q)
463{
464 struct cx88_buffer *buf, *prev;
465 struct list_head *item;
466
467 if (!list_empty(&q->active)) {
468 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
469 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
470 buf, buf->vb.i);
471 start_video_dma(dev, q, buf);
472 list_for_each(item,&q->active) {
473 buf = list_entry(item, struct cx88_buffer, vb.queue);
474 buf->count = q->count++;
475 }
476 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
477 return 0;
478 }
479
480 prev = NULL;
481 for (;;) {
482 if (list_empty(&q->queued))
483 return 0;
484 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
485 if (NULL == prev) {
486 list_del(&buf->vb.queue);
487 list_add_tail(&buf->vb.queue,&q->active);
488 start_video_dma(dev, q, buf);
489 buf->vb.state = STATE_ACTIVE;
490 buf->count = q->count++;
491 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
492 dprintk(2,"[%p/%d] restart_queue - first active\n",
493 buf,buf->vb.i);
494
495 } else if (prev->vb.width == buf->vb.width &&
496 prev->vb.height == buf->vb.height &&
497 prev->fmt == buf->fmt) {
498 list_del(&buf->vb.queue);
499 list_add_tail(&buf->vb.queue,&q->active);
500 buf->vb.state = STATE_ACTIVE;
501 buf->count = q->count++;
502 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
503 dprintk(2,"[%p/%d] restart_queue - move to active\n",
504 buf,buf->vb.i);
505 } else {
506 return 0;
507 }
508 prev = buf;
509 }
510}
511
512/* ------------------------------------------------------------------ */
513
514static int
515buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
516{
517 struct cx8800_fh *fh = q->priv_data;
518
519 *size = fh->fmt->depth*fh->width*fh->height >> 3;
520 if (0 == *count)
521 *count = 32;
522 while (*size * *count > vid_limit * 1024 * 1024)
523 (*count)--;
524 return 0;
525}
526
527static int
528buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
529 enum v4l2_field field)
530{
531 struct cx8800_fh *fh = q->priv_data;
532 struct cx8800_dev *dev = fh->dev;
533 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
534 int rc, init_buffer = 0;
535
536 BUG_ON(NULL == fh->fmt);
537 if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) ||
538 fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm))
539 return -EINVAL;
540 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
541 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
542 return -EINVAL;
543
544 if (buf->fmt != fh->fmt ||
545 buf->vb.width != fh->width ||
546 buf->vb.height != fh->height ||
547 buf->vb.field != field) {
548 buf->fmt = fh->fmt;
549 buf->vb.width = fh->width;
550 buf->vb.height = fh->height;
551 buf->vb.field = field;
552 init_buffer = 1;
553 }
554
555 if (STATE_NEEDS_INIT == buf->vb.state) {
556 init_buffer = 1;
557 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
558 goto fail;
559 }
560
561 if (init_buffer) {
562 buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
563 switch (buf->vb.field) {
564 case V4L2_FIELD_TOP:
565 cx88_risc_buffer(dev->pci, &buf->risc,
566 buf->vb.dma.sglist, 0, UNSET,
567 buf->bpl, 0, buf->vb.height);
568 break;
569 case V4L2_FIELD_BOTTOM:
570 cx88_risc_buffer(dev->pci, &buf->risc,
571 buf->vb.dma.sglist, UNSET, 0,
572 buf->bpl, 0, buf->vb.height);
573 break;
574 case V4L2_FIELD_INTERLACED:
575 cx88_risc_buffer(dev->pci, &buf->risc,
576 buf->vb.dma.sglist, 0, buf->bpl,
577 buf->bpl, buf->bpl,
578 buf->vb.height >> 1);
579 break;
580 case V4L2_FIELD_SEQ_TB:
581 cx88_risc_buffer(dev->pci, &buf->risc,
582 buf->vb.dma.sglist,
583 0, buf->bpl * (buf->vb.height >> 1),
584 buf->bpl, 0,
585 buf->vb.height >> 1);
586 break;
587 case V4L2_FIELD_SEQ_BT:
588 cx88_risc_buffer(dev->pci, &buf->risc,
589 buf->vb.dma.sglist,
590 buf->bpl * (buf->vb.height >> 1), 0,
591 buf->bpl, 0,
592 buf->vb.height >> 1);
593 break;
594 default:
595 BUG();
596 }
597 }
598 dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
599 buf, buf->vb.i,
600 fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
601 (unsigned long)buf->risc.dma);
602
603 buf->vb.state = STATE_PREPARED;
604 return 0;
605
606 fail:
607 cx88_free_buffer(dev->pci,buf);
608 return rc;
609}
610
611static void
612buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
613{
614 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
615 struct cx88_buffer *prev;
616 struct cx8800_fh *fh = vq->priv_data;
617 struct cx8800_dev *dev = fh->dev;
618 struct cx88_dmaqueue *q = &dev->vidq;
619
620 /* add jump to stopper */
621 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
622 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
623
624 if (!list_empty(&q->queued)) {
625 list_add_tail(&buf->vb.queue,&q->queued);
626 buf->vb.state = STATE_QUEUED;
627 dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
628 buf, buf->vb.i);
629
630 } else if (list_empty(&q->active)) {
631 list_add_tail(&buf->vb.queue,&q->active);
632 start_video_dma(dev, q, buf);
633 buf->vb.state = STATE_ACTIVE;
634 buf->count = q->count++;
635 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
636 dprintk(2,"[%p/%d] buffer_queue - first active\n",
637 buf, buf->vb.i);
638
639 } else {
640 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
641 if (prev->vb.width == buf->vb.width &&
642 prev->vb.height == buf->vb.height &&
643 prev->fmt == buf->fmt) {
644 list_add_tail(&buf->vb.queue,&q->active);
645 buf->vb.state = STATE_ACTIVE;
646 buf->count = q->count++;
647 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
648 dprintk(2,"[%p/%d] buffer_queue - append to active\n",
649 buf, buf->vb.i);
650
651 } else {
652 list_add_tail(&buf->vb.queue,&q->queued);
653 buf->vb.state = STATE_QUEUED;
654 dprintk(2,"[%p/%d] buffer_queue - first queued\n",
655 buf, buf->vb.i);
656 }
657 }
658}
659
660static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
661{
662 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
663 struct cx8800_fh *fh = q->priv_data;
664
665 cx88_free_buffer(fh->dev->pci,buf);
666}
667
668struct videobuf_queue_ops cx8800_video_qops = {
669 .buf_setup = buffer_setup,
670 .buf_prepare = buffer_prepare,
671 .buf_queue = buffer_queue,
672 .buf_release = buffer_release,
673};
674
675/* ------------------------------------------------------------------ */
676
677#if 0 /* overlay support not finished yet */
678static u32* ov_risc_field(struct cx8800_dev *dev, struct cx8800_fh *fh,
679 u32 *rp, struct btcx_skiplist *skips,
680 u32 sync_line, int skip_even, int skip_odd)
681{
682 int line,maxy,start,end,skip,nskips;
683 u32 ri,ra;
684 u32 addr;
685
686 /* sync instruction */
687 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
688
689 addr = (unsigned long)dev->fbuf.base;
690 addr += dev->fbuf.fmt.bytesperline * fh->win.w.top;
691 addr += (fh->fmt->depth >> 3) * fh->win.w.left;
692
693 /* scan lines */
694 for (maxy = -1, line = 0; line < fh->win.w.height;
695 line++, addr += dev->fbuf.fmt.bytesperline) {
696 if ((line%2) == 0 && skip_even)
697 continue;
698 if ((line%2) == 1 && skip_odd)
699 continue;
700
701 /* calculate clipping */
702 if (line > maxy)
703 btcx_calc_skips(line, fh->win.w.width, &maxy,
704 skips, &nskips, fh->clips, fh->nclips);
705
706 /* write out risc code */
707 for (start = 0, skip = 0; start < fh->win.w.width; start = end) {
708 if (skip >= nskips) {
709 ri = RISC_WRITE;
710 end = fh->win.w.width;
711 } else if (start < skips[skip].start) {
712 ri = RISC_WRITE;
713 end = skips[skip].start;
714 } else {
715 ri = RISC_SKIP;
716 end = skips[skip].end;
717 skip++;
718 }
719 if (RISC_WRITE == ri)
720 ra = addr + (fh->fmt->depth>>3)*start;
721 else
722 ra = 0;
723
724 if (0 == start)
725 ri |= RISC_SOL;
726 if (fh->win.w.width == end)
727 ri |= RISC_EOL;
728 ri |= (fh->fmt->depth>>3) * (end-start);
729
730 *(rp++)=cpu_to_le32(ri);
731 if (0 != ra)
732 *(rp++)=cpu_to_le32(ra);
733 }
734 }
735 kfree(skips);
736 return rp;
737}
738
739static int ov_risc_frame(struct cx8800_dev *dev, struct cx8800_fh *fh,
740 struct cx88_buffer *buf)
741{
742 struct btcx_skiplist *skips;
743 u32 instructions,fields;
744 u32 *rp;
745 int rc;
746
747 /* skip list for window clipping */
748 if (NULL == (skips = kmalloc(sizeof(*skips) * fh->nclips,GFP_KERNEL)))
749 return -ENOMEM;
750
751 fields = 0;
752 if (V4L2_FIELD_HAS_TOP(fh->win.field))
753 fields++;
754 if (V4L2_FIELD_HAS_BOTTOM(fh->win.field))
755 fields++;
756
757 /* estimate risc mem: worst case is (clip+1) * lines instructions
758 + syncs + jump (all 2 dwords) */
759 instructions = (fh->nclips+1) * fh->win.w.height;
760 instructions += 3 + 4;
761 if ((rc = btcx_riscmem_alloc(dev->pci,&buf->risc,instructions*8)) < 0) {
762 kfree(skips);
763 return rc;
764 }
765
766 /* write risc instructions */
767 rp = buf->risc.cpu;
768 switch (fh->win.field) {
769 case V4L2_FIELD_TOP:
770 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 0);
771 break;
772 case V4L2_FIELD_BOTTOM:
773 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 0, 0);
774 break;
775 case V4L2_FIELD_INTERLACED:
776 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 1);
777 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 1, 0);
778 break;
779 default:
780 BUG();
781 }
782
783 /* save pointer to jmp instruction address */
784 buf->risc.jmp = rp;
785 kfree(skips);
786 return 0;
787}
788
789static int verify_window(struct cx8800_dev *dev, struct v4l2_window *win)
790{
791 enum v4l2_field field;
792 int maxw, maxh;
793
794 if (NULL == dev->fbuf.base)
795 return -EINVAL;
796 if (win->w.width < 48 || win->w.height < 32)
797 return -EINVAL;
798 if (win->clipcount > 2048)
799 return -EINVAL;
800
801 field = win->field;
802 maxw = norm_maxw(core->tvnorm);
803 maxh = norm_maxh(core->tvnorm);
804
805 if (V4L2_FIELD_ANY == field) {
806 field = (win->w.height > maxh/2)
807 ? V4L2_FIELD_INTERLACED
808 : V4L2_FIELD_TOP;
809 }
810 switch (field) {
811 case V4L2_FIELD_TOP:
812 case V4L2_FIELD_BOTTOM:
813 maxh = maxh / 2;
814 break;
815 case V4L2_FIELD_INTERLACED:
816 break;
817 default:
818 return -EINVAL;
819 }
820
821 win->field = field;
822 if (win->w.width > maxw)
823 win->w.width = maxw;
824 if (win->w.height > maxh)
825 win->w.height = maxh;
826 return 0;
827}
828
829static int setup_window(struct cx8800_dev *dev, struct cx8800_fh *fh,
830 struct v4l2_window *win)
831{
832 struct v4l2_clip *clips = NULL;
833 int n,size,retval = 0;
834
835 if (NULL == fh->fmt)
836 return -EINVAL;
837 retval = verify_window(dev,win);
838 if (0 != retval)
839 return retval;
840
841 /* copy clips -- luckily v4l1 + v4l2 are binary
842 compatible here ...*/
843 n = win->clipcount;
844 size = sizeof(*clips)*(n+4);
845 clips = kmalloc(size,GFP_KERNEL);
846 if (NULL == clips)
847 return -ENOMEM;
848 if (n > 0) {
849 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
850 kfree(clips);
851 return -EFAULT;
852 }
853 }
854
855 /* clip against screen */
856 if (NULL != dev->fbuf.base)
857 n = btcx_screen_clips(dev->fbuf.fmt.width, dev->fbuf.fmt.height,
858 &win->w, clips, n);
859 btcx_sort_clips(clips,n);
860
861 /* 4-byte alignments */
862 switch (fh->fmt->depth) {
863 case 8:
864 case 24:
865 btcx_align(&win->w, clips, n, 3);
866 break;
867 case 16:
868 btcx_align(&win->w, clips, n, 1);
869 break;
870 case 32:
871 /* no alignment fixups needed */
872 break;
873 default:
874 BUG();
875 }
876
877 down(&fh->vidq.lock);
878 if (fh->clips)
879 kfree(fh->clips);
880 fh->clips = clips;
881 fh->nclips = n;
882 fh->win = *win;
883#if 0
884 fh->ov.setup_ok = 1;
885#endif
886
887 /* update overlay if needed */
888 retval = 0;
889#if 0
890 if (check_btres(fh, RESOURCE_OVERLAY)) {
891 struct bttv_buffer *new;
892
893 new = videobuf_alloc(sizeof(*new));
894 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
895 retval = bttv_switch_overlay(btv,fh,new);
896 }
897#endif
898 up(&fh->vidq.lock);
899 return retval;
900}
901#endif
902
903/* ------------------------------------------------------------------ */
904
905static struct videobuf_queue* get_queue(struct cx8800_fh *fh)
906{
907 switch (fh->type) {
908 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
909 return &fh->vidq;
910 case V4L2_BUF_TYPE_VBI_CAPTURE:
911 return &fh->vbiq;
912 default:
913 BUG();
914 return NULL;
915 }
916}
917
918static int get_ressource(struct cx8800_fh *fh)
919{
920 switch (fh->type) {
921 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
922 return RESOURCE_VIDEO;
923 case V4L2_BUF_TYPE_VBI_CAPTURE:
924 return RESOURCE_VBI;
925 default:
926 BUG();
927 return 0;
928 }
929}
930
931static int video_open(struct inode *inode, struct file *file)
932{
933 int minor = iminor(inode);
934 struct cx8800_dev *h,*dev = NULL;
935 struct cx8800_fh *fh;
936 struct list_head *list;
937 enum v4l2_buf_type type = 0;
938 int radio = 0;
939
940 list_for_each(list,&cx8800_devlist) {
941 h = list_entry(list, struct cx8800_dev, devlist);
942 if (h->video_dev->minor == minor) {
943 dev = h;
944 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
945 }
946 if (h->vbi_dev->minor == minor) {
947 dev = h;
948 type = V4L2_BUF_TYPE_VBI_CAPTURE;
949 }
950 if (h->radio_dev &&
951 h->radio_dev->minor == minor) {
952 radio = 1;
953 dev = h;
954 }
955 }
956 if (NULL == dev)
957 return -ENODEV;
958
959 dprintk(1,"open minor=%d radio=%d type=%s\n",
960 minor,radio,v4l2_type_names[type]);
961
962 /* allocate + initialize per filehandle data */
963 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
964 if (NULL == fh)
965 return -ENOMEM;
966 memset(fh,0,sizeof(*fh));
967 file->private_data = fh;
968 fh->dev = dev;
969 fh->radio = radio;
970 fh->type = type;
971 fh->width = 320;
972 fh->height = 240;
973 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
974
975 videobuf_queue_init(&fh->vidq, &cx8800_video_qops,
976 dev->pci, &dev->slock,
977 V4L2_BUF_TYPE_VIDEO_CAPTURE,
978 V4L2_FIELD_INTERLACED,
979 sizeof(struct cx88_buffer),
980 fh);
981 videobuf_queue_init(&fh->vbiq, &cx8800_vbi_qops,
982 dev->pci, &dev->slock,
983 V4L2_BUF_TYPE_VBI_CAPTURE,
984 V4L2_FIELD_SEQ_TB,
985 sizeof(struct cx88_buffer),
986 fh);
987
988 if (fh->radio) {
989 struct cx88_core *core = dev->core;
990 int board = core->board;
991 dprintk(1,"video_open: setting radio device\n");
992 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
993 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
994 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
995 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
996 dev->core->tvaudio = WW_FM;
997 cx88_set_tvaudio(core);
998 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
999 cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL);
1000 }
1001
1002 return 0;
1003}
1004
1005static ssize_t
1006video_read(struct file *file, char *data, size_t count, loff_t *ppos)
1007{
1008 struct cx8800_fh *fh = file->private_data;
1009
1010 switch (fh->type) {
1011 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1012 if (res_locked(fh->dev,RESOURCE_VIDEO))
1013 return -EBUSY;
1014 return videobuf_read_one(&fh->vidq, data, count, ppos,
1015 file->f_flags & O_NONBLOCK);
1016 case V4L2_BUF_TYPE_VBI_CAPTURE:
1017 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1018 return -EBUSY;
1019 return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
1020 file->f_flags & O_NONBLOCK);
1021 default:
1022 BUG();
1023 return 0;
1024 }
1025}
1026
1027static unsigned int
1028video_poll(struct file *file, struct poll_table_struct *wait)
1029{
1030 struct cx8800_fh *fh = file->private_data;
1031 struct cx88_buffer *buf;
1032
1033 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
1034 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1035 return POLLERR;
1036 return videobuf_poll_stream(file, &fh->vbiq, wait);
1037 }
1038
1039 if (res_check(fh,RESOURCE_VIDEO)) {
1040 /* streaming capture */
1041 if (list_empty(&fh->vidq.stream))
1042 return POLLERR;
1043 buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
1044 } else {
1045 /* read() capture */
1046 buf = (struct cx88_buffer*)fh->vidq.read_buf;
1047 if (NULL == buf)
1048 return POLLERR;
1049 }
1050 poll_wait(file, &buf->vb.done, wait);
1051 if (buf->vb.state == STATE_DONE ||
1052 buf->vb.state == STATE_ERROR)
1053 return POLLIN|POLLRDNORM;
1054 return 0;
1055}
1056
1057static int video_release(struct inode *inode, struct file *file)
1058{
1059 struct cx8800_fh *fh = file->private_data;
1060 struct cx8800_dev *dev = fh->dev;
1061
1062 /* turn off overlay */
1063 if (res_check(fh, RESOURCE_OVERLAY)) {
1064 /* FIXME */
1065 res_free(dev,fh,RESOURCE_OVERLAY);
1066 }
1067
1068 /* stop video capture */
1069 if (res_check(fh, RESOURCE_VIDEO)) {
1070 videobuf_queue_cancel(&fh->vidq);
1071 res_free(dev,fh,RESOURCE_VIDEO);
1072 }
1073 if (fh->vidq.read_buf) {
1074 buffer_release(&fh->vidq,fh->vidq.read_buf);
1075 kfree(fh->vidq.read_buf);
1076 }
1077
1078 /* stop vbi capture */
1079 if (res_check(fh, RESOURCE_VBI)) {
1080 if (fh->vbiq.streaming)
1081 videobuf_streamoff(&fh->vbiq);
1082 if (fh->vbiq.reading)
1083 videobuf_read_stop(&fh->vbiq);
1084 res_free(dev,fh,RESOURCE_VBI);
1085 }
1086
1087 videobuf_mmap_free(&fh->vidq);
1088 videobuf_mmap_free(&fh->vbiq);
1089 file->private_data = NULL;
1090 kfree(fh);
1091 return 0;
1092}
1093
1094static int
1095video_mmap(struct file *file, struct vm_area_struct * vma)
1096{
1097 struct cx8800_fh *fh = file->private_data;
1098
1099 return videobuf_mmap_mapper(get_queue(fh), vma);
1100}
1101
1102/* ------------------------------------------------------------------ */
1103
1104static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
1105{
1106 struct cx88_core *core = dev->core;
1107 struct cx88_ctrl *c = NULL;
1108 u32 value;
1109 int i;
1110
1111 for (i = 0; i < CX8800_CTLS; i++)
1112 if (cx8800_ctls[i].v.id == ctl->id)
1113 c = &cx8800_ctls[i];
1114 if (NULL == c)
1115 return -EINVAL;
1116
1117 value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
1118 switch (ctl->id) {
1119 case V4L2_CID_AUDIO_BALANCE:
1120 ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f));
1121 break;
1122 case V4L2_CID_AUDIO_VOLUME:
1123 ctl->value = 0x3f - (value & 0x3f);
1124 break;
1125 default:
1126 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
1127 break;
1128 }
1129 return 0;
1130}
1131
1132static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
1133{
1134 struct cx88_core *core = dev->core;
1135 struct cx88_ctrl *c = NULL;
1136 u32 v_sat_value;
1137 u32 value;
1138 int i;
1139
1140 for (i = 0; i < CX8800_CTLS; i++)
1141 if (cx8800_ctls[i].v.id == ctl->id)
1142 c = &cx8800_ctls[i];
1143 if (NULL == c)
1144 return -EINVAL;
1145
1146 if (ctl->value < c->v.minimum)
1147 return -ERANGE;
1148 if (ctl->value > c->v.maximum)
1149 return -ERANGE;
1150 switch (ctl->id) {
1151 case V4L2_CID_AUDIO_BALANCE:
1152 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
1153 break;
1154 case V4L2_CID_AUDIO_VOLUME:
1155 value = 0x3f - (ctl->value & 0x3f);
1156 break;
1157 case V4L2_CID_SATURATION:
1158 /* special v_sat handling */
1159 v_sat_value = ctl->value - (0x7f - 0x5a);
1160 if (v_sat_value > 0xff)
1161 v_sat_value = 0xff;
1162 if (v_sat_value < 0x00)
1163 v_sat_value = 0x00;
1164 cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8);
1165 /* fall through to default route for u_sat */
1166 default:
1167 value = ((ctl->value - c->off) << c->shift) & c->mask;
1168 break;
1169 }
1170 dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n",
1171 ctl->id, c->reg, value, c->sreg ? " [shadowed]" : "");
1172 if (c->sreg) {
1173 cx_sandor(c->sreg, c->reg, c->mask, value);
1174 } else {
1175 cx_andor(c->reg, c->mask, value);
1176 }
1177 return 0;
1178}
1179
1180static void init_controls(struct cx8800_dev *dev)
1181{
1182 static struct v4l2_control mute = {
1183 .id = V4L2_CID_AUDIO_MUTE,
1184 .value = 1,
1185 };
1186 static struct v4l2_control volume = {
1187 .id = V4L2_CID_AUDIO_VOLUME,
1188 .value = 0x3f,
1189 };
1190
1191 set_control(dev,&mute);
1192 set_control(dev,&volume);
1193}
1194
1195/* ------------------------------------------------------------------ */
1196
1197static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1198 struct v4l2_format *f)
1199{
1200 switch (f->type) {
1201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1202 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1203 f->fmt.pix.width = fh->width;
1204 f->fmt.pix.height = fh->height;
1205 f->fmt.pix.field = fh->vidq.field;
1206 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1207 f->fmt.pix.bytesperline =
1208 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1209 f->fmt.pix.sizeimage =
1210 f->fmt.pix.height * f->fmt.pix.bytesperline;
1211 return 0;
1212 case V4L2_BUF_TYPE_VBI_CAPTURE:
1213 cx8800_vbi_fmt(dev, f);
1214 return 0;
1215 default:
1216 return -EINVAL;
1217 }
1218}
1219
1220static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1221 struct v4l2_format *f)
1222{
1223 switch (f->type) {
1224 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1225 {
1226 struct cx8800_fmt *fmt;
1227 enum v4l2_field field;
1228 unsigned int maxw, maxh;
1229
1230 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1231 if (NULL == fmt)
1232 return -EINVAL;
1233
1234 field = f->fmt.pix.field;
1235 maxw = norm_maxw(dev->core->tvnorm);
1236 maxh = norm_maxh(dev->core->tvnorm);
1237
1238 if (V4L2_FIELD_ANY == field) {
1239 field = (f->fmt.pix.height > maxh/2)
1240 ? V4L2_FIELD_INTERLACED
1241 : V4L2_FIELD_BOTTOM;
1242 }
1243
1244 switch (field) {
1245 case V4L2_FIELD_TOP:
1246 case V4L2_FIELD_BOTTOM:
1247 maxh = maxh / 2;
1248 break;
1249 case V4L2_FIELD_INTERLACED:
1250 break;
1251 default:
1252 return -EINVAL;
1253 }
1254
1255 f->fmt.pix.field = field;
1256 if (f->fmt.pix.height < 32)
1257 f->fmt.pix.height = 32;
1258 if (f->fmt.pix.height > maxh)
1259 f->fmt.pix.height = maxh;
1260 if (f->fmt.pix.width < 48)
1261 f->fmt.pix.width = 48;
1262 if (f->fmt.pix.width > maxw)
1263 f->fmt.pix.width = maxw;
1264 f->fmt.pix.width &= ~0x03;
1265 f->fmt.pix.bytesperline =
1266 (f->fmt.pix.width * fmt->depth) >> 3;
1267 f->fmt.pix.sizeimage =
1268 f->fmt.pix.height * f->fmt.pix.bytesperline;
1269
1270 return 0;
1271 }
1272 case V4L2_BUF_TYPE_VBI_CAPTURE:
1273 cx8800_vbi_fmt(dev, f);
1274 return 0;
1275 default:
1276 return -EINVAL;
1277 }
1278}
1279
1280static int cx8800_s_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1281 struct v4l2_format *f)
1282{
1283 int err;
1284
1285 switch (f->type) {
1286 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1287 err = cx8800_try_fmt(dev,fh,f);
1288 if (0 != err)
1289 return err;
1290
1291 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1292 fh->width = f->fmt.pix.width;
1293 fh->height = f->fmt.pix.height;
1294 fh->vidq.field = f->fmt.pix.field;
1295 return 0;
1296 case V4L2_BUF_TYPE_VBI_CAPTURE:
1297 cx8800_vbi_fmt(dev, f);
1298 return 0;
1299 default:
1300 return -EINVAL;
1301 }
1302}
1303
1304/*
1305 * This function is _not_ called directly, but from
1306 * video_generic_ioctl (and maybe others). userspace
1307 * copying is done already, arg is a kernel pointer.
1308 */
1309static int video_do_ioctl(struct inode *inode, struct file *file,
1310 unsigned int cmd, void *arg)
1311{
1312 struct cx8800_fh *fh = file->private_data;
1313 struct cx8800_dev *dev = fh->dev;
1314 struct cx88_core *core = dev->core;
1315#if 0
1316 unsigned long flags;
1317#endif
1318 int err;
1319
1320 if (video_debug > 1)
1321 cx88_print_ioctl(core->name,cmd);
1322 switch (cmd) {
1323 case VIDIOC_QUERYCAP:
1324 {
1325 struct v4l2_capability *cap = arg;
1326
1327 memset(cap,0,sizeof(*cap));
1328 strcpy(cap->driver, "cx8800");
1329 strlcpy(cap->card, cx88_boards[core->board].name,
1330 sizeof(cap->card));
1331 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1332 cap->version = CX88_VERSION_CODE;
1333 cap->capabilities =
1334 V4L2_CAP_VIDEO_CAPTURE |
1335 V4L2_CAP_READWRITE |
1336 V4L2_CAP_STREAMING |
1337 V4L2_CAP_VBI_CAPTURE |
1338#if 0
1339 V4L2_CAP_VIDEO_OVERLAY |
1340#endif
1341 0;
1342 if (UNSET != core->tuner_type)
1343 cap->capabilities |= V4L2_CAP_TUNER;
1344 return 0;
1345 }
1346
1347 /* ---------- tv norms ---------- */
1348 case VIDIOC_ENUMSTD:
1349 {
1350 struct v4l2_standard *e = arg;
1351 unsigned int i;
1352
1353 i = e->index;
1354 if (i >= ARRAY_SIZE(tvnorms))
1355 return -EINVAL;
1356 err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1357 tvnorms[e->index].name);
1358 e->index = i;
1359 if (err < 0)
1360 return err;
1361 return 0;
1362 }
1363 case VIDIOC_G_STD:
1364 {
1365 v4l2_std_id *id = arg;
1366
1367 *id = core->tvnorm->id;
1368 return 0;
1369 }
1370 case VIDIOC_S_STD:
1371 {
1372 v4l2_std_id *id = arg;
1373 unsigned int i;
1374
1375 for(i = 0; i < ARRAY_SIZE(tvnorms); i++)
1376 if (*id & tvnorms[i].id)
1377 break;
1378 if (i == ARRAY_SIZE(tvnorms))
1379 return -EINVAL;
1380
1381 down(&dev->lock);
1382 cx88_set_tvnorm(dev->core,&tvnorms[i]);
1383 up(&dev->lock);
1384 return 0;
1385 }
1386
1387 /* ------ input switching ---------- */
1388 case VIDIOC_ENUMINPUT:
1389 {
1390 static const char *iname[] = {
1391 [ CX88_VMUX_COMPOSITE1 ] = "Composite1",
1392 [ CX88_VMUX_COMPOSITE2 ] = "Composite2",
1393 [ CX88_VMUX_COMPOSITE3 ] = "Composite3",
1394 [ CX88_VMUX_COMPOSITE4 ] = "Composite4",
1395 [ CX88_VMUX_SVIDEO ] = "S-Video",
1396 [ CX88_VMUX_TELEVISION ] = "Television",
1397 [ CX88_VMUX_CABLE ] = "Cable TV",
1398 [ CX88_VMUX_DVB ] = "DVB",
1399 [ CX88_VMUX_DEBUG ] = "for debug only",
1400 };
1401 struct v4l2_input *i = arg;
1402 unsigned int n;
1403
1404 n = i->index;
1405 if (n >= 4)
1406 return -EINVAL;
1407 if (0 == INPUT(n)->type)
1408 return -EINVAL;
1409 memset(i,0,sizeof(*i));
1410 i->index = n;
1411 i->type = V4L2_INPUT_TYPE_CAMERA;
1412 strcpy(i->name,iname[INPUT(n)->type]);
1413 if ((CX88_VMUX_TELEVISION == INPUT(n)->type) ||
1414 (CX88_VMUX_CABLE == INPUT(n)->type))
1415 i->type = V4L2_INPUT_TYPE_TUNER;
1416 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
1417 i->std |= tvnorms[n].id;
1418 return 0;
1419 }
1420 case VIDIOC_G_INPUT:
1421 {
1422 unsigned int *i = arg;
1423
1424 *i = dev->core->input;
1425 return 0;
1426 }
1427 case VIDIOC_S_INPUT:
1428 {
1429 unsigned int *i = arg;
1430
1431 if (*i >= 4)
1432 return -EINVAL;
1433 down(&dev->lock);
1434 cx88_newstation(core);
1435 video_mux(dev,*i);
1436 up(&dev->lock);
1437 return 0;
1438 }
1439
1440
1441#if 0
1442 /* needs review */
1443 case VIDIOC_G_AUDIO:
1444 {
1445 struct v4l2_audio *a = arg;
1446 unsigned int n = a->index;
1447
1448 memset(a,0,sizeof(*a));
1449 a->index = n;
1450 switch (n) {
1451 case 0:
1452 if ((CX88_VMUX_TELEVISION == INPUT(n)->type)
1453 || (CX88_VMUX_CABLE == INPUT(n)->type)) {
1454 strcpy(a->name,"Television");
1455 // FIXME figure out if stereo received and set V4L2_AUDCAP_STEREO.
1456 return 0;
1457 }
1458 break;
1459 case 1:
1460 if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD == core->board) {
1461 strcpy(a->name,"Line In");
1462 a->capability = V4L2_AUDCAP_STEREO;
1463 return 0;
1464 }
1465 break;
1466 }
1467 // Audio input not available.
1468 return -EINVAL;
1469 }
1470#endif
1471
1472 /* --- capture ioctls ---------------------------------------- */
1473 case VIDIOC_ENUM_FMT:
1474 {
1475 struct v4l2_fmtdesc *f = arg;
1476 enum v4l2_buf_type type;
1477 unsigned int index;
1478
1479 index = f->index;
1480 type = f->type;
1481 switch (type) {
1482 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1483 if (index >= ARRAY_SIZE(formats))
1484 return -EINVAL;
1485 memset(f,0,sizeof(*f));
1486 f->index = index;
1487 f->type = type;
1488 strlcpy(f->description,formats[index].name,sizeof(f->description));
1489 f->pixelformat = formats[index].fourcc;
1490 break;
1491 default:
1492 return -EINVAL;
1493 }
1494 return 0;
1495 }
1496 case VIDIOC_G_FMT:
1497 {
1498 struct v4l2_format *f = arg;
1499 return cx8800_g_fmt(dev,fh,f);
1500 }
1501 case VIDIOC_S_FMT:
1502 {
1503 struct v4l2_format *f = arg;
1504 return cx8800_s_fmt(dev,fh,f);
1505 }
1506 case VIDIOC_TRY_FMT:
1507 {
1508 struct v4l2_format *f = arg;
1509 return cx8800_try_fmt(dev,fh,f);
1510 }
1511
1512 /* --- controls ---------------------------------------------- */
1513 case VIDIOC_QUERYCTRL:
1514 {
1515 struct v4l2_queryctrl *c = arg;
1516 int i;
1517
1518 if (c->id < V4L2_CID_BASE ||
1519 c->id >= V4L2_CID_LASTP1)
1520 return -EINVAL;
1521 for (i = 0; i < CX8800_CTLS; i++)
1522 if (cx8800_ctls[i].v.id == c->id)
1523 break;
1524 if (i == CX8800_CTLS) {
1525 *c = no_ctl;
1526 return 0;
1527 }
1528 *c = cx8800_ctls[i].v;
1529 return 0;
1530 }
1531 case VIDIOC_G_CTRL:
1532 return get_control(dev,arg);
1533 case VIDIOC_S_CTRL:
1534 return set_control(dev,arg);
1535
1536 /* --- tuner ioctls ------------------------------------------ */
1537 case VIDIOC_G_TUNER:
1538 {
1539 struct v4l2_tuner *t = arg;
1540 u32 reg;
1541
1542 if (UNSET == core->tuner_type)
1543 return -EINVAL;
1544 if (0 != t->index)
1545 return -EINVAL;
1546
1547 memset(t,0,sizeof(*t));
1548 strcpy(t->name, "Television");
1549 t->type = V4L2_TUNER_ANALOG_TV;
1550 t->capability = V4L2_TUNER_CAP_NORM;
1551 t->rangehigh = 0xffffffffUL;
1552
1553 cx88_get_stereo(core ,t);
1554 reg = cx_read(MO_DEVICE_STATUS);
1555 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1556 return 0;
1557 }
1558 case VIDIOC_S_TUNER:
1559 {
1560 struct v4l2_tuner *t = arg;
1561
1562 if (UNSET == core->tuner_type)
1563 return -EINVAL;
1564 if (0 != t->index)
1565 return -EINVAL;
1566 cx88_set_stereo(core, t->audmode, 1);
1567 return 0;
1568 }
1569 case VIDIOC_G_FREQUENCY:
1570 {
1571 struct v4l2_frequency *f = arg;
1572
1573 if (UNSET == core->tuner_type)
1574 return -EINVAL;
1575 if (f->tuner != 0)
1576 return -EINVAL;
1577 memset(f,0,sizeof(*f));
1578 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1579 f->frequency = dev->freq;
1580 return 0;
1581 }
1582 case VIDIOC_S_FREQUENCY:
1583 {
1584 struct v4l2_frequency *f = arg;
1585
1586 if (UNSET == core->tuner_type)
1587 return -EINVAL;
1588 if (f->tuner != 0)
1589 return -EINVAL;
1590 if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)
1591 return -EINVAL;
1592 if (1 == fh->radio && f->type != V4L2_TUNER_RADIO)
1593 return -EINVAL;
1594 down(&dev->lock);
1595 dev->freq = f->frequency;
1596 cx88_newstation(core);
1597#ifdef V4L2_I2C_CLIENTS
1598 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
1599#else
1600 cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq);
1601#endif
1602 up(&dev->lock);
1603 return 0;
1604 }
1605
1606 /* --- streaming capture ------------------------------------- */
1607 case VIDIOCGMBUF:
1608 {
1609 struct video_mbuf *mbuf = arg;
1610 struct videobuf_queue *q;
1611 struct v4l2_requestbuffers req;
1612 unsigned int i;
1613
1614 q = get_queue(fh);
1615 memset(&req,0,sizeof(req));
1616 req.type = q->type;
1617 req.count = 8;
1618 req.memory = V4L2_MEMORY_MMAP;
1619 err = videobuf_reqbufs(q,&req);
1620 if (err < 0)
1621 return err;
1622 memset(mbuf,0,sizeof(*mbuf));
1623 mbuf->frames = req.count;
1624 mbuf->size = 0;
1625 for (i = 0; i < mbuf->frames; i++) {
1626 mbuf->offsets[i] = q->bufs[i]->boff;
1627 mbuf->size += q->bufs[i]->bsize;
1628 }
1629 return 0;
1630 }
1631 case VIDIOC_REQBUFS:
1632 return videobuf_reqbufs(get_queue(fh), arg);
1633
1634 case VIDIOC_QUERYBUF:
1635 return videobuf_querybuf(get_queue(fh), arg);
1636
1637 case VIDIOC_QBUF:
1638 return videobuf_qbuf(get_queue(fh), arg);
1639
1640 case VIDIOC_DQBUF:
1641 return videobuf_dqbuf(get_queue(fh), arg,
1642 file->f_flags & O_NONBLOCK);
1643
1644 case VIDIOC_STREAMON:
1645 {
1646 int res = get_ressource(fh);
1647
1648 if (!res_get(dev,fh,res))
1649 return -EBUSY;
1650 return videobuf_streamon(get_queue(fh));
1651 }
1652 case VIDIOC_STREAMOFF:
1653 {
1654 int res = get_ressource(fh);
1655
1656 err = videobuf_streamoff(get_queue(fh));
1657 if (err < 0)
1658 return err;
1659 res_free(dev,fh,res);
1660 return 0;
1661 }
1662
1663 default:
1664 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1665 video_do_ioctl);
1666 }
1667 return 0;
1668}
1669
1670static int video_ioctl(struct inode *inode, struct file *file,
1671 unsigned int cmd, unsigned long arg)
1672{
1673 return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
1674}
1675
1676/* ----------------------------------------------------------- */
1677
1678static int radio_do_ioctl(struct inode *inode, struct file *file,
1679 unsigned int cmd, void *arg)
1680{
1681 struct cx8800_fh *fh = file->private_data;
1682 struct cx8800_dev *dev = fh->dev;
1683 struct cx88_core *core = dev->core;
1684
1685 if (video_debug > 1)
1686 cx88_print_ioctl(core->name,cmd);
1687
1688 switch (cmd) {
1689 case VIDIOC_QUERYCAP:
1690 {
1691 struct v4l2_capability *cap = arg;
1692
1693 memset(cap,0,sizeof(*cap));
1694 strcpy(cap->driver, "cx8800");
1695 strlcpy(cap->card, cx88_boards[core->board].name,
1696 sizeof(cap->card));
1697 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
1698 cap->version = CX88_VERSION_CODE;
1699 cap->capabilities = V4L2_CAP_TUNER;
1700 return 0;
1701 }
1702 case VIDIOC_G_TUNER:
1703 {
1704 struct v4l2_tuner *t = arg;
1705
1706 if (t->index > 0)
1707 return -EINVAL;
1708
1709 memset(t,0,sizeof(*t));
1710 strcpy(t->name, "Radio");
1711 t->rangelow = (int)(65*16);
1712 t->rangehigh = (int)(108*16);
1713
1714#ifdef V4L2_I2C_CLIENTS
1715 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
1716#else
1717 {
1718 struct video_tuner vt;
1719 memset(&vt,0,sizeof(vt));
1720 cx88_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
1721 t->signal = vt.signal;
1722 }
1723#endif
1724 return 0;
1725 }
1726 case VIDIOC_ENUMINPUT:
1727 {
1728 struct v4l2_input *i = arg;
1729
1730 if (i->index != 0)
1731 return -EINVAL;
1732 strcpy(i->name,"Radio");
1733 i->type = V4L2_INPUT_TYPE_TUNER;
1734 return 0;
1735 }
1736 case VIDIOC_G_INPUT:
1737 {
1738 int *i = arg;
1739 *i = 0;
1740 return 0;
1741 }
1742 case VIDIOC_G_AUDIO:
1743 {
1744 struct v4l2_audio *a = arg;
1745
1746 memset(a,0,sizeof(*a));
1747 strcpy(a->name,"Radio");
1748 return 0;
1749 }
1750 case VIDIOC_G_STD:
1751 {
1752 v4l2_std_id *id = arg;
1753 *id = 0;
1754 return 0;
1755 }
1756 case VIDIOC_S_AUDIO:
1757 case VIDIOC_S_TUNER:
1758 case VIDIOC_S_INPUT:
1759 case VIDIOC_S_STD:
1760 return 0;
1761
1762 case VIDIOC_QUERYCTRL:
1763 {
1764 struct v4l2_queryctrl *c = arg;
1765 int i;
1766
1767 if (c->id < V4L2_CID_BASE ||
1768 c->id >= V4L2_CID_LASTP1)
1769 return -EINVAL;
1770 if (c->id == V4L2_CID_AUDIO_MUTE) {
1771 for (i = 0; i < CX8800_CTLS; i++)
1772 if (cx8800_ctls[i].v.id == c->id)
1773 break;
1774 *c = cx8800_ctls[i].v;
1775 } else
1776 *c = no_ctl;
1777 return 0;
1778 }
1779
1780
1781 case VIDIOC_G_CTRL:
1782 case VIDIOC_S_CTRL:
1783 case VIDIOC_G_FREQUENCY:
1784 case VIDIOC_S_FREQUENCY:
1785 return video_do_ioctl(inode,file,cmd,arg);
1786
1787 default:
1788 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1789 radio_do_ioctl);
1790 }
1791 return 0;
1792};
1793
1794static int radio_ioctl(struct inode *inode, struct file *file,
1795 unsigned int cmd, unsigned long arg)
1796{
1797 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
1798};
1799
1800/* ----------------------------------------------------------- */
1801
1802static void cx8800_vid_timeout(unsigned long data)
1803{
1804 struct cx8800_dev *dev = (struct cx8800_dev*)data;
1805 struct cx88_core *core = dev->core;
1806 struct cx88_dmaqueue *q = &dev->vidq;
1807 struct cx88_buffer *buf;
1808 unsigned long flags;
1809
1810 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
1811
1812 cx_clear(MO_VID_DMACNTRL, 0x11);
1813 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1814
1815 spin_lock_irqsave(&dev->slock,flags);
1816 while (!list_empty(&q->active)) {
1817 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
1818 list_del(&buf->vb.queue);
1819 buf->vb.state = STATE_ERROR;
1820 wake_up(&buf->vb.done);
1821 printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name,
1822 buf, buf->vb.i, (unsigned long)buf->risc.dma);
1823 }
1824 restart_video_queue(dev,q);
1825 spin_unlock_irqrestore(&dev->slock,flags);
1826}
1827
1828static void cx8800_vid_irq(struct cx8800_dev *dev)
1829{
1830 struct cx88_core *core = dev->core;
1831 u32 status, mask, count;
1832
1833 status = cx_read(MO_VID_INTSTAT);
1834 mask = cx_read(MO_VID_INTMSK);
1835 if (0 == (status & mask))
1836 return;
1837 cx_write(MO_VID_INTSTAT, status);
1838 if (irq_debug || (status & mask & ~0xff))
1839 cx88_print_irqbits(core->name, "irq vid",
1840 cx88_vid_irqs, status, mask);
1841
1842 /* risc op code error */
1843 if (status & (1 << 16)) {
1844 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
1845 cx_clear(MO_VID_DMACNTRL, 0x11);
1846 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1847 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
1848 }
1849
1850 /* risc1 y */
1851 if (status & 0x01) {
1852 spin_lock(&dev->slock);
1853 count = cx_read(MO_VIDY_GPCNT);
1854 cx88_wakeup(dev->core, &dev->vidq, count);
1855 spin_unlock(&dev->slock);
1856 }
1857
1858 /* risc1 vbi */
1859 if (status & 0x08) {
1860 spin_lock(&dev->slock);
1861 count = cx_read(MO_VBI_GPCNT);
1862 cx88_wakeup(dev->core, &dev->vbiq, count);
1863 spin_unlock(&dev->slock);
1864 }
1865
1866 /* risc2 y */
1867 if (status & 0x10) {
1868 dprintk(2,"stopper video\n");
1869 spin_lock(&dev->slock);
1870 restart_video_queue(dev,&dev->vidq);
1871 spin_unlock(&dev->slock);
1872 }
1873
1874 /* risc2 vbi */
1875 if (status & 0x80) {
1876 dprintk(2,"stopper vbi\n");
1877 spin_lock(&dev->slock);
1878 cx8800_restart_vbi_queue(dev,&dev->vbiq);
1879 spin_unlock(&dev->slock);
1880 }
1881}
1882
1883static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs)
1884{
1885 struct cx8800_dev *dev = dev_id;
1886 struct cx88_core *core = dev->core;
1887 u32 status;
1888 int loop, handled = 0;
1889
1890 for (loop = 0; loop < 10; loop++) {
1891 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x01);
1892 if (0 == status)
1893 goto out;
1894 cx_write(MO_PCI_INTSTAT, status);
1895 handled = 1;
1896
1897 if (status & core->pci_irqmask)
1898 cx88_core_irq(core,status);
1899 if (status & 0x01)
1900 cx8800_vid_irq(dev);
1901 };
1902 if (10 == loop) {
1903 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
1904 core->name);
1905 cx_write(MO_PCI_INTMSK,0);
1906 }
1907
1908 out:
1909 return IRQ_RETVAL(handled);
1910}
1911
1912/* ----------------------------------------------------------- */
1913/* exported stuff */
1914
1915static struct file_operations video_fops =
1916{
1917 .owner = THIS_MODULE,
1918 .open = video_open,
1919 .release = video_release,
1920 .read = video_read,
1921 .poll = video_poll,
1922 .mmap = video_mmap,
1923 .ioctl = video_ioctl,
1924 .llseek = no_llseek,
1925};
1926
1927struct video_device cx8800_video_template =
1928{
1929 .name = "cx8800-video",
1930 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
1931 .hardware = 0,
1932 .fops = &video_fops,
1933 .minor = -1,
1934};
1935
1936struct video_device cx8800_vbi_template =
1937{
1938 .name = "cx8800-vbi",
1939 .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER,
1940 .hardware = 0,
1941 .fops = &video_fops,
1942 .minor = -1,
1943};
1944
1945static struct file_operations radio_fops =
1946{
1947 .owner = THIS_MODULE,
1948 .open = video_open,
1949 .release = video_release,
1950 .ioctl = radio_ioctl,
1951 .llseek = no_llseek,
1952};
1953
1954struct video_device cx8800_radio_template =
1955{
1956 .name = "cx8800-radio",
1957 .type = VID_TYPE_TUNER,
1958 .hardware = 0,
1959 .fops = &radio_fops,
1960 .minor = -1,
1961};
1962
1963/* ----------------------------------------------------------- */
1964
1965static void cx8800_unregister_video(struct cx8800_dev *dev)
1966{
1967 if (dev->radio_dev) {
1968 if (-1 != dev->radio_dev->minor)
1969 video_unregister_device(dev->radio_dev);
1970 else
1971 video_device_release(dev->radio_dev);
1972 dev->radio_dev = NULL;
1973 }
1974 if (dev->vbi_dev) {
1975 if (-1 != dev->vbi_dev->minor)
1976 video_unregister_device(dev->vbi_dev);
1977 else
1978 video_device_release(dev->vbi_dev);
1979 dev->vbi_dev = NULL;
1980 }
1981 if (dev->video_dev) {
1982 if (-1 != dev->video_dev->minor)
1983 video_unregister_device(dev->video_dev);
1984 else
1985 video_device_release(dev->video_dev);
1986 dev->video_dev = NULL;
1987 }
1988}
1989
1990static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1991 const struct pci_device_id *pci_id)
1992{
1993 struct cx8800_dev *dev;
1994 struct cx88_core *core;
1995 int err;
1996
1997 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
1998 if (NULL == dev)
1999 return -ENOMEM;
2000 memset(dev,0,sizeof(*dev));
2001
2002 /* pci init */
2003 dev->pci = pci_dev;
2004 if (pci_enable_device(pci_dev)) {
2005 err = -EIO;
2006 goto fail_free;
2007 }
2008 core = cx88_core_get(dev->pci);
2009 if (NULL == core) {
2010 err = -EINVAL;
2011 goto fail_free;
2012 }
2013 dev->core = core;
2014
2015 /* print pci info */
2016 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
2017 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
2018 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
2019 "latency: %d, mmio: 0x%lx\n", core->name,
2020 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
2021 dev->pci_lat,pci_resource_start(pci_dev,0));
2022
2023 pci_set_master(pci_dev);
2024 if (!pci_dma_supported(pci_dev,0xffffffff)) {
2025 printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
2026 err = -EIO;
2027 goto fail_core;
2028 }
2029
2030 /* initialize driver struct */
2031 init_MUTEX(&dev->lock);
2032 spin_lock_init(&dev->slock);
2033 core->tvnorm = tvnorms;
2034
2035 /* init video dma queues */
2036 INIT_LIST_HEAD(&dev->vidq.active);
2037 INIT_LIST_HEAD(&dev->vidq.queued);
2038 dev->vidq.timeout.function = cx8800_vid_timeout;
2039 dev->vidq.timeout.data = (unsigned long)dev;
2040 init_timer(&dev->vidq.timeout);
2041 cx88_risc_stopper(dev->pci,&dev->vidq.stopper,
2042 MO_VID_DMACNTRL,0x11,0x00);
2043
2044 /* init vbi dma queues */
2045 INIT_LIST_HEAD(&dev->vbiq.active);
2046 INIT_LIST_HEAD(&dev->vbiq.queued);
2047 dev->vbiq.timeout.function = cx8800_vbi_timeout;
2048 dev->vbiq.timeout.data = (unsigned long)dev;
2049 init_timer(&dev->vbiq.timeout);
2050 cx88_risc_stopper(dev->pci,&dev->vbiq.stopper,
2051 MO_VID_DMACNTRL,0x88,0x00);
2052
2053 /* get irq */
2054 err = request_irq(pci_dev->irq, cx8800_irq,
2055 SA_SHIRQ | SA_INTERRUPT, core->name, dev);
2056 if (err < 0) {
2057 printk(KERN_ERR "%s: can't get IRQ %d\n",
2058 core->name,pci_dev->irq);
2059 goto fail_core;
2060 }
2061 cx_set(MO_PCI_INTMSK, core->pci_irqmask);
2062
2063 /* load and configure helper modules */
2064 if (TUNER_ABSENT != core->tuner_type)
2065 request_module("tuner");
2066 if (core->tda9887_conf)
2067 request_module("tda9887");
2068 if (core->tuner_type != UNSET)
2069 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type);
2070 if (core->tda9887_conf)
2071 cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
2072
2073 /* register v4l devices */
2074 dev->video_dev = cx88_vdev_init(core,dev->pci,
2075 &cx8800_video_template,"video");
2076 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
2077 video_nr[core->nr]);
2078 if (err < 0) {
2079 printk(KERN_INFO "%s: can't register video device\n",
2080 core->name);
2081 goto fail_unreg;
2082 }
2083 printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
2084 core->name,dev->video_dev->minor & 0x1f);
2085
2086 dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
2087 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
2088 vbi_nr[core->nr]);
2089 if (err < 0) {
2090 printk(KERN_INFO "%s/0: can't register vbi device\n",
2091 core->name);
2092 goto fail_unreg;
2093 }
2094 printk(KERN_INFO "%s/0: registered device vbi%d\n",
2095 core->name,dev->vbi_dev->minor & 0x1f);
2096
2097 if (core->has_radio) {
2098 dev->radio_dev = cx88_vdev_init(core,dev->pci,
2099 &cx8800_radio_template,"radio");
2100 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
2101 radio_nr[core->nr]);
2102 if (err < 0) {
2103 printk(KERN_INFO "%s/0: can't register radio device\n",
2104 core->name);
2105 goto fail_unreg;
2106 }
2107 printk(KERN_INFO "%s/0: registered device radio%d\n",
2108 core->name,dev->radio_dev->minor & 0x1f);
2109 }
2110
2111 /* everything worked */
2112 list_add_tail(&dev->devlist,&cx8800_devlist);
2113 pci_set_drvdata(pci_dev,dev);
2114
2115 /* initial device configuration */
2116 down(&dev->lock);
2117 init_controls(dev);
2118 cx88_set_tvnorm(dev->core,tvnorms);
2119 video_mux(dev,0);
2120 up(&dev->lock);
2121
2122 /* start tvaudio thread */
2123 if (core->tuner_type != TUNER_ABSENT)
2124 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
2125 return 0;
2126
2127fail_unreg:
2128 cx8800_unregister_video(dev);
2129 free_irq(pci_dev->irq, dev);
2130fail_core:
2131 cx88_core_put(core,dev->pci);
2132fail_free:
2133 kfree(dev);
2134 return err;
2135}
2136
2137static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
2138{
2139 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2140
2141 /* stop thread */
2142 if (dev->core->kthread) {
2143 kthread_stop(dev->core->kthread);
2144 dev->core->kthread = NULL;
2145 }
2146
2147 cx88_shutdown(dev->core); /* FIXME */
2148 pci_disable_device(pci_dev);
2149
2150 /* unregister stuff */
2151
2152 free_irq(pci_dev->irq, dev);
2153 cx8800_unregister_video(dev);
2154 pci_set_drvdata(pci_dev, NULL);
2155
2156 /* free memory */
2157 btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
2158 list_del(&dev->devlist);
2159 cx88_core_put(dev->core,dev->pci);
2160 kfree(dev);
2161}
2162
2163static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2164{
2165 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2166 struct cx88_core *core = dev->core;
2167
2168 /* stop video+vbi capture */
2169 spin_lock(&dev->slock);
2170 if (!list_empty(&dev->vidq.active)) {
2171 printk("%s: suspend video\n", core->name);
2172 stop_video_dma(dev);
2173 del_timer(&dev->vidq.timeout);
2174 }
2175 if (!list_empty(&dev->vbiq.active)) {
2176 printk("%s: suspend vbi\n", core->name);
2177 cx8800_stop_vbi_dma(dev);
2178 del_timer(&dev->vbiq.timeout);
2179 }
2180 spin_unlock(&dev->slock);
2181
2182#if 1
2183 /* FIXME -- shutdown device */
2184 cx88_shutdown(dev->core);
2185#endif
2186
2187 pci_save_state(pci_dev);
2188 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
2189 pci_disable_device(pci_dev);
2190 dev->state.disabled = 1;
2191 }
2192 return 0;
2193}
2194
2195static int cx8800_resume(struct pci_dev *pci_dev)
2196{
2197 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2198 struct cx88_core *core = dev->core;
2199
2200 if (dev->state.disabled) {
2201 pci_enable_device(pci_dev);
2202 dev->state.disabled = 0;
2203 }
2204 pci_set_power_state(pci_dev, PCI_D0);
2205 pci_restore_state(pci_dev);
2206
2207#if 1
2208 /* FIXME: re-initialize hardware */
2209 cx88_reset(dev->core);
2210#endif
2211
2212 /* restart video+vbi capture */
2213 spin_lock(&dev->slock);
2214 if (!list_empty(&dev->vidq.active)) {
2215 printk("%s: resume video\n", core->name);
2216 restart_video_queue(dev,&dev->vidq);
2217 }
2218 if (!list_empty(&dev->vbiq.active)) {
2219 printk("%s: resume vbi\n", core->name);
2220 cx8800_restart_vbi_queue(dev,&dev->vbiq);
2221 }
2222 spin_unlock(&dev->slock);
2223
2224 return 0;
2225}
2226
2227/* ----------------------------------------------------------- */
2228
2229struct pci_device_id cx8800_pci_tbl[] = {
2230 {
2231 .vendor = 0x14f1,
2232 .device = 0x8800,
2233 .subvendor = PCI_ANY_ID,
2234 .subdevice = PCI_ANY_ID,
2235 },{
2236 /* --- end of list --- */
2237 }
2238};
2239MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
2240
2241static struct pci_driver cx8800_pci_driver = {
2242 .name = "cx8800",
2243 .id_table = cx8800_pci_tbl,
2244 .probe = cx8800_initdev,
2245 .remove = __devexit_p(cx8800_finidev),
2246
2247 .suspend = cx8800_suspend,
2248 .resume = cx8800_resume,
2249};
2250
2251static int cx8800_init(void)
2252{
2253 printk(KERN_INFO "cx2388x v4l2 driver version %d.%d.%d loaded\n",
2254 (CX88_VERSION_CODE >> 16) & 0xff,
2255 (CX88_VERSION_CODE >> 8) & 0xff,
2256 CX88_VERSION_CODE & 0xff);
2257#ifdef SNAPSHOT
2258 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
2259 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
2260#endif
2261 return pci_register_driver(&cx8800_pci_driver);
2262}
2263
2264static void cx8800_fini(void)
2265{
2266 pci_unregister_driver(&cx8800_pci_driver);
2267}
2268
2269module_init(cx8800_init);
2270module_exit(cx8800_fini);
2271
2272/* ----------------------------------------------------------- */
2273/*
2274 * Local variables:
2275 * c-basic-offset: 8
2276 * End:
2277 */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
new file mode 100644
index 000000000000..b351d9eae615
--- /dev/null
+++ b/drivers/media/video/cx88/cx88.h
@@ -0,0 +1,551 @@
1/*
2 * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * v4l2 device driver for cx2388x based TV cards
5 *
6 * (c) 2003,04 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
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#include <linux/pci.h>
24#include <linux/i2c.h>
25#include <linux/i2c-algo-bit.h>
26#include <linux/videodev.h>
27#include <linux/kdev_t.h>
28
29#include <media/tuner.h>
30#include <media/tveeprom.h>
31#include <media/audiochip.h>
32#include <media/video-buf.h>
33#include <media/video-buf-dvb.h>
34
35#include "btcx-risc.h"
36#include "cx88-reg.h"
37
38#include <linux/version.h>
39#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
40
41#ifndef TRUE
42# define TRUE (1==1)
43#endif
44#ifndef FALSE
45# define FALSE (1==0)
46#endif
47#define UNSET (-1U)
48
49#define CX88_MAXBOARDS 8
50
51/* ----------------------------------------------------------- */
52/* defines and enums */
53
54#define V4L2_I2C_CLIENTS 1
55
56#define FORMAT_FLAGS_PACKED 0x01
57#define FORMAT_FLAGS_PLANAR 0x02
58
59#define VBI_LINE_COUNT 17
60#define VBI_LINE_LENGTH 2048
61
62/* need "shadow" registers for some write-only ones ... */
63#define SHADOW_AUD_VOL_CTL 1
64#define SHADOW_AUD_BAL_CTL 2
65#define SHADOW_MAX 2
66
67/* ----------------------------------------------------------- */
68/* tv norms */
69
70struct cx88_tvnorm {
71 char *name;
72 v4l2_std_id id;
73 u32 cxiformat;
74 u32 cxoformat;
75};
76
77static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
78{
79 return (norm->id & V4L2_STD_625_50) ? 768 : 640;
80// return (norm->id & V4L2_STD_625_50) ? 720 : 640;
81}
82
83static unsigned int inline norm_maxh(struct cx88_tvnorm *norm)
84{
85 return (norm->id & V4L2_STD_625_50) ? 576 : 480;
86}
87
88/* ----------------------------------------------------------- */
89/* static data */
90
91struct cx8800_fmt {
92 char *name;
93 u32 fourcc; /* v4l2 format id */
94 int depth;
95 int flags;
96 u32 cxformat;
97};
98
99struct cx88_ctrl {
100 struct v4l2_queryctrl v;
101 u32 off;
102 u32 reg;
103 u32 sreg;
104 u32 mask;
105 u32 shift;
106};
107
108/* ----------------------------------------------------------- */
109/* SRAM memory management data (see cx88-core.c) */
110
111#define SRAM_CH21 0 /* video */
112#define SRAM_CH22 1
113#define SRAM_CH23 2
114#define SRAM_CH24 3 /* vbi */
115#define SRAM_CH25 4 /* audio */
116#define SRAM_CH26 5
117#define SRAM_CH28 6 /* mpeg */
118/* more */
119
120struct sram_channel {
121 char *name;
122 u32 cmds_start;
123 u32 ctrl_start;
124 u32 cdt;
125 u32 fifo_start;
126 u32 fifo_size;
127 u32 ptr1_reg;
128 u32 ptr2_reg;
129 u32 cnt1_reg;
130 u32 cnt2_reg;
131};
132extern struct sram_channel cx88_sram_channels[];
133
134/* ----------------------------------------------------------- */
135/* card configuration */
136
137#define CX88_BOARD_NOAUTO UNSET
138#define CX88_BOARD_UNKNOWN 0
139#define CX88_BOARD_HAUPPAUGE 1
140#define CX88_BOARD_GDI 2
141#define CX88_BOARD_PIXELVIEW 3
142#define CX88_BOARD_ATI_WONDER_PRO 4
143#define CX88_BOARD_WINFAST2000XP_EXPERT 5
144#define CX88_BOARD_AVERTV_303 6
145#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
146#define CX88_BOARD_WINFAST_DV2000 8
147#define CX88_BOARD_LEADTEK_PVR2000 9
148#define CX88_BOARD_IODATA_GVVCP3PCI 10
149#define CX88_BOARD_PROLINK_PLAYTVPVR 11
150#define CX88_BOARD_ASUS_PVR_416 12
151#define CX88_BOARD_MSI_TVANYWHERE 13
152#define CX88_BOARD_KWORLD_DVB_T 14
153#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
154#define CX88_BOARD_KWORLD_LTV883 16
155#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD 17
156#define CX88_BOARD_HAUPPAUGE_DVB_T1 18
157#define CX88_BOARD_CONEXANT_DVB_T1 19
158#define CX88_BOARD_PROVIDEO_PV259 20
159#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS 21
160#define CX88_BOARD_PCHDTV_HD3000 22
161#define CX88_BOARD_DNTV_LIVE_DVB_T 23
162#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
163#define CX88_BOARD_DIGITALLOGIC_MEC 25
164#define CX88_BOARD_IODATA_GVBCTV7E 26
165
166enum cx88_itype {
167 CX88_VMUX_COMPOSITE1 = 1,
168 CX88_VMUX_COMPOSITE2,
169 CX88_VMUX_COMPOSITE3,
170 CX88_VMUX_COMPOSITE4,
171 CX88_VMUX_SVIDEO,
172 CX88_VMUX_TELEVISION,
173 CX88_VMUX_CABLE,
174 CX88_VMUX_DVB,
175 CX88_VMUX_DEBUG,
176 CX88_RADIO,
177};
178
179struct cx88_input {
180 enum cx88_itype type;
181 unsigned int vmux;
182 u32 gpio0, gpio1, gpio2, gpio3;
183};
184
185struct cx88_board {
186 char *name;
187 unsigned int tuner_type;
188 int tda9887_conf;
189 struct cx88_input input[8];
190 struct cx88_input radio;
191 int blackbird:1;
192 int dvb:1;
193};
194
195struct cx88_subid {
196 u16 subvendor;
197 u16 subdevice;
198 u32 card;
199};
200
201#define INPUT(nr) (&cx88_boards[core->board].input[nr])
202
203/* ----------------------------------------------------------- */
204/* device / file handle status */
205
206#define RESOURCE_OVERLAY 1
207#define RESOURCE_VIDEO 2
208#define RESOURCE_VBI 4
209
210#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
211//#define BUFFER_TIMEOUT (HZ*2)
212
213/* buffer for one video frame */
214struct cx88_buffer {
215 /* common v4l buffer stuff -- must be first */
216 struct videobuf_buffer vb;
217
218 /* cx88 specific */
219 unsigned int bpl;
220 struct btcx_riscmem risc;
221 struct cx8800_fmt *fmt;
222 u32 count;
223};
224
225struct cx88_dmaqueue {
226 struct list_head active;
227 struct list_head queued;
228 struct timer_list timeout;
229 struct btcx_riscmem stopper;
230 u32 count;
231};
232
233struct cx88_core {
234 struct list_head devlist;
235 atomic_t refcount;
236
237 /* board name */
238 int nr;
239 char name[32];
240
241 /* pci stuff */
242 int pci_bus;
243 int pci_slot;
244 u32 __iomem *lmmio;
245 u8 __iomem *bmmio;
246 u32 shadow[SHADOW_MAX];
247 int pci_irqmask;
248
249 /* i2c i/o */
250 struct i2c_adapter i2c_adap;
251 struct i2c_algo_bit_data i2c_algo;
252 struct i2c_client i2c_client;
253 u32 i2c_state, i2c_rc;
254
255 /* config info -- analog */
256 unsigned int board;
257 unsigned int tuner_type;
258 unsigned int tda9887_conf;
259 unsigned int has_radio;
260
261 /* config info -- dvb */
262 struct dvb_pll_desc *pll_desc;
263 unsigned int pll_addr;
264
265 /* state info */
266 struct task_struct *kthread;
267 struct cx88_tvnorm *tvnorm;
268 u32 tvaudio;
269 u32 audiomode_manual;
270 u32 audiomode_current;
271 u32 input;
272 u32 astat;
273
274 /* IR remote control state */
275 struct cx88_IR *ir;
276};
277
278struct cx8800_dev;
279struct cx8802_dev;
280
281/* ----------------------------------------------------------- */
282/* function 0: video stuff */
283
284struct cx8800_fh {
285 struct cx8800_dev *dev;
286 enum v4l2_buf_type type;
287 int radio;
288 unsigned int resources;
289
290 /* video overlay */
291 struct v4l2_window win;
292 struct v4l2_clip *clips;
293 unsigned int nclips;
294
295 /* video capture */
296 struct cx8800_fmt *fmt;
297 unsigned int width,height;
298 struct videobuf_queue vidq;
299
300 /* vbi capture */
301 struct videobuf_queue vbiq;
302};
303
304struct cx8800_suspend_state {
305 int disabled;
306};
307
308struct cx8800_dev {
309 struct cx88_core *core;
310 struct list_head devlist;
311 struct semaphore lock;
312 spinlock_t slock;
313
314 /* various device info */
315 unsigned int resources;
316 struct video_device *video_dev;
317 struct video_device *vbi_dev;
318 struct video_device *radio_dev;
319
320 /* pci i/o */
321 struct pci_dev *pci;
322 unsigned char pci_rev,pci_lat;
323
324#if 0
325 /* video overlay */
326 struct v4l2_framebuffer fbuf;
327 struct cx88_buffer *screen;
328#endif
329
330 /* capture queues */
331 struct cx88_dmaqueue vidq;
332 struct cx88_dmaqueue vbiq;
333
334 /* various v4l controls */
335 u32 freq;
336
337 /* other global state info */
338 struct cx8800_suspend_state state;
339};
340
341/* ----------------------------------------------------------- */
342/* function 1: audio/alsa stuff */
343
344struct cx8801_dev {
345 struct cx88_core *core;
346
347 /* pci i/o */
348 struct pci_dev *pci;
349 unsigned char pci_rev,pci_lat;
350};
351
352/* ----------------------------------------------------------- */
353/* function 2: mpeg stuff */
354
355struct cx8802_fh {
356 struct cx8802_dev *dev;
357 struct videobuf_queue mpegq;
358};
359
360struct cx8802_suspend_state {
361 int disabled;
362};
363
364struct cx8802_dev {
365 struct cx88_core *core;
366 struct semaphore lock;
367 spinlock_t slock;
368
369 /* pci i/o */
370 struct pci_dev *pci;
371 unsigned char pci_rev,pci_lat;
372
373 /* dma queues */
374 struct cx88_dmaqueue mpegq;
375 u32 ts_packet_size;
376 u32 ts_packet_count;
377
378 /* other global state info */
379 struct cx8802_suspend_state state;
380
381 /* for blackbird only */
382 struct list_head devlist;
383 struct video_device *mpeg_dev;
384 u32 mailbox;
385 int width;
386 int height;
387
388 /* for dvb only */
389 struct videobuf_dvb dvb;
390 void* fe_handle;
391 int (*fe_release)(void *handle);
392
393 /* for switching modulation types */
394 unsigned char ts_gen_cntrl;
395};
396
397/* ----------------------------------------------------------- */
398
399#define cx_read(reg) readl(core->lmmio + ((reg)>>2))
400#define cx_write(reg,value) writel((value), core->lmmio + ((reg)>>2))
401#define cx_writeb(reg,value) writeb((value), core->bmmio + (reg))
402
403#define cx_andor(reg,mask,value) \
404 writel((readl(core->lmmio+((reg)>>2)) & ~(mask)) |\
405 ((value) & (mask)), core->lmmio+((reg)>>2))
406#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
407#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
408
409#define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); }
410
411/* shadow registers */
412#define cx_sread(sreg) (core->shadow[sreg])
413#define cx_swrite(sreg,reg,value) \
414 (core->shadow[sreg] = value, \
415 writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
416#define cx_sandor(sreg,reg,mask,value) \
417 (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | ((value) & (mask)), \
418 writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
419
420/* ----------------------------------------------------------- */
421/* cx88-core.c */
422
423extern char *cx88_pci_irqs[32];
424extern char *cx88_vid_irqs[32];
425extern char *cx88_mpeg_irqs[32];
426extern void cx88_print_irqbits(char *name, char *tag, char **strings,
427 u32 bits, u32 mask);
428extern void cx88_print_ioctl(char *name, unsigned int cmd);
429
430extern int cx88_core_irq(struct cx88_core *core, u32 status);
431extern void cx88_wakeup(struct cx88_core *core,
432 struct cx88_dmaqueue *q, u32 count);
433extern void cx88_shutdown(struct cx88_core *core);
434extern int cx88_reset(struct cx88_core *core);
435
436extern int
437cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
438 struct scatterlist *sglist,
439 unsigned int top_offset, unsigned int bottom_offset,
440 unsigned int bpl, unsigned int padding, unsigned int lines);
441extern int
442cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
443 struct scatterlist *sglist, unsigned int bpl,
444 unsigned int lines);
445extern int
446cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
447 u32 reg, u32 mask, u32 value);
448extern void
449cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf);
450
451extern void cx88_risc_disasm(struct cx88_core *core,
452 struct btcx_riscmem *risc);
453extern int cx88_sram_channel_setup(struct cx88_core *core,
454 struct sram_channel *ch,
455 unsigned int bpl, u32 risc);
456extern void cx88_sram_channel_dump(struct cx88_core *core,
457 struct sram_channel *ch);
458
459extern int cx88_set_scale(struct cx88_core *core, unsigned int width,
460 unsigned int height, enum v4l2_field field);
461extern int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm);
462
463extern struct video_device *cx88_vdev_init(struct cx88_core *core,
464 struct pci_dev *pci,
465 struct video_device *template,
466 char *type);
467extern struct cx88_core* cx88_core_get(struct pci_dev *pci);
468extern void cx88_core_put(struct cx88_core *core,
469 struct pci_dev *pci);
470
471/* ----------------------------------------------------------- */
472/* cx88-vbi.c */
473
474void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
475int cx8800_start_vbi_dma(struct cx8800_dev *dev,
476 struct cx88_dmaqueue *q,
477 struct cx88_buffer *buf);
478int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
479int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
480 struct cx88_dmaqueue *q);
481void cx8800_vbi_timeout(unsigned long data);
482
483extern struct videobuf_queue_ops cx8800_vbi_qops;
484
485/* ----------------------------------------------------------- */
486/* cx88-i2c.c */
487
488extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
489extern void cx88_call_i2c_clients(struct cx88_core *core,
490 unsigned int cmd, void *arg);
491
492
493/* ----------------------------------------------------------- */
494/* cx88-cards.c */
495
496extern struct cx88_board cx88_boards[];
497extern const unsigned int cx88_bcount;
498
499extern struct cx88_subid cx88_subids[];
500extern const unsigned int cx88_idcount;
501
502extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci);
503extern void cx88_card_setup(struct cx88_core *core);
504
505/* ----------------------------------------------------------- */
506/* cx88-tvaudio.c */
507
508#define WW_NONE 1
509#define WW_BTSC 2
510#define WW_NICAM_I 3
511#define WW_NICAM_BGDKL 4
512#define WW_A1 5
513#define WW_A2_BG 6
514#define WW_A2_DK 7
515#define WW_A2_M 8
516#define WW_EIAJ 9
517#define WW_SYSTEM_L_AM 10
518#define WW_I2SPT 11
519#define WW_FM 12
520
521void cx88_set_tvaudio(struct cx88_core *core);
522void cx88_newstation(struct cx88_core *core);
523void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
524void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
525int cx88_audio_thread(void *data);
526
527/* ----------------------------------------------------------- */
528/* cx88-input.c */
529
530int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
531int cx88_ir_fini(struct cx88_core *core);
532void cx88_ir_irq(struct cx88_core *core);
533
534/* ----------------------------------------------------------- */
535/* cx88-mpeg.c */
536
537int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf);
538void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
539void cx8802_cancel_buffers(struct cx8802_dev *dev);
540
541int cx8802_init_common(struct cx8802_dev *dev);
542void cx8802_fini_common(struct cx8802_dev *dev);
543
544int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
545int cx8802_resume_common(struct pci_dev *pci_dev);
546
547/*
548 * Local variables:
549 * c-basic-offset: 8
550 * End:
551 */
diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c
new file mode 100644
index 000000000000..da9481198c53
--- /dev/null
+++ b/drivers/media/video/dpc7146.c
@@ -0,0 +1,401 @@
1/*
2 dpc7146.c - v4l2 driver for the dpc7146 demonstration board
3
4 Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de>
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
21#define DEBUG_VARIABLE debug
22
23#include <media/saa7146_vv.h>
24#include <linux/video_decoder.h> /* for saa7111a */
25
26#define I2C_SAA7111A 0x24
27
28/* All unused bytes are reserverd. */
29#define SAA711X_CHIP_VERSION 0x00
30#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02
31#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03
32#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04
33#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05
34#define SAA711X_HORIZONTAL_SYNC_START 0x06
35#define SAA711X_HORIZONTAL_SYNC_STOP 0x07
36#define SAA711X_SYNC_CONTROL 0x08
37#define SAA711X_LUMINANCE_CONTROL 0x09
38#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A
39#define SAA711X_LUMINANCE_CONTRAST 0x0B
40#define SAA711X_CHROMA_SATURATION 0x0C
41#define SAA711X_CHROMA_HUE_CONTROL 0x0D
42#define SAA711X_CHROMA_CONTROL 0x0E
43#define SAA711X_FORMAT_DELAY_CONTROL 0x10
44#define SAA711X_OUTPUT_CONTROL_1 0x11
45#define SAA711X_OUTPUT_CONTROL_2 0x12
46#define SAA711X_OUTPUT_CONTROL_3 0x13
47#define SAA711X_V_GATE_1_START 0x15
48#define SAA711X_V_GATE_1_STOP 0x16
49#define SAA711X_V_GATE_1_MSB 0x17
50#define SAA711X_TEXT_SLICER_STATUS 0x1A
51#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B
52#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C
53#define SAA711X_STATUS_BYTE 0x1F
54
55#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
56
57static int debug = 0;
58module_param(debug, int, 0);
59MODULE_PARM_DESC(debug, "debug verbosity");
60
61static int dpc_num = 0;
62
63#define DPC_INPUTS 2
64static struct v4l2_input dpc_inputs[DPC_INPUTS] = {
65 { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
66 { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
67};
68
69#define DPC_AUDIOS 0
70
71static struct saa7146_extension_ioctls ioctls[] = {
72 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
73 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
74 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
75 { VIDIOC_S_STD, SAA7146_AFTER },
76 { 0, 0 }
77};
78
79struct dpc
80{
81 struct video_device *video_dev;
82 struct video_device *vbi_dev;
83
84 struct i2c_adapter i2c_adapter;
85 struct i2c_client *saa7111a;
86
87 int cur_input; /* current input */
88};
89
90/* fixme: add vbi stuff here */
91static int dpc_probe(struct saa7146_dev* dev)
92{
93 struct dpc* dpc = NULL;
94 struct i2c_client *client;
95 struct list_head *item;
96
97 dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
98 if( NULL == dpc ) {
99 printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n");
100 return -ENOMEM;
101 }
102 memset(dpc, 0x0, sizeof(struct dpc));
103
104 /* FIXME: enable i2c-port pins, video-port-pins
105 video port pins should be enabled here ?! */
106 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
107
108 dpc->i2c_adapter = (struct i2c_adapter) {
109 .class = I2C_CLASS_TV_ANALOG,
110 .name = "dpc7146",
111 };
112 saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
113 if(i2c_add_adapter(&dpc->i2c_adapter) < 0) {
114 DEB_S(("cannot register i2c-device. skipping.\n"));
115 kfree(dpc);
116 return -EFAULT;
117 }
118
119 /* loop through all i2c-devices on the bus and look who is there */
120 list_for_each(item,&dpc->i2c_adapter.clients) {
121 client = list_entry(item, struct i2c_client, list);
122 if( I2C_SAA7111A == client->addr )
123 dpc->saa7111a = client;
124 }
125
126 /* check if all devices are present */
127 if( 0 == dpc->saa7111a ) {
128 DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));
129 i2c_del_adapter(&dpc->i2c_adapter);
130 kfree(dpc);
131 return -ENODEV;
132 }
133
134 /* all devices are present, probe was successful */
135 DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n"));
136
137 /* we store the pointer in our private data field */
138 dev->ext_priv = dpc;
139
140 return 0;
141}
142
143/* bring hardware to a sane state. this has to be done, just in case someone
144 wants to capture from this device before it has been properly initialized.
145 the capture engine would badly fail, because no valid signal arrives on the
146 saa7146, thus leading to timeouts and stuff. */
147static int dpc_init_done(struct saa7146_dev* dev)
148{
149 struct dpc* dpc = (struct dpc*)dev->ext_priv;
150
151 DEB_D(("dpc_v4l2.o: dpc_init_done called.\n"));
152
153 /* initialize the helper ics to useful values */
154 i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11);
155
156 i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0);
157 i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30);
158 i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00);
159 i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00);
160 i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde);
161 i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad);
162 i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8);
163 i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00);
164 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80);
165 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47);
166 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40);
167 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00);
168 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03);
169
170 i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0);
171 i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c);
172 i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1);
173 i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30);
174
175 i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81);
176
177 return 0;
178}
179
180static struct saa7146_ext_vv vv_data;
181
182/* this function only gets called when the probing was successful */
183static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
184{
185 struct dpc* dpc = (struct dpc*)dev->ext_priv;
186
187 DEB_D(("dpc_v4l2.o: dpc_attach called.\n"));
188
189 /* checking for i2c-devices can be omitted here, because we
190 already did this in "dpc_vl42_probe" */
191
192 saa7146_vv_init(dev,&vv_data);
193 if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
194 ERR(("cannot register capture v4l2 device. skipping.\n"));
195 return -1;
196 }
197
198 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
199 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
200 if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) {
201 ERR(("cannot register vbi v4l2 device. skipping.\n"));
202 }
203 }
204
205 i2c_use_client(dpc->saa7111a);
206
207 printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num);
208 dpc_num++;
209
210 /* the rest */
211 dpc->cur_input = 0;
212 dpc_init_done(dev);
213
214 return 0;
215}
216
217static int dpc_detach(struct saa7146_dev* dev)
218{
219 struct dpc* dpc = (struct dpc*)dev->ext_priv;
220
221 DEB_EE(("dev:%p\n",dev));
222
223 i2c_release_client(dpc->saa7111a);
224
225 saa7146_unregister_device(&dpc->video_dev,dev);
226 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
227 saa7146_unregister_device(&dpc->vbi_dev,dev);
228 }
229 saa7146_vv_release(dev);
230
231 dpc_num--;
232
233 i2c_del_adapter(&dpc->i2c_adapter);
234 kfree(dpc);
235 return 0;
236}
237
238#ifdef axa
239int dpc_vbi_bypass(struct saa7146_dev* dev)
240{
241 struct dpc* dpc = (struct dpc*)dev->ext_priv;
242
243 int i = 1;
244
245 /* switch bypass in saa7111a */
246 if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) {
247 printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n");
248 return -1;
249 }
250
251 return 0;
252}
253#endif
254
255static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
256{
257 struct saa7146_dev *dev = fh->dev;
258 struct dpc* dpc = (struct dpc*)dev->ext_priv;
259/*
260 struct saa7146_vv *vv = dev->vv_data;
261*/
262 switch(cmd)
263 {
264 case VIDIOC_ENUMINPUT:
265 {
266 struct v4l2_input *i = arg;
267 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
268
269 if( i->index < 0 || i->index >= DPC_INPUTS) {
270 return -EINVAL;
271 }
272
273 memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input));
274
275 DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index));
276 return 0;
277 }
278 case VIDIOC_G_INPUT:
279 {
280 int *input = (int *)arg;
281 *input = dpc->cur_input;
282
283 DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input));
284 return 0;
285 }
286 case VIDIOC_S_INPUT:
287 {
288 int input = *(int *)arg;
289
290 if (input < 0 || input >= DPC_INPUTS) {
291 return -EINVAL;
292 }
293
294 dpc->cur_input = input;
295
296 /* fixme: switch input here, switch audio, too! */
297// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
298 printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n");
299
300 return 0;
301 }
302 default:
303/*
304 DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n"));
305*/
306 return -ENOIOCTLCMD;
307 }
308 return 0;
309}
310
311static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
312{
313 return 0;
314}
315
316static struct saa7146_standard standard[] = {
317 {
318 .name = "PAL", .id = V4L2_STD_PAL,
319 .v_offset = 0x17, .v_field = 288,
320 .h_offset = 0x14, .h_pixels = 680,
321 .v_max_out = 576, .h_max_out = 768,
322 }, {
323 .name = "NTSC", .id = V4L2_STD_NTSC,
324 .v_offset = 0x16, .v_field = 240,
325 .h_offset = 0x06, .h_pixels = 708,
326 .v_max_out = 480, .h_max_out = 640,
327 }, {
328 .name = "SECAM", .id = V4L2_STD_SECAM,
329 .v_offset = 0x14, .v_field = 288,
330 .h_offset = 0x14, .h_pixels = 720,
331 .v_max_out = 576, .h_max_out = 768,
332 }
333};
334
335static struct saa7146_extension extension;
336
337static struct saa7146_pci_extension_data dpc = {
338 .ext_priv = "Multimedia eXtension Board",
339 .ext = &extension,
340};
341
342static struct pci_device_id pci_tbl[] = {
343 {
344 .vendor = PCI_VENDOR_ID_PHILIPS,
345 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
346 .subvendor = 0x0000,
347 .subdevice = 0x0000,
348 .driver_data = (unsigned long)&dpc,
349 }, {
350 .vendor = 0,
351 }
352};
353
354MODULE_DEVICE_TABLE(pci, pci_tbl);
355
356static struct saa7146_ext_vv vv_data = {
357 .inputs = DPC_INPUTS,
358 .capabilities = V4L2_CAP_VBI_CAPTURE,
359 .stds = &standard[0],
360 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
361 .std_callback = &std_callback,
362 .ioctls = &ioctls[0],
363 .ioctl = dpc_ioctl,
364};
365
366static struct saa7146_extension extension = {
367 .name = "dpc7146 demonstration board",
368 .flags = SAA7146_USE_I2C_IRQ,
369
370 .pci_tbl = &pci_tbl[0],
371 .module = THIS_MODULE,
372
373 .probe = dpc_probe,
374 .attach = dpc_attach,
375 .detach = dpc_detach,
376
377 .irq_mask = 0,
378 .irq_func = NULL,
379};
380
381static int __init dpc_init_module(void)
382{
383 if( 0 != saa7146_register_extension(&extension)) {
384 DEB_S(("failed to register extension.\n"));
385 return -ENODEV;
386 }
387
388 return 0;
389}
390
391static void __exit dpc_cleanup_module(void)
392{
393 saa7146_unregister_extension(&extension);
394}
395
396module_init(dpc_init_module);
397module_exit(dpc_cleanup_module);
398
399MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'");
400MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
401MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
new file mode 100644
index 000000000000..c9b00eafefde
--- /dev/null
+++ b/drivers/media/video/hexium_gemini.c
@@ -0,0 +1,556 @@
1/*
2 hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
3
4 Visit http://www.mihu.de/linux/saa7146/ and follow the link
5 to "hexium" for further details about this card.
6
7 Copyright (C) 2003 Michael Hunold <michael@mihu.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#define DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27
28static int debug = 0;
29module_param(debug, int, 0);
30MODULE_PARM_DESC(debug, "debug verbosity");
31
32/* global variables */
33static int hexium_num = 0;
34
35#define HEXIUM_GEMINI 4
36#define HEXIUM_GEMINI_DUAL 5
37
38#define HEXIUM_INPUTS 9
39static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
40 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
41 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
42 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
43 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
44 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
45 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
46 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
47 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
48 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
49};
50
51#define HEXIUM_AUDIOS 0
52
53struct hexium_data
54{
55 s8 adr;
56 u8 byte;
57};
58
59static struct saa7146_extension_ioctls ioctls[] = {
60 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
61 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { VIDIOC_G_CTRL, SAA7146_BEFORE },
66 { VIDIOC_S_CTRL, SAA7146_BEFORE },
67 { 0, 0 }
68};
69
70#define HEXIUM_CONTROLS 1
71static struct v4l2_queryctrl hexium_controls[] = {
72 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
73};
74
75#define HEXIUM_GEMINI_V_1_0 1
76#define HEXIUM_GEMINI_DUAL_V_1_0 2
77
78struct hexium
79{
80 int type;
81
82 struct video_device *video_dev;
83 struct i2c_adapter i2c_adapter;
84
85 int cur_input; /* current input */
86 v4l2_std_id cur_std; /* current standard */
87 int cur_bw; /* current black/white status */
88};
89
90/* Samsung KS0127B decoder default registers */
91static u8 hexium_ks0127b[0x100]={
92/*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10,
93/*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06,
94/*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00,
95/*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22,
96/*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97/*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00,
98/*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80,
99/*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00,
100/*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
101/*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
102/*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103/*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104/*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
105/*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106/*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107/*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108/*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109/*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110/*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111/*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112/*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113/*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114/*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115/*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116/*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117/*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118/*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119/*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120/*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121/*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122/*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123/*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
124};
125
126static struct hexium_data hexium_pal[] = {
127 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
128};
129
130static struct hexium_data hexium_pal_bw[] = {
131 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
132};
133
134static struct hexium_data hexium_ntsc[] = {
135 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
136};
137
138static struct hexium_data hexium_ntsc_bw[] = {
139 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
140};
141
142static struct hexium_data hexium_secam[] = {
143 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
144};
145
146static struct hexium_data hexium_input_select[] = {
147 { 0x02, 0x60 },
148 { 0x02, 0x64 },
149 { 0x02, 0x61 },
150 { 0x02, 0x65 },
151 { 0x02, 0x62 },
152 { 0x02, 0x66 },
153 { 0x02, 0x68 },
154 { 0x02, 0x69 },
155 { 0x02, 0x6A },
156};
157
158/* fixme: h_offset = 0 for Hexium Gemini *Dual*, which
159 are currently *not* supported*/
160static struct saa7146_standard hexium_standards[] = {
161 {
162 .name = "PAL", .id = V4L2_STD_PAL,
163 .v_offset = 28, .v_field = 288,
164 .h_offset = 1, .h_pixels = 680,
165 .v_max_out = 576, .h_max_out = 768,
166 }, {
167 .name = "NTSC", .id = V4L2_STD_NTSC,
168 .v_offset = 28, .v_field = 240,
169 .h_offset = 1, .h_pixels = 640,
170 .v_max_out = 480, .h_max_out = 640,
171 }, {
172 .name = "SECAM", .id = V4L2_STD_SECAM,
173 .v_offset = 28, .v_field = 288,
174 .h_offset = 1, .h_pixels = 720,
175 .v_max_out = 576, .h_max_out = 768,
176 }
177};
178
179/* bring hardware to a sane state. this has to be done, just in case someone
180 wants to capture from this device before it has been properly initialized.
181 the capture engine would badly fail, because no valid signal arrives on the
182 saa7146, thus leading to timeouts and stuff. */
183static int hexium_init_done(struct saa7146_dev *dev)
184{
185 struct hexium *hexium = (struct hexium *) dev->ext_priv;
186 union i2c_smbus_data data;
187 int i = 0;
188
189 DEB_D(("hexium_init_done called.\n"));
190
191 /* initialize the helper ics to useful values */
192 for (i = 0; i < sizeof(hexium_ks0127b); i++) {
193 data.byte = hexium_ks0127b[i];
194 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
195 printk("hexium_gemini: hexium_init_done() failed for address 0x%02x\n", i);
196 }
197 }
198
199 return 0;
200}
201
202static int hexium_set_input(struct hexium *hexium, int input)
203{
204 union i2c_smbus_data data;
205
206 DEB_D((".\n"));
207
208 data.byte = hexium_input_select[input].byte;
209 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) {
210 return -1;
211 }
212
213 return 0;
214}
215
216static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
217{
218 union i2c_smbus_data data;
219 int i = 0;
220
221 DEB_D((".\n"));
222
223 while (vdec[i].adr != -1) {
224 data.byte = vdec[i].byte;
225 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) {
226 printk("hexium_init_done: hexium_set_standard() failed for address 0x%02x\n", i);
227 return -1;
228 }
229 i++;
230 }
231 return 0;
232}
233
234static struct saa7146_ext_vv vv_data;
235
236/* this function only gets called when the probing was successful */
237static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
238{
239 struct hexium *hexium = (struct hexium *) dev->ext_priv;
240
241 DEB_EE((".\n"));
242
243 hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
244 if (NULL == hexium) {
245 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
246 return -ENOMEM;
247 }
248 memset(hexium, 0x0, sizeof(struct hexium));
249 dev->ext_priv = hexium;
250
251 /* enable i2c-port pins */
252 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
253
254 hexium->i2c_adapter = (struct i2c_adapter) {
255 .class = I2C_CLASS_TV_ANALOG,
256 .name = "hexium gemini",
257 };
258 saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
259 if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
260 DEB_S(("cannot register i2c-device. skipping.\n"));
261 kfree(hexium);
262 return -EFAULT;
263 }
264
265 /* set HWControl GPIO number 2 */
266 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
267
268 saa7146_write(dev, DD1_INIT, 0x07000700);
269 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
270 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
271
272 /* the rest */
273 hexium->cur_input = 0;
274 hexium_init_done(dev);
275
276 hexium_set_standard(hexium, hexium_pal);
277 hexium->cur_std = V4L2_STD_PAL;
278
279 hexium_set_input(hexium, 0);
280 hexium->cur_input = 0;
281
282 saa7146_vv_init(dev, &vv_data);
283 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
284 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
285 return -1;
286 }
287
288 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
289 hexium_num++;
290
291 return 0;
292}
293
294static int hexium_detach(struct saa7146_dev *dev)
295{
296 struct hexium *hexium = (struct hexium *) dev->ext_priv;
297
298 DEB_EE(("dev:%p\n", dev));
299
300 saa7146_unregister_device(&hexium->video_dev, dev);
301 saa7146_vv_release(dev);
302
303 hexium_num--;
304
305 i2c_del_adapter(&hexium->i2c_adapter);
306 kfree(hexium);
307 return 0;
308}
309
310static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
311{
312 struct saa7146_dev *dev = fh->dev;
313 struct hexium *hexium = (struct hexium *) dev->ext_priv;
314/*
315 struct saa7146_vv *vv = dev->vv_data;
316*/
317 switch (cmd) {
318 case VIDIOC_ENUMINPUT:
319 {
320 struct v4l2_input *i = arg;
321 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
322
323 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
324 return -EINVAL;
325 }
326
327 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
328
329 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
330 return 0;
331 }
332 case VIDIOC_G_INPUT:
333 {
334 int *input = (int *) arg;
335 *input = hexium->cur_input;
336
337 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
338 return 0;
339 }
340 case VIDIOC_S_INPUT:
341 {
342 int input = *(int *) arg;
343
344 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
345
346 if (input < 0 || input >= HEXIUM_INPUTS) {
347 return -EINVAL;
348 }
349
350 hexium->cur_input = input;
351 hexium_set_input(hexium, input);
352
353 return 0;
354 }
355 /* the saa7146 provides some controls (brightness, contrast, saturation)
356 which gets registered *after* this function. because of this we have
357 to return with a value != 0 even if the function succeded.. */
358 case VIDIOC_QUERYCTRL:
359 {
360 struct v4l2_queryctrl *qc = arg;
361 int i;
362
363 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
364 if (hexium_controls[i].id == qc->id) {
365 *qc = hexium_controls[i];
366 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
367 return 0;
368 }
369 }
370 return -EAGAIN;
371 }
372 case VIDIOC_G_CTRL:
373 {
374 struct v4l2_control *vc = arg;
375 int i;
376
377 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
378 if (hexium_controls[i].id == vc->id) {
379 break;
380 }
381 }
382
383 if (i < 0) {
384 return -EAGAIN;
385 }
386
387 switch (vc->id) {
388 case V4L2_CID_PRIVATE_BASE:{
389 vc->value = hexium->cur_bw;
390 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
391 return 0;
392 }
393 }
394 return -EINVAL;
395 }
396
397 case VIDIOC_S_CTRL:
398 {
399 struct v4l2_control *vc = arg;
400 int i = 0;
401
402 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
403 if (hexium_controls[i].id == vc->id) {
404 break;
405 }
406 }
407
408 if (i < 0) {
409 return -EAGAIN;
410 }
411
412 switch (vc->id) {
413 case V4L2_CID_PRIVATE_BASE:{
414 hexium->cur_bw = vc->value;
415 break;
416 }
417 }
418
419 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
420
421 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
422 hexium_set_standard(hexium, hexium_pal);
423 return 0;
424 }
425 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
426 hexium_set_standard(hexium, hexium_ntsc);
427 return 0;
428 }
429 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
430 hexium_set_standard(hexium, hexium_secam);
431 return 0;
432 }
433 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
434 hexium_set_standard(hexium, hexium_pal_bw);
435 return 0;
436 }
437 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
438 hexium_set_standard(hexium, hexium_ntsc_bw);
439 return 0;
440 }
441 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
442 /* fixme: is there no bw secam mode? */
443 return -EINVAL;
444 }
445
446 return -EINVAL;
447 }
448 default:
449/*
450 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
451*/
452 return -ENOIOCTLCMD;
453 }
454 return 0;
455}
456
457static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
458{
459 struct hexium *hexium = (struct hexium *) dev->ext_priv;
460
461 if (V4L2_STD_PAL == std->id) {
462 hexium_set_standard(hexium, hexium_pal);
463 hexium->cur_std = V4L2_STD_PAL;
464 return 0;
465 } else if (V4L2_STD_NTSC == std->id) {
466 hexium_set_standard(hexium, hexium_ntsc);
467 hexium->cur_std = V4L2_STD_NTSC;
468 return 0;
469 } else if (V4L2_STD_SECAM == std->id) {
470 hexium_set_standard(hexium, hexium_secam);
471 hexium->cur_std = V4L2_STD_SECAM;
472 return 0;
473 }
474
475 return -1;
476}
477
478static struct saa7146_extension hexium_extension;
479
480static struct saa7146_pci_extension_data hexium_gemini_4bnc = {
481 .ext_priv = "Hexium Gemini (4 BNC)",
482 .ext = &hexium_extension,
483};
484
485static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
486 .ext_priv = "Hexium Gemini Dual (4 BNC)",
487 .ext = &hexium_extension,
488};
489
490static struct pci_device_id pci_tbl[] = {
491 {
492 .vendor = PCI_VENDOR_ID_PHILIPS,
493 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
494 .subvendor = 0x17c8,
495 .subdevice = 0x2401,
496 .driver_data = (unsigned long) &hexium_gemini_4bnc,
497 },
498 {
499 .vendor = PCI_VENDOR_ID_PHILIPS,
500 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
501 .subvendor = 0x17c8,
502 .subdevice = 0x2402,
503 .driver_data = (unsigned long) &hexium_gemini_dual_4bnc,
504 },
505 {
506 .vendor = 0,
507 }
508};
509
510MODULE_DEVICE_TABLE(pci, pci_tbl);
511
512static struct saa7146_ext_vv vv_data = {
513 .inputs = HEXIUM_INPUTS,
514 .capabilities = 0,
515 .stds = &hexium_standards[0],
516 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
517 .std_callback = &std_callback,
518 .ioctls = &ioctls[0],
519 .ioctl = hexium_ioctl,
520};
521
522static struct saa7146_extension hexium_extension = {
523 .name = "hexium gemini",
524 .flags = SAA7146_USE_I2C_IRQ,
525
526 .pci_tbl = &pci_tbl[0],
527 .module = THIS_MODULE,
528
529 .attach = hexium_attach,
530 .detach = hexium_detach,
531
532 .irq_mask = 0,
533 .irq_func = NULL,
534};
535
536static int __init hexium_init_module(void)
537{
538 if (0 != saa7146_register_extension(&hexium_extension)) {
539 DEB_S(("failed to register extension.\n"));
540 return -ENODEV;
541 }
542
543 return 0;
544}
545
546static void __exit hexium_cleanup_module(void)
547{
548 saa7146_unregister_extension(&hexium_extension);
549}
550
551module_init(hexium_init_module);
552module_exit(hexium_cleanup_module);
553
554MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards");
555MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
556MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
new file mode 100644
index 000000000000..42a9414155c3
--- /dev/null
+++ b/drivers/media/video/hexium_orion.c
@@ -0,0 +1,522 @@
1/*
2 hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards
3
4 Visit http://www.mihu.de/linux/saa7146/ and follow the link
5 to "hexium" for further details about this card.
6
7 Copyright (C) 2003 Michael Hunold <michael@mihu.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#define DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27
28static int debug = 0;
29module_param(debug, int, 0);
30MODULE_PARM_DESC(debug, "debug verbosity");
31
32/* global variables */
33static int hexium_num = 0;
34
35#define HEXIUM_HV_PCI6_ORION 1
36#define HEXIUM_ORION_1SVHS_3BNC 2
37#define HEXIUM_ORION_4BNC 3
38
39#define HEXIUM_INPUTS 9
40static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
41 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
42 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
43 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
44 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
45 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
46 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
47 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
48 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
49 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
50};
51
52#define HEXIUM_AUDIOS 0
53
54struct hexium_data
55{
56 s8 adr;
57 u8 byte;
58};
59
60static struct saa7146_extension_ioctls ioctls[] = {
61 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { 0, 0 }
66};
67
68struct hexium
69{
70 int type;
71 struct video_device *video_dev;
72 struct i2c_adapter i2c_adapter;
73
74 int cur_input; /* current input */
75};
76
77/* Philips SAA7110 decoder default registers */
78static u8 hexium_saa7110[53]={
79/*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00,
80/*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90,
81/*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA,
82/*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,
83/*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F,
84/*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03,
85/*30*/ 0x44,0x75,0x01,0x8C,0x03
86};
87
88static struct {
89 struct hexium_data data[8];
90} hexium_input_select[] = {
91{
92 { /* cvbs 1 */
93 { 0x06, 0x00 },
94 { 0x20, 0xD9 },
95 { 0x21, 0x17 }, // 0x16,
96 { 0x22, 0x40 },
97 { 0x2C, 0x03 },
98 { 0x30, 0x44 },
99 { 0x31, 0x75 }, // ??
100 { 0x21, 0x16 }, // 0x03,
101 }
102}, {
103 { /* cvbs 2 */
104 { 0x06, 0x00 },
105 { 0x20, 0x78 },
106 { 0x21, 0x07 }, // 0x03,
107 { 0x22, 0xD2 },
108 { 0x2C, 0x83 },
109 { 0x30, 0x60 },
110 { 0x31, 0xB5 }, // ?
111 { 0x21, 0x03 },
112 }
113}, {
114 { /* cvbs 3 */
115 { 0x06, 0x00 },
116 { 0x20, 0xBA },
117 { 0x21, 0x07 }, // 0x05,
118 { 0x22, 0x91 },
119 { 0x2C, 0x03 },
120 { 0x30, 0x60 },
121 { 0x31, 0xB5 }, // ??
122 { 0x21, 0x05 }, // 0x03,
123 }
124}, {
125 { /* cvbs 4 */
126 { 0x06, 0x00 },
127 { 0x20, 0xD8 },
128 { 0x21, 0x17 }, // 0x16,
129 { 0x22, 0x40 },
130 { 0x2C, 0x03 },
131 { 0x30, 0x44 },
132 { 0x31, 0x75 }, // ??
133 { 0x21, 0x16 }, // 0x03,
134 }
135}, {
136 { /* cvbs 5 */
137 { 0x06, 0x00 },
138 { 0x20, 0xB8 },
139 { 0x21, 0x07 }, // 0x05,
140 { 0x22, 0x91 },
141 { 0x2C, 0x03 },
142 { 0x30, 0x60 },
143 { 0x31, 0xB5 }, // ??
144 { 0x21, 0x05 }, // 0x03,
145 }
146}, {
147 { /* cvbs 6 */
148 { 0x06, 0x00 },
149 { 0x20, 0x7C },
150 { 0x21, 0x07 }, // 0x03
151 { 0x22, 0xD2 },
152 { 0x2C, 0x83 },
153 { 0x30, 0x60 },
154 { 0x31, 0xB5 }, // ??
155 { 0x21, 0x03 },
156 }
157}, {
158 { /* y/c 1 */
159 { 0x06, 0x80 },
160 { 0x20, 0x59 },
161 { 0x21, 0x17 },
162 { 0x22, 0x42 },
163 { 0x2C, 0xA3 },
164 { 0x30, 0x44 },
165 { 0x31, 0x75 },
166 { 0x21, 0x12 },
167 }
168}, {
169 { /* y/c 2 */
170 { 0x06, 0x80 },
171 { 0x20, 0x9A },
172 { 0x21, 0x17 },
173 { 0x22, 0xB1 },
174 { 0x2C, 0x13 },
175 { 0x30, 0x60 },
176 { 0x31, 0xB5 },
177 { 0x21, 0x14 },
178 }
179}, {
180 { /* y/c 3 */
181 { 0x06, 0x80 },
182 { 0x20, 0x3C },
183 { 0x21, 0x27 },
184 { 0x22, 0xC1 },
185 { 0x2C, 0x23 },
186 { 0x30, 0x44 },
187 { 0x31, 0x75 },
188 { 0x21, 0x21 },
189 }
190}
191};
192
193static struct saa7146_standard hexium_standards[] = {
194 {
195 .name = "PAL", .id = V4L2_STD_PAL,
196 .v_offset = 16, .v_field = 288,
197 .h_offset = 1, .h_pixels = 680,
198 .v_max_out = 576, .h_max_out = 768,
199 }, {
200 .name = "NTSC", .id = V4L2_STD_NTSC,
201 .v_offset = 16, .v_field = 240,
202 .h_offset = 1, .h_pixels = 640,
203 .v_max_out = 480, .h_max_out = 640,
204 }, {
205 .name = "SECAM", .id = V4L2_STD_SECAM,
206 .v_offset = 16, .v_field = 288,
207 .h_offset = 1, .h_pixels = 720,
208 .v_max_out = 576, .h_max_out = 768,
209 }
210};
211
212/* this is only called for old HV-PCI6/Orion cards
213 without eeprom */
214static int hexium_probe(struct saa7146_dev *dev)
215{
216 struct hexium *hexium = NULL;
217 union i2c_smbus_data data;
218 int err = 0;
219
220 DEB_EE((".\n"));
221
222 /* there are no hexium orion cards with revision 0 saa7146s */
223 if (0 == dev->revision) {
224 return -EFAULT;
225 }
226
227 hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
228 if (NULL == hexium) {
229 printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
230 return -ENOMEM;
231 }
232 memset(hexium, 0x0, sizeof(struct hexium));
233
234 /* enable i2c-port pins */
235 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
236
237 saa7146_write(dev, DD1_INIT, 0x01000100);
238 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
239 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
240
241 hexium->i2c_adapter = (struct i2c_adapter) {
242 .class = I2C_CLASS_TV_ANALOG,
243 .name = "hexium orion",
244 };
245 saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
246 if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
247 DEB_S(("cannot register i2c-device. skipping.\n"));
248 kfree(hexium);
249 return -EFAULT;
250 }
251
252 /* set SAA7110 control GPIO 0 */
253 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
254 /* set HWControl GPIO number 2 */
255 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
256
257 mdelay(10);
258
259 /* detect newer Hexium Orion cards by subsystem ids */
260 if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) {
261 printk("hexium_orion: device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs.\n");
262 /* we store the pointer in our private data field */
263 dev->ext_priv = hexium;
264 hexium->type = HEXIUM_ORION_1SVHS_3BNC;
265 return 0;
266 }
267
268 if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) {
269 printk("hexium_orion: device is a Hexium Orion w/ 4 BNC inputs.\n");
270 /* we store the pointer in our private data field */
271 dev->ext_priv = hexium;
272 hexium->type = HEXIUM_ORION_4BNC;
273 return 0;
274 }
275
276 /* check if this is an old hexium Orion card by looking at
277 a saa7110 at address 0x4e */
278 if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
279 printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n");
280 /* we store the pointer in our private data field */
281 dev->ext_priv = hexium;
282 hexium->type = HEXIUM_HV_PCI6_ORION;
283 return 0;
284 }
285
286 i2c_del_adapter(&hexium->i2c_adapter);
287 kfree(hexium);
288 return -EFAULT;
289}
290
291/* bring hardware to a sane state. this has to be done, just in case someone
292 wants to capture from this device before it has been properly initialized.
293 the capture engine would badly fail, because no valid signal arrives on the
294 saa7146, thus leading to timeouts and stuff. */
295static int hexium_init_done(struct saa7146_dev *dev)
296{
297 struct hexium *hexium = (struct hexium *) dev->ext_priv;
298 union i2c_smbus_data data;
299 int i = 0;
300
301 DEB_D(("hexium_init_done called.\n"));
302
303 /* initialize the helper ics to useful values */
304 for (i = 0; i < sizeof(hexium_saa7110); i++) {
305 data.byte = hexium_saa7110[i];
306 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
307 printk("hexium_orion: failed for address 0x%02x\n", i);
308 }
309 }
310
311 return 0;
312}
313
314static int hexium_set_input(struct hexium *hexium, int input)
315{
316 union i2c_smbus_data data;
317 int i = 0;
318
319 DEB_D((".\n"));
320
321 for (i = 0; i < 8; i++) {
322 int adr = hexium_input_select[input].data[i].adr;
323 data.byte = hexium_input_select[input].data[i].byte;
324 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, adr, I2C_SMBUS_BYTE_DATA, &data)) {
325 return -1;
326 }
327 printk("%d: 0x%02x => 0x%02x\n",input, adr,data.byte);
328 }
329
330 return 0;
331}
332
333static struct saa7146_ext_vv vv_data;
334
335/* this function only gets called when the probing was successful */
336static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
337{
338 struct hexium *hexium = (struct hexium *) dev->ext_priv;
339
340 DEB_EE((".\n"));
341
342 saa7146_vv_init(dev, &vv_data);
343 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
344 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
345 return -1;
346 }
347
348 printk("hexium_orion: found 'hexium orion' frame grabber-%d.\n", hexium_num);
349 hexium_num++;
350
351 /* the rest */
352 hexium->cur_input = 0;
353 hexium_init_done(dev);
354
355 return 0;
356}
357
358static int hexium_detach(struct saa7146_dev *dev)
359{
360 struct hexium *hexium = (struct hexium *) dev->ext_priv;
361
362 DEB_EE(("dev:%p\n", dev));
363
364 saa7146_unregister_device(&hexium->video_dev, dev);
365 saa7146_vv_release(dev);
366
367 hexium_num--;
368
369 i2c_del_adapter(&hexium->i2c_adapter);
370 kfree(hexium);
371 return 0;
372}
373
374static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
375{
376 struct saa7146_dev *dev = fh->dev;
377 struct hexium *hexium = (struct hexium *) dev->ext_priv;
378/*
379 struct saa7146_vv *vv = dev->vv_data;
380*/
381 switch (cmd) {
382 case VIDIOC_ENUMINPUT:
383 {
384 struct v4l2_input *i = arg;
385 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
386
387 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
388 return -EINVAL;
389 }
390
391 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
392
393 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
394 return 0;
395 }
396 case VIDIOC_G_INPUT:
397 {
398 int *input = (int *) arg;
399 *input = hexium->cur_input;
400
401 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
402 return 0;
403 }
404 case VIDIOC_S_INPUT:
405 {
406 int input = *(int *) arg;
407
408 if (input < 0 || input >= HEXIUM_INPUTS) {
409 return -EINVAL;
410 }
411
412 hexium->cur_input = input;
413 hexium_set_input(hexium, input);
414
415 return 0;
416 }
417 default:
418/*
419 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
420*/
421 return -ENOIOCTLCMD;
422 }
423 return 0;
424}
425
426static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
427{
428 return 0;
429}
430
431static struct saa7146_extension extension;
432
433static struct saa7146_pci_extension_data hexium_hv_pci6 = {
434 .ext_priv = "Hexium HV-PCI6 / Orion",
435 .ext = &extension,
436};
437
438static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = {
439 .ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)",
440 .ext = &extension,
441};
442
443static struct saa7146_pci_extension_data hexium_orion_4bnc = {
444 .ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)",
445 .ext = &extension,
446};
447
448static struct pci_device_id pci_tbl[] = {
449 {
450 .vendor = PCI_VENDOR_ID_PHILIPS,
451 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
452 .subvendor = 0x0000,
453 .subdevice = 0x0000,
454 .driver_data = (unsigned long) &hexium_hv_pci6,
455 },
456 {
457 .vendor = PCI_VENDOR_ID_PHILIPS,
458 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
459 .subvendor = 0x17c8,
460 .subdevice = 0x0101,
461 .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc,
462 },
463 {
464 .vendor = PCI_VENDOR_ID_PHILIPS,
465 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
466 .subvendor = 0x17c8,
467 .subdevice = 0x2101,
468 .driver_data = (unsigned long) &hexium_orion_4bnc,
469 },
470 {
471 .vendor = 0,
472 }
473};
474
475MODULE_DEVICE_TABLE(pci, pci_tbl);
476
477static struct saa7146_ext_vv vv_data = {
478 .inputs = HEXIUM_INPUTS,
479 .capabilities = 0,
480 .stds = &hexium_standards[0],
481 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
482 .std_callback = &std_callback,
483 .ioctls = &ioctls[0],
484 .ioctl = hexium_ioctl,
485};
486
487static struct saa7146_extension extension = {
488 .name = "hexium HV-PCI6/Orion",
489 .flags = 0, // SAA7146_USE_I2C_IRQ,
490
491 .pci_tbl = &pci_tbl[0],
492 .module = THIS_MODULE,
493
494 .probe = hexium_probe,
495 .attach = hexium_attach,
496 .detach = hexium_detach,
497
498 .irq_mask = 0,
499 .irq_func = NULL,
500};
501
502static int __init hexium_init_module(void)
503{
504 if (0 != saa7146_register_extension(&extension)) {
505 DEB_S(("failed to register extension.\n"));
506 return -ENODEV;
507 }
508
509 return 0;
510}
511
512static void __exit hexium_cleanup_module(void)
513{
514 saa7146_unregister_extension(&extension);
515}
516
517module_init(hexium_init_module);
518module_exit(hexium_cleanup_module);
519
520MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards");
521MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
522MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/ibmmpeg2.h b/drivers/media/video/ibmmpeg2.h
new file mode 100644
index 000000000000..68e10387c498
--- /dev/null
+++ b/drivers/media/video/ibmmpeg2.h
@@ -0,0 +1,94 @@
1/* ibmmpeg2.h - IBM MPEGCD21 definitions */
2
3#ifndef __IBM_MPEG2__
4#define __IBM_MPEG2__
5
6/* Define all MPEG Decoder registers */
7/* Chip Control and Status */
8#define IBM_MP2_CHIP_CONTROL 0x200*2
9#define IBM_MP2_CHIP_MODE 0x201*2
10/* Timer Control and Status */
11#define IBM_MP2_SYNC_STC2 0x202*2
12#define IBM_MP2_SYNC_STC1 0x203*2
13#define IBM_MP2_SYNC_STC0 0x204*2
14#define IBM_MP2_SYNC_PTS2 0x205*2
15#define IBM_MP2_SYNC_PTS1 0x206*2
16#define IBM_MP2_SYNC_PTS0 0x207*2
17/* Video FIFO Control */
18#define IBM_MP2_FIFO 0x208*2
19#define IBM_MP2_FIFOW 0x100*2
20#define IBM_MP2_FIFO_STAT 0x209*2
21#define IBM_MP2_RB_THRESHOLD 0x22b*2
22/* Command buffer */
23#define IBM_MP2_COMMAND 0x20a*2
24#define IBM_MP2_CMD_DATA 0x20b*2
25#define IBM_MP2_CMD_STAT 0x20c*2
26#define IBM_MP2_CMD_ADDR 0x20d*2
27/* Internal Processor Control and Status */
28#define IBM_MP2_PROC_IADDR 0x20e*2
29#define IBM_MP2_PROC_IDATA 0x20f*2
30#define IBM_MP2_WR_PROT 0x235*2
31/* DRAM Access */
32#define IBM_MP2_DRAM_ADDR 0x210*2
33#define IBM_MP2_DRAM_DATA 0x212*2
34#define IBM_MP2_DRAM_CMD_STAT 0x213*2
35#define IBM_MP2_BLOCK_SIZE 0x23b*2
36#define IBM_MP2_SRC_ADDR 0x23c*2
37/* Onscreen Display */
38#define IBM_MP2_OSD_ADDR 0x214*2
39#define IBM_MP2_OSD_DATA 0x215*2
40#define IBM_MP2_OSD_MODE 0x217*2
41#define IBM_MP2_OSD_LINK_ADDR 0x229*2
42#define IBM_MP2_OSD_SIZE 0x22a*2
43/* Interrupt Control */
44#define IBM_MP2_HOST_INT 0x218*2
45#define IBM_MP2_MASK0 0x219*2
46#define IBM_MP2_HOST_INT1 0x23e*2
47#define IBM_MP2_MASK1 0x23f*2
48/* Audio Control */
49#define IBM_MP2_AUD_IADDR 0x21a*2
50#define IBM_MP2_AUD_IDATA 0x21b*2
51#define IBM_MP2_AUD_FIFO 0x21c*2
52#define IBM_MP2_AUD_FIFOW 0x101*2
53#define IBM_MP2_AUD_CTL 0x21d*2
54#define IBM_MP2_BEEP_CTL 0x21e*2
55#define IBM_MP2_FRNT_ATTEN 0x22d*2
56/* Display Control */
57#define IBM_MP2_DISP_MODE 0x220*2
58#define IBM_MP2_DISP_DLY 0x221*2
59#define IBM_MP2_VBI_CTL 0x222*2
60#define IBM_MP2_DISP_LBOR 0x223*2
61#define IBM_MP2_DISP_TBOR 0x224*2
62/* Polarity Control */
63#define IBM_MP2_INFC_CTL 0x22c*2
64
65/* control commands */
66#define IBM_MP2_PLAY 0
67#define IBM_MP2_PAUSE 1
68#define IBM_MP2_SINGLE_FRAME 2
69#define IBM_MP2_FAST_FORWARD 3
70#define IBM_MP2_SLOW_MOTION 4
71#define IBM_MP2_IMED_NORM_PLAY 5
72#define IBM_MP2_RESET_WINDOW 6
73#define IBM_MP2_FREEZE_FRAME 7
74#define IBM_MP2_RESET_VID_RATE 8
75#define IBM_MP2_CONFIG_DECODER 9
76#define IBM_MP2_CHANNEL_SWITCH 10
77#define IBM_MP2_RESET_AUD_RATE 11
78#define IBM_MP2_PRE_OP_CHN_SW 12
79#define IBM_MP2_SET_STILL_MODE 14
80
81/* Define Xilinx FPGA Internal Registers */
82
83/* general control register 0 */
84#define XILINX_CTL0 0x600
85/* genlock delay resister 1 */
86#define XILINX_GLDELAY 0x602
87/* send 16 bits to CS3310 port */
88#define XILINX_CS3310 0x604
89/* send 16 bits to CS3310 and complete */
90#define XILINX_CS3310_CMPLT 0x60c
91/* pulse width modulator control */
92#define XILINX_PWM 0x606
93
94#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
new file mode 100644
index 000000000000..ab6620de4b3b
--- /dev/null
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -0,0 +1,444 @@
1/*
2 * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $
3 *
4 * Copyright (c) 2003 Gerd Knorr
5 * Copyright (c) 2003 Pavel Machek
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/input.h>
28#include <linux/pci.h>
29
30#include <media/ir-common.h>
31
32#include "bttv.h"
33
34/* ---------------------------------------------------------------------- */
35
36static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
37 [ 34 ] = KEY_KP0,
38 [ 40 ] = KEY_KP1,
39 [ 24 ] = KEY_KP2,
40 [ 56 ] = KEY_KP3,
41 [ 36 ] = KEY_KP4,
42 [ 20 ] = KEY_KP5,
43 [ 52 ] = KEY_KP6,
44 [ 44 ] = KEY_KP7,
45 [ 28 ] = KEY_KP8,
46 [ 60 ] = KEY_KP9,
47
48 [ 48 ] = KEY_EJECTCD, // Unmarked on my controller
49 [ 0 ] = KEY_POWER,
50 [ 18 ] = BTN_LEFT, // DISPLAY/L
51 [ 50 ] = BTN_RIGHT, // LOOP/R
52 [ 10 ] = KEY_MUTE,
53 [ 38 ] = KEY_RECORD,
54 [ 22 ] = KEY_PAUSE,
55 [ 54 ] = KEY_STOP,
56 [ 30 ] = KEY_VOLUMEDOWN,
57 [ 62 ] = KEY_VOLUMEUP,
58
59 [ 32 ] = KEY_TUNER, // TV/FM
60 [ 16 ] = KEY_CD,
61 [ 8 ] = KEY_VIDEO,
62 [ 4 ] = KEY_AUDIO,
63 [ 12 ] = KEY_ZOOM, // full screen
64 [ 2 ] = KEY_INFO, // preview
65 [ 42 ] = KEY_SEARCH, // autoscan
66 [ 26 ] = KEY_STOP, // freeze
67 [ 58 ] = KEY_RECORD, // capture
68 [ 6 ] = KEY_PLAY, // unmarked
69 [ 46 ] = KEY_RED, // unmarked
70 [ 14 ] = KEY_GREEN, // unmarked
71
72 [ 33 ] = KEY_YELLOW, // unmarked
73 [ 17 ] = KEY_CHANNELDOWN,
74 [ 49 ] = KEY_CHANNELUP,
75 [ 1 ] = KEY_BLUE, // unmarked
76};
77
78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
79static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
80 [ 0x28 ] = KEY_KP0, //'0' / 'enter'
81 [ 0x22 ] = KEY_KP1, //'1'
82 [ 0x12 ] = KEY_KP2, //'2' / 'up arrow'
83 [ 0x32 ] = KEY_KP3, //'3'
84 [ 0x24 ] = KEY_KP4, //'4' / 'left arrow'
85 [ 0x14 ] = KEY_KP5, //'5'
86 [ 0x34 ] = KEY_KP6, //'6' / 'right arrow'
87 [ 0x26 ] = KEY_KP7, //'7'
88 [ 0x16 ] = KEY_KP8, //'8' / 'down arrow'
89 [ 0x36 ] = KEY_KP9, //'9'
90
91 [ 0x20 ] = KEY_LIST, // 'source'
92 [ 0x10 ] = KEY_TEXT, // 'teletext'
93 [ 0x00 ] = KEY_POWER, // 'power'
94 [ 0x04 ] = KEY_AUDIO, // 'audio'
95 [ 0x06 ] = KEY_ZOOM, // 'full screen'
96 [ 0x18 ] = KEY_VIDEO, // 'display'
97 [ 0x38 ] = KEY_SEARCH, // 'loop'
98 [ 0x08 ] = KEY_INFO, // 'preview'
99 [ 0x2a ] = KEY_REWIND, // 'backward <<'
100 [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
101 [ 0x3a ] = KEY_RECORD, // 'capture'
102 [ 0x0a ] = KEY_MUTE, // 'mute'
103 [ 0x2c ] = KEY_RECORD, // 'record'
104 [ 0x1c ] = KEY_PAUSE, // 'pause'
105 [ 0x3c ] = KEY_STOP, // 'stop'
106 [ 0x0c ] = KEY_PLAY, // 'play'
107 [ 0x2e ] = KEY_RED, // 'red'
108 [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel'
109 [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok'
110 [ 0x21 ] = KEY_GREEN, // 'green'
111 [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
112 [ 0x31 ] = KEY_CHANNELUP, // 'channel +'
113 [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -'
114 [ 0x3e ] = KEY_VOLUMEUP, // 'volume +'
115};
116
117static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
118 [ 2 ] = KEY_KP0,
119 [ 1 ] = KEY_KP1,
120 [ 11 ] = KEY_KP2,
121 [ 27 ] = KEY_KP3,
122 [ 5 ] = KEY_KP4,
123 [ 9 ] = KEY_KP5,
124 [ 21 ] = KEY_KP6,
125 [ 6 ] = KEY_KP7,
126 [ 10 ] = KEY_KP8,
127 [ 18 ] = KEY_KP9,
128
129 [ 3 ] = KEY_TUNER, // TV/FM
130 [ 7 ] = KEY_SEARCH, // scan
131 [ 28 ] = KEY_ZOOM, // full screen
132 [ 30 ] = KEY_POWER,
133 [ 23 ] = KEY_VOLUMEDOWN,
134 [ 31 ] = KEY_VOLUMEUP,
135 [ 20 ] = KEY_CHANNELDOWN,
136 [ 22 ] = KEY_CHANNELUP,
137 [ 24 ] = KEY_MUTE,
138
139 [ 0 ] = KEY_LIST, // source
140 [ 19 ] = KEY_INFO, // loop
141 [ 16 ] = KEY_LAST, // +100
142 [ 13 ] = KEY_CLEAR, // reset
143 [ 12 ] = BTN_RIGHT, // fun++
144 [ 4 ] = BTN_LEFT, // fun--
145 [ 14 ] = KEY_GOTO, // function
146 [ 15 ] = KEY_STOP, // freeze
147};
148
149/* Attila Kondoros <attila.kondoros@chello.hu> */
150static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
151
152 [ 1 ] = KEY_KP1,
153 [ 2 ] = KEY_KP2,
154 [ 3 ] = KEY_KP3,
155 [ 4 ] = KEY_KP4,
156 [ 5 ] = KEY_KP5,
157 [ 6 ] = KEY_KP6,
158 [ 7 ] = KEY_KP7,
159 [ 8 ] = KEY_KP8,
160 [ 9 ] = KEY_KP9,
161 [ 0 ] = KEY_KP0,
162 [ 23 ] = KEY_LAST, // +100
163 [ 10 ] = KEY_LIST, // recall
164
165
166 [ 28 ] = KEY_TUNER, // TV/FM
167 [ 21 ] = KEY_SEARCH, // scan
168 [ 18 ] = KEY_POWER, // power
169 [ 31 ] = KEY_VOLUMEDOWN, // vol up
170 [ 27 ] = KEY_VOLUMEUP, // vol down
171 [ 30 ] = KEY_CHANNELDOWN, // chn up
172 [ 26 ] = KEY_CHANNELUP, // chn down
173
174 [ 17 ] = KEY_VIDEO, // video
175 [ 15 ] = KEY_ZOOM, // full screen
176 [ 19 ] = KEY_MUTE, // mute/unmute
177 [ 16 ] = KEY_TEXT, // min
178
179 [ 13 ] = KEY_STOP, // freeze
180 [ 14 ] = KEY_RECORD, // record
181 [ 29 ] = KEY_PLAYPAUSE, // stop
182 [ 25 ] = KEY_PLAY, // play
183
184 [ 22 ] = KEY_GOTO, // osd
185 [ 20 ] = KEY_REFRESH, // default
186 [ 12 ] = KEY_KPPLUS, // fine tune >>>>
187 [ 24 ] = KEY_KPMINUS // fine tune <<<<
188};
189
190/* ---------------------------------------------------------------------- */
191
192struct IR {
193 struct bttv_sub_device *sub;
194 struct input_dev input;
195 struct ir_input_state ir;
196 char name[32];
197 char phys[32];
198 u32 mask_keycode;
199 u32 mask_keydown;
200 u32 mask_keyup;
201
202 int polling;
203 u32 last_gpio;
204 struct work_struct work;
205 struct timer_list timer;
206};
207
208static int debug;
209module_param(debug, int, 0644); /* debug level (0,1,2) */
210
211#define DEVNAME "ir-kbd-gpio"
212#define dprintk(fmt, arg...) if (debug) \
213 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
214
215static void ir_irq(struct bttv_sub_device *sub);
216static int ir_probe(struct device *dev);
217static int ir_remove(struct device *dev);
218
219static struct bttv_sub_driver driver = {
220 .drv = {
221 .name = DEVNAME,
222 .probe = ir_probe,
223 .remove = ir_remove,
224 },
225 .gpio_irq = ir_irq,
226};
227
228/* ---------------------------------------------------------------------- */
229
230static void ir_handle_key(struct IR *ir)
231{
232 u32 gpio,data;
233
234 /* read gpio value */
235 gpio = bttv_gpio_read(ir->sub->core);
236 if (ir->polling) {
237 if (ir->last_gpio == gpio)
238 return;
239 ir->last_gpio = gpio;
240 }
241
242 /* extract data */
243 data = ir_extract_bits(gpio, ir->mask_keycode);
244 dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
245 gpio, data,
246 ir->polling ? "poll" : "irq",
247 (gpio & ir->mask_keydown) ? " down" : "",
248 (gpio & ir->mask_keyup) ? " up" : "");
249
250 if (ir->mask_keydown) {
251 /* bit set on keydown */
252 if (gpio & ir->mask_keydown) {
253 ir_input_keydown(&ir->input,&ir->ir,data,data);
254 } else {
255 ir_input_nokey(&ir->input,&ir->ir);
256 }
257
258 } else if (ir->mask_keyup) {
259 /* bit cleared on keydown */
260 if (0 == (gpio & ir->mask_keyup)) {
261 ir_input_keydown(&ir->input,&ir->ir,data,data);
262 } else {
263 ir_input_nokey(&ir->input,&ir->ir);
264 }
265
266 } else {
267 /* can't disturgissh keydown/up :-/ */
268 ir_input_keydown(&ir->input,&ir->ir,data,data);
269 ir_input_nokey(&ir->input,&ir->ir);
270 }
271}
272
273static void ir_irq(struct bttv_sub_device *sub)
274{
275 struct IR *ir = dev_get_drvdata(&sub->dev);
276
277 if (!ir->polling)
278 ir_handle_key(ir);
279}
280
281static void ir_timer(unsigned long data)
282{
283 struct IR *ir = (struct IR*)data;
284
285 schedule_work(&ir->work);
286}
287
288static void ir_work(void *data)
289{
290 struct IR *ir = data;
291 unsigned long timeout;
292
293 ir_handle_key(ir);
294 timeout = jiffies + (ir->polling * HZ / 1000);
295 mod_timer(&ir->timer, timeout);
296}
297
298/* ---------------------------------------------------------------------- */
299
300static int ir_probe(struct device *dev)
301{
302 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
303 struct IR *ir;
304 IR_KEYTAB_TYPE *ir_codes = NULL;
305 int ir_type = IR_TYPE_OTHER;
306
307 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
308 if (NULL == ir)
309 return -ENOMEM;
310 memset(ir,0,sizeof(*ir));
311
312 /* detect & configure */
313 switch (sub->core->type) {
314 case BTTV_AVERMEDIA:
315 case BTTV_AVPHONE98:
316 case BTTV_AVERMEDIA98:
317 ir_codes = ir_codes_avermedia;
318 ir->mask_keycode = 0xf88000;
319 ir->mask_keydown = 0x010000;
320 ir->polling = 50; // ms
321 break;
322
323 case BTTV_AVDVBT_761:
324 case BTTV_AVDVBT_771:
325 ir_codes = ir_codes_avermedia_dvbt;
326 ir->mask_keycode = 0x0f00c0;
327 ir->mask_keydown = 0x000020;
328 ir->polling = 50; // ms
329 break;
330
331 case BTTV_PXELVWPLTVPAK:
332 ir_codes = ir_codes_pixelview;
333 ir->mask_keycode = 0x003e00;
334 ir->mask_keyup = 0x010000;
335 ir->polling = 50; // ms
336 break;
337 case BTTV_PV_BT878P_9B:
338 case BTTV_PV_BT878P_PLUS:
339 ir_codes = ir_codes_pixelview;
340 ir->mask_keycode = 0x001f00;
341 ir->mask_keyup = 0x008000;
342 ir->polling = 50; // ms
343 break;
344
345 case BTTV_WINFAST2000:
346 ir_codes = ir_codes_winfast;
347 ir->mask_keycode = 0x1f8;
348 break;
349 case BTTV_MAGICTVIEW061:
350 case BTTV_MAGICTVIEW063:
351 ir_codes = ir_codes_winfast;
352 ir->mask_keycode = 0x0008e000;
353 ir->mask_keydown = 0x00200000;
354 break;
355 case BTTV_APAC_VIEWCOMP:
356 ir_codes = ir_codes_apac_viewcomp;
357 ir->mask_keycode = 0x001f00;
358 ir->mask_keyup = 0x008000;
359 ir->polling = 50; // ms
360 break;
361 }
362 if (NULL == ir_codes) {
363 kfree(ir);
364 return -ENODEV;
365 }
366
367 /* init hardware-specific stuff */
368 bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
369 ir->sub = sub;
370
371 /* init input device */
372 snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
373 sub->core->type);
374 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
375 pci_name(sub->core->pci));
376
377 ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
378 ir->input.name = ir->name;
379 ir->input.phys = ir->phys;
380 ir->input.id.bustype = BUS_PCI;
381 ir->input.id.version = 1;
382 if (sub->core->pci->subsystem_vendor) {
383 ir->input.id.vendor = sub->core->pci->subsystem_vendor;
384 ir->input.id.product = sub->core->pci->subsystem_device;
385 } else {
386 ir->input.id.vendor = sub->core->pci->vendor;
387 ir->input.id.product = sub->core->pci->device;
388 }
389
390 if (ir->polling) {
391 INIT_WORK(&ir->work, ir_work, ir);
392 init_timer(&ir->timer);
393 ir->timer.function = ir_timer;
394 ir->timer.data = (unsigned long)ir;
395 schedule_work(&ir->work);
396 }
397
398 /* all done */
399 dev_set_drvdata(dev,ir);
400 input_register_device(&ir->input);
401 printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
402
403 return 0;
404}
405
406static int ir_remove(struct device *dev)
407{
408 struct IR *ir = dev_get_drvdata(dev);
409
410 if (ir->polling) {
411 del_timer(&ir->timer);
412 flush_scheduled_work();
413 }
414
415 input_unregister_device(&ir->input);
416 kfree(ir);
417 return 0;
418}
419
420/* ---------------------------------------------------------------------- */
421
422MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
423MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
424MODULE_LICENSE("GPL");
425
426static int ir_init(void)
427{
428 return bttv_sub_register(&driver, "remote");
429}
430
431static void ir_fini(void)
432{
433 bttv_sub_unregister(&driver);
434}
435
436module_init(ir_init);
437module_exit(ir_fini);
438
439
440/*
441 * Local variables:
442 * c-basic-offset: 8
443 * End:
444 */
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
new file mode 100644
index 000000000000..92664f75d327
--- /dev/null
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -0,0 +1,492 @@
1/*
2 * $Id: ir-kbd-i2c.c,v 1.10 2004/12/09 12:51:35 kraxel Exp $
3 *
4 * keyboard input driver for i2c IR remote controls
5 *
6 * Copyright (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
7 * modified for PixelView (BT878P+W/FM) by
8 * Michal Kochanowicz <mkochano@pld.org.pl>
9 * Christoph Bartelmus <lirc@bartelmus.de>
10 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
11 * Ulrich Mueller <ulrich.mueller42@web.de>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/string.h>
35#include <linux/timer.h>
36#include <linux/delay.h>
37#include <linux/errno.h>
38#include <linux/slab.h>
39#include <linux/i2c.h>
40#include <linux/workqueue.h>
41
42#include <asm/semaphore.h>
43
44#include <media/ir-common.h>
45
46/* Mark Phalan <phalanm@o2.ie> */
47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
48 [ 0 ] = KEY_KP0,
49 [ 1 ] = KEY_KP1,
50 [ 2 ] = KEY_KP2,
51 [ 3 ] = KEY_KP3,
52 [ 4 ] = KEY_KP4,
53 [ 5 ] = KEY_KP5,
54 [ 6 ] = KEY_KP6,
55 [ 7 ] = KEY_KP7,
56 [ 8 ] = KEY_KP8,
57 [ 9 ] = KEY_KP9,
58
59 [ 18 ] = KEY_POWER,
60 [ 16 ] = KEY_MUTE,
61 [ 31 ] = KEY_VOLUMEDOWN,
62 [ 27 ] = KEY_VOLUMEUP,
63 [ 26 ] = KEY_CHANNELUP,
64 [ 30 ] = KEY_CHANNELDOWN,
65 [ 14 ] = KEY_PAGEUP,
66 [ 29 ] = KEY_PAGEDOWN,
67 [ 19 ] = KEY_SOUND,
68
69 [ 24 ] = KEY_KPPLUSMINUS, // CH +/-
70 [ 22 ] = KEY_SUBTITLE, // CC
71 [ 13 ] = KEY_TEXT, // TTX
72 [ 11 ] = KEY_TV, // AIR/CBL
73 [ 17 ] = KEY_PC, // PC/TV
74 [ 23 ] = KEY_OK, // CH RTN
75 [ 25 ] = KEY_MODE, // FUNC
76 [ 12 ] = KEY_SEARCH, // AUTOSCAN
77
78 /* Not sure what to do with these ones! */
79 [ 15 ] = KEY_SELECT, // SOURCE
80 [ 10 ] = KEY_KPPLUS, // +100
81 [ 20 ] = KEY_KPEQUAL, // SYNC
82 [ 28 ] = KEY_MEDIA, // PC/TV
83};
84
85static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
86 [ 0x3 ] = KEY_POWER,
87 [ 0x6f ] = KEY_MUTE,
88 [ 0x10 ] = KEY_BACKSPACE, // Recall
89
90 [ 0x11 ] = KEY_KP0,
91 [ 0x4 ] = KEY_KP1,
92 [ 0x5 ] = KEY_KP2,
93 [ 0x6 ] = KEY_KP3,
94 [ 0x8 ] = KEY_KP4,
95 [ 0x9 ] = KEY_KP5,
96 [ 0xa ] = KEY_KP6,
97 [ 0xc ] = KEY_KP7,
98 [ 0xd ] = KEY_KP8,
99 [ 0xe ] = KEY_KP9,
100 [ 0x12 ] = KEY_KPDOT, // 100+
101
102 [ 0x7 ] = KEY_VOLUMEUP,
103 [ 0xb ] = KEY_VOLUMEDOWN,
104 [ 0x1a ] = KEY_KPPLUS,
105 [ 0x18 ] = KEY_KPMINUS,
106 [ 0x15 ] = KEY_UP,
107 [ 0x1d ] = KEY_DOWN,
108 [ 0xf ] = KEY_CHANNELUP,
109 [ 0x13 ] = KEY_CHANNELDOWN,
110 [ 0x48 ] = KEY_ZOOM,
111
112 [ 0x1b ] = KEY_VIDEO, // Video source
113#if 0
114 [ 0x1f ] = KEY_S, // Snapshot
115#endif
116 [ 0x49 ] = KEY_LANGUAGE, // MTS Select
117 [ 0x19 ] = KEY_SEARCH, // Auto Scan
118
119 [ 0x4b ] = KEY_RECORD,
120 [ 0x46 ] = KEY_PLAY,
121 [ 0x45 ] = KEY_PAUSE, // Pause
122 [ 0x44 ] = KEY_STOP,
123#if 0
124 [ 0x43 ] = KEY_T, // Time Shift
125 [ 0x47 ] = KEY_Y, // Time Shift OFF
126 [ 0x4a ] = KEY_O, // TOP
127 [ 0x17 ] = KEY_F, // SURF CH
128#endif
129 [ 0x40 ] = KEY_FORWARD, // Forward ?
130 [ 0x42 ] = KEY_REWIND, // Backward ?
131
132};
133
134struct IR;
135struct IR {
136 struct i2c_client c;
137 struct input_dev input;
138 struct ir_input_state ir;
139
140 struct work_struct work;
141 struct timer_list timer;
142 char phys[32];
143 int (*get_key)(struct IR*, u32*, u32*);
144};
145
146/* ----------------------------------------------------------------------- */
147/* insmod parameters */
148
149static int debug;
150module_param(debug, int, 0644); /* debug level (0,1,2) */
151
152#define DEVNAME "ir-kbd-i2c"
153#define dprintk(level, fmt, arg...) if (debug >= level) \
154 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
155
156/* ----------------------------------------------------------------------- */
157
158static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
159{
160 unsigned char buf[3];
161 int start, toggle, dev, code;
162
163 /* poll IR chip */
164 if (3 != i2c_master_recv(&ir->c,buf,3))
165 return -EIO;
166
167 /* split rc5 data block ... */
168 start = (buf[0] >> 6) & 3;
169 toggle = (buf[0] >> 5) & 1;
170 dev = buf[0] & 0x1f;
171 code = (buf[1] >> 2) & 0x3f;
172
173 if (3 != start)
174 /* no key pressed */
175 return 0;
176 dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
177 start, toggle, dev, code);
178
179 /* return key */
180 *ir_key = code;
181 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
182 return 1;
183}
184
185static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
186{
187 unsigned char b;
188
189 /* poll IR chip */
190 if (1 != i2c_master_recv(&ir->c,&b,1)) {
191 dprintk(1,"read error\n");
192 return -EIO;
193 }
194 *ir_key = b;
195 *ir_raw = b;
196 return 1;
197}
198
199static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
200{
201 unsigned char b;
202
203 /* poll IR chip */
204 if (1 != i2c_master_recv(&ir->c,&b,1)) {
205 dprintk(1,"read error\n");
206 return -EIO;
207 }
208
209 /* ignore 0xaa */
210 if (b==0xaa)
211 return 0;
212 dprintk(2,"key %02x\n", b);
213
214 *ir_key = b;
215 *ir_raw = b;
216 return 1;
217}
218
219static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
220{
221 unsigned char b;
222
223 /* poll IR chip */
224 if (1 != i2c_master_recv(&ir->c,&b,1)) {
225 dprintk(1,"read error\n");
226 return -EIO;
227 }
228
229 /* it seems that 0xFE indicates that a button is still hold
230 down, while 0xFF indicates that no button is hold
231 down. 0xFE sequences are sometimes interrupted by 0xFF */
232
233 dprintk(2,"key %02x\n", b);
234
235 if (b == 0xFF)
236 return 0;
237
238 if (b == 0xFE)
239 /* keep old data */
240 return 1;
241
242 *ir_key = b;
243 *ir_raw = b;
244 return 1;
245}
246
247static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
248{
249 unsigned char b;
250
251 /* poll IR chip */
252 if (1 != i2c_master_recv(&ir->c,&b,1)) {
253 dprintk(1,"read error\n");
254 return -EIO;
255 }
256
257 /* no button press */
258 if (b==0)
259 return 0;
260
261 /* repeating */
262 if (b & 0x80)
263 return 1;
264
265 *ir_key = b;
266 *ir_raw = b;
267 return 1;
268}
269/* ----------------------------------------------------------------------- */
270
271static void ir_key_poll(struct IR *ir)
272{
273 static u32 ir_key, ir_raw;
274 int rc;
275
276 dprintk(2,"ir_poll_key\n");
277 rc = ir->get_key(ir, &ir_key, &ir_raw);
278 if (rc < 0) {
279 dprintk(2,"error\n");
280 return;
281 }
282
283 if (0 == rc) {
284 ir_input_nokey(&ir->input,&ir->ir);
285 } else {
286 ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw);
287 }
288}
289
290static void ir_timer(unsigned long data)
291{
292 struct IR *ir = (struct IR*)data;
293 schedule_work(&ir->work);
294}
295
296static void ir_work(void *data)
297{
298 struct IR *ir = data;
299 ir_key_poll(ir);
300 mod_timer(&ir->timer, jiffies+HZ/10);
301}
302
303/* ----------------------------------------------------------------------- */
304
305static int ir_attach(struct i2c_adapter *adap, int addr,
306 unsigned short flags, int kind);
307static int ir_detach(struct i2c_client *client);
308static int ir_probe(struct i2c_adapter *adap);
309
310static struct i2c_driver driver = {
311 .name = "ir remote kbd driver",
312 .id = I2C_DRIVERID_EXP3, /* FIXME */
313 .flags = I2C_DF_NOTIFY,
314 .attach_adapter = ir_probe,
315 .detach_client = ir_detach,
316};
317
318static struct i2c_client client_template =
319{
320 I2C_DEVNAME("unset"),
321 .driver = &driver
322};
323
324static int ir_attach(struct i2c_adapter *adap, int addr,
325 unsigned short flags, int kind)
326{
327 IR_KEYTAB_TYPE *ir_codes = NULL;
328 char *name;
329 int ir_type;
330 struct IR *ir;
331
332 if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
333 return -ENOMEM;
334 memset(ir,0,sizeof(*ir));
335 ir->c = client_template;
336
337 i2c_set_clientdata(&ir->c, ir);
338 ir->c.adapter = adap;
339 ir->c.addr = addr;
340
341 switch(addr) {
342 case 0x64:
343 name = "Pixelview";
344 ir->get_key = get_key_pixelview;
345 ir_type = IR_TYPE_OTHER;
346 ir_codes = ir_codes_empty;
347 break;
348 case 0x4b:
349 name = "PV951";
350 ir->get_key = get_key_pv951;
351 ir_type = IR_TYPE_OTHER;
352 ir_codes = ir_codes_pv951;
353 break;
354 case 0x18:
355 case 0x1a:
356 name = "Hauppauge";
357 ir->get_key = get_key_haup;
358 ir_type = IR_TYPE_RC5;
359 ir_codes = ir_codes_rc5_tv;
360 break;
361 case 0x30:
362 name = "KNC One";
363 ir->get_key = get_key_knc1;
364 ir_type = IR_TYPE_OTHER;
365 ir_codes = ir_codes_empty;
366 break;
367 case 0x7a:
368 name = "Purple TV";
369 ir->get_key = get_key_purpletv;
370 ir_type = IR_TYPE_OTHER;
371 ir_codes = ir_codes_purpletv;
372 break;
373 default:
374 /* shouldn't happen */
375 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
376 kfree(ir);
377 return -1;
378 }
379
380 /* register i2c device */
381 i2c_attach_client(&ir->c);
382 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
383 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
384 ir->c.adapter->dev.bus_id,
385 ir->c.dev.bus_id);
386
387 /* init + register input device */
388 ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes);
389 ir->input.id.bustype = BUS_I2C;
390 ir->input.name = ir->c.name;
391 ir->input.phys = ir->phys;
392 input_register_device(&ir->input);
393 printk(DEVNAME ": %s detected at %s [%s]\n",
394 ir->input.name,ir->input.phys,adap->name);
395
396 /* start polling via eventd */
397 INIT_WORK(&ir->work, ir_work, ir);
398 init_timer(&ir->timer);
399 ir->timer.function = ir_timer;
400 ir->timer.data = (unsigned long)ir;
401 schedule_work(&ir->work);
402
403 return 0;
404}
405
406static int ir_detach(struct i2c_client *client)
407{
408 struct IR *ir = i2c_get_clientdata(client);
409
410 /* kill outstanding polls */
411 del_timer(&ir->timer);
412 flush_scheduled_work();
413
414 /* unregister devices */
415 input_unregister_device(&ir->input);
416 i2c_detach_client(&ir->c);
417
418 /* free memory */
419 kfree(ir);
420 return 0;
421}
422
423static int ir_probe(struct i2c_adapter *adap)
424{
425
426 /* The external IR receiver is at i2c address 0x34 (0x35 for
427 reads). Future Hauppauge cards will have an internal
428 receiver at 0x30 (0x31 for reads). In theory, both can be
429 fitted, and Hauppauge suggest an external overrides an
430 internal.
431
432 That's why we probe 0x1a (~0x34) first. CB
433 */
434
435 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
436 static const int probe_saa7134[] = { 0x7a, -1 };
437 const int *probe = NULL;
438 struct i2c_client c; char buf; int i,rc;
439
440 switch (adap->id) {
441 case I2C_ALGO_BIT | I2C_HW_B_BT848:
442 probe = probe_bttv;
443 break;
444 case I2C_ALGO_SAA7134:
445 probe = probe_saa7134;
446 break;
447 }
448 if (NULL == probe)
449 return 0;
450
451 memset(&c,0,sizeof(c));
452 c.adapter = adap;
453 for (i = 0; -1 != probe[i]; i++) {
454 c.addr = probe[i];
455 rc = i2c_master_recv(&c,&buf,1);
456 dprintk(1,"probe 0x%02x @ %s: %s\n",
457 probe[i], adap->name,
458 (1 == rc) ? "yes" : "no");
459 if (1 == rc) {
460 ir_attach(adap,probe[i],0,0);
461 break;
462 }
463 }
464 return 0;
465}
466
467/* ----------------------------------------------------------------------- */
468
469MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
470MODULE_DESCRIPTION("input driver for i2c IR remote controls");
471MODULE_LICENSE("GPL");
472
473static int __init ir_init(void)
474{
475 return i2c_add_driver(&driver);
476}
477
478static void __exit ir_fini(void)
479{
480 i2c_del_driver(&driver);
481}
482
483module_init(ir_init);
484module_exit(ir_fini);
485
486/*
487 * Overrides for Emacs so that we follow Linus's tabbing style.
488 * ---------------------------------------------------------------------------
489 * Local variables:
490 * c-basic-offset: 8
491 * End:
492 */
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
new file mode 100644
index 000000000000..be72c2ce242e
--- /dev/null
+++ b/drivers/media/video/meye.c
@@ -0,0 +1,2041 @@
1/*
2 * Motion Eye video4linux driver for Sony Vaio PictureBook
3 *
4 * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
5 *
6 * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
7 *
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
9 *
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
11 *
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/pci.h>
32#include <linux/sched.h>
33#include <linux/init.h>
34#include <linux/videodev.h>
35#include <asm/uaccess.h>
36#include <asm/io.h>
37#include <linux/delay.h>
38#include <linux/interrupt.h>
39#include <linux/vmalloc.h>
40
41#include "meye.h"
42#include <linux/meye.h>
43
44MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
45MODULE_DESCRIPTION("v4l/v4l2 driver for the MotionEye camera");
46MODULE_LICENSE("GPL");
47MODULE_VERSION(MEYE_DRIVER_VERSION);
48
49/* force usage of V4L1 API */
50static int forcev4l1; /* = 0 */
51module_param(forcev4l1, int, 0644);
52MODULE_PARM_DESC(forcev4l1, "force use of V4L1 instead of V4L2");
53
54/* number of grab buffers */
55static unsigned int gbuffers = 2;
56module_param(gbuffers, int, 0444);
57MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)");
58
59/* size of a grab buffer */
60static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
61module_param(gbufsize, int, 0444);
62MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400"
63 " (will be rounded up to a page multiple)");
64
65/* /dev/videoX registration number */
66static int video_nr = -1;
67module_param(video_nr, int, 0444);
68MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
69
70/* driver structure - only one possible */
71static struct meye meye;
72
73/****************************************************************************/
74/* Memory allocation routines (stolen from bttv-driver.c) */
75/****************************************************************************/
76static void *rvmalloc(unsigned long size)
77{
78 void *mem;
79 unsigned long adr;
80
81 size = PAGE_ALIGN(size);
82 mem = vmalloc_32(size);
83 if (mem) {
84 memset(mem, 0, size);
85 adr = (unsigned long) mem;
86 while (size > 0) {
87 SetPageReserved(vmalloc_to_page((void *)adr));
88 adr += PAGE_SIZE;
89 size -= PAGE_SIZE;
90 }
91 }
92 return mem;
93}
94
95static void rvfree(void * mem, unsigned long size)
96{
97 unsigned long adr;
98
99 if (mem) {
100 adr = (unsigned long) mem;
101 while ((long) size > 0) {
102 ClearPageReserved(vmalloc_to_page((void *)adr));
103 adr += PAGE_SIZE;
104 size -= PAGE_SIZE;
105 }
106 vfree(mem);
107 }
108}
109
110/*
111 * return a page table pointing to N pages of locked memory
112 *
113 * NOTE: The meye device expects DMA addresses on 32 bits, we build
114 * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes.
115 */
116static int ptable_alloc(void)
117{
118 u32 *pt;
119 int i;
120
121 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
122
123 /* give only 32 bit DMA addresses */
124 if (dma_set_mask(&meye.mchip_dev->dev, 0xffffffff))
125 return -1;
126
127 meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
128 PAGE_SIZE,
129 &meye.mchip_dmahandle,
130 GFP_KERNEL);
131 if (!meye.mchip_ptable_toc) {
132 meye.mchip_dmahandle = 0;
133 return -1;
134 }
135
136 pt = meye.mchip_ptable_toc;
137 for (i = 0; i < MCHIP_NB_PAGES; i++) {
138 dma_addr_t dma;
139 meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
140 PAGE_SIZE,
141 &dma,
142 GFP_KERNEL);
143 if (!meye.mchip_ptable[i]) {
144 int j;
145 pt = meye.mchip_ptable_toc;
146 for (j = 0; j < i; ++j) {
147 dma = (dma_addr_t) *pt;
148 dma_free_coherent(&meye.mchip_dev->dev,
149 PAGE_SIZE,
150 meye.mchip_ptable[j], dma);
151 pt++;
152 }
153 dma_free_coherent(&meye.mchip_dev->dev,
154 PAGE_SIZE,
155 meye.mchip_ptable_toc,
156 meye.mchip_dmahandle);
157 meye.mchip_ptable_toc = NULL;
158 meye.mchip_dmahandle = 0;
159 return -1;
160 }
161 *pt = (u32) dma;
162 pt++;
163 }
164 return 0;
165}
166
167static void ptable_free(void)
168{
169 u32 *pt;
170 int i;
171
172 pt = meye.mchip_ptable_toc;
173 for (i = 0; i < MCHIP_NB_PAGES; i++) {
174 dma_addr_t dma = (dma_addr_t) *pt;
175 if (meye.mchip_ptable[i])
176 dma_free_coherent(&meye.mchip_dev->dev,
177 PAGE_SIZE,
178 meye.mchip_ptable[i], dma);
179 pt++;
180 }
181
182 if (meye.mchip_ptable_toc)
183 dma_free_coherent(&meye.mchip_dev->dev,
184 PAGE_SIZE,
185 meye.mchip_ptable_toc,
186 meye.mchip_dmahandle);
187
188 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
189 meye.mchip_ptable_toc = NULL;
190 meye.mchip_dmahandle = 0;
191}
192
193/* copy data from ptable into buf */
194static void ptable_copy(u8 *buf, int start, int size, int pt_pages)
195{
196 int i;
197
198 for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
199 memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
200 if (start >= pt_pages)
201 start = 0;
202 }
203 memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
204}
205
206/****************************************************************************/
207/* JPEG tables at different qualities to load into the VRJ chip */
208/****************************************************************************/
209
210/* return a set of quantisation tables based on a quality from 1 to 10 */
211static u16 *jpeg_quantisation_tables(int *length, int quality)
212{
213 static u16 jpeg_tables[][70] = { {
214 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
215 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
216 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
217 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
218 0xffff, 0xffff, 0xffff,
219 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
220 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
221 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
222 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
223 0xffff, 0xffff, 0xffff,
224 },
225 {
226 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
227 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
228 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
229 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
230 0xffff, 0xffff, 0xffff,
231 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
232 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
233 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
234 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
235 0xffff, 0xffff, 0xffff,
236 },
237 {
238 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
239 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
240 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
241 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
242 0xe6ff, 0xfffd, 0xfff8,
243 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
244 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
245 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
246 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
247 0xf8f8, 0xf8f8, 0xfff8,
248 },
249 {
250 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
251 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
252 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
253 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
254 0x99c7, 0xaba8, 0xffa4,
255 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
256 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
257 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
258 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
259 0xa4a4, 0xa4a4, 0xffa4,
260 },
261 {
262 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
263 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
264 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
265 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
266 0x7396, 0x817e, 0xff7c,
267 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
268 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
269 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
270 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
271 0x7c7c, 0x7c7c, 0xff7c,
272 },
273 {
274 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
275 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
276 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
277 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
278 0x5c78, 0x6765, 0xff63,
279 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
280 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
281 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
282 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
283 0x6363, 0x6363, 0xff63,
284 },
285 {
286 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
287 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
288 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
289 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
290 0x4a60, 0x5251, 0xff4f,
291 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
292 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
293 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
294 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
295 0x4f4f, 0x4f4f, 0xff4f,
296 },
297 {
298 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
299 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
300 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
301 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
302 0x3748, 0x3e3d, 0xff3b,
303 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
304 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
305 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
306 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
307 0x3b3b, 0x3b3b, 0xff3b,
308 },
309 {
310 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
311 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
312 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
313 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
314 0x2530, 0x2928, 0xff28,
315 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
316 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
317 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
318 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
319 0x2828, 0x2828, 0xff28,
320 },
321 {
322 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
323 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
324 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
325 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
326 0x1218, 0x1514, 0xff14,
327 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
328 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
329 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
330 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
331 0x1414, 0x1414, 0xff14,
332 },
333 {
334 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
335 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
336 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
337 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
338 0x0101, 0x0101, 0xff01,
339 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
340 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
341 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
342 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
343 0x0101, 0x0101, 0xff01,
344 } };
345
346 if (quality < 0 || quality > 10) {
347 printk(KERN_WARNING
348 "meye: invalid quality level %d - using 8\n", quality);
349 quality = 8;
350 }
351
352 *length = ARRAY_SIZE(jpeg_tables[quality]);
353 return jpeg_tables[quality];
354}
355
356/* return a generic set of huffman tables */
357static u16 *jpeg_huffman_tables(int *length)
358{
359 static u16 tables[] = {
360 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
361 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
362 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
363 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
364 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
365 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
366 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
367 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
368 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
369 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
370 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
371 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
372 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
373 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
374 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
375 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
376 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
377 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
378 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
379 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
380 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
381 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
382 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
383 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
384 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
385 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
386 0xFF0B,
387 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
388 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
389 0xFF0B
390 };
391
392 *length = ARRAY_SIZE(tables);
393 return tables;
394}
395
396/****************************************************************************/
397/* MCHIP low-level functions */
398/****************************************************************************/
399
400/* returns the horizontal capture size */
401static inline int mchip_hsize(void)
402{
403 return meye.params.subsample ? 320 : 640;
404}
405
406/* returns the vertical capture size */
407static inline int mchip_vsize(void)
408{
409 return meye.params.subsample ? 240 : 480;
410}
411
412/* waits for a register to be available */
413static void mchip_sync(int reg)
414{
415 u32 status;
416 int i;
417
418 if (reg == MCHIP_MM_FIFO_DATA) {
419 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
420 status = readl(meye.mchip_mmregs +
421 MCHIP_MM_FIFO_STATUS);
422 if (!(status & MCHIP_MM_FIFO_WAIT)) {
423 printk(KERN_WARNING "meye: fifo not ready\n");
424 return;
425 }
426 if (status & MCHIP_MM_FIFO_READY)
427 return;
428 udelay(1);
429 }
430 } else if (reg > 0x80) {
431 u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
432 : MCHIP_HIC_STATUS_VRJ_RDY;
433 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
434 status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
435 if (status & mask)
436 return;
437 udelay(1);
438 }
439 } else
440 return;
441 printk(KERN_WARNING
442 "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n",
443 reg, status);
444}
445
446/* sets a value into the register */
447static inline void mchip_set(int reg, u32 v)
448{
449 mchip_sync(reg);
450 writel(v, meye.mchip_mmregs + reg);
451}
452
453/* get the register value */
454static inline u32 mchip_read(int reg)
455{
456 mchip_sync(reg);
457 return readl(meye.mchip_mmregs + reg);
458}
459
460/* wait for a register to become a particular value */
461static inline int mchip_delay(u32 reg, u32 v)
462{
463 int n = 10;
464 while (--n && mchip_read(reg) != v)
465 udelay(1);
466 return n;
467}
468
469/* setup subsampling */
470static void mchip_subsample(void)
471{
472 mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
473 mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
474 mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
475 mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
476 mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
477 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
478}
479
480/* set the framerate into the mchip */
481static void mchip_set_framerate(void)
482{
483 mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
484}
485
486/* load some huffman and quantisation tables into the VRJ chip ready
487 for JPEG compression */
488static void mchip_load_tables(void)
489{
490 int i;
491 int length;
492 u16 *tables;
493
494 tables = jpeg_huffman_tables(&length);
495 for (i = 0; i < length; i++)
496 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
497
498 tables = jpeg_quantisation_tables(&length, meye.params.quality);
499 for (i = 0; i < length; i++)
500 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
501}
502
503/* setup the VRJ parameters in the chip */
504static void mchip_vrj_setup(u8 mode)
505{
506 mchip_set(MCHIP_VRJ_BUS_MODE, 5);
507 mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
508 mchip_set(MCHIP_VRJ_PDAT_USE, 1);
509 mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
510 mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
511 mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
512 mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
513 mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
514 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
515 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
516 mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
517 mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
518 mchip_set(MCHIP_VRJ_SOF1, 0x601);
519 mchip_set(MCHIP_VRJ_SOF2, 0x1502);
520 mchip_set(MCHIP_VRJ_SOF3, 0x1503);
521 mchip_set(MCHIP_VRJ_SOF4, 0x1596);
522 mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
523
524 mchip_load_tables();
525}
526
527/* sets the DMA parameters into the chip */
528static void mchip_dma_setup(dma_addr_t dma_addr)
529{
530 int i;
531
532 mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr);
533 for (i = 0; i < 4; i++)
534 mchip_set(MCHIP_MM_FIR(i), 0);
535 meye.mchip_fnum = 0;
536}
537
538/* setup for DMA transfers - also zeros the framebuffer */
539static int mchip_dma_alloc(void)
540{
541 if (!meye.mchip_dmahandle)
542 if (ptable_alloc())
543 return -1;
544 return 0;
545}
546
547/* frees the DMA buffer */
548static void mchip_dma_free(void)
549{
550 if (meye.mchip_dmahandle) {
551 mchip_dma_setup(0);
552 ptable_free();
553 }
554}
555
556/* stop any existing HIC action and wait for any dma to complete then
557 reset the dma engine */
558static void mchip_hic_stop(void)
559{
560 int i, j;
561
562 meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
563 if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
564 return;
565 for (i = 0; i < 20; ++i) {
566 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
567 mchip_delay(MCHIP_HIC_CMD, 0);
568 for (j = 0; j < 100; ++j) {
569 if (mchip_delay(MCHIP_HIC_STATUS,
570 MCHIP_HIC_STATUS_IDLE))
571 return;
572 msleep(1);
573 }
574 printk(KERN_ERR "meye: need to reset HIC!\n");
575
576 mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
577 msleep(250);
578 }
579 printk(KERN_ERR "meye: resetting HIC hanged!\n");
580}
581
582/****************************************************************************/
583/* MCHIP frame processing functions */
584/****************************************************************************/
585
586/* get the next ready frame from the dma engine */
587static u32 mchip_get_frame(void)
588{
589 u32 v;
590
591 v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
592 return v;
593}
594
595/* frees the current frame from the dma engine */
596static void mchip_free_frame(void)
597{
598 mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
599 meye.mchip_fnum++;
600 meye.mchip_fnum %= 4;
601}
602
603/* read one frame from the framebuffer assuming it was captured using
604 a uncompressed transfer */
605static void mchip_cont_read_frame(u32 v, u8 *buf, int size)
606{
607 int pt_id;
608
609 pt_id = (v >> 17) & 0x3FF;
610
611 ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
612}
613
614/* read a compressed frame from the framebuffer */
615static int mchip_comp_read_frame(u32 v, u8 *buf, int size)
616{
617 int pt_start, pt_end, trailer;
618 int fsize;
619 int i;
620
621 pt_start = (v >> 19) & 0xFF;
622 pt_end = (v >> 11) & 0xFF;
623 trailer = (v >> 1) & 0x3FF;
624
625 if (pt_end < pt_start)
626 fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
627 pt_end * PAGE_SIZE + trailer * 4;
628 else
629 fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
630
631 if (fsize > size) {
632 printk(KERN_WARNING "meye: oversized compressed frame %d\n",
633 fsize);
634 return -1;
635 }
636
637 ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
638
639#ifdef MEYE_JPEG_CORRECTION
640
641 /* Some mchip generated jpeg frames are incorrect. In most
642 * (all ?) of those cases, the final EOI (0xff 0xd9) marker
643 * is not present at the end of the frame.
644 *
645 * Since adding the final marker is not enough to restore
646 * the jpeg integrity, we drop the frame.
647 */
648
649 for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
650
651 if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
652 return -1;
653
654#endif
655
656 return fsize;
657}
658
659/* take a picture into SDRAM */
660static void mchip_take_picture(void)
661{
662 int i;
663
664 mchip_hic_stop();
665 mchip_subsample();
666 mchip_dma_setup(meye.mchip_dmahandle);
667
668 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
669 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
670
671 mchip_delay(MCHIP_HIC_CMD, 0);
672
673 for (i = 0; i < 100; ++i) {
674 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
675 break;
676 msleep(1);
677 }
678}
679
680/* dma a previously taken picture into a buffer */
681static void mchip_get_picture(u8 *buf, int bufsize)
682{
683 u32 v;
684 int i;
685
686 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
687 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
688
689 mchip_delay(MCHIP_HIC_CMD, 0);
690 for (i = 0; i < 100; ++i) {
691 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
692 break;
693 msleep(1);
694 }
695 for (i = 0; i < 4; ++i) {
696 v = mchip_get_frame();
697 if (v & MCHIP_MM_FIR_RDY) {
698 mchip_cont_read_frame(v, buf, bufsize);
699 break;
700 }
701 mchip_free_frame();
702 }
703}
704
705/* start continuous dma capture */
706static void mchip_continuous_start(void)
707{
708 mchip_hic_stop();
709 mchip_subsample();
710 mchip_set_framerate();
711 mchip_dma_setup(meye.mchip_dmahandle);
712
713 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
714
715 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
716 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
717
718 mchip_delay(MCHIP_HIC_CMD, 0);
719}
720
721/* compress one frame into a buffer */
722static int mchip_compress_frame(u8 *buf, int bufsize)
723{
724 u32 v;
725 int len = -1, i;
726
727 mchip_vrj_setup(0x3f);
728 udelay(50);
729
730 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
731 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
732
733 mchip_delay(MCHIP_HIC_CMD, 0);
734 for (i = 0; i < 100; ++i) {
735 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
736 break;
737 msleep(1);
738 }
739
740 for (i = 0; i < 4; ++i) {
741 v = mchip_get_frame();
742 if (v & MCHIP_MM_FIR_RDY) {
743 len = mchip_comp_read_frame(v, buf, bufsize);
744 break;
745 }
746 mchip_free_frame();
747 }
748 return len;
749}
750
751#if 0
752/* uncompress one image into a buffer */
753static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize)
754{
755 mchip_vrj_setup(0x3f);
756 udelay(50);
757
758 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
759 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
760
761 mchip_delay(MCHIP_HIC_CMD, 0);
762
763 return mchip_comp_read_frame(buf, bufsize);
764}
765#endif
766
767/* start continuous compressed capture */
768static void mchip_cont_compression_start(void)
769{
770 mchip_hic_stop();
771 mchip_vrj_setup(0x3f);
772 mchip_subsample();
773 mchip_set_framerate();
774 mchip_dma_setup(meye.mchip_dmahandle);
775
776 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
777
778 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
779 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
780
781 mchip_delay(MCHIP_HIC_CMD, 0);
782}
783
784/****************************************************************************/
785/* Interrupt handling */
786/****************************************************************************/
787
788static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs)
789{
790 u32 v;
791 int reqnr;
792 static int sequence = 0;
793
794 v = mchip_read(MCHIP_MM_INTA);
795
796 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT &&
797 meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
798 return IRQ_NONE;
799
800again:
801 v = mchip_get_frame();
802 if (!(v & MCHIP_MM_FIR_RDY))
803 return IRQ_HANDLED;
804
805 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
806 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
807 sizeof(int)) != sizeof(int)) {
808 mchip_free_frame();
809 return IRQ_HANDLED;
810 }
811 mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr,
812 mchip_hsize() * mchip_vsize() * 2);
813 meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2;
814 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
815 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
816 meye.grab_buffer[reqnr].sequence = sequence++;
817 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
818 wake_up_interruptible(&meye.proc_list);
819 } else {
820 int size;
821 size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize);
822 if (size == -1) {
823 mchip_free_frame();
824 goto again;
825 }
826 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
827 sizeof(int)) != sizeof(int)) {
828 mchip_free_frame();
829 goto again;
830 }
831 memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp,
832 size);
833 meye.grab_buffer[reqnr].size = size;
834 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
835 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
836 meye.grab_buffer[reqnr].sequence = sequence++;
837 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
838 wake_up_interruptible(&meye.proc_list);
839 }
840 mchip_free_frame();
841 goto again;
842}
843
844/****************************************************************************/
845/* video4linux integration */
846/****************************************************************************/
847
848static int meye_open(struct inode *inode, struct file *file)
849{
850 int i, err;
851
852 err = video_exclusive_open(inode, file);
853 if (err < 0)
854 return err;
855
856 mchip_hic_stop();
857
858 if (mchip_dma_alloc()) {
859 printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
860 video_exclusive_release(inode, file);
861 return -ENOBUFS;
862 }
863
864 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
865 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
866 kfifo_reset(meye.grabq);
867 kfifo_reset(meye.doneq);
868 return 0;
869}
870
871static int meye_release(struct inode *inode, struct file *file)
872{
873 mchip_hic_stop();
874 mchip_dma_free();
875 video_exclusive_release(inode, file);
876 return 0;
877}
878
879static int meye_do_ioctl(struct inode *inode, struct file *file,
880 unsigned int cmd, void *arg)
881{
882 switch (cmd) {
883
884 case VIDIOCGCAP: {
885 struct video_capability *b = arg;
886 strcpy(b->name,meye.video_dev->name);
887 b->type = VID_TYPE_CAPTURE;
888 b->channels = 1;
889 b->audios = 0;
890 b->maxwidth = 640;
891 b->maxheight = 480;
892 b->minwidth = 320;
893 b->minheight = 240;
894 break;
895 }
896
897 case VIDIOCGCHAN: {
898 struct video_channel *v = arg;
899 v->flags = 0;
900 v->tuners = 0;
901 v->type = VIDEO_TYPE_CAMERA;
902 if (v->channel != 0)
903 return -EINVAL;
904 strcpy(v->name,"Camera");
905 break;
906 }
907
908 case VIDIOCSCHAN: {
909 struct video_channel *v = arg;
910 if (v->channel != 0)
911 return -EINVAL;
912 break;
913 }
914
915 case VIDIOCGPICT: {
916 struct video_picture *p = arg;
917 *p = meye.picture;
918 break;
919 }
920
921 case VIDIOCSPICT: {
922 struct video_picture *p = arg;
923 if (p->depth != 16)
924 return -EINVAL;
925 if (p->palette != VIDEO_PALETTE_YUV422)
926 return -EINVAL;
927 down(&meye.lock);
928 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
929 p->brightness >> 10);
930 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE,
931 p->hue >> 10);
932 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR,
933 p->colour >> 10);
934 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST,
935 p->contrast >> 10);
936 meye.picture = *p;
937 up(&meye.lock);
938 break;
939 }
940
941 case VIDIOCSYNC: {
942 int *i = arg;
943 int unused;
944
945 if (*i < 0 || *i >= gbuffers)
946 return -EINVAL;
947
948 down(&meye.lock);
949
950 switch (meye.grab_buffer[*i].state) {
951
952 case MEYE_BUF_UNUSED:
953 up(&meye.lock);
954 return -EINVAL;
955 case MEYE_BUF_USING:
956 if (file->f_flags & O_NONBLOCK) {
957 up(&meye.lock);
958 return -EAGAIN;
959 }
960 if (wait_event_interruptible(meye.proc_list,
961 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
962 up(&meye.lock);
963 return -EINTR;
964 }
965 /* fall through */
966 case MEYE_BUF_DONE:
967 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
968 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
969 }
970 up(&meye.lock);
971 break;
972 }
973
974 case VIDIOCMCAPTURE: {
975 struct video_mmap *vm = arg;
976 int restart = 0;
977
978 if (vm->frame >= gbuffers || vm->frame < 0)
979 return -EINVAL;
980 if (vm->format != VIDEO_PALETTE_YUV422)
981 return -EINVAL;
982 if (vm->height * vm->width * 2 > gbufsize)
983 return -EINVAL;
984 if (!meye.grab_fbuffer)
985 return -EINVAL;
986 if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
987 return -EBUSY;
988
989 down(&meye.lock);
990 if (vm->width == 640 && vm->height == 480) {
991 if (meye.params.subsample) {
992 meye.params.subsample = 0;
993 restart = 1;
994 }
995 } else if (vm->width == 320 && vm->height == 240) {
996 if (!meye.params.subsample) {
997 meye.params.subsample = 1;
998 restart = 1;
999 }
1000 } else {
1001 up(&meye.lock);
1002 return -EINVAL;
1003 }
1004
1005 if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
1006 mchip_continuous_start();
1007 meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
1008 kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int));
1009 up(&meye.lock);
1010 break;
1011 }
1012
1013 case VIDIOCGMBUF: {
1014 struct video_mbuf *vm = arg;
1015 int i;
1016
1017 memset(vm, 0 , sizeof(*vm));
1018 vm->size = gbufsize * gbuffers;
1019 vm->frames = gbuffers;
1020 for (i = 0; i < gbuffers; i++)
1021 vm->offsets[i] = i * gbufsize;
1022 break;
1023 }
1024
1025 case MEYEIOC_G_PARAMS: {
1026 struct meye_params *p = arg;
1027 *p = meye.params;
1028 break;
1029 }
1030
1031 case MEYEIOC_S_PARAMS: {
1032 struct meye_params *jp = arg;
1033 if (jp->subsample > 1)
1034 return -EINVAL;
1035 if (jp->quality > 10)
1036 return -EINVAL;
1037 if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
1038 return -EINVAL;
1039 if (jp->framerate > 31)
1040 return -EINVAL;
1041 down(&meye.lock);
1042 if (meye.params.subsample != jp->subsample ||
1043 meye.params.quality != jp->quality)
1044 mchip_hic_stop(); /* need restart */
1045 meye.params = *jp;
1046 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
1047 meye.params.sharpness);
1048 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
1049 meye.params.agc);
1050 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,
1051 meye.params.picture);
1052 up(&meye.lock);
1053 break;
1054 }
1055
1056 case MEYEIOC_QBUF_CAPT: {
1057 int *nb = arg;
1058
1059 if (!meye.grab_fbuffer)
1060 return -EINVAL;
1061 if (*nb >= gbuffers)
1062 return -EINVAL;
1063 if (*nb < 0) {
1064 /* stop capture */
1065 mchip_hic_stop();
1066 return 0;
1067 }
1068 if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
1069 return -EBUSY;
1070 down(&meye.lock);
1071 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
1072 mchip_cont_compression_start();
1073 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
1074 kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
1075 up(&meye.lock);
1076 break;
1077 }
1078
1079 case MEYEIOC_SYNC: {
1080 int *i = arg;
1081 int unused;
1082
1083 if (*i < 0 || *i >= gbuffers)
1084 return -EINVAL;
1085
1086 down(&meye.lock);
1087 switch (meye.grab_buffer[*i].state) {
1088
1089 case MEYE_BUF_UNUSED:
1090 up(&meye.lock);
1091 return -EINVAL;
1092 case MEYE_BUF_USING:
1093 if (file->f_flags & O_NONBLOCK) {
1094 up(&meye.lock);
1095 return -EAGAIN;
1096 }
1097 if (wait_event_interruptible(meye.proc_list,
1098 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
1099 up(&meye.lock);
1100 return -EINTR;
1101 }
1102 /* fall through */
1103 case MEYE_BUF_DONE:
1104 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
1105 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
1106 }
1107 *i = meye.grab_buffer[*i].size;
1108 up(&meye.lock);
1109 break;
1110 }
1111
1112 case MEYEIOC_STILLCAPT: {
1113
1114 if (!meye.grab_fbuffer)
1115 return -EINVAL;
1116 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1117 return -EBUSY;
1118 down(&meye.lock);
1119 meye.grab_buffer[0].state = MEYE_BUF_USING;
1120 mchip_take_picture();
1121 mchip_get_picture(
1122 meye.grab_fbuffer,
1123 mchip_hsize() * mchip_vsize() * 2);
1124 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1125 up(&meye.lock);
1126 break;
1127 }
1128
1129 case MEYEIOC_STILLJCAPT: {
1130 int *len = arg;
1131
1132 if (!meye.grab_fbuffer)
1133 return -EINVAL;
1134 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1135 return -EBUSY;
1136 down(&meye.lock);
1137 meye.grab_buffer[0].state = MEYE_BUF_USING;
1138 *len = -1;
1139 while (*len == -1) {
1140 mchip_take_picture();
1141 *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
1142 }
1143 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1144 up(&meye.lock);
1145 break;
1146 }
1147
1148 case VIDIOC_QUERYCAP: {
1149 struct v4l2_capability *cap = arg;
1150
1151 if (forcev4l1)
1152 return -EINVAL;
1153
1154 memset(cap, 0, sizeof(*cap));
1155 strcpy(cap->driver, "meye");
1156 strcpy(cap->card, "meye");
1157 sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
1158 cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +
1159 MEYE_DRIVER_MINORVERSION;
1160 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1161 V4L2_CAP_STREAMING;
1162 break;
1163 }
1164
1165 case VIDIOC_ENUMINPUT: {
1166 struct v4l2_input *i = arg;
1167
1168 if (i->index != 0)
1169 return -EINVAL;
1170 memset(i, 0, sizeof(*i));
1171 i->index = 0;
1172 strcpy(i->name, "Camera");
1173 i->type = V4L2_INPUT_TYPE_CAMERA;
1174 break;
1175 }
1176
1177 case VIDIOC_G_INPUT: {
1178 int *i = arg;
1179
1180 *i = 0;
1181 break;
1182 }
1183
1184 case VIDIOC_S_INPUT: {
1185 int *i = arg;
1186
1187 if (*i != 0)
1188 return -EINVAL;
1189 break;
1190 }
1191
1192 case VIDIOC_QUERYCTRL: {
1193 struct v4l2_queryctrl *c = arg;
1194
1195 switch (c->id) {
1196
1197 case V4L2_CID_BRIGHTNESS:
1198 c->type = V4L2_CTRL_TYPE_INTEGER;
1199 strcpy(c->name, "Brightness");
1200 c->minimum = 0;
1201 c->maximum = 63;
1202 c->step = 1;
1203 c->default_value = 32;
1204 c->flags = 0;
1205 break;
1206 case V4L2_CID_HUE:
1207 c->type = V4L2_CTRL_TYPE_INTEGER;
1208 strcpy(c->name, "Hue");
1209 c->minimum = 0;
1210 c->maximum = 63;
1211 c->step = 1;
1212 c->default_value = 32;
1213 c->flags = 0;
1214 break;
1215 case V4L2_CID_CONTRAST:
1216 c->type = V4L2_CTRL_TYPE_INTEGER;
1217 strcpy(c->name, "Contrast");
1218 c->minimum = 0;
1219 c->maximum = 63;
1220 c->step = 1;
1221 c->default_value = 32;
1222 c->flags = 0;
1223 break;
1224 case V4L2_CID_SATURATION:
1225 c->type = V4L2_CTRL_TYPE_INTEGER;
1226 strcpy(c->name, "Saturation");
1227 c->minimum = 0;
1228 c->maximum = 63;
1229 c->step = 1;
1230 c->default_value = 32;
1231 c->flags = 0;
1232 break;
1233 case V4L2_CID_AGC:
1234 c->type = V4L2_CTRL_TYPE_INTEGER;
1235 strcpy(c->name, "Agc");
1236 c->minimum = 0;
1237 c->maximum = 63;
1238 c->step = 1;
1239 c->default_value = 48;
1240 c->flags = 0;
1241 break;
1242 case V4L2_CID_SHARPNESS:
1243 c->type = V4L2_CTRL_TYPE_INTEGER;
1244 strcpy(c->name, "Sharpness");
1245 c->minimum = 0;
1246 c->maximum = 63;
1247 c->step = 1;
1248 c->default_value = 32;
1249 c->flags = 0;
1250 break;
1251 case V4L2_CID_PICTURE:
1252 c->type = V4L2_CTRL_TYPE_INTEGER;
1253 strcpy(c->name, "Picture");
1254 c->minimum = 0;
1255 c->maximum = 63;
1256 c->step = 1;
1257 c->default_value = 0;
1258 c->flags = 0;
1259 break;
1260 case V4L2_CID_JPEGQUAL:
1261 c->type = V4L2_CTRL_TYPE_INTEGER;
1262 strcpy(c->name, "JPEG quality");
1263 c->minimum = 0;
1264 c->maximum = 10;
1265 c->step = 1;
1266 c->default_value = 8;
1267 c->flags = 0;
1268 break;
1269 case V4L2_CID_FRAMERATE:
1270 c->type = V4L2_CTRL_TYPE_INTEGER;
1271 strcpy(c->name, "Framerate");
1272 c->minimum = 0;
1273 c->maximum = 31;
1274 c->step = 1;
1275 c->default_value = 0;
1276 c->flags = 0;
1277 break;
1278 default:
1279 return -EINVAL;
1280 }
1281 break;
1282 }
1283
1284 case VIDIOC_S_CTRL: {
1285 struct v4l2_control *c = arg;
1286
1287 down(&meye.lock);
1288 switch (c->id) {
1289 case V4L2_CID_BRIGHTNESS:
1290 sonypi_camera_command(
1291 SONYPI_COMMAND_SETCAMERABRIGHTNESS, c->value);
1292 meye.picture.brightness = c->value << 10;
1293 break;
1294 case V4L2_CID_HUE:
1295 sonypi_camera_command(
1296 SONYPI_COMMAND_SETCAMERAHUE, c->value);
1297 meye.picture.hue = c->value << 10;
1298 break;
1299 case V4L2_CID_CONTRAST:
1300 sonypi_camera_command(
1301 SONYPI_COMMAND_SETCAMERACONTRAST, c->value);
1302 meye.picture.contrast = c->value << 10;
1303 break;
1304 case V4L2_CID_SATURATION:
1305 sonypi_camera_command(
1306 SONYPI_COMMAND_SETCAMERACOLOR, c->value);
1307 meye.picture.colour = c->value << 10;
1308 break;
1309 case V4L2_CID_AGC:
1310 sonypi_camera_command(
1311 SONYPI_COMMAND_SETCAMERAAGC, c->value);
1312 meye.params.agc = c->value;
1313 break;
1314 case V4L2_CID_SHARPNESS:
1315 sonypi_camera_command(
1316 SONYPI_COMMAND_SETCAMERASHARPNESS, c->value);
1317 meye.params.sharpness = c->value;
1318 break;
1319 case V4L2_CID_PICTURE:
1320 sonypi_camera_command(
1321 SONYPI_COMMAND_SETCAMERAPICTURE, c->value);
1322 meye.params.picture = c->value;
1323 break;
1324 case V4L2_CID_JPEGQUAL:
1325 meye.params.quality = c->value;
1326 break;
1327 case V4L2_CID_FRAMERATE:
1328 meye.params.framerate = c->value;
1329 break;
1330 default:
1331 up(&meye.lock);
1332 return -EINVAL;
1333 }
1334 up(&meye.lock);
1335 break;
1336 }
1337
1338 case VIDIOC_G_CTRL: {
1339 struct v4l2_control *c = arg;
1340
1341 down(&meye.lock);
1342 switch (c->id) {
1343 case V4L2_CID_BRIGHTNESS:
1344 c->value = meye.picture.brightness >> 10;
1345 break;
1346 case V4L2_CID_HUE:
1347 c->value = meye.picture.hue >> 10;
1348 break;
1349 case V4L2_CID_CONTRAST:
1350 c->value = meye.picture.contrast >> 10;
1351 break;
1352 case V4L2_CID_SATURATION:
1353 c->value = meye.picture.colour >> 10;
1354 break;
1355 case V4L2_CID_AGC:
1356 c->value = meye.params.agc;
1357 break;
1358 case V4L2_CID_SHARPNESS:
1359 c->value = meye.params.sharpness;
1360 break;
1361 case V4L2_CID_PICTURE:
1362 c->value = meye.params.picture;
1363 break;
1364 case V4L2_CID_JPEGQUAL:
1365 c->value = meye.params.quality;
1366 break;
1367 case V4L2_CID_FRAMERATE:
1368 c->value = meye.params.framerate;
1369 break;
1370 default:
1371 up(&meye.lock);
1372 return -EINVAL;
1373 }
1374 up(&meye.lock);
1375 break;
1376 }
1377
1378 case VIDIOC_ENUM_FMT: {
1379 struct v4l2_fmtdesc *f = arg;
1380
1381 if (f->index > 1)
1382 return -EINVAL;
1383 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1384 return -EINVAL;
1385 if (f->index == 0) {
1386 /* standard YUV 422 capture */
1387 memset(f, 0, sizeof(*f));
1388 f->index = 0;
1389 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1390 f->flags = 0;
1391 strcpy(f->description, "YUV422");
1392 f->pixelformat = V4L2_PIX_FMT_YUYV;
1393 } else {
1394 /* compressed MJPEG capture */
1395 memset(f, 0, sizeof(*f));
1396 f->index = 1;
1397 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1398 f->flags = V4L2_FMT_FLAG_COMPRESSED;
1399 strcpy(f->description, "MJPEG");
1400 f->pixelformat = V4L2_PIX_FMT_MJPEG;
1401 }
1402 break;
1403 }
1404
1405 case VIDIOC_TRY_FMT: {
1406 struct v4l2_format *f = arg;
1407
1408 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1409 return -EINVAL;
1410 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1411 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1412 return -EINVAL;
1413 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1414 f->fmt.pix.field != V4L2_FIELD_NONE)
1415 return -EINVAL;
1416 f->fmt.pix.field = V4L2_FIELD_NONE;
1417 if (f->fmt.pix.width <= 320) {
1418 f->fmt.pix.width = 320;
1419 f->fmt.pix.height = 240;
1420 } else {
1421 f->fmt.pix.width = 640;
1422 f->fmt.pix.height = 480;
1423 }
1424 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1425 f->fmt.pix.sizeimage = f->fmt.pix.height *
1426 f->fmt.pix.bytesperline;
1427 f->fmt.pix.colorspace = 0;
1428 f->fmt.pix.priv = 0;
1429 break;
1430 }
1431
1432 case VIDIOC_G_FMT: {
1433 struct v4l2_format *f = arg;
1434
1435 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1436 return -EINVAL;
1437 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
1438 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1439 switch (meye.mchip_mode) {
1440 case MCHIP_HIC_MODE_CONT_OUT:
1441 default:
1442 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1443 break;
1444 case MCHIP_HIC_MODE_CONT_COMP:
1445 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
1446 break;
1447 }
1448 f->fmt.pix.field = V4L2_FIELD_NONE;
1449 f->fmt.pix.width = mchip_hsize();
1450 f->fmt.pix.height = mchip_vsize();
1451 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1452 f->fmt.pix.sizeimage = f->fmt.pix.height *
1453 f->fmt.pix.bytesperline;
1454 f->fmt.pix.colorspace = 0;
1455 f->fmt.pix.priv = 0;
1456 break;
1457 }
1458
1459 case VIDIOC_S_FMT: {
1460 struct v4l2_format *f = arg;
1461
1462 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1463 return -EINVAL;
1464 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1465 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1466 return -EINVAL;
1467 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1468 f->fmt.pix.field != V4L2_FIELD_NONE)
1469 return -EINVAL;
1470 f->fmt.pix.field = V4L2_FIELD_NONE;
1471 down(&meye.lock);
1472 if (f->fmt.pix.width <= 320) {
1473 f->fmt.pix.width = 320;
1474 f->fmt.pix.height = 240;
1475 meye.params.subsample = 1;
1476 } else {
1477 f->fmt.pix.width = 640;
1478 f->fmt.pix.height = 480;
1479 meye.params.subsample = 0;
1480 }
1481 switch (f->fmt.pix.pixelformat) {
1482 case V4L2_PIX_FMT_YUYV:
1483 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
1484 break;
1485 case V4L2_PIX_FMT_MJPEG:
1486 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
1487 break;
1488 }
1489 up(&meye.lock);
1490 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1491 f->fmt.pix.sizeimage = f->fmt.pix.height *
1492 f->fmt.pix.bytesperline;
1493 f->fmt.pix.colorspace = 0;
1494 f->fmt.pix.priv = 0;
1495
1496 break;
1497 }
1498
1499 case VIDIOC_REQBUFS: {
1500 struct v4l2_requestbuffers *req = arg;
1501 int i;
1502
1503 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1504 return -EINVAL;
1505 if (req->memory != V4L2_MEMORY_MMAP)
1506 return -EINVAL;
1507 if (meye.grab_fbuffer && req->count == gbuffers) {
1508 /* already allocated, no modifications */
1509 break;
1510 }
1511 down(&meye.lock);
1512 if (meye.grab_fbuffer) {
1513 for (i = 0; i < gbuffers; i++)
1514 if (meye.vma_use_count[i]) {
1515 up(&meye.lock);
1516 return -EINVAL;
1517 }
1518 rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
1519 meye.grab_fbuffer = NULL;
1520 }
1521 gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));
1522 req->count = gbuffers;
1523 meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);
1524 if (!meye.grab_fbuffer) {
1525 printk(KERN_ERR "meye: v4l framebuffer allocation"
1526 " failed\n");
1527 up(&meye.lock);
1528 return -ENOMEM;
1529 }
1530 for (i = 0; i < gbuffers; i++)
1531 meye.vma_use_count[i] = 0;
1532 up(&meye.lock);
1533 break;
1534 }
1535
1536 case VIDIOC_QUERYBUF: {
1537 struct v4l2_buffer *buf = arg;
1538 int index = buf->index;
1539
1540 if (index < 0 || index >= gbuffers)
1541 return -EINVAL;
1542 memset(buf, 0, sizeof(*buf));
1543 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1544 buf->index = index;
1545 buf->bytesused = meye.grab_buffer[index].size;
1546 buf->flags = V4L2_BUF_FLAG_MAPPED;
1547 if (meye.grab_buffer[index].state == MEYE_BUF_USING)
1548 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1549 if (meye.grab_buffer[index].state == MEYE_BUF_DONE)
1550 buf->flags |= V4L2_BUF_FLAG_DONE;
1551 buf->field = V4L2_FIELD_NONE;
1552 buf->timestamp = meye.grab_buffer[index].timestamp;
1553 buf->sequence = meye.grab_buffer[index].sequence;
1554 buf->memory = V4L2_MEMORY_MMAP;
1555 buf->m.offset = index * gbufsize;
1556 buf->length = gbufsize;
1557 break;
1558 }
1559
1560 case VIDIOC_QBUF: {
1561 struct v4l2_buffer *buf = arg;
1562
1563 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1564 return -EINVAL;
1565 if (buf->memory != V4L2_MEMORY_MMAP)
1566 return -EINVAL;
1567 if (buf->index < 0 || buf->index >= gbuffers)
1568 return -EINVAL;
1569 if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
1570 return -EINVAL;
1571 down(&meye.lock);
1572 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1573 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1574 meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
1575 kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
1576 up(&meye.lock);
1577 break;
1578 }
1579
1580 case VIDIOC_DQBUF: {
1581 struct v4l2_buffer *buf = arg;
1582 int reqnr;
1583
1584 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1585 return -EINVAL;
1586 if (buf->memory != V4L2_MEMORY_MMAP)
1587 return -EINVAL;
1588
1589 down(&meye.lock);
1590 if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
1591 up(&meye.lock);
1592 return -EAGAIN;
1593 }
1594 if (wait_event_interruptible(meye.proc_list,
1595 kfifo_len(meye.doneq) != 0) < 0) {
1596 up(&meye.lock);
1597 return -EINTR;
1598 }
1599 if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
1600 sizeof(int))) {
1601 up(&meye.lock);
1602 return -EBUSY;
1603 }
1604 if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
1605 up(&meye.lock);
1606 return -EINVAL;
1607 }
1608 buf->index = reqnr;
1609 buf->bytesused = meye.grab_buffer[reqnr].size;
1610 buf->flags = V4L2_BUF_FLAG_MAPPED;
1611 buf->field = V4L2_FIELD_NONE;
1612 buf->timestamp = meye.grab_buffer[reqnr].timestamp;
1613 buf->sequence = meye.grab_buffer[reqnr].sequence;
1614 buf->memory = V4L2_MEMORY_MMAP;
1615 buf->m.offset = reqnr * gbufsize;
1616 buf->length = gbufsize;
1617 meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
1618 up(&meye.lock);
1619 break;
1620 }
1621
1622 case VIDIOC_STREAMON: {
1623 down(&meye.lock);
1624 switch (meye.mchip_mode) {
1625 case MCHIP_HIC_MODE_CONT_OUT:
1626 mchip_continuous_start();
1627 break;
1628 case MCHIP_HIC_MODE_CONT_COMP:
1629 mchip_cont_compression_start();
1630 break;
1631 default:
1632 up(&meye.lock);
1633 return -EINVAL;
1634 }
1635 up(&meye.lock);
1636 break;
1637 }
1638
1639 case VIDIOC_STREAMOFF: {
1640 int i;
1641
1642 down(&meye.lock);
1643 mchip_hic_stop();
1644 kfifo_reset(meye.grabq);
1645 kfifo_reset(meye.doneq);
1646 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
1647 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
1648 up(&meye.lock);
1649 break;
1650 }
1651
1652 /*
1653 * XXX what about private snapshot ioctls ?
1654 * Do they need to be converted to V4L2 ?
1655 */
1656
1657 default:
1658 return -ENOIOCTLCMD;
1659 }
1660
1661 return 0;
1662}
1663
1664static int meye_ioctl(struct inode *inode, struct file *file,
1665 unsigned int cmd, unsigned long arg)
1666{
1667 return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
1668}
1669
1670static unsigned int meye_poll(struct file *file, poll_table *wait)
1671{
1672 unsigned int res = 0;
1673
1674 down(&meye.lock);
1675 poll_wait(file, &meye.proc_list, wait);
1676 if (kfifo_len(meye.doneq))
1677 res = POLLIN | POLLRDNORM;
1678 up(&meye.lock);
1679 return res;
1680}
1681
1682static void meye_vm_open(struct vm_area_struct *vma)
1683{
1684 int idx = (int)vma->vm_private_data;
1685 meye.vma_use_count[idx]++;
1686}
1687
1688static void meye_vm_close(struct vm_area_struct *vma)
1689{
1690 int idx = (int)vma->vm_private_data;
1691 meye.vma_use_count[idx]--;
1692}
1693
1694static struct vm_operations_struct meye_vm_ops = {
1695 .open = meye_vm_open,
1696 .close = meye_vm_close,
1697};
1698
1699static int meye_mmap(struct file *file, struct vm_area_struct *vma)
1700{
1701 unsigned long start = vma->vm_start;
1702 unsigned long size = vma->vm_end - vma->vm_start;
1703 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1704 unsigned long page, pos;
1705
1706 down(&meye.lock);
1707 if (size > gbuffers * gbufsize) {
1708 up(&meye.lock);
1709 return -EINVAL;
1710 }
1711 if (!meye.grab_fbuffer) {
1712 int i;
1713
1714 /* lazy allocation */
1715 meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
1716 if (!meye.grab_fbuffer) {
1717 printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
1718 up(&meye.lock);
1719 return -ENOMEM;
1720 }
1721 for (i = 0; i < gbuffers; i++)
1722 meye.vma_use_count[i] = 0;
1723 }
1724 pos = (unsigned long)meye.grab_fbuffer + offset;
1725
1726 while (size > 0) {
1727 page = vmalloc_to_pfn((void *)pos);
1728 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1729 up(&meye.lock);
1730 return -EAGAIN;
1731 }
1732 start += PAGE_SIZE;
1733 pos += PAGE_SIZE;
1734 if (size > PAGE_SIZE)
1735 size -= PAGE_SIZE;
1736 else
1737 size = 0;
1738 }
1739
1740 vma->vm_ops = &meye_vm_ops;
1741 vma->vm_flags &= ~VM_IO; /* not I/O memory */
1742 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
1743 vma->vm_private_data = (void *) (offset / gbufsize);
1744 meye_vm_open(vma);
1745
1746 up(&meye.lock);
1747 return 0;
1748}
1749
1750static struct file_operations meye_fops = {
1751 .owner = THIS_MODULE,
1752 .open = meye_open,
1753 .release = meye_release,
1754 .mmap = meye_mmap,
1755 .ioctl = meye_ioctl,
1756 .poll = meye_poll,
1757 .llseek = no_llseek,
1758};
1759
1760static struct video_device meye_template = {
1761 .owner = THIS_MODULE,
1762 .name = "meye",
1763 .type = VID_TYPE_CAPTURE,
1764 .hardware = VID_HARDWARE_MEYE,
1765 .fops = &meye_fops,
1766 .release = video_device_release,
1767 .minor = -1,
1768};
1769
1770#ifdef CONFIG_PM
1771static int meye_suspend(struct pci_dev *pdev, u32 state)
1772{
1773 pci_save_state(pdev);
1774 meye.pm_mchip_mode = meye.mchip_mode;
1775 mchip_hic_stop();
1776 mchip_set(MCHIP_MM_INTA, 0x0);
1777 return 0;
1778}
1779
1780static int meye_resume(struct pci_dev *pdev)
1781{
1782 pci_restore_state(pdev);
1783 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1784
1785 mchip_delay(MCHIP_HIC_CMD, 0);
1786 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1787 msleep(1);
1788 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1789 msleep(1);
1790 mchip_set(MCHIP_MM_PCI_MODE, 5);
1791 msleep(1);
1792 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1793
1794 switch (meye.pm_mchip_mode) {
1795 case MCHIP_HIC_MODE_CONT_OUT:
1796 mchip_continuous_start();
1797 break;
1798 case MCHIP_HIC_MODE_CONT_COMP:
1799 mchip_cont_compression_start();
1800 break;
1801 }
1802 return 0;
1803}
1804#endif
1805
1806static int __devinit meye_probe(struct pci_dev *pcidev,
1807 const struct pci_device_id *ent)
1808{
1809 int ret = -EBUSY;
1810 unsigned long mchip_adr;
1811 u8 revision;
1812
1813 if (meye.mchip_dev != NULL) {
1814 printk(KERN_ERR "meye: only one device allowed!\n");
1815 goto outnotdev;
1816 }
1817
1818 meye.mchip_dev = pcidev;
1819 meye.video_dev = video_device_alloc();
1820 if (!meye.video_dev) {
1821 printk(KERN_ERR "meye: video_device_alloc() failed!\n");
1822 goto outnotdev;
1823 }
1824
1825 ret = -ENOMEM;
1826 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
1827 if (!meye.grab_temp) {
1828 printk(KERN_ERR "meye: grab buffer allocation failed\n");
1829 goto outvmalloc;
1830 }
1831
1832 spin_lock_init(&meye.grabq_lock);
1833 meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1834 &meye.grabq_lock);
1835 if (IS_ERR(meye.grabq)) {
1836 printk(KERN_ERR "meye: fifo allocation failed\n");
1837 goto outkfifoalloc1;
1838 }
1839 spin_lock_init(&meye.doneq_lock);
1840 meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1841 &meye.doneq_lock);
1842 if (IS_ERR(meye.doneq)) {
1843 printk(KERN_ERR "meye: fifo allocation failed\n");
1844 goto outkfifoalloc2;
1845 }
1846
1847 memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
1848 meye.video_dev->dev = &meye.mchip_dev->dev;
1849
1850 if ((ret = sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1))) {
1851 printk(KERN_ERR "meye: unable to power on the camera\n");
1852 printk(KERN_ERR "meye: did you enable the camera in "
1853 "sonypi using the module options ?\n");
1854 goto outsonypienable;
1855 }
1856
1857 ret = -EIO;
1858 if ((ret = pci_enable_device(meye.mchip_dev))) {
1859 printk(KERN_ERR "meye: pci_enable_device failed\n");
1860 goto outenabledev;
1861 }
1862
1863 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1864 if (!mchip_adr) {
1865 printk(KERN_ERR "meye: mchip has no device base address\n");
1866 goto outregions;
1867 }
1868 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1869 pci_resource_len(meye.mchip_dev, 0),
1870 "meye")) {
1871 printk(KERN_ERR "meye: request_mem_region failed\n");
1872 goto outregions;
1873 }
1874 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1875 if (!meye.mchip_mmregs) {
1876 printk(KERN_ERR "meye: ioremap failed\n");
1877 goto outremap;
1878 }
1879
1880 meye.mchip_irq = pcidev->irq;
1881 if (request_irq(meye.mchip_irq, meye_irq,
1882 SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq)) {
1883 printk(KERN_ERR "meye: request_irq failed\n");
1884 goto outreqirq;
1885 }
1886
1887 pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
1888 pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
1889 pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
1890
1891 pci_set_master(meye.mchip_dev);
1892
1893 /* Ask the camera to perform a soft reset. */
1894 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1895
1896 mchip_delay(MCHIP_HIC_CMD, 0);
1897 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1898
1899 msleep(1);
1900 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1901
1902 msleep(1);
1903 mchip_set(MCHIP_MM_PCI_MODE, 5);
1904
1905 msleep(1);
1906 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1907
1908 if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER,
1909 video_nr) < 0) {
1910 printk(KERN_ERR "meye: video_register_device failed\n");
1911 goto outvideoreg;
1912 }
1913
1914 init_MUTEX(&meye.lock);
1915 init_waitqueue_head(&meye.proc_list);
1916 meye.picture.depth = 16;
1917 meye.picture.palette = VIDEO_PALETTE_YUV422;
1918 meye.picture.brightness = 32 << 10;
1919 meye.picture.hue = 32 << 10;
1920 meye.picture.colour = 32 << 10;
1921 meye.picture.contrast = 32 << 10;
1922 meye.picture.whiteness = 0;
1923 meye.params.subsample = 0;
1924 meye.params.quality = 8;
1925 meye.params.sharpness = 32;
1926 meye.params.agc = 48;
1927 meye.params.picture = 0;
1928 meye.params.framerate = 0;
1929
1930 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32);
1931 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32);
1932 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32);
1933 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 32);
1934 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, 32);
1935 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0);
1936 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);
1937
1938 printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n",
1939 MEYE_DRIVER_VERSION);
1940 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
1941 revision, mchip_adr, meye.mchip_irq);
1942
1943 return 0;
1944
1945outvideoreg:
1946 free_irq(meye.mchip_irq, meye_irq);
1947outreqirq:
1948 iounmap(meye.mchip_mmregs);
1949outremap:
1950 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1951 pci_resource_len(meye.mchip_dev, 0));
1952outregions:
1953 pci_disable_device(meye.mchip_dev);
1954outenabledev:
1955 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1956outsonypienable:
1957 kfifo_free(meye.doneq);
1958outkfifoalloc2:
1959 kfifo_free(meye.grabq);
1960outkfifoalloc1:
1961 vfree(meye.grab_temp);
1962outvmalloc:
1963 video_device_release(meye.video_dev);
1964outnotdev:
1965 return ret;
1966}
1967
1968static void __devexit meye_remove(struct pci_dev *pcidev)
1969{
1970 video_unregister_device(meye.video_dev);
1971
1972 mchip_hic_stop();
1973
1974 mchip_dma_free();
1975
1976 /* disable interrupts */
1977 mchip_set(MCHIP_MM_INTA, 0x0);
1978
1979 free_irq(meye.mchip_irq, meye_irq);
1980
1981 iounmap(meye.mchip_mmregs);
1982
1983 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1984 pci_resource_len(meye.mchip_dev, 0));
1985
1986 pci_disable_device(meye.mchip_dev);
1987
1988 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1989
1990 kfifo_free(meye.doneq);
1991 kfifo_free(meye.grabq);
1992
1993 vfree(meye.grab_temp);
1994
1995 if (meye.grab_fbuffer) {
1996 rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
1997 meye.grab_fbuffer = NULL;
1998 }
1999
2000 printk(KERN_INFO "meye: removed\n");
2001}
2002
2003static struct pci_device_id meye_pci_tbl[] = {
2004 { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002,
2005 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2006 { }
2007};
2008
2009MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
2010
2011static struct pci_driver meye_driver = {
2012 .name = "meye",
2013 .id_table = meye_pci_tbl,
2014 .probe = meye_probe,
2015 .remove = __devexit_p(meye_remove),
2016#ifdef CONFIG_PM
2017 .suspend = meye_suspend,
2018 .resume = meye_resume,
2019#endif
2020};
2021
2022static int __init meye_init(void)
2023{
2024 gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
2025 if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
2026 gbufsize = MEYE_MAX_BUFSIZE;
2027 gbufsize = PAGE_ALIGN(gbufsize);
2028 printk(KERN_INFO "meye: using %d buffers with %dk (%dk total)"
2029 "for capture\n",
2030 gbuffers,
2031 gbufsize / 1024, gbuffers * gbufsize / 1024);
2032 return pci_register_driver(&meye_driver);
2033}
2034
2035static void __exit meye_exit(void)
2036{
2037 pci_unregister_driver(&meye_driver);
2038}
2039
2040module_init(meye_init);
2041module_exit(meye_exit);
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
new file mode 100644
index 000000000000..e8cd897b0d20
--- /dev/null
+++ b/drivers/media/video/meye.h
@@ -0,0 +1,318 @@
1/*
2 * Motion Eye video4linux driver for Sony Vaio PictureBook
3 *
4 * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
5 *
6 * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
7 *
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
9 *
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
11 *
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef _MEYE_PRIV_H_
31#define _MEYE_PRIV_H_
32
33#define MEYE_DRIVER_MAJORVERSION 1
34#define MEYE_DRIVER_MINORVERSION 13
35
36#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \
37 __stringify(MEYE_DRIVER_MINORVERSION)
38
39#include <linux/config.h>
40#include <linux/types.h>
41#include <linux/pci.h>
42#include <linux/kfifo.h>
43
44/****************************************************************************/
45/* Motion JPEG chip registers */
46/****************************************************************************/
47
48/* Motion JPEG chip PCI configuration registers */
49#define MCHIP_PCI_POWER_CSR 0x54
50#define MCHIP_PCI_MCORE_STATUS 0x60 /* see HIC_STATUS */
51#define MCHIP_PCI_HOSTUSEREQ_SET 0x64
52#define MCHIP_PCI_HOSTUSEREQ_CLR 0x68
53#define MCHIP_PCI_LOWPOWER_SET 0x6c
54#define MCHIP_PCI_LOWPOWER_CLR 0x70
55#define MCHIP_PCI_SOFTRESET_SET 0x74
56
57/* Motion JPEG chip memory mapped registers */
58#define MCHIP_MM_REGS 0x200 /* 512 bytes */
59#define MCHIP_REG_TIMEOUT 1000 /* reg access, ~us */
60#define MCHIP_MCC_VRJ_TIMEOUT 1000 /* MCC & VRJ access */
61
62#define MCHIP_MM_PCI_MODE 0x00 /* PCI access mode */
63#define MCHIP_MM_PCI_MODE_RETRY 0x00000001 /* retry mode */
64#define MCHIP_MM_PCI_MODE_MASTER 0x00000002 /* master access */
65#define MCHIP_MM_PCI_MODE_READ_LINE 0x00000004 /* read line */
66
67#define MCHIP_MM_INTA 0x04 /* Int status/mask */
68#define MCHIP_MM_INTA_MCC 0x00000001 /* MCC interrupt */
69#define MCHIP_MM_INTA_VRJ 0x00000002 /* VRJ interrupt */
70#define MCHIP_MM_INTA_HIC_1 0x00000004 /* one frame done */
71#define MCHIP_MM_INTA_HIC_1_MASK 0x00000400 /* 1: enable */
72#define MCHIP_MM_INTA_HIC_END 0x00000008 /* all frames done */
73#define MCHIP_MM_INTA_HIC_END_MASK 0x00000800
74#define MCHIP_MM_INTA_JPEG 0x00000010 /* decompress. error */
75#define MCHIP_MM_INTA_JPEG_MASK 0x00001000
76#define MCHIP_MM_INTA_CAPTURE 0x00000020 /* capture end */
77#define MCHIP_MM_INTA_PCI_ERR 0x00000040 /* PCI error */
78#define MCHIP_MM_INTA_PCI_ERR_MASK 0x00004000
79
80#define MCHIP_MM_PT_ADDR 0x08 /* page table address*/
81 /* n*4kB */
82#define MCHIP_NB_PAGES 1024 /* pages for display */
83#define MCHIP_NB_PAGES_MJPEG 256 /* pages for mjpeg */
84
85#define MCHIP_MM_FIR(n) (0x0c+(n)*4) /* Frame info 0-3 */
86#define MCHIP_MM_FIR_RDY 0x00000001 /* frame ready */
87#define MCHIP_MM_FIR_FAILFR_MASK 0xf8000000 /* # of failed frames */
88#define MCHIP_MM_FIR_FAILFR_SHIFT 27
89
90 /* continuous comp/decomp mode */
91#define MCHIP_MM_FIR_C_ENDL_MASK 0x000007fe /* end DW [10] */
92#define MCHIP_MM_FIR_C_ENDL_SHIFT 1
93#define MCHIP_MM_FIR_C_ENDP_MASK 0x0007f800 /* end page [8] */
94#define MCHIP_MM_FIR_C_ENDP_SHIFT 11
95#define MCHIP_MM_FIR_C_STARTP_MASK 0x07f80000 /* start page [8] */
96#define MCHIP_MM_FIR_C_STARTP_SHIFT 19
97
98 /* continuous picture output mode */
99#define MCHIP_MM_FIR_O_STARTP_MASK 0x7ffe0000 /* start page [10] */
100#define MCHIP_MM_FIR_O_STARTP_SHIFT 17
101
102#define MCHIP_MM_FIFO_DATA 0x1c /* PCI TGT FIFO data */
103#define MCHIP_MM_FIFO_STATUS 0x20 /* PCI TGT FIFO stat */
104#define MCHIP_MM_FIFO_MASK 0x00000003
105#define MCHIP_MM_FIFO_WAIT_OR_READY 0x00000002 /* Bits common to WAIT & READY*/
106#define MCHIP_MM_FIFO_IDLE 0x0 /* HIC idle */
107#define MCHIP_MM_FIFO_IDLE1 0x1 /* idem ??? */
108#define MCHIP_MM_FIFO_WAIT 0x2 /* wait request */
109#define MCHIP_MM_FIFO_READY 0x3 /* data ready */
110
111#define MCHIP_HIC_HOST_USEREQ 0x40 /* host uses MCORE */
112
113#define MCHIP_HIC_TP_BUSY 0x44 /* taking picture */
114
115#define MCHIP_HIC_PIC_SAVED 0x48 /* pic in SDRAM */
116
117#define MCHIP_HIC_LOWPOWER 0x4c /* clock stopped */
118
119#define MCHIP_HIC_CTL 0x50 /* HIC control */
120#define MCHIP_HIC_CTL_SOFT_RESET 0x00000001 /* MCORE reset */
121#define MCHIP_HIC_CTL_MCORE_RDY 0x00000002 /* MCORE ready */
122
123#define MCHIP_HIC_CMD 0x54 /* HIC command */
124#define MCHIP_HIC_CMD_BITS 0x00000003 /* cmd width=[1:0]*/
125#define MCHIP_HIC_CMD_NOOP 0x0
126#define MCHIP_HIC_CMD_START 0x1
127#define MCHIP_HIC_CMD_STOP 0x2
128
129#define MCHIP_HIC_MODE 0x58
130#define MCHIP_HIC_MODE_NOOP 0x0
131#define MCHIP_HIC_MODE_STILL_CAP 0x1 /* still pic capt */
132#define MCHIP_HIC_MODE_DISPLAY 0x2 /* display */
133#define MCHIP_HIC_MODE_STILL_COMP 0x3 /* still pic comp. */
134#define MCHIP_HIC_MODE_STILL_DECOMP 0x4 /* still pic decomp. */
135#define MCHIP_HIC_MODE_CONT_COMP 0x5 /* cont capt+comp */
136#define MCHIP_HIC_MODE_CONT_DECOMP 0x6 /* cont decomp+disp */
137#define MCHIP_HIC_MODE_STILL_OUT 0x7 /* still pic output */
138#define MCHIP_HIC_MODE_CONT_OUT 0x8 /* cont output */
139
140#define MCHIP_HIC_STATUS 0x5c
141#define MCHIP_HIC_STATUS_MCC_RDY 0x00000001 /* MCC reg acc ok */
142#define MCHIP_HIC_STATUS_VRJ_RDY 0x00000002 /* VRJ reg acc ok */
143#define MCHIP_HIC_STATUS_IDLE 0x00000003
144#define MCHIP_HIC_STATUS_CAPDIS 0x00000004 /* cap/disp in prog */
145#define MCHIP_HIC_STATUS_COMPDEC 0x00000008 /* (de)comp in prog */
146#define MCHIP_HIC_STATUS_BUSY 0x00000010 /* HIC busy */
147
148#define MCHIP_HIC_S_RATE 0x60 /* MJPEG # frames */
149
150#define MCHIP_HIC_PCI_VFMT 0x64 /* video format */
151#define MCHIP_HIC_PCI_VFMT_YVYU 0x00000001 /* 0: V Y' U Y */
152 /* 1: Y' V Y U */
153
154#define MCHIP_MCC_CMD 0x80 /* MCC commands */
155#define MCHIP_MCC_CMD_INITIAL 0x0 /* idle ? */
156#define MCHIP_MCC_CMD_IIC_START_SET 0x1
157#define MCHIP_MCC_CMD_IIC_END_SET 0x2
158#define MCHIP_MCC_CMD_FM_WRITE 0x3 /* frame memory */
159#define MCHIP_MCC_CMD_FM_READ 0x4
160#define MCHIP_MCC_CMD_FM_STOP 0x5
161#define MCHIP_MCC_CMD_CAPTURE 0x6
162#define MCHIP_MCC_CMD_DISPLAY 0x7
163#define MCHIP_MCC_CMD_END_DISP 0x8
164#define MCHIP_MCC_CMD_STILL_COMP 0x9
165#define MCHIP_MCC_CMD_STILL_DECOMP 0xa
166#define MCHIP_MCC_CMD_STILL_OUTPUT 0xb
167#define MCHIP_MCC_CMD_CONT_OUTPUT 0xc
168#define MCHIP_MCC_CMD_CONT_COMP 0xd
169#define MCHIP_MCC_CMD_CONT_DECOMP 0xe
170#define MCHIP_MCC_CMD_RESET 0xf /* MCC reset */
171
172#define MCHIP_MCC_IIC_WR 0x84
173
174#define MCHIP_MCC_MCC_WR 0x88
175
176#define MCHIP_MCC_MCC_RD 0x8c
177
178#define MCHIP_MCC_STATUS 0x90
179#define MCHIP_MCC_STATUS_CAPT 0x00000001 /* capturing */
180#define MCHIP_MCC_STATUS_DISP 0x00000002 /* displaying */
181#define MCHIP_MCC_STATUS_COMP 0x00000004 /* compressing */
182#define MCHIP_MCC_STATUS_DECOMP 0x00000008 /* decompressing */
183#define MCHIP_MCC_STATUS_MCC_WR 0x00000010 /* register ready */
184#define MCHIP_MCC_STATUS_MCC_RD 0x00000020 /* register ready */
185#define MCHIP_MCC_STATUS_IIC_WR 0x00000040 /* register ready */
186#define MCHIP_MCC_STATUS_OUTPUT 0x00000080 /* output in prog */
187
188#define MCHIP_MCC_SIG_POLARITY 0x94
189#define MCHIP_MCC_SIG_POL_VS_H 0x00000001 /* VS active-high */
190#define MCHIP_MCC_SIG_POL_HS_H 0x00000002 /* HS active-high */
191#define MCHIP_MCC_SIG_POL_DOE_H 0x00000004 /* DOE active-high */
192
193#define MCHIP_MCC_IRQ 0x98
194#define MCHIP_MCC_IRQ_CAPDIS_STRT 0x00000001 /* cap/disp started */
195#define MCHIP_MCC_IRQ_CAPDIS_STRT_MASK 0x00000010
196#define MCHIP_MCC_IRQ_CAPDIS_END 0x00000002 /* cap/disp ended */
197#define MCHIP_MCC_IRQ_CAPDIS_END_MASK 0x00000020
198#define MCHIP_MCC_IRQ_COMPDEC_STRT 0x00000004 /* (de)comp started */
199#define MCHIP_MCC_IRQ_COMPDEC_STRT_MASK 0x00000040
200#define MCHIP_MCC_IRQ_COMPDEC_END 0x00000008 /* (de)comp ended */
201#define MCHIP_MCC_IRQ_COMPDEC_END_MASK 0x00000080
202
203#define MCHIP_MCC_HSTART 0x9c /* video in */
204#define MCHIP_MCC_VSTART 0xa0
205#define MCHIP_MCC_HCOUNT 0xa4
206#define MCHIP_MCC_VCOUNT 0xa8
207#define MCHIP_MCC_R_XBASE 0xac /* capt/disp */
208#define MCHIP_MCC_R_YBASE 0xb0
209#define MCHIP_MCC_R_XRANGE 0xb4
210#define MCHIP_MCC_R_YRANGE 0xb8
211#define MCHIP_MCC_B_XBASE 0xbc /* comp/decomp */
212#define MCHIP_MCC_B_YBASE 0xc0
213#define MCHIP_MCC_B_XRANGE 0xc4
214#define MCHIP_MCC_B_YRANGE 0xc8
215
216#define MCHIP_MCC_R_SAMPLING 0xcc /* 1: 1:4 */
217
218#define MCHIP_VRJ_CMD 0x100 /* VRJ commands */
219
220/* VRJ registers (see table 12.2.4) */
221#define MCHIP_VRJ_COMPRESSED_DATA 0x1b0
222#define MCHIP_VRJ_PIXEL_DATA 0x1b8
223
224#define MCHIP_VRJ_BUS_MODE 0x100
225#define MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL 0x108
226#define MCHIP_VRJ_PDAT_USE 0x110
227#define MCHIP_VRJ_MODE_SPECIFY 0x118
228#define MCHIP_VRJ_LIMIT_COMPRESSED_LO 0x120
229#define MCHIP_VRJ_LIMIT_COMPRESSED_HI 0x124
230#define MCHIP_VRJ_COMP_DATA_FORMAT 0x128
231#define MCHIP_VRJ_TABLE_DATA 0x140
232#define MCHIP_VRJ_RESTART_INTERVAL 0x148
233#define MCHIP_VRJ_NUM_LINES 0x150
234#define MCHIP_VRJ_NUM_PIXELS 0x158
235#define MCHIP_VRJ_NUM_COMPONENTS 0x160
236#define MCHIP_VRJ_SOF1 0x168
237#define MCHIP_VRJ_SOF2 0x170
238#define MCHIP_VRJ_SOF3 0x178
239#define MCHIP_VRJ_SOF4 0x180
240#define MCHIP_VRJ_SOS 0x188
241#define MCHIP_VRJ_SOFT_RESET 0x190
242
243#define MCHIP_VRJ_STATUS 0x1c0
244#define MCHIP_VRJ_STATUS_BUSY 0x00001
245#define MCHIP_VRJ_STATUS_COMP_ACCESS 0x00002
246#define MCHIP_VRJ_STATUS_PIXEL_ACCESS 0x00004
247#define MCHIP_VRJ_STATUS_ERROR 0x00008
248
249#define MCHIP_VRJ_IRQ_FLAG 0x1c8
250#define MCHIP_VRJ_ERROR_REPORT 0x1d8
251
252#define MCHIP_VRJ_START_COMMAND 0x1a0
253
254/****************************************************************************/
255/* Driver definitions. */
256/****************************************************************************/
257
258/* Sony Programmable I/O Controller for accessing the camera commands */
259#include <linux/sonypi.h>
260
261/* private API definitions */
262#include <linux/meye.h>
263
264/* Enable jpg software correction */
265#define MEYE_JPEG_CORRECTION 1
266
267/* Maximum size of a buffer */
268#define MEYE_MAX_BUFSIZE 614400 /* 640 * 480 * 2 */
269
270/* Maximum number of buffers */
271#define MEYE_MAX_BUFNBRS 32
272
273/* State of a buffer */
274#define MEYE_BUF_UNUSED 0 /* not used */
275#define MEYE_BUF_USING 1 /* currently grabbing / playing */
276#define MEYE_BUF_DONE 2 /* done */
277
278/* grab buffer */
279struct meye_grab_buffer {
280 int state; /* state of buffer */
281 unsigned long size; /* size of jpg frame */
282 struct timeval timestamp; /* timestamp */
283 unsigned long sequence; /* sequence number */
284};
285
286/* size of kfifos containings buffer indices */
287#define MEYE_QUEUE_SIZE MEYE_MAX_BUFNBRS
288
289/* Motion Eye device structure */
290struct meye {
291 struct pci_dev *mchip_dev; /* pci device */
292 u8 mchip_irq; /* irq */
293 u8 mchip_mode; /* actual mchip mode: HIC_MODE... */
294 u8 mchip_fnum; /* current mchip frame number */
295 unsigned char __iomem *mchip_mmregs;/* mchip: memory mapped registers */
296 u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */
297 void *mchip_ptable_toc; /* mchip: ptable toc */
298 dma_addr_t mchip_dmahandle; /* mchip: dma handle to ptable toc */
299 unsigned char *grab_fbuffer; /* capture framebuffer */
300 unsigned char *grab_temp; /* temporary buffer */
301 /* list of buffers */
302 struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
303 int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
304 struct semaphore lock; /* semaphore for open/mmap... */
305 struct kfifo *grabq; /* queue for buffers to be grabbed */
306 spinlock_t grabq_lock; /* lock protecting the queue */
307 struct kfifo *doneq; /* queue for grabbed buffers */
308 spinlock_t doneq_lock; /* lock protecting the queue */
309 wait_queue_head_t proc_list; /* wait queue */
310 struct video_device *video_dev; /* video device parameters */
311 struct video_picture picture; /* video picture parameters */
312 struct meye_params params; /* additional parameters */
313#ifdef CONFIG_PM
314 u8 pm_mchip_mode; /* old mchip mode */
315#endif
316};
317
318#endif
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
new file mode 100644
index 000000000000..d996ec99caff
--- /dev/null
+++ b/drivers/media/video/msp3400.c
@@ -0,0 +1,1876 @@
1/*
2 * programming the msp34* sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * what works and what doesn't:
7 *
8 * AM-Mono
9 * Support for Hauppauge cards added (decoding handled by tuner) added by
10 * Frederic Crozat <fcrozat@mail.dotcom.fr>
11 *
12 * FM-Mono
13 * should work. The stereo modes are backward compatible to FM-mono,
14 * therefore FM-Mono should be allways available.
15 *
16 * FM-Stereo (B/G, used in germany)
17 * should work, with autodetect
18 *
19 * FM-Stereo (satellite)
20 * should work, no autodetect (i.e. default is mono, but you can
21 * switch to stereo -- untested)
22 *
23 * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
24 * should work, with autodetect. Support for NICAM was added by
25 * Pekka Pietikainen <pp@netppl.fi>
26 *
27 *
28 * TODO:
29 * - better SAT support
30 *
31 *
32 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
33 * using soundcore instead of OSS
34 *
35 */
36
37#include <linux/config.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/kernel.h>
41#include <linux/sched.h>
42#include <linux/string.h>
43#include <linux/timer.h>
44#include <linux/delay.h>
45#include <linux/errno.h>
46#include <linux/slab.h>
47#include <linux/i2c.h>
48#include <linux/videodev.h>
49#include <linux/init.h>
50#include <linux/smp_lock.h>
51#include <linux/kthread.h>
52#include <linux/suspend.h>
53#include <asm/semaphore.h>
54#include <asm/pgtable.h>
55
56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h"
59
60#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
63#define OPMODE_SIMPLER 2 /* use shorter programming (>= msp34xxG) */
64
65/* insmod parameters */
66static int opmode = OPMODE_AUTO;
67static int debug = 0; /* debug output */
68static int once = 0; /* no continous stereo monitoring */
69static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
70 the autoscan seems work well only with FM... */
71static int standard = 1; /* Override auto detect of audio standard, if needed. */
72static int dolby = 0;
73
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */
76
77struct msp3400c {
78 int rev1,rev2;
79
80 int opmode;
81 int mode;
82 int norm;
83 int nicam_on;
84 int acb;
85 int main, second; /* sound carrier */
86 int input;
87 int source; /* see msp34xxg_set_source */
88
89 /* v4l2 */
90 int audmode;
91 int rxsubchans;
92
93 int muted;
94 int volume, balance;
95 int bass, treble;
96
97 /* thread */
98 struct task_struct *kthread;
99 wait_queue_head_t wq;
100 int restart:1;
101 int watch_stereo:1;
102};
103
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
107#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
108
109#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
110
111/* ---------------------------------------------------------------------- */
112
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */
117module_param(opmode, int, 0444);
118
119/* read-write */
120module_param(once, int, 0644);
121module_param(debug, int, 0644);
122module_param(stereo_threshold, int, 0644);
123module_param(standard, int, 0644);
124module_param(amsound, int, 0644);
125module_param(dolby, int, 0644);
126
127MODULE_PARM_DESC(once, "No continuous stereo monitoring");
128MODULE_PARM_DESC(debug, "Enable debug messages");
129MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
130MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
131
132MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
133MODULE_AUTHOR("Gerd Knorr");
134MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
135
136/* ---------------------------------------------------------------------- */
137
138#define I2C_MSP3400C 0x80
139#define I2C_MSP3400C_ALT 0x88
140
141#define I2C_MSP3400C_DEM 0x10
142#define I2C_MSP3400C_DFP 0x12
143
144/* Addresses to scan */
145static unsigned short normal_i2c[] = {
146 I2C_MSP3400C >> 1,
147 I2C_MSP3400C_ALT >> 1,
148 I2C_CLIENT_END
149};
150static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
151I2C_CLIENT_INSMOD;
152
153/* ----------------------------------------------------------------------- */
154/* functions for talking to the MSP3400C Sound processor */
155
156static int msp3400c_reset(struct i2c_client *client)
157{
158 /* reset and read revision code */
159 static char reset_off[3] = { 0x00, 0x80, 0x00 };
160 static char reset_on[3] = { 0x00, 0x00, 0x00 };
161 static char write[3] = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e };
162 char read[2];
163 struct i2c_msg reset[2] = {
164 { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
165 { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
166 };
167 struct i2c_msg test[2] = {
168 { client->addr, 0, 3, write },
169 { client->addr, I2C_M_RD, 2, read },
170 };
171
172 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
173 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
174 (2 != i2c_transfer(client->adapter,test,2)) ) {
175 printk(KERN_ERR "msp3400: chip reset failed\n");
176 return -1;
177 }
178 return 0;
179}
180
181static int
182msp3400c_read(struct i2c_client *client, int dev, int addr)
183{
184 int err;
185
186 unsigned char write[3];
187 unsigned char read[2];
188 struct i2c_msg msgs[2] = {
189 { client->addr, 0, 3, write },
190 { client->addr, I2C_M_RD, 2, read }
191 };
192 write[0] = dev+1;
193 write[1] = addr >> 8;
194 write[2] = addr & 0xff;
195
196 for (err = 0; err < 3;) {
197 if (2 == i2c_transfer(client->adapter,msgs,2))
198 break;
199 err++;
200 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
201 err, dev, addr);
202 msleep(10);
203 }
204 if (3 == err) {
205 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
206 msp3400c_reset(client);
207 return -1;
208 }
209 return read[0] << 8 | read[1];
210}
211
212static int
213msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
214{
215 int err;
216 unsigned char buffer[5];
217
218 buffer[0] = dev;
219 buffer[1] = addr >> 8;
220 buffer[2] = addr & 0xff;
221 buffer[3] = val >> 8;
222 buffer[4] = val & 0xff;
223
224 for (err = 0; err < 3;) {
225 if (5 == i2c_master_send(client, buffer, 5))
226 break;
227 err++;
228 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
229 err, dev, addr);
230 msleep(10);
231 }
232 if (3 == err) {
233 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
234 msp3400c_reset(client);
235 return -1;
236 }
237 return 0;
238}
239
240/* ------------------------------------------------------------------------ */
241
242/* This macro is allowed for *constants* only, gcc must calculate it
243 at compile time. Remember -- no floats in kernel mode */
244#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
245
246#define MSP_MODE_AM_DETECT 0
247#define MSP_MODE_FM_RADIO 2
248#define MSP_MODE_FM_TERRA 3
249#define MSP_MODE_FM_SAT 4
250#define MSP_MODE_FM_NICAM1 5
251#define MSP_MODE_FM_NICAM2 6
252#define MSP_MODE_AM_NICAM 7
253#define MSP_MODE_BTSC 8
254#define MSP_MODE_EXTERN 9
255
256static struct MSP_INIT_DATA_DEM {
257 int fir1[6];
258 int fir2[6];
259 int cdo1;
260 int cdo2;
261 int ad_cv;
262 int mode_reg;
263 int dfp_src;
264 int dfp_matrix;
265} msp_init_data[] = {
266 /* AM (for carrier detect / msp3400) */
267 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
268 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
269 0x00d0, 0x0500, 0x0020, 0x3000},
270
271 /* AM (for carrier detect / msp3410) */
272 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
273 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
274 0x00d0, 0x0100, 0x0020, 0x3000},
275
276 /* FM Radio */
277 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
278 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
279 0x00d0, 0x0480, 0x0020, 0x3000 },
280
281 /* Terrestial FM-mono + FM-stereo */
282 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
283 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
284 0x00d0, 0x0480, 0x0030, 0x3000},
285
286 /* Sat FM-mono */
287 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
288 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
289 0x00c6, 0x0480, 0x0000, 0x3000},
290
291 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
292 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
293 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
294 0x00d0, 0x0040, 0x0120, 0x3000},
295
296 /* NICAM/FM -- I (6.0/6.552) */
297 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
298 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
299 0x00d0, 0x0040, 0x0120, 0x3000},
300
301 /* NICAM/AM -- L (6.5/5.85) */
302 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 },
303 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
304 0x00c6, 0x0140, 0x0120, 0x7c03},
305};
306
307struct CARRIER_DETECT {
308 int cdo;
309 char *name;
310};
311
312static struct CARRIER_DETECT carrier_detect_main[] = {
313 /* main carrier */
314 { MSP_CARRIER(4.5), "4.5 NTSC" },
315 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
316 { MSP_CARRIER(6.0), "6.0 PAL I" },
317 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
318};
319
320static struct CARRIER_DETECT carrier_detect_55[] = {
321 /* PAL B/G */
322 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
323 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
324};
325
326static struct CARRIER_DETECT carrier_detect_65[] = {
327 /* PAL SAT / SECAM */
328 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
329 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
330 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
331 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
332 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
333 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
334};
335
336#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
337
338/* ----------------------------------------------------------------------- */
339
340static int scarts[3][9] = {
341 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
342 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
343 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
344 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
345};
346
347static char *scart_names[] = {
348 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
349};
350
351static void
352msp3400c_set_scart(struct i2c_client *client, int in, int out)
353{
354 struct msp3400c *msp = i2c_get_clientdata(client);
355
356 if (-1 == scarts[out][in])
357 return;
358
359 dprintk(KERN_DEBUG
360 "msp34xx: scart switch: %s => %d\n",scart_names[in],out);
361 msp->acb &= ~scarts[out][SCART_MASK];
362 msp->acb |= scarts[out][in];
363 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
364}
365
366/* ------------------------------------------------------------------------ */
367
368static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
369{
370 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
371 msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
372 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
373 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
374 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
375}
376
377static void msp3400c_setvolume(struct i2c_client *client,
378 int muted, int volume, int balance)
379{
380 int val = 0, bal = 0;
381
382 if (!muted) {
383 val = (volume * 0x7F / 65535) << 8;
384 }
385 if (val) {
386 bal = (balance / 256) - 128;
387 }
388 dprintk(KERN_DEBUG
389 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
390 muted ? "on" : "off", volume, balance, val>>8, bal);
391 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
392 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
393 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
394 muted ? 0x01 : (val | 0x01));
395 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8);
396}
397
398static void msp3400c_setbass(struct i2c_client *client, int bass)
399{
400 int val = ((bass-32768) * 0x60 / 65535) << 8;
401
402 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
403 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
404}
405
406static void msp3400c_settreble(struct i2c_client *client, int treble)
407{
408 int val = ((treble-32768) * 0x60 / 65535) << 8;
409
410 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
411 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
412}
413
414static void msp3400c_setmode(struct i2c_client *client, int type)
415{
416 struct msp3400c *msp = i2c_get_clientdata(client);
417 int i;
418
419 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type);
420 msp->mode = type;
421 msp->audmode = V4L2_TUNER_MODE_MONO;
422 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
423
424 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */
425 msp_init_data[type].ad_cv);
426
427 for (i = 5; i >= 0; i--) /* fir 1 */
428 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
429 msp_init_data[type].fir1[i]);
430
431 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
432 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
433 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
434 for (i = 5; i >= 0; i--)
435 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
436 msp_init_data[type].fir2[i]);
437
438 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */
439 msp_init_data[type].mode_reg);
440
441 msp3400c_setcarrier(client, msp_init_data[type].cdo1,
442 msp_init_data[type].cdo2);
443
444 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
445
446 if (dolby) {
447 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
448 0x0520); /* I2S1 */
449 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
450 0x0620); /* I2S2 */
451 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
452 msp_init_data[type].dfp_src);
453 } else {
454 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
455 msp_init_data[type].dfp_src);
456 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
457 msp_init_data[type].dfp_src);
458 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
459 msp_init_data[type].dfp_src);
460 }
461 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
462 msp_init_data[type].dfp_src);
463 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
464 msp_init_data[type].dfp_matrix);
465
466 if (HAVE_NICAM(msp)) {
467 /* nicam prescale */
468 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
469 }
470}
471
472static int best_audio_mode(int rxsubchans)
473{
474 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
475 return V4L2_TUNER_MODE_STEREO;
476 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
477 return V4L2_TUNER_MODE_LANG1;
478 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
479 return V4L2_TUNER_MODE_LANG2;
480 return V4L2_TUNER_MODE_MONO;
481}
482
483/* turn on/off nicam + stereo */
484static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
485{
486 static char *strmode[16] = {
487#if __GNUC__ >= 3
488 [ 0 ... 15 ] = "invalid",
489#endif
490 [ V4L2_TUNER_MODE_MONO ] = "mono",
491 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
492 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
493 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
494 };
495 struct msp3400c *msp = i2c_get_clientdata(client);
496 int nicam=0; /* channel source: FM/AM or nicam */
497 int src=0;
498
499 BUG_ON(msp->opmode == OPMODE_SIMPLER);
500 msp->audmode = audmode;
501
502 /* switch demodulator */
503 switch (msp->mode) {
504 case MSP_MODE_FM_TERRA:
505 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n",
506 strmode[audmode]);
507 msp3400c_setcarrier(client,msp->second,msp->main);
508 switch (audmode) {
509 case V4L2_TUNER_MODE_STEREO:
510 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
511 break;
512 case V4L2_TUNER_MODE_MONO:
513 case V4L2_TUNER_MODE_LANG1:
514 case V4L2_TUNER_MODE_LANG2:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
516 break;
517 }
518 break;
519 case MSP_MODE_FM_SAT:
520 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n",
521 strmode[audmode]);
522 switch (audmode) {
523 case V4L2_TUNER_MODE_MONO:
524 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
525 break;
526 case V4L2_TUNER_MODE_STEREO:
527 msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
528 break;
529 case V4L2_TUNER_MODE_LANG1:
530 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
531 break;
532 case V4L2_TUNER_MODE_LANG2:
533 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
534 break;
535 }
536 break;
537 case MSP_MODE_FM_NICAM1:
538 case MSP_MODE_FM_NICAM2:
539 case MSP_MODE_AM_NICAM:
540 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n",
541 strmode[audmode]);
542 msp3400c_setcarrier(client,msp->second,msp->main);
543 if (msp->nicam_on)
544 nicam=0x0100;
545 break;
546 case MSP_MODE_BTSC:
547 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n",
548 strmode[audmode]);
549 nicam=0x0300;
550 break;
551 case MSP_MODE_EXTERN:
552 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n",
553 strmode[audmode]);
554 nicam = 0x0200;
555 break;
556 case MSP_MODE_FM_RADIO:
557 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n",
558 strmode[audmode]);
559 break;
560 default:
561 dprintk(KERN_DEBUG "msp3400: mono setstereo\n");
562 return;
563 }
564
565 /* switch audio */
566 switch (audmode) {
567 case V4L2_TUNER_MODE_STEREO:
568 src = 0x0020 | nicam;
569#if 0
570 /* spatial effect */
571 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
572#endif
573 break;
574 case V4L2_TUNER_MODE_MONO:
575 if (msp->mode == MSP_MODE_AM_NICAM) {
576 dprintk("msp3400: switching to AM mono\n");
577 /* AM mono decoding is handled by tuner, not MSP chip */
578 /* SCART switching control register */
579 msp3400c_set_scart(client,SCART_MONO,0);
580 src = 0x0200;
581 break;
582 }
583 case V4L2_TUNER_MODE_LANG1:
584 src = 0x0000 | nicam;
585 break;
586 case V4L2_TUNER_MODE_LANG2:
587 src = 0x0010 | nicam;
588 break;
589 }
590 dprintk(KERN_DEBUG
591 "msp3400: setstereo final source/matrix = 0x%x\n", src);
592
593 if (dolby) {
594 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
596 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
597 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
598 } else {
599 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
600 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
601 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
602 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
603 }
604}
605
606static void
607msp3400c_print_mode(struct msp3400c *msp)
608{
609 if (msp->main == msp->second) {
610 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n",
611 msp->main/910000,(msp->main/910)%1000);
612 } else {
613 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n",
614 msp->main/910000,(msp->main/910)%1000);
615 }
616 if (msp->mode == MSP_MODE_FM_NICAM1 ||
617 msp->mode == MSP_MODE_FM_NICAM2)
618 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
619 msp->second/910000,(msp->second/910)%1000);
620 if (msp->mode == MSP_MODE_AM_NICAM)
621 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n",
622 msp->second/910000,(msp->second/910)%1000);
623 if (msp->mode == MSP_MODE_FM_TERRA &&
624 msp->main != msp->second) {
625 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n",
626 msp->second/910000,(msp->second/910)%1000);
627 }
628}
629
630/* ----------------------------------------------------------------------- */
631
632struct REGISTER_DUMP {
633 int addr;
634 char *name;
635};
636
637static int
638autodetect_stereo(struct i2c_client *client)
639{
640 struct msp3400c *msp = i2c_get_clientdata(client);
641 int val;
642 int rxsubchans = msp->rxsubchans;
643 int newnicam = msp->nicam_on;
644 int update = 0;
645
646 switch (msp->mode) {
647 case MSP_MODE_FM_TERRA:
648 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
649 if (val > 32767)
650 val -= 65536;
651 dprintk(KERN_DEBUG
652 "msp34xx: stereo detect register: %d\n",val);
653 if (val > 4096) {
654 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
655 } else if (val < -4096) {
656 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
657 } else {
658 rxsubchans = V4L2_TUNER_SUB_MONO;
659 }
660 newnicam = 0;
661 break;
662 case MSP_MODE_FM_NICAM1:
663 case MSP_MODE_FM_NICAM2:
664 case MSP_MODE_AM_NICAM:
665 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
666 dprintk(KERN_DEBUG
667 "msp34xx: nicam sync=%d, mode=%d\n",
668 val & 1, (val & 0x1e) >> 1);
669
670 if (val & 1) {
671 /* nicam synced */
672 switch ((val & 0x1e) >> 1) {
673 case 0:
674 case 8:
675 rxsubchans = V4L2_TUNER_SUB_STEREO;
676 break;
677 case 1:
678 case 9:
679 rxsubchans = V4L2_TUNER_SUB_MONO
680 | V4L2_TUNER_SUB_LANG1;
681 break;
682 case 2:
683 case 10:
684 rxsubchans = V4L2_TUNER_SUB_MONO
685 | V4L2_TUNER_SUB_LANG1
686 | V4L2_TUNER_SUB_LANG2;
687 break;
688 default:
689 rxsubchans = V4L2_TUNER_SUB_MONO;
690 break;
691 }
692 newnicam=1;
693 } else {
694 newnicam = 0;
695 rxsubchans = V4L2_TUNER_SUB_MONO;
696 }
697 break;
698 case MSP_MODE_BTSC:
699 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
700 dprintk(KERN_DEBUG
701 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 val,
703 (val & 0x0002) ? "no" : "yes",
704 (val & 0x0004) ? "no" : "yes",
705 (val & 0x0040) ? "stereo" : "mono",
706 (val & 0x0080) ? ", nicam 2nd mono" : "",
707 (val & 0x0100) ? ", bilingual/SAP" : "");
708 rxsubchans = V4L2_TUNER_SUB_MONO;
709 if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
710 if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
711 break;
712 }
713 if (rxsubchans != msp->rxsubchans) {
714 update = 1;
715 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n",
716 msp->rxsubchans,rxsubchans);
717 msp->rxsubchans = rxsubchans;
718 }
719 if (newnicam != msp->nicam_on) {
720 update = 1;
721 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n",
722 msp->nicam_on,newnicam);
723 msp->nicam_on = newnicam;
724 }
725 return update;
726}
727
728/*
729 * A kernel thread for msp3400 control -- we don't want to block the
730 * in the ioctl while doing the sound carrier & stereo detect
731 */
732
733static int msp34xx_sleep(struct msp3400c *msp, int timeout)
734{
735 DECLARE_WAITQUEUE(wait, current);
736
737again:
738 add_wait_queue(&msp->wq, &wait);
739 if (!kthread_should_stop()) {
740 if (timeout < 0) {
741 set_current_state(TASK_INTERRUPTIBLE);
742 schedule();
743 } else {
744#if 0
745 /* hmm, that one doesn't return on wakeup ... */
746 msleep_interruptible(timeout);
747#else
748 set_current_state(TASK_INTERRUPTIBLE);
749 schedule_timeout(msecs_to_jiffies(timeout));
750#endif
751 }
752 }
753
754 remove_wait_queue(&msp->wq, &wait);
755
756 if (try_to_freeze(PF_FREEZE))
757 goto again;
758
759 return msp->restart;
760}
761
762/* stereo/multilang monitoring */
763static void watch_stereo(struct i2c_client *client)
764{
765 struct msp3400c *msp = i2c_get_clientdata(client);
766
767 if (autodetect_stereo(client))
768 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans));
769 if (once)
770 msp->watch_stereo = 0;
771}
772
773static int msp3400c_thread(void *data)
774{
775 struct i2c_client *client = data;
776 struct msp3400c *msp = i2c_get_clientdata(client);
777 struct CARRIER_DETECT *cd;
778 int count, max1,max2,val1,val2, val,this;
779
780 printk("msp3400: kthread started\n");
781 for (;;) {
782 d2printk("msp3400: thread: sleep\n");
783 msp34xx_sleep(msp,-1);
784 d2printk("msp3400: thread: wakeup\n");
785
786 restart:
787 dprintk("msp3410: thread: restart scan\n");
788 msp->restart = 0;
789 if (kthread_should_stop())
790 break;
791
792 if (VIDEO_MODE_RADIO == msp->norm ||
793 MSP_MODE_EXTERN == msp->mode) {
794 /* no carrier scan, just unmute */
795 printk("msp3400: thread: no carrier scan\n");
796 msp3400c_setvolume(client, msp->muted,
797 msp->volume, msp->balance);
798 continue;
799 }
800
801 /* mute */
802 msp3400c_setvolume(client, msp->muted, 0, 0);
803 msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
804 val1 = val2 = 0;
805 max1 = max2 = -1;
806 msp->watch_stereo = 0;
807
808 /* some time for the tuner to sync */
809 if (msp34xx_sleep(msp,200))
810 goto restart;
811
812 /* carrier detect pass #1 -- main carrier */
813 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
814
815 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
816 /* autodetect doesn't work well with AM ... */
817 max1 = 3;
818 count = 0;
819 dprintk("msp3400: AM sound override\n");
820 }
821
822 for (this = 0; this < count; this++) {
823 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
824 if (msp34xx_sleep(msp,100))
825 goto restart;
826 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
827 if (val > 32767)
828 val -= 65536;
829 if (val1 < val)
830 val1 = val, max1 = this;
831 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);
832 }
833
834 /* carrier detect pass #2 -- second (stereo) carrier */
835 switch (max1) {
836 case 1: /* 5.5 */
837 cd = carrier_detect_55;
838 count = CARRIER_COUNT(carrier_detect_55);
839 break;
840 case 3: /* 6.5 */
841 cd = carrier_detect_65;
842 count = CARRIER_COUNT(carrier_detect_65);
843 break;
844 case 0: /* 4.5 */
845 case 2: /* 6.0 */
846 default:
847 cd = NULL; count = 0;
848 break;
849 }
850
851 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
852 /* autodetect doesn't work well with AM ... */
853 cd = NULL; count = 0; max2 = 0;
854 }
855 for (this = 0; this < count; this++) {
856 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
857 if (msp34xx_sleep(msp,100))
858 goto restart;
859 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
860 if (val > 32767)
861 val -= 65536;
862 if (val2 < val)
863 val2 = val, max2 = this;
864 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);
865 }
866
867 /* programm the msp3400 according to the results */
868 msp->main = carrier_detect_main[max1].cdo;
869 switch (max1) {
870 case 1: /* 5.5 */
871 if (max2 == 0) {
872 /* B/G FM-stereo */
873 msp->second = carrier_detect_55[max2].cdo;
874 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
875 msp->nicam_on = 0;
876 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
877 msp->watch_stereo = 1;
878 } else if (max2 == 1 && HAVE_NICAM(msp)) {
879 /* B/G NICAM */
880 msp->second = carrier_detect_55[max2].cdo;
881 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
882 msp->nicam_on = 1;
883 msp3400c_setcarrier(client, msp->second, msp->main);
884 msp->watch_stereo = 1;
885 } else {
886 goto no_second;
887 }
888 break;
889 case 2: /* 6.0 */
890 /* PAL I NICAM */
891 msp->second = MSP_CARRIER(6.552);
892 msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
893 msp->nicam_on = 1;
894 msp3400c_setcarrier(client, msp->second, msp->main);
895 msp->watch_stereo = 1;
896 break;
897 case 3: /* 6.5 */
898 if (max2 == 1 || max2 == 2) {
899 /* D/K FM-stereo */
900 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
902 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
904 msp->watch_stereo = 1;
905 } else if (max2 == 0 &&
906 msp->norm == VIDEO_MODE_SECAM) {
907 /* L NICAM or AM-mono */
908 msp->second = carrier_detect_65[max2].cdo;
909 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
910 msp->nicam_on = 0;
911 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
912 msp3400c_setcarrier(client, msp->second, msp->main);
913 /* volume prescale for SCART (AM mono input) */
914 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
915 msp->watch_stereo = 1;
916 } else if (max2 == 0 && HAVE_NICAM(msp)) {
917 /* D/K NICAM */
918 msp->second = carrier_detect_65[max2].cdo;
919 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
920 msp->nicam_on = 1;
921 msp3400c_setcarrier(client, msp->second, msp->main);
922 msp->watch_stereo = 1;
923 } else {
924 goto no_second;
925 }
926 break;
927 case 0: /* 4.5 */
928 default:
929 no_second:
930 msp->second = carrier_detect_main[max1].cdo;
931 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
932 msp->nicam_on = 0;
933 msp3400c_setcarrier(client, msp->second, msp->main);
934 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
935 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
936 break;
937 }
938
939 /* unmute */
940 msp3400c_setvolume(client, msp->muted,
941 msp->volume, msp->balance);
942 if (debug)
943 msp3400c_print_mode(msp);
944
945 /* monitor tv audio mode */
946 while (msp->watch_stereo) {
947 if (msp34xx_sleep(msp,5000))
948 goto restart;
949 watch_stereo(client);
950 }
951 }
952 dprintk(KERN_DEBUG "msp3400: thread: exit\n");
953 return 0;
954}
955
956/* ----------------------------------------------------------------------- */
957/* this one uses the automatic sound standard detection of newer */
958/* msp34xx chip versions */
959
960static struct MODES {
961 int retval;
962 int main, second;
963 char *name;
964} modelist[] = {
965 { 0x0000, 0, 0, "ERROR" },
966 { 0x0001, 0, 0, "autodetect start" },
967 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
968 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
969 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
970 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
971 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
972 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
973 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
974 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
975 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
976 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
977 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
978 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
979 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
980 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
981 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
982 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
983 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
984 { -1, 0, 0, NULL }, /* EOF */
985};
986
987static inline const char *msp34xx_standard_mode_name(int mode)
988{
989 int i;
990 for (i = 0; modelist[i].name != NULL; i++)
991 if (modelist[i].retval == mode)
992 return modelist[i].name;
993 return "unknown";
994}
995
996static int msp34xx_modus(int norm)
997{
998 switch (norm) {
999 case VIDEO_MODE_PAL:
1000 return 0x1003;
1001 case VIDEO_MODE_NTSC: /* BTSC */
1002 return 0x2003;
1003 case VIDEO_MODE_SECAM:
1004 return 0x0003;
1005 case VIDEO_MODE_RADIO:
1006 return 0x0003;
1007 case VIDEO_MODE_AUTO:
1008 return 0x2003;
1009 default:
1010 return 0x0003;
1011 }
1012}
1013
1014static int msp34xx_standard(int norm)
1015{
1016 switch (norm) {
1017 case VIDEO_MODE_PAL:
1018 return 1;
1019 case VIDEO_MODE_NTSC: /* BTSC */
1020 return 0x0020;
1021 case VIDEO_MODE_SECAM:
1022 return 1;
1023 case VIDEO_MODE_RADIO:
1024 return 0x0040;
1025 default:
1026 return 1;
1027 }
1028}
1029
1030static int msp3410d_thread(void *data)
1031{
1032 struct i2c_client *client = data;
1033 struct msp3400c *msp = i2c_get_clientdata(client);
1034 int mode,val,i,std;
1035
1036 printk("msp3410: daemon started\n");
1037 for (;;) {
1038 d2printk(KERN_DEBUG "msp3410: thread: sleep\n");
1039 msp34xx_sleep(msp,-1);
1040 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n");
1041
1042 restart:
1043 dprintk("msp3410: thread: restart scan\n");
1044 msp->restart = 0;
1045 if (kthread_should_stop())
1046 break;
1047
1048 if (msp->mode == MSP_MODE_EXTERN) {
1049 /* no carrier scan needed, just unmute */
1050 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n");
1051 msp3400c_setvolume(client, msp->muted,
1052 msp->volume, msp->balance);
1053 continue;
1054 }
1055
1056 /* put into sane state (and mute) */
1057 msp3400c_reset(client);
1058
1059 /* some time for the tuner to sync */
1060 if (msp34xx_sleep(msp,200))
1061 goto restart;
1062
1063 /* start autodetect */
1064 mode = msp34xx_modus(msp->norm);
1065 std = msp34xx_standard(msp->norm);
1066 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1067 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1068 msp->watch_stereo = 0;
1069
1070 if (debug)
1071 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n",
1072 msp34xx_standard_mode_name(std) ,std);
1073
1074 if (std != 1) {
1075 /* programmed some specific mode */
1076 val = std;
1077 } else {
1078 /* triggered autodetect */
1079 for (;;) {
1080 if (msp34xx_sleep(msp,100))
1081 goto restart;
1082
1083 /* check results */
1084 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1085 if (val < 0x07ff)
1086 break;
1087 dprintk(KERN_DEBUG "msp3410: detection still in progress\n");
1088 }
1089 }
1090 for (i = 0; modelist[i].name != NULL; i++)
1091 if (modelist[i].retval == val)
1092 break;
1093 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n",
1094 modelist[i].name ? modelist[i].name : "unknown",
1095 val);
1096 msp->main = modelist[i].main;
1097 msp->second = modelist[i].second;
1098
1099 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1100 /* autodetection has failed, let backup */
1101 dprintk(KERN_DEBUG "msp3410: autodetection failed,"
1102 " switching to backup mode: %s (0x%04x)\n",
1103 modelist[8].name ? modelist[8].name : "unknown",val);
1104 val = 0x0009;
1105 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
1106 }
1107
1108 /* set various prescales */
1109 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
1110 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
1111 msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
1112
1113 /* set stereo */
1114 switch (val) {
1115 case 0x0008: /* B/G NICAM */
1116 case 0x000a: /* I NICAM */
1117 if (val == 0x0008)
1118 msp->mode = MSP_MODE_FM_NICAM1;
1119 else
1120 msp->mode = MSP_MODE_FM_NICAM2;
1121 /* just turn on stereo */
1122 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1123 msp->nicam_on = 1;
1124 msp->watch_stereo = 1;
1125 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
1126 break;
1127 case 0x0009:
1128 msp->mode = MSP_MODE_AM_NICAM;
1129 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1130 msp->nicam_on = 1;
1131 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO);
1132 msp->watch_stereo = 1;
1133 break;
1134 case 0x0020: /* BTSC */
1135 /* just turn on stereo */
1136 msp->mode = MSP_MODE_BTSC;
1137 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1138 msp->nicam_on = 0;
1139 msp->watch_stereo = 1;
1140 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
1141 break;
1142 case 0x0040: /* FM radio */
1143 msp->mode = MSP_MODE_FM_RADIO;
1144 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1145 msp->audmode = V4L2_TUNER_MODE_STEREO;
1146 msp->nicam_on = 0;
1147 msp->watch_stereo = 0;
1148 /* not needed in theory if HAVE_RADIO(), but
1149 short programming enables carrier mute */
1150 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1151 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1152 MSP_CARRIER(10.7));
1153 /* scart routing */
1154 msp3400c_set_scart(client,SCART_IN2,0);
1155#if 0
1156 /* radio from SCART_IN2 */
1157 msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
1158 msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
1159 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
1160#else
1161 /* msp34xx does radio decoding */
1162 msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
1163 msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
1164 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
1165#endif
1166 break;
1167 case 0x0003:
1168 case 0x0004:
1169 case 0x0005:
1170 msp->mode = MSP_MODE_FM_TERRA;
1171 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1172 msp->audmode = V4L2_TUNER_MODE_MONO;
1173 msp->nicam_on = 0;
1174 msp->watch_stereo = 1;
1175 break;
1176 }
1177
1178 /* unmute, restore misc registers */
1179 msp3400c_setbass(client, msp->bass);
1180 msp3400c_settreble(client, msp->treble);
1181 msp3400c_setvolume(client, msp->muted,
1182 msp->volume, msp->balance);
1183 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
1184
1185 /* monitor tv audio mode */
1186 while (msp->watch_stereo) {
1187 if (msp34xx_sleep(msp,5000))
1188 goto restart;
1189 watch_stereo(client);
1190 }
1191 }
1192 dprintk(KERN_DEBUG "msp3410: thread: exit\n");
1193 return 0;
1194}
1195
1196/* ----------------------------------------------------------------------- */
1197/* msp34xxG + (simpler no-thread) */
1198/* this one uses both automatic standard detection and automatic sound */
1199/* select which are available in the newer G versions */
1200/* struct msp: only norm, acb and source are really used in this mode */
1201
1202static void msp34xxg_set_source(struct i2c_client *client, int source);
1203
1204/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1205 * return 0 if it worked, -1 if it failed
1206 */
1207static int msp34xxg_init(struct i2c_client *client)
1208{
1209 struct msp3400c *msp = i2c_get_clientdata(client);
1210 int modus,std;
1211
1212 if (msp3400c_reset(client))
1213 return -1;
1214
1215 /* make sure that input/output is muted (paranoid mode) */
1216 if (msp3400c_write(client,
1217 I2C_MSP3400C_DFP,
1218 0x13, /* ACB */
1219 0x0f20 /* mute DSP input, mute SCART 1 */))
1220 return -1;
1221
1222 /* step-by-step initialisation, as described in the manual */
1223 modus = msp34xx_modus(msp->norm);
1224 std = msp34xx_standard(msp->norm);
1225 modus &= ~0x03; /* STATUS_CHANGE=0 */
1226 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
1227 if (msp3400c_write(client,
1228 I2C_MSP3400C_DEM,
1229 0x30/*MODUS*/,
1230 modus))
1231 return -1;
1232 if (msp3400c_write(client,
1233 I2C_MSP3400C_DEM,
1234 0x20/*stanard*/,
1235 std))
1236 return -1;
1237
1238 /* write the dfps that may have an influence on
1239 standard/audio autodetection right now */
1240 msp34xxg_set_source(client, msp->source);
1241
1242 if (msp3400c_write(client, I2C_MSP3400C_DFP,
1243 0x0e, /* AM/FM Prescale */
1244 0x3000 /* default: [15:8] 75khz deviation */))
1245 return -1;
1246
1247 if (msp3400c_write(client, I2C_MSP3400C_DFP,
1248 0x10, /* NICAM Prescale */
1249 0x5a00 /* default: 9db gain (as recommended) */))
1250 return -1;
1251
1252 if (msp3400c_write(client,
1253 I2C_MSP3400C_DEM,
1254 0x20, /* STANDARD SELECT */
1255 standard /* default: 0x01 for automatic standard select*/))
1256 return -1;
1257 return 0;
1258}
1259
1260static int msp34xxg_thread(void *data)
1261{
1262 struct i2c_client *client = data;
1263 struct msp3400c *msp = i2c_get_clientdata(client);
1264 int val, std, i;
1265
1266 printk("msp34xxg: daemon started\n");
1267 for (;;) {
1268 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n");
1269 msp34xx_sleep(msp,-1);
1270 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n");
1271
1272 restart:
1273 dprintk("msp34xxg: thread: restart scan\n");
1274 msp->restart = 0;
1275 if (kthread_should_stop())
1276 break;
1277
1278 /* setup the chip*/
1279 msp34xxg_init(client);
1280 std = standard;
1281 if (std != 0x01)
1282 goto unmute;
1283
1284 /* watch autodetect */
1285 dprintk("msp34xxg: triggered autodetect, waiting for result\n");
1286 for (i = 0; i < 10; i++) {
1287 if (msp34xx_sleep(msp,100))
1288 goto restart;
1289
1290 /* check results */
1291 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1292 if (val < 0x07ff) {
1293 std = val;
1294 break;
1295 }
1296 dprintk("msp34xxg: detection still in progress\n");
1297 }
1298 if (0x01 == std) {
1299 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n");
1300 continue;
1301 }
1302
1303 unmute:
1304 dprintk("msp34xxg: current mode: %s (0x%04x)\n",
1305 msp34xx_standard_mode_name(std), std);
1306
1307 /* unmute: dispatch sound to scart output, set scart volume */
1308 dprintk("msp34xxg: unmute\n");
1309
1310 msp3400c_setbass(client, msp->bass);
1311 msp3400c_settreble(client, msp->treble);
1312 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance);
1313
1314 /* restore ACB */
1315 if (msp3400c_write(client,
1316 I2C_MSP3400C_DFP,
1317 0x13, /* ACB */
1318 msp->acb))
1319 return -1;
1320 }
1321 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n");
1322 return 0;
1323}
1324
1325/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
1326 * the value for source is the same as bit 15:8 of DFP registers 0x08,
1327 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
1328 *
1329 * this function replaces msp3400c_setstereo
1330 */
1331static void msp34xxg_set_source(struct i2c_client *client, int source)
1332{
1333 struct msp3400c *msp = i2c_get_clientdata(client);
1334
1335 /* fix matrix mode to stereo and let the msp choose what
1336 * to output according to 'source', as recommended
1337 */
1338 int value = (source&0x07)<<8|(source==0 ? 0x00:0x20);
1339 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value);
1340 msp3400c_write(client,
1341 I2C_MSP3400C_DFP,
1342 0x08, /* Loudspeaker Output */
1343 value);
1344 msp3400c_write(client,
1345 I2C_MSP3400C_DFP,
1346 0x0a, /* SCART1 DA Output */
1347 value);
1348 msp3400c_write(client,
1349 I2C_MSP3400C_DFP,
1350 0x0c, /* Quasi-peak detector */
1351 value);
1352 /*
1353 * set identification threshold. Personally, I
1354 * I set it to a higher value that the default
1355 * of 0x190 to ignore noisy stereo signals.
1356 * this needs tuning. (recommended range 0x00a0-0x03c0)
1357 * 0x7f0 = forced mono mode
1358 */
1359 msp3400c_write(client,
1360 I2C_MSP3400C_DEM,
1361 0x22, /* a2 threshold for stereo/bilingual */
1362 source==0 ? 0x7f0:stereo_threshold);
1363 msp->source=source;
1364}
1365
1366static void msp34xxg_detect_stereo(struct i2c_client *client)
1367{
1368 struct msp3400c *msp = i2c_get_clientdata(client);
1369
1370 int status = msp3400c_read(client,
1371 I2C_MSP3400C_DEM,
1372 0x0200 /* STATUS */);
1373 int is_bilingual = status&0x100;
1374 int is_stereo = status&0x40;
1375
1376 msp->rxsubchans = 0;
1377 if (is_stereo)
1378 msp->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1379 else
1380 msp->rxsubchans |= V4L2_TUNER_SUB_MONO;
1381 if (is_bilingual) {
1382 msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2;
1383 /* I'm supposed to check whether it's SAP or not
1384 * and set only LANG2/SAP in this case. Yet, the MSP
1385 * does a lot of work to hide this and handle everything
1386 * the same way. I don't want to work around it so unless
1387 * this is a problem, I'll handle SAP just like lang1/lang2.
1388 */
1389 }
1390 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1391 status, is_stereo, is_bilingual, msp->rxsubchans);
1392}
1393
1394static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
1395{
1396 struct msp3400c *msp = i2c_get_clientdata(client);
1397 int source = 0;
1398
1399 switch (audmode) {
1400 case V4L2_TUNER_MODE_MONO:
1401 source=0; /* mono only */
1402 break;
1403 case V4L2_TUNER_MODE_STEREO:
1404 source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
1405 /* problem: that could also mean 2 (scart input) */
1406 break;
1407 case V4L2_TUNER_MODE_LANG1:
1408 source=3; /* stereo or A */
1409 break;
1410 case V4L2_TUNER_MODE_LANG2:
1411 source=4; /* stereo or B */
1412 break;
1413 default: /* doing nothing: a safe, sane default */
1414 audmode = 0;
1415 return;
1416 }
1417 msp->audmode = audmode;
1418 msp34xxg_set_source(client, source);
1419}
1420
1421
1422/* ----------------------------------------------------------------------- */
1423
1424static int msp_attach(struct i2c_adapter *adap, int addr, int kind);
1425static int msp_detach(struct i2c_client *client);
1426static int msp_probe(struct i2c_adapter *adap);
1427static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
1428
1429static int msp_suspend(struct device * dev, u32 state, u32 level);
1430static int msp_resume(struct device * dev, u32 level);
1431
1432static void msp_wake_thread(struct i2c_client *client);
1433
1434static struct i2c_driver driver = {
1435 .owner = THIS_MODULE,
1436 .name = "i2c msp3400 driver",
1437 .id = I2C_DRIVERID_MSP3400,
1438 .flags = I2C_DF_NOTIFY,
1439 .attach_adapter = msp_probe,
1440 .detach_client = msp_detach,
1441 .command = msp_command,
1442 .driver = {
1443 .suspend = msp_suspend,
1444 .resume = msp_resume,
1445 },
1446};
1447
1448static struct i2c_client client_template =
1449{
1450 I2C_DEVNAME("(unset)"),
1451 .flags = I2C_CLIENT_ALLOW_USE,
1452 .driver = &driver,
1453};
1454
1455static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1456{
1457 struct msp3400c *msp;
1458 struct i2c_client *c;
1459 int (*thread_func)(void *data) = NULL;
1460
1461 client_template.adapter = adap;
1462 client_template.addr = addr;
1463
1464 if (-1 == msp3400c_reset(&client_template)) {
1465 dprintk("msp3400: no chip found\n");
1466 return -1;
1467 }
1468
1469 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1470 return -ENOMEM;
1471 memcpy(c,&client_template,sizeof(struct i2c_client));
1472 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1473 kfree(c);
1474 return -ENOMEM;
1475 }
1476
1477 memset(msp,0,sizeof(struct msp3400c));
1478 msp->volume = 58880; /* 0db gain */
1479 msp->balance = 32768;
1480 msp->bass = 32768;
1481 msp->treble = 32768;
1482 msp->input = -1;
1483 msp->muted = 1;
1484
1485 i2c_set_clientdata(c, msp);
1486 init_waitqueue_head(&msp->wq);
1487
1488 if (-1 == msp3400c_reset(c)) {
1489 kfree(msp);
1490 kfree(c);
1491 dprintk("msp3400: no chip found\n");
1492 return -1;
1493 }
1494
1495 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
1496 if (-1 != msp->rev1)
1497 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
1498 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1499 kfree(msp);
1500 kfree(c);
1501 printk("msp3400: error while reading chip version\n");
1502 return -1;
1503 }
1504
1505#if 0
1506 /* this will turn on a 1kHz beep - might be useful for debugging... */
1507 msp3400c_write(c,I2C_MSP3400C_DFP, 0x0014, 0x1040);
1508#endif
1509 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
1510
1511 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d",
1512 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
1513 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1514
1515 msp->opmode = opmode;
1516 if (OPMODE_AUTO == msp->opmode) {
1517#if 0 /* seems to work for ivtv only, disable by default for now ... */
1518 if (HAVE_SIMPLER(msp))
1519 msp->opmode = OPMODE_SIMPLER;
1520 else
1521#endif
1522 if (HAVE_SIMPLE(msp))
1523 msp->opmode = OPMODE_SIMPLE;
1524 else
1525 msp->opmode = OPMODE_MANUAL;
1526 }
1527
1528 /* hello world :-) */
1529 printk(KERN_INFO "msp34xx: init: chip=%s",i2c_clientname(c));
1530 if (HAVE_NICAM(msp))
1531 printk(" +nicam");
1532 if (HAVE_SIMPLE(msp))
1533 printk(" +simple");
1534 if (HAVE_SIMPLER(msp))
1535 printk(" +simpler");
1536 if (HAVE_RADIO(msp))
1537 printk(" +radio");
1538
1539 /* version-specific initialization */
1540 switch (msp->opmode) {
1541 case OPMODE_MANUAL:
1542 printk(" mode=manual");
1543 thread_func = msp3400c_thread;
1544 break;
1545 case OPMODE_SIMPLE:
1546 printk(" mode=simple");
1547 thread_func = msp3410d_thread;
1548 break;
1549 case OPMODE_SIMPLER:
1550 printk(" mode=simpler");
1551 thread_func = msp34xxg_thread;
1552 break;
1553 }
1554 printk("\n");
1555
1556 /* startup control thread if needed */
1557 if (thread_func) {
1558 msp->kthread = kthread_run(thread_func, c, "msp34xx");
1559 if (NULL == msp->kthread)
1560 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
1561 msp_wake_thread(c);
1562 }
1563
1564 /* done */
1565 i2c_attach_client(c);
1566 return 0;
1567}
1568
1569static int msp_detach(struct i2c_client *client)
1570{
1571 struct msp3400c *msp = i2c_get_clientdata(client);
1572
1573 /* shutdown control thread */
1574 if (msp->kthread >= 0) {
1575 msp->restart = 1;
1576 kthread_stop(msp->kthread);
1577 }
1578 msp3400c_reset(client);
1579
1580 i2c_detach_client(client);
1581 kfree(msp);
1582 kfree(client);
1583 return 0;
1584}
1585
1586static int msp_probe(struct i2c_adapter *adap)
1587{
1588 if (adap->class & I2C_CLASS_TV_ANALOG)
1589 return i2c_probe(adap, &addr_data, msp_attach);
1590 return 0;
1591}
1592
1593static void msp_wake_thread(struct i2c_client *client)
1594{
1595 struct msp3400c *msp = i2c_get_clientdata(client);
1596
1597 if (NULL == msp->kthread)
1598 return;
1599 msp3400c_setvolume(client,msp->muted,0,0);
1600 msp->watch_stereo = 0;
1601 msp->restart = 1;
1602 wake_up_interruptible(&msp->wq);
1603}
1604
1605/* ----------------------------------------------------------------------- */
1606
1607static int mode_v4l2_to_v4l1(int rxsubchans)
1608{
1609 int mode = 0;
1610
1611 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
1612 mode |= VIDEO_SOUND_STEREO;
1613 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
1614 mode |= VIDEO_SOUND_LANG2;
1615 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
1616 mode |= VIDEO_SOUND_LANG1;
1617 if (0 == mode)
1618 mode |= VIDEO_SOUND_MONO;
1619 return mode;
1620}
1621
1622static int mode_v4l1_to_v4l2(int mode)
1623{
1624 if (mode & VIDEO_SOUND_STEREO)
1625 return V4L2_TUNER_MODE_STEREO;
1626 if (mode & VIDEO_SOUND_LANG2)
1627 return V4L2_TUNER_MODE_LANG2;
1628 if (mode & VIDEO_SOUND_LANG1)
1629 return V4L2_TUNER_MODE_LANG1;
1630 return V4L2_TUNER_MODE_MONO;
1631}
1632
1633static void msp_any_detect_stereo(struct i2c_client *client)
1634{
1635 struct msp3400c *msp = i2c_get_clientdata(client);
1636
1637 switch (msp->opmode) {
1638 case OPMODE_MANUAL:
1639 case OPMODE_SIMPLE:
1640 autodetect_stereo(client);
1641 break;
1642 case OPMODE_SIMPLER:
1643 msp34xxg_detect_stereo(client);
1644 break;
1645 }
1646}
1647
1648static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1649{
1650 struct msp3400c *msp = i2c_get_clientdata(client);
1651
1652 switch (msp->opmode) {
1653 case OPMODE_MANUAL:
1654 case OPMODE_SIMPLE:
1655 msp->watch_stereo = 0;
1656 msp3400c_set_audmode(client, audmode);
1657 break;
1658 case OPMODE_SIMPLER:
1659 msp34xxg_set_audmode(client, audmode);
1660 break;
1661 }
1662}
1663
1664static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1665{
1666 struct msp3400c *msp = i2c_get_clientdata(client);
1667 __u16 *sarg = arg;
1668 int scart = 0;
1669
1670 switch (cmd) {
1671
1672 case AUDC_SET_INPUT:
1673 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
1674 if (*sarg == msp->input)
1675 break;
1676 msp->input = *sarg;
1677 switch (*sarg) {
1678 case AUDIO_RADIO:
1679 /* Hauppauge uses IN2 for the radio */
1680 msp->mode = MSP_MODE_FM_RADIO;
1681 scart = SCART_IN2;
1682 break;
1683 case AUDIO_EXTERN_1:
1684 /* IN1 is often used for external input ... */
1685 msp->mode = MSP_MODE_EXTERN;
1686 scart = SCART_IN1;
1687 break;
1688 case AUDIO_EXTERN_2:
1689 /* ... sometimes it is IN2 through ;) */
1690 msp->mode = MSP_MODE_EXTERN;
1691 scart = SCART_IN2;
1692 break;
1693 case AUDIO_TUNER:
1694 msp->mode = -1;
1695 break;
1696 default:
1697 if (*sarg & AUDIO_MUTE)
1698 msp3400c_set_scart(client,SCART_MUTE,0);
1699 break;
1700 }
1701 if (scart) {
1702 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1703 msp->audmode = V4L2_TUNER_MODE_STEREO;
1704 msp3400c_set_scart(client,scart,0);
1705 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1706 if (msp->opmode != OPMODE_SIMPLER)
1707 msp3400c_set_audmode(client, msp->audmode);
1708 }
1709 msp_wake_thread(client);
1710 break;
1711
1712 case AUDC_SET_RADIO:
1713 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n");
1714 msp->norm = VIDEO_MODE_RADIO;
1715 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n");
1716 msp->watch_stereo = 0;
1717 switch (msp->opmode) {
1718 case OPMODE_MANUAL:
1719 /* set msp3400 to FM radio mode */
1720 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1721 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1722 MSP_CARRIER(10.7));
1723 msp3400c_setvolume(client, msp->muted,
1724 msp->volume, msp->balance);
1725 break;
1726 case OPMODE_SIMPLE:
1727 case OPMODE_SIMPLER:
1728 /* the thread will do for us */
1729 msp_wake_thread(client);
1730 break;
1731 }
1732 break;
1733
1734 /* --- v4l ioctls --- */
1735 /* take care: bttv does userspace copying, we'll get a
1736 kernel pointer here... */
1737 case VIDIOCGAUDIO:
1738 {
1739 struct video_audio *va = arg;
1740
1741 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n");
1742 va->flags |= VIDEO_AUDIO_VOLUME |
1743 VIDEO_AUDIO_BASS |
1744 VIDEO_AUDIO_TREBLE |
1745 VIDEO_AUDIO_MUTABLE;
1746 if (msp->muted)
1747 va->flags |= VIDEO_AUDIO_MUTE;
1748
1749 va->volume = msp->volume;
1750 va->balance = (va->volume) ? msp->balance : 32768;
1751 va->bass = msp->bass;
1752 va->treble = msp->treble;
1753
1754 msp_any_detect_stereo(client);
1755 va->mode = mode_v4l2_to_v4l1(msp->rxsubchans);
1756 break;
1757 }
1758 case VIDIOCSAUDIO:
1759 {
1760 struct video_audio *va = arg;
1761
1762 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n");
1763 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1764 msp->volume = va->volume;
1765 msp->balance = va->balance;
1766 msp->bass = va->bass;
1767 msp->treble = va->treble;
1768
1769 msp3400c_setvolume(client, msp->muted,
1770 msp->volume, msp->balance);
1771 msp3400c_setbass(client,msp->bass);
1772 msp3400c_settreble(client,msp->treble);
1773
1774 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1775 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1776 break;
1777 }
1778 case VIDIOCSCHAN:
1779 {
1780 struct video_channel *vc = arg;
1781
1782 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm);
1783 msp->norm = vc->norm;
1784 msp_wake_thread(client);
1785 break;
1786 }
1787
1788 case VIDIOCSFREQ:
1789 case VIDIOC_S_FREQUENCY:
1790 {
1791 /* new channel -- kick audio carrier scan */
1792 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n");
1793 msp_wake_thread(client);
1794 break;
1795 }
1796
1797 /* --- v4l2 ioctls --- */
1798 case VIDIOC_G_TUNER:
1799 {
1800 struct v4l2_tuner *vt = arg;
1801
1802 msp_any_detect_stereo(client);
1803 vt->audmode = msp->audmode;
1804 vt->rxsubchans = msp->rxsubchans;
1805 vt->capability = V4L2_TUNER_CAP_STEREO |
1806 V4L2_TUNER_CAP_LANG1|
1807 V4L2_TUNER_CAP_LANG2;
1808 break;
1809 }
1810 case VIDIOC_S_TUNER:
1811 {
1812 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
1813
1814 /* only set audmode */
1815 if (vt->audmode != -1 && vt->audmode != 0)
1816 msp_any_set_audmode(client, vt->audmode);
1817 break;
1818 }
1819
1820 /* msp34xx specific */
1821 case MSP_SET_MATRIX:
1822 {
1823 struct msp_matrix *mspm = arg;
1824
1825 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1826 msp3400c_set_scart(client, mspm->input, mspm->output);
1827 break;
1828 }
1829
1830 default:
1831 /* nothing */
1832 break;
1833 }
1834 return 0;
1835}
1836
1837static int msp_suspend(struct device * dev, u32 state, u32 level)
1838{
1839 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
1840
1841 dprintk("msp34xx: suspend\n");
1842 msp3400c_reset(c);
1843 return 0;
1844}
1845
1846static int msp_resume(struct device * dev, u32 level)
1847{
1848 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
1849
1850 dprintk("msp34xx: resume\n");
1851 msp_wake_thread(c);
1852 return 0;
1853}
1854
1855/* ----------------------------------------------------------------------- */
1856
1857static int __init msp3400_init_module(void)
1858{
1859 return i2c_add_driver(&driver);
1860}
1861
1862static void __exit msp3400_cleanup_module(void)
1863{
1864 i2c_del_driver(&driver);
1865}
1866
1867module_init(msp3400_init_module);
1868module_exit(msp3400_cleanup_module);
1869
1870/*
1871 * Overrides for Emacs so that we follow Linus's tabbing style.
1872 * ---------------------------------------------------------------------------
1873 * Local variables:
1874 * c-basic-offset: 8
1875 * End:
1876 */
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
new file mode 100644
index 000000000000..d70a954e13aa
--- /dev/null
+++ b/drivers/media/video/msp3400.h
@@ -0,0 +1,36 @@
1#ifndef MSP3400_H
2#define MSP3400_H
3
4/* ---------------------------------------------------------------------- */
5
6struct msp_dfpreg {
7 int reg;
8 int value;
9};
10
11struct msp_matrix {
12 int input;
13 int output;
14};
15
16#define MSP_SET_DFPREG _IOW('m',15,struct msp_dfpreg)
17#define MSP_GET_DFPREG _IOW('m',16,struct msp_dfpreg)
18
19/* ioctl for MSP_SET_MATRIX will have to be registered */
20#define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix)
21
22#define SCART_MASK 0
23#define SCART_IN1 1
24#define SCART_IN2 2
25#define SCART_IN1_DA 3
26#define SCART_IN2_DA 4
27#define SCART_IN3 5
28#define SCART_IN4 6
29#define SCART_MONO 7
30#define SCART_MUTE 8
31
32#define SCART_DSP_IN 0
33#define SCART1_OUT 1
34#define SCART2_OUT 2
35
36#endif /* MSP3400_H */
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
new file mode 100644
index 000000000000..95ad17b7f38e
--- /dev/null
+++ b/drivers/media/video/mt20xx.c
@@ -0,0 +1,558 @@
1/*
2 * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls microtune tuners, mt2032 + mt2050 at the moment.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/moduleparam.h>
11#include <media/tuner.h>
12
13/* ---------------------------------------------------------------------- */
14
15static unsigned int optimize_vco = 1;
16module_param(optimize_vco, int, 0644);
17
18static unsigned int tv_antenna = 1;
19module_param(tv_antenna, int, 0644);
20
21static unsigned int radio_antenna = 0;
22module_param(radio_antenna, int, 0644);
23
24/* ---------------------------------------------------------------------- */
25
26#define MT2032 0x04
27#define MT2030 0x06
28#define MT2040 0x07
29#define MT2050 0x42
30
31static char *microtune_part[] = {
32 [ MT2030 ] = "MT2030",
33 [ MT2032 ] = "MT2032",
34 [ MT2040 ] = "MT2040",
35 [ MT2050 ] = "MT2050",
36};
37
38// IsSpurInBand()?
39static int mt2032_spurcheck(struct i2c_client *c,
40 int f1, int f2, int spectrum_from,int spectrum_to)
41{
42 struct tuner *t = i2c_get_clientdata(c);
43 int n1=1,n2,f;
44
45 f1=f1/1000; //scale to kHz to avoid 32bit overflows
46 f2=f2/1000;
47 spectrum_from/=1000;
48 spectrum_to/=1000;
49
50 tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n",
51 f1,f2,spectrum_from,spectrum_to);
52
53 do {
54 n2=-n1;
55 f=n1*(f1-f2);
56 do {
57 n2--;
58 f=f-f2;
59 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
60
61 if( (f>spectrum_from) && (f<spectrum_to))
62 tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
63 } while ( (f>(f2-spectrum_to)) || (n2>-5));
64 n1++;
65 } while (n1<5);
66
67 return 1;
68}
69
70static int mt2032_compute_freq(struct i2c_client *c,
71 unsigned int rfin,
72 unsigned int if1, unsigned int if2,
73 unsigned int spectrum_from,
74 unsigned int spectrum_to,
75 unsigned char *buf,
76 int *ret_sel,
77 unsigned int xogc) //all in Hz
78{
79 struct tuner *t = i2c_get_clientdata(c);
80 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
81 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
82
83 fref= 5250 *1000; //5.25MHz
84 desired_lo1=rfin+if1;
85
86 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
87 lo1n=lo1/8;
88 lo1a=lo1-(lo1n*8);
89
90 s=rfin/1000/1000+1090;
91
92 if(optimize_vco) {
93 if(s>1890) sel=0;
94 else if(s>1720) sel=1;
95 else if(s>1530) sel=2;
96 else if(s>1370) sel=3;
97 else sel=4; // >1090
98 }
99 else {
100 if(s>1790) sel=0; // <1958
101 else if(s>1617) sel=1;
102 else if(s>1449) sel=2;
103 else if(s>1291) sel=3;
104 else sel=4; // >1090
105 }
106 *ret_sel=sel;
107
108 lo1freq=(lo1a+8*lo1n)*fref;
109
110 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
111 rfin,lo1,lo1n,lo1a,sel,lo1freq);
112
113 desired_lo2=lo1freq-rfin-if2;
114 lo2=(desired_lo2)/fref;
115 lo2n=lo2/8;
116 lo2a=lo2-(lo2n*8);
117 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
118 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
119
120 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
121 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
122
123 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
124 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
125 lo1a, lo1n, lo2a,lo2n);
126 return(-1);
127 }
128
129 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
130 // should recalculate lo1 (one step up/down)
131
132 // set up MT2032 register map for transfer over i2c
133 buf[0]=lo1n-1;
134 buf[1]=lo1a | (sel<<4);
135 buf[2]=0x86; // LOGC
136 buf[3]=0x0f; //reserved
137 buf[4]=0x1f;
138 buf[5]=(lo2n-1) | (lo2a<<5);
139 if(rfin >400*1000*1000)
140 buf[6]=0xe4;
141 else
142 buf[6]=0xf4; // set PKEN per rev 1.2
143 buf[7]=8+xogc;
144 buf[8]=0xc3; //reserved
145 buf[9]=0x4e; //reserved
146 buf[10]=0xec; //reserved
147 buf[11]=(lo2num&0xff);
148 buf[12]=(lo2num>>8) |0x80; // Lo2RST
149
150 return 0;
151}
152
153static int mt2032_check_lo_lock(struct i2c_client *c)
154{
155 struct tuner *t = i2c_get_clientdata(c);
156 int try,lock=0;
157 unsigned char buf[2];
158
159 for(try=0;try<10;try++) {
160 buf[0]=0x0e;
161 i2c_master_send(c,buf,1);
162 i2c_master_recv(c,buf,1);
163 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
164 lock=buf[0] &0x06;
165
166 if (lock==6)
167 break;
168
169 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
170 udelay(1000);
171 }
172 return lock;
173}
174
175static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
176{
177 struct tuner *t = i2c_get_clientdata(c);
178 unsigned char buf[2];
179 int tad1;
180
181 buf[0]=0x0f;
182 i2c_master_send(c,buf,1);
183 i2c_master_recv(c,buf,1);
184 tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
185 tad1=buf[0]&0x07;
186
187 if(tad1 ==0) return lock;
188 if(tad1 ==1) return lock;
189
190 if(tad1==2) {
191 if(sel==0)
192 return lock;
193 else sel--;
194 }
195 else {
196 if(sel<4)
197 sel++;
198 else
199 return lock;
200 }
201
202 tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
203
204 buf[0]=0x0f;
205 buf[1]=sel;
206 i2c_master_send(c,buf,2);
207 lock=mt2032_check_lo_lock(c);
208 return lock;
209}
210
211
212static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
213 unsigned int if1, unsigned int if2,
214 unsigned int from, unsigned int to)
215{
216 unsigned char buf[21];
217 int lint_try,ret,sel,lock=0;
218 struct tuner *t = i2c_get_clientdata(c);
219
220 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
221 rfin,if1,if2,from,to);
222
223 buf[0]=0;
224 ret=i2c_master_send(c,buf,1);
225 i2c_master_recv(c,buf,21);
226
227 buf[0]=0;
228 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
229 if (ret<0)
230 return;
231
232 // send only the relevant registers per Rev. 1.2
233 buf[0]=0;
234 ret=i2c_master_send(c,buf,4);
235 buf[5]=5;
236 ret=i2c_master_send(c,buf+5,4);
237 buf[11]=11;
238 ret=i2c_master_send(c,buf+11,3);
239 if(ret!=3)
240 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
241
242 // wait for PLLs to lock (per manual), retry LINT if not.
243 for(lint_try=0; lint_try<2; lint_try++) {
244 lock=mt2032_check_lo_lock(c);
245
246 if(optimize_vco)
247 lock=mt2032_optimize_vco(c,sel,lock);
248 if(lock==6) break;
249
250 tuner_dbg("mt2032: re-init PLLs by LINT\n");
251 buf[0]=7;
252 buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs
253 i2c_master_send(c,buf,2);
254 mdelay(10);
255 buf[1]=8+t->xogc;
256 i2c_master_send(c,buf,2);
257 }
258
259 if (lock!=6)
260 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
261
262 buf[0]=2;
263 buf[1]=0x20; // LOGC for optimal phase noise
264 ret=i2c_master_send(c,buf,2);
265 if (ret!=2)
266 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
267}
268
269
270static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
271{
272 struct tuner *t = i2c_get_clientdata(c);
273 int if2,from,to;
274
275 // signal bandwidth and picture carrier
276 if (t->std & V4L2_STD_525_60) {
277 // NTSC
278 from = 40750*1000;
279 to = 46750*1000;
280 if2 = 45750*1000;
281 } else {
282 // PAL
283 from = 32900*1000;
284 to = 39900*1000;
285 if2 = 38900*1000;
286 }
287
288 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
289 1090*1000*1000, if2, from, to);
290}
291
292static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
293{
294 struct tuner *t = i2c_get_clientdata(c);
295 int if2 = t->radio_if2;
296
297 // per Manual for FM tuning: first if center freq. 1085 MHz
298 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
299 1085*1000*1000,if2,if2,if2);
300}
301
302// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
303static int mt2032_init(struct i2c_client *c)
304{
305 struct tuner *t = i2c_get_clientdata(c);
306 unsigned char buf[21];
307 int ret,xogc,xok=0;
308
309 // Initialize Registers per spec.
310 buf[1]=2; // Index to register 2
311 buf[2]=0xff;
312 buf[3]=0x0f;
313 buf[4]=0x1f;
314 ret=i2c_master_send(c,buf+1,4);
315
316 buf[5]=6; // Index register 6
317 buf[6]=0xe4;
318 buf[7]=0x8f;
319 buf[8]=0xc3;
320 buf[9]=0x4e;
321 buf[10]=0xec;
322 ret=i2c_master_send(c,buf+5,6);
323
324 buf[12]=13; // Index register 13
325 buf[13]=0x32;
326 ret=i2c_master_send(c,buf+12,2);
327
328 // Adjust XOGC (register 7), wait for XOK
329 xogc=7;
330 do {
331 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
332 mdelay(10);
333 buf[0]=0x0e;
334 i2c_master_send(c,buf,1);
335 i2c_master_recv(c,buf,1);
336 xok=buf[0]&0x01;
337 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
338 if (xok == 1) break;
339
340 xogc--;
341 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
342 if (xogc == 3) {
343 xogc=4; // min. 4 per spec
344 break;
345 }
346 buf[0]=0x07;
347 buf[1]=0x88 + xogc;
348 ret=i2c_master_send(c,buf,2);
349 if (ret!=2)
350 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
351 } while (xok != 1 );
352 t->xogc=xogc;
353
354 t->tv_freq = mt2032_set_tv_freq;
355 t->radio_freq = mt2032_set_radio_freq;
356 return(1);
357}
358
359static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
360{
361 struct tuner *t = i2c_get_clientdata(c);
362 unsigned char buf[2];
363 int ret;
364
365 buf[0] = 6;
366 buf[1] = antenna ? 0x11 : 0x10;
367 ret=i2c_master_send(c,buf,2);
368 tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
369}
370
371static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
372{
373 struct tuner *t = i2c_get_clientdata(c);
374 unsigned int if1=1218*1000*1000;
375 unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
376 int ret;
377 unsigned char buf[6];
378
379 tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
380 freq,if1,if2);
381
382 f_lo1=freq+if1;
383 f_lo1=(f_lo1/1000000)*1000000;
384
385 f_lo2=f_lo1-freq-if2;
386 f_lo2=(f_lo2/50000)*50000;
387
388 lo1=f_lo1/4000000;
389 lo2=f_lo2/4000000;
390
391 f_lo1_modulo= f_lo1-(lo1*4000000);
392 f_lo2_modulo= f_lo2-(lo2*4000000);
393
394 num1=4*f_lo1_modulo/4000000;
395 num2=4096*(f_lo2_modulo/1000)/4000;
396
397 // todo spurchecks
398
399 div1a=(lo1/12)-1;
400 div1b=lo1-(div1a+1)*12;
401
402 div2a=(lo2/8)-1;
403 div2b=lo2-(div2a+1)*8;
404
405 if (tuner_debug > 1) {
406 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
407 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
408 num1,num2,div1a,div1b,div2a,div2b);
409 }
410
411 buf[0]=1;
412 buf[1]= 4*div1b + num1;
413 if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
414
415 buf[2]=div1a;
416 buf[3]=32*div2b + num2/256;
417 buf[4]=num2-(num2/256)*256;
418 buf[5]=div2a;
419 if(num2!=0) buf[5]=buf[5]|0x40;
420
421 if (tuner_debug > 1) {
422 int i;
423 tuner_dbg("bufs is: ");
424 for(i=0;i<6;i++)
425 printk("%x ",buf[i]);
426 printk("\n");
427 }
428
429 ret=i2c_master_send(c,buf,6);
430 if (ret!=6)
431 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
432}
433
434static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
435{
436 struct tuner *t = i2c_get_clientdata(c);
437 unsigned int if2;
438
439 if (t->std & V4L2_STD_525_60) {
440 // NTSC
441 if2 = 45750*1000;
442 } else {
443 // PAL
444 if2 = 38900*1000;
445 }
446 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
447 // DVB (pinnacle 300i)
448 if2 = 36150*1000;
449 }
450 mt2050_set_if_freq(c, freq*62500, if2);
451 mt2050_set_antenna(c, tv_antenna);
452}
453
454static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455{
456 struct tuner *t = i2c_get_clientdata(c);
457 int if2 = t->radio_if2;
458
459 mt2050_set_if_freq(c, freq*62500, if2);
460 mt2050_set_antenna(c, radio_antenna);
461}
462
463static int mt2050_init(struct i2c_client *c)
464{
465 struct tuner *t = i2c_get_clientdata(c);
466 unsigned char buf[2];
467 int ret;
468
469 buf[0]=6;
470 buf[1]=0x10;
471 ret=i2c_master_send(c,buf,2); // power
472
473 buf[0]=0x0f;
474 buf[1]=0x0f;
475 ret=i2c_master_send(c,buf,2); // m1lo
476
477 buf[0]=0x0d;
478 ret=i2c_master_send(c,buf,1);
479 i2c_master_recv(c,buf,1);
480
481 tuner_dbg("mt2050: sro is %x\n",buf[0]);
482 t->tv_freq = mt2050_set_tv_freq;
483 t->radio_freq = mt2050_set_radio_freq;
484 return 0;
485}
486
487int microtune_init(struct i2c_client *c)
488{
489 struct tuner *t = i2c_get_clientdata(c);
490 char *name;
491 unsigned char buf[21];
492 int company_code;
493
494 memset(buf,0,sizeof(buf));
495 t->tv_freq = NULL;
496 t->radio_freq = NULL;
497 name = "unknown";
498
499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) {
502 int i;
503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" ");
507 }
508 printk("\n");
509 }
510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]);
513
514#if 0
515 /* seems to cause more problems than it solves ... */
516 switch (company_code) {
517 case 0x30bf:
518 case 0x3cbf:
519 case 0x3dbf:
520 case 0x4d54:
521 case 0x8e81:
522 case 0x8e91:
523 /* ok (?) */
524 break;
525 default:
526 tuner_warn("tuner: microtune: unknown companycode\n");
527 return 0;
528 }
529#endif
530
531 if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
532 NULL != microtune_part[buf[0x13]])
533 name = microtune_part[buf[0x13]];
534 switch (buf[0x13]) {
535 case MT2032:
536 mt2032_init(c);
537 break;
538 case MT2050:
539 mt2050_init(c);
540 break;
541 default:
542 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
543 name);
544 return 0;
545 }
546
547 strlcpy(c->name, name, sizeof(c->name));
548 tuner_info("microtune %s found, OK\n",name);
549 return 0;
550}
551
552/*
553 * Overrides for Emacs so that we follow Linus's tabbing style.
554 * ---------------------------------------------------------------------------
555 * Local variables:
556 * c-basic-offset: 8
557 * End:
558 */
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
new file mode 100644
index 000000000000..70bf1f1fad59
--- /dev/null
+++ b/drivers/media/video/mxb.c
@@ -0,0 +1,1035 @@
1/*
2 mxb - v4l2 driver for the Multimedia eXtension Board
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 Visit http://www.mihu.de/linux/saa7146/mxb/
7 for further details about this card.
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#define DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27#include <media/tuner.h>
28#include <linux/video_decoder.h>
29
30#include "mxb.h"
31#include "tea6415c.h"
32#include "tea6420.h"
33#include "tda9840.h"
34
35#define I2C_SAA7111 0x24
36
37#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
38
39/* global variable */
40static int mxb_num = 0;
41
42/* initial frequence the tuner will be tuned to.
43 in verden (lower saxony, germany) 4148 is a
44 channel called "phoenix" */
45static int freq = 4148;
46module_param(freq, int, 0644);
47MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
48
49static int debug = 0;
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
52
53#define MXB_INPUTS 4
54enum { TUNER, AUX1, AUX3, AUX3_YC };
55
56static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
57 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
58 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
59 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
61};
62
63/* this array holds the information, which port of the saa7146 each
64 input actually uses. the mxb uses port 0 for every input */
65static struct {
66 int hps_source;
67 int hps_sync;
68} input_port_selection[MXB_INPUTS] = {
69 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
70 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
71 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
72 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
73};
74
75/* this array holds the information of the audio source (mxb_audios),
76 which has to be switched corresponding to the video source (mxb_channels) */
77static int video_audio_connect[MXB_INPUTS] =
78 { 0, 1, 3, 3 };
79
80/* these are the necessary input-output-pins for bringing one audio source
81(see above) to the CD-output */
82static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
83 {
84 {{1,1,0},{1,1,0}}, /* Tuner */
85 {{5,1,0},{6,1,0}}, /* AUX 1 */
86 {{4,1,0},{6,1,0}}, /* AUX 2 */
87 {{3,1,0},{6,1,0}}, /* AUX 3 */
88 {{1,1,0},{3,1,0}}, /* Radio */
89 {{1,1,0},{2,1,0}}, /* CD-Rom */
90 {{6,1,0},{6,1,0}} /* Mute */
91 };
92
93/* these are the necessary input-output-pins for bringing one audio source
94(see above) to the line-output */
95static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
96 {
97 {{2,3,0},{1,2,0}},
98 {{5,3,0},{6,2,0}},
99 {{4,3,0},{6,2,0}},
100 {{3,3,0},{6,2,0}},
101 {{2,3,0},{3,2,0}},
102 {{2,3,0},{2,2,0}},
103 {{6,3,0},{6,2,0}} /* Mute */
104 };
105
106#define MAXCONTROLS 1
107static struct v4l2_queryctrl mxb_controls[] = {
108 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
109};
110
111static struct saa7146_extension_ioctls ioctls[] = {
112 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
113 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
114 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
116 { VIDIOC_G_CTRL, SAA7146_BEFORE },
117 { VIDIOC_S_CTRL, SAA7146_BEFORE },
118 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
119 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
120 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
124 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
125 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
126 { 0, 0 }
127};
128
129struct mxb
130{
131 struct video_device *video_dev;
132 struct video_device *vbi_dev;
133
134 struct i2c_adapter i2c_adapter;
135
136 struct i2c_client* saa7111a;
137 struct i2c_client* tda9840;
138 struct i2c_client* tea6415c;
139 struct i2c_client* tuner;
140 struct i2c_client* tea6420_1;
141 struct i2c_client* tea6420_2;
142
143 int cur_mode; /* current audio mode (mono, stereo, ...) */
144 int cur_input; /* current input */
145 int cur_freq; /* current frequency the tuner is tuned to */
146 int cur_mute; /* current mute status */
147};
148
149static struct saa7146_extension extension;
150
151static int mxb_probe(struct saa7146_dev* dev)
152{
153 struct mxb* mxb = NULL;
154 struct i2c_client *client;
155 struct list_head *item;
156 int result;
157
158 if ((result = request_module("saa7111")) < 0) {
159 printk("mxb: saa7111 i2c module not available.\n");
160 return -ENODEV;
161 }
162 if ((result = request_module("tuner")) < 0) {
163 printk("mxb: tuner i2c module not available.\n");
164 return -ENODEV;
165 }
166 if ((result = request_module("tea6420")) < 0) {
167 printk("mxb: tea6420 i2c module not available.\n");
168 return -ENODEV;
169 }
170 if ((result = request_module("tea6415c")) < 0) {
171 printk("mxb: tea6415c i2c module not available.\n");
172 return -ENODEV;
173 }
174 if ((result = request_module("tda9840")) < 0) {
175 printk("mxb: tda9840 i2c module not available.\n");
176 return -ENODEV;
177 }
178
179 mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
180 if( NULL == mxb ) {
181 DEB_D(("not enough kernel memory.\n"));
182 return -ENOMEM;
183 }
184 memset(mxb, 0x0, sizeof(struct mxb));
185
186 mxb->i2c_adapter = (struct i2c_adapter) {
187 .class = I2C_CLASS_TV_ANALOG,
188 .name = "mxb",
189 };
190
191 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
192 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
193 DEB_S(("cannot register i2c-device. skipping.\n"));
194 kfree(mxb);
195 return -EFAULT;
196 }
197
198 /* loop through all i2c-devices on the bus and look who is there */
199 list_for_each(item,&mxb->i2c_adapter.clients) {
200 client = list_entry(item, struct i2c_client, list);
201 if( I2C_TEA6420_1 == client->addr )
202 mxb->tea6420_1 = client;
203 if( I2C_TEA6420_2 == client->addr )
204 mxb->tea6420_2 = client;
205 if( I2C_TEA6415C_2 == client->addr )
206 mxb->tea6415c = client;
207 if( I2C_TDA9840 == client->addr )
208 mxb->tda9840 = client;
209 if( I2C_SAA7111 == client->addr )
210 mxb->saa7111a = client;
211 if( 0x60 == client->addr )
212 mxb->tuner = client;
213 }
214
215 /* check if all devices are present */
216 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
217 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
218
219 printk("mxb: did not find all i2c devices. aborting\n");
220 i2c_del_adapter(&mxb->i2c_adapter);
221 kfree(mxb);
222 return -ENODEV;
223 }
224
225 /* all devices are present, probe was successful */
226
227 /* we store the pointer in our private data field */
228 dev->ext_priv = mxb;
229
230 return 0;
231}
232
233/* some init data for the saa7740, the so-called 'sound arena module'.
234 there are no specs available, so we simply use some init values */
235static struct {
236 int length;
237 char data[9];
238} mxb_saa7740_init[] = {
239 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
240 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
241 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
242 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
243 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
244 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
245 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
246 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
247 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
248 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
249 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
250 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
251 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
252 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
253 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
254 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
255 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
256 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
257 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
258 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
259 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
260 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
261 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
262 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
263 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
264 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
265 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
266 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
267 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
268 { 3, { 0x48, 0x00, 0x01 } },
269 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
270 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
271 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
272 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
273 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
274 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
275 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
276 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
277 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
278 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
279 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
280 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
281 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
282 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
283 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
284 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
285 { 3, { 0x80, 0xb3, 0x0a } },
286 {-1, { 0} }
287};
288
289static const unsigned char mxb_saa7111_init[] = {
290 0x00, 0x00, /* 00 - ID byte */
291 0x01, 0x00, /* 01 - reserved */
292
293 /*front end */
294 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
295 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
296 0x04, 0x00, /* 04 - GAI1=256 */
297 0x05, 0x00, /* 05 - GAI2=256 */
298
299 /* decoder */
300 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
301 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
302 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
303 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
304 0x0a, 0x80, /* 0a - BRIG=128 */
305 0x0b, 0x47, /* 0b - CONT=1.109 */
306 0x0c, 0x40, /* 0c - SATN=1.0 */
307 0x0d, 0x00, /* 0d - HUE=0 */
308 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
309 0x0f, 0x00, /* 0f - reserved */
310 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
311 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
312 0x12, 0x80, /* 12 - xx output control 2 */
313 0x13, 0x30, /* 13 - xx output control 3 */
314 0x14, 0x00, /* 14 - reserved */
315 0x15, 0x15, /* 15 - VBI */
316 0x16, 0x04, /* 16 - VBI */
317 0x17, 0x00, /* 17 - VBI */
318};
319
320/* bring hardware to a sane state. this has to be done, just in case someone
321 wants to capture from this device before it has been properly initialized.
322 the capture engine would badly fail, because no valid signal arrives on the
323 saa7146, thus leading to timeouts and stuff. */
324static int mxb_init_done(struct saa7146_dev* dev)
325{
326 struct mxb* mxb = (struct mxb*)dev->ext_priv;
327 struct video_decoder_init init;
328 struct i2c_msg msg;
329
330 int i = 0, err = 0;
331 struct tea6415c_multiplex vm;
332
333 /* select video mode in saa7111a */
334 i = VIDEO_MODE_PAL;
335 /* fixme: currently pointless: gets overwritten by configuration below */
336 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
337
338 /* write configuration to saa7111a */
339 init.data = mxb_saa7111_init;
340 init.len = sizeof(mxb_saa7111_init);
341 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
342
343 /* select tuner-output on saa7111a */
344 i = 0;
345 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
346
347 /* enable vbi bypass */
348 i = 1;
349 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
350
351 /* select a tuner type */
352 i = 5;
353 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
354
355 /* mute audio on tea6420s */
356 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
357 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
358 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
359 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
360
361 /* switch to tuner-channel on tea6415c*/
362 vm.out = 17;
363 vm.in = 3;
364 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
365
366 /* select tuner-output on multicable on tea6415c*/
367 vm.in = 3;
368 vm.out = 13;
369 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
370
371 /* tune in some frequency on tuner */
372 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
373
374 /* the rest for mxb */
375 mxb->cur_input = 0;
376 mxb->cur_freq = freq;
377 mxb->cur_mute = 1;
378
379 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
380 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
381
382 /* check if the saa7740 (aka 'sound arena module') is present
383 on the mxb. if so, we must initialize it. due to lack of
384 informations about the saa7740, the values were reverse
385 engineered. */
386 msg.addr = 0x1b;
387 msg.flags = 0;
388 msg.len = mxb_saa7740_init[0].length;
389 msg.buf = &mxb_saa7740_init[0].data[0];
390
391 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
392 /* the sound arena module is a pos, that's probably the reason
393 philips refuses to hand out a datasheet for the saa7740...
394 it seems to screw up the i2c bus, so we disable fast irq
395 based i2c transactions here and rely on the slow and safe
396 polling method ... */
397 extension.flags &= ~SAA7146_USE_I2C_IRQ;
398 for(i = 1;;i++) {
399 if( -1 == mxb_saa7740_init[i].length ) {
400 break;
401 }
402
403 msg.len = mxb_saa7740_init[i].length;
404 msg.buf = &mxb_saa7740_init[i].data[0];
405 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
406 DEB_D(("failed to initialize 'sound arena module'.\n"));
407 goto err;
408 }
409 }
410 INFO(("'sound arena module' detected.\n"));
411 }
412err:
413 /* the rest for saa7146: you should definitely set some basic values
414 for the input-port handling of the saa7146. */
415
416 /* ext->saa has been filled by the core driver */
417
418 /* some stuff is done via variables */
419 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
420
421 /* some stuff is done via direct write to the registers */
422
423 /* this is ugly, but because of the fact that this is completely
424 hardware dependend, it should be done directly... */
425 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
426 saa7146_write(dev, DD1_INIT, 0x02000200);
427 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
428
429 return 0;
430}
431
432/* interrupt-handler. this gets called when irq_mask is != 0.
433 it must clear the interrupt-bits in irq_mask it has handled */
434/*
435void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
436{
437 struct mxb* mxb = (struct mxb*)dev->ext_priv;
438}
439*/
440
441static struct saa7146_ext_vv vv_data;
442
443/* this function only gets called when the probing was successful */
444static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
445{
446 struct mxb* mxb = (struct mxb*)dev->ext_priv;
447
448 DEB_EE(("dev:%p\n",dev));
449
450 /* checking for i2c-devices can be omitted here, because we
451 already did this in "mxb_vl42_probe" */
452
453 saa7146_vv_init(dev,&vv_data);
454 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
455 ERR(("cannot register capture v4l2 device. skipping.\n"));
456 return -1;
457 }
458
459 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
460 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
461 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
462 ERR(("cannot register vbi v4l2 device. skipping.\n"));
463 }
464 }
465
466 i2c_use_client(mxb->tea6420_1);
467 i2c_use_client(mxb->tea6420_2);
468 i2c_use_client(mxb->tea6415c);
469 i2c_use_client(mxb->tda9840);
470 i2c_use_client(mxb->saa7111a);
471 i2c_use_client(mxb->tuner);
472
473 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
474
475 mxb_num++;
476 mxb_init_done(dev);
477 return 0;
478}
479
480static int mxb_detach(struct saa7146_dev* dev)
481{
482 struct mxb* mxb = (struct mxb*)dev->ext_priv;
483
484 DEB_EE(("dev:%p\n",dev));
485
486 i2c_release_client(mxb->tea6420_1);
487 i2c_release_client(mxb->tea6420_2);
488 i2c_release_client(mxb->tea6415c);
489 i2c_release_client(mxb->tda9840);
490 i2c_release_client(mxb->saa7111a);
491 i2c_release_client(mxb->tuner);
492
493 saa7146_unregister_device(&mxb->video_dev,dev);
494 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
495 saa7146_unregister_device(&mxb->vbi_dev,dev);
496 }
497 saa7146_vv_release(dev);
498
499 mxb_num--;
500
501 i2c_del_adapter(&mxb->i2c_adapter);
502 kfree(mxb);
503
504 return 0;
505}
506
507static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
508{
509 struct saa7146_dev *dev = fh->dev;
510 struct mxb* mxb = (struct mxb*)dev->ext_priv;
511 struct saa7146_vv *vv = dev->vv_data;
512
513 switch(cmd) {
514 case VIDIOC_ENUMINPUT:
515 {
516 struct v4l2_input *i = arg;
517
518 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
519 if( i->index < 0 || i->index >= MXB_INPUTS) {
520 return -EINVAL;
521 }
522 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
523
524 return 0;
525 }
526 /* the saa7146 provides some controls (brightness, contrast, saturation)
527 which gets registered *after* this function. because of this we have
528 to return with a value != 0 even if the function succeded.. */
529 case VIDIOC_QUERYCTRL:
530 {
531 struct v4l2_queryctrl *qc = arg;
532 int i;
533
534 for (i = MAXCONTROLS - 1; i >= 0; i--) {
535 if (mxb_controls[i].id == qc->id) {
536 *qc = mxb_controls[i];
537 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
538 return 0;
539 }
540 }
541 return -EAGAIN;
542 }
543 case VIDIOC_G_CTRL:
544 {
545 struct v4l2_control *vc = arg;
546 int i;
547
548 for (i = MAXCONTROLS - 1; i >= 0; i--) {
549 if (mxb_controls[i].id == vc->id) {
550 break;
551 }
552 }
553
554 if( i < 0 ) {
555 return -EAGAIN;
556 }
557
558 switch (vc->id ) {
559 case V4L2_CID_AUDIO_MUTE: {
560 vc->value = mxb->cur_mute;
561 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
562 return 0;
563 }
564 }
565
566 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
567 return 0;
568 }
569
570 case VIDIOC_S_CTRL:
571 {
572 struct v4l2_control *vc = arg;
573 int i = 0;
574
575 for (i = MAXCONTROLS - 1; i >= 0; i--) {
576 if (mxb_controls[i].id == vc->id) {
577 break;
578 }
579 }
580
581 if( i < 0 ) {
582 return -EAGAIN;
583 }
584
585 switch (vc->id ) {
586 case V4L2_CID_AUDIO_MUTE: {
587 mxb->cur_mute = vc->value;
588 if( 0 == vc->value ) {
589 /* switch the audio-source */
590 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
591 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
592 } else {
593 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
594 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
595 }
596 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
597 break;
598 }
599 }
600 return 0;
601 }
602 case VIDIOC_G_INPUT:
603 {
604 int *input = (int *)arg;
605 *input = mxb->cur_input;
606
607 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
608 return 0;
609 }
610 case VIDIOC_S_INPUT:
611 {
612 int input = *(int *)arg;
613 struct tea6415c_multiplex vm;
614 int i = 0;
615
616 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
617
618 if (input < 0 || input >= MXB_INPUTS) {
619 return -EINVAL;
620 }
621
622 /* fixme: locke das setzen des inputs mit hilfe des mutexes
623 down(&dev->lock);
624 video_mux(dev,*i);
625 up(&dev->lock);
626 */
627
628 /* fixme: check if streaming capture
629 if ( 0 != dev->streaming ) {
630 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
631 return -EPERM;
632 }
633 */
634
635 mxb->cur_input = input;
636
637 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
638
639 /* prepare switching of tea6415c and saa7111a;
640 have a look at the 'background'-file for further informations */
641 switch( input ) {
642
643 case TUNER:
644 {
645 i = 0;
646 vm.in = 3;
647 vm.out = 17;
648
649 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
650 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
651 return -EFAULT;
652 }
653 /* connect tuner-output always to multicable */
654 vm.in = 3;
655 vm.out = 13;
656 break;
657 }
658 case AUX3_YC:
659 {
660 /* nothing to be done here. aux3_yc is
661 directly connected to the saa711a */
662 i = 5;
663 break;
664 }
665 case AUX3:
666 {
667 /* nothing to be done here. aux3 is
668 directly connected to the saa711a */
669 i = 1;
670 break;
671 }
672 case AUX1:
673 {
674 i = 0;
675 vm.in = 1;
676 vm.out = 17;
677 break;
678 }
679 }
680
681 /* switch video in tea6415c only if necessary */
682 switch( input ) {
683 case TUNER:
684 case AUX1:
685 {
686 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
687 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
688 return -EFAULT;
689 }
690 break;
691 }
692 default:
693 {
694 break;
695 }
696 }
697
698 /* switch video in saa7111a */
699 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
700 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
701 }
702
703 /* switch the audio-source only if necessary */
704 if( 0 == mxb->cur_mute ) {
705 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
706 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
707 }
708
709 return 0;
710 }
711 case VIDIOC_G_TUNER:
712 {
713 struct v4l2_tuner *t = arg;
714 int byte = 0;
715
716 if( 0 != t->index ) {
717 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
718 return -EINVAL;
719 }
720
721 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
722
723 memset(t,0,sizeof(*t));
724 strcpy(t->name, "Television");
725
726 t->type = V4L2_TUNER_ANALOG_TV;
727 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
728 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
729 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
730 /* FIXME: add the real signal strength here */
731 t->signal = 0xffff;
732 t->afc = 0;
733
734 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
735 t->audmode = mxb->cur_mode;
736
737 if( byte < 0 ) {
738 t->rxsubchans = V4L2_TUNER_SUB_MONO;
739 } else {
740 switch(byte) {
741 case TDA9840_MONO_DETECT: {
742 t->rxsubchans = V4L2_TUNER_SUB_MONO;
743 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
744 break;
745 }
746 case TDA9840_DUAL_DETECT: {
747 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
748 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
749 break;
750 }
751 case TDA9840_STEREO_DETECT: {
752 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
753 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
754 break;
755 }
756 default: { /* TDA9840_INCORRECT_DETECT */
757 t->rxsubchans = V4L2_TUNER_MODE_MONO;
758 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
759 break;
760 }
761 }
762 }
763
764 return 0;
765 }
766 case VIDIOC_S_TUNER:
767 {
768 struct v4l2_tuner *t = arg;
769 int result = 0;
770 int byte = 0;
771
772 if( 0 != t->index ) {
773 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
774 return -EINVAL;
775 }
776
777 switch(t->audmode) {
778 case V4L2_TUNER_MODE_STEREO: {
779 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
780 byte = TDA9840_SET_STEREO;
781 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
782 break;
783 }
784 case V4L2_TUNER_MODE_LANG1: {
785 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
786 byte = TDA9840_SET_LANG1;
787 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
788 break;
789 }
790 case V4L2_TUNER_MODE_LANG2: {
791 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
792 byte = TDA9840_SET_LANG2;
793 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
794 break;
795 }
796 default: { /* case V4L2_TUNER_MODE_MONO: {*/
797 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
798 byte = TDA9840_SET_MONO;
799 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
800 break;
801 }
802 }
803
804 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
805 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
806 }
807
808 return 0;
809 }
810 case VIDIOC_G_FREQUENCY:
811 {
812 struct v4l2_frequency *f = arg;
813
814 if(0 != mxb->cur_input) {
815 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
816 return -EINVAL;
817 }
818
819 memset(f,0,sizeof(*f));
820 f->type = V4L2_TUNER_ANALOG_TV;
821 f->frequency = mxb->cur_freq;
822
823 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
824 return 0;
825 }
826 case VIDIOC_S_FREQUENCY:
827 {
828 struct v4l2_frequency *f = arg;
829 int t_locked = 0;
830 int v_byte = 0;
831
832 if (0 != f->tuner)
833 return -EINVAL;
834
835 if (V4L2_TUNER_ANALOG_TV != f->type)
836 return -EINVAL;
837
838 if(0 != mxb->cur_input) {
839 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
840 return -EINVAL;
841 }
842
843 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
844
845 mxb->cur_freq = f->frequency;
846
847 /* tune in desired frequency */
848 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
849
850 /* check if pll of tuner & saa7111a is locked */
851// mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);
852 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);
853
854 /* not locked -- anything to do here ? */
855 if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
856 }
857
858 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
859 spin_lock(&dev->slock);
860 vv->vbi_fieldcount = 0;
861 spin_unlock(&dev->slock);
862
863 return 0;
864 }
865 case MXB_S_AUDIO_CD:
866 {
867 int i = *(int*)arg;
868
869 if( i < 0 || i >= MXB_AUDIOS ) {
870 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
871 return -EINVAL;
872 }
873
874 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
875
876 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
877 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
878
879 return 0;
880 }
881 case MXB_S_AUDIO_LINE:
882 {
883 int i = *(int*)arg;
884
885 if( i < 0 || i >= MXB_AUDIOS ) {
886 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
887 return -EINVAL;
888 }
889
890 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
891 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
892 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
893
894 return 0;
895 }
896 case VIDIOC_G_AUDIO:
897 {
898 struct v4l2_audio *a = arg;
899
900 if( a->index < 0 || a->index > MXB_INPUTS ) {
901 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
902 return -EINVAL;
903 }
904
905 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
906 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
907
908 return 0;
909 }
910 case VIDIOC_S_AUDIO:
911 {
912 struct v4l2_audio *a = arg;
913 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
914 return 0;
915 }
916 default:
917/*
918 DEB2(printk("does not handle this ioctl.\n"));
919*/
920 return -ENOIOCTLCMD;
921 }
922 return 0;
923}
924
925static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
926{
927 struct mxb* mxb = (struct mxb*)dev->ext_priv;
928 int zero = 0;
929 int one = 1;
930
931 if(V4L2_STD_PAL_I == std->id ) {
932 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
933 /* set the 7146 gpio register -- I don't know what this does exactly */
934 saa7146_write(dev, GPIO_CTRL, 0x00404050);
935 /* unset the 7111 gpio register -- I don't know what this does exactly */
936 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
937 } else {
938 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
939 /* set the 7146 gpio register -- I don't know what this does exactly */
940 saa7146_write(dev, GPIO_CTRL, 0x00404050);
941 /* set the 7111 gpio register -- I don't know what this does exactly */
942 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
943 }
944 return 0;
945}
946
947static struct saa7146_standard standard[] = {
948 {
949 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
950 .v_offset = 0x17, .v_field = 288,
951 .h_offset = 0x14, .h_pixels = 680,
952 .v_max_out = 576, .h_max_out = 768,
953 }, {
954 .name = "PAL-I", .id = V4L2_STD_PAL_I,
955 .v_offset = 0x17, .v_field = 288,
956 .h_offset = 0x14, .h_pixels = 680,
957 .v_max_out = 576, .h_max_out = 768,
958 }, {
959 .name = "NTSC", .id = V4L2_STD_NTSC,
960 .v_offset = 0x16, .v_field = 240,
961 .h_offset = 0x06, .h_pixels = 708,
962 .v_max_out = 480, .h_max_out = 640,
963 }, {
964 .name = "SECAM", .id = V4L2_STD_SECAM,
965 .v_offset = 0x14, .v_field = 288,
966 .h_offset = 0x14, .h_pixels = 720,
967 .v_max_out = 576, .h_max_out = 768,
968 }
969};
970
971static struct saa7146_pci_extension_data mxb = {
972 .ext_priv = "Multimedia eXtension Board",
973 .ext = &extension,
974};
975
976static struct pci_device_id pci_tbl[] = {
977 {
978 .vendor = PCI_VENDOR_ID_PHILIPS,
979 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
980 .subvendor = 0x0000,
981 .subdevice = 0x0000,
982 .driver_data = (unsigned long)&mxb,
983 }, {
984 .vendor = 0,
985 }
986};
987
988MODULE_DEVICE_TABLE(pci, pci_tbl);
989
990static struct saa7146_ext_vv vv_data = {
991 .inputs = MXB_INPUTS,
992 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
993 .stds = &standard[0],
994 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
995 .std_callback = &std_callback,
996 .ioctls = &ioctls[0],
997 .ioctl = mxb_ioctl,
998};
999
1000static struct saa7146_extension extension = {
1001 .name = MXB_IDENTIFIER,
1002 .flags = SAA7146_USE_I2C_IRQ,
1003
1004 .pci_tbl = &pci_tbl[0],
1005 .module = THIS_MODULE,
1006
1007 .probe = mxb_probe,
1008 .attach = mxb_attach,
1009 .detach = mxb_detach,
1010
1011 .irq_mask = 0,
1012 .irq_func = NULL,
1013};
1014
1015static int __init mxb_init_module(void)
1016{
1017 if( 0 != saa7146_register_extension(&extension)) {
1018 DEB_S(("failed to register extension.\n"));
1019 return -ENODEV;
1020 }
1021
1022 return 0;
1023}
1024
1025static void __exit mxb_cleanup_module(void)
1026{
1027 saa7146_unregister_extension(&extension);
1028}
1029
1030module_init(mxb_init_module);
1031module_exit(mxb_cleanup_module);
1032
1033MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1034MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1035MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h
new file mode 100644
index 000000000000..2332ed5f7c6b
--- /dev/null
+++ b/drivers/media/video/mxb.h
@@ -0,0 +1,42 @@
1#ifndef __MXB__
2#define __MXB__
3
4#define BASE_VIDIOC_MXB 10
5
6#define MXB_S_AUDIO_CD _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+0, int)
7#define MXB_S_AUDIO_LINE _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+1, int)
8
9#define MXB_IDENTIFIER "Multimedia eXtension Board"
10
11#define MXB_AUDIOS 6
12
13/* these are the available audio sources, which can switched
14 to the line- and cd-output individually */
15static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
16 {
17 .index = 0,
18 .name = "Tuner",
19 .capability = V4L2_AUDCAP_STEREO,
20 } , {
21 .index = 1,
22 .name = "AUX1",
23 .capability = V4L2_AUDCAP_STEREO,
24 } , {
25 .index = 2,
26 .name = "AUX2",
27 .capability = V4L2_AUDCAP_STEREO,
28 } , {
29 .index = 3,
30 .name = "AUX3",
31 .capability = V4L2_AUDCAP_STEREO,
32 } , {
33 .index = 4,
34 .name = "Radio (X9)",
35 .capability = V4L2_AUDCAP_STEREO,
36 } , {
37 .index = 5,
38 .name = "CD-ROM (X10)",
39 .capability = V4L2_AUDCAP_STEREO,
40 }
41};
42#endif
diff --git a/drivers/media/video/ovcamchip/Makefile b/drivers/media/video/ovcamchip/Makefile
new file mode 100644
index 000000000000..bca41ad93de8
--- /dev/null
+++ b/drivers/media/video/ovcamchip/Makefile
@@ -0,0 +1,4 @@
1ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
2 ov76be.o
3
4obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
diff --git a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c
new file mode 100644
index 000000000000..3433619ad93f
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov6x20.c
@@ -0,0 +1,415 @@
1/* OmniVision OV6620/OV6120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation */
22#define REG_CNT 0x05 /* Y contrast */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
25#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
26#define REG_EXP 0x10 /* exposure */
27
28/* Window parameters */
29#define HWSBASE 0x38
30#define HWEBASE 0x3A
31#define VWSBASE 0x05
32#define VWEBASE 0x06
33
34struct ov6x20 {
35 int auto_brt;
36 int auto_exp;
37 int backlight;
38 int bandfilt;
39 int mirror;
40};
41
42/* Initial values for use with OV511/OV511+ cameras */
43static struct ovcamchip_regvals regvals_init_6x20_511[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x11, 0x01 },
46 { 0x03, 0x60 },
47 { 0x05, 0x7f }, /* For when autoadjust is off */
48 { 0x07, 0xa8 },
49 { 0x0c, 0x24 },
50 { 0x0d, 0x24 },
51 { 0x0f, 0x15 }, /* COMS */
52 { 0x10, 0x75 }, /* AEC Exposure time */
53 { 0x12, 0x24 }, /* Enable AGC and AWB */
54 { 0x14, 0x04 },
55 { 0x16, 0x03 },
56 { 0x26, 0xb2 }, /* BLC enable */
57 /* 0x28: 0x05 Selects RGB format if RGB on */
58 { 0x28, 0x05 },
59 { 0x2a, 0x04 }, /* Disable framerate adjust */
60 { 0x2d, 0x99 },
61 { 0x33, 0xa0 }, /* Color Processing Parameter */
62 { 0x34, 0xd2 }, /* Max A/D range */
63 { 0x38, 0x8b },
64 { 0x39, 0x40 },
65
66 { 0x3c, 0x39 }, /* Enable AEC mode changing */
67 { 0x3c, 0x3c }, /* Change AEC mode */
68 { 0x3c, 0x24 }, /* Disable AEC mode changing */
69
70 { 0x3d, 0x80 },
71 /* These next two registers (0x4a, 0x4b) are undocumented. They
72 * control the color balance */
73 { 0x4a, 0x80 },
74 { 0x4b, 0x80 },
75 { 0x4d, 0xd2 }, /* This reduces noise a bit */
76 { 0x4e, 0xc1 },
77 { 0x4f, 0x04 },
78 { 0xff, 0xff }, /* END MARKER */
79};
80
81/* Initial values for use with OV518 cameras */
82static struct ovcamchip_regvals regvals_init_6x20_518[] = {
83 { 0x12, 0x80 }, /* Do a reset */
84 { 0x03, 0xc0 }, /* Saturation */
85 { 0x05, 0x8a }, /* Contrast */
86 { 0x0c, 0x24 }, /* AWB blue */
87 { 0x0d, 0x24 }, /* AWB red */
88 { 0x0e, 0x8d }, /* Additional 2x gain */
89 { 0x0f, 0x25 }, /* Black expanding level = 1.3V */
90 { 0x11, 0x01 }, /* Clock div. */
91 { 0x12, 0x24 }, /* Enable AGC and AWB */
92 { 0x13, 0x01 }, /* (default) */
93 { 0x14, 0x80 }, /* Set reserved bit 7 */
94 { 0x15, 0x01 }, /* (default) */
95 { 0x16, 0x03 }, /* (default) */
96 { 0x17, 0x38 }, /* (default) */
97 { 0x18, 0xea }, /* (default) */
98 { 0x19, 0x04 },
99 { 0x1a, 0x93 },
100 { 0x1b, 0x00 }, /* (default) */
101 { 0x1e, 0xc4 }, /* (default) */
102 { 0x1f, 0x04 }, /* (default) */
103 { 0x20, 0x20 }, /* Enable 1st stage aperture correction */
104 { 0x21, 0x10 }, /* Y offset */
105 { 0x22, 0x88 }, /* U offset */
106 { 0x23, 0xc0 }, /* Set XTAL power level */
107 { 0x24, 0x53 }, /* AEC bright ratio */
108 { 0x25, 0x7a }, /* AEC black ratio */
109 { 0x26, 0xb2 }, /* BLC enable */
110 { 0x27, 0xa2 }, /* Full output range */
111 { 0x28, 0x01 }, /* (default) */
112 { 0x29, 0x00 }, /* (default) */
113 { 0x2a, 0x84 }, /* (default) */
114 { 0x2b, 0xa8 }, /* Set custom frame rate */
115 { 0x2c, 0xa0 }, /* (reserved) */
116 { 0x2d, 0x95 }, /* Enable banding filter */
117 { 0x2e, 0x88 }, /* V offset */
118 { 0x33, 0x22 }, /* Luminance gamma on */
119 { 0x34, 0xc7 }, /* A/D bias */
120 { 0x36, 0x12 }, /* (reserved) */
121 { 0x37, 0x63 }, /* (reserved) */
122 { 0x38, 0x8b }, /* Quick AEC/AEB */
123 { 0x39, 0x00 }, /* (default) */
124 { 0x3a, 0x0f }, /* (default) */
125 { 0x3b, 0x3c }, /* (default) */
126 { 0x3c, 0x5c }, /* AEC controls */
127 { 0x3d, 0x80 }, /* Drop 1 (bad) frame when AEC change */
128 { 0x3e, 0x80 }, /* (default) */
129 { 0x3f, 0x02 }, /* (default) */
130 { 0x40, 0x10 }, /* (reserved) */
131 { 0x41, 0x10 }, /* (reserved) */
132 { 0x42, 0x00 }, /* (reserved) */
133 { 0x43, 0x7f }, /* (reserved) */
134 { 0x44, 0x80 }, /* (reserved) */
135 { 0x45, 0x1c }, /* (reserved) */
136 { 0x46, 0x1c }, /* (reserved) */
137 { 0x47, 0x80 }, /* (reserved) */
138 { 0x48, 0x5f }, /* (reserved) */
139 { 0x49, 0x00 }, /* (reserved) */
140 { 0x4a, 0x00 }, /* Color balance (undocumented) */
141 { 0x4b, 0x80 }, /* Color balance (undocumented) */
142 { 0x4c, 0x58 }, /* (reserved) */
143 { 0x4d, 0xd2 }, /* U *= .938, V *= .838 */
144 { 0x4e, 0xa0 }, /* (default) */
145 { 0x4f, 0x04 }, /* UV 3-point average */
146 { 0x50, 0xff }, /* (reserved) */
147 { 0x51, 0x58 }, /* (reserved) */
148 { 0x52, 0xc0 }, /* (reserved) */
149 { 0x53, 0x42 }, /* (reserved) */
150 { 0x27, 0xa6 }, /* Enable manual offset adj. (reg 21 & 22) */
151 { 0x12, 0x20 },
152 { 0x12, 0x24 },
153
154 { 0xff, 0xff }, /* END MARKER */
155};
156
157/* This initializes the OV6x20 camera chip and relevant variables. */
158static int ov6x20_init(struct i2c_client *c)
159{
160 struct ovcamchip *ov = i2c_get_clientdata(c);
161 struct ov6x20 *s;
162 int rc;
163
164 DDEBUG(4, &c->dev, "entered");
165
166 switch (c->adapter->id) {
167 case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511:
168 rc = ov_write_regvals(c, regvals_init_6x20_511);
169 break;
170 case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518:
171 rc = ov_write_regvals(c, regvals_init_6x20_518);
172 break;
173 default:
174 dev_err(&c->dev, "ov6x20: Unsupported adapter\n");
175 rc = -ENODEV;
176 }
177
178 if (rc < 0)
179 return rc;
180
181 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
182 if (!s)
183 return -ENOMEM;
184 memset(s, 0, sizeof *s);
185
186 s->auto_brt = 1;
187 s->auto_exp = 1;
188
189 return rc;
190}
191
192static int ov6x20_free(struct i2c_client *c)
193{
194 struct ovcamchip *ov = i2c_get_clientdata(c);
195
196 kfree(ov->spriv);
197 return 0;
198}
199
200static int ov6x20_set_control(struct i2c_client *c,
201 struct ovcamchip_control *ctl)
202{
203 struct ovcamchip *ov = i2c_get_clientdata(c);
204 struct ov6x20 *s = ov->spriv;
205 int rc;
206 int v = ctl->value;
207
208 switch (ctl->id) {
209 case OVCAMCHIP_CID_CONT:
210 rc = ov_write(c, REG_CNT, v >> 8);
211 break;
212 case OVCAMCHIP_CID_BRIGHT:
213 rc = ov_write(c, REG_BRT, v >> 8);
214 break;
215 case OVCAMCHIP_CID_SAT:
216 rc = ov_write(c, REG_SAT, v >> 8);
217 break;
218 case OVCAMCHIP_CID_HUE:
219 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
220 if (rc < 0)
221 goto out;
222
223 rc = ov_write(c, REG_BLUE, v >> 8);
224 break;
225 case OVCAMCHIP_CID_EXP:
226 rc = ov_write(c, REG_EXP, v);
227 break;
228 case OVCAMCHIP_CID_FREQ:
229 {
230 int sixty = (v == 60);
231
232 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
233 if (rc < 0)
234 goto out;
235
236 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
237 break;
238 }
239 case OVCAMCHIP_CID_BANDFILT:
240 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
241 s->bandfilt = v;
242 break;
243 case OVCAMCHIP_CID_AUTOBRIGHT:
244 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
245 s->auto_brt = v;
246 break;
247 case OVCAMCHIP_CID_AUTOEXP:
248 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
249 s->auto_exp = v;
250 break;
251 case OVCAMCHIP_CID_BACKLIGHT:
252 {
253 rc = ov_write_mask(c, 0x4e, v?0xe0:0xc0, 0xe0);
254 if (rc < 0)
255 goto out;
256
257 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
258 if (rc < 0)
259 goto out;
260
261 rc = ov_write_mask(c, 0x0e, v?0x80:0x00, 0x80);
262 s->backlight = v;
263 break;
264 }
265 case OVCAMCHIP_CID_MIRROR:
266 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
267 s->mirror = v;
268 break;
269 default:
270 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
271 return -EPERM;
272 }
273
274out:
275 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
276 return rc;
277}
278
279static int ov6x20_get_control(struct i2c_client *c,
280 struct ovcamchip_control *ctl)
281{
282 struct ovcamchip *ov = i2c_get_clientdata(c);
283 struct ov6x20 *s = ov->spriv;
284 int rc = 0;
285 unsigned char val = 0;
286
287 switch (ctl->id) {
288 case OVCAMCHIP_CID_CONT:
289 rc = ov_read(c, REG_CNT, &val);
290 ctl->value = val << 8;
291 break;
292 case OVCAMCHIP_CID_BRIGHT:
293 rc = ov_read(c, REG_BRT, &val);
294 ctl->value = val << 8;
295 break;
296 case OVCAMCHIP_CID_SAT:
297 rc = ov_read(c, REG_SAT, &val);
298 ctl->value = val << 8;
299 break;
300 case OVCAMCHIP_CID_HUE:
301 rc = ov_read(c, REG_BLUE, &val);
302 ctl->value = val << 8;
303 break;
304 case OVCAMCHIP_CID_EXP:
305 rc = ov_read(c, REG_EXP, &val);
306 ctl->value = val;
307 break;
308 case OVCAMCHIP_CID_BANDFILT:
309 ctl->value = s->bandfilt;
310 break;
311 case OVCAMCHIP_CID_AUTOBRIGHT:
312 ctl->value = s->auto_brt;
313 break;
314 case OVCAMCHIP_CID_AUTOEXP:
315 ctl->value = s->auto_exp;
316 break;
317 case OVCAMCHIP_CID_BACKLIGHT:
318 ctl->value = s->backlight;
319 break;
320 case OVCAMCHIP_CID_MIRROR:
321 ctl->value = s->mirror;
322 break;
323 default:
324 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
325 return -EPERM;
326 }
327
328 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
329 return rc;
330}
331
332static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
333{
334 /******** QCIF-specific regs ********/
335
336 ov_write(c, 0x14, win->quarter?0x24:0x04);
337
338 /******** Palette-specific regs ********/
339
340 /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */
341 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
342 if (win->format == VIDEO_PALETTE_GREY)
343 ov_write_mask(c, 0x13, 0x00, 0x20);
344 else
345 ov_write_mask(c, 0x13, 0x20, 0x20);
346 } else {
347 if (win->format == VIDEO_PALETTE_GREY)
348 ov_write_mask(c, 0x13, 0x20, 0x20);
349 else
350 ov_write_mask(c, 0x13, 0x00, 0x20);
351 }
352
353 /******** Clock programming ********/
354
355 /* The OV6620 needs special handling. This prevents the
356 * severe banding that normally occurs */
357
358 /* Clock down */
359 ov_write(c, 0x2a, 0x04);
360
361 ov_write(c, 0x11, win->clockdiv);
362
363 ov_write(c, 0x2a, 0x84);
364 /* This next setting is critical. It seems to improve
365 * the gain or the contrast. The "reserved" bits seem
366 * to have some effect in this case. */
367 ov_write(c, 0x2d, 0x85); /* FIXME: This messes up banding filter */
368
369 return 0;
370}
371
372static int ov6x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
373{
374 int ret, hwscale, vwscale;
375
376 ret = ov6x20_mode_init(c, win);
377 if (ret < 0)
378 return ret;
379
380 if (win->quarter) {
381 hwscale = 0;
382 vwscale = 0;
383 } else {
384 hwscale = 1;
385 vwscale = 1; /* The datasheet says 0; it's wrong */
386 }
387
388 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
389 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
390 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
391 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
392
393 return 0;
394}
395
396static int ov6x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
397{
398 switch (cmd) {
399 case OVCAMCHIP_CMD_S_CTRL:
400 return ov6x20_set_control(c, arg);
401 case OVCAMCHIP_CMD_G_CTRL:
402 return ov6x20_get_control(c, arg);
403 case OVCAMCHIP_CMD_S_MODE:
404 return ov6x20_set_window(c, arg);
405 default:
406 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
407 return -ENOIOCTLCMD;
408 }
409}
410
411struct ovcamchip_ops ov6x20_ops = {
412 .init = ov6x20_init,
413 .free = ov6x20_free,
414 .command = ov6x20_command,
415};
diff --git a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c
new file mode 100644
index 000000000000..44a842379b45
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov6x30.c
@@ -0,0 +1,374 @@
1/* OmniVision OV6630/OV6130 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation [7:3] */
22#define REG_CNT 0x05 /* Y contrast [3:0] */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_SHARP 0x07 /* sharpness */
25#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
26#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
27#define REG_EXP 0x10 /* exposure */
28
29/* Window parameters */
30#define HWSBASE 0x38
31#define HWEBASE 0x3A
32#define VWSBASE 0x05
33#define VWEBASE 0x06
34
35struct ov6x30 {
36 int auto_brt;
37 int auto_exp;
38 int backlight;
39 int bandfilt;
40 int mirror;
41};
42
43static struct ovcamchip_regvals regvals_init_6x30[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x00, 0x1f }, /* Gain */
46 { 0x01, 0x99 }, /* Blue gain */
47 { 0x02, 0x7c }, /* Red gain */
48 { 0x03, 0xc0 }, /* Saturation */
49 { 0x05, 0x0a }, /* Contrast */
50 { 0x06, 0x95 }, /* Brightness */
51 { 0x07, 0x2d }, /* Sharpness */
52 { 0x0c, 0x20 },
53 { 0x0d, 0x20 },
54 { 0x0e, 0x20 },
55 { 0x0f, 0x05 },
56 { 0x10, 0x9a }, /* "exposure check" */
57 { 0x11, 0x00 }, /* Pixel clock = fastest */
58 { 0x12, 0x24 }, /* Enable AGC and AWB */
59 { 0x13, 0x21 },
60 { 0x14, 0x80 },
61 { 0x15, 0x01 },
62 { 0x16, 0x03 },
63 { 0x17, 0x38 },
64 { 0x18, 0xea },
65 { 0x19, 0x04 },
66 { 0x1a, 0x93 },
67 { 0x1b, 0x00 },
68 { 0x1e, 0xc4 },
69 { 0x1f, 0x04 },
70 { 0x20, 0x20 },
71 { 0x21, 0x10 },
72 { 0x22, 0x88 },
73 { 0x23, 0xc0 }, /* Crystal circuit power level */
74 { 0x25, 0x9a }, /* Increase AEC black pixel ratio */
75 { 0x26, 0xb2 }, /* BLC enable */
76 { 0x27, 0xa2 },
77 { 0x28, 0x00 },
78 { 0x29, 0x00 },
79 { 0x2a, 0x84 }, /* (keep) */
80 { 0x2b, 0xa8 }, /* (keep) */
81 { 0x2c, 0xa0 },
82 { 0x2d, 0x95 }, /* Enable auto-brightness */
83 { 0x2e, 0x88 },
84 { 0x33, 0x26 },
85 { 0x34, 0x03 },
86 { 0x36, 0x8f },
87 { 0x37, 0x80 },
88 { 0x38, 0x83 },
89 { 0x39, 0x80 },
90 { 0x3a, 0x0f },
91 { 0x3b, 0x3c },
92 { 0x3c, 0x1a },
93 { 0x3d, 0x80 },
94 { 0x3e, 0x80 },
95 { 0x3f, 0x0e },
96 { 0x40, 0x00 }, /* White bal */
97 { 0x41, 0x00 }, /* White bal */
98 { 0x42, 0x80 },
99 { 0x43, 0x3f }, /* White bal */
100 { 0x44, 0x80 },
101 { 0x45, 0x20 },
102 { 0x46, 0x20 },
103 { 0x47, 0x80 },
104 { 0x48, 0x7f },
105 { 0x49, 0x00 },
106 { 0x4a, 0x00 },
107 { 0x4b, 0x80 },
108 { 0x4c, 0xd0 },
109 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
110 { 0x4e, 0x40 },
111 { 0x4f, 0x07 }, /* UV average mode, color killer: strongest */
112 { 0x50, 0xff },
113 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
114 { 0x55, 0xff },
115 { 0x56, 0x12 },
116 { 0x57, 0x81 }, /* (default) */
117 { 0x58, 0x75 },
118 { 0x59, 0x01 }, /* AGC dark current compensation: +1 */
119 { 0x5a, 0x2c },
120 { 0x5b, 0x0f }, /* AWB chrominance levels */
121 { 0x5c, 0x10 },
122 { 0x3d, 0x80 },
123 { 0x27, 0xa6 },
124 /* Toggle AWB off and on */
125 { 0x12, 0x20 },
126 { 0x12, 0x24 },
127
128 { 0xff, 0xff }, /* END MARKER */
129};
130
131/* This initializes the OV6x30 camera chip and relevant variables. */
132static int ov6x30_init(struct i2c_client *c)
133{
134 struct ovcamchip *ov = i2c_get_clientdata(c);
135 struct ov6x30 *s;
136 int rc;
137
138 DDEBUG(4, &c->dev, "entered");
139
140 rc = ov_write_regvals(c, regvals_init_6x30);
141 if (rc < 0)
142 return rc;
143
144 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
145 if (!s)
146 return -ENOMEM;
147 memset(s, 0, sizeof *s);
148
149 s->auto_brt = 1;
150 s->auto_exp = 1;
151
152 return rc;
153}
154
155static int ov6x30_free(struct i2c_client *c)
156{
157 struct ovcamchip *ov = i2c_get_clientdata(c);
158
159 kfree(ov->spriv);
160 return 0;
161}
162
163static int ov6x30_set_control(struct i2c_client *c,
164 struct ovcamchip_control *ctl)
165{
166 struct ovcamchip *ov = i2c_get_clientdata(c);
167 struct ov6x30 *s = ov->spriv;
168 int rc;
169 int v = ctl->value;
170
171 switch (ctl->id) {
172 case OVCAMCHIP_CID_CONT:
173 rc = ov_write_mask(c, REG_CNT, v >> 12, 0x0f);
174 break;
175 case OVCAMCHIP_CID_BRIGHT:
176 rc = ov_write(c, REG_BRT, v >> 8);
177 break;
178 case OVCAMCHIP_CID_SAT:
179 rc = ov_write(c, REG_SAT, v >> 8);
180 break;
181 case OVCAMCHIP_CID_HUE:
182 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
183 if (rc < 0)
184 goto out;
185
186 rc = ov_write(c, REG_BLUE, v >> 8);
187 break;
188 case OVCAMCHIP_CID_EXP:
189 rc = ov_write(c, REG_EXP, v);
190 break;
191 case OVCAMCHIP_CID_FREQ:
192 {
193 int sixty = (v == 60);
194
195 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
196 if (rc < 0)
197 goto out;
198
199 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
200 break;
201 }
202 case OVCAMCHIP_CID_BANDFILT:
203 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
204 s->bandfilt = v;
205 break;
206 case OVCAMCHIP_CID_AUTOBRIGHT:
207 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
208 s->auto_brt = v;
209 break;
210 case OVCAMCHIP_CID_AUTOEXP:
211 rc = ov_write_mask(c, 0x28, v?0x00:0x10, 0x10);
212 s->auto_exp = v;
213 break;
214 case OVCAMCHIP_CID_BACKLIGHT:
215 {
216 rc = ov_write_mask(c, 0x4e, v?0x80:0x60, 0xe0);
217 if (rc < 0)
218 goto out;
219
220 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
221 if (rc < 0)
222 goto out;
223
224 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
225 s->backlight = v;
226 break;
227 }
228 case OVCAMCHIP_CID_MIRROR:
229 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
230 s->mirror = v;
231 break;
232 default:
233 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
234 return -EPERM;
235 }
236
237out:
238 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
239 return rc;
240}
241
242static int ov6x30_get_control(struct i2c_client *c,
243 struct ovcamchip_control *ctl)
244{
245 struct ovcamchip *ov = i2c_get_clientdata(c);
246 struct ov6x30 *s = ov->spriv;
247 int rc = 0;
248 unsigned char val = 0;
249
250 switch (ctl->id) {
251 case OVCAMCHIP_CID_CONT:
252 rc = ov_read(c, REG_CNT, &val);
253 ctl->value = (val & 0x0f) << 12;
254 break;
255 case OVCAMCHIP_CID_BRIGHT:
256 rc = ov_read(c, REG_BRT, &val);
257 ctl->value = val << 8;
258 break;
259 case OVCAMCHIP_CID_SAT:
260 rc = ov_read(c, REG_SAT, &val);
261 ctl->value = val << 8;
262 break;
263 case OVCAMCHIP_CID_HUE:
264 rc = ov_read(c, REG_BLUE, &val);
265 ctl->value = val << 8;
266 break;
267 case OVCAMCHIP_CID_EXP:
268 rc = ov_read(c, REG_EXP, &val);
269 ctl->value = val;
270 break;
271 case OVCAMCHIP_CID_BANDFILT:
272 ctl->value = s->bandfilt;
273 break;
274 case OVCAMCHIP_CID_AUTOBRIGHT:
275 ctl->value = s->auto_brt;
276 break;
277 case OVCAMCHIP_CID_AUTOEXP:
278 ctl->value = s->auto_exp;
279 break;
280 case OVCAMCHIP_CID_BACKLIGHT:
281 ctl->value = s->backlight;
282 break;
283 case OVCAMCHIP_CID_MIRROR:
284 ctl->value = s->mirror;
285 break;
286 default:
287 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
288 return -EPERM;
289 }
290
291 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
292 return rc;
293}
294
295static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
296{
297 /******** QCIF-specific regs ********/
298
299 ov_write_mask(c, 0x14, win->quarter?0x20:0x00, 0x20);
300
301 /******** Palette-specific regs ********/
302
303 if (win->format == VIDEO_PALETTE_GREY) {
304 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
305 /* Do nothing - we're already in 8-bit mode */
306 } else {
307 ov_write_mask(c, 0x13, 0x20, 0x20);
308 }
309 } else {
310 /* The OV518 needs special treatment. Although both the OV518
311 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
312 * bus is actually used. The UV bus is tied to ground.
313 * Therefore, the OV6630 needs to be in 8-bit multiplexed
314 * output mode */
315
316 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
317 /* Do nothing - we want to stay in 8-bit mode */
318 /* Warning: Messing with reg 0x13 breaks OV518 color */
319 } else {
320 ov_write_mask(c, 0x13, 0x00, 0x20);
321 }
322 }
323
324 /******** Clock programming ********/
325
326 ov_write(c, 0x11, win->clockdiv);
327
328 return 0;
329}
330
331static int ov6x30_set_window(struct i2c_client *c, struct ovcamchip_window *win)
332{
333 int ret, hwscale, vwscale;
334
335 ret = ov6x30_mode_init(c, win);
336 if (ret < 0)
337 return ret;
338
339 if (win->quarter) {
340 hwscale = 0;
341 vwscale = 0;
342 } else {
343 hwscale = 1;
344 vwscale = 1; /* The datasheet says 0; it's wrong */
345 }
346
347 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
348 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
349 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
350 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
351
352 return 0;
353}
354
355static int ov6x30_command(struct i2c_client *c, unsigned int cmd, void *arg)
356{
357 switch (cmd) {
358 case OVCAMCHIP_CMD_S_CTRL:
359 return ov6x30_set_control(c, arg);
360 case OVCAMCHIP_CMD_G_CTRL:
361 return ov6x30_get_control(c, arg);
362 case OVCAMCHIP_CMD_S_MODE:
363 return ov6x30_set_window(c, arg);
364 default:
365 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
366 return -ENOIOCTLCMD;
367 }
368}
369
370struct ovcamchip_ops ov6x30_ops = {
371 .init = ov6x30_init,
372 .free = ov6x30_free,
373 .command = ov6x30_command,
374};
diff --git a/drivers/media/video/ovcamchip/ov76be.c b/drivers/media/video/ovcamchip/ov76be.c
new file mode 100644
index 000000000000..29bbdc05e3b6
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov76be.c
@@ -0,0 +1,303 @@
1/* OmniVision OV76BE Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* OV7610 registers: Since the OV76BE is undocumented, we'll settle for these
18 * for now. */
19#define REG_GAIN 0x00 /* gain [5:0] */
20#define REG_BLUE 0x01 /* blue channel balance */
21#define REG_RED 0x02 /* red channel balance */
22#define REG_SAT 0x03 /* saturation */
23#define REG_CNT 0x05 /* Y contrast */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
26#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
27#define REG_GAMMA_COEFF 0x0E /* gamma settings */
28#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
29#define REG_EXP 0x10 /* manual exposure setting */
30#define REG_CLOCK 0x11 /* polarity/clock prescaler */
31#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
32#define REG_HWIN_START 0x17 /* horizontal window start */
33#define REG_HWIN_END 0x18 /* horizontal window end */
34#define REG_VWIN_START 0x19 /* vertical window start */
35#define REG_VWIN_END 0x1A /* vertical window end */
36#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
37#define REG_YOFFSET 0x21 /* Y channel offset */
38#define REG_UOFFSET 0x22 /* U channel offset */
39#define REG_ECW 0x24 /* exposure white level for AEC */
40#define REG_ECB 0x25 /* exposure black level for AEC */
41#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
42#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
43#define REG_ALC 0x2C /* Auto Level Control settings */
44#define REG_VOFFSET 0x2E /* V channel offset adjustment */
45#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
46#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
47#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
48
49/* Window parameters */
50#define HWSBASE 0x38
51#define HWEBASE 0x3a
52#define VWSBASE 0x05
53#define VWEBASE 0x05
54
55struct ov76be {
56 int auto_brt;
57 int auto_exp;
58 int bandfilt;
59 int mirror;
60};
61
62/* NOTE: These are the same as the 7x10 settings, but should eventually be
63 * optimized for the OV76BE */
64static struct ovcamchip_regvals regvals_init_76be[] = {
65 { 0x10, 0xff },
66 { 0x16, 0x03 },
67 { 0x28, 0x24 },
68 { 0x2b, 0xac },
69 { 0x12, 0x00 },
70 { 0x38, 0x81 },
71 { 0x28, 0x24 }, /* 0c */
72 { 0x0f, 0x85 }, /* lg's setting */
73 { 0x15, 0x01 },
74 { 0x20, 0x1c },
75 { 0x23, 0x2a },
76 { 0x24, 0x10 },
77 { 0x25, 0x8a },
78 { 0x26, 0xa2 },
79 { 0x27, 0xc2 },
80 { 0x2a, 0x04 },
81 { 0x2c, 0xfe },
82 { 0x2d, 0x93 },
83 { 0x30, 0x71 },
84 { 0x31, 0x60 },
85 { 0x32, 0x26 },
86 { 0x33, 0x20 },
87 { 0x34, 0x48 },
88 { 0x12, 0x24 },
89 { 0x11, 0x01 },
90 { 0x0c, 0x24 },
91 { 0x0d, 0x24 },
92 { 0xff, 0xff }, /* END MARKER */
93};
94
95/* This initializes the OV76be camera chip and relevant variables. */
96static int ov76be_init(struct i2c_client *c)
97{
98 struct ovcamchip *ov = i2c_get_clientdata(c);
99 struct ov76be *s;
100 int rc;
101
102 DDEBUG(4, &c->dev, "entered");
103
104 rc = ov_write_regvals(c, regvals_init_76be);
105 if (rc < 0)
106 return rc;
107
108 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
109 if (!s)
110 return -ENOMEM;
111 memset(s, 0, sizeof *s);
112
113 s->auto_brt = 1;
114 s->auto_exp = 1;
115
116 return rc;
117}
118
119static int ov76be_free(struct i2c_client *c)
120{
121 struct ovcamchip *ov = i2c_get_clientdata(c);
122
123 kfree(ov->spriv);
124 return 0;
125}
126
127static int ov76be_set_control(struct i2c_client *c,
128 struct ovcamchip_control *ctl)
129{
130 struct ovcamchip *ov = i2c_get_clientdata(c);
131 struct ov76be *s = ov->spriv;
132 int rc;
133 int v = ctl->value;
134
135 switch (ctl->id) {
136 case OVCAMCHIP_CID_BRIGHT:
137 rc = ov_write(c, REG_BRT, v >> 8);
138 break;
139 case OVCAMCHIP_CID_SAT:
140 rc = ov_write(c, REG_SAT, v >> 8);
141 break;
142 case OVCAMCHIP_CID_EXP:
143 rc = ov_write(c, REG_EXP, v);
144 break;
145 case OVCAMCHIP_CID_FREQ:
146 {
147 int sixty = (v == 60);
148
149 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
150 if (rc < 0)
151 goto out;
152
153 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
154 if (rc < 0)
155 goto out;
156
157 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
158 break;
159 }
160 case OVCAMCHIP_CID_BANDFILT:
161 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
162 s->bandfilt = v;
163 break;
164 case OVCAMCHIP_CID_AUTOBRIGHT:
165 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
166 s->auto_brt = v;
167 break;
168 case OVCAMCHIP_CID_AUTOEXP:
169 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
170 s->auto_exp = v;
171 break;
172 case OVCAMCHIP_CID_MIRROR:
173 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
174 s->mirror = v;
175 break;
176 default:
177 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
178 return -EPERM;
179 }
180
181out:
182 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
183 return rc;
184}
185
186static int ov76be_get_control(struct i2c_client *c,
187 struct ovcamchip_control *ctl)
188{
189 struct ovcamchip *ov = i2c_get_clientdata(c);
190 struct ov76be *s = ov->spriv;
191 int rc = 0;
192 unsigned char val = 0;
193
194 switch (ctl->id) {
195 case OVCAMCHIP_CID_BRIGHT:
196 rc = ov_read(c, REG_BRT, &val);
197 ctl->value = val << 8;
198 break;
199 case OVCAMCHIP_CID_SAT:
200 rc = ov_read(c, REG_SAT, &val);
201 ctl->value = val << 8;
202 break;
203 case OVCAMCHIP_CID_EXP:
204 rc = ov_read(c, REG_EXP, &val);
205 ctl->value = val;
206 break;
207 case OVCAMCHIP_CID_BANDFILT:
208 ctl->value = s->bandfilt;
209 break;
210 case OVCAMCHIP_CID_AUTOBRIGHT:
211 ctl->value = s->auto_brt;
212 break;
213 case OVCAMCHIP_CID_AUTOEXP:
214 ctl->value = s->auto_exp;
215 break;
216 case OVCAMCHIP_CID_MIRROR:
217 ctl->value = s->mirror;
218 break;
219 default:
220 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
221 return -EPERM;
222 }
223
224 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
225 return rc;
226}
227
228static int ov76be_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
229{
230 int qvga = win->quarter;
231
232 /******** QVGA-specific regs ********/
233
234 ov_write(c, 0x14, qvga?0xa4:0x84);
235
236 /******** Palette-specific regs ********/
237
238 if (win->format == VIDEO_PALETTE_GREY) {
239 ov_write_mask(c, 0x0e, 0x40, 0x40);
240 ov_write_mask(c, 0x13, 0x20, 0x20);
241 } else {
242 ov_write_mask(c, 0x0e, 0x00, 0x40);
243 ov_write_mask(c, 0x13, 0x00, 0x20);
244 }
245
246 /******** Clock programming ********/
247
248 ov_write(c, 0x11, win->clockdiv);
249
250 /******** Resolution-specific ********/
251
252 if (win->width == 640 && win->height == 480)
253 ov_write(c, 0x35, 0x9e);
254 else
255 ov_write(c, 0x35, 0x1e);
256
257 return 0;
258}
259
260static int ov76be_set_window(struct i2c_client *c, struct ovcamchip_window *win)
261{
262 int ret, hwscale, vwscale;
263
264 ret = ov76be_mode_init(c, win);
265 if (ret < 0)
266 return ret;
267
268 if (win->quarter) {
269 hwscale = 1;
270 vwscale = 0;
271 } else {
272 hwscale = 2;
273 vwscale = 1;
274 }
275
276 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
277 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
278 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
279 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
280
281 return 0;
282}
283
284static int ov76be_command(struct i2c_client *c, unsigned int cmd, void *arg)
285{
286 switch (cmd) {
287 case OVCAMCHIP_CMD_S_CTRL:
288 return ov76be_set_control(c, arg);
289 case OVCAMCHIP_CMD_G_CTRL:
290 return ov76be_get_control(c, arg);
291 case OVCAMCHIP_CMD_S_MODE:
292 return ov76be_set_window(c, arg);
293 default:
294 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
295 return -ENOIOCTLCMD;
296 }
297}
298
299struct ovcamchip_ops ov76be_ops = {
300 .init = ov76be_init,
301 .free = ov76be_free,
302 .command = ov76be_command,
303};
diff --git a/drivers/media/video/ovcamchip/ov7x10.c b/drivers/media/video/ovcamchip/ov7x10.c
new file mode 100644
index 000000000000..6c383d4b14fa
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov7x10.c
@@ -0,0 +1,335 @@
1/* OmniVision OV7610/OV7110 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue channel balance */
22#define REG_RED 0x02 /* red channel balance */
23#define REG_SAT 0x03 /* saturation */
24#define REG_CNT 0x05 /* Y contrast */
25#define REG_BRT 0x06 /* Y brightness */
26#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
27#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
28#define REG_GAMMA_COEFF 0x0E /* gamma settings */
29#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
30#define REG_EXP 0x10 /* manual exposure setting */
31#define REG_CLOCK 0x11 /* polarity/clock prescaler */
32#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
33#define REG_HWIN_START 0x17 /* horizontal window start */
34#define REG_HWIN_END 0x18 /* horizontal window end */
35#define REG_VWIN_START 0x19 /* vertical window start */
36#define REG_VWIN_END 0x1A /* vertical window end */
37#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
38#define REG_YOFFSET 0x21 /* Y channel offset */
39#define REG_UOFFSET 0x22 /* U channel offset */
40#define REG_ECW 0x24 /* exposure white level for AEC */
41#define REG_ECB 0x25 /* exposure black level for AEC */
42#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
43#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
44#define REG_ALC 0x2C /* Auto Level Control settings */
45#define REG_VOFFSET 0x2E /* V channel offset adjustment */
46#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
47#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
48#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
49
50/* Window parameters */
51#define HWSBASE 0x38
52#define HWEBASE 0x3a
53#define VWSBASE 0x05
54#define VWEBASE 0x05
55
56struct ov7x10 {
57 int auto_brt;
58 int auto_exp;
59 int bandfilt;
60 int mirror;
61};
62
63/* Lawrence Glaister <lg@jfm.bc.ca> reports:
64 *
65 * Register 0x0f in the 7610 has the following effects:
66 *
67 * 0x85 (AEC method 1): Best overall, good contrast range
68 * 0x45 (AEC method 2): Very overexposed
69 * 0xa5 (spec sheet default): Ok, but the black level is
70 * shifted resulting in loss of contrast
71 * 0x05 (old driver setting): very overexposed, too much
72 * contrast
73 */
74static struct ovcamchip_regvals regvals_init_7x10[] = {
75 { 0x10, 0xff },
76 { 0x16, 0x03 },
77 { 0x28, 0x24 },
78 { 0x2b, 0xac },
79 { 0x12, 0x00 },
80 { 0x38, 0x81 },
81 { 0x28, 0x24 }, /* 0c */
82 { 0x0f, 0x85 }, /* lg's setting */
83 { 0x15, 0x01 },
84 { 0x20, 0x1c },
85 { 0x23, 0x2a },
86 { 0x24, 0x10 },
87 { 0x25, 0x8a },
88 { 0x26, 0xa2 },
89 { 0x27, 0xc2 },
90 { 0x2a, 0x04 },
91 { 0x2c, 0xfe },
92 { 0x2d, 0x93 },
93 { 0x30, 0x71 },
94 { 0x31, 0x60 },
95 { 0x32, 0x26 },
96 { 0x33, 0x20 },
97 { 0x34, 0x48 },
98 { 0x12, 0x24 },
99 { 0x11, 0x01 },
100 { 0x0c, 0x24 },
101 { 0x0d, 0x24 },
102 { 0xff, 0xff }, /* END MARKER */
103};
104
105/* This initializes the OV7x10 camera chip and relevant variables. */
106static int ov7x10_init(struct i2c_client *c)
107{
108 struct ovcamchip *ov = i2c_get_clientdata(c);
109 struct ov7x10 *s;
110 int rc;
111
112 DDEBUG(4, &c->dev, "entered");
113
114 rc = ov_write_regvals(c, regvals_init_7x10);
115 if (rc < 0)
116 return rc;
117
118 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
119 if (!s)
120 return -ENOMEM;
121 memset(s, 0, sizeof *s);
122
123 s->auto_brt = 1;
124 s->auto_exp = 1;
125
126 return rc;
127}
128
129static int ov7x10_free(struct i2c_client *c)
130{
131 struct ovcamchip *ov = i2c_get_clientdata(c);
132
133 kfree(ov->spriv);
134 return 0;
135}
136
137static int ov7x10_set_control(struct i2c_client *c,
138 struct ovcamchip_control *ctl)
139{
140 struct ovcamchip *ov = i2c_get_clientdata(c);
141 struct ov7x10 *s = ov->spriv;
142 int rc;
143 int v = ctl->value;
144
145 switch (ctl->id) {
146 case OVCAMCHIP_CID_CONT:
147 rc = ov_write(c, REG_CNT, v >> 8);
148 break;
149 case OVCAMCHIP_CID_BRIGHT:
150 rc = ov_write(c, REG_BRT, v >> 8);
151 break;
152 case OVCAMCHIP_CID_SAT:
153 rc = ov_write(c, REG_SAT, v >> 8);
154 break;
155 case OVCAMCHIP_CID_HUE:
156 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
157 if (rc < 0)
158 goto out;
159
160 rc = ov_write(c, REG_BLUE, v >> 8);
161 break;
162 case OVCAMCHIP_CID_EXP:
163 rc = ov_write(c, REG_EXP, v);
164 break;
165 case OVCAMCHIP_CID_FREQ:
166 {
167 int sixty = (v == 60);
168
169 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
170 if (rc < 0)
171 goto out;
172
173 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
174 if (rc < 0)
175 goto out;
176
177 rc = ov_write_mask(c, 0x13, 0x10, 0x10);
178 if (rc < 0)
179 goto out;
180
181 rc = ov_write_mask(c, 0x13, 0x00, 0x10);
182 break;
183 }
184 case OVCAMCHIP_CID_BANDFILT:
185 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
186 s->bandfilt = v;
187 break;
188 case OVCAMCHIP_CID_AUTOBRIGHT:
189 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
190 s->auto_brt = v;
191 break;
192 case OVCAMCHIP_CID_AUTOEXP:
193 rc = ov_write_mask(c, 0x29, v?0x00:0x80, 0x80);
194 s->auto_exp = v;
195 break;
196 case OVCAMCHIP_CID_MIRROR:
197 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
198 s->mirror = v;
199 break;
200 default:
201 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
202 return -EPERM;
203 }
204
205out:
206 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
207 return rc;
208}
209
210static int ov7x10_get_control(struct i2c_client *c,
211 struct ovcamchip_control *ctl)
212{
213 struct ovcamchip *ov = i2c_get_clientdata(c);
214 struct ov7x10 *s = ov->spriv;
215 int rc = 0;
216 unsigned char val = 0;
217
218 switch (ctl->id) {
219 case OVCAMCHIP_CID_CONT:
220 rc = ov_read(c, REG_CNT, &val);
221 ctl->value = val << 8;
222 break;
223 case OVCAMCHIP_CID_BRIGHT:
224 rc = ov_read(c, REG_BRT, &val);
225 ctl->value = val << 8;
226 break;
227 case OVCAMCHIP_CID_SAT:
228 rc = ov_read(c, REG_SAT, &val);
229 ctl->value = val << 8;
230 break;
231 case OVCAMCHIP_CID_HUE:
232 rc = ov_read(c, REG_BLUE, &val);
233 ctl->value = val << 8;
234 break;
235 case OVCAMCHIP_CID_EXP:
236 rc = ov_read(c, REG_EXP, &val);
237 ctl->value = val;
238 break;
239 case OVCAMCHIP_CID_BANDFILT:
240 ctl->value = s->bandfilt;
241 break;
242 case OVCAMCHIP_CID_AUTOBRIGHT:
243 ctl->value = s->auto_brt;
244 break;
245 case OVCAMCHIP_CID_AUTOEXP:
246 ctl->value = s->auto_exp;
247 break;
248 case OVCAMCHIP_CID_MIRROR:
249 ctl->value = s->mirror;
250 break;
251 default:
252 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
253 return -EPERM;
254 }
255
256 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
257 return rc;
258}
259
260static int ov7x10_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
261{
262 int qvga = win->quarter;
263
264 /******** QVGA-specific regs ********/
265
266 ov_write(c, 0x14, qvga?0x24:0x04);
267
268 /******** Palette-specific regs ********/
269
270 if (win->format == VIDEO_PALETTE_GREY) {
271 ov_write_mask(c, 0x0e, 0x40, 0x40);
272 ov_write_mask(c, 0x13, 0x20, 0x20);
273 } else {
274 ov_write_mask(c, 0x0e, 0x00, 0x40);
275 ov_write_mask(c, 0x13, 0x00, 0x20);
276 }
277
278 /******** Clock programming ********/
279
280 ov_write(c, 0x11, win->clockdiv);
281
282 /******** Resolution-specific ********/
283
284 if (win->width == 640 && win->height == 480)
285 ov_write(c, 0x35, 0x9e);
286 else
287 ov_write(c, 0x35, 0x1e);
288
289 return 0;
290}
291
292static int ov7x10_set_window(struct i2c_client *c, struct ovcamchip_window *win)
293{
294 int ret, hwscale, vwscale;
295
296 ret = ov7x10_mode_init(c, win);
297 if (ret < 0)
298 return ret;
299
300 if (win->quarter) {
301 hwscale = 1;
302 vwscale = 0;
303 } else {
304 hwscale = 2;
305 vwscale = 1;
306 }
307
308 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
309 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
310 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
311 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
312
313 return 0;
314}
315
316static int ov7x10_command(struct i2c_client *c, unsigned int cmd, void *arg)
317{
318 switch (cmd) {
319 case OVCAMCHIP_CMD_S_CTRL:
320 return ov7x10_set_control(c, arg);
321 case OVCAMCHIP_CMD_G_CTRL:
322 return ov7x10_get_control(c, arg);
323 case OVCAMCHIP_CMD_S_MODE:
324 return ov7x10_set_window(c, arg);
325 default:
326 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
327 return -ENOIOCTLCMD;
328 }
329}
330
331struct ovcamchip_ops ov7x10_ops = {
332 .init = ov7x10_init,
333 .free = ov7x10_free,
334 .command = ov7x10_command,
335};
diff --git a/drivers/media/video/ovcamchip/ov7x20.c b/drivers/media/video/ovcamchip/ov7x20.c
new file mode 100644
index 000000000000..3c8c48f338ba
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov7x20.c
@@ -0,0 +1,455 @@
1/* OmniVision OV7620/OV7120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue gain */
22#define REG_RED 0x02 /* red gain */
23#define REG_SAT 0x03 /* saturation */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_SHARP 0x07 /* analog sharpness */
26#define REG_BLUE_BIAS 0x0C /* WB blue ratio [5:0] */
27#define REG_RED_BIAS 0x0D /* WB red ratio [5:0] */
28#define REG_EXP 0x10 /* exposure */
29
30/* Default control settings. Values are in terms of V4L2 controls. */
31#define OV7120_DFL_BRIGHT 0x60
32#define OV7620_DFL_BRIGHT 0x60
33#define OV7120_DFL_SAT 0xb0
34#define OV7620_DFL_SAT 0xc0
35#define DFL_AUTO_EXP 1
36#define DFL_AUTO_GAIN 1
37#define OV7120_DFL_GAIN 0x00
38#define OV7620_DFL_GAIN 0x00
39/* NOTE: Since autoexposure is the default, these aren't programmed into the
40 * OV7x20 chip. They are just here because V4L2 expects a default */
41#define OV7120_DFL_EXP 0x7f
42#define OV7620_DFL_EXP 0x7f
43
44/* Window parameters */
45#define HWSBASE 0x2F /* From 7620.SET (spec is wrong) */
46#define HWEBASE 0x2F
47#define VWSBASE 0x05
48#define VWEBASE 0x05
49
50struct ov7x20 {
51 int auto_brt;
52 int auto_exp;
53 int auto_gain;
54 int backlight;
55 int bandfilt;
56 int mirror;
57};
58
59/* Contrast look-up table */
60static unsigned char ctab[] = {
61 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
62 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
63};
64
65/* Settings for (Black & White) OV7120 camera chip */
66static struct ovcamchip_regvals regvals_init_7120[] = {
67 { 0x12, 0x80 }, /* reset */
68 { 0x13, 0x00 }, /* Autoadjust off */
69 { 0x12, 0x20 }, /* Disable AWB */
70 { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, /* Autoadjust on (if desired) */
71 { 0x00, OV7120_DFL_GAIN },
72 { 0x01, 0x80 },
73 { 0x02, 0x80 },
74 { 0x03, OV7120_DFL_SAT },
75 { 0x06, OV7120_DFL_BRIGHT },
76 { 0x07, 0x00 },
77 { 0x0c, 0x20 },
78 { 0x0d, 0x20 },
79 { 0x11, 0x01 },
80 { 0x14, 0x84 },
81 { 0x15, 0x01 },
82 { 0x16, 0x03 },
83 { 0x17, 0x2f },
84 { 0x18, 0xcf },
85 { 0x19, 0x06 },
86 { 0x1a, 0xf5 },
87 { 0x1b, 0x00 },
88 { 0x20, 0x08 },
89 { 0x21, 0x80 },
90 { 0x22, 0x80 },
91 { 0x23, 0x00 },
92 { 0x26, 0xa0 },
93 { 0x27, 0xfa },
94 { 0x28, 0x20 }, /* DON'T set bit 6. It is for the OV7620 only */
95 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
96 { 0x2a, 0x10 },
97 { 0x2b, 0x00 },
98 { 0x2c, 0x88 },
99 { 0x2d, 0x95 },
100 { 0x2e, 0x80 },
101 { 0x2f, 0x44 },
102 { 0x60, 0x20 },
103 { 0x61, 0x02 },
104 { 0x62, 0x5f },
105 { 0x63, 0xd5 },
106 { 0x64, 0x57 },
107 { 0x65, 0x83 }, /* OV says "don't change this value" */
108 { 0x66, 0x55 },
109 { 0x67, 0x92 },
110 { 0x68, 0xcf },
111 { 0x69, 0x76 },
112 { 0x6a, 0x22 },
113 { 0x6b, 0xe2 },
114 { 0x6c, 0x40 },
115 { 0x6d, 0x48 },
116 { 0x6e, 0x80 },
117 { 0x6f, 0x0d },
118 { 0x70, 0x89 },
119 { 0x71, 0x00 },
120 { 0x72, 0x14 },
121 { 0x73, 0x54 },
122 { 0x74, 0xa0 },
123 { 0x75, 0x8e },
124 { 0x76, 0x00 },
125 { 0x77, 0xff },
126 { 0x78, 0x80 },
127 { 0x79, 0x80 },
128 { 0x7a, 0x80 },
129 { 0x7b, 0xe6 },
130 { 0x7c, 0x00 },
131 { 0x24, 0x3a },
132 { 0x25, 0x60 },
133 { 0xff, 0xff }, /* END MARKER */
134};
135
136/* Settings for (color) OV7620 camera chip */
137static struct ovcamchip_regvals regvals_init_7620[] = {
138 { 0x12, 0x80 }, /* reset */
139 { 0x00, OV7620_DFL_GAIN },
140 { 0x01, 0x80 },
141 { 0x02, 0x80 },
142 { 0x03, OV7620_DFL_SAT },
143 { 0x06, OV7620_DFL_BRIGHT },
144 { 0x07, 0x00 },
145 { 0x0c, 0x24 },
146 { 0x0c, 0x24 },
147 { 0x0d, 0x24 },
148 { 0x11, 0x01 },
149 { 0x12, 0x24 },
150 { 0x13, DFL_AUTO_GAIN?0x01:0x00 },
151 { 0x14, 0x84 },
152 { 0x15, 0x01 },
153 { 0x16, 0x03 },
154 { 0x17, 0x2f },
155 { 0x18, 0xcf },
156 { 0x19, 0x06 },
157 { 0x1a, 0xf5 },
158 { 0x1b, 0x00 },
159 { 0x20, 0x18 },
160 { 0x21, 0x80 },
161 { 0x22, 0x80 },
162 { 0x23, 0x00 },
163 { 0x26, 0xa2 },
164 { 0x27, 0xea },
165 { 0x28, 0x20 },
166 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
167 { 0x2a, 0x10 },
168 { 0x2b, 0x00 },
169 { 0x2c, 0x88 },
170 { 0x2d, 0x91 },
171 { 0x2e, 0x80 },
172 { 0x2f, 0x44 },
173 { 0x60, 0x27 },
174 { 0x61, 0x02 },
175 { 0x62, 0x5f },
176 { 0x63, 0xd5 },
177 { 0x64, 0x57 },
178 { 0x65, 0x83 },
179 { 0x66, 0x55 },
180 { 0x67, 0x92 },
181 { 0x68, 0xcf },
182 { 0x69, 0x76 },
183 { 0x6a, 0x22 },
184 { 0x6b, 0x00 },
185 { 0x6c, 0x02 },
186 { 0x6d, 0x44 },
187 { 0x6e, 0x80 },
188 { 0x6f, 0x1d },
189 { 0x70, 0x8b },
190 { 0x71, 0x00 },
191 { 0x72, 0x14 },
192 { 0x73, 0x54 },
193 { 0x74, 0x00 },
194 { 0x75, 0x8e },
195 { 0x76, 0x00 },
196 { 0x77, 0xff },
197 { 0x78, 0x80 },
198 { 0x79, 0x80 },
199 { 0x7a, 0x80 },
200 { 0x7b, 0xe2 },
201 { 0x7c, 0x00 },
202 { 0xff, 0xff }, /* END MARKER */
203};
204
205/* Returns index into the specified look-up table, with 'n' elements, for which
206 * the value is greater than or equal to "val". If a match isn't found, (n-1)
207 * is returned. The entries in the table must be in ascending order. */
208static inline int ov7x20_lut_find(unsigned char lut[], int n, unsigned char val)
209{
210 int i = 0;
211
212 while (lut[i] < val && i < n)
213 i++;
214
215 return i;
216}
217
218/* This initializes the OV7x20 camera chip and relevant variables. */
219static int ov7x20_init(struct i2c_client *c)
220{
221 struct ovcamchip *ov = i2c_get_clientdata(c);
222 struct ov7x20 *s;
223 int rc;
224
225 DDEBUG(4, &c->dev, "entered");
226
227 if (ov->mono)
228 rc = ov_write_regvals(c, regvals_init_7120);
229 else
230 rc = ov_write_regvals(c, regvals_init_7620);
231
232 if (rc < 0)
233 return rc;
234
235 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
236 if (!s)
237 return -ENOMEM;
238 memset(s, 0, sizeof *s);
239
240 s->auto_brt = 1;
241 s->auto_exp = DFL_AUTO_EXP;
242 s->auto_gain = DFL_AUTO_GAIN;
243
244 return 0;
245}
246
247static int ov7x20_free(struct i2c_client *c)
248{
249 struct ovcamchip *ov = i2c_get_clientdata(c);
250
251 kfree(ov->spriv);
252 return 0;
253}
254
255static int ov7x20_set_v4l1_control(struct i2c_client *c,
256 struct ovcamchip_control *ctl)
257{
258 struct ovcamchip *ov = i2c_get_clientdata(c);
259 struct ov7x20 *s = ov->spriv;
260 int rc;
261 int v = ctl->value;
262
263 switch (ctl->id) {
264 case OVCAMCHIP_CID_CONT:
265 {
266 /* Use Y gamma control instead. Bit 0 enables it. */
267 rc = ov_write(c, 0x64, ctab[v >> 12]);
268 break;
269 }
270 case OVCAMCHIP_CID_BRIGHT:
271 /* 7620 doesn't like manual changes when in auto mode */
272 if (!s->auto_brt)
273 rc = ov_write(c, REG_BRT, v >> 8);
274 else
275 rc = 0;
276 break;
277 case OVCAMCHIP_CID_SAT:
278 rc = ov_write(c, REG_SAT, v >> 8);
279 break;
280 case OVCAMCHIP_CID_EXP:
281 if (!s->auto_exp)
282 rc = ov_write(c, REG_EXP, v);
283 else
284 rc = -EBUSY;
285 break;
286 case OVCAMCHIP_CID_FREQ:
287 {
288 int sixty = (v == 60);
289
290 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
291 if (rc < 0)
292 goto out;
293
294 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
295 if (rc < 0)
296 goto out;
297
298 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
299 break;
300 }
301 case OVCAMCHIP_CID_BANDFILT:
302 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
303 s->bandfilt = v;
304 break;
305 case OVCAMCHIP_CID_AUTOBRIGHT:
306 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
307 s->auto_brt = v;
308 break;
309 case OVCAMCHIP_CID_AUTOEXP:
310 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
311 s->auto_exp = v;
312 break;
313 case OVCAMCHIP_CID_BACKLIGHT:
314 {
315 rc = ov_write_mask(c, 0x68, v?0xe0:0xc0, 0xe0);
316 if (rc < 0)
317 goto out;
318
319 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
320 if (rc < 0)
321 goto out;
322
323 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
324 s->backlight = v;
325 break;
326 }
327 case OVCAMCHIP_CID_MIRROR:
328 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
329 s->mirror = v;
330 break;
331 default:
332 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
333 return -EPERM;
334 }
335
336out:
337 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
338 return rc;
339}
340
341static int ov7x20_get_v4l1_control(struct i2c_client *c,
342 struct ovcamchip_control *ctl)
343{
344 struct ovcamchip *ov = i2c_get_clientdata(c);
345 struct ov7x20 *s = ov->spriv;
346 int rc = 0;
347 unsigned char val = 0;
348
349 switch (ctl->id) {
350 case OVCAMCHIP_CID_CONT:
351 rc = ov_read(c, 0x64, &val);
352 ctl->value = ov7x20_lut_find(ctab, 16, val) << 12;
353 break;
354 case OVCAMCHIP_CID_BRIGHT:
355 rc = ov_read(c, REG_BRT, &val);
356 ctl->value = val << 8;
357 break;
358 case OVCAMCHIP_CID_SAT:
359 rc = ov_read(c, REG_SAT, &val);
360 ctl->value = val << 8;
361 break;
362 case OVCAMCHIP_CID_EXP:
363 rc = ov_read(c, REG_EXP, &val);
364 ctl->value = val;
365 break;
366 case OVCAMCHIP_CID_BANDFILT:
367 ctl->value = s->bandfilt;
368 break;
369 case OVCAMCHIP_CID_AUTOBRIGHT:
370 ctl->value = s->auto_brt;
371 break;
372 case OVCAMCHIP_CID_AUTOEXP:
373 ctl->value = s->auto_exp;
374 break;
375 case OVCAMCHIP_CID_BACKLIGHT:
376 ctl->value = s->backlight;
377 break;
378 case OVCAMCHIP_CID_MIRROR:
379 ctl->value = s->mirror;
380 break;
381 default:
382 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
383 return -EPERM;
384 }
385
386 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
387 return rc;
388}
389
390static int ov7x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
391{
392 struct ovcamchip *ov = i2c_get_clientdata(c);
393 int qvga = win->quarter;
394
395 /******** QVGA-specific regs ********/
396 ov_write_mask(c, 0x14, qvga?0x20:0x00, 0x20);
397 ov_write_mask(c, 0x28, qvga?0x00:0x20, 0x20);
398 ov_write(c, 0x24, qvga?0x20:0x3a);
399 ov_write(c, 0x25, qvga?0x30:0x60);
400 ov_write_mask(c, 0x2d, qvga?0x40:0x00, 0x40);
401 if (!ov->mono)
402 ov_write_mask(c, 0x67, qvga?0xf0:0x90, 0xf0);
403 ov_write_mask(c, 0x74, qvga?0x20:0x00, 0x20);
404
405 /******** Clock programming ********/
406
407 ov_write(c, 0x11, win->clockdiv);
408
409 return 0;
410}
411
412static int ov7x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
413{
414 int ret, hwscale, vwscale;
415
416 ret = ov7x20_mode_init(c, win);
417 if (ret < 0)
418 return ret;
419
420 if (win->quarter) {
421 hwscale = 1;
422 vwscale = 0;
423 } else {
424 hwscale = 2;
425 vwscale = 1;
426 }
427
428 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
429 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
430 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
431 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
432
433 return 0;
434}
435
436static int ov7x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
437{
438 switch (cmd) {
439 case OVCAMCHIP_CMD_S_CTRL:
440 return ov7x20_set_v4l1_control(c, arg);
441 case OVCAMCHIP_CMD_G_CTRL:
442 return ov7x20_get_v4l1_control(c, arg);
443 case OVCAMCHIP_CMD_S_MODE:
444 return ov7x20_set_window(c, arg);
445 default:
446 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
447 return -ENOIOCTLCMD;
448 }
449}
450
451struct ovcamchip_ops ov7x20_ops = {
452 .init = ov7x20_init,
453 .free = ov7x20_free,
454 .command = ov7x20_command,
455};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
new file mode 100644
index 000000000000..54dd5612d3b8
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -0,0 +1,444 @@
1/* Shared Code for OmniVision Camera Chip Drivers
2 *
3 * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include "ovcamchip_priv.h"
20
21#define DRIVER_VERSION "v2.27 for Linux 2.6"
22#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>"
23#define DRIVER_DESC "OV camera chip I2C driver"
24
25#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args);
26#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args);
27
28#ifdef DEBUG
29int ovcamchip_debug = 0;
30static int debug;
31module_param(debug, int, 0);
32MODULE_PARM_DESC(debug,
33 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all");
34#endif
35
36/* By default, let bridge driver tell us if chip is monochrome. mono=0
37 * will ignore that and always treat chips as color. mono=1 will force
38 * monochrome mode for all chips. */
39static int mono = -1;
40module_param(mono, int, 0);
41MODULE_PARM_DESC(mono,
42 "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)");
43
44MODULE_AUTHOR(DRIVER_AUTHOR);
45MODULE_DESCRIPTION(DRIVER_DESC);
46MODULE_LICENSE("GPL");
47
48/* Registers common to all chips, that are needed for detection */
49#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
50#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
51#define GENERIC_REG_COM_I 0x29 /* misc ID bits */
52
53extern struct ovcamchip_ops ov6x20_ops;
54extern struct ovcamchip_ops ov6x30_ops;
55extern struct ovcamchip_ops ov7x10_ops;
56extern struct ovcamchip_ops ov7x20_ops;
57extern struct ovcamchip_ops ov76be_ops;
58
59static char *chip_names[NUM_CC_TYPES] = {
60 [CC_UNKNOWN] = "Unknown chip",
61 [CC_OV76BE] = "OV76BE",
62 [CC_OV7610] = "OV7610",
63 [CC_OV7620] = "OV7620",
64 [CC_OV7620AE] = "OV7620AE",
65 [CC_OV6620] = "OV6620",
66 [CC_OV6630] = "OV6630",
67 [CC_OV6630AE] = "OV6630AE",
68 [CC_OV6630AF] = "OV6630AF",
69};
70
71/* Forward declarations */
72static struct i2c_driver driver;
73static struct i2c_client client_template;
74
75/* ----------------------------------------------------------------------- */
76
77int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
78{
79 int rc;
80
81 while (rvals->reg != 0xff) {
82 rc = ov_write(c, rvals->reg, rvals->val);
83 if (rc < 0)
84 return rc;
85 rvals++;
86 }
87
88 return 0;
89}
90
91/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
92 * the same position as 1's in "mask" are cleared and set to "value". Bits
93 * that are in the same position as 0's in "mask" are preserved, regardless
94 * of their respective state in "value".
95 */
96int ov_write_mask(struct i2c_client *c,
97 unsigned char reg,
98 unsigned char value,
99 unsigned char mask)
100{
101 int rc;
102 unsigned char oldval, newval;
103
104 if (mask == 0xff) {
105 newval = value;
106 } else {
107 rc = ov_read(c, reg, &oldval);
108 if (rc < 0)
109 return rc;
110
111 oldval &= (~mask); /* Clear the masked bits */
112 value &= mask; /* Enforce mask on value */
113 newval = oldval | value; /* Set the desired bits */
114 }
115
116 return ov_write(c, reg, newval);
117}
118
119/* ----------------------------------------------------------------------- */
120
121/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure.
122 */
123static int init_camchip(struct i2c_client *c)
124{
125 int i, success;
126 unsigned char high, low;
127
128 /* Reset the chip */
129 ov_write(c, 0x12, 0x80);
130
131 /* Wait for it to initialize */
132 msleep(150);
133
134 for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) {
135 if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) {
136 if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) {
137 if (high == 0x7F && low == 0xA2) {
138 success = 1;
139 continue;
140 }
141 }
142 }
143
144 /* Reset the chip */
145 ov_write(c, 0x12, 0x80);
146
147 /* Wait for it to initialize */
148 msleep(150);
149
150 /* Dummy read to sync I2C */
151 ov_read(c, 0x00, &low);
152 }
153
154 if (!success)
155 return -EIO;
156
157 PDEBUG(1, "I2C synced in %d attempt(s)", i);
158
159 return 0;
160}
161
162/* This detects the OV7610, OV7620, or OV76BE chip. */
163static int ov7xx0_detect(struct i2c_client *c)
164{
165 struct ovcamchip *ov = i2c_get_clientdata(c);
166 int rc;
167 unsigned char val;
168
169 PDEBUG(4, "");
170
171 /* Detect chip (sub)type */
172 rc = ov_read(c, GENERIC_REG_COM_I, &val);
173 if (rc < 0) {
174 PERROR("Error detecting ov7xx0 type");
175 return rc;
176 }
177
178 if ((val & 3) == 3) {
179 PINFO("Camera chip is an OV7610");
180 ov->subtype = CC_OV7610;
181 } else if ((val & 3) == 1) {
182 rc = ov_read(c, 0x15, &val);
183 if (rc < 0) {
184 PERROR("Error detecting ov7xx0 type");
185 return rc;
186 }
187
188 if (val & 1) {
189 PINFO("Camera chip is an OV7620AE");
190 /* OV7620 is a close enough match for now. There are
191 * some definite differences though, so this should be
192 * fixed */
193 ov->subtype = CC_OV7620;
194 } else {
195 PINFO("Camera chip is an OV76BE");
196 ov->subtype = CC_OV76BE;
197 }
198 } else if ((val & 3) == 0) {
199 PINFO("Camera chip is an OV7620");
200 ov->subtype = CC_OV7620;
201 } else {
202 PERROR("Unknown camera chip version: %d", val & 3);
203 return -ENOSYS;
204 }
205
206 if (ov->subtype == CC_OV76BE)
207 ov->sops = &ov76be_ops;
208 else if (ov->subtype == CC_OV7620)
209 ov->sops = &ov7x20_ops;
210 else
211 ov->sops = &ov7x10_ops;
212
213 return 0;
214}
215
216/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */
217static int ov6xx0_detect(struct i2c_client *c)
218{
219 struct ovcamchip *ov = i2c_get_clientdata(c);
220 int rc;
221 unsigned char val;
222
223 PDEBUG(4, "");
224
225 /* Detect chip (sub)type */
226 rc = ov_read(c, GENERIC_REG_COM_I, &val);
227 if (rc < 0) {
228 PERROR("Error detecting ov6xx0 type");
229 return -1;
230 }
231
232 if ((val & 3) == 0) {
233 ov->subtype = CC_OV6630;
234 PINFO("Camera chip is an OV6630");
235 } else if ((val & 3) == 1) {
236 ov->subtype = CC_OV6620;
237 PINFO("Camera chip is an OV6620");
238 } else if ((val & 3) == 2) {
239 ov->subtype = CC_OV6630;
240 PINFO("Camera chip is an OV6630AE");
241 } else if ((val & 3) == 3) {
242 ov->subtype = CC_OV6630;
243 PINFO("Camera chip is an OV6630AF");
244 }
245
246 if (ov->subtype == CC_OV6620)
247 ov->sops = &ov6x20_ops;
248 else
249 ov->sops = &ov6x30_ops;
250
251 return 0;
252}
253
254static int ovcamchip_detect(struct i2c_client *c)
255{
256 /* Ideally we would just try a single register write and see if it NAKs.
257 * That isn't possible since the OV518 can't report I2C transaction
258 * failures. So, we have to try to initialize the chip (i.e. reset it
259 * and check the ID registers) to detect its presence. */
260
261 /* Test for 7xx0 */
262 PDEBUG(3, "Testing for 0V7xx0");
263 c->addr = OV7xx0_SID;
264 if (init_camchip(c) < 0) {
265 /* Test for 6xx0 */
266 PDEBUG(3, "Testing for 0V6xx0");
267 c->addr = OV6xx0_SID;
268 if (init_camchip(c) < 0) {
269 return -ENODEV;
270 } else {
271 if (ov6xx0_detect(c) < 0) {
272 PERROR("Failed to init OV6xx0");
273 return -EIO;
274 }
275 }
276 } else {
277 if (ov7xx0_detect(c) < 0) {
278 PERROR("Failed to init OV7xx0");
279 return -EIO;
280 }
281 }
282
283 return 0;
284}
285
286/* ----------------------------------------------------------------------- */
287
288static int ovcamchip_attach(struct i2c_adapter *adap)
289{
290 int rc = 0;
291 struct ovcamchip *ov;
292 struct i2c_client *c;
293
294 /* I2C is not a PnP bus, so we can never be certain that we're talking
295 * to the right chip. To prevent damage to EEPROMS and such, only
296 * attach to adapters that are known to contain OV camera chips. */
297
298 switch (adap->id) {
299 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511):
300 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518):
301 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OVFX2):
302 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF):
303 PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
304 break;
305 default:
306 PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id);
307 return -ENODEV;
308 }
309
310 c = kmalloc(sizeof *c, GFP_KERNEL);
311 if (!c) {
312 rc = -ENOMEM;
313 goto no_client;
314 }
315 memcpy(c, &client_template, sizeof *c);
316 c->adapter = adap;
317 strcpy(i2c_clientname(c), "OV????");
318
319 ov = kmalloc(sizeof *ov, GFP_KERNEL);
320 if (!ov) {
321 rc = -ENOMEM;
322 goto no_ov;
323 }
324 memset(ov, 0, sizeof *ov);
325 i2c_set_clientdata(c, ov);
326
327 rc = ovcamchip_detect(c);
328 if (rc < 0)
329 goto error;
330
331 strcpy(i2c_clientname(c), chip_names[ov->subtype]);
332
333 PDEBUG(1, "Camera chip detection complete");
334
335 i2c_attach_client(c);
336
337 return rc;
338error:
339 kfree(ov);
340no_ov:
341 kfree(c);
342no_client:
343 PDEBUG(1, "returning %d", rc);
344 return rc;
345}
346
347static int ovcamchip_detach(struct i2c_client *c)
348{
349 struct ovcamchip *ov = i2c_get_clientdata(c);
350 int rc;
351
352 rc = ov->sops->free(c);
353 if (rc < 0)
354 return rc;
355
356 i2c_detach_client(c);
357
358 kfree(ov);
359 kfree(c);
360 return 0;
361}
362
363static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
364{
365 struct ovcamchip *ov = i2c_get_clientdata(c);
366
367 if (!ov->initialized &&
368 cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
369 cmd != OVCAMCHIP_CMD_INITIALIZE) {
370 dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n");
371 return -EPERM;
372 }
373
374 switch (cmd) {
375 case OVCAMCHIP_CMD_Q_SUBTYPE:
376 {
377 *(int *)arg = ov->subtype;
378 return 0;
379 }
380 case OVCAMCHIP_CMD_INITIALIZE:
381 {
382 int rc;
383
384 if (mono == -1)
385 ov->mono = *(int *)arg;
386 else
387 ov->mono = mono;
388
389 if (ov->mono) {
390 if (ov->subtype != CC_OV7620)
391 dev_warn(&c->dev, "Warning: Monochrome not "
392 "implemented for this chip\n");
393 else
394 dev_info(&c->dev, "Initializing chip as "
395 "monochrome\n");
396 }
397
398 rc = ov->sops->init(c);
399 if (rc < 0)
400 return rc;
401
402 ov->initialized = 1;
403 return 0;
404 }
405 default:
406 return ov->sops->command(c, cmd, arg);
407 }
408}
409
410/* ----------------------------------------------------------------------- */
411
412static struct i2c_driver driver = {
413 .owner = THIS_MODULE,
414 .name = "ovcamchip",
415 .id = I2C_DRIVERID_OVCAMCHIP,
416 .class = I2C_CLASS_CAM_DIGITAL,
417 .flags = I2C_DF_NOTIFY,
418 .attach_adapter = ovcamchip_attach,
419 .detach_client = ovcamchip_detach,
420 .command = ovcamchip_command,
421};
422
423static struct i2c_client client_template = {
424 I2C_DEVNAME("(unset)"),
425 .driver = &driver,
426};
427
428static int __init ovcamchip_init(void)
429{
430#ifdef DEBUG
431 ovcamchip_debug = debug;
432#endif
433
434 PINFO(DRIVER_VERSION " : " DRIVER_DESC);
435 return i2c_add_driver(&driver);
436}
437
438static void __exit ovcamchip_exit(void)
439{
440 i2c_del_driver(&driver);
441}
442
443module_init(ovcamchip_init);
444module_exit(ovcamchip_exit);
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
new file mode 100644
index 000000000000..575e612a5546
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h
@@ -0,0 +1,87 @@
1/* OmniVision* camera chip driver private definitions for core code and
2 * chip-specific code
3 *
4 * Copyright (c) 1999-2004 Mark McClelland
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 *
11 * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver
12 * is not sponsored or developed by them.
13 */
14
15#ifndef __LINUX_OVCAMCHIP_PRIV_H
16#define __LINUX_OVCAMCHIP_PRIV_H
17
18#include <media/ovcamchip.h>
19
20#ifdef DEBUG
21extern int ovcamchip_debug;
22#endif
23
24#define PDEBUG(level, fmt, args...) \
25 if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \
26 __FUNCTION__, __LINE__ , ## args)
27
28#define DDEBUG(level, dev, fmt, args...) \
29 if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \
30 __FUNCTION__, __LINE__ , ## args)
31
32/* Number of times to retry chip detection. Increase this if you are getting
33 * "Failed to init camera chip" */
34#define I2C_DETECT_RETRIES 10
35
36struct ovcamchip_regvals {
37 unsigned char reg;
38 unsigned char val;
39};
40
41struct ovcamchip_ops {
42 int (*init)(struct i2c_client *);
43 int (*free)(struct i2c_client *);
44 int (*command)(struct i2c_client *, unsigned int, void *);
45};
46
47struct ovcamchip {
48 struct ovcamchip_ops *sops;
49 void *spriv; /* Private data for OV7x10.c etc... */
50 int subtype; /* = SEN_OV7610 etc... */
51 int mono; /* Monochrome chip? (invalid until init) */
52 int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
53};
54
55/* --------------------------------- */
56/* I2C I/O */
57/* --------------------------------- */
58
59static inline int ov_read(struct i2c_client *c, unsigned char reg,
60 unsigned char *value)
61{
62 int rc;
63
64 rc = i2c_smbus_read_byte_data(c, reg);
65 *value = (unsigned char) rc;
66 return rc;
67}
68
69static inline int ov_write(struct i2c_client *c, unsigned char reg,
70 unsigned char value )
71{
72 return i2c_smbus_write_byte_data(c, reg, value);
73}
74
75/* --------------------------------- */
76/* FUNCTION PROTOTYPES */
77/* --------------------------------- */
78
79/* Functions in ovcamchip_core.c */
80
81extern int ov_write_regvals(struct i2c_client *c,
82 struct ovcamchip_regvals *rvals);
83
84extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
85 unsigned char value, unsigned char mask);
86
87#endif
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
new file mode 100644
index 000000000000..b19c33434eaf
--- /dev/null
+++ b/drivers/media/video/planb.c
@@ -0,0 +1,2303 @@
1/*
2 planb - PlanB frame grabber driver
3
4 PlanB is used in the 7x00/8x00 series of PowerMacintosh
5 Computers as video input DMA controller.
6
7 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
8
9 Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
10
11 Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
29
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/major.h>
35#include <linux/slab.h>
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/delay.h>
39#include <linux/vmalloc.h>
40#include <linux/mm.h>
41#include <linux/sched.h>
42#include <linux/videodev.h>
43#include <linux/wait.h>
44#include <asm/uaccess.h>
45#include <asm/io.h>
46#include <asm/prom.h>
47#include <asm/dbdma.h>
48#include <asm/pgtable.h>
49#include <asm/page.h>
50#include <asm/irq.h>
51#include <asm/semaphore.h>
52
53#include "planb.h"
54#include "saa7196.h"
55
56/* Would you mind for some ugly debugging? */
57#if 0
58#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
59#else
60#define DEBUG(x...) /* Don't debug driver */
61#endif
62
63#if 0
64#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
65#else
66#define IDEBUG(x...) /* Don't debug interrupt part */
67#endif
68
69/* Ever seen a Mac with more than 1 of these? */
70#define PLANB_MAX 1
71
72static int planb_num;
73static struct planb planbs[PLANB_MAX];
74static volatile struct planb_registers *planb_regs;
75
76static int def_norm = PLANB_DEF_NORM; /* default norm */
77static int video_nr = -1;
78
79MODULE_PARM(def_norm, "i");
80MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
81MODULE_PARM(video_nr,"i");
82MODULE_LICENSE("GPL");
83
84
85/* ------------------ PlanB Exported Functions ------------------ */
86static long planb_write(struct video_device *, const char *, unsigned long, int);
87static long planb_read(struct video_device *, char *, unsigned long, int);
88static int planb_open(struct video_device *, int);
89static void planb_close(struct video_device *);
90static int planb_ioctl(struct video_device *, unsigned int, void *);
91static int planb_init_done(struct video_device *);
92static int planb_mmap(struct video_device *, const char *, unsigned long);
93static void planb_irq(int, void *, struct pt_regs *);
94static void release_planb(void);
95int init_planbs(struct video_init *);
96
97/* ------------------ PlanB Internal Functions ------------------ */
98static int planb_prepare_open(struct planb *);
99static void planb_prepare_close(struct planb *);
100static void saa_write_reg(unsigned char, unsigned char);
101static unsigned char saa_status(int, struct planb *);
102static void saa_set(unsigned char, unsigned char, struct planb *);
103static void saa_init_regs(struct planb *);
104static int grabbuf_alloc(struct planb *);
105static int vgrab(struct planb *, struct video_mmap *);
106static void add_clip(struct planb *, struct video_clip *);
107static void fill_cmd_buff(struct planb *);
108static void cmd_buff(struct planb *);
109static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
110static void overlay_start(struct planb *);
111static void overlay_stop(struct planb *);
112static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
113 unsigned int);
114static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
115 unsigned int);
116static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
117 unsigned short, unsigned int, unsigned int);
118static int init_planb(struct planb *);
119static int find_planb(void);
120static void planb_pre_capture(int, int, struct planb *);
121static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
122 int, int, int, int, int, struct planb *);
123static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
124static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
125static inline int overlay_is_active(struct planb *);
126
127/*******************************/
128/* Memory management functions */
129/*******************************/
130
131static int grabbuf_alloc(struct planb *pb)
132{
133 int i, npage;
134
135 npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
136#ifndef PLANB_GSCANLINE
137 + MAX_LNUM
138#endif /* PLANB_GSCANLINE */
139 );
140 if ((pb->rawbuf = (unsigned char**) kmalloc (npage
141 * sizeof(unsigned long), GFP_KERNEL)) == 0)
142 return -ENOMEM;
143 for (i = 0; i < npage; i++) {
144 pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
145 |GFP_DMA, 0);
146 if (!pb->rawbuf[i])
147 break;
148 SetPageReserved(virt_to_page(pb->rawbuf[i]));
149 }
150 if (i-- < npage) {
151 printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
152 for (; i > 0; i--) {
153 ClearPageReserved(virt_to_page(pb->rawbuf[i]));
154 free_pages((unsigned long)pb->rawbuf[i], 0);
155 }
156 kfree(pb->rawbuf);
157 return -ENOBUFS;
158 }
159 pb->rawbuf_size = npage;
160 return 0;
161}
162
163/*****************************/
164/* Hardware access functions */
165/*****************************/
166
167static void saa_write_reg(unsigned char addr, unsigned char val)
168{
169 planb_regs->saa_addr = addr; eieio();
170 planb_regs->saa_regval = val; eieio();
171 return;
172}
173
174/* return status byte 0 or 1: */
175static unsigned char saa_status(int byte, struct planb *pb)
176{
177 saa_regs[pb->win.norm][SAA7196_STDC] =
178 (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
179 saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
180
181 /* Let's wait 30msec for this one */
182 msleep_interruptible(30);
183
184 return (unsigned char)in_8 (&planb_regs->saa_status);
185}
186
187static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
188{
189 if(saa_regs[pb->win.norm][addr] != val) {
190 saa_regs[pb->win.norm][addr] = val;
191 saa_write_reg (addr, val);
192 }
193 return;
194}
195
196static void saa_init_regs(struct planb *pb)
197{
198 int i;
199
200 for (i = 0; i < SAA7196_NUMREGS; i++)
201 saa_write_reg (i, saa_regs[pb->win.norm][i]);
202}
203
204static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
205 struct planb *pb)
206{
207 int ht, norm = pb->win.norm;
208
209 switch(bpp) {
210 case 2:
211 /* RGB555+a 1x16-bit + 16-bit transparent */
212 saa_regs[norm][SAA7196_FMTS] &= ~0x3;
213 break;
214 case 1:
215 case 4:
216 /* RGB888 1x24-bit + 8-bit transparent */
217 saa_regs[norm][SAA7196_FMTS] &= ~0x1;
218 saa_regs[norm][SAA7196_FMTS] |= 0x2;
219 break;
220 default:
221 return -EINVAL;
222 }
223 ht = (interlace ? height / 2 : height);
224 saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
225 saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
226 | (width >> 8 & 0x3);
227 saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
228 saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
229 | (ht >> 8 & 0x3);
230 /* feed both fields if interlaced, or else feed only even fields */
231 saa_regs[norm][SAA7196_FMTS] = (interlace) ?
232 (saa_regs[norm][SAA7196_FMTS] & ~0x60)
233 : (saa_regs[norm][SAA7196_FMTS] | 0x60);
234 /* transparent mode; extended format enabled */
235 saa_regs[norm][SAA7196_DPATH] |= 0x3;
236
237 return 0;
238}
239
240/***************************/
241/* DBDMA support functions */
242/***************************/
243
244static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
245{
246 out_le32(&ch->control, PLANB_CLR(RUN));
247 out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
248}
249
250static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
251{
252 int i = 0;
253
254 out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
255 while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
256 IDEBUG("PlanB: waiting for DMA to stop\n");
257 i++;
258 }
259}
260
261static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
262 unsigned short command, unsigned int cmd_dep)
263{
264 st_le16(&ch->command, command);
265 st_le32(&ch->cmd_dep, cmd_dep);
266}
267
268static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
269 unsigned int phy_addr, unsigned int cmd_dep)
270{
271 st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
272 st_le16(&ch->req_count, 4);
273 st_le32(&ch->phy_addr, phy_addr);
274 st_le32(&ch->cmd_dep, cmd_dep);
275}
276
277static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
278 unsigned short command, unsigned short req_count,
279 unsigned int phy_addr, unsigned int cmd_dep)
280{
281 st_le16(&ch->command, command);
282 st_le16(&ch->req_count, req_count);
283 st_le32(&ch->phy_addr, phy_addr);
284 st_le32(&ch->cmd_dep, cmd_dep);
285}
286
287static volatile struct dbdma_cmd *cmd_geo_setup(
288 volatile struct dbdma_cmd *c1, int width, int height, int interlace,
289 int bpp, int clip, struct planb *pb)
290{
291 int norm = pb->win.norm;
292
293 if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
294 return (volatile struct dbdma_cmd *)NULL;
295 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
296 SAA7196_FMTS);
297 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
298 saa_regs[norm][SAA7196_FMTS]);
299 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
300 SAA7196_DPATH);
301 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
302 saa_regs[norm][SAA7196_DPATH]);
303 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
304 bpp | ((clip)? PLANB_CLIPMASK: 0));
305 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
306 bpp | ((clip)? PLANB_CLIPMASK: 0));
307 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
308 SAA7196_OUTPIX);
309 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
310 saa_regs[norm][SAA7196_OUTPIX]);
311 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
312 SAA7196_HFILT);
313 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
314 saa_regs[norm][SAA7196_HFILT]);
315 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
316 SAA7196_OUTLINE);
317 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
318 saa_regs[norm][SAA7196_OUTLINE]);
319 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
320 SAA7196_VYP);
321 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
322 saa_regs[norm][SAA7196_VYP]);
323 return c1;
324}
325
326/******************************/
327/* misc. supporting functions */
328/******************************/
329
330static inline void planb_lock(struct planb *pb)
331{
332 down(&pb->lock);
333}
334
335static inline void planb_unlock(struct planb *pb)
336{
337 up(&pb->lock);
338}
339
340/***************/
341/* Driver Core */
342/***************/
343
344static int planb_prepare_open(struct planb *pb)
345{
346 int i, size;
347
348 /* allocate memory for two plus alpha command buffers (size: max lines,
349 plus 40 commands handling, plus 1 alignment), plus dummy command buf,
350 plus clipmask buffer, plus frame grabbing status */
351 size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
352 * PLANB_DUMMY)*sizeof(struct dbdma_cmd)
353 +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
354 +MAX_GBUFFERS*sizeof(unsigned int);
355 if ((pb->priv_space = kmalloc (size, GFP_KERNEL)) == 0)
356 return -ENOMEM;
357 memset ((void *) pb->priv_space, 0, size);
358 pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
359 DBDMA_ALIGN (pb->priv_space);
360 pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
361 pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
362 pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
363 pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
364 for (i = 1; i < MAX_GBUFFERS; i++) {
365 pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
366 pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
367 }
368 pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
369 + PLANB_DUMMY);
370 pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
371
372 pb->rawbuf = NULL;
373 pb->rawbuf_size = 0;
374 pb->grabbing = 0;
375 for (i = 0; i < MAX_GBUFFERS; i++) {
376 pb->frame_stat[i] = GBUFFER_UNUSED;
377 pb->gwidth[i] = 0;
378 pb->gheight[i] = 0;
379 pb->gfmt[i] = 0;
380 pb->gnorm_switch[i] = 0;
381#ifndef PLANB_GSCANLINE
382 pb->lsize[i] = 0;
383 pb->lnum[i] = 0;
384#endif /* PLANB_GSCANLINE */
385 }
386 pb->gcount = 0;
387 pb->suspend = 0;
388 pb->last_fr = -999;
389 pb->prev_last_fr = -999;
390
391 /* Reset DMA controllers */
392 planb_dbdma_stop(&pb->planb_base->ch2);
393 planb_dbdma_stop(&pb->planb_base->ch1);
394
395 return 0;
396}
397
398static void planb_prepare_close(struct planb *pb)
399{
400 int i;
401
402 /* make sure the dma's are idle */
403 planb_dbdma_stop(&pb->planb_base->ch2);
404 planb_dbdma_stop(&pb->planb_base->ch1);
405 /* free kernel memory of command buffers */
406 if(pb->priv_space != 0) {
407 kfree (pb->priv_space);
408 pb->priv_space = 0;
409 pb->cmd_buff_inited = 0;
410 }
411 if(pb->rawbuf) {
412 for (i = 0; i < pb->rawbuf_size; i++) {
413 ClearPageReserved(virt_to_page(pb->rawbuf[i]));
414 free_pages((unsigned long)pb->rawbuf[i], 0);
415 }
416 kfree(pb->rawbuf);
417 }
418 pb->rawbuf = NULL;
419}
420
421/*****************************/
422/* overlay support functions */
423/*****************************/
424
425static inline int overlay_is_active(struct planb *pb)
426{
427 unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
428 unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
429
430 return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
431 && (caddr < (pb->ch1_cmd_phys + size))
432 && (caddr >= (unsigned)pb->ch1_cmd_phys);
433}
434
435static void overlay_start(struct planb *pb)
436{
437
438 DEBUG("PlanB: overlay_start()\n");
439
440 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
441
442 DEBUG("PlanB: presumably, grabbing is in progress...\n");
443
444 planb_dbdma_stop(&pb->planb_base->ch2);
445 out_le32 (&pb->planb_base->ch2.cmdptr,
446 virt_to_bus(pb->ch2_cmd));
447 planb_dbdma_restart(&pb->planb_base->ch2);
448 st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
449 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
450 DBDMA_NOP | BR_ALWAYS,
451 virt_to_bus(pb->ch1_cmd));
452 eieio();
453 pb->prev_last_fr = pb->last_fr;
454 pb->last_fr = -2;
455 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
456 IDEBUG("PlanB: became inactive "
457 "in the mean time... reactivating\n");
458 planb_dbdma_stop(&pb->planb_base->ch1);
459 out_le32 (&pb->planb_base->ch1.cmdptr,
460 virt_to_bus(pb->ch1_cmd));
461 planb_dbdma_restart(&pb->planb_base->ch1);
462 }
463 } else {
464
465 DEBUG("PlanB: currently idle, so can do whatever\n");
466
467 planb_dbdma_stop(&pb->planb_base->ch2);
468 planb_dbdma_stop(&pb->planb_base->ch1);
469 st_le32 (&pb->planb_base->ch2.cmdptr,
470 virt_to_bus(pb->ch2_cmd));
471 st_le32 (&pb->planb_base->ch1.cmdptr,
472 virt_to_bus(pb->ch1_cmd));
473 out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
474 planb_dbdma_restart(&pb->planb_base->ch2);
475 planb_dbdma_restart(&pb->planb_base->ch1);
476 pb->last_fr = -1;
477 }
478 return;
479}
480
481static void overlay_stop(struct planb *pb)
482{
483 DEBUG("PlanB: overlay_stop()\n");
484
485 if(pb->last_fr == -1) {
486
487 DEBUG("PlanB: no grabbing, it seems...\n");
488
489 planb_dbdma_stop(&pb->planb_base->ch2);
490 planb_dbdma_stop(&pb->planb_base->ch1);
491 pb->last_fr = -999;
492 } else if(pb->last_fr == -2) {
493 unsigned int cmd_dep;
494 tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
495 eieio();
496 cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
497 if(overlay_is_active(pb)) {
498
499 DEBUG("PlanB: overlay is currently active\n");
500
501 planb_dbdma_stop(&pb->planb_base->ch2);
502 planb_dbdma_stop(&pb->planb_base->ch1);
503 if(cmd_dep != pb->ch1_cmd_phys) {
504 out_le32(&pb->planb_base->ch1.cmdptr,
505 virt_to_bus(pb->overlay_last1));
506 planb_dbdma_restart(&pb->planb_base->ch1);
507 }
508 }
509 pb->last_fr = pb->prev_last_fr;
510 pb->prev_last_fr = -999;
511 }
512 return;
513}
514
515static void suspend_overlay(struct planb *pb)
516{
517 int fr = -1;
518 struct dbdma_cmd last;
519
520 DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
521
522 if(pb->suspend++)
523 return;
524 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
525 if(pb->last_fr == -2) {
526 fr = pb->prev_last_fr;
527 memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
528 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
529 }
530 if(overlay_is_active(pb)) {
531 planb_dbdma_stop(&pb->planb_base->ch2);
532 planb_dbdma_stop(&pb->planb_base->ch1);
533 pb->suspended.overlay = 1;
534 pb->suspended.frame = fr;
535 memcpy(&pb->suspended.cmd, &last, sizeof(last));
536 return;
537 }
538 }
539 pb->suspended.overlay = 0;
540 pb->suspended.frame = fr;
541 memcpy(&pb->suspended.cmd, &last, sizeof(last));
542 return;
543}
544
545static void resume_overlay(struct planb *pb)
546{
547
548 DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
549
550 if(pb->suspend > 1)
551 return;
552 if(pb->suspended.frame != -1) {
553 memcpy((void*)pb->last_cmd[pb->suspended.frame],
554 &pb->suspended.cmd, sizeof(pb->suspended.cmd));
555 }
556 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
557 goto finish;
558 }
559 if(pb->suspended.overlay) {
560
561 DEBUG("PlanB: overlay being resumed\n");
562
563 st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
564 st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
565 /* Set command buffer addresses */
566 st_le32(&pb->planb_base->ch1.cmdptr,
567 virt_to_bus(pb->overlay_last1));
568 out_le32(&pb->planb_base->ch2.cmdptr,
569 virt_to_bus(pb->overlay_last2));
570 /* Start the DMA controller */
571 out_le32 (&pb->planb_base->ch2.control,
572 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
573 out_le32 (&pb->planb_base->ch1.control,
574 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
575 } else if(pb->suspended.frame != -1) {
576 out_le32(&pb->planb_base->ch1.cmdptr,
577 virt_to_bus(pb->last_cmd[pb->suspended.frame]));
578 out_le32 (&pb->planb_base->ch1.control,
579 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
580 }
581
582finish:
583 pb->suspend--;
584 wake_up_interruptible(&pb->suspendq);
585}
586
587static void add_clip(struct planb *pb, struct video_clip *clip)
588{
589 volatile unsigned char *base;
590 int xc = clip->x, yc = clip->y;
591 int wc = clip->width, hc = clip->height;
592 int ww = pb->win.width, hw = pb->win.height;
593 int x, y, xtmp1, xtmp2;
594
595 DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
596
597 if(xc < 0) {
598 wc += xc;
599 xc = 0;
600 }
601 if(yc < 0) {
602 hc += yc;
603 yc = 0;
604 }
605 if(xc + wc > ww)
606 wc = ww - xc;
607 if(wc <= 0) /* Nothing to do */
608 return;
609 if(yc + hc > hw)
610 hc = hw - yc;
611
612 for (y = yc; y < yc+hc; y++) {
613 xtmp1=xc>>3;
614 xtmp2=(xc+wc)>>3;
615 base = pb->mask + y*96;
616 if(xc != 0 || wc >= 8)
617 *(base + xtmp1) &= (unsigned char)(0x00ff &
618 (0xff00 >> (xc&7)));
619 for (x = xtmp1 + 1; x < xtmp2; x++) {
620 *(base + x) = 0;
621 }
622 if(xc < (ww & ~0x7))
623 *(base + xtmp2) &= (unsigned char)(0x00ff >>
624 ((xc+wc) & 7));
625 }
626
627 return;
628}
629
630static void fill_cmd_buff(struct planb *pb)
631{
632 int restore = 0;
633 volatile struct dbdma_cmd last;
634
635 DEBUG("PlanB: fill_cmd_buff()\n");
636
637 if(pb->overlay_last1 != pb->ch1_cmd) {
638 restore = 1;
639 last = *(pb->overlay_last1);
640 }
641 memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
642 * sizeof(struct dbdma_cmd));
643 cmd_buff (pb);
644 if(restore)
645 *(pb->overlay_last1) = last;
646 if(pb->suspended.overlay) {
647 unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
648 if(jump_addr != pb->ch1_cmd_phys) {
649 int i;
650
651 DEBUG("PlanB: adjusting ch1's jump address\n");
652
653 for(i = 0; i < MAX_GBUFFERS; i++) {
654 if(pb->need_pre_capture[i]) {
655 if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
656 goto found;
657 } else {
658 if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
659 goto found;
660 }
661 }
662
663 DEBUG("PlanB: not found...\n");
664
665 goto out;
666found:
667 if(pb->need_pre_capture[i])
668 out_le32(&pb->pre_cmd[i]->phy_addr,
669 virt_to_bus(pb->overlay_last1));
670 else
671 out_le32(&pb->cap_cmd[i]->phy_addr,
672 virt_to_bus(pb->overlay_last1));
673 }
674 }
675out:
676 pb->cmd_buff_inited = 1;
677
678 return;
679}
680
681static void cmd_buff(struct planb *pb)
682{
683 int i, bpp, count, nlines, stepsize, interlace;
684 unsigned long base, jump, addr_com, addr_dep;
685 volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
686 volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
687
688 interlace = pb->win.interlace;
689 bpp = pb->win.bpp;
690 count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
691 (pb->win.swidth - pb->win.x) : pb->win.width));
692 nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
693 (pb->win.sheight - pb->win.y) : pb->win.height);
694
695 /* Do video in: */
696
697 /* Preamble commands: */
698 addr_com = virt_to_bus(c1);
699 addr_dep = virt_to_bus(&c1->cmd_dep);
700 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
701 jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
702 if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
703 bpp, 1, pb)) == NULL) {
704 printk(KERN_WARNING "PlanB: encountered serious problems\n");
705 tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
706 tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
707 return;
708 }
709 tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
710 tab_cmd_store(c1++, addr_dep, jump);
711 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
712 PLANB_SET(FIELD_SYNC));
713 /* (1) wait for field sync to be set */
714 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
715 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
716 PLANB_SET(ODD_FIELD));
717 /* wait for field sync to be cleared */
718 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
719 /* if not odd field, wait until field sync is set again */
720 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
721 /* assert ch_sync to ch2 */
722 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
723 PLANB_SET(CH_SYNC));
724 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
725 PLANB_SET(DMA_ABORT));
726
727 base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
728 + pb->win.pad) + pb->win.x * bpp);
729
730 if (interlace) {
731 stepsize = 2;
732 jump = virt_to_bus(c1 + (nlines + 1) / 2);
733 } else {
734 stepsize = 1;
735 jump = virt_to_bus(c1 + nlines);
736 }
737
738 /* even field data: */
739 for (i=0; i < nlines; i += stepsize, c1++)
740 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
741 count, base + i * (pb->win.bpl + pb->win.pad), jump);
742
743 /* For non-interlaced, we use even fields only */
744 if (!interlace)
745 goto cmd_tab_data_end;
746
747 /* Resync to odd field */
748 /* (2) wait for field sync to be set */
749 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
750 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
751 PLANB_SET(ODD_FIELD));
752 /* wait for field sync to be cleared */
753 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
754 /* if not odd field, wait until field sync is set again */
755 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
756 /* assert ch_sync to ch2 */
757 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
758 PLANB_SET(CH_SYNC));
759 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
760 PLANB_SET(DMA_ABORT));
761
762 /* odd field data: */
763 jump = virt_to_bus(c1 + nlines / 2);
764 for (i=1; i < nlines; i += stepsize, c1++)
765 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
766 base + i * (pb->win.bpl + pb->win.pad), jump);
767
768 /* And jump back to the start */
769cmd_tab_data_end:
770 pb->overlay_last1 = c1; /* keep a pointer to the last command */
771 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
772
773 /* Clipmask command buffer */
774
775 /* Preamble commands: */
776 tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
777 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
778 PLANB_SET(CH_SYNC));
779 /* wait until ch1 asserts ch_sync */
780 tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
781 /* clear ch_sync asserted by ch1 */
782 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
783 PLANB_CLR(CH_SYNC));
784 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
785 PLANB_SET(FIELD_SYNC));
786 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
787 PLANB_SET(ODD_FIELD));
788
789 /* jump to end of even field if appropriate */
790 /* this points to (interlace)? pos. C: pos. B */
791 jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
792 virt_to_bus(c2 + nlines + 2);
793 /* if odd field, skip over to odd field clipmasking */
794 tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
795
796 /* even field mask: */
797 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
798 PLANB_SET(DMA_ABORT));
799 /* this points to pos. B */
800 jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
801 virt_to_bus(c2 + nlines);
802 base = virt_to_bus(pb->mask);
803 for (i=0; i < nlines; i += stepsize, c2++)
804 tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
805 base + i * 96, jump);
806
807 /* For non-interlaced, we use only even fields */
808 if(!interlace)
809 goto cmd_tab_mask_end;
810
811 /* odd field mask: */
812/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
813 PLANB_SET(DMA_ABORT));
814 /* this points to pos. B */
815 jump = virt_to_bus(c2 + nlines / 2);
816 base = virt_to_bus(pb->mask);
817 for (i=1; i < nlines; i += 2, c2++) /* abort if set */
818 tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
819 base + i * 96, jump);
820
821 /* Inform channel 1 and jump back to start */
822cmd_tab_mask_end:
823 /* ok, I just realized this is kind of flawed. */
824 /* this part is reached only after odd field clipmasking. */
825 /* wanna clean up? */
826 /* wait for field sync to be set */
827 /* corresponds to fsync (1) of ch1 */
828/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
829 /* restart ch1, meant to clear any dead bit or something */
830 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
831 PLANB_CLR(RUN));
832 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
833 PLANB_SET(RUN));
834 pb->overlay_last2 = c2; /* keep a pointer to the last command */
835 /* start over even field clipmasking */
836 tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
837
838 eieio();
839 return;
840}
841
842/*********************************/
843/* grabdisplay support functions */
844/*********************************/
845
846static int palette2fmt[] = {
847 0,
848 PLANB_GRAY,
849 0,
850 0,
851 0,
852 PLANB_COLOUR32,
853 PLANB_COLOUR15,
854 0,
855 0,
856 0,
857 0,
858 0,
859 0,
860 0,
861 0,
862};
863
864#define PLANB_PALETTE_MAX 15
865
866static int vgrab(struct planb *pb, struct video_mmap *mp)
867{
868 unsigned int fr = mp->frame;
869 unsigned int format;
870
871 if(pb->rawbuf==NULL) {
872 int err;
873 if((err=grabbuf_alloc(pb)))
874 return err;
875 }
876
877 IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
878 mp->width, mp->height, fr);
879
880 if(pb->grabbing >= MAX_GBUFFERS)
881 return -ENOBUFS;
882 if(fr > (MAX_GBUFFERS - 1) || fr < 0)
883 return -EINVAL;
884 if(mp->height <= 0 || mp->width <= 0)
885 return -EINVAL;
886 if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
887 return -EINVAL;
888 if((format = palette2fmt[mp->format]) == 0)
889 return -EINVAL;
890 if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
891 return -EINVAL;
892
893 planb_lock(pb);
894 if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
895 format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
896 int i;
897#ifndef PLANB_GSCANLINE
898 unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
899 * pb->gfmt[fr];
900 unsigned int nsize = mp->width * mp->height * format;
901#endif
902
903 IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
904 mp->width, mp->height, mp->format);
905
906#ifndef PLANB_GSCANLINE
907 if(pb->gnorm_switch[fr])
908 nsize = 0;
909 if (nsize < osize) {
910 for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
911 memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
912 osize -= PAGE_SIZE;
913 }
914 }
915 for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
916 + pb->lnum[fr]; i++)
917 memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
918#else
919/* XXX TODO */
920/*
921 if(pb->gnorm_switch[fr])
922 memset((void *)pb->gbuffer[fr], 0,
923 pb->gbytes_per_line * pb->gheight[fr]);
924 else {
925 if(mp->
926 for(i = 0; i < pb->gheight[fr]; i++) {
927 memset((void *)(pb->gbuffer[fr]
928 + pb->gbytes_per_line * i
929 }
930 }
931*/
932#endif
933 pb->gwidth[fr] = mp->width;
934 pb->gheight[fr] = mp->height;
935 pb->gfmt[fr] = format;
936 pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
937 planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
938 pb->need_pre_capture[fr] = 1;
939 pb->gnorm_switch[fr] = 0;
940 } else
941 pb->need_pre_capture[fr] = 0;
942 pb->frame_stat[fr] = GBUFFER_GRABBING;
943 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
944
945 IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
946
947 planb_dbdma_stop(&pb->planb_base->ch1);
948 if(pb->need_pre_capture[fr]) {
949
950 IDEBUG("PlanB: padding pre-capture sequence\n");
951
952 out_le32 (&pb->planb_base->ch1.cmdptr,
953 virt_to_bus(pb->pre_cmd[fr]));
954 } else {
955 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
956 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
957 /* let's be on the safe side. here is not timing critical. */
958 tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
959 out_le32 (&pb->planb_base->ch1.cmdptr,
960 virt_to_bus(pb->cap_cmd[fr]));
961 }
962 planb_dbdma_restart(&pb->planb_base->ch1);
963 pb->last_fr = fr;
964 } else {
965 int i;
966
967 IDEBUG("PlanB: ch1 active, grabbing being queued\n");
968
969 if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
970 overlay_is_active(pb))) {
971
972 IDEBUG("PlanB: overlay is active, grabbing defered\n");
973
974 tab_cmd_dbdma(pb->last_cmd[fr],
975 DBDMA_NOP | BR_ALWAYS,
976 virt_to_bus(pb->ch1_cmd));
977 if(pb->need_pre_capture[fr]) {
978
979 IDEBUG("PlanB: padding pre-capture sequence\n");
980
981 tab_cmd_store(pb->pre_cmd[fr],
982 virt_to_bus(&pb->overlay_last1->cmd_dep),
983 virt_to_bus(pb->ch1_cmd));
984 eieio();
985 out_le32 (&pb->overlay_last1->cmd_dep,
986 virt_to_bus(pb->pre_cmd[fr]));
987 } else {
988 tab_cmd_store(pb->cap_cmd[fr],
989 virt_to_bus(&pb->overlay_last1->cmd_dep),
990 virt_to_bus(pb->ch1_cmd));
991 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
992 DBDMA_NOP, 0);
993 eieio();
994 out_le32 (&pb->overlay_last1->cmd_dep,
995 virt_to_bus(pb->cap_cmd[fr]));
996 }
997 for(i = 0; overlay_is_active(pb) && i < 999; i++)
998 IDEBUG("PlanB: waiting for overlay done\n");
999 tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
1000 pb->prev_last_fr = fr;
1001 pb->last_fr = -2;
1002 } else if(pb->last_fr == -2) {
1003
1004 IDEBUG("PlanB: mixed mode detected, grabbing"
1005 " will be done before activating overlay\n");
1006
1007 tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
1008 if(pb->need_pre_capture[fr]) {
1009
1010 IDEBUG("PlanB: padding pre-capture sequence\n");
1011
1012 tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
1013 DBDMA_NOP | BR_ALWAYS,
1014 virt_to_bus(pb->pre_cmd[fr]));
1015 eieio();
1016 } else {
1017 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
1018 if(pb->gwidth[pb->prev_last_fr] !=
1019 pb->gwidth[fr]
1020 || pb->gheight[pb->prev_last_fr] !=
1021 pb->gheight[fr]
1022 || pb->gfmt[pb->prev_last_fr] !=
1023 pb->gfmt[fr])
1024 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1025 DBDMA_NOP, 0);
1026 else
1027 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1028 DBDMA_NOP | BR_ALWAYS,
1029 virt_to_bus(pb->cap_cmd[fr] + 16));
1030 tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
1031 DBDMA_NOP | BR_ALWAYS,
1032 virt_to_bus(pb->cap_cmd[fr]));
1033 eieio();
1034 }
1035 tab_cmd_dbdma(pb->last_cmd[fr],
1036 DBDMA_NOP | BR_ALWAYS,
1037 virt_to_bus(pb->ch1_cmd));
1038 eieio();
1039 pb->prev_last_fr = fr;
1040 pb->last_fr = -2;
1041 } else {
1042
1043 IDEBUG("PlanB: active grabbing session detected\n");
1044
1045 if(pb->need_pre_capture[fr]) {
1046
1047 IDEBUG("PlanB: padding pre-capture sequence\n");
1048
1049 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
1050 DBDMA_NOP | BR_ALWAYS,
1051 virt_to_bus(pb->pre_cmd[fr]));
1052 eieio();
1053 } else {
1054 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
1055 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
1056 if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
1057 || pb->gheight[pb->last_fr] !=
1058 pb->gheight[fr]
1059 || pb->gfmt[pb->last_fr] !=
1060 pb->gfmt[fr])
1061 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1062 DBDMA_NOP, 0);
1063 else
1064 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1065 DBDMA_NOP | BR_ALWAYS,
1066 virt_to_bus(pb->cap_cmd[fr] + 16));
1067 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
1068 DBDMA_NOP | BR_ALWAYS,
1069 virt_to_bus(pb->cap_cmd[fr]));
1070 eieio();
1071 }
1072 pb->last_fr = fr;
1073 }
1074 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
1075
1076 IDEBUG("PlanB: became inactive in the mean time..."
1077 "reactivating\n");
1078
1079 planb_dbdma_stop(&pb->planb_base->ch1);
1080 out_le32 (&pb->planb_base->ch1.cmdptr,
1081 virt_to_bus(pb->cap_cmd[fr]));
1082 planb_dbdma_restart(&pb->planb_base->ch1);
1083 }
1084 }
1085 pb->grabbing++;
1086 planb_unlock(pb);
1087
1088 return 0;
1089}
1090
1091static void planb_pre_capture(int fr, int bpp, struct planb *pb)
1092{
1093 volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
1094 int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
1095
1096 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
1097 if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
1098 bpp, 0, pb)) == NULL) {
1099 printk(KERN_WARNING "PlanB: encountered some problems\n");
1100 tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
1101 return;
1102 }
1103 /* Sync to even field */
1104 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
1105 PLANB_SET(FIELD_SYNC));
1106 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1107 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1108 PLANB_SET(ODD_FIELD));
1109 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1110 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
1111 tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
1112 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1113 PLANB_SET(DMA_ABORT));
1114 /* For non-interlaced, we use even fields only */
1115 if (pb->gheight[fr] <= pb->maxlines/2)
1116 goto cmd_tab_data_end;
1117 /* Sync to odd field */
1118 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1119 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1120 PLANB_SET(ODD_FIELD));
1121 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1122 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
1123 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1124 PLANB_SET(DMA_ABORT));
1125cmd_tab_data_end:
1126 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
1127
1128 eieio();
1129}
1130
1131static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
1132{
1133 int i, bpp, count, nlines, stepsize, interlace;
1134#ifdef PLANB_GSCANLINE
1135 int scanline;
1136#else
1137 int nlpp, leftover1;
1138 unsigned long base;
1139#endif
1140 unsigned long jump;
1141 int pagei;
1142 volatile struct dbdma_cmd *c1;
1143 volatile struct dbdma_cmd *jump_addr;
1144
1145 c1 = pb->cap_cmd[fr];
1146 interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
1147 bpp = pb->gfmt[fr]; /* gfmt = bpp */
1148 count = bpp * pb->gwidth[fr];
1149 nlines = pb->gheight[fr];
1150#ifdef PLANB_GSCANLINE
1151 scanline = pb->gbytes_per_line;
1152#else
1153 pb->lsize[fr] = count;
1154 pb->lnum[fr] = 0;
1155#endif
1156
1157 /* Do video in: */
1158
1159 /* Preamble commands: */
1160 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
1161 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
1162 if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
1163 bpp, 0, pb)) == NULL) {
1164 printk(KERN_WARNING "PlanB: encountered serious problems\n");
1165 tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
1166 return (pb->cap_cmd[fr] + 2);
1167 }
1168 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
1169 PLANB_SET(FIELD_SYNC));
1170 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1171 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1172 PLANB_SET(ODD_FIELD));
1173 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1174 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
1175 tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
1176 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1177 PLANB_SET(DMA_ABORT));
1178
1179 if (interlace) {
1180 stepsize = 2;
1181 jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
1182 } else {
1183 stepsize = 1;
1184 jump_addr = c1 + TAB_FACTOR * nlines;
1185 }
1186 jump = virt_to_bus(jump_addr);
1187
1188 /* even field data: */
1189
1190 pagei = pb->gbuf_idx[fr];
1191#ifdef PLANB_GSCANLINE
1192 for (i = 0; i < nlines; i += stepsize) {
1193 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1194 virt_to_bus(pb->rawbuf[pagei
1195 + i * scanline / PAGE_SIZE]), jump);
1196 }
1197#else
1198 i = 0;
1199 leftover1 = 0;
1200 do {
1201 int j;
1202
1203 base = virt_to_bus(pb->rawbuf[pagei]);
1204 nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
1205 for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
1206 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
1207 count, base + count * j * stepsize + leftover1, jump);
1208 if(i < nlines) {
1209 int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
1210
1211 if(lov0 == 0)
1212 leftover1 = 0;
1213 else {
1214 if(lov0 >= count) {
1215 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
1216 + count * nlpp * stepsize + leftover1, jump);
1217 } else {
1218 pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
1219 + count * nlpp * stepsize + leftover1;
1220 pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
1221 pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
1222 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1223 virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
1224 + pb->lnum[fr]]), jump);
1225 if(++pb->lnum[fr] > MAX_LNUM)
1226 pb->lnum[fr]--;
1227 }
1228 leftover1 = count * stepsize - lov0;
1229 i += stepsize;
1230 }
1231 }
1232 pagei++;
1233 } while(i < nlines);
1234 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
1235 c1 = jump_addr;
1236#endif /* PLANB_GSCANLINE */
1237
1238 /* For non-interlaced, we use even fields only */
1239 if (!interlace)
1240 goto cmd_tab_data_end;
1241
1242 /* Sync to odd field */
1243 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1244 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1245 PLANB_SET(ODD_FIELD));
1246 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1247 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
1248 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1249 PLANB_SET(DMA_ABORT));
1250
1251 /* odd field data: */
1252 jump_addr = c1 + TAB_FACTOR * nlines / 2;
1253 jump = virt_to_bus(jump_addr);
1254#ifdef PLANB_GSCANLINE
1255 for (i = 1; i < nlines; i += stepsize) {
1256 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1257 virt_to_bus(pb->rawbuf[pagei
1258 + i * scanline / PAGE_SIZE]), jump);
1259 }
1260#else
1261 i = 1;
1262 leftover1 = 0;
1263 pagei = pb->gbuf_idx[fr];
1264 if(nlines <= 1)
1265 goto skip;
1266 do {
1267 int j;
1268
1269 base = virt_to_bus(pb->rawbuf[pagei]);
1270 nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
1271 if(leftover1 >= count) {
1272 tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
1273 base + leftover1 - count, jump);
1274 i += stepsize;
1275 }
1276 for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
1277 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
1278 base + count * (j * stepsize + 1) + leftover1, jump);
1279 if(i < nlines) {
1280 int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
1281
1282 if(lov0 == 0)
1283 leftover1 = 0;
1284 else {
1285 if(lov0 > count) {
1286 pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
1287 + count * (nlpp * stepsize + 1) + leftover1;
1288 pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
1289 pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
1290 - lov0;
1291 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1292 virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
1293 + pb->lnum[fr]]), jump);
1294 if(++pb->lnum[fr] > MAX_LNUM)
1295 pb->lnum[fr]--;
1296 i += stepsize;
1297 }
1298 leftover1 = count * stepsize - lov0;
1299 }
1300 }
1301 pagei++;
1302 } while(i < nlines);
1303skip:
1304 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
1305 c1 = jump_addr;
1306#endif /* PLANB_GSCANLINE */
1307
1308cmd_tab_data_end:
1309 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
1310 (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
1311 /* stop it */
1312 tab_cmd_dbdma(c1, DBDMA_STOP, 0);
1313
1314 eieio();
1315 return c1;
1316}
1317
1318static void planb_irq(int irq, void *dev_id, struct pt_regs * regs)
1319{
1320 unsigned int stat, astat;
1321 struct planb *pb = (struct planb *)dev_id;
1322
1323 IDEBUG("PlanB: planb_irq()\n");
1324
1325 /* get/clear interrupt status bits */
1326 eieio();
1327 stat = in_le32(&pb->planb_base->intr_stat);
1328 astat = stat & pb->intr_mask;
1329 out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
1330 & ~astat & stat & ~PLANB_GEN_IRQ);
1331 IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
1332
1333 if(astat & PLANB_FRM_IRQ) {
1334 unsigned int fr = stat >> 9;
1335#ifndef PLANB_GSCANLINE
1336 int i;
1337#endif
1338 IDEBUG("PlanB: PLANB_FRM_IRQ\n");
1339
1340 pb->gcount++;
1341
1342 IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
1343 pb->grabbing, fr, pb->gcount);
1344#ifndef PLANB_GSCANLINE
1345 IDEBUG("PlanB: %d * %d bytes are being copied over\n",
1346 pb->lnum[fr], pb->lsize[fr]);
1347 for(i = 0; i < pb->lnum[fr]; i++) {
1348 int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
1349
1350 memcpy(pb->l_to_addr[fr][i],
1351 pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
1352 first);
1353 memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
1354 pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
1355 pb->l_to_next_size[fr][i]);
1356 }
1357#endif
1358 pb->frame_stat[fr] = GBUFFER_DONE;
1359 pb->grabbing--;
1360 wake_up_interruptible(&pb->capq);
1361 return;
1362 }
1363 /* incorrect interrupts? */
1364 pb->intr_mask = PLANB_CLR_IRQ;
1365 out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
1366 printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
1367 " unconditionally\n");
1368}
1369
1370/*******************************
1371 * Device Operations functions *
1372 *******************************/
1373
1374static int planb_open(struct video_device *dev, int mode)
1375{
1376 struct planb *pb = (struct planb *)dev;
1377
1378 if (pb->user == 0) {
1379 int err;
1380 if((err = planb_prepare_open(pb)) != 0)
1381 return err;
1382 }
1383 pb->user++;
1384
1385 DEBUG("PlanB: device opened\n");
1386 return 0;
1387}
1388
1389static void planb_close(struct video_device *dev)
1390{
1391 struct planb *pb = (struct planb *)dev;
1392
1393 if(pb->user < 1) /* ??? */
1394 return;
1395 planb_lock(pb);
1396 if (pb->user == 1) {
1397 if (pb->overlay) {
1398 planb_dbdma_stop(&pb->planb_base->ch2);
1399 planb_dbdma_stop(&pb->planb_base->ch1);
1400 pb->overlay = 0;
1401 }
1402 planb_prepare_close(pb);
1403 }
1404 pb->user--;
1405 planb_unlock(pb);
1406
1407 DEBUG("PlanB: device closed\n");
1408}
1409
1410static long planb_read(struct video_device *v, char *buf, unsigned long count,
1411 int nonblock)
1412{
1413 DEBUG("planb: read request\n");
1414 return -EINVAL;
1415}
1416
1417static long planb_write(struct video_device *v, const char *buf,
1418 unsigned long count, int nonblock)
1419{
1420 DEBUG("planb: write request\n");
1421 return -EINVAL;
1422}
1423
1424static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
1425{
1426 struct planb *pb=(struct planb *)dev;
1427
1428 switch (cmd)
1429 {
1430 case VIDIOCGCAP:
1431 {
1432 struct video_capability b;
1433
1434 DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
1435
1436 strcpy (b.name, pb->video_dev.name);
1437 b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
1438 VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
1439 VID_TYPE_CAPTURE;
1440 b.channels = 2; /* composite & svhs */
1441 b.audios = 0;
1442 b.maxwidth = PLANB_MAXPIXELS;
1443 b.maxheight = PLANB_MAXLINES;
1444 b.minwidth = 32; /* wild guess */
1445 b.minheight = 32;
1446 if (copy_to_user(arg,&b,sizeof(b)))
1447 return -EFAULT;
1448 return 0;
1449 }
1450 case VIDIOCSFBUF:
1451 {
1452 struct video_buffer v;
1453 unsigned short bpp;
1454 unsigned int fmt;
1455
1456 DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
1457
1458 if (!capable(CAP_SYS_ADMIN)
1459 || !capable(CAP_SYS_RAWIO))
1460 return -EPERM;
1461 if (copy_from_user(&v, arg,sizeof(v)))
1462 return -EFAULT;
1463 planb_lock(pb);
1464 switch(v.depth) {
1465 case 8:
1466 bpp = 1;
1467 fmt = PLANB_GRAY;
1468 break;
1469 case 15:
1470 case 16:
1471 bpp = 2;
1472 fmt = PLANB_COLOUR15;
1473 break;
1474 case 24:
1475 case 32:
1476 bpp = 4;
1477 fmt = PLANB_COLOUR32;
1478 break;
1479 default:
1480 planb_unlock(pb);
1481 return -EINVAL;
1482 }
1483 if (bpp * v.width > v.bytesperline) {
1484 planb_unlock(pb);
1485 return -EINVAL;
1486 }
1487 pb->win.bpp = bpp;
1488 pb->win.color_fmt = fmt;
1489 pb->frame_buffer_phys = (unsigned long) v.base;
1490 pb->win.sheight = v.height;
1491 pb->win.swidth = v.width;
1492 pb->picture.depth = pb->win.depth = v.depth;
1493 pb->win.bpl = pb->win.bpp * pb->win.swidth;
1494 pb->win.pad = v.bytesperline - pb->win.bpl;
1495
1496 DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
1497 " bpl %d (+ %d)\n", v.base, v.width,v.height,
1498 pb->win.bpp, pb->win.bpl, pb->win.pad);
1499
1500 pb->cmd_buff_inited = 0;
1501 if(pb->overlay) {
1502 suspend_overlay(pb);
1503 fill_cmd_buff(pb);
1504 resume_overlay(pb);
1505 }
1506 planb_unlock(pb);
1507 return 0;
1508 }
1509 case VIDIOCGFBUF:
1510 {
1511 struct video_buffer v;
1512
1513 DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
1514
1515 v.base = (void *)pb->frame_buffer_phys;
1516 v.height = pb->win.sheight;
1517 v.width = pb->win.swidth;
1518 v.depth = pb->win.depth;
1519 v.bytesperline = pb->win.bpl + pb->win.pad;
1520 if (copy_to_user(arg, &v, sizeof(v)))
1521 return -EFAULT;
1522 return 0;
1523 }
1524 case VIDIOCCAPTURE:
1525 {
1526 int i;
1527
1528 if(copy_from_user(&i, arg, sizeof(i)))
1529 return -EFAULT;
1530 if(i==0) {
1531 DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
1532
1533 if (!(pb->overlay))
1534 return 0;
1535 planb_lock(pb);
1536 pb->overlay = 0;
1537 overlay_stop(pb);
1538 planb_unlock(pb);
1539 } else {
1540 DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
1541
1542 if (pb->frame_buffer_phys == 0 ||
1543 pb->win.width == 0 ||
1544 pb->win.height == 0)
1545 return -EINVAL;
1546 if (pb->overlay)
1547 return 0;
1548 planb_lock(pb);
1549 pb->overlay = 1;
1550 if(!(pb->cmd_buff_inited))
1551 fill_cmd_buff(pb);
1552 overlay_start(pb);
1553 planb_unlock(pb);
1554 }
1555 return 0;
1556 }
1557 case VIDIOCGCHAN:
1558 {
1559 struct video_channel v;
1560
1561 DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
1562
1563 if(copy_from_user(&v, arg,sizeof(v)))
1564 return -EFAULT;
1565 v.flags = 0;
1566 v.tuners = 0;
1567 v.type = VIDEO_TYPE_CAMERA;
1568 v.norm = pb->win.norm;
1569 switch(v.channel)
1570 {
1571 case 0:
1572 strcpy(v.name,"Composite");
1573 break;
1574 case 1:
1575 strcpy(v.name,"SVHS");
1576 break;
1577 default:
1578 return -EINVAL;
1579 break;
1580 }
1581 if(copy_to_user(arg,&v,sizeof(v)))
1582 return -EFAULT;
1583
1584 return 0;
1585 }
1586 case VIDIOCSCHAN:
1587 {
1588 struct video_channel v;
1589
1590 DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
1591
1592 if(copy_from_user(&v, arg, sizeof(v)))
1593 return -EFAULT;
1594
1595 if (v.norm != pb->win.norm) {
1596 int i, maxlines;
1597
1598 switch (v.norm)
1599 {
1600 case VIDEO_MODE_PAL:
1601 case VIDEO_MODE_SECAM:
1602 maxlines = PLANB_MAXLINES;
1603 break;
1604 case VIDEO_MODE_NTSC:
1605 maxlines = PLANB_NTSC_MAXLINES;
1606 break;
1607 default:
1608 return -EINVAL;
1609 break;
1610 }
1611 planb_lock(pb);
1612 /* empty the grabbing queue */
1613 wait_event(pb->capq, !pb->grabbing);
1614 pb->maxlines = maxlines;
1615 pb->win.norm = v.norm;
1616 /* Stop overlay if running */
1617 suspend_overlay(pb);
1618 for(i = 0; i < MAX_GBUFFERS; i++)
1619 pb->gnorm_switch[i] = 1;
1620 /* I know it's an overkill, but.... */
1621 fill_cmd_buff(pb);
1622 /* ok, now init it accordingly */
1623 saa_init_regs (pb);
1624 /* restart overlay if it was running */
1625 resume_overlay(pb);
1626 planb_unlock(pb);
1627 }
1628
1629 switch(v.channel)
1630 {
1631 case 0: /* Composite */
1632 saa_set (SAA7196_IOCC,
1633 ((saa_regs[pb->win.norm][SAA7196_IOCC] &
1634 ~7) | 3), pb);
1635 break;
1636 case 1: /* SVHS */
1637 saa_set (SAA7196_IOCC,
1638 ((saa_regs[pb->win.norm][SAA7196_IOCC] &
1639 ~7) | 4), pb);
1640 break;
1641 default:
1642 return -EINVAL;
1643 break;
1644 }
1645
1646 return 0;
1647 }
1648 case VIDIOCGPICT:
1649 {
1650 struct video_picture vp = pb->picture;
1651
1652 DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
1653
1654 switch(pb->win.color_fmt) {
1655 case PLANB_GRAY:
1656 vp.palette = VIDEO_PALETTE_GREY;
1657 case PLANB_COLOUR15:
1658 vp.palette = VIDEO_PALETTE_RGB555;
1659 break;
1660 case PLANB_COLOUR32:
1661 vp.palette = VIDEO_PALETTE_RGB32;
1662 break;
1663 default:
1664 vp.palette = 0;
1665 break;
1666 }
1667
1668 if(copy_to_user(arg,&vp,sizeof(vp)))
1669 return -EFAULT;
1670 return 0;
1671 }
1672 case VIDIOCSPICT:
1673 {
1674 struct video_picture vp;
1675
1676 DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
1677
1678 if(copy_from_user(&vp,arg,sizeof(vp)))
1679 return -EFAULT;
1680 pb->picture = vp;
1681 /* Should we do sanity checks here? */
1682 saa_set (SAA7196_BRIG, (unsigned char)
1683 ((pb->picture.brightness) >> 8), pb);
1684 saa_set (SAA7196_HUEC, (unsigned char)
1685 ((pb->picture.hue) >> 8) ^ 0x80, pb);
1686 saa_set (SAA7196_CSAT, (unsigned char)
1687 ((pb->picture.colour) >> 9), pb);
1688 saa_set (SAA7196_CONT, (unsigned char)
1689 ((pb->picture.contrast) >> 9), pb);
1690
1691 return 0;
1692 }
1693 case VIDIOCSWIN:
1694 {
1695 struct video_window vw;
1696 struct video_clip clip;
1697 int i;
1698
1699 DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
1700
1701 if(copy_from_user(&vw,arg,sizeof(vw)))
1702 return -EFAULT;
1703
1704 planb_lock(pb);
1705 /* Stop overlay if running */
1706 suspend_overlay(pb);
1707 pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
1708 if (pb->win.x != vw.x ||
1709 pb->win.y != vw.y ||
1710 pb->win.width != vw.width ||
1711 pb->win.height != vw.height ||
1712 !pb->cmd_buff_inited) {
1713 pb->win.x = vw.x;
1714 pb->win.y = vw.y;
1715 pb->win.width = vw.width;
1716 pb->win.height = vw.height;
1717 fill_cmd_buff(pb);
1718 }
1719 /* Reset clip mask */
1720 memset ((void *) pb->mask, 0xff, (pb->maxlines
1721 * ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
1722 /* Add any clip rects */
1723 for (i = 0; i < vw.clipcount; i++) {
1724 if (copy_from_user(&clip, vw.clips + i,
1725 sizeof(struct video_clip)))
1726 return -EFAULT;
1727 add_clip(pb, &clip);
1728 }
1729 /* restart overlay if it was running */
1730 resume_overlay(pb);
1731 planb_unlock(pb);
1732 return 0;
1733 }
1734 case VIDIOCGWIN:
1735 {
1736 struct video_window vw;
1737
1738 DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
1739
1740 vw.x=pb->win.x;
1741 vw.y=pb->win.y;
1742 vw.width=pb->win.width;
1743 vw.height=pb->win.height;
1744 vw.chromakey=0;
1745 vw.flags=0;
1746 if(pb->win.interlace)
1747 vw.flags|=VIDEO_WINDOW_INTERLACE;
1748 if(copy_to_user(arg,&vw,sizeof(vw)))
1749 return -EFAULT;
1750 return 0;
1751 }
1752 case VIDIOCSYNC: {
1753 int i;
1754
1755 IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
1756
1757 if(copy_from_user((void *)&i,arg,sizeof(int)))
1758 return -EFAULT;
1759
1760 IDEBUG("PlanB: sync to frame %d\n", i);
1761
1762 if(i > (MAX_GBUFFERS - 1) || i < 0)
1763 return -EINVAL;
1764chk_grab:
1765 switch (pb->frame_stat[i]) {
1766 case GBUFFER_UNUSED:
1767 return -EINVAL;
1768 case GBUFFER_GRABBING:
1769 IDEBUG("PlanB: waiting for grab"
1770 " done (%d)\n", i);
1771 interruptible_sleep_on(&pb->capq);
1772 if(signal_pending(current))
1773 return -EINTR;
1774 goto chk_grab;
1775 case GBUFFER_DONE:
1776 pb->frame_stat[i] = GBUFFER_UNUSED;
1777 break;
1778 }
1779 return 0;
1780 }
1781
1782 case VIDIOCMCAPTURE:
1783 {
1784 struct video_mmap vm;
1785 volatile unsigned int status;
1786
1787 IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
1788
1789 if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
1790 return -EFAULT;
1791 status = pb->frame_stat[vm.frame];
1792 if (status != GBUFFER_UNUSED)
1793 return -EBUSY;
1794
1795 return vgrab(pb, &vm);
1796 }
1797
1798 case VIDIOCGMBUF:
1799 {
1800 int i;
1801 struct video_mbuf vm;
1802
1803 DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
1804
1805 memset(&vm, 0 , sizeof(vm));
1806 vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
1807 vm.frames = MAX_GBUFFERS;
1808 for(i = 0; i<MAX_GBUFFERS; i++)
1809 vm.offsets[i] = PLANB_MAX_FBUF * i;
1810 if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1811 return -EFAULT;
1812 return 0;
1813 }
1814
1815 case PLANBIOCGSAAREGS:
1816 {
1817 struct planb_saa_regs preg;
1818
1819 DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
1820
1821 if(copy_from_user(&preg, arg, sizeof(preg)))
1822 return -EFAULT;
1823 if(preg.addr >= SAA7196_NUMREGS)
1824 return -EINVAL;
1825 preg.val = saa_regs[pb->win.norm][preg.addr];
1826 if(copy_to_user((void *)arg, (void *)&preg,
1827 sizeof(preg)))
1828 return -EFAULT;
1829 return 0;
1830 }
1831
1832 case PLANBIOCSSAAREGS:
1833 {
1834 struct planb_saa_regs preg;
1835
1836 DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
1837
1838 if(copy_from_user(&preg, arg, sizeof(preg)))
1839 return -EFAULT;
1840 if(preg.addr >= SAA7196_NUMREGS)
1841 return -EINVAL;
1842 saa_set (preg.addr, preg.val, pb);
1843 return 0;
1844 }
1845
1846 case PLANBIOCGSTAT:
1847 {
1848 struct planb_stat_regs pstat;
1849
1850 DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
1851
1852 pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
1853 pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
1854 pstat.saa_stat0 = saa_status(0, pb);
1855 pstat.saa_stat1 = saa_status(1, pb);
1856
1857 if(copy_to_user((void *)arg, (void *)&pstat,
1858 sizeof(pstat)))
1859 return -EFAULT;
1860 return 0;
1861 }
1862
1863 case PLANBIOCSMODE: {
1864 int v;
1865
1866 DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
1867
1868 if(copy_from_user(&v, arg, sizeof(v)))
1869 return -EFAULT;
1870
1871 switch(v)
1872 {
1873 case PLANB_TV_MODE:
1874 saa_set (SAA7196_STDC,
1875 (saa_regs[pb->win.norm][SAA7196_STDC] &
1876 0x7f), pb);
1877 break;
1878 case PLANB_VTR_MODE:
1879 saa_set (SAA7196_STDC,
1880 (saa_regs[pb->win.norm][SAA7196_STDC] |
1881 0x80), pb);
1882 break;
1883 default:
1884 return -EINVAL;
1885 break;
1886 }
1887 pb->win.mode = v;
1888 return 0;
1889 }
1890 case PLANBIOCGMODE: {
1891 int v=pb->win.mode;
1892
1893 DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
1894
1895 if(copy_to_user(arg,&v,sizeof(v)))
1896 return -EFAULT;
1897 return 0;
1898 }
1899#ifdef PLANB_GSCANLINE
1900 case PLANBG_GRAB_BPL: {
1901 int v=pb->gbytes_per_line;
1902
1903 DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
1904
1905 if(copy_to_user(arg,&v,sizeof(v)))
1906 return -EFAULT;
1907 return 0;
1908 }
1909#endif /* PLANB_GSCANLINE */
1910 case PLANB_INTR_DEBUG: {
1911 int i;
1912
1913 DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
1914
1915 if(copy_from_user(&i, arg, sizeof(i)))
1916 return -EFAULT;
1917
1918 /* avoid hang ups all together */
1919 for (i = 0; i < MAX_GBUFFERS; i++) {
1920 if(pb->frame_stat[i] == GBUFFER_GRABBING) {
1921 pb->frame_stat[i] = GBUFFER_DONE;
1922 }
1923 }
1924 if(pb->grabbing)
1925 pb->grabbing--;
1926 wake_up_interruptible(&pb->capq);
1927 return 0;
1928 }
1929 case PLANB_INV_REGS: {
1930 int i;
1931 struct planb_any_regs any;
1932
1933 DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
1934
1935 if(copy_from_user(&any, arg, sizeof(any)))
1936 return -EFAULT;
1937 if(any.offset < 0 || any.offset + any.bytes > 0x400)
1938 return -EINVAL;
1939 if(any.bytes > 128)
1940 return -EINVAL;
1941 for (i = 0; i < any.bytes; i++) {
1942 any.data[i] =
1943 in_8((unsigned char *)pb->planb_base
1944 + any.offset + i);
1945 }
1946 if(copy_to_user(arg,&any,sizeof(any)))
1947 return -EFAULT;
1948 return 0;
1949 }
1950 default:
1951 {
1952 DEBUG("PlanB: Unimplemented IOCTL\n");
1953 return -ENOIOCTLCMD;
1954 }
1955 /* Some IOCTLs are currently unsupported on PlanB */
1956 case VIDIOCGTUNER: {
1957 DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
1958 goto unimplemented; }
1959 case VIDIOCSTUNER: {
1960 DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
1961 goto unimplemented; }
1962 case VIDIOCSFREQ: {
1963 DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
1964 goto unimplemented; }
1965 case VIDIOCGFREQ: {
1966 DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
1967 goto unimplemented; }
1968 case VIDIOCKEY: {
1969 DEBUG("PlanB: IOCTL VIDIOCKEY\n");
1970 goto unimplemented; }
1971 case VIDIOCSAUDIO: {
1972 DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
1973 goto unimplemented; }
1974 case VIDIOCGAUDIO: {
1975 DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
1976 goto unimplemented; }
1977unimplemented:
1978 DEBUG(" Unimplemented\n");
1979 return -ENOIOCTLCMD;
1980 }
1981 return 0;
1982}
1983
1984static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size)
1985{
1986 int i;
1987 struct planb *pb = (struct planb *)dev;
1988 unsigned long start = (unsigned long)adr;
1989
1990 if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
1991 return -EINVAL;
1992 if (!pb->rawbuf) {
1993 int err;
1994 if((err=grabbuf_alloc(pb)))
1995 return err;
1996 }
1997 for (i = 0; i < pb->rawbuf_size; i++) {
1998 unsigned long pfn;
1999
2000 pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT;
2001 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
2002 return -EAGAIN;
2003 start += PAGE_SIZE;
2004 if (size <= PAGE_SIZE)
2005 break;
2006 size -= PAGE_SIZE;
2007 }
2008 return 0;
2009}
2010
2011static struct video_device planb_template=
2012{
2013 .owner = THIS_MODULE,
2014 .name = PLANB_DEVICE_NAME,
2015 .type = VID_TYPE_OVERLAY,
2016 .hardware = VID_HARDWARE_PLANB,
2017 .open = planb_open,
2018 .close = planb_close,
2019 .read = planb_read,
2020 .write = planb_write,
2021 .ioctl = planb_ioctl,
2022 .mmap = planb_mmap, /* mmap? */
2023};
2024
2025static int init_planb(struct planb *pb)
2026{
2027 unsigned char saa_rev;
2028 int i, result;
2029
2030 memset ((void *) &pb->win, 0, sizeof (struct planb_window));
2031 /* Simple sanity check */
2032 if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
2033 printk(KERN_ERR "PlanB: Option(s) invalid\n");
2034 return -2;
2035 }
2036 pb->win.norm = def_norm;
2037 pb->win.mode = PLANB_TV_MODE; /* TV mode */
2038 pb->win.interlace=1;
2039 pb->win.x=0;
2040 pb->win.y=0;
2041 pb->win.width=768; /* 640 */
2042 pb->win.height=576; /* 480 */
2043 pb->maxlines=576;
2044#if 0
2045 btv->win.cropwidth=768; /* 640 */
2046 btv->win.cropheight=576; /* 480 */
2047 btv->win.cropx=0;
2048 btv->win.cropy=0;
2049#endif
2050 pb->win.pad=0;
2051 pb->win.bpp=4;
2052 pb->win.depth=32;
2053 pb->win.color_fmt=PLANB_COLOUR32;
2054 pb->win.bpl=1024*pb->win.bpp;
2055 pb->win.swidth=1024;
2056 pb->win.sheight=768;
2057#ifdef PLANB_GSCANLINE
2058 if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
2059 || (pb->gbytes_per_line <= 0))
2060 return -3;
2061 else {
2062 /* page align pb->gbytes_per_line for DMA purpose */
2063 for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
2064 i>>=1;
2065 pb->gbytes_per_line = i;
2066 }
2067#endif
2068 pb->tab_size = PLANB_MAXLINES + 40;
2069 pb->suspend = 0;
2070 init_MUTEX(&pb->lock);
2071 pb->ch1_cmd = 0;
2072 pb->ch2_cmd = 0;
2073 pb->mask = 0;
2074 pb->priv_space = 0;
2075 pb->offset = 0;
2076 pb->user = 0;
2077 pb->overlay = 0;
2078 init_waitqueue_head(&pb->suspendq);
2079 pb->cmd_buff_inited = 0;
2080 pb->frame_buffer_phys = 0;
2081
2082 /* Reset DMA controllers */
2083 planb_dbdma_stop(&pb->planb_base->ch2);
2084 planb_dbdma_stop(&pb->planb_base->ch1);
2085
2086 saa_rev = (saa_status(0, pb) & 0xf0) >> 4;
2087 printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev);
2088 /* Initialize the SAA registers in memory and on chip */
2089 saa_init_regs (pb);
2090
2091 /* clear interrupt mask */
2092 pb->intr_mask = PLANB_CLR_IRQ;
2093
2094 result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
2095 if (result < 0) {
2096 if (result==-EINVAL)
2097 printk(KERN_ERR "PlanB: Bad irq number (%d) "
2098 "or handler\n", (int)pb->irq);
2099 else if (result==-EBUSY)
2100 printk(KERN_ERR "PlanB: I don't know why, "
2101 "but IRQ %d is busy\n", (int)pb->irq);
2102 return result;
2103 }
2104 disable_irq(pb->irq);
2105
2106 /* Now add the template and register the device unit. */
2107 memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
2108
2109 pb->picture.brightness=0x90<<8;
2110 pb->picture.contrast = 0x70 << 8;
2111 pb->picture.colour = 0x70<<8;
2112 pb->picture.hue = 0x8000;
2113 pb->picture.whiteness = 0;
2114 pb->picture.depth = pb->win.depth;
2115
2116 pb->frame_stat=NULL;
2117 init_waitqueue_head(&pb->capq);
2118 for(i=0; i<MAX_GBUFFERS; i++) {
2119 pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
2120 pb->gwidth[i]=0;
2121 pb->gheight[i]=0;
2122 pb->gfmt[i]=0;
2123 pb->cap_cmd[i]=NULL;
2124#ifndef PLANB_GSCANLINE
2125 pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
2126 / PAGE_SIZE + 1) + MAX_LNUM * i;
2127 pb->lsize[i] = 0;
2128 pb->lnum[i] = 0;
2129#endif
2130 }
2131 pb->rawbuf=NULL;
2132 pb->grabbing=0;
2133
2134 /* enable interrupts */
2135 out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
2136 pb->intr_mask = PLANB_FRM_IRQ;
2137 enable_irq(pb->irq);
2138
2139 if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
2140 return -1;
2141
2142 return 0;
2143}
2144
2145/*
2146 * Scan for a PlanB controller, request the irq and map the io memory
2147 */
2148
2149static int find_planb(void)
2150{
2151 struct planb *pb;
2152 struct device_node *planb_devices;
2153 unsigned char dev_fn, confreg, bus;
2154 unsigned int old_base, new_base;
2155 unsigned int irq;
2156 struct pci_dev *pdev;
2157 int rc;
2158
2159 if (_machine != _MACH_Pmac)
2160 return 0;
2161
2162 planb_devices = find_devices("planb");
2163 if (planb_devices == 0) {
2164 planb_num=0;
2165 printk(KERN_WARNING "PlanB: no device found!\n");
2166 return planb_num;
2167 }
2168
2169 if (planb_devices->next != NULL)
2170 printk(KERN_ERR "Warning: only using first PlanB device!\n");
2171 pb = &planbs[0];
2172 planb_num = 1;
2173
2174 if (planb_devices->n_addrs != 1) {
2175 printk (KERN_WARNING "PlanB: expecting 1 address for planb "
2176 "(got %d)", planb_devices->n_addrs);
2177 return 0;
2178 }
2179
2180 if (planb_devices->n_intrs == 0) {
2181 printk(KERN_WARNING "PlanB: no intrs for device %s\n",
2182 planb_devices->full_name);
2183 return 0;
2184 } else {
2185 irq = planb_devices->intrs[0].line;
2186 }
2187
2188 /* Initialize PlanB's PCI registers */
2189
2190 /* There is a bug with the way OF assigns addresses
2191 to the devices behind the chaos bridge.
2192 control needs only 0x1000 of space, but decodes only
2193 the upper 16 bits. It therefore occupies a full 64K.
2194 OF assigns the planb controller memory within this space;
2195 so we need to change that here in order to access planb. */
2196
2197 /* We remap to 0xf1000000 in hope that nobody uses it ! */
2198
2199 bus = (planb_devices->addrs[0].space >> 16) & 0xff;
2200 dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
2201 confreg = planb_devices->addrs[0].space & 0xff;
2202 old_base = planb_devices->addrs[0].address;
2203 new_base = 0xf1000000;
2204
2205 DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
2206 "membase 0x%x (base reg. 0x%x)\n",
2207 bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
2208
2209 pdev = pci_find_slot (bus, dev_fn);
2210 if (!pdev) {
2211 printk(KERN_ERR "planb: cannot find slot\n");
2212 goto err_out;
2213 }
2214
2215 /* Enable response in memory space, bus mastering,
2216 use memory write and invalidate */
2217 rc = pci_enable_device(pdev);
2218 if (rc) {
2219 printk(KERN_ERR "planb: cannot enable PCI device %s\n",
2220 pci_name(pdev));
2221 goto err_out;
2222 }
2223 rc = pci_set_mwi(pdev);
2224 if (rc) {
2225 printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n",
2226 pci_name(pdev));
2227 goto err_out_disable;
2228 }
2229 pci_set_master(pdev);
2230
2231 /* Set the new base address */
2232 pci_write_config_dword (pdev, confreg, new_base);
2233
2234 planb_regs = (volatile struct planb_registers *)
2235 ioremap (new_base, 0x400);
2236 pb->planb_base = planb_regs;
2237 pb->planb_base_phys = (struct planb_registers *)new_base;
2238 pb->irq = irq;
2239
2240 return planb_num;
2241
2242err_out_disable:
2243 pci_disable_device(pdev);
2244err_out:
2245 /* FIXME handle error */ /* comment moved from pci_find_slot, above */
2246 return 0;
2247}
2248
2249static void release_planb(void)
2250{
2251 int i;
2252 struct planb *pb;
2253
2254 for (i=0;i<planb_num; i++)
2255 {
2256 pb=&planbs[i];
2257
2258 /* stop and flash DMAs unconditionally */
2259 planb_dbdma_stop(&pb->planb_base->ch2);
2260 planb_dbdma_stop(&pb->planb_base->ch1);
2261
2262 /* clear and free interrupts */
2263 pb->intr_mask = PLANB_CLR_IRQ;
2264 out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
2265 free_irq(pb->irq, pb);
2266
2267 /* make sure all allocated memory are freed */
2268 planb_prepare_close(pb);
2269
2270 printk(KERN_INFO "PlanB: unregistering with v4l\n");
2271 video_unregister_device(&pb->video_dev);
2272
2273 /* note that iounmap() does nothing on the PPC right now */
2274 iounmap ((void *)pb->planb_base);
2275 }
2276}
2277
2278static int __init init_planbs(void)
2279{
2280 int i;
2281
2282 if (find_planb()<=0)
2283 return -EIO;
2284
2285 for (i=0; i<planb_num; i++) {
2286 if (init_planb(&planbs[i])<0) {
2287 printk(KERN_ERR "PlanB: error registering device %d"
2288 " with v4l\n", i);
2289 release_planb();
2290 return -EIO;
2291 }
2292 printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
2293 }
2294 return 0;
2295}
2296
2297static void __exit exit_planbs(void)
2298{
2299 release_planb();
2300}
2301
2302module_init(init_planbs);
2303module_exit(exit_planbs);
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h
new file mode 100644
index 000000000000..8a0faad16118
--- /dev/null
+++ b/drivers/media/video/planb.h
@@ -0,0 +1,231 @@
1/*
2 planb - PlanB frame grabber driver
3
4 PlanB is used in the 7x00/8x00 series of PowerMacintosh
5 Computers as video input DMA controller.
6
7 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
8
9 Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
10
11 Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
12
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27*/
28
29/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
30
31#ifndef _PLANB_H_
32#define _PLANB_H_
33
34#ifdef __KERNEL__
35#include <asm/dbdma.h>
36#include "saa7196.h"
37#endif /* __KERNEL__ */
38
39#define PLANB_DEVICE_NAME "Apple PlanB Video-In"
40#define PLANB_REV "1.0"
41
42#ifdef __KERNEL__
43//#define PLANB_GSCANLINE /* use this if apps have the notion of */
44 /* grab buffer scanline */
45/* This should be safe for both PAL and NTSC */
46#define PLANB_MAXPIXELS 768
47#define PLANB_MAXLINES 576
48#define PLANB_NTSC_MAXLINES 480
49
50/* Uncomment your preferred norm ;-) */
51#define PLANB_DEF_NORM VIDEO_MODE_PAL
52//#define PLANB_DEF_NORM VIDEO_MODE_NTSC
53//#define PLANB_DEF_NORM VIDEO_MODE_SECAM
54
55/* fields settings */
56#define PLANB_GRAY 0x1 /* 8-bit mono? */
57#define PLANB_COLOUR15 0x2 /* 16-bit mode */
58#define PLANB_COLOUR32 0x4 /* 32-bit mode */
59#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */
60
61/* misc. flags for PlanB DMA operation */
62#define CH_SYNC 0x1 /* synchronize channels (set by ch1;
63 cleared by ch2) */
64#define FIELD_SYNC 0x2 /* used for the start of each field
65 (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */
66#define EVEN_FIELD 0x0 /* even field is detected if unset */
67#define DMA_ABORT 0x2 /* error or just out of sync if set */
68#define ODD_FIELD 0x4 /* odd field is detected if set */
69
70/* for capture operations */
71#define MAX_GBUFFERS 2
72/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
73#ifdef PLANB_GSCANLINE
74#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */
75#define TAB_FACTOR (1)
76#else
77#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */
78#define TAB_FACTOR (2)
79#endif
80#endif /* __KERNEL__ */
81
82struct planb_saa_regs {
83 unsigned char addr;
84 unsigned char val;
85};
86
87struct planb_stat_regs {
88 unsigned int ch1_stat;
89 unsigned int ch2_stat;
90 unsigned char saa_stat0;
91 unsigned char saa_stat1;
92};
93
94struct planb_any_regs {
95 unsigned int offset;
96 unsigned int bytes;
97 unsigned char data[128];
98};
99
100/* planb private ioctls */
101#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */
102#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */
103#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */
104#define PLANB_TV_MODE 1
105#define PLANB_VTR_MODE 2
106#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */
107#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */
108
109#ifdef PLANB_GSCANLINE
110#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */
111#endif
112
113/* call wake_up_interruptible() with appropriate actions */
114#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int)
115/* investigate which reg does what */
116#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
117
118#ifdef __KERNEL__
119
120/* Potentially useful macros */
121#define PLANB_SET(x) ((x) << 16 | (x))
122#define PLANB_CLR(x) ((x) << 16)
123
124/* This represents the physical register layout */
125struct planb_registers {
126 volatile struct dbdma_regs ch1; /* 0x00: video in */
127 volatile unsigned int even; /* 0x40: even field setting */
128 volatile unsigned int odd; /* 0x44; odd field setting */
129 unsigned int pad1[14]; /* empty? */
130 volatile struct dbdma_regs ch2; /* 0x80: clipmask out */
131 unsigned int pad2[16]; /* 0xc0: empty? */
132 volatile unsigned int reg3; /* 0x100: ???? */
133 volatile unsigned int intr_stat; /* 0x104: irq status */
134#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */
135#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */
136#define PLANB_FRM_IRQ 0x0100 /* end of frame */
137 unsigned int pad3[1]; /* empty? */
138 volatile unsigned int reg5; /* 0x10c: ??? */
139 unsigned int pad4[60]; /* empty? */
140 volatile unsigned char saa_addr; /* 0x200: SAA subadr */
141 char pad5[3];
142 volatile unsigned char saa_regval; /* SAA7196 write reg. val */
143 char pad6[3];
144 volatile unsigned char saa_status; /* SAA7196 status byte */
145 /* There is more unused stuff here */
146};
147
148struct planb_window {
149 int x, y;
150 ushort width, height;
151 ushort bpp, bpl, depth, pad;
152 ushort swidth, sheight;
153 int norm;
154 int interlace;
155 u32 color_fmt;
156 int chromakey;
157 int mode; /* used to switch between TV/VTR modes */
158};
159
160struct planb_suspend {
161 int overlay;
162 int frame;
163 struct dbdma_cmd cmd;
164};
165
166struct planb {
167 struct video_device video_dev;
168 struct video_picture picture; /* Current picture params */
169 struct video_audio audio_dev; /* Current audio params */
170
171 volatile struct planb_registers *planb_base; /* virt base of planb */
172 struct planb_registers *planb_base_phys; /* phys base of planb */
173 void *priv_space; /* Org. alloc. mem for kfree */
174 int user;
175 unsigned int tab_size;
176 int maxlines;
177 struct semaphore lock;
178 unsigned int irq; /* interrupt number */
179 volatile unsigned int intr_mask;
180
181 int overlay; /* overlay running? */
182 struct planb_window win;
183 unsigned long frame_buffer_phys; /* We need phys for DMA */
184 int offset; /* offset of pixel 1 */
185 volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */
186 volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */
187 volatile struct dbdma_cmd *overlay_last1;
188 volatile struct dbdma_cmd *overlay_last2;
189 unsigned long ch1_cmd_phys;
190 volatile unsigned char *mask; /* Clipmask buffer */
191 int suspend;
192 wait_queue_head_t suspendq;
193 struct planb_suspend suspended;
194 int cmd_buff_inited; /* cmd buffer inited? */
195
196 int grabbing;
197 unsigned int gcount;
198 wait_queue_head_t capq;
199 int last_fr;
200 int prev_last_fr;
201 unsigned char **rawbuf;
202 int rawbuf_size;
203 int gbuf_idx[MAX_GBUFFERS];
204 volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
205 volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
206 volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
207 int need_pre_capture[MAX_GBUFFERS];
208#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */
209 int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
210 unsigned int gfmt[MAX_GBUFFERS];
211 int gnorm_switch[MAX_GBUFFERS];
212 volatile unsigned int *frame_stat;
213#define GBUFFER_UNUSED 0x00U
214#define GBUFFER_GRABBING 0x01U
215#define GBUFFER_DONE 0x02U
216#ifdef PLANB_GSCANLINE
217 int gbytes_per_line;
218#else
219#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */
220 /* PLANB_MAXPIXELS changes */
221 int l_fr_addr_idx[MAX_GBUFFERS];
222 unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
223 int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
224 int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
225 int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
226#endif
227};
228
229#endif /* __KERNEL__ */
230
231#endif /* _PLANB_H_ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
new file mode 100644
index 000000000000..2504207b2e3d
--- /dev/null
+++ b/drivers/media/video/pms.c
@@ -0,0 +1,1060 @@
1/*
2 * Media Vision Pro Movie Studio
3 * or
4 * "all you need is an I2C bus some RAM and a prayer"
5 *
6 * This draws heavily on code
7 *
8 * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
9 * Kiefernring 15
10 * 14478 Potsdam, Germany
11 *
12 * Most of this code is directly derived from his userspace driver.
13 * His driver works so send any reports to alan@redhat.com unless the
14 * userspace driver also doesn't work for you...
15 *
16 * Changes:
17 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
18 * - pms_capture: report back -EFAULT
19 */
20
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/fs.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/mm.h>
28#include <linux/ioport.h>
29#include <linux/init.h>
30#include <asm/io.h>
31#include <linux/sched.h>
32#include <linux/videodev.h>
33#include <asm/uaccess.h>
34
35
36#define MOTOROLA 1
37#define PHILIPS2 2
38#define PHILIPS1 3
39#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
40
41struct pms_device
42{
43 struct video_device v;
44 struct video_picture picture;
45 int height;
46 int width;
47 struct semaphore lock;
48};
49
50struct i2c_info
51{
52 u8 slave;
53 u8 sub;
54 u8 data;
55 u8 hits;
56};
57
58static int i2c_count = 0;
59static struct i2c_info i2cinfo[64];
60
61static int decoder = PHILIPS2;
62static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
63
64/*
65 * I/O ports and Shared Memory
66 */
67
68static int io_port = 0x250;
69static int data_port = 0x251;
70static int mem_base = 0xC8000;
71static void __iomem *mem;
72static int video_nr = -1;
73
74
75
76static inline void mvv_write(u8 index, u8 value)
77{
78 outw(index|(value<<8), io_port);
79}
80
81static inline u8 mvv_read(u8 index)
82{
83 outb(index, io_port);
84 return inb(data_port);
85}
86
87static int pms_i2c_stat(u8 slave)
88{
89 int counter;
90 int i;
91
92 outb(0x28, io_port);
93
94 counter=0;
95 while((inb(data_port)&0x01)==0)
96 if(counter++==256)
97 break;
98
99 while((inb(data_port)&0x01)!=0)
100 if(counter++==256)
101 break;
102
103 outb(slave, io_port);
104
105 counter=0;
106 while((inb(data_port)&0x01)==0)
107 if(counter++==256)
108 break;
109
110 while((inb(data_port)&0x01)!=0)
111 if(counter++==256)
112 break;
113
114 for(i=0;i<12;i++)
115 {
116 char st=inb(data_port);
117 if((st&2)!=0)
118 return -1;
119 if((st&1)==0)
120 break;
121 }
122 outb(0x29, io_port);
123 return inb(data_port);
124}
125
126static int pms_i2c_write(u16 slave, u16 sub, u16 data)
127{
128 int skip=0;
129 int count;
130 int i;
131
132 for(i=0;i<i2c_count;i++)
133 {
134 if((i2cinfo[i].slave==slave) &&
135 (i2cinfo[i].sub == sub))
136 {
137 if(i2cinfo[i].data==data)
138 skip=1;
139 i2cinfo[i].data=data;
140 i=i2c_count+1;
141 }
142 }
143
144 if(i==i2c_count && i2c_count<64)
145 {
146 i2cinfo[i2c_count].slave=slave;
147 i2cinfo[i2c_count].sub=sub;
148 i2cinfo[i2c_count].data=data;
149 i2c_count++;
150 }
151
152 if(skip)
153 return 0;
154
155 mvv_write(0x29, sub);
156 mvv_write(0x2A, data);
157 mvv_write(0x28, slave);
158
159 outb(0x28, io_port);
160
161 count=0;
162 while((inb(data_port)&1)==0)
163 if(count>255)
164 break;
165 while((inb(data_port)&1)!=0)
166 if(count>255)
167 break;
168
169 count=inb(data_port);
170
171 if(count&2)
172 return -1;
173 return count;
174}
175
176static int pms_i2c_read(int slave, int sub)
177{
178 int i=0;
179 for(i=0;i<i2c_count;i++)
180 {
181 if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
182 return i2cinfo[i].data;
183 }
184 return 0;
185}
186
187
188static void pms_i2c_andor(int slave, int sub, int and, int or)
189{
190 u8 tmp;
191
192 tmp=pms_i2c_read(slave, sub);
193 tmp = (tmp&and)|or;
194 pms_i2c_write(slave, sub, tmp);
195}
196
197/*
198 * Control functions
199 */
200
201
202static void pms_videosource(short source)
203{
204 mvv_write(0x2E, source?0x31:0x30);
205}
206
207static void pms_hue(short hue)
208{
209 switch(decoder)
210 {
211 case MOTOROLA:
212 pms_i2c_write(0x8A, 0x00, hue);
213 break;
214 case PHILIPS2:
215 pms_i2c_write(0x8A, 0x07, hue);
216 break;
217 case PHILIPS1:
218 pms_i2c_write(0x42, 0x07, hue);
219 break;
220 }
221}
222
223static void pms_colour(short colour)
224{
225 switch(decoder)
226 {
227 case MOTOROLA:
228 pms_i2c_write(0x8A, 0x00, colour);
229 break;
230 case PHILIPS1:
231 pms_i2c_write(0x42, 0x12, colour);
232 break;
233 }
234}
235
236
237static void pms_contrast(short contrast)
238{
239 switch(decoder)
240 {
241 case MOTOROLA:
242 pms_i2c_write(0x8A, 0x00, contrast);
243 break;
244 case PHILIPS1:
245 pms_i2c_write(0x42, 0x13, contrast);
246 break;
247 }
248}
249
250static void pms_brightness(short brightness)
251{
252 switch(decoder)
253 {
254 case MOTOROLA:
255 pms_i2c_write(0x8A, 0x00, brightness);
256 pms_i2c_write(0x8A, 0x00, brightness);
257 pms_i2c_write(0x8A, 0x00, brightness);
258 break;
259 case PHILIPS1:
260 pms_i2c_write(0x42, 0x19, brightness);
261 break;
262 }
263}
264
265
266static void pms_format(short format)
267{
268 int target;
269 standard = format;
270
271 if(decoder==PHILIPS1)
272 target=0x42;
273 else if(decoder==PHILIPS2)
274 target=0x8A;
275 else
276 return;
277
278 switch(format)
279 {
280 case 0: /* Auto */
281 pms_i2c_andor(target, 0x0D, 0xFE,0x00);
282 pms_i2c_andor(target, 0x0F, 0x3F,0x80);
283 break;
284 case 1: /* NTSC */
285 pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
286 pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
287 break;
288 case 2: /* PAL */
289 pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
290 pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
291 break;
292 case 3: /* SECAM */
293 pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
294 pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
295 break;
296 }
297}
298
299#ifdef FOR_FUTURE_EXPANSION
300
301/*
302 * These features of the PMS card are not currently exposes. They
303 * could become a private v4l ioctl for PMSCONFIG or somesuch if
304 * people need it. We also don't yet use the PMS interrupt.
305 */
306
307static void pms_hstart(short start)
308{
309 switch(decoder)
310 {
311 case PHILIPS1:
312 pms_i2c_write(0x8A, 0x05, start);
313 pms_i2c_write(0x8A, 0x18, start);
314 break;
315 case PHILIPS2:
316 pms_i2c_write(0x42, 0x05, start);
317 pms_i2c_write(0x42, 0x18, start);
318 break;
319 }
320}
321
322/*
323 * Bandpass filters
324 */
325
326static void pms_bandpass(short pass)
327{
328 if(decoder==PHILIPS2)
329 pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
330 else if(decoder==PHILIPS1)
331 pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
332}
333
334static void pms_antisnow(short snow)
335{
336 if(decoder==PHILIPS2)
337 pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
338 else if(decoder==PHILIPS1)
339 pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
340}
341
342static void pms_sharpness(short sharp)
343{
344 if(decoder==PHILIPS2)
345 pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
346 else if(decoder==PHILIPS1)
347 pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
348}
349
350static void pms_chromaagc(short agc)
351{
352 if(decoder==PHILIPS2)
353 pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
354 else if(decoder==PHILIPS1)
355 pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
356}
357
358static void pms_vertnoise(short noise)
359{
360 if(decoder==PHILIPS2)
361 pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
362 else if(decoder==PHILIPS1)
363 pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
364}
365
366static void pms_forcecolour(short colour)
367{
368 if(decoder==PHILIPS2)
369 pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
370 else if(decoder==PHILIPS1)
371 pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
372}
373
374static void pms_antigamma(short gamma)
375{
376 if(decoder==PHILIPS2)
377 pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
378 else if(decoder==PHILIPS1)
379 pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
380}
381
382static void pms_prefilter(short filter)
383{
384 if(decoder==PHILIPS2)
385 pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
386 else if(decoder==PHILIPS1)
387 pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
388}
389
390static void pms_hfilter(short filter)
391{
392 if(decoder==PHILIPS2)
393 pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
394 else if(decoder==PHILIPS1)
395 pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
396}
397
398static void pms_vfilter(short filter)
399{
400 if(decoder==PHILIPS2)
401 pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
402 else if(decoder==PHILIPS1)
403 pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
404}
405
406static void pms_killcolour(short colour)
407{
408 if(decoder==PHILIPS2)
409 {
410 pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
411 pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
412 }
413 else if(decoder==PHILIPS1)
414 {
415 pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
416 pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
417 }
418}
419
420static void pms_chromagain(short chroma)
421{
422 if(decoder==PHILIPS2)
423 {
424 pms_i2c_write(0x8A, 0x11, chroma);
425 }
426 else if(decoder==PHILIPS1)
427 {
428 pms_i2c_write(0x42, 0x11, chroma);
429 }
430}
431
432
433static void pms_spacialcompl(short data)
434{
435 mvv_write(0x3B, data);
436}
437
438static void pms_spacialcomph(short data)
439{
440 mvv_write(0x3A, data);
441}
442
443static void pms_vstart(short start)
444{
445 mvv_write(0x16, start);
446 mvv_write(0x17, (start>>8)&0x01);
447}
448
449#endif
450
451static void pms_secamcross(short cross)
452{
453 if(decoder==PHILIPS2)
454 pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
455 else if(decoder==PHILIPS1)
456 pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
457}
458
459
460static void pms_swsense(short sense)
461{
462 if(decoder==PHILIPS2)
463 {
464 pms_i2c_write(0x8A, 0x0A, sense);
465 pms_i2c_write(0x8A, 0x0B, sense);
466 }
467 else if(decoder==PHILIPS1)
468 {
469 pms_i2c_write(0x42, 0x0A, sense);
470 pms_i2c_write(0x42, 0x0B, sense);
471 }
472}
473
474
475static void pms_framerate(short frr)
476{
477 int fps=(standard==1)?30:25;
478 if(frr==0)
479 return;
480 fps=fps/frr;
481 mvv_write(0x14,0x80|fps);
482 mvv_write(0x15,1);
483}
484
485static void pms_vert(u8 deciden, u8 decinum)
486{
487 mvv_write(0x1C, deciden); /* Denominator */
488 mvv_write(0x1D, decinum); /* Numerator */
489}
490
491/*
492 * Turn 16bit ratios into best small ratio the chipset can grok
493 */
494
495static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
496{
497 /* Knock it down by /5 once */
498 if(decinum%5==0)
499 {
500 deciden/=5;
501 decinum/=5;
502 }
503 /*
504 * 3's
505 */
506 while(decinum%3==0 && deciden%3==0)
507 {
508 deciden/=3;
509 decinum/=3;
510 }
511 /*
512 * 2's
513 */
514 while(decinum%2==0 && deciden%2==0)
515 {
516 decinum/=2;
517 deciden/=2;
518 }
519 /*
520 * Fudgyify
521 */
522 while(deciden>32)
523 {
524 deciden/=2;
525 decinum=(decinum+1)/2;
526 }
527 if(deciden==32)
528 deciden--;
529 pms_vert(deciden,decinum);
530}
531
532static void pms_horzdeci(short decinum, short deciden)
533{
534 if(decinum<=512)
535 {
536 if(decinum%5==0)
537 {
538 decinum/=5;
539 deciden/=5;
540 }
541 }
542 else
543 {
544 decinum=512;
545 deciden=640; /* 768 would be ideal */
546 }
547
548 while(((decinum|deciden)&1)==0)
549 {
550 decinum>>=1;
551 deciden>>=1;
552 }
553 while(deciden>32)
554 {
555 deciden>>=1;
556 decinum=(decinum+1)>>1;
557 }
558 if(deciden==32)
559 deciden--;
560
561 mvv_write(0x24, 0x80|deciden);
562 mvv_write(0x25, decinum);
563}
564
565static void pms_resolution(short width, short height)
566{
567 int fg_height;
568
569 fg_height=height;
570 if(fg_height>280)
571 fg_height=280;
572
573 mvv_write(0x18, fg_height);
574 mvv_write(0x19, fg_height>>8);
575
576 if(standard==1)
577 {
578 mvv_write(0x1A, 0xFC);
579 mvv_write(0x1B, 0x00);
580 if(height>fg_height)
581 pms_vertdeci(240,240);
582 else
583 pms_vertdeci(fg_height,240);
584 }
585 else
586 {
587 mvv_write(0x1A, 0x1A);
588 mvv_write(0x1B, 0x01);
589 if(fg_height>256)
590 pms_vertdeci(270,270);
591 else
592 pms_vertdeci(fg_height, 270);
593 }
594 mvv_write(0x12,0);
595 mvv_write(0x13, MVVMEMORYWIDTH);
596 mvv_write(0x42, 0x00);
597 mvv_write(0x43, 0x00);
598 mvv_write(0x44, MVVMEMORYWIDTH);
599
600 mvv_write(0x22, width+8);
601 mvv_write(0x23, (width+8)>> 8);
602
603 if(standard==1)
604 pms_horzdeci(width,640);
605 else
606 pms_horzdeci(width+8, 768);
607
608 mvv_write(0x30, mvv_read(0x30)&0xFE);
609 mvv_write(0x08, mvv_read(0x08)|0x01);
610 mvv_write(0x01, mvv_read(0x01)&0xFD);
611 mvv_write(0x32, 0x00);
612 mvv_write(0x33, MVVMEMORYWIDTH);
613}
614
615
616/*
617 * Set Input
618 */
619
620static void pms_vcrinput(short input)
621{
622 if(decoder==PHILIPS2)
623 pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
624 else if(decoder==PHILIPS1)
625 pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
626}
627
628
629static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count)
630{
631 int y;
632 int dw = 2*dev->width;
633
634 char tmp[dw+32]; /* using a temp buffer is faster than direct */
635 int cnt = 0;
636 int len=0;
637 unsigned char r8 = 0x5; /* value for reg8 */
638
639 if (rgb555)
640 r8 |= 0x20; /* else use untranslated rgb = 565 */
641 mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
642
643/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
644
645 for (y = 0; y < dev->height; y++ )
646 {
647 writeb(0, mem); /* synchronisiert neue Zeile */
648
649 /*
650 * This is in truth a fifo, be very careful as if you
651 * forgot this odd things will occur 8)
652 */
653
654 memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */
655 cnt -= dev->height;
656 while (cnt <= 0)
657 {
658 /*
659 * Don't copy too far
660 */
661 int dt=dw;
662 if(dt+len>count)
663 dt=count-len;
664 cnt += dev->height;
665 if (copy_to_user(buf, tmp+32, dt))
666 return len ? len : -EFAULT;
667 buf += dt;
668 len += dt;
669 }
670 }
671 return len;
672}
673
674
675/*
676 * Video4linux interfacing
677 */
678
679static int pms_do_ioctl(struct inode *inode, struct file *file,
680 unsigned int cmd, void *arg)
681{
682 struct video_device *dev = video_devdata(file);
683 struct pms_device *pd=(struct pms_device *)dev;
684
685 switch(cmd)
686 {
687 case VIDIOCGCAP:
688 {
689 struct video_capability *b = arg;
690 strcpy(b->name, "Mediavision PMS");
691 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
692 b->channels = 4;
693 b->audios = 0;
694 b->maxwidth = 640;
695 b->maxheight = 480;
696 b->minwidth = 16;
697 b->minheight = 16;
698 return 0;
699 }
700 case VIDIOCGCHAN:
701 {
702 struct video_channel *v = arg;
703 if(v->channel<0 || v->channel>3)
704 return -EINVAL;
705 v->flags=0;
706 v->tuners=1;
707 /* Good question.. its composite or SVHS so.. */
708 v->type = VIDEO_TYPE_CAMERA;
709 switch(v->channel)
710 {
711 case 0:
712 strcpy(v->name, "Composite");break;
713 case 1:
714 strcpy(v->name, "SVideo");break;
715 case 2:
716 strcpy(v->name, "Composite(VCR)");break;
717 case 3:
718 strcpy(v->name, "SVideo(VCR)");break;
719 }
720 return 0;
721 }
722 case VIDIOCSCHAN:
723 {
724 struct video_channel *v = arg;
725 if(v->channel<0 || v->channel>3)
726 return -EINVAL;
727 down(&pd->lock);
728 pms_videosource(v->channel&1);
729 pms_vcrinput(v->channel>>1);
730 up(&pd->lock);
731 return 0;
732 }
733 case VIDIOCGTUNER:
734 {
735 struct video_tuner *v = arg;
736 if(v->tuner)
737 return -EINVAL;
738 strcpy(v->name, "Format");
739 v->rangelow=0;
740 v->rangehigh=0;
741 v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
742 switch(standard)
743 {
744 case 0:
745 v->mode = VIDEO_MODE_AUTO;
746 break;
747 case 1:
748 v->mode = VIDEO_MODE_NTSC;
749 break;
750 case 2:
751 v->mode = VIDEO_MODE_PAL;
752 break;
753 case 3:
754 v->mode = VIDEO_MODE_SECAM;
755 break;
756 }
757 return 0;
758 }
759 case VIDIOCSTUNER:
760 {
761 struct video_tuner *v = arg;
762 if(v->tuner)
763 return -EINVAL;
764 down(&pd->lock);
765 switch(v->mode)
766 {
767 case VIDEO_MODE_AUTO:
768 pms_framerate(25);
769 pms_secamcross(0);
770 pms_format(0);
771 break;
772 case VIDEO_MODE_NTSC:
773 pms_framerate(30);
774 pms_secamcross(0);
775 pms_format(1);
776 break;
777 case VIDEO_MODE_PAL:
778 pms_framerate(25);
779 pms_secamcross(0);
780 pms_format(2);
781 break;
782 case VIDEO_MODE_SECAM:
783 pms_framerate(25);
784 pms_secamcross(1);
785 pms_format(2);
786 break;
787 default:
788 up(&pd->lock);
789 return -EINVAL;
790 }
791 up(&pd->lock);
792 return 0;
793 }
794 case VIDIOCGPICT:
795 {
796 struct video_picture *p = arg;
797 *p = pd->picture;
798 return 0;
799 }
800 case VIDIOCSPICT:
801 {
802 struct video_picture *p = arg;
803 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
804 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
805 return -EINVAL;
806 pd->picture= *p;
807
808 /*
809 * Now load the card.
810 */
811
812 down(&pd->lock);
813 pms_brightness(p->brightness>>8);
814 pms_hue(p->hue>>8);
815 pms_colour(p->colour>>8);
816 pms_contrast(p->contrast>>8);
817 up(&pd->lock);
818 return 0;
819 }
820 case VIDIOCSWIN:
821 {
822 struct video_window *vw = arg;
823 if(vw->flags)
824 return -EINVAL;
825 if(vw->clipcount)
826 return -EINVAL;
827 if(vw->height<16||vw->height>480)
828 return -EINVAL;
829 if(vw->width<16||vw->width>640)
830 return -EINVAL;
831 pd->width=vw->width;
832 pd->height=vw->height;
833 down(&pd->lock);
834 pms_resolution(pd->width, pd->height);
835 up(&pd->lock); /* Ok we figured out what to use from our wide choice */
836 return 0;
837 }
838 case VIDIOCGWIN:
839 {
840 struct video_window *vw = arg;
841 memset(vw,0,sizeof(*vw));
842 vw->width=pd->width;
843 vw->height=pd->height;
844 return 0;
845 }
846 case VIDIOCKEY:
847 return 0;
848 case VIDIOCCAPTURE:
849 case VIDIOCGFBUF:
850 case VIDIOCSFBUF:
851 case VIDIOCGFREQ:
852 case VIDIOCSFREQ:
853 case VIDIOCGAUDIO:
854 case VIDIOCSAUDIO:
855 return -EINVAL;
856 default:
857 return -ENOIOCTLCMD;
858 }
859 return 0;
860}
861
862static int pms_ioctl(struct inode *inode, struct file *file,
863 unsigned int cmd, unsigned long arg)
864{
865 return video_usercopy(inode, file, cmd, arg, pms_do_ioctl);
866}
867
868static ssize_t pms_read(struct file *file, char __user *buf,
869 size_t count, loff_t *ppos)
870{
871 struct video_device *v = video_devdata(file);
872 struct pms_device *pd=(struct pms_device *)v;
873 int len;
874
875 down(&pd->lock);
876 len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
877 up(&pd->lock);
878 return len;
879}
880
881static struct file_operations pms_fops = {
882 .owner = THIS_MODULE,
883 .open = video_exclusive_open,
884 .release = video_exclusive_release,
885 .ioctl = pms_ioctl,
886 .read = pms_read,
887 .llseek = no_llseek,
888};
889
890static struct video_device pms_template=
891{
892 .owner = THIS_MODULE,
893 .name = "Mediavision PMS",
894 .type = VID_TYPE_CAPTURE,
895 .hardware = VID_HARDWARE_PMS,
896 .fops = &pms_fops,
897};
898
899static struct pms_device pms_device;
900
901
902/*
903 * Probe for and initialise the Mediavision PMS
904 */
905
906static int init_mediavision(void)
907{
908 int id;
909 int idec, decst;
910 int i;
911
912 unsigned char i2c_defs[]={
913 0x4C,0x30,0x00,0xE8,
914 0xB6,0xE2,0x00,0x00,
915 0xFF,0xFF,0x00,0x00,
916 0x00,0x00,0x78,0x98,
917 0x00,0x00,0x00,0x00,
918 0x34,0x0A,0xF4,0xCE,
919 0xE4
920 };
921
922 mem = ioremap(mem_base, 0x800);
923 if (!mem)
924 return -ENOMEM;
925
926 if (!request_region(0x9A01, 1, "Mediavision PMS config"))
927 {
928 printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
929 iounmap(mem);
930 return -EBUSY;
931 }
932 if (!request_region(io_port, 3, "Mediavision PMS"))
933 {
934 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
935 release_region(0x9A01, 1);
936 iounmap(mem);
937 return -EBUSY;
938 }
939 outb(0xB8, 0x9A01); /* Unlock */
940 outb(io_port>>4, 0x9A01); /* Set IO port */
941
942
943 id=mvv_read(3);
944 decst=pms_i2c_stat(0x43);
945
946 if(decst!=-1)
947 idec=2;
948 else if(pms_i2c_stat(0xb9)!=-1)
949 idec=3;
950 else if(pms_i2c_stat(0x8b)!=-1)
951 idec=1;
952 else
953 idec=0;
954
955 printk(KERN_INFO "PMS type is %d\n", idec);
956 if(idec == 0) {
957 release_region(io_port, 3);
958 release_region(0x9A01, 1);
959 iounmap(mem);
960 return -ENODEV;
961 }
962
963 /*
964 * Ok we have a PMS of some sort
965 */
966
967 mvv_write(0x04, mem_base>>12); /* Set the memory area */
968
969 /* Ok now load the defaults */
970
971 for(i=0;i<0x19;i++)
972 {
973 if(i2c_defs[i]==0xFF)
974 pms_i2c_andor(0x8A, i, 0x07,0x00);
975 else
976 pms_i2c_write(0x8A, i, i2c_defs[i]);
977 }
978
979 pms_i2c_write(0xB8,0x00,0x12);
980 pms_i2c_write(0xB8,0x04,0x00);
981 pms_i2c_write(0xB8,0x07,0x00);
982 pms_i2c_write(0xB8,0x08,0x00);
983 pms_i2c_write(0xB8,0x09,0xFF);
984 pms_i2c_write(0xB8,0x0A,0x00);
985 pms_i2c_write(0xB8,0x0B,0x10);
986 pms_i2c_write(0xB8,0x10,0x03);
987
988 mvv_write(0x01, 0x00);
989 mvv_write(0x05, 0xA0);
990 mvv_write(0x08, 0x25);
991 mvv_write(0x09, 0x00);
992 mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
993
994 mvv_write(0x10, 0x02);
995 mvv_write(0x1E, 0x0C);
996 mvv_write(0x1F, 0x03);
997 mvv_write(0x26, 0x06);
998
999 mvv_write(0x2B, 0x00);
1000 mvv_write(0x2C, 0x20);
1001 mvv_write(0x2D, 0x00);
1002 mvv_write(0x2F, 0x70);
1003 mvv_write(0x32, 0x00);
1004 mvv_write(0x33, MVVMEMORYWIDTH);
1005 mvv_write(0x34, 0x00);
1006 mvv_write(0x35, 0x00);
1007 mvv_write(0x3A, 0x80);
1008 mvv_write(0x3B, 0x10);
1009 mvv_write(0x20, 0x00);
1010 mvv_write(0x21, 0x00);
1011 mvv_write(0x30, 0x22);
1012 return 0;
1013}
1014
1015/*
1016 * Initialization and module stuff
1017 */
1018
1019static int __init init_pms_cards(void)
1020{
1021 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
1022
1023 data_port = io_port +1;
1024
1025 if(init_mediavision())
1026 {
1027 printk(KERN_INFO "Board not found.\n");
1028 return -ENODEV;
1029 }
1030 memcpy(&pms_device, &pms_template, sizeof(pms_template));
1031 init_MUTEX(&pms_device.lock);
1032 pms_device.height=240;
1033 pms_device.width=320;
1034 pms_swsense(75);
1035 pms_resolution(320,240);
1036 return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
1037}
1038
1039module_param(io_port, int, 0);
1040module_param(mem_base, int, 0);
1041module_param(video_nr, int, 0);
1042MODULE_LICENSE("GPL");
1043
1044
1045static void __exit shutdown_mediavision(void)
1046{
1047 release_region(io_port,3);
1048 release_region(0x9A01, 1);
1049}
1050
1051static void __exit cleanup_pms_module(void)
1052{
1053 shutdown_mediavision();
1054 video_unregister_device((struct video_device *)&pms_device);
1055 iounmap(mem);
1056}
1057
1058module_init(init_pms_cards);
1059module_exit(cleanup_pms_module);
1060
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
new file mode 100644
index 000000000000..ba69f09cbdd1
--- /dev/null
+++ b/drivers/media/video/saa5246a.c
@@ -0,0 +1,843 @@
1/*
2 * Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from
3 * Philips.
4 *
5 * Only capturing of Teletext pages is tested. The videotext chips also have a
6 * TV output but my hardware doesn't use it. For this reason this driver does
7 * not support changing any TV display settings.
8 *
9 * Copyright (C) 2004 Michael Geng <linux@MichaelGeng.de>
10 *
11 * Derived from
12 *
13 * saa5249 driver
14 * Copyright (C) 1998 Richard Guenther
15 * <richard.guenther@student.uni-tuebingen.de>
16 *
17 * with changes by
18 * Alan Cox <Alan.Cox@linux.org>
19 *
20 * and
21 *
22 * vtx.c
23 * Copyright (C) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de>
24 *
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
38 * USA.
39 */
40
41#include <linux/module.h>
42#include <linux/kernel.h>
43#include <linux/sched.h>
44#include <linux/mm.h>
45#include <linux/init.h>
46#include <linux/i2c.h>
47#include <linux/videotext.h>
48#include <linux/videodev.h>
49#include "saa5246a.h"
50
51MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
52MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
53MODULE_LICENSE("GPL");
54
55struct saa5246a_device
56{
57 u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
58 int is_searching[NUM_DAUS];
59 struct i2c_client *client;
60 struct semaphore lock;
61};
62
63static struct video_device saa_template; /* Declared near bottom */
64
65/* Addresses to scan */
66static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END };
67static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
68I2C_CLIENT_INSMOD;
69
70static struct i2c_client client_template;
71
72static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind)
73{
74 int pgbuf;
75 int err;
76 struct i2c_client *client;
77 struct video_device *vd;
78 struct saa5246a_device *t;
79
80 printk(KERN_INFO "saa5246a: teletext chip found.\n");
81 client=kmalloc(sizeof(*client), GFP_KERNEL);
82 if(client==NULL)
83 return -ENOMEM;
84 client_template.adapter = adap;
85 client_template.addr = addr;
86 memcpy(client, &client_template, sizeof(*client));
87 t = kmalloc(sizeof(*t), GFP_KERNEL);
88 if(t==NULL)
89 {
90 kfree(client);
91 return -ENOMEM;
92 }
93 memset(t, 0, sizeof(*t));
94 strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
95 init_MUTEX(&t->lock);
96
97 /*
98 * Now create a video4linux device
99 */
100
101 vd = video_device_alloc();
102 if(vd==NULL)
103 {
104 kfree(t);
105 kfree(client);
106 return -ENOMEM;
107 }
108 i2c_set_clientdata(client, vd);
109 memcpy(vd, &saa_template, sizeof(*vd));
110
111 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
112 {
113 memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
114 t->is_searching[pgbuf] = FALSE;
115 }
116 vd->priv=t;
117
118
119 /*
120 * Register it
121 */
122
123 if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0)
124 {
125 kfree(t);
126 kfree(client);
127 video_device_release(vd);
128 return err;
129 }
130 t->client = client;
131 i2c_attach_client(client);
132 return 0;
133}
134
135/*
136 * We do most of the hard work when we become a device on the i2c.
137 */
138static int saa5246a_probe(struct i2c_adapter *adap)
139{
140 if (adap->class & I2C_CLASS_TV_ANALOG)
141 return i2c_probe(adap, &addr_data, saa5246a_attach);
142 return 0;
143}
144
145static int saa5246a_detach(struct i2c_client *client)
146{
147 struct video_device *vd = i2c_get_clientdata(client);
148 i2c_detach_client(client);
149 video_unregister_device(vd);
150 kfree(vd->priv);
151 kfree(client);
152 return 0;
153}
154
155static int saa5246a_command(struct i2c_client *device, unsigned int cmd,
156 void *arg)
157{
158 return -EINVAL;
159}
160
161/*
162 * I2C interfaces
163 */
164
165static struct i2c_driver i2c_driver_videotext =
166{
167 .owner = THIS_MODULE,
168 .name = IF_NAME, /* name */
169 .id = I2C_DRIVERID_SAA5249, /* in i2c.h */
170 .flags = I2C_DF_NOTIFY,
171 .attach_adapter = saa5246a_probe,
172 .detach_client = saa5246a_detach,
173 .command = saa5246a_command
174};
175
176static struct i2c_client client_template = {
177 .driver = &i2c_driver_videotext,
178 .name = "(unset)",
179};
180
181static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
182{
183 char buf[64];
184
185 buf[0] = reg;
186 memcpy(buf+1, data, count);
187
188 if(i2c_master_send(t->client, buf, count+1)==count+1)
189 return 0;
190 return -1;
191}
192
193static int i2c_senddata(struct saa5246a_device *t, ...)
194{
195 unsigned char buf[64];
196 int v;
197 int ct=0;
198 va_list argp;
199 va_start(argp,t);
200
201 while((v=va_arg(argp,int))!=-1)
202 buf[ct++]=v;
203 return i2c_sendbuf(t, buf[0], ct-1, buf+1);
204}
205
206/* Get count number of bytes from I²C-device at address adr, store them in buf.
207 * Start & stop handshaking is done by this routine, ack will be sent after the
208 * last byte to inhibit further sending of data. If uaccess is TRUE, data is
209 * written to user-space with put_user. Returns -1 if I²C-device didn't send
210 * acknowledge, 0 otherwise
211 */
212static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
213{
214 if(i2c_master_recv(t->client, buf, count)!=count)
215 return -1;
216 return 0;
217}
218
219/* When a page is found then the not FOUND bit in one of the status registers
220 * of the SAA5264A chip is cleared. Unfortunately this bit is not set
221 * automatically when a new page is requested. Instead this function must be
222 * called after a page has been requested.
223 *
224 * Return value: 0 if successful
225 */
226static int saa5246a_clear_found_bit(struct saa5246a_device *t,
227 unsigned char dau_no)
228{
229 unsigned char row_25_column_8;
230
231 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
232
233 dau_no |
234 R8_DO_NOT_CLEAR_MEMORY,
235
236 R9_CURSER_ROW_25,
237
238 R10_CURSER_COLUMN_8,
239
240 COMMAND_END) ||
241 i2c_getdata(t, 1, &row_25_column_8))
242 {
243 return -EIO;
244 }
245 row_25_column_8 |= ROW25_COLUMN8_PAGE_NOT_FOUND;
246 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
247
248 dau_no |
249 R8_DO_NOT_CLEAR_MEMORY,
250
251 R9_CURSER_ROW_25,
252
253 R10_CURSER_COLUMN_8,
254
255 row_25_column_8,
256
257 COMMAND_END))
258 {
259 return -EIO;
260 }
261
262 return 0;
263}
264
265/* Requests one videotext page as described in req. The fields of req are
266 * checked and an error is returned if something is invalid.
267 *
268 * Return value: 0 if successful
269 */
270static int saa5246a_request_page(struct saa5246a_device *t,
271 vtx_pagereq_t *req)
272{
273 if (req->pagemask < 0 || req->pagemask >= PGMASK_MAX)
274 return -EINVAL;
275 if (req->pagemask & PGMASK_PAGE)
276 if (req->page < 0 || req->page > PAGE_MAX)
277 return -EINVAL;
278 if (req->pagemask & PGMASK_HOUR)
279 if (req->hour < 0 || req->hour > HOUR_MAX)
280 return -EINVAL;
281 if (req->pagemask & PGMASK_MINUTE)
282 if (req->minute < 0 || req->minute > MINUTE_MAX)
283 return -EINVAL;
284 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
285 return -EINVAL;
286
287 if (i2c_senddata(t, SAA5246A_REGISTER_R2,
288
289 R2_IN_R3_SELECT_PAGE_HUNDREDS |
290 req->pgbuf << 4 |
291 R2_BANK_0 |
292 R2_HAMMING_CHECK_OFF,
293
294 HUNDREDS_OF_PAGE(req->page) |
295 R3_HOLD_PAGE |
296 (req->pagemask & PG_HUND ?
297 R3_PAGE_HUNDREDS_DO_CARE :
298 R3_PAGE_HUNDREDS_DO_NOT_CARE),
299
300 TENS_OF_PAGE(req->page) |
301 (req->pagemask & PG_TEN ?
302 R3_PAGE_TENS_DO_CARE :
303 R3_PAGE_TENS_DO_NOT_CARE),
304
305 UNITS_OF_PAGE(req->page) |
306 (req->pagemask & PG_UNIT ?
307 R3_PAGE_UNITS_DO_CARE :
308 R3_PAGE_UNITS_DO_NOT_CARE),
309
310 TENS_OF_HOUR(req->hour) |
311 (req->pagemask & HR_TEN ?
312 R3_HOURS_TENS_DO_CARE :
313 R3_HOURS_TENS_DO_NOT_CARE),
314
315 UNITS_OF_HOUR(req->hour) |
316 (req->pagemask & HR_UNIT ?
317 R3_HOURS_UNITS_DO_CARE :
318 R3_HOURS_UNITS_DO_NOT_CARE),
319
320 TENS_OF_MINUTE(req->minute) |
321 (req->pagemask & MIN_TEN ?
322 R3_MINUTES_TENS_DO_CARE :
323 R3_MINUTES_TENS_DO_NOT_CARE),
324
325 UNITS_OF_MINUTE(req->minute) |
326 (req->pagemask & MIN_UNIT ?
327 R3_MINUTES_UNITS_DO_CARE :
328 R3_MINUTES_UNITS_DO_NOT_CARE),
329
330 COMMAND_END) || i2c_senddata(t, SAA5246A_REGISTER_R2,
331
332 R2_IN_R3_SELECT_PAGE_HUNDREDS |
333 req->pgbuf << 4 |
334 R2_BANK_0 |
335 R2_HAMMING_CHECK_OFF,
336
337 HUNDREDS_OF_PAGE(req->page) |
338 R3_UPDATE_PAGE |
339 (req->pagemask & PG_HUND ?
340 R3_PAGE_HUNDREDS_DO_CARE :
341 R3_PAGE_HUNDREDS_DO_NOT_CARE),
342
343 COMMAND_END))
344 {
345 return -EIO;
346 }
347
348 t->is_searching[req->pgbuf] = TRUE;
349 return 0;
350}
351
352/* This routine decodes the page number from the infobits contained in line 25.
353 *
354 * Parameters:
355 * infobits: must be bits 0 to 9 of column 25
356 *
357 * Return value: page number coded in hexadecimal, i. e. page 123 is coded 0x123
358 */
359static inline int saa5246a_extract_pagenum_from_infobits(
360 unsigned char infobits[10])
361{
362 int page_hundreds, page_tens, page_units;
363
364 page_units = infobits[0] & ROW25_COLUMN0_PAGE_UNITS;
365 page_tens = infobits[1] & ROW25_COLUMN1_PAGE_TENS;
366 page_hundreds = infobits[8] & ROW25_COLUMN8_PAGE_HUNDREDS;
367
368 /* page 0x.. means page 8.. */
369 if (page_hundreds == 0)
370 page_hundreds = 8;
371
372 return((page_hundreds << 8) | (page_tens << 4) | page_units);
373}
374
375/* Decodes the hour from the infobits contained in line 25.
376 *
377 * Parameters:
378 * infobits: must be bits 0 to 9 of column 25
379 *
380 * Return: hour coded in hexadecimal, i. e. 12h is coded 0x12
381 */
382static inline int saa5246a_extract_hour_from_infobits(
383 unsigned char infobits[10])
384{
385 int hour_tens, hour_units;
386
387 hour_units = infobits[4] & ROW25_COLUMN4_HOUR_UNITS;
388 hour_tens = infobits[5] & ROW25_COLUMN5_HOUR_TENS;
389
390 return((hour_tens << 4) | hour_units);
391}
392
393/* Decodes the minutes from the infobits contained in line 25.
394 *
395 * Parameters:
396 * infobits: must be bits 0 to 9 of column 25
397 *
398 * Return: minutes coded in hexadecimal, i. e. 10min is coded 0x10
399 */
400static inline int saa5246a_extract_minutes_from_infobits(
401 unsigned char infobits[10])
402{
403 int minutes_tens, minutes_units;
404
405 minutes_units = infobits[2] & ROW25_COLUMN2_MINUTES_UNITS;
406 minutes_tens = infobits[3] & ROW25_COLUMN3_MINUTES_TENS;
407
408 return((minutes_tens << 4) | minutes_units);
409}
410
411/* Reads the status bits contained in the first 10 columns of the first line
412 * and extracts the information into info.
413 *
414 * Return value: 0 if successful
415 */
416static inline int saa5246a_get_status(struct saa5246a_device *t,
417 vtx_pageinfo_t *info, unsigned char dau_no)
418{
419 unsigned char infobits[10];
420 int column;
421
422 if (dau_no >= NUM_DAUS)
423 return -EINVAL;
424
425 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
426
427 dau_no |
428 R8_DO_NOT_CLEAR_MEMORY,
429
430 R9_CURSER_ROW_25,
431
432 R10_CURSER_COLUMN_0,
433
434 COMMAND_END) ||
435 i2c_getdata(t, 10, infobits))
436 {
437 return -EIO;
438 }
439
440 info->pagenum = saa5246a_extract_pagenum_from_infobits(infobits);
441 info->hour = saa5246a_extract_hour_from_infobits(infobits);
442 info->minute = saa5246a_extract_minutes_from_infobits(infobits);
443 info->charset = ((infobits[7] & ROW25_COLUMN7_CHARACTER_SET) >> 1);
444 info->delete = !!(infobits[3] & ROW25_COLUMN3_DELETE_PAGE);
445 info->headline = !!(infobits[5] & ROW25_COLUMN5_INSERT_HEADLINE);
446 info->subtitle = !!(infobits[5] & ROW25_COLUMN5_INSERT_SUBTITLE);
447 info->supp_header = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_HEADER);
448 info->update = !!(infobits[6] & ROW25_COLUMN6_UPDATE_PAGE);
449 info->inter_seq = !!(infobits[6] & ROW25_COLUMN6_INTERRUPTED_SEQUENCE);
450 info->dis_disp = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_DISPLAY);
451 info->serial = !!(infobits[7] & ROW25_COLUMN7_SERIAL_MODE);
452 info->notfound = !!(infobits[8] & ROW25_COLUMN8_PAGE_NOT_FOUND);
453 info->pblf = !!(infobits[9] & ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR);
454 info->hamming = 0;
455 for (column = 0; column <= 7; column++) {
456 if (infobits[column] & ROW25_COLUMN0_TO_7_HAMMING_ERROR) {
457 info->hamming = 1;
458 break;
459 }
460 }
461 if (!info->hamming && !info->notfound)
462 t->is_searching[dau_no] = FALSE;
463 return 0;
464}
465
466/* Reads 1 videotext page buffer of the SAA5246A.
467 *
468 * req is used both as input and as output. It contains information which part
469 * must be read. The videotext page is copied into req->buffer.
470 *
471 * Return value: 0 if successful
472 */
473static inline int saa5246a_get_page(struct saa5246a_device *t,
474 vtx_pagereq_t *req)
475{
476 int start, end, size;
477 char *buf;
478 int err;
479
480 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS ||
481 req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE)
482 return -EINVAL;
483
484 buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL);
485 if (!buf)
486 return -ENOMEM;
487
488 /* Read "normal" part of page */
489 err = -EIO;
490
491 end = min(req->end, VTX_PAGESIZE - 1);
492 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
493 req->pgbuf | R8_DO_NOT_CLEAR_MEMORY,
494 ROW(req->start), COLUMN(req->start), COMMAND_END))
495 goto out;
496 if (i2c_getdata(t, end - req->start + 1, buf))
497 goto out;
498 err = -EFAULT;
499 if (copy_to_user(req->buffer, buf, end - req->start + 1))
500 goto out;
501
502 /* Always get the time from buffer 4, since this stupid SAA5246A only
503 * updates the currently displayed buffer...
504 */
505 if (REQ_CONTAINS_TIME(req)) {
506 start = max(req->start, POS_TIME_START);
507 end = min(req->end, POS_TIME_END);
508 size = end - start + 1;
509 err = -EINVAL;
510 if (size < 0)
511 goto out;
512 err = -EIO;
513 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
514 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
515 R9_CURSER_ROW_0, start, COMMAND_END))
516 goto out;
517 if (i2c_getdata(t, size, buf))
518 goto out;
519 err = -EFAULT;
520 if (copy_to_user(req->buffer + start - req->start, buf, size))
521 goto out;
522 }
523 /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */
524 if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) {
525 start = max(req->start, POS_HEADER_START);
526 end = min(req->end, POS_HEADER_END);
527 size = end - start + 1;
528 err = -EINVAL;
529 if (size < 0)
530 goto out;
531 err = -EIO;
532 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
533 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
534 R9_CURSER_ROW_0, start, COMMAND_END))
535 goto out;
536 if (i2c_getdata(t, end - start + 1, buf))
537 goto out;
538 err = -EFAULT;
539 if (copy_to_user(req->buffer + start - req->start, buf, size))
540 goto out;
541 }
542 err = 0;
543out:
544 kfree(buf);
545 return err;
546}
547
548/* Stops the acquisition circuit given in dau_no. The page buffer associated
549 * with this acquisition circuit will no more be updated. The other daus are
550 * not affected.
551 *
552 * Return value: 0 if successful
553 */
554static inline int saa5246a_stop_dau(struct saa5246a_device *t,
555 unsigned char dau_no)
556{
557 if (dau_no >= NUM_DAUS)
558 return -EINVAL;
559 if (i2c_senddata(t, SAA5246A_REGISTER_R2,
560
561 R2_IN_R3_SELECT_PAGE_HUNDREDS |
562 dau_no << 4 |
563 R2_BANK_0 |
564 R2_HAMMING_CHECK_OFF,
565
566 R3_PAGE_HUNDREDS_0 |
567 R3_HOLD_PAGE |
568 R3_PAGE_HUNDREDS_DO_NOT_CARE,
569
570 COMMAND_END))
571 {
572 return -EIO;
573 }
574 t->is_searching[dau_no] = FALSE;
575 return 0;
576}
577
578/* Handles ioctls defined in videotext.h
579 *
580 * Returns 0 if successful
581 */
582static int do_saa5246a_ioctl(struct inode *inode, struct file *file,
583 unsigned int cmd, void *arg)
584{
585 struct video_device *vd = video_devdata(file);
586 struct saa5246a_device *t=vd->priv;
587 switch(cmd)
588 {
589 case VTXIOCGETINFO:
590 {
591 vtx_info_t *info = arg;
592
593 info->version_major = MAJOR_VERSION;
594 info->version_minor = MINOR_VERSION;
595 info->numpages = NUM_DAUS;
596 return 0;
597 }
598
599 case VTXIOCCLRPAGE:
600 {
601 vtx_pagereq_t *req = arg;
602
603 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
604 return -EINVAL;
605 memset(t->pgbuf[req->pgbuf], ' ', sizeof(t->pgbuf[0]));
606 return 0;
607 }
608
609 case VTXIOCCLRFOUND:
610 {
611 vtx_pagereq_t *req = arg;
612
613 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
614 return -EINVAL;
615 return(saa5246a_clear_found_bit(t, req->pgbuf));
616 }
617
618 case VTXIOCPAGEREQ:
619 {
620 vtx_pagereq_t *req = arg;
621
622 return(saa5246a_request_page(t, req));
623 }
624
625 case VTXIOCGETSTAT:
626 {
627 vtx_pagereq_t *req = arg;
628 vtx_pageinfo_t info;
629 int rval;
630
631 if ((rval = saa5246a_get_status(t, &info, req->pgbuf)))
632 return rval;
633 if(copy_to_user(req->buffer, &info,
634 sizeof(vtx_pageinfo_t)))
635 return -EFAULT;
636 return 0;
637 }
638
639 case VTXIOCGETPAGE:
640 {
641 vtx_pagereq_t *req = arg;
642
643 return(saa5246a_get_page(t, req));
644 }
645
646 case VTXIOCSTOPDAU:
647 {
648 vtx_pagereq_t *req = arg;
649
650 return(saa5246a_stop_dau(t, req->pgbuf));
651 }
652
653 case VTXIOCPUTPAGE:
654 case VTXIOCSETDISP:
655 case VTXIOCPUTSTAT:
656 return 0;
657
658 case VTXIOCCLRCACHE:
659 {
660 return 0;
661 }
662
663 case VTXIOCSETVIRT:
664 {
665 /* I do not know what "virtual mode" means */
666 return 0;
667 }
668 }
669 return -EINVAL;
670}
671
672/*
673 * Translates old vtx IOCTLs to new ones
674 *
675 * This keeps new kernel versions compatible with old userspace programs.
676 */
677static inline unsigned int vtx_fix_command(unsigned int cmd)
678{
679 switch (cmd) {
680 case VTXIOCGETINFO_OLD:
681 cmd = VTXIOCGETINFO;
682 break;
683 case VTXIOCCLRPAGE_OLD:
684 cmd = VTXIOCCLRPAGE;
685 break;
686 case VTXIOCCLRFOUND_OLD:
687 cmd = VTXIOCCLRFOUND;
688 break;
689 case VTXIOCPAGEREQ_OLD:
690 cmd = VTXIOCPAGEREQ;
691 break;
692 case VTXIOCGETSTAT_OLD:
693 cmd = VTXIOCGETSTAT;
694 break;
695 case VTXIOCGETPAGE_OLD:
696 cmd = VTXIOCGETPAGE;
697 break;
698 case VTXIOCSTOPDAU_OLD:
699 cmd = VTXIOCSTOPDAU;
700 break;
701 case VTXIOCPUTPAGE_OLD:
702 cmd = VTXIOCPUTPAGE;
703 break;
704 case VTXIOCSETDISP_OLD:
705 cmd = VTXIOCSETDISP;
706 break;
707 case VTXIOCPUTSTAT_OLD:
708 cmd = VTXIOCPUTSTAT;
709 break;
710 case VTXIOCCLRCACHE_OLD:
711 cmd = VTXIOCCLRCACHE;
712 break;
713 case VTXIOCSETVIRT_OLD:
714 cmd = VTXIOCSETVIRT;
715 break;
716 }
717 return cmd;
718}
719
720/*
721 * Handle the locking
722 */
723static int saa5246a_ioctl(struct inode *inode, struct file *file,
724 unsigned int cmd, unsigned long arg)
725{
726 struct video_device *vd = video_devdata(file);
727 struct saa5246a_device *t = vd->priv;
728 int err;
729
730 cmd = vtx_fix_command(cmd);
731 down(&t->lock);
732 err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl);
733 up(&t->lock);
734 return err;
735}
736
737static int saa5246a_open(struct inode *inode, struct file *file)
738{
739 struct video_device *vd = video_devdata(file);
740 struct saa5246a_device *t = vd->priv;
741 int err;
742
743 err = video_exclusive_open(inode,file);
744 if (err < 0)
745 return err;
746
747 if (t->client==NULL) {
748 err = -ENODEV;
749 goto fail;
750 }
751
752 if (i2c_senddata(t, SAA5246A_REGISTER_R0,
753
754 R0_SELECT_R11 |
755 R0_PLL_TIME_CONSTANT_LONG |
756 R0_ENABLE_nODD_EVEN_OUTPUT |
757 R0_ENABLE_HDR_POLL |
758 R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED |
759 R0_NO_FREE_RUN_PLL |
760 R0_NO_AUTOMATIC_FASTEXT_PROMPT,
761
762 R1_NON_INTERLACED_312_312_LINES |
763 R1_DEW |
764 R1_EXTENDED_PACKET_DISABLE |
765 R1_DAUS_ALL_ON |
766 R1_8_BITS_NO_PARITY |
767 R1_VCS_TO_SCS,
768
769 COMMAND_END) ||
770 i2c_senddata(t, SAA5246A_REGISTER_R4,
771
772 /* We do not care much for the TV display but nevertheless we
773 * need the currently displayed page later because only on that
774 * page the time is updated. */
775 R4_DISPLAY_PAGE_4,
776
777 COMMAND_END))
778 {
779 err = -EIO;
780 goto fail;
781 }
782
783 return 0;
784
785fail:
786 video_exclusive_release(inode,file);
787 return err;
788}
789
790static int saa5246a_release(struct inode *inode, struct file *file)
791{
792 struct video_device *vd = video_devdata(file);
793 struct saa5246a_device *t = vd->priv;
794
795 /* Stop all acquisition circuits. */
796 i2c_senddata(t, SAA5246A_REGISTER_R1,
797
798 R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES |
799 R1_DEW |
800 R1_EXTENDED_PACKET_DISABLE |
801 R1_DAUS_ALL_OFF |
802 R1_8_BITS_NO_PARITY |
803 R1_VCS_TO_SCS,
804
805 COMMAND_END);
806 video_exclusive_release(inode,file);
807 return 0;
808}
809
810static int __init init_saa_5246a (void)
811{
812 printk(KERN_INFO
813 "SAA5246A (or compatible) Teletext decoder driver version %d.%d\n",
814 MAJOR_VERSION, MINOR_VERSION);
815 return i2c_add_driver(&i2c_driver_videotext);
816}
817
818static void __exit cleanup_saa_5246a (void)
819{
820 i2c_del_driver(&i2c_driver_videotext);
821}
822
823module_init(init_saa_5246a);
824module_exit(cleanup_saa_5246a);
825
826static struct file_operations saa_fops = {
827 .owner = THIS_MODULE,
828 .open = saa5246a_open,
829 .release = saa5246a_release,
830 .ioctl = saa5246a_ioctl,
831 .llseek = no_llseek,
832};
833
834static struct video_device saa_template =
835{
836 .owner = THIS_MODULE,
837 .name = IF_NAME,
838 .type = VID_TYPE_TELETEXT,
839 .hardware = VID_HARDWARE_SAA5249,
840 .fops = &saa_fops,
841 .release = video_device_release,
842 .minor = -1,
843};
diff --git a/drivers/media/video/saa5246a.h b/drivers/media/video/saa5246a.h
new file mode 100644
index 000000000000..7b91112304e0
--- /dev/null
+++ b/drivers/media/video/saa5246a.h
@@ -0,0 +1,364 @@
1/*
2 Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from
3 Philips.
4
5 Copyright (C) 2004 Michael Geng (linux@MichaelGeng.de)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22#ifndef __SAA5246A_H__
23#define __SAA5246A_H__
24
25#define MAJOR_VERSION 1 /* driver major version number */
26#define MINOR_VERSION 8 /* driver minor version number */
27
28#define IF_NAME "SAA5246A"
29
30#define I2C_ADDRESS 17
31
32/* Number of DAUs = number of pages that can be searched at the same time. */
33#define NUM_DAUS 4
34
35#define NUM_ROWS_PER_PAGE 40
36
37/* first column is 0 (not 1) */
38#define POS_TIME_START 32
39#define POS_TIME_END 39
40
41#define POS_HEADER_START 7
42#define POS_HEADER_END 31
43
44/* Returns TRUE if the part of the videotext page described with req contains
45 (at least parts of) the time field */
46#define REQ_CONTAINS_TIME(p_req) \
47 ((p_req)->start <= POS_TIME_END && \
48 (p_req)->end >= POS_TIME_START)
49
50/* Returns TRUE if the part of the videotext page described with req contains
51 (at least parts of) the page header */
52#define REQ_CONTAINS_HEADER(p_req) \
53 ((p_req)->start <= POS_HEADER_END && \
54 (p_req)->end >= POS_HEADER_START)
55
56#ifndef FALSE
57#define FALSE 0
58#define TRUE 1
59#endif
60
61/*****************************************************************************/
62/* Mode register numbers of the SAA5246A */
63/*****************************************************************************/
64#define SAA5246A_REGISTER_R0 0
65#define SAA5246A_REGISTER_R1 1
66#define SAA5246A_REGISTER_R2 2
67#define SAA5246A_REGISTER_R3 3
68#define SAA5246A_REGISTER_R4 4
69#define SAA5246A_REGISTER_R5 5
70#define SAA5246A_REGISTER_R6 6
71#define SAA5246A_REGISTER_R7 7
72#define SAA5246A_REGISTER_R8 8
73#define SAA5246A_REGISTER_R9 9
74#define SAA5246A_REGISTER_R10 10
75#define SAA5246A_REGISTER_R11 11
76#define SAA5246A_REGISTER_R11B 11
77
78/* SAA5246A mode registers often autoincrement to the next register.
79 Therefore we use variable argument lists. The following macro indicates
80 the end of a command list. */
81#define COMMAND_END (- 1)
82
83/*****************************************************************************/
84/* Contents of the mode registers of the SAA5246A */
85/*****************************************************************************/
86/* Register R0 (Advanced Control) */
87#define R0_SELECT_R11 0x00
88#define R0_SELECT_R11B 0x01
89
90#define R0_PLL_TIME_CONSTANT_LONG 0x00
91#define R0_PLL_TIME_CONSTANT_SHORT 0x02
92
93#define R0_ENABLE_nODD_EVEN_OUTPUT 0x00
94#define R0_DISABLE_nODD_EVEN_OUTPUT 0x04
95
96#define R0_ENABLE_HDR_POLL 0x00
97#define R0_DISABLE_HDR_POLL 0x10
98
99#define R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x00
100#define R0_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x20
101
102#define R0_NO_FREE_RUN_PLL 0x00
103#define R0_FREE_RUN_PLL 0x40
104
105#define R0_NO_AUTOMATIC_FASTEXT_PROMPT 0x00
106#define R0_AUTOMATIC_FASTEXT_PROMPT 0x80
107
108/* Register R1 (Mode) */
109#define R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES 0x00
110#define R1_NON_INTERLACED_312_313_LINES 0x01
111#define R1_NON_INTERLACED_312_312_LINES 0x02
112#define R1_FFB_LEADING_EDGE_IN_FIRST_BROAD_PULSE 0x03
113#define R1_FFB_LEADING_EDGE_IN_SECOND_BROAD_PULSE 0x07
114
115#define R1_DEW 0x00
116#define R1_FULL_FIELD 0x08
117
118#define R1_EXTENDED_PACKET_DISABLE 0x00
119#define R1_EXTENDED_PACKET_ENABLE 0x10
120
121#define R1_DAUS_ALL_ON 0x00
122#define R1_DAUS_ALL_OFF 0x20
123
124#define R1_7_BITS_PLUS_PARITY 0x00
125#define R1_8_BITS_NO_PARITY 0x40
126
127#define R1_VCS_TO_SCS 0x00
128#define R1_NO_VCS_TO_SCS 0x80
129
130/* Register R2 (Page request address) */
131#define R2_IN_R3_SELECT_PAGE_HUNDREDS 0x00
132#define R2_IN_R3_SELECT_PAGE_TENS 0x01
133#define R2_IN_R3_SELECT_PAGE_UNITS 0x02
134#define R2_IN_R3_SELECT_HOURS_TENS 0x03
135#define R2_IN_R3_SELECT_HOURS_UNITS 0x04
136#define R2_IN_R3_SELECT_MINUTES_TENS 0x05
137#define R2_IN_R3_SELECT_MINUTES_UNITS 0x06
138
139#define R2_DAU_0 0x00
140#define R2_DAU_1 0x10
141#define R2_DAU_2 0x20
142#define R2_DAU_3 0x30
143
144#define R2_BANK_0 0x00
145#define R2_BANK 1 0x40
146
147#define R2_HAMMING_CHECK_ON 0x80
148#define R2_HAMMING_CHECK_OFF 0x00
149
150/* Register R3 (Page request data) */
151#define R3_PAGE_HUNDREDS_0 0x00
152#define R3_PAGE_HUNDREDS_1 0x01
153#define R3_PAGE_HUNDREDS_2 0x02
154#define R3_PAGE_HUNDREDS_3 0x03
155#define R3_PAGE_HUNDREDS_4 0x04
156#define R3_PAGE_HUNDREDS_5 0x05
157#define R3_PAGE_HUNDREDS_6 0x06
158#define R3_PAGE_HUNDREDS_7 0x07
159
160#define R3_HOLD_PAGE 0x00
161#define R3_UPDATE_PAGE 0x08
162
163#define R3_PAGE_HUNDREDS_DO_NOT_CARE 0x00
164#define R3_PAGE_HUNDREDS_DO_CARE 0x10
165
166#define R3_PAGE_TENS_DO_NOT_CARE 0x00
167#define R3_PAGE_TENS_DO_CARE 0x10
168
169#define R3_PAGE_UNITS_DO_NOT_CARE 0x00
170#define R3_PAGE_UNITS_DO_CARE 0x10
171
172#define R3_HOURS_TENS_DO_NOT_CARE 0x00
173#define R3_HOURS_TENS_DO_CARE 0x10
174
175#define R3_HOURS_UNITS_DO_NOT_CARE 0x00
176#define R3_HOURS_UNITS_DO_CARE 0x10
177
178#define R3_MINUTES_TENS_DO_NOT_CARE 0x00
179#define R3_MINUTES_TENS_DO_CARE 0x10
180
181#define R3_MINUTES_UNITS_DO_NOT_CARE 0x00
182#define R3_MINUTES_UNITS_DO_CARE 0x10
183
184/* Register R4 (Display chapter) */
185#define R4_DISPLAY_PAGE_0 0x00
186#define R4_DISPLAY_PAGE_1 0x01
187#define R4_DISPLAY_PAGE_2 0x02
188#define R4_DISPLAY_PAGE_3 0x03
189#define R4_DISPLAY_PAGE_4 0x04
190#define R4_DISPLAY_PAGE_5 0x05
191#define R4_DISPLAY_PAGE_6 0x06
192#define R4_DISPLAY_PAGE_7 0x07
193
194/* Register R5 (Normal display control) */
195#define R5_PICTURE_INSIDE_BOXING_OFF 0x00
196#define R5_PICTURE_INSIDE_BOXING_ON 0x01
197
198#define R5_PICTURE_OUTSIDE_BOXING_OFF 0x00
199#define R5_PICTURE_OUTSIDE_BOXING_ON 0x02
200
201#define R5_TEXT_INSIDE_BOXING_OFF 0x00
202#define R5_TEXT_INSIDE_BOXING_ON 0x04
203
204#define R5_TEXT_OUTSIDE_BOXING_OFF 0x00
205#define R5_TEXT_OUTSIDE_BOXING_ON 0x08
206
207#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00
208#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10
209
210#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00
211#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20
212
213#define R5_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00
214#define R5_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40
215
216#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00
217#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80
218
219/* Register R6 (Newsflash display) */
220#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_OFF 0x00
221#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_ON 0x01
222
223#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_OFF 0x00
224#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_ON 0x02
225
226#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_OFF 0x00
227#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_ON 0x04
228
229#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_OFF 0x00
230#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_ON 0x08
231
232#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00
233#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10
234
235#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00
236#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20
237
238#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00
239#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40
240
241#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00
242#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80
243
244/* Register R7 (Display mode) */
245#define R7_BOX_OFF_ROW_0 0x00
246#define R7_BOX_ON_ROW_0 0x01
247
248#define R7_BOX_OFF_ROW_1_TO_23 0x00
249#define R7_BOX_ON_ROW_1_TO_23 0x02
250
251#define R7_BOX_OFF_ROW_24 0x00
252#define R7_BOX_ON_ROW_24 0x04
253
254#define R7_SINGLE_HEIGHT 0x00
255#define R7_DOUBLE_HEIGHT 0x08
256
257#define R7_TOP_HALF 0x00
258#define R7_BOTTOM_HALF 0x10
259
260#define R7_REVEAL_OFF 0x00
261#define R7_REVEAL_ON 0x20
262
263#define R7_CURSER_OFF 0x00
264#define R7_CURSER_ON 0x40
265
266#define R7_STATUS_BOTTOM 0x00
267#define R7_STATUS_TOP 0x80
268
269/* Register R8 (Active chapter) */
270#define R8_ACTIVE_CHAPTER_0 0x00
271#define R8_ACTIVE_CHAPTER_1 0x01
272#define R8_ACTIVE_CHAPTER_2 0x02
273#define R8_ACTIVE_CHAPTER_3 0x03
274#define R8_ACTIVE_CHAPTER_4 0x04
275#define R8_ACTIVE_CHAPTER_5 0x05
276#define R8_ACTIVE_CHAPTER_6 0x06
277#define R8_ACTIVE_CHAPTER_7 0x07
278
279#define R8_CLEAR_MEMORY 0x08
280#define R8_DO_NOT_CLEAR_MEMORY 0x00
281
282/* Register R9 (Curser row) */
283#define R9_CURSER_ROW_0 0x00
284#define R9_CURSER_ROW_1 0x01
285#define R9_CURSER_ROW_2 0x02
286#define R9_CURSER_ROW_25 0x19
287
288/* Register R10 (Curser column) */
289#define R10_CURSER_COLUMN_0 0x00
290#define R10_CURSER_COLUMN_6 0x06
291#define R10_CURSER_COLUMN_8 0x08
292
293/*****************************************************************************/
294/* Row 25 control data in column 0 to 9 */
295/*****************************************************************************/
296#define ROW25_COLUMN0_PAGE_UNITS 0x0F
297
298#define ROW25_COLUMN1_PAGE_TENS 0x0F
299
300#define ROW25_COLUMN2_MINUTES_UNITS 0x0F
301
302#define ROW25_COLUMN3_MINUTES_TENS 0x07
303#define ROW25_COLUMN3_DELETE_PAGE 0x08
304
305#define ROW25_COLUMN4_HOUR_UNITS 0x0F
306
307#define ROW25_COLUMN5_HOUR_TENS 0x03
308#define ROW25_COLUMN5_INSERT_HEADLINE 0x04
309#define ROW25_COLUMN5_INSERT_SUBTITLE 0x08
310
311#define ROW25_COLUMN6_SUPPRESS_HEADER 0x01
312#define ROW25_COLUMN6_UPDATE_PAGE 0x02
313#define ROW25_COLUMN6_INTERRUPTED_SEQUENCE 0x04
314#define ROW25_COLUMN6_SUPPRESS_DISPLAY 0x08
315
316#define ROW25_COLUMN7_SERIAL_MODE 0x01
317#define ROW25_COLUMN7_CHARACTER_SET 0x0E
318
319#define ROW25_COLUMN8_PAGE_HUNDREDS 0x07
320#define ROW25_COLUMN8_PAGE_NOT_FOUND 0x10
321
322#define ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR 0x20
323
324#define ROW25_COLUMN0_TO_7_HAMMING_ERROR 0x10
325
326/*****************************************************************************/
327/* Helper macros for extracting page, hour and minute digits */
328/*****************************************************************************/
329/* BYTE_POS 0 is at row 0, column 0,
330 BYTE_POS 1 is at row 0, column 1,
331 BYTE_POS 40 is at row 1, column 0, (with NUM_ROWS_PER_PAGE = 40)
332 BYTE_POS 41 is at row 1, column 1, (with NUM_ROWS_PER_PAGE = 40),
333 ... */
334#define ROW(BYTE_POS) (BYTE_POS / NUM_ROWS_PER_PAGE)
335#define COLUMN(BYTE_POS) (BYTE_POS % NUM_ROWS_PER_PAGE)
336
337/*****************************************************************************/
338/* Helper macros for extracting page, hour and minute digits */
339/*****************************************************************************/
340/* Macros for extracting hundreds, tens and units of a page number which
341 must be in the range 0 ... 0x799.
342 Note that page is coded in hexadecimal, i.e. 0x123 means page 123.
343 page 0x.. means page 8.. */
344#define HUNDREDS_OF_PAGE(page) (((page) / 0x100) & 0x7)
345#define TENS_OF_PAGE(page) (((page) / 0x10) & 0xF)
346#define UNITS_OF_PAGE(page) ((page) & 0xF)
347
348/* Macros for extracting tens and units of a hour information which
349 must be in the range 0 ... 0x24.
350 Note that hour is coded in hexadecimal, i.e. 0x12 means 12 hours */
351#define TENS_OF_HOUR(hour) ((hour) / 0x10)
352#define UNITS_OF_HOUR(hour) ((hour) & 0xF)
353
354/* Macros for extracting tens and units of a minute information which
355 must be in the range 0 ... 0x59.
356 Note that minute is coded in hexadecimal, i.e. 0x12 means 12 minutes */
357#define TENS_OF_MINUTE(minute) ((minute) / 0x10)
358#define UNITS_OF_MINUTE(minute) ((minute) & 0xF)
359
360#define HOUR_MAX 0x23
361#define MINUTE_MAX 0x59
362#define PAGE_MAX 0x8FF
363
364#endif /* __SAA5246A_H__ */
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
new file mode 100644
index 000000000000..d74caa139f0a
--- /dev/null
+++ b/drivers/media/video/saa5249.c
@@ -0,0 +1,725 @@
1/*
2 * Modified in order to keep it compatible both with new and old videotext IOCTLs by
3 * Michael Geng <linux@MichaelGeng.de>
4 *
5 * Cleaned up to use existing videodev interface and allow the idea
6 * of multiple teletext decoders on the video4linux iface. Changed i2c
7 * to cover addressing clashes on device busses. It's also rebuilt so
8 * you can add arbitary multiple teletext devices to Linux video4linux
9 * now (well 32 anyway).
10 *
11 * Alan Cox <Alan.Cox@linux.org>
12 *
13 * The original driver was heavily modified to match the i2c interface
14 * It was truncated to use the WinTV boards, too.
15 *
16 * Copyright (c) 1998 Richard Guenther <richard.guenther@student.uni-tuebingen.de>
17 *
18 * $Id: saa5249.c,v 1.1 1998/03/30 22:23:23 alan Exp $
19 *
20 * Derived From
21 *
22 * vtx.c:
23 * This is a loadable character-device-driver for videotext-interfaces
24 * (aka teletext). Please check the Makefile/README for a list of supported
25 * interfaces.
26 *
27 * Copyright (c) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de>
28 *
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
43 * USA.
44 */
45
46#include <linux/module.h>
47#include <linux/kernel.h>
48#include <linux/sched.h>
49#include <linux/mm.h>
50#include <linux/errno.h>
51#include <linux/delay.h>
52#include <linux/ioport.h>
53#include <linux/slab.h>
54#include <linux/init.h>
55#include <stdarg.h>
56#include <linux/i2c.h>
57#include <linux/videotext.h>
58#include <linux/videodev.h>
59
60#include <asm/io.h>
61#include <asm/uaccess.h>
62
63#define VTX_VER_MAJ 1
64#define VTX_VER_MIN 8
65
66
67
68#define NUM_DAUS 4
69#define NUM_BUFS 8
70#define IF_NAME "SAA5249"
71
72static const int disp_modes[8][3] =
73{
74 { 0x46, 0x03, 0x03 }, /* DISPOFF */
75 { 0x46, 0xcc, 0xcc }, /* DISPNORM */
76 { 0x44, 0x0f, 0x0f }, /* DISPTRANS */
77 { 0x46, 0xcc, 0x46 }, /* DISPINS */
78 { 0x44, 0x03, 0x03 }, /* DISPOFF, interlaced */
79 { 0x44, 0xcc, 0xcc }, /* DISPNORM, interlaced */
80 { 0x44, 0x0f, 0x0f }, /* DISPTRANS, interlaced */
81 { 0x44, 0xcc, 0x46 } /* DISPINS, interlaced */
82};
83
84
85
86#define PAGE_WAIT (300*HZ/1000) /* Time between requesting page and */
87 /* checking status bits */
88#define PGBUF_EXPIRE (15*HZ) /* Time to wait before retransmitting */
89 /* page regardless of infobits */
90typedef struct {
91 u8 pgbuf[VTX_VIRTUALSIZE]; /* Page-buffer */
92 u8 laststat[10]; /* Last value of infobits for DAU */
93 u8 sregs[7]; /* Page-request registers */
94 unsigned long expire; /* Time when page will be expired */
95 unsigned clrfound : 1; /* VTXIOCCLRFOUND has been called */
96 unsigned stopped : 1; /* VTXIOCSTOPDAU has been called */
97} vdau_t;
98
99struct saa5249_device
100{
101 vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
102 /* real DAU, so we have to simulate some more) */
103 int vtx_use_count;
104 int is_searching[NUM_DAUS];
105 int disp_mode;
106 int virtual_mode;
107 struct i2c_client *client;
108 struct semaphore lock;
109};
110
111
112#define CCTWR 34 /* I²C write/read-address of vtx-chip */
113#define CCTRD 35
114#define NOACK_REPEAT 10 /* Retry access this many times on failure */
115#define CLEAR_DELAY (HZ/20) /* Time required to clear a page */
116#define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */
117#define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */
118#define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */
119
120#define VTX_DEV_MINOR 0
121
122/* General defines and debugging support */
123
124#ifndef FALSE
125#define FALSE 0
126#define TRUE 1
127#endif
128
129#define RESCHED do { cond_resched(); } while(0)
130
131static struct video_device saa_template; /* Declared near bottom */
132
133/* Addresses to scan */
134static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
135static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
136I2C_CLIENT_INSMOD;
137
138static struct i2c_client client_template;
139
140static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind)
141{
142 int pgbuf;
143 int err;
144 struct i2c_client *client;
145 struct video_device *vd;
146 struct saa5249_device *t;
147
148 printk(KERN_INFO "saa5249: teletext chip found.\n");
149 client=kmalloc(sizeof(*client), GFP_KERNEL);
150 if(client==NULL)
151 return -ENOMEM;
152 client_template.adapter = adap;
153 client_template.addr = addr;
154 memcpy(client, &client_template, sizeof(*client));
155 t = kmalloc(sizeof(*t), GFP_KERNEL);
156 if(t==NULL)
157 {
158 kfree(client);
159 return -ENOMEM;
160 }
161 memset(t, 0, sizeof(*t));
162 strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
163 init_MUTEX(&t->lock);
164
165 /*
166 * Now create a video4linux device
167 */
168
169 vd = (struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL);
170 if(vd==NULL)
171 {
172 kfree(t);
173 kfree(client);
174 return -ENOMEM;
175 }
176 i2c_set_clientdata(client, vd);
177 memcpy(vd, &saa_template, sizeof(*vd));
178
179 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
180 {
181 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
182 memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
183 memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
184 t->vdau[pgbuf].expire = 0;
185 t->vdau[pgbuf].clrfound = TRUE;
186 t->vdau[pgbuf].stopped = TRUE;
187 t->is_searching[pgbuf] = FALSE;
188 }
189 vd->priv=t;
190
191
192 /*
193 * Register it
194 */
195
196 if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0)
197 {
198 kfree(t);
199 kfree(vd);
200 kfree(client);
201 return err;
202 }
203 t->client = client;
204 i2c_attach_client(client);
205 return 0;
206}
207
208/*
209 * We do most of the hard work when we become a device on the i2c.
210 */
211
212static int saa5249_probe(struct i2c_adapter *adap)
213{
214 if (adap->class & I2C_CLASS_TV_ANALOG)
215 return i2c_probe(adap, &addr_data, saa5249_attach);
216 return 0;
217}
218
219static int saa5249_detach(struct i2c_client *client)
220{
221 struct video_device *vd = i2c_get_clientdata(client);
222 i2c_detach_client(client);
223 video_unregister_device(vd);
224 kfree(vd->priv);
225 kfree(vd);
226 kfree(client);
227 return 0;
228}
229
230static int saa5249_command(struct i2c_client *device,
231 unsigned int cmd, void *arg)
232{
233 return -EINVAL;
234}
235
236/* new I2C driver support */
237
238static struct i2c_driver i2c_driver_videotext =
239{
240 .owner = THIS_MODULE,
241 .name = IF_NAME, /* name */
242 .id = I2C_DRIVERID_SAA5249, /* in i2c.h */
243 .flags = I2C_DF_NOTIFY,
244 .attach_adapter = saa5249_probe,
245 .detach_client = saa5249_detach,
246 .command = saa5249_command
247};
248
249static struct i2c_client client_template = {
250 .driver = &i2c_driver_videotext,
251 .name = "(unset)",
252};
253
254/*
255 * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual
256 * delay may be longer.
257 */
258
259static void jdelay(unsigned long delay)
260{
261 sigset_t oldblocked = current->blocked;
262
263 spin_lock_irq(&current->sighand->siglock);
264 sigfillset(&current->blocked);
265 recalc_sigpending();
266 spin_unlock_irq(&current->sighand->siglock);
267 msleep_interruptible(jiffies_to_msecs(delay));
268
269 spin_lock_irq(&current->sighand->siglock);
270 current->blocked = oldblocked;
271 recalc_sigpending();
272 spin_unlock_irq(&current->sighand->siglock);
273}
274
275
276/*
277 * I2C interfaces
278 */
279
280static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
281{
282 char buf[64];
283
284 buf[0] = reg;
285 memcpy(buf+1, data, count);
286
287 if(i2c_master_send(t->client, buf, count+1)==count+1)
288 return 0;
289 return -1;
290}
291
292static int i2c_senddata(struct saa5249_device *t, ...)
293{
294 unsigned char buf[64];
295 int v;
296 int ct=0;
297 va_list argp;
298 va_start(argp,t);
299
300 while((v=va_arg(argp,int))!=-1)
301 buf[ct++]=v;
302 return i2c_sendbuf(t, buf[0], ct-1, buf+1);
303}
304
305/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
306 * handshaking is done by this routine, ack will be sent after the last byte to inhibit further
307 * sending of data. If uaccess is TRUE, data is written to user-space with put_user.
308 * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
309 */
310
311static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
312{
313 if(i2c_master_recv(t->client, buf, count)!=count)
314 return -1;
315 return 0;
316}
317
318
319/*
320 * Standard character-device-driver functions
321 */
322
323static int do_saa5249_ioctl(struct inode *inode, struct file *file,
324 unsigned int cmd, void *arg)
325{
326 static int virtual_mode = FALSE;
327 struct video_device *vd = video_devdata(file);
328 struct saa5249_device *t=vd->priv;
329
330 switch(cmd)
331 {
332 case VTXIOCGETINFO:
333 {
334 vtx_info_t *info = arg;
335 info->version_major = VTX_VER_MAJ;
336 info->version_minor = VTX_VER_MIN;
337 info->numpages = NUM_DAUS;
338 /*info->cct_type = CCT_TYPE;*/
339 return 0;
340 }
341
342 case VTXIOCCLRPAGE:
343 {
344 vtx_pagereq_t *req = arg;
345
346 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
347 return -EINVAL;
348 memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
349 t->vdau[req->pgbuf].clrfound = TRUE;
350 return 0;
351 }
352
353 case VTXIOCCLRFOUND:
354 {
355 vtx_pagereq_t *req = arg;
356
357 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
358 return -EINVAL;
359 t->vdau[req->pgbuf].clrfound = TRUE;
360 return 0;
361 }
362
363 case VTXIOCPAGEREQ:
364 {
365 vtx_pagereq_t *req = arg;
366 if (!(req->pagemask & PGMASK_PAGE))
367 req->page = 0;
368 if (!(req->pagemask & PGMASK_HOUR))
369 req->hour = 0;
370 if (!(req->pagemask & PGMASK_MINUTE))
371 req->minute = 0;
372 if (req->page < 0 || req->page > 0x8ff) /* 7FF ?? */
373 return -EINVAL;
374 req->page &= 0x7ff;
375 if (req->hour < 0 || req->hour > 0x3f || req->minute < 0 || req->minute > 0x7f ||
376 req->pagemask < 0 || req->pagemask >= PGMASK_MAX || req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
377 return -EINVAL;
378 t->vdau[req->pgbuf].sregs[0] = (req->pagemask & PG_HUND ? 0x10 : 0) | (req->page / 0x100);
379 t->vdau[req->pgbuf].sregs[1] = (req->pagemask & PG_TEN ? 0x10 : 0) | ((req->page / 0x10) & 0xf);
380 t->vdau[req->pgbuf].sregs[2] = (req->pagemask & PG_UNIT ? 0x10 : 0) | (req->page & 0xf);
381 t->vdau[req->pgbuf].sregs[3] = (req->pagemask & HR_TEN ? 0x10 : 0) | (req->hour / 0x10);
382 t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf);
383 t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10);
384 t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf);
385 t->vdau[req->pgbuf].stopped = FALSE;
386 t->vdau[req->pgbuf].clrfound = TRUE;
387 t->is_searching[req->pgbuf] = TRUE;
388 return 0;
389 }
390
391 case VTXIOCGETSTAT:
392 {
393 vtx_pagereq_t *req = arg;
394 u8 infobits[10];
395 vtx_pageinfo_t info;
396 int a;
397
398 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
399 return -EINVAL;
400 if (!t->vdau[req->pgbuf].stopped)
401 {
402 if (i2c_senddata(t, 2, 0, -1) ||
403 i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) ||
404 i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) ||
405 i2c_senddata(t, 2, 0, t->vdau[req->pgbuf].sregs[0] | 8, -1) ||
406 i2c_senddata(t, 8, 0, 25, 0, -1))
407 return -EIO;
408 jdelay(PAGE_WAIT);
409 if (i2c_getdata(t, 10, infobits))
410 return -EIO;
411
412 if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */
413 (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) ||
414 time_after_eq(jiffies, t->vdau[req->pgbuf].expire)))
415 { /* check if new page arrived */
416 if (i2c_senddata(t, 8, 0, 0, 0, -1) ||
417 i2c_getdata(t, VTX_PAGESIZE, t->vdau[req->pgbuf].pgbuf))
418 return -EIO;
419 t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE;
420 memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE);
421 if (t->virtual_mode)
422 {
423 /* Packet X/24 */
424 if (i2c_senddata(t, 8, 0, 0x20, 0, -1) ||
425 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40))
426 return -EIO;
427 /* Packet X/27/0 */
428 if (i2c_senddata(t, 8, 0, 0x21, 0, -1) ||
429 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40))
430 return -EIO;
431 /* Packet 8/30/0...8/30/15
432 * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30,
433 * so we should undo this here.
434 */
435 if (i2c_senddata(t, 8, 0, 0x22, 0, -1) ||
436 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40))
437 return -EIO;
438 }
439 t->vdau[req->pgbuf].clrfound = FALSE;
440 memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits));
441 }
442 else
443 {
444 memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits));
445 }
446 }
447 else
448 {
449 memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits));
450 }
451
452 info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f);
453 if (info.pagenum < 0x100)
454 info.pagenum += 0x800;
455 info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f);
456 info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f);
457 info.charset = ((infobits[7] >> 1) & 7);
458 info.delete = !!(infobits[3] & 8);
459 info.headline = !!(infobits[5] & 4);
460 info.subtitle = !!(infobits[5] & 8);
461 info.supp_header = !!(infobits[6] & 1);
462 info.update = !!(infobits[6] & 2);
463 info.inter_seq = !!(infobits[6] & 4);
464 info.dis_disp = !!(infobits[6] & 8);
465 info.serial = !!(infobits[7] & 1);
466 info.notfound = !!(infobits[8] & 0x10);
467 info.pblf = !!(infobits[9] & 0x20);
468 info.hamming = 0;
469 for (a = 0; a <= 7; a++)
470 {
471 if (infobits[a] & 0xf0)
472 {
473 info.hamming = 1;
474 break;
475 }
476 }
477 if (t->vdau[req->pgbuf].clrfound)
478 info.notfound = 1;
479 if(copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t)))
480 return -EFAULT;
481 if (!info.hamming && !info.notfound)
482 {
483 t->is_searching[req->pgbuf] = FALSE;
484 }
485 return 0;
486 }
487
488 case VTXIOCGETPAGE:
489 {
490 vtx_pagereq_t *req = arg;
491 int start, end;
492
493 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 ||
494 req->start > req->end || req->end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE))
495 return -EINVAL;
496 if(copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1))
497 return -EFAULT;
498
499 /*
500 * Always read the time directly from SAA5249
501 */
502
503 if (req->start <= 39 && req->end >= 32)
504 {
505 int len;
506 char buf[16];
507 start = max(req->start, 32);
508 end = min(req->end, 39);
509 len=end-start+1;
510 if (i2c_senddata(t, 8, 0, 0, start, -1) ||
511 i2c_getdata(t, len, buf))
512 return -EIO;
513 if(copy_to_user(req->buffer+start-req->start, buf, len))
514 return -EFAULT;
515 }
516 /* Insert the current header if DAU is still searching for a page */
517 if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf])
518 {
519 char buf[32];
520 int len;
521 start = max(req->start, 7);
522 end = min(req->end, 31);
523 len=end-start+1;
524 if (i2c_senddata(t, 8, 0, 0, start, -1) ||
525 i2c_getdata(t, len, buf))
526 return -EIO;
527 if(copy_to_user(req->buffer+start-req->start, buf, len))
528 return -EFAULT;
529 }
530 return 0;
531 }
532
533 case VTXIOCSTOPDAU:
534 {
535 vtx_pagereq_t *req = arg;
536
537 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
538 return -EINVAL;
539 t->vdau[req->pgbuf].stopped = TRUE;
540 t->is_searching[req->pgbuf] = FALSE;
541 return 0;
542 }
543
544 case VTXIOCPUTPAGE:
545 case VTXIOCSETDISP:
546 case VTXIOCPUTSTAT:
547 return 0;
548
549 case VTXIOCCLRCACHE:
550 {
551 if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11,
552 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
553 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1))
554 return -EIO;
555 if (i2c_senddata(t, 3, 0x20, -1))
556 return -EIO;
557 jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */
558 return 0;
559 }
560
561 case VTXIOCSETVIRT:
562 {
563 /* The SAA5249 has virtual-row reception turned on always */
564 t->virtual_mode = (int)(long)arg;
565 return 0;
566 }
567 }
568 return -EINVAL;
569}
570
571/*
572 * Translates old vtx IOCTLs to new ones
573 *
574 * This keeps new kernel versions compatible with old userspace programs.
575 */
576static inline unsigned int vtx_fix_command(unsigned int cmd)
577{
578 switch (cmd) {
579 case VTXIOCGETINFO_OLD:
580 cmd = VTXIOCGETINFO;
581 break;
582 case VTXIOCCLRPAGE_OLD:
583 cmd = VTXIOCCLRPAGE;
584 break;
585 case VTXIOCCLRFOUND_OLD:
586 cmd = VTXIOCCLRFOUND;
587 break;
588 case VTXIOCPAGEREQ_OLD:
589 cmd = VTXIOCPAGEREQ;
590 break;
591 case VTXIOCGETSTAT_OLD:
592 cmd = VTXIOCGETSTAT;
593 break;
594 case VTXIOCGETPAGE_OLD:
595 cmd = VTXIOCGETPAGE;
596 break;
597 case VTXIOCSTOPDAU_OLD:
598 cmd = VTXIOCSTOPDAU;
599 break;
600 case VTXIOCPUTPAGE_OLD:
601 cmd = VTXIOCPUTPAGE;
602 break;
603 case VTXIOCSETDISP_OLD:
604 cmd = VTXIOCSETDISP;
605 break;
606 case VTXIOCPUTSTAT_OLD:
607 cmd = VTXIOCPUTSTAT;
608 break;
609 case VTXIOCCLRCACHE_OLD:
610 cmd = VTXIOCCLRCACHE;
611 break;
612 case VTXIOCSETVIRT_OLD:
613 cmd = VTXIOCSETVIRT;
614 break;
615 }
616 return cmd;
617}
618
619/*
620 * Handle the locking
621 */
622
623static int saa5249_ioctl(struct inode *inode, struct file *file,
624 unsigned int cmd, unsigned long arg)
625{
626 struct video_device *vd = video_devdata(file);
627 struct saa5249_device *t=vd->priv;
628 int err;
629
630 cmd = vtx_fix_command(cmd);
631 down(&t->lock);
632 err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl);
633 up(&t->lock);
634 return err;
635}
636
637static int saa5249_open(struct inode *inode, struct file *file)
638{
639 struct video_device *vd = video_devdata(file);
640 struct saa5249_device *t=vd->priv;
641 int err,pgbuf;
642
643 err = video_exclusive_open(inode,file);
644 if (err < 0)
645 return err;
646
647 if (t->client==NULL) {
648 err = -ENODEV;
649 goto fail;
650 }
651
652 if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */
653 /* Turn off parity checks (we do this ourselves) */
654 i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) ||
655 /* Display TV-picture, no virtual rows */
656 i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
657
658 {
659 err = -EIO;
660 goto fail;
661 }
662
663 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
664 {
665 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
666 memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
667 memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
668 t->vdau[pgbuf].expire = 0;
669 t->vdau[pgbuf].clrfound = TRUE;
670 t->vdau[pgbuf].stopped = TRUE;
671 t->is_searching[pgbuf] = FALSE;
672 }
673 t->virtual_mode=FALSE;
674 return 0;
675
676 fail:
677 video_exclusive_release(inode,file);
678 return err;
679}
680
681
682
683static int saa5249_release(struct inode *inode, struct file *file)
684{
685 struct video_device *vd = video_devdata(file);
686 struct saa5249_device *t=vd->priv;
687 i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */
688 i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */
689 video_exclusive_release(inode,file);
690 return 0;
691}
692
693static int __init init_saa_5249 (void)
694{
695 printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n",
696 VTX_VER_MAJ, VTX_VER_MIN);
697 return i2c_add_driver(&i2c_driver_videotext);
698}
699
700static void __exit cleanup_saa_5249 (void)
701{
702 i2c_del_driver(&i2c_driver_videotext);
703}
704
705module_init(init_saa_5249);
706module_exit(cleanup_saa_5249);
707
708static struct file_operations saa_fops = {
709 .owner = THIS_MODULE,
710 .open = saa5249_open,
711 .release = saa5249_release,
712 .ioctl = saa5249_ioctl,
713 .llseek = no_llseek,
714};
715
716static struct video_device saa_template =
717{
718 .owner = THIS_MODULE,
719 .name = IF_NAME,
720 .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */
721 .hardware = VID_HARDWARE_SAA5249,
722 .fops = &saa_fops,
723};
724
725MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
new file mode 100644
index 000000000000..64273b438530
--- /dev/null
+++ b/drivers/media/video/saa7110.c
@@ -0,0 +1,623 @@
1/*
2 * saa7110 - Philips SAA7110(A) video decoder driver
3 *
4 * Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
5 *
6 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
7 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
8 * - some corrections for Pinnacle Systems Inc. DC10plus card.
9 *
10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/wait.h>
34#include <asm/io.h>
35#include <asm/uaccess.h>
36
37MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
38MODULE_AUTHOR("Pauline Middelink");
39MODULE_LICENSE("GPL");
40
41#include <linux/i2c.h>
42#include <linux/i2c-dev.h>
43
44#define I2C_NAME(s) (s)->name
45
46#include <linux/videodev.h>
47#include <linux/video_decoder.h>
48
49static int debug = 0;
50module_param(debug, int, 0);
51MODULE_PARM_DESC(debug, "Debug level (0-1)");
52
53#define dprintk(num, format, args...) \
54 do { \
55 if (debug >= num) \
56 printk(format, ##args); \
57 } while (0)
58
59#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
60#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */
61
62#define I2C_SAA7110 0x9C /* or 0x9E */
63
64#define SAA7110_NR_REG 0x35
65
66struct saa7110 {
67 u8 reg[SAA7110_NR_REG];
68
69 int norm;
70 int input;
71 int enable;
72 int bright;
73 int contrast;
74 int hue;
75 int sat;
76
77 wait_queue_head_t wq;
78};
79
80/* ----------------------------------------------------------------------- */
81/* I2C support functions */
82/* ----------------------------------------------------------------------- */
83
84static int
85saa7110_write (struct i2c_client *client,
86 u8 reg,
87 u8 value)
88{
89 struct saa7110 *decoder = i2c_get_clientdata(client);
90
91 decoder->reg[reg] = value;
92 return i2c_smbus_write_byte_data(client, reg, value);
93}
94
95static int
96saa7110_write_block (struct i2c_client *client,
97 const u8 *data,
98 unsigned int len)
99{
100 int ret = -1;
101 u8 reg = *data; /* first register to write to */
102
103 /* Sanity check */
104 if (reg + (len - 1) > SAA7110_NR_REG)
105 return ret;
106
107 /* the saa7110 has an autoincrement function, use it if
108 * the adapter understands raw I2C */
109 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
110 struct saa7110 *decoder = i2c_get_clientdata(client);
111 struct i2c_msg msg;
112
113 msg.len = len;
114 msg.buf = (char *) data;
115 msg.addr = client->addr;
116 msg.flags = 0;
117 ret = i2c_transfer(client->adapter, &msg, 1);
118
119 /* Cache the written data */
120 memcpy(decoder->reg + reg, data + 1, len - 1);
121 } else {
122 for (++data, --len; len; len--) {
123 if ((ret = saa7110_write(client, reg++,
124 *data++)) < 0)
125 break;
126 }
127 }
128
129 return ret;
130}
131
132static inline int
133saa7110_read (struct i2c_client *client)
134{
135 return i2c_smbus_read_byte(client);
136}
137
138/* ----------------------------------------------------------------------- */
139/* SAA7110 functions */
140/* ----------------------------------------------------------------------- */
141
142#define FRESP_06H_COMPST 0x03 //0x13
143#define FRESP_06H_SVIDEO 0x83 //0xC0
144
145
146static int
147saa7110_selmux (struct i2c_client *client,
148 int chan)
149{
150 static const unsigned char modes[9][8] = {
151 /* mode 0 */
152 {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
153 0x44, 0x75, 0x16},
154 /* mode 1 */
155 {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
156 0x44, 0x75, 0x16},
157 /* mode 2 */
158 {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
159 0x60, 0xB5, 0x05},
160 /* mode 3 */
161 {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
162 0x60, 0xB5, 0x05},
163 /* mode 4 */
164 {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
165 0x60, 0xB5, 0x03},
166 /* mode 5 */
167 {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
168 0x60, 0xB5, 0x03},
169 /* mode 6 */
170 {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
171 0x44, 0x75, 0x12},
172 /* mode 7 */
173 {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
174 0x60, 0xB5, 0x14},
175 /* mode 8 */
176 {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
177 0x44, 0x75, 0x21}
178 };
179 struct saa7110 *decoder = i2c_get_clientdata(client);
180 const unsigned char *ptr = modes[chan];
181
182 saa7110_write(client, 0x06, ptr[0]); /* Luminance control */
183 saa7110_write(client, 0x20, ptr[1]); /* Analog Control #1 */
184 saa7110_write(client, 0x21, ptr[2]); /* Analog Control #2 */
185 saa7110_write(client, 0x22, ptr[3]); /* Mixer Control #1 */
186 saa7110_write(client, 0x2C, ptr[4]); /* Mixer Control #2 */
187 saa7110_write(client, 0x30, ptr[5]); /* ADCs gain control */
188 saa7110_write(client, 0x31, ptr[6]); /* Mixer Control #3 */
189 saa7110_write(client, 0x21, ptr[7]); /* Analog Control #2 */
190 decoder->input = chan;
191
192 return 0;
193}
194
195static const unsigned char initseq[1 + SAA7110_NR_REG] = {
196 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
197 /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
198 /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
199 /* 0x18 */ 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 /* 0x20 */ 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
201 /* 0x28 */ 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
202 /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
203};
204
205static int
206determine_norm (struct i2c_client *client)
207{
208 DEFINE_WAIT(wait);
209 struct saa7110 *decoder = i2c_get_clientdata(client);
210 int status;
211
212 /* mode changed, start automatic detection */
213 saa7110_write_block(client, initseq, sizeof(initseq));
214 saa7110_selmux(client, decoder->input);
215 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
216 schedule_timeout(HZ/4);
217 finish_wait(&decoder->wq, &wait);
218 status = saa7110_read(client);
219 if (status & 0x40) {
220 dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
221 I2C_NAME(client), status);
222 return decoder->norm; // no change
223 }
224 if ((status & 3) == 0) {
225 saa7110_write(client, 0x06, 0x83);
226 if (status & 0x20) {
227 dprintk(1,
228 KERN_INFO
229 "%s: status=0x%02x (NTSC/no color)\n",
230 I2C_NAME(client), status);
231 //saa7110_write(client,0x2E,0x81);
232 return VIDEO_MODE_NTSC;
233 }
234 dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
235 I2C_NAME(client), status);
236 //saa7110_write(client,0x2E,0x9A);
237 return VIDEO_MODE_PAL;
238 }
239 //saa7110_write(client,0x06,0x03);
240 if (status & 0x20) { /* 60Hz */
241 dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
242 I2C_NAME(client), status);
243 saa7110_write(client, 0x0D, 0x86);
244 saa7110_write(client, 0x0F, 0x50);
245 saa7110_write(client, 0x11, 0x2C);
246 //saa7110_write(client,0x2E,0x81);
247 return VIDEO_MODE_NTSC;
248 }
249
250 /* 50Hz -> PAL/SECAM */
251 saa7110_write(client, 0x0D, 0x86);
252 saa7110_write(client, 0x0F, 0x10);
253 saa7110_write(client, 0x11, 0x59);
254 //saa7110_write(client,0x2E,0x9A);
255
256 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
257 schedule_timeout(HZ/4);
258 finish_wait(&decoder->wq, &wait);
259
260 status = saa7110_read(client);
261 if ((status & 0x03) == 0x01) {
262 dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
263 I2C_NAME(client), status);
264 saa7110_write(client, 0x0D, 0x87);
265 return VIDEO_MODE_SECAM;
266 }
267 dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
268 status);
269 return VIDEO_MODE_PAL;
270}
271
272static int
273saa7110_command (struct i2c_client *client,
274 unsigned int cmd,
275 void *arg)
276{
277 struct saa7110 *decoder = i2c_get_clientdata(client);
278 int v;
279
280 switch (cmd) {
281 case 0:
282 //saa7110_write_block(client, initseq, sizeof(initseq));
283 break;
284
285 case DECODER_GET_CAPABILITIES:
286 {
287 struct video_decoder_capability *dc = arg;
288
289 dc->flags =
290 VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
291 VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
292 dc->inputs = SAA7110_MAX_INPUT;
293 dc->outputs = SAA7110_MAX_OUTPUT;
294 }
295 break;
296
297 case DECODER_GET_STATUS:
298 {
299 int status;
300 int res = 0;
301
302 status = saa7110_read(client);
303 dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
304 I2C_NAME(client), status, decoder->norm);
305 if (!(status & 0x40))
306 res |= DECODER_STATUS_GOOD;
307 if (status & 0x03)
308 res |= DECODER_STATUS_COLOR;
309
310 switch (decoder->norm) {
311 case VIDEO_MODE_NTSC:
312 res |= DECODER_STATUS_NTSC;
313 break;
314 case VIDEO_MODE_PAL:
315 res |= DECODER_STATUS_PAL;
316 break;
317 case VIDEO_MODE_SECAM:
318 res |= DECODER_STATUS_SECAM;
319 break;
320 }
321 *(int *) arg = res;
322 }
323 break;
324
325 case DECODER_SET_NORM:
326 v = *(int *) arg;
327 if (decoder->norm != v) {
328 decoder->norm = v;
329 //saa7110_write(client, 0x06, 0x03);
330 switch (v) {
331 case VIDEO_MODE_NTSC:
332 saa7110_write(client, 0x0D, 0x86);
333 saa7110_write(client, 0x0F, 0x50);
334 saa7110_write(client, 0x11, 0x2C);
335 //saa7110_write(client, 0x2E, 0x81);
336 dprintk(1,
337 KERN_INFO "%s: switched to NTSC\n",
338 I2C_NAME(client));
339 break;
340 case VIDEO_MODE_PAL:
341 saa7110_write(client, 0x0D, 0x86);
342 saa7110_write(client, 0x0F, 0x10);
343 saa7110_write(client, 0x11, 0x59);
344 //saa7110_write(client, 0x2E, 0x9A);
345 dprintk(1,
346 KERN_INFO "%s: switched to PAL\n",
347 I2C_NAME(client));
348 break;
349 case VIDEO_MODE_SECAM:
350 saa7110_write(client, 0x0D, 0x87);
351 saa7110_write(client, 0x0F, 0x10);
352 saa7110_write(client, 0x11, 0x59);
353 //saa7110_write(client, 0x2E, 0x9A);
354 dprintk(1,
355 KERN_INFO
356 "%s: switched to SECAM\n",
357 I2C_NAME(client));
358 break;
359 case VIDEO_MODE_AUTO:
360 dprintk(1,
361 KERN_INFO
362 "%s: TV standard detection...\n",
363 I2C_NAME(client));
364 decoder->norm = determine_norm(client);
365 *(int *) arg = decoder->norm;
366 break;
367 default:
368 return -EPERM;
369 }
370 }
371 break;
372
373 case DECODER_SET_INPUT:
374 v = *(int *) arg;
375 if (v < 0 || v > SAA7110_MAX_INPUT) {
376 dprintk(1,
377 KERN_INFO "%s: input=%d not available\n",
378 I2C_NAME(client), v);
379 return -EINVAL;
380 }
381 if (decoder->input != v) {
382 saa7110_selmux(client, v);
383 dprintk(1, KERN_INFO "%s: switched to input=%d\n",
384 I2C_NAME(client), v);
385 }
386 break;
387
388 case DECODER_SET_OUTPUT:
389 v = *(int *) arg;
390 /* not much choice of outputs */
391 if (v != 0)
392 return -EINVAL;
393 break;
394
395 case DECODER_ENABLE_OUTPUT:
396 v = *(int *) arg;
397 if (decoder->enable != v) {
398 decoder->enable = v;
399 saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
400 dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
401 v ? "on" : "off");
402 }
403 break;
404
405 case DECODER_SET_PICTURE:
406 {
407 struct video_picture *pic = arg;
408
409 if (decoder->bright != pic->brightness) {
410 /* We want 0 to 255 we get 0-65535 */
411 decoder->bright = pic->brightness;
412 saa7110_write(client, 0x19, decoder->bright >> 8);
413 }
414 if (decoder->contrast != pic->contrast) {
415 /* We want 0 to 127 we get 0-65535 */
416 decoder->contrast = pic->contrast;
417 saa7110_write(client, 0x13,
418 decoder->contrast >> 9);
419 }
420 if (decoder->sat != pic->colour) {
421 /* We want 0 to 127 we get 0-65535 */
422 decoder->sat = pic->colour;
423 saa7110_write(client, 0x12, decoder->sat >> 9);
424 }
425 if (decoder->hue != pic->hue) {
426 /* We want -128 to 127 we get 0-65535 */
427 decoder->hue = pic->hue;
428 saa7110_write(client, 0x07,
429 (decoder->hue >> 8) - 128);
430 }
431 }
432 break;
433
434 case DECODER_DUMP:
435 for (v = 0; v < 0x34; v += 16) {
436 int j;
437 dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client),
438 v);
439 for (j = 0; j < 16; j++) {
440 dprintk(1, KERN_INFO " %02x",
441 decoder->reg[v + j]);
442 }
443 dprintk(1, KERN_INFO "\n");
444 }
445 break;
446
447 default:
448 dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
449 cmd);
450 return -EINVAL;
451 }
452 return 0;
453}
454
455/* ----------------------------------------------------------------------- */
456
457/*
458 * Generic i2c probe
459 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
460 */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7110 >> 1,
463 (I2C_SAA7110 >> 1) + 1,
464 I2C_CLIENT_END
465};
466static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
467
468static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
469static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
470static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
471static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
472static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
473
474static struct i2c_client_address_data addr_data = {
475 .normal_i2c = normal_i2c,
476 .normal_i2c_range = normal_i2c_range,
477 .probe = probe,
478 .probe_range = probe_range,
479 .ignore = ignore,
480 .ignore_range = ignore_range,
481 .force = force
482};
483
484static struct i2c_driver i2c_driver_saa7110;
485
486static int
487saa7110_detect_client (struct i2c_adapter *adapter,
488 int address,
489 int kind)
490{
491 struct i2c_client *client;
492 struct saa7110 *decoder;
493 int rv;
494
495 dprintk(1,
496 KERN_INFO
497 "saa7110.c: detecting saa7110 client on address 0x%x\n",
498 address << 1);
499
500 /* Check if the adapter supports the needed features */
501 if (!i2c_check_functionality
502 (adapter,
503 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
504 return 0;
505
506 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
507 if (client == 0)
508 return -ENOMEM;
509 memset(client, 0, sizeof(struct i2c_client));
510 client->addr = address;
511 client->adapter = adapter;
512 client->driver = &i2c_driver_saa7110;
513 client->flags = I2C_CLIENT_ALLOW_USE;
514 strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
515
516 decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
517 if (decoder == 0) {
518 kfree(client);
519 return -ENOMEM;
520 }
521 memset(decoder, 0, sizeof(struct saa7110));
522 decoder->norm = VIDEO_MODE_PAL;
523 decoder->input = 0;
524 decoder->enable = 1;
525 decoder->bright = 32768;
526 decoder->contrast = 32768;
527 decoder->hue = 32768;
528 decoder->sat = 32768;
529 init_waitqueue_head(&decoder->wq);
530 i2c_set_clientdata(client, decoder);
531
532 rv = i2c_attach_client(client);
533 if (rv) {
534 kfree(client);
535 kfree(decoder);
536 return rv;
537 }
538
539 rv = saa7110_write_block(client, initseq, sizeof(initseq));
540 if (rv < 0)
541 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
542 I2C_NAME(client), rv);
543 else {
544 int ver, status;
545 saa7110_write(client, 0x21, 0x10);
546 saa7110_write(client, 0x0e, 0x18);
547 saa7110_write(client, 0x0D, 0x04);
548 ver = saa7110_read(client);
549 saa7110_write(client, 0x0D, 0x06);
550 //mdelay(150);
551 status = saa7110_read(client);
552 dprintk(1,
553 KERN_INFO
554 "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
555 I2C_NAME(client), ver, client->addr << 1, status);
556 saa7110_write(client, 0x0D, 0x86);
557 saa7110_write(client, 0x0F, 0x10);
558 saa7110_write(client, 0x11, 0x59);
559 //saa7110_write(client, 0x2E, 0x9A);
560 }
561
562 //saa7110_selmux(client,0);
563 //determine_norm(client);
564 /* setup and implicit mode 0 select has been performed */
565
566 return 0;
567}
568
569static int
570saa7110_attach_adapter (struct i2c_adapter *adapter)
571{
572 dprintk(1,
573 KERN_INFO
574 "saa7110.c: starting probe for adapter %s (0x%x)\n",
575 I2C_NAME(adapter), adapter->id);
576 return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
577}
578
579static int
580saa7110_detach_client (struct i2c_client *client)
581{
582 struct saa7110 *decoder = i2c_get_clientdata(client);
583 int err;
584
585 err = i2c_detach_client(client);
586 if (err) {
587 return err;
588 }
589
590 kfree(decoder);
591 kfree(client);
592
593 return 0;
594}
595
596/* ----------------------------------------------------------------------- */
597
598static struct i2c_driver i2c_driver_saa7110 = {
599 .owner = THIS_MODULE,
600 .name = "saa7110",
601
602 .id = I2C_DRIVERID_SAA7110,
603 .flags = I2C_DF_NOTIFY,
604
605 .attach_adapter = saa7110_attach_adapter,
606 .detach_client = saa7110_detach_client,
607 .command = saa7110_command,
608};
609
610static int __init
611saa7110_init (void)
612{
613 return i2c_add_driver(&i2c_driver_saa7110);
614}
615
616static void __exit
617saa7110_exit (void)
618{
619 i2c_del_driver(&i2c_driver_saa7110);
620}
621
622module_init(saa7110_init);
623module_exit(saa7110_exit);
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
new file mode 100644
index 000000000000..0a873112ae23
--- /dev/null
+++ b/drivers/media/video/saa7111.c
@@ -0,0 +1,627 @@
1/*
2 * saa7111 - Philips SAA7111A video decoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 *
6 * Slight changes for video timing and attachment output by
7 * Wolfgang Scherr <scherr@net4you.net>
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
11 *
12 * Changes by Michael Hunold <michael@mihu.de>
13 * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/errno.h>
34#include <linux/fs.h>
35#include <linux/kernel.h>
36#include <linux/major.h>
37#include <linux/slab.h>
38#include <linux/mm.h>
39#include <linux/pci.h>
40#include <linux/signal.h>
41#include <asm/io.h>
42#include <asm/pgtable.h>
43#include <asm/page.h>
44#include <linux/sched.h>
45#include <asm/segment.h>
46#include <linux/types.h>
47
48#include <linux/videodev.h>
49#include <asm/uaccess.h>
50
51MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
52MODULE_AUTHOR("Dave Perks");
53MODULE_LICENSE("GPL");
54
55#include <linux/i2c.h>
56#include <linux/i2c-dev.h>
57
58#define I2C_NAME(s) (s)->name
59
60#include <linux/video_decoder.h>
61
62static int debug = 0;
63module_param(debug, int, 0644);
64MODULE_PARM_DESC(debug, "Debug level (0-1)");
65
66#define dprintk(num, format, args...) \
67 do { \
68 if (debug >= num) \
69 printk(format, ##args); \
70 } while (0)
71
72/* ----------------------------------------------------------------------- */
73
74struct saa7111 {
75 unsigned char reg[32];
76
77 int norm;
78 int input;
79 int enable;
80 int bright;
81 int contrast;
82 int hue;
83 int sat;
84};
85
86#define I2C_SAA7111 0x48
87
88/* ----------------------------------------------------------------------- */
89
90static inline int
91saa7111_write (struct i2c_client *client,
92 u8 reg,
93 u8 value)
94{
95 struct saa7111 *decoder = i2c_get_clientdata(client);
96
97 decoder->reg[reg] = value;
98 return i2c_smbus_write_byte_data(client, reg, value);
99}
100
101static int
102saa7111_write_block (struct i2c_client *client,
103 const u8 *data,
104 unsigned int len)
105{
106 int ret = -1;
107 u8 reg;
108
109 /* the saa7111 has an autoincrement function, use it if
110 * the adapter understands raw I2C */
111 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
112 /* do raw I2C, not smbus compatible */
113 struct saa7111 *decoder = i2c_get_clientdata(client);
114 struct i2c_msg msg;
115 u8 block_data[32];
116
117 msg.addr = client->addr;
118 msg.flags = 0;
119 while (len >= 2) {
120 msg.buf = (char *) block_data;
121 msg.len = 0;
122 block_data[msg.len++] = reg = data[0];
123 do {
124 block_data[msg.len++] =
125 decoder->reg[reg++] = data[1];
126 len -= 2;
127 data += 2;
128 } while (len >= 2 && data[0] == reg &&
129 msg.len < 32);
130 if ((ret = i2c_transfer(client->adapter,
131 &msg, 1)) < 0)
132 break;
133 }
134 } else {
135 /* do some slow I2C emulation kind of thing */
136 while (len >= 2) {
137 reg = *data++;
138 if ((ret = saa7111_write(client, reg,
139 *data++)) < 0)
140 break;
141 len -= 2;
142 }
143 }
144
145 return ret;
146}
147
148static int
149saa7111_init_decoder (struct i2c_client *client,
150 struct video_decoder_init *init)
151{
152 return saa7111_write_block(client, init->data, init->len);
153}
154
155static inline int
156saa7111_read (struct i2c_client *client,
157 u8 reg)
158{
159 return i2c_smbus_read_byte_data(client, reg);
160}
161
162/* ----------------------------------------------------------------------- */
163
164static const unsigned char saa7111_i2c_init[] = {
165 0x00, 0x00, /* 00 - ID byte */
166 0x01, 0x00, /* 01 - reserved */
167
168 /*front end */
169 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
170 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
171 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
172 0x04, 0x00, /* 04 - GAI1=256 */
173 0x05, 0x00, /* 05 - GAI2=256 */
174
175 /* decoder */
176 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz)
177 * pixels after end of last line */
178 /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
179 * after end of last line */
180 0x07, 0xe8, /* 07 - HSS seems to be needed to
181 * work with NTSC, too */
182 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0,
183 * VTRC=1, HPLL=0, VNOI=0 */
184 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0,
185 * VBLB=0, UPTCV=0, APER=1 */
186 0x0a, 0x80, /* 0a - BRIG=128 */
187 0x0b, 0x47, /* 0b - CONT=1.109 */
188 0x0c, 0x40, /* 0c - SATN=1.0 */
189 0x0d, 0x00, /* 0d - HUE=0 */
190 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
191 * FCTC=0, CHBW=1 */
192 0x0f, 0x00, /* 0f - reserved */
193 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
194 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
195 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
196 0x12, 0x00, /* 12 - output control 2 */
197 0x13, 0x00, /* 13 - output control 3 */
198 0x14, 0x00, /* 14 - reserved */
199 0x15, 0x00, /* 15 - VBI */
200 0x16, 0x00, /* 16 - VBI */
201 0x17, 0x00, /* 17 - VBI */
202};
203
204static int
205saa7111_command (struct i2c_client *client,
206 unsigned int cmd,
207 void *arg)
208{
209 struct saa7111 *decoder = i2c_get_clientdata(client);
210
211 switch (cmd) {
212
213 case 0:
214 case DECODER_INIT:
215 {
216 struct video_decoder_init *init = arg;
217 if (NULL != init)
218 return saa7111_init_decoder(client, init);
219 else {
220 struct video_decoder_init vdi;
221 vdi.data = saa7111_i2c_init;
222 vdi.len = sizeof(saa7111_i2c_init);
223 return saa7111_init_decoder(client, &vdi);
224 }
225 }
226
227 case DECODER_DUMP:
228 {
229 int i;
230
231 for (i = 0; i < 32; i += 16) {
232 int j;
233
234 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
235 for (j = 0; j < 16; ++j) {
236 printk(" %02x",
237 saa7111_read(client, i + j));
238 }
239 printk("\n");
240 }
241 }
242 break;
243
244 case DECODER_GET_CAPABILITIES:
245 {
246 struct video_decoder_capability *cap = arg;
247
248 cap->flags = VIDEO_DECODER_PAL |
249 VIDEO_DECODER_NTSC |
250 VIDEO_DECODER_SECAM |
251 VIDEO_DECODER_AUTO |
252 VIDEO_DECODER_CCIR;
253 cap->inputs = 8;
254 cap->outputs = 1;
255 }
256 break;
257
258 case DECODER_GET_STATUS:
259 {
260 int *iarg = arg;
261 int status;
262 int res;
263
264 status = saa7111_read(client, 0x1f);
265 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
266 status);
267 res = 0;
268 if ((status & (1 << 6)) == 0) {
269 res |= DECODER_STATUS_GOOD;
270 }
271 switch (decoder->norm) {
272 case VIDEO_MODE_NTSC:
273 res |= DECODER_STATUS_NTSC;
274 break;
275 case VIDEO_MODE_PAL:
276 res |= DECODER_STATUS_PAL;
277 break;
278 case VIDEO_MODE_SECAM:
279 res |= DECODER_STATUS_SECAM;
280 break;
281 default:
282 case VIDEO_MODE_AUTO:
283 if ((status & (1 << 5)) != 0) {
284 res |= DECODER_STATUS_NTSC;
285 } else {
286 res |= DECODER_STATUS_PAL;
287 }
288 break;
289 }
290 if ((status & (1 << 0)) != 0) {
291 res |= DECODER_STATUS_COLOR;
292 }
293 *iarg = res;
294 }
295 break;
296
297 case DECODER_SET_GPIO:
298 {
299 int *iarg = arg;
300 if (0 != *iarg) {
301 saa7111_write(client, 0x11,
302 (decoder->reg[0x11] | 0x80));
303 } else {
304 saa7111_write(client, 0x11,
305 (decoder->reg[0x11] & 0x7f));
306 }
307 break;
308 }
309
310 case DECODER_SET_VBI_BYPASS:
311 {
312 int *iarg = arg;
313 if (0 != *iarg) {
314 saa7111_write(client, 0x13,
315 (decoder->reg[0x13] & 0xf0) | 0x0a);
316 } else {
317 saa7111_write(client, 0x13,
318 (decoder->reg[0x13] & 0xf0));
319 }
320 break;
321 }
322
323 case DECODER_SET_NORM:
324 {
325 int *iarg = arg;
326
327 switch (*iarg) {
328
329 case VIDEO_MODE_NTSC:
330 saa7111_write(client, 0x08,
331 (decoder->reg[0x08] & 0x3f) | 0x40);
332 saa7111_write(client, 0x0e,
333 (decoder->reg[0x0e] & 0x8f));
334 break;
335
336 case VIDEO_MODE_PAL:
337 saa7111_write(client, 0x08,
338 (decoder->reg[0x08] & 0x3f) | 0x00);
339 saa7111_write(client, 0x0e,
340 (decoder->reg[0x0e] & 0x8f));
341 break;
342
343 case VIDEO_MODE_SECAM:
344 saa7111_write(client, 0x08,
345 (decoder->reg[0x08] & 0x3f) | 0x00);
346 saa7111_write(client, 0x0e,
347 (decoder->reg[0x0e] & 0x8f) | 0x50);
348 break;
349
350 case VIDEO_MODE_AUTO:
351 saa7111_write(client, 0x08,
352 (decoder->reg[0x08] & 0x3f) | 0x80);
353 saa7111_write(client, 0x0e,
354 (decoder->reg[0x0e] & 0x8f));
355 break;
356
357 default:
358 return -EINVAL;
359
360 }
361 decoder->norm = *iarg;
362 }
363 break;
364
365 case DECODER_SET_INPUT:
366 {
367 int *iarg = arg;
368
369 if (*iarg < 0 || *iarg > 7) {
370 return -EINVAL;
371 }
372
373 if (decoder->input != *iarg) {
374 decoder->input = *iarg;
375 /* select mode */
376 saa7111_write(client, 0x02,
377 (decoder->
378 reg[0x02] & 0xf8) | decoder->input);
379 /* bypass chrominance trap for modes 4..7 */
380 saa7111_write(client, 0x09,
381 (decoder->
382 reg[0x09] & 0x7f) | ((decoder->
383 input >
384 3) ? 0x80 :
385 0));
386 }
387 }
388 break;
389
390 case DECODER_SET_OUTPUT:
391 {
392 int *iarg = arg;
393
394 /* not much choice of outputs */
395 if (*iarg != 0) {
396 return -EINVAL;
397 }
398 }
399 break;
400
401 case DECODER_ENABLE_OUTPUT:
402 {
403 int *iarg = arg;
404 int enable = (*iarg != 0);
405
406 if (decoder->enable != enable) {
407 decoder->enable = enable;
408
409 /* RJ: If output should be disabled (for
410 * playing videos), we also need a open PLL.
411 * The input is set to 0 (where no input
412 * source is connected), although this
413 * is not necessary.
414 *
415 * If output should be enabled, we have to
416 * reverse the above.
417 */
418
419 if (decoder->enable) {
420 saa7111_write(client, 0x02,
421 (decoder->
422 reg[0x02] & 0xf8) |
423 decoder->input);
424 saa7111_write(client, 0x08,
425 (decoder->reg[0x08] & 0xfb));
426 saa7111_write(client, 0x11,
427 (decoder->
428 reg[0x11] & 0xf3) | 0x0c);
429 } else {
430 saa7111_write(client, 0x02,
431 (decoder->reg[0x02] & 0xf8));
432 saa7111_write(client, 0x08,
433 (decoder->
434 reg[0x08] & 0xfb) | 0x04);
435 saa7111_write(client, 0x11,
436 (decoder->reg[0x11] & 0xf3));
437 }
438 }
439 }
440 break;
441
442 case DECODER_SET_PICTURE:
443 {
444 struct video_picture *pic = arg;
445
446 if (decoder->bright != pic->brightness) {
447 /* We want 0 to 255 we get 0-65535 */
448 decoder->bright = pic->brightness;
449 saa7111_write(client, 0x0a, decoder->bright >> 8);
450 }
451 if (decoder->contrast != pic->contrast) {
452 /* We want 0 to 127 we get 0-65535 */
453 decoder->contrast = pic->contrast;
454 saa7111_write(client, 0x0b,
455 decoder->contrast >> 9);
456 }
457 if (decoder->sat != pic->colour) {
458 /* We want 0 to 127 we get 0-65535 */
459 decoder->sat = pic->colour;
460 saa7111_write(client, 0x0c, decoder->sat >> 9);
461 }
462 if (decoder->hue != pic->hue) {
463 /* We want -128 to 127 we get 0-65535 */
464 decoder->hue = pic->hue;
465 saa7111_write(client, 0x0d,
466 (decoder->hue - 32768) >> 8);
467 }
468 }
469 break;
470
471 default:
472 return -EINVAL;
473 }
474
475 return 0;
476}
477
478/* ----------------------------------------------------------------------- */
479
480/*
481 * Generic i2c probe
482 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
483 */
484static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
485static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
486
487static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
488static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
489static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
490static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
491static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
492
493static struct i2c_client_address_data addr_data = {
494 .normal_i2c = normal_i2c,
495 .normal_i2c_range = normal_i2c_range,
496 .probe = probe,
497 .probe_range = probe_range,
498 .ignore = ignore,
499 .ignore_range = ignore_range,
500 .force = force
501};
502
503static struct i2c_driver i2c_driver_saa7111;
504
505static int
506saa7111_detect_client (struct i2c_adapter *adapter,
507 int address,
508 int kind)
509{
510 int i;
511 struct i2c_client *client;
512 struct saa7111 *decoder;
513 struct video_decoder_init vdi;
514
515 dprintk(1,
516 KERN_INFO
517 "saa7111.c: detecting saa7111 client on address 0x%x\n",
518 address << 1);
519
520 /* Check if the adapter supports the needed features */
521 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
522 return 0;
523
524 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
525 if (client == 0)
526 return -ENOMEM;
527 memset(client, 0, sizeof(struct i2c_client));
528 client->addr = address;
529 client->adapter = adapter;
530 client->driver = &i2c_driver_saa7111;
531 client->flags = I2C_CLIENT_ALLOW_USE;
532 strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
533
534 decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
535 if (decoder == NULL) {
536 kfree(client);
537 return -ENOMEM;
538 }
539 memset(decoder, 0, sizeof(struct saa7111));
540 decoder->norm = VIDEO_MODE_NTSC;
541 decoder->input = 0;
542 decoder->enable = 1;
543 decoder->bright = 32768;
544 decoder->contrast = 32768;
545 decoder->hue = 32768;
546 decoder->sat = 32768;
547 i2c_set_clientdata(client, decoder);
548
549 i = i2c_attach_client(client);
550 if (i) {
551 kfree(client);
552 kfree(decoder);
553 return i;
554 }
555
556 vdi.data = saa7111_i2c_init;
557 vdi.len = sizeof(saa7111_i2c_init);
558 i = saa7111_init_decoder(client, &vdi);
559 if (i < 0) {
560 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
561 I2C_NAME(client), i);
562 } else {
563 dprintk(1,
564 KERN_INFO
565 "%s_attach: chip version %x at address 0x%x\n",
566 I2C_NAME(client), saa7111_read(client, 0x00) >> 4,
567 client->addr << 1);
568 }
569
570 return 0;
571}
572
573static int
574saa7111_attach_adapter (struct i2c_adapter *adapter)
575{
576 dprintk(1,
577 KERN_INFO
578 "saa7111.c: starting probe for adapter %s (0x%x)\n",
579 I2C_NAME(adapter), adapter->id);
580 return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
581}
582
583static int
584saa7111_detach_client (struct i2c_client *client)
585{
586 struct saa7111 *decoder = i2c_get_clientdata(client);
587 int err;
588
589 err = i2c_detach_client(client);
590 if (err) {
591 return err;
592 }
593
594 kfree(decoder);
595 kfree(client);
596
597 return 0;
598}
599
600/* ----------------------------------------------------------------------- */
601
602static struct i2c_driver i2c_driver_saa7111 = {
603 .owner = THIS_MODULE,
604 .name = "saa7111",
605
606 .id = I2C_DRIVERID_SAA7111A,
607 .flags = I2C_DF_NOTIFY,
608
609 .attach_adapter = saa7111_attach_adapter,
610 .detach_client = saa7111_detach_client,
611 .command = saa7111_command,
612};
613
614static int __init
615saa7111_init (void)
616{
617 return i2c_add_driver(&i2c_driver_saa7111);
618}
619
620static void __exit
621saa7111_exit (void)
622{
623 i2c_del_driver(&i2c_driver_saa7111);
624}
625
626module_init(saa7111_init);
627module_exit(saa7111_exit);
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
new file mode 100644
index 000000000000..e73023695e58
--- /dev/null
+++ b/drivers/media/video/saa7114.c
@@ -0,0 +1,1241 @@
1/*
2 * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
3 *
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
5 *
6 * Based on saa7111 driver by Dave Perks
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 *
10 * Slight changes for video timing and attachment output by
11 * Wolfgang Scherr <scherr@net4you.net>
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
15 *
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38
39#include <linux/slab.h>
40
41#include <linux/mm.h>
42#include <linux/pci.h>
43#include <linux/signal.h>
44#include <asm/io.h>
45#include <asm/pgtable.h>
46#include <asm/page.h>
47#include <linux/sched.h>
48#include <asm/segment.h>
49#include <linux/types.h>
50
51#include <linux/videodev.h>
52#include <asm/uaccess.h>
53
54MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
55MODULE_AUTHOR("Maxim Yevtyushkin");
56MODULE_LICENSE("GPL");
57
58#include <linux/i2c.h>
59#include <linux/i2c-dev.h>
60
61#define I2C_NAME(x) (x)->name
62
63#include <linux/video_decoder.h>
64
65static int debug = 0;
66module_param(debug, int, 0);
67MODULE_PARM_DESC(debug, "Debug level (0-1)");
68
69#define dprintk(num, format, args...) \
70 do { \
71 if (debug >= num) \
72 printk(format, ##args); \
73 } while (0)
74
75/* ----------------------------------------------------------------------- */
76
77struct saa7114 {
78 unsigned char reg[0xf0 * 2];
79
80 int norm;
81 int input;
82 int enable;
83 int bright;
84 int contrast;
85 int hue;
86 int sat;
87 int playback;
88};
89
90#define I2C_SAA7114 0x42
91#define I2C_SAA7114A 0x40
92
93#define I2C_DELAY 10
94
95
96//#define SAA_7114_NTSC_HSYNC_START (-3)
97//#define SAA_7114_NTSC_HSYNC_STOP (-18)
98
99#define SAA_7114_NTSC_HSYNC_START (-17)
100#define SAA_7114_NTSC_HSYNC_STOP (-32)
101
102//#define SAA_7114_NTSC_HOFFSET (5)
103#define SAA_7114_NTSC_HOFFSET (6)
104#define SAA_7114_NTSC_VOFFSET (10)
105#define SAA_7114_NTSC_WIDTH (720)
106#define SAA_7114_NTSC_HEIGHT (250)
107
108#define SAA_7114_SECAM_HSYNC_START (-17)
109#define SAA_7114_SECAM_HSYNC_STOP (-32)
110
111#define SAA_7114_SECAM_HOFFSET (2)
112#define SAA_7114_SECAM_VOFFSET (10)
113#define SAA_7114_SECAM_WIDTH (720)
114#define SAA_7114_SECAM_HEIGHT (300)
115
116#define SAA_7114_PAL_HSYNC_START (-17)
117#define SAA_7114_PAL_HSYNC_STOP (-32)
118
119#define SAA_7114_PAL_HOFFSET (2)
120#define SAA_7114_PAL_VOFFSET (10)
121#define SAA_7114_PAL_WIDTH (720)
122#define SAA_7114_PAL_HEIGHT (300)
123
124
125
126#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
127#define SAA_7114_VERTICAL_LUMA_OFFSET 0
128
129#define REG_ADDR(x) (((x) << 1) + 1)
130#define LOBYTE(x) ((unsigned char)((x) & 0xff))
131#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
132#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
133#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
134
135
136/* ----------------------------------------------------------------------- */
137
138static inline int
139saa7114_write (struct i2c_client *client,
140 u8 reg,
141 u8 value)
142{
143 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
144
145 /*decoder->reg[reg] = value;*/
146 return i2c_smbus_write_byte_data(client, reg, value);
147}
148
149static int
150saa7114_write_block (struct i2c_client *client,
151 const u8 *data,
152 unsigned int len)
153{
154 int ret = -1;
155 u8 reg;
156
157 /* the saa7114 has an autoincrement function, use it if
158 * the adapter understands raw I2C */
159 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
160 /* do raw I2C, not smbus compatible */
161 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
162 struct i2c_msg msg;
163 u8 block_data[32];
164
165 msg.addr = client->addr;
166 msg.flags = 0;
167 while (len >= 2) {
168 msg.buf = (char *) block_data;
169 msg.len = 0;
170 block_data[msg.len++] = reg = data[0];
171 do {
172 block_data[msg.len++] =
173 /*decoder->reg[reg++] =*/ data[1];
174 len -= 2;
175 data += 2;
176 } while (len >= 2 && data[0] == reg &&
177 msg.len < 32);
178 if ((ret = i2c_transfer(client->adapter,
179 &msg, 1)) < 0)
180 break;
181 }
182 } else {
183 /* do some slow I2C emulation kind of thing */
184 while (len >= 2) {
185 reg = *data++;
186 if ((ret = saa7114_write(client, reg,
187 *data++)) < 0)
188 break;
189 len -= 2;
190 }
191 }
192
193 return ret;
194}
195
196static inline int
197saa7114_read (struct i2c_client *client,
198 u8 reg)
199{
200 return i2c_smbus_read_byte_data(client, reg);
201}
202
203/* ----------------------------------------------------------------------- */
204
205// initially set NTSC, composite
206
207
208static const unsigned char init[] = {
209 0x00, 0x00, /* 00 - ID byte , chip version,
210 * read only */
211 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
212 * horizontal increment delay,
213 * recommended position */
214 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
215 * input control */
216 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
217 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
218 0x04, 0x90, /* 04 - GAI1=256 */
219 0x05, 0x90, /* 05 - GAI2=256 */
220 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
221 * depends on the video standard */
222 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
223 *on the video standard */
224 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
225 * HPLL: free running in playback, locked
226 * in capture, VNOI=0 */
227 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
228 * UPTCV=0, APER=1; depends from input */
229 0x0a, 0x80, /* 0a - BRIG=128 */
230 0x0b, 0x44, /* 0b - CONT=1.109 */
231 0x0c, 0x40, /* 0c - SATN=1.0 */
232 0x0d, 0x00, /* 0d - HUE=0 */
233 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
234 * CCOMB; depends from video standard */
235 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
236 * from video standard */
237 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
238 * LCBW2 to 0 */
239 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
240 * YDEL2 to 0 */
241 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
242 * and 03 to 00 */
243 0x13, 0x80, /* 13 - RT/X port output control */
244 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
245 0x15, 0x00, /* 15 - VGATE start FID change */
246 0x16, 0xfe, /* 16 - VGATE stop */
247 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
248 0x18, 0x40, /* RAWG */
249 0x19, 0x80, /* RAWO */
250 0x1a, 0x00,
251 0x1b, 0x00,
252 0x1c, 0x00,
253 0x1d, 0x00,
254 0x1e, 0x00,
255 0x1f, 0x00, /* status byte, read only */
256 0x20, 0x00, /* video decoder reserved part */
257 0x21, 0x00,
258 0x22, 0x00,
259 0x23, 0x00,
260 0x24, 0x00,
261 0x25, 0x00,
262 0x26, 0x00,
263 0x27, 0x00,
264 0x28, 0x00,
265 0x29, 0x00,
266 0x2a, 0x00,
267 0x2b, 0x00,
268 0x2c, 0x00,
269 0x2d, 0x00,
270 0x2e, 0x00,
271 0x2f, 0x00,
272 0x30, 0xbc, /* audio clock generator */
273 0x31, 0xdf,
274 0x32, 0x02,
275 0x33, 0x00,
276 0x34, 0xcd,
277 0x35, 0xcc,
278 0x36, 0x3a,
279 0x37, 0x00,
280 0x38, 0x03,
281 0x39, 0x10,
282 0x3a, 0x00,
283 0x3b, 0x00,
284 0x3c, 0x00,
285 0x3d, 0x00,
286 0x3e, 0x00,
287 0x3f, 0x00,
288 0x40, 0x00, /* VBI data slicer */
289 0x41, 0xff,
290 0x42, 0xff,
291 0x43, 0xff,
292 0x44, 0xff,
293 0x45, 0xff,
294 0x46, 0xff,
295 0x47, 0xff,
296 0x48, 0xff,
297 0x49, 0xff,
298 0x4a, 0xff,
299 0x4b, 0xff,
300 0x4c, 0xff,
301 0x4d, 0xff,
302 0x4e, 0xff,
303 0x4f, 0xff,
304 0x50, 0xff,
305 0x51, 0xff,
306 0x52, 0xff,
307 0x53, 0xff,
308 0x54, 0xff,
309 0x55, 0xff,
310 0x56, 0xff,
311 0x57, 0xff,
312 0x58, 0x40, // framing code
313 0x59, 0x47, // horizontal offset
314 0x5a, 0x06, // vertical offset
315 0x5b, 0x83, // field offset
316 0x5c, 0x00, // reserved
317 0x5d, 0x3e, // header and data
318 0x5e, 0x00, // sliced data
319 0x5f, 0x00, // reserved
320 0x60, 0x00, /* video decoder reserved part */
321 0x61, 0x00,
322 0x62, 0x00,
323 0x63, 0x00,
324 0x64, 0x00,
325 0x65, 0x00,
326 0x66, 0x00,
327 0x67, 0x00,
328 0x68, 0x00,
329 0x69, 0x00,
330 0x6a, 0x00,
331 0x6b, 0x00,
332 0x6c, 0x00,
333 0x6d, 0x00,
334 0x6e, 0x00,
335 0x6f, 0x00,
336 0x70, 0x00, /* video decoder reserved part */
337 0x71, 0x00,
338 0x72, 0x00,
339 0x73, 0x00,
340 0x74, 0x00,
341 0x75, 0x00,
342 0x76, 0x00,
343 0x77, 0x00,
344 0x78, 0x00,
345 0x79, 0x00,
346 0x7a, 0x00,
347 0x7b, 0x00,
348 0x7c, 0x00,
349 0x7d, 0x00,
350 0x7e, 0x00,
351 0x7f, 0x00,
352 0x80, 0x00, /* X-port, I-port and scaler */
353 0x81, 0x00,
354 0x82, 0x00,
355 0x83, 0x00,
356 0x84, 0xc5,
357 0x85, 0x0d, // hsync and vsync ?
358 0x86, 0x40,
359 0x87, 0x01,
360 0x88, 0x00,
361 0x89, 0x00,
362 0x8a, 0x00,
363 0x8b, 0x00,
364 0x8c, 0x00,
365 0x8d, 0x00,
366 0x8e, 0x00,
367 0x8f, 0x00,
368 0x90, 0x03, /* Task A definition */
369 0x91, 0x08,
370 0x92, 0x00,
371 0x93, 0x40,
372 0x94, 0x00, // window settings
373 0x95, 0x00,
374 0x96, 0x00,
375 0x97, 0x00,
376 0x98, 0x00,
377 0x99, 0x00,
378 0x9a, 0x00,
379 0x9b, 0x00,
380 0x9c, 0x00,
381 0x9d, 0x00,
382 0x9e, 0x00,
383 0x9f, 0x00,
384 0xa0, 0x01, /* horizontal integer prescaling ratio */
385 0xa1, 0x00, /* horizontal prescaler accumulation
386 * sequence length */
387 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
388 * DC gain */
389 0xa3, 0x00,
390 0xa4, 0x80, // luminance brightness
391 0xa5, 0x40, // luminance gain
392 0xa6, 0x40, // chrominance saturation
393 0xa7, 0x00,
394 0xa8, 0x00, // horizontal luminance scaling increment
395 0xa9, 0x04,
396 0xaa, 0x00, // horizontal luminance phase offset
397 0xab, 0x00,
398 0xac, 0x00, // horizontal chrominance scaling increment
399 0xad, 0x02,
400 0xae, 0x00, // horizontal chrominance phase offset
401 0xaf, 0x00,
402 0xb0, 0x00, // vertical luminance scaling increment
403 0xb1, 0x04,
404 0xb2, 0x00, // vertical chrominance scaling increment
405 0xb3, 0x04,
406 0xb4, 0x00,
407 0xb5, 0x00,
408 0xb6, 0x00,
409 0xb7, 0x00,
410 0xb8, 0x00,
411 0xb9, 0x00,
412 0xba, 0x00,
413 0xbb, 0x00,
414 0xbc, 0x00,
415 0xbd, 0x00,
416 0xbe, 0x00,
417 0xbf, 0x00,
418 0xc0, 0x02, // Task B definition
419 0xc1, 0x08,
420 0xc2, 0x00,
421 0xc3, 0x40,
422 0xc4, 0x00, // window settings
423 0xc5, 0x00,
424 0xc6, 0x00,
425 0xc7, 0x00,
426 0xc8, 0x00,
427 0xc9, 0x00,
428 0xca, 0x00,
429 0xcb, 0x00,
430 0xcc, 0x00,
431 0xcd, 0x00,
432 0xce, 0x00,
433 0xcf, 0x00,
434 0xd0, 0x01, // horizontal integer prescaling ratio
435 0xd1, 0x00, // horizontal prescaler accumulation sequence length
436 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
437 0xd3, 0x00,
438 0xd4, 0x80, // luminance brightness
439 0xd5, 0x40, // luminance gain
440 0xd6, 0x40, // chrominance saturation
441 0xd7, 0x00,
442 0xd8, 0x00, // horizontal luminance scaling increment
443 0xd9, 0x04,
444 0xda, 0x00, // horizontal luminance phase offset
445 0xdb, 0x00,
446 0xdc, 0x00, // horizontal chrominance scaling increment
447 0xdd, 0x02,
448 0xde, 0x00, // horizontal chrominance phase offset
449 0xdf, 0x00,
450 0xe0, 0x00, // vertical luminance scaling increment
451 0xe1, 0x04,
452 0xe2, 0x00, // vertical chrominance scaling increment
453 0xe3, 0x04,
454 0xe4, 0x00,
455 0xe5, 0x00,
456 0xe6, 0x00,
457 0xe7, 0x00,
458 0xe8, 0x00,
459 0xe9, 0x00,
460 0xea, 0x00,
461 0xeb, 0x00,
462 0xec, 0x00,
463 0xed, 0x00,
464 0xee, 0x00,
465 0xef, 0x00
466};
467
468static int
469saa7114_command (struct i2c_client *client,
470 unsigned int cmd,
471 void *arg)
472{
473 struct saa7114 *decoder = i2c_get_clientdata(client);
474
475 switch (cmd) {
476
477 case 0:
478 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
479 //saa7114_write_block(client, init, sizeof(init));
480 break;
481
482 case DECODER_DUMP:
483 {
484 int i;
485
486 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
487
488 for (i = 0; i < 32; i += 16) {
489 int j;
490
491 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
492 for (j = 0; j < 16; ++j) {
493 printk(" %02x",
494 saa7114_read(client, i + j));
495 }
496 printk("\n");
497 }
498 }
499 break;
500
501 case DECODER_GET_CAPABILITIES:
502 {
503 struct video_decoder_capability *cap = arg;
504
505 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
506 I2C_NAME(client));
507
508 cap->flags = VIDEO_DECODER_PAL |
509 VIDEO_DECODER_NTSC |
510 VIDEO_DECODER_AUTO |
511 VIDEO_DECODER_CCIR;
512 cap->inputs = 8;
513 cap->outputs = 1;
514 }
515 break;
516
517 case DECODER_GET_STATUS:
518 {
519 int *iarg = arg;
520 int status;
521 int res;
522
523 status = saa7114_read(client, 0x1f);
524
525 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
526 status);
527 res = 0;
528 if ((status & (1 << 6)) == 0) {
529 res |= DECODER_STATUS_GOOD;
530 }
531 switch (decoder->norm) {
532 case VIDEO_MODE_NTSC:
533 res |= DECODER_STATUS_NTSC;
534 break;
535 case VIDEO_MODE_PAL:
536 res |= DECODER_STATUS_PAL;
537 break;
538 case VIDEO_MODE_SECAM:
539 res |= DECODER_STATUS_SECAM;
540 break;
541 default:
542 case VIDEO_MODE_AUTO:
543 if ((status & (1 << 5)) != 0) {
544 res |= DECODER_STATUS_NTSC;
545 } else {
546 res |= DECODER_STATUS_PAL;
547 }
548 break;
549 }
550 if ((status & (1 << 0)) != 0) {
551 res |= DECODER_STATUS_COLOR;
552 }
553 *iarg = res;
554 }
555 break;
556
557 case DECODER_SET_NORM:
558 {
559 int *iarg = arg;
560
561 short int hoff = 0, voff = 0, w = 0, h = 0;
562
563 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
564 I2C_NAME(client));
565 switch (*iarg) {
566
567 case VIDEO_MODE_NTSC:
568 dprintk(1, "NTSC\n");
569 decoder->reg[REG_ADDR(0x06)] =
570 SAA_7114_NTSC_HSYNC_START;
571 decoder->reg[REG_ADDR(0x07)] =
572 SAA_7114_NTSC_HSYNC_STOP;
573
574 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
575
576 decoder->reg[REG_ADDR(0x0e)] = 0x85;
577 decoder->reg[REG_ADDR(0x0f)] = 0x24;
578
579 hoff = SAA_7114_NTSC_HOFFSET;
580 voff = SAA_7114_NTSC_VOFFSET;
581 w = SAA_7114_NTSC_WIDTH;
582 h = SAA_7114_NTSC_HEIGHT;
583
584 break;
585
586 case VIDEO_MODE_PAL:
587 dprintk(1, "PAL\n");
588 decoder->reg[REG_ADDR(0x06)] =
589 SAA_7114_PAL_HSYNC_START;
590 decoder->reg[REG_ADDR(0x07)] =
591 SAA_7114_PAL_HSYNC_STOP;
592
593 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
594
595 decoder->reg[REG_ADDR(0x0e)] = 0x81;
596 decoder->reg[REG_ADDR(0x0f)] = 0x24;
597
598 hoff = SAA_7114_PAL_HOFFSET;
599 voff = SAA_7114_PAL_VOFFSET;
600 w = SAA_7114_PAL_WIDTH;
601 h = SAA_7114_PAL_HEIGHT;
602
603 break;
604
605 default:
606 dprintk(1, " Unknown video mode!!!\n");
607 return -EINVAL;
608
609 }
610
611
612 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
613 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
614 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
615 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
616 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
617 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
618 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
619 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
620 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
621 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
622 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
623 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
624
625 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
626 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
627 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
628 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
629 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
630 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
631 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
632 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
633 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
634 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
635 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
636 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
637
638
639 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
640 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
641 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
642
643 saa7114_write_block(client, decoder->reg + (0x06 << 1),
644 3 << 1);
645 saa7114_write_block(client, decoder->reg + (0x0e << 1),
646 2 << 1);
647 saa7114_write_block(client, decoder->reg + (0x5a << 1),
648 2 << 1);
649
650 saa7114_write_block(client, decoder->reg + (0x94 << 1),
651 (0x9f + 1 - 0x94) << 1);
652 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
653 (0xcf + 1 - 0xc4) << 1);
654
655 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
656 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
657 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
658
659 decoder->norm = *iarg;
660 }
661 break;
662
663 case DECODER_SET_INPUT:
664 {
665 int *iarg = arg;
666
667 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
668 I2C_NAME(client), *iarg);
669 if (*iarg < 0 || *iarg > 7) {
670 return -EINVAL;
671 }
672
673 if (decoder->input != *iarg) {
674 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
675 I2C_NAME(client),
676 *iarg >= 6 ? "S-Video" : "Composite");
677 decoder->input = *iarg;
678
679 /* select mode */
680 decoder->reg[REG_ADDR(0x02)] =
681 (decoder->
682 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
683 input <
684 6 ? 0x0 : 0x9);
685 saa7114_write(client, 0x02,
686 decoder->reg[REG_ADDR(0x02)]);
687
688 /* bypass chrominance trap for modes 6..9 */
689 decoder->reg[REG_ADDR(0x09)] =
690 (decoder->
691 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
692 input <
693 6 ? 0x0 :
694 0x80);
695 saa7114_write(client, 0x09,
696 decoder->reg[REG_ADDR(0x09)]);
697
698 decoder->reg[REG_ADDR(0x0e)] =
699 decoder->input <
700 6 ? decoder->
701 reg[REG_ADDR(0x0e)] | 1 : decoder->
702 reg[REG_ADDR(0x0e)] & ~1;
703 saa7114_write(client, 0x0e,
704 decoder->reg[REG_ADDR(0x0e)]);
705 }
706 }
707 break;
708
709 case DECODER_SET_OUTPUT:
710 {
711 int *iarg = arg;
712
713 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
714 I2C_NAME(client));
715
716 /* not much choice of outputs */
717 if (*iarg != 0) {
718 return -EINVAL;
719 }
720 }
721 break;
722
723 case DECODER_ENABLE_OUTPUT:
724 {
725 int *iarg = arg;
726 int enable = (*iarg != 0);
727
728 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
729 I2C_NAME(client), enable ? "enable" : "disable");
730
731 decoder->playback = !enable;
732
733 if (decoder->enable != enable) {
734 decoder->enable = enable;
735
736 /* RJ: If output should be disabled (for
737 * playing videos), we also need a open PLL.
738 * The input is set to 0 (where no input
739 * source is connected), although this
740 * is not necessary.
741 *
742 * If output should be enabled, we have to
743 * reverse the above.
744 */
745
746 if (decoder->enable) {
747 decoder->reg[REG_ADDR(0x08)] = 0xb8;
748 decoder->reg[REG_ADDR(0x12)] = 0xc9;
749 decoder->reg[REG_ADDR(0x13)] = 0x80;
750 decoder->reg[REG_ADDR(0x87)] = 0x01;
751 } else {
752 decoder->reg[REG_ADDR(0x08)] = 0x7c;
753 decoder->reg[REG_ADDR(0x12)] = 0x00;
754 decoder->reg[REG_ADDR(0x13)] = 0x00;
755 decoder->reg[REG_ADDR(0x87)] = 0x00;
756 }
757
758 saa7114_write_block(client,
759 decoder->reg + (0x12 << 1),
760 2 << 1);
761 saa7114_write(client, 0x08,
762 decoder->reg[REG_ADDR(0x08)]);
763 saa7114_write(client, 0x87,
764 decoder->reg[REG_ADDR(0x87)]);
765 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
766 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
767 saa7114_write(client, 0x80, 0x36);
768
769 }
770 }
771 break;
772
773 case DECODER_SET_PICTURE:
774 {
775 struct video_picture *pic = arg;
776
777 dprintk(1,
778 KERN_DEBUG
779 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
780 I2C_NAME(client), pic->brightness, pic->contrast,
781 pic->colour, pic->hue);
782
783 if (decoder->bright != pic->brightness) {
784 /* We want 0 to 255 we get 0-65535 */
785 decoder->bright = pic->brightness;
786 saa7114_write(client, 0x0a, decoder->bright >> 8);
787 }
788 if (decoder->contrast != pic->contrast) {
789 /* We want 0 to 127 we get 0-65535 */
790 decoder->contrast = pic->contrast;
791 saa7114_write(client, 0x0b,
792 decoder->contrast >> 9);
793 }
794 if (decoder->sat != pic->colour) {
795 /* We want 0 to 127 we get 0-65535 */
796 decoder->sat = pic->colour;
797 saa7114_write(client, 0x0c, decoder->sat >> 9);
798 }
799 if (decoder->hue != pic->hue) {
800 /* We want -128 to 127 we get 0-65535 */
801 decoder->hue = pic->hue;
802 saa7114_write(client, 0x0d,
803 (decoder->hue - 32768) >> 8);
804 }
805 }
806 break;
807
808 default:
809 return -EINVAL;
810 }
811
812 return 0;
813}
814
815/* ----------------------------------------------------------------------- */
816
817/*
818 * Generic i2c probe
819 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
820 */
821static unsigned short normal_i2c[] =
822 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
823static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
824
825static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
826static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
827static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
828static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
829static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
830
831static struct i2c_client_address_data addr_data = {
832 .normal_i2c = normal_i2c,
833 .normal_i2c_range = normal_i2c_range,
834 .probe = probe,
835 .probe_range = probe_range,
836 .ignore = ignore,
837 .ignore_range = ignore_range,
838 .force = force
839};
840
841static struct i2c_driver i2c_driver_saa7114;
842
843static int
844saa7114_detect_client (struct i2c_adapter *adapter,
845 int address,
846 int kind)
847{
848 int i, err[30];
849 short int hoff = SAA_7114_NTSC_HOFFSET;
850 short int voff = SAA_7114_NTSC_VOFFSET;
851 short int w = SAA_7114_NTSC_WIDTH;
852 short int h = SAA_7114_NTSC_HEIGHT;
853 struct i2c_client *client;
854 struct saa7114 *decoder;
855
856 dprintk(1,
857 KERN_INFO
858 "saa7114.c: detecting saa7114 client on address 0x%x\n",
859 address << 1);
860
861 /* Check if the adapter supports the needed features */
862 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
863 return 0;
864
865 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
866 if (client == 0)
867 return -ENOMEM;
868 memset(client, 0, sizeof(struct i2c_client));
869 client->addr = address;
870 client->adapter = adapter;
871 client->driver = &i2c_driver_saa7114;
872 client->flags = I2C_CLIENT_ALLOW_USE;
873 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
874
875 decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
876 if (decoder == NULL) {
877 kfree(client);
878 return -ENOMEM;
879 }
880 memset(decoder, 0, sizeof(struct saa7114));
881 decoder->norm = VIDEO_MODE_NTSC;
882 decoder->input = -1;
883 decoder->enable = 1;
884 decoder->bright = 32768;
885 decoder->contrast = 32768;
886 decoder->hue = 32768;
887 decoder->sat = 32768;
888 decoder->playback = 0; // initially capture mode useda
889 i2c_set_clientdata(client, decoder);
890
891 memcpy(decoder->reg, init, sizeof(init));
892
893 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
894 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
895 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
896 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
897 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
898 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
899 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
900 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
901 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
902 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
903 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
904 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
905
906 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
907 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
908 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
909 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
910 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
911 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
912 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
913 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
914 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
915 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
916 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
917 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
918
919 decoder->reg[REG_ADDR(0xb8)] =
920 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
921 decoder->reg[REG_ADDR(0xb9)] =
922 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
923 decoder->reg[REG_ADDR(0xba)] =
924 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
925 decoder->reg[REG_ADDR(0xbb)] =
926 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
927
928 decoder->reg[REG_ADDR(0xbc)] =
929 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
930 decoder->reg[REG_ADDR(0xbd)] =
931 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
932 decoder->reg[REG_ADDR(0xbe)] =
933 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
934 decoder->reg[REG_ADDR(0xbf)] =
935 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
936
937 decoder->reg[REG_ADDR(0xe8)] =
938 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
939 decoder->reg[REG_ADDR(0xe9)] =
940 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
941 decoder->reg[REG_ADDR(0xea)] =
942 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
943 decoder->reg[REG_ADDR(0xeb)] =
944 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
945
946 decoder->reg[REG_ADDR(0xec)] =
947 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
948 decoder->reg[REG_ADDR(0xed)] =
949 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
950 decoder->reg[REG_ADDR(0xee)] =
951 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
952 decoder->reg[REG_ADDR(0xef)] =
953 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
954
955
956 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
957 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
958 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
959
960 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
961 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
962 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
963
964
965 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
966 I2C_NAME(client));
967
968 err[0] =
969 saa7114_write_block(client, decoder->reg + (0x20 << 1),
970 0x10 << 1);
971 err[1] =
972 saa7114_write_block(client, decoder->reg + (0x30 << 1),
973 0x10 << 1);
974 err[2] =
975 saa7114_write_block(client, decoder->reg + (0x63 << 1),
976 (0x7f + 1 - 0x63) << 1);
977 err[3] =
978 saa7114_write_block(client, decoder->reg + (0x89 << 1),
979 6 << 1);
980 err[4] =
981 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
982 8 << 1);
983 err[5] =
984 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
985 8 << 1);
986
987
988 for (i = 0; i <= 5; i++) {
989 if (err[i] < 0) {
990 dprintk(1,
991 KERN_ERR
992 "%s_attach: init error %d at stage %d, leaving attach.\n",
993 I2C_NAME(client), i, err[i]);
994 kfree(decoder);
995 kfree(client);
996 return 0;
997 }
998 }
999
1000 for (i = 6; i < 8; i++) {
1001 dprintk(1,
1002 KERN_DEBUG
1003 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1004 I2C_NAME(client), i, saa7114_read(client, i),
1005 decoder->reg[REG_ADDR(i)]);
1006 }
1007
1008 dprintk(1,
1009 KERN_DEBUG
1010 "%s_attach: performing decoder reset sequence\n",
1011 I2C_NAME(client));
1012
1013 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
1014 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1015 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1016
1017 for (i = 6; i <= 8; i++) {
1018 if (err[i] < 0) {
1019 dprintk(1,
1020 KERN_ERR
1021 "%s_attach: init error %d at stage %d, leaving attach.\n",
1022 I2C_NAME(client), i, err[i]);
1023 kfree(decoder);
1024 kfree(client);
1025 return 0;
1026 }
1027 }
1028
1029 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1030 I2C_NAME(client));
1031
1032
1033 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1034 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1035 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1036 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1037 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1038 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1039 err[15] =
1040 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1041 12 << 1);
1042 err[16] =
1043 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1044 8 << 1);
1045 err[17] =
1046 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1047 8 << 1);
1048 err[18] =
1049 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1050 8 << 1);
1051 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1052 err[15] =
1053 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1054 12 << 1);
1055 err[16] =
1056 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1057 8 << 1);
1058 err[17] =
1059 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1060 8 << 1);
1061 err[18] =
1062 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1063 8 << 1);
1064
1065 for (i = 9; i <= 18; i++) {
1066 if (err[i] < 0) {
1067 dprintk(1,
1068 KERN_ERR
1069 "%s_attach: init error %d at stage %d, leaving attach.\n",
1070 I2C_NAME(client), i, err[i]);
1071 kfree(decoder);
1072 kfree(client);
1073 return 0;
1074 }
1075 }
1076
1077
1078 for (i = 6; i < 8; i++) {
1079 dprintk(1,
1080 KERN_DEBUG
1081 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1082 I2C_NAME(client), i, saa7114_read(client, i),
1083 decoder->reg[REG_ADDR(i)]);
1084 }
1085
1086
1087 for (i = 0x11; i <= 0x13; i++) {
1088 dprintk(1,
1089 KERN_DEBUG
1090 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1091 I2C_NAME(client), i, saa7114_read(client, i),
1092 decoder->reg[REG_ADDR(i)]);
1093 }
1094
1095
1096 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1097 I2C_NAME(client));
1098
1099 err[19] =
1100 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1101 err[20] =
1102 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1103 err[21] =
1104 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1105
1106 for (i = 19; i <= 21; i++) {
1107 if (err[i] < 0) {
1108 dprintk(1,
1109 KERN_ERR
1110 "%s_attach: init error %d at stage %d, leaving attach.\n",
1111 I2C_NAME(client), i, err[i]);
1112 kfree(decoder);
1113 kfree(client);
1114 return 0;
1115 }
1116 }
1117
1118 dprintk(1,
1119 KERN_DEBUG
1120 "%s_attach: performing decoder reset sequence\n",
1121 I2C_NAME(client));
1122
1123 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1124 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1125 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1126
1127
1128 for (i = 22; i <= 24; i++) {
1129 if (err[i] < 0) {
1130 dprintk(1,
1131 KERN_ERR
1132 "%s_attach: init error %d at stage %d, leaving attach.\n",
1133 I2C_NAME(client), i, err[i]);
1134 kfree(decoder);
1135 kfree(client);
1136 return 0;
1137 }
1138 }
1139
1140 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1141 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1142 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1143
1144 dprintk(1,
1145 KERN_INFO
1146 "%s_attach: chip version %x, decoder status 0x%02x\n",
1147 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1148 saa7114_read(client, 0x1f));
1149 dprintk(1,
1150 KERN_DEBUG
1151 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1152 I2C_NAME(client), saa7114_read(client, 0x88),
1153 saa7114_read(client, 0x8f));
1154
1155
1156 for (i = 0x94; i < 0x96; i++) {
1157 dprintk(1,
1158 KERN_DEBUG
1159 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1160 I2C_NAME(client), i, saa7114_read(client, i),
1161 decoder->reg[REG_ADDR(i)]);
1162 }
1163
1164 i = i2c_attach_client(client);
1165 if (i) {
1166 kfree(client);
1167 kfree(decoder);
1168 return i;
1169 }
1170
1171 //i = saa7114_write_block(client, init, sizeof(init));
1172 i = 0;
1173 if (i < 0) {
1174 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1175 I2C_NAME(client), i);
1176 } else {
1177 dprintk(1,
1178 KERN_INFO
1179 "%s_attach: chip version %x at address 0x%x\n",
1180 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1181 client->addr << 1);
1182 }
1183
1184 return 0;
1185}
1186
1187static int
1188saa7114_attach_adapter (struct i2c_adapter *adapter)
1189{
1190 dprintk(1,
1191 KERN_INFO
1192 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1193 I2C_NAME(adapter), adapter->id);
1194 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1195}
1196
1197static int
1198saa7114_detach_client (struct i2c_client *client)
1199{
1200 struct saa7114 *decoder = i2c_get_clientdata(client);
1201 int err;
1202
1203 err = i2c_detach_client(client);
1204 if (err) {
1205 return err;
1206 }
1207
1208 kfree(decoder);
1209 kfree(client);
1210
1211 return 0;
1212}
1213
1214/* ----------------------------------------------------------------------- */
1215
1216static struct i2c_driver i2c_driver_saa7114 = {
1217 .owner = THIS_MODULE,
1218 .name = "saa7114",
1219
1220 .id = I2C_DRIVERID_SAA7114,
1221 .flags = I2C_DF_NOTIFY,
1222
1223 .attach_adapter = saa7114_attach_adapter,
1224 .detach_client = saa7114_detach_client,
1225 .command = saa7114_command,
1226};
1227
1228static int __init
1229saa7114_init (void)
1230{
1231 return i2c_add_driver(&i2c_driver_saa7114);
1232}
1233
1234static void __exit
1235saa7114_exit (void)
1236{
1237 i2c_del_driver(&i2c_driver_saa7114);
1238}
1239
1240module_init(saa7114_init);
1241module_exit(saa7114_exit);
diff --git a/drivers/media/video/saa7121.h b/drivers/media/video/saa7121.h
new file mode 100644
index 000000000000..74e37d405208
--- /dev/null
+++ b/drivers/media/video/saa7121.h
@@ -0,0 +1,132 @@
1/* saa7121.h - saa7121 initializations
2 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19#ifndef __SAA7121_H__
20#define __SAA7121_H__
21
22#define NTSC_BURST_START 0x19 /* 28 */
23#define NTSC_BURST_END 0x1d /* 29 */
24#define NTSC_CHROMA_PHASE 0x67 /* 5a */
25#define NTSC_GAINU 0x76 /* 5b */
26#define NTSC_GAINV 0xa5 /* 5c */
27#define NTSC_BLACK_LEVEL 0x2a /* 5d */
28#define NTSC_BLANKING_LEVEL 0x2e /* 5e */
29#define NTSC_VBI_BLANKING 0x2e /* 5f */
30#define NTSC_DAC_CONTROL 0x11 /* 61 */
31#define NTSC_BURST_AMP 0x3f /* 62 */
32#define NTSC_SUBC3 0x1f /* 63 */
33#define NTSC_SUBC2 0x7c /* 64 */
34#define NTSC_SUBC1 0xf0 /* 65 */
35#define NTSC_SUBC0 0x21 /* 66 */
36#define NTSC_HTRIG 0x72 /* 6c */
37#define NTSC_VTRIG 0x00 /* 6c */
38#define NTSC_MULTI 0x30 /* 6e */
39#define NTSC_CCTTX 0x11 /* 6f */
40#define NTSC_FIRST_ACTIVE 0x12 /* 7a */
41#define NTSC_LAST_ACTIVE 0x02 /* 7b */
42#define NTSC_MSB_VERTICAL 0x40 /* 7c */
43
44#define PAL_BURST_START 0x21 /* 28 */
45#define PAL_BURST_END 0x1d /* 29 */
46#define PAL_CHROMA_PHASE 0x3f /* 5a */
47#define PAL_GAINU 0x7d /* 5b */
48#define PAL_GAINV 0xaf /* 5c */
49#define PAL_BLACK_LEVEL 0x23 /* 5d */
50#define PAL_BLANKING_LEVEL 0x35 /* 5e */
51#define PAL_VBI_BLANKING 0x35 /* 5f */
52#define PAL_DAC_CONTROL 0x02 /* 61 */
53#define PAL_BURST_AMP 0x2f /* 62 */
54#define PAL_SUBC3 0xcb /* 63 */
55#define PAL_SUBC2 0x8a /* 64 */
56#define PAL_SUBC1 0x09 /* 65 */
57#define PAL_SUBC0 0x2a /* 66 */
58#define PAL_HTRIG 0x86 /* 6c */
59#define PAL_VTRIG 0x04 /* 6d */
60#define PAL_MULTI 0x20 /* 6e */
61#define PAL_CCTTX 0x15 /* 6f */
62#define PAL_FIRST_ACTIVE 0x16 /* 7a */
63#define PAL_LAST_ACTIVE 0x36 /* 7b */
64#define PAL_MSB_VERTICAL 0x40 /* 7c */
65
66/* Initialization Sequence */
67
68static __u8 init7121ntsc[] = {
69 0x26, 0x0, 0x27, 0x0,
70 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END,
71 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
72 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
73 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
74 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
75 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
76 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
77 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
78 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
79 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
80 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
81 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
82 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
83 0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU,
84 0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL,
85 0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING,
86 0x60, 0x0, 0x61, NTSC_DAC_CONTROL,
87 0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3,
88 0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1,
89 0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80,
90 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
91 0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG,
92 0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX,
93 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
94 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
95 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE,
96 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL,
97 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
98};
99#define INIT7121LEN (sizeof(init7121ntsc)/2)
100
101static __u8 init7121pal[] = {
102 0x26, 0x0, 0x27, 0x0,
103 0x28, PAL_BURST_START, 0x29, PAL_BURST_END,
104 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
105 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
106 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
107 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
108 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
109 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
110 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
111 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
112 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
113 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
114 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
115 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
116 0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU,
117 0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL,
118 0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING,
119 0x60, 0x0, 0x61, PAL_DAC_CONTROL,
120 0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3,
121 0x64, PAL_SUBC2, 0x65, PAL_SUBC1,
122 0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80,
123 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
124 0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG,
125 0x6e, PAL_MULTI, 0x6f, PAL_CCTTX,
126 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
127 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
128 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE,
129 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL,
130 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
131};
132#endif
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
new file mode 100644
index 000000000000..e577a06b136b
--- /dev/null
+++ b/drivers/media/video/saa7134/Makefile
@@ -0,0 +1,11 @@
1
2saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8
9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
new file mode 100644
index 000000000000..cee13584c9cf
--- /dev/null
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -0,0 +1,543 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/sched.h>
4#include <linux/string.h>
5#include <linux/timer.h>
6#include <linux/delay.h>
7#include <linux/errno.h>
8#include <linux/slab.h>
9#include <linux/poll.h>
10#include <linux/i2c.h>
11#include <linux/types.h>
12#include <linux/videodev.h>
13#include <linux/init.h>
14#include <linux/crc32.h>
15
16#include <media/id.h>
17
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
20#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
21#define MPEG_PID_MAX ((1 << 14) - 1)
22
23/* Addresses to scan */
24static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
25static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
26I2C_CLIENT_INSMOD;
27
28MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
29MODULE_AUTHOR("Andrew de Quincey");
30MODULE_LICENSE("GPL");
31
32static struct i2c_driver driver;
33static struct i2c_client client_template;
34
35struct saa6752hs_state {
36 struct i2c_client client;
37 struct v4l2_mpeg_compression params;
38};
39
40enum saa6752hs_command {
41 SAA6752HS_COMMAND_RESET = 0,
42 SAA6752HS_COMMAND_STOP = 1,
43 SAA6752HS_COMMAND_START = 2,
44 SAA6752HS_COMMAND_PAUSE = 3,
45 SAA6752HS_COMMAND_RECONFIGURE = 4,
46 SAA6752HS_COMMAND_SLEEP = 5,
47 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
48
49 SAA6752HS_COMMAND_MAX
50};
51
52/* ---------------------------------------------------------------------- */
53
54static u8 PAT[] = {
55 0xc2, // i2c register
56 0x00, // table number for encoder
57
58 0x47, // sync
59 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
60 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
61
62 0x00, // PSI pointer to start of table
63
64 0x00, // tid(0)
65 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
66
67 0x00, 0x01, // transport_stream_id(1)
68
69 0xc1, // version_number(0), current_next_indicator(1)
70
71 0x00, 0x00, // section_number(0), last_section_number(0)
72
73 0x00, 0x01, // program_number(1)
74
75 0xe0, 0x00, // PMT PID
76
77 0x00, 0x00, 0x00, 0x00 // CRC32
78};
79
80static u8 PMT[] = {
81 0xc2, // i2c register
82 0x01, // table number for encoder
83
84 0x47, // sync
85 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
86 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
87
88 0x00, // PSI pointer to start of table
89
90 0x02, // tid(2)
91 0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
92
93 0x00, 0x01, // program_number(1)
94
95 0xc1, // version_number(0), current_next_indicator(1)
96
97 0x00, 0x00, // section_number(0), last_section_number(0)
98
99 0xe0, 0x00, // PCR_PID
100
101 0xf0, 0x00, // program_info_length(0)
102
103 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
104 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
105
106 0x00, 0x00, 0x00, 0x00 // CRC32
107};
108
109static struct v4l2_mpeg_compression param_defaults =
110{
111 .st_type = V4L2_MPEG_TS_2,
112 .st_bitrate = {
113 .mode = V4L2_BITRATE_CBR,
114 .target = 7000,
115 },
116
117 .ts_pid_pmt = 16,
118 .ts_pid_video = 260,
119 .ts_pid_audio = 256,
120 .ts_pid_pcr = 259,
121
122 .vi_type = V4L2_MPEG_VI_2,
123 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
124 .vi_bitrate = {
125 .mode = V4L2_BITRATE_VBR,
126 .target = 4000,
127 .max = 6000,
128 },
129
130 .au_type = V4L2_MPEG_AU_2_II,
131 .au_bitrate = {
132 .mode = V4L2_BITRATE_CBR,
133 .target = 256,
134 },
135
136#if 0
137 /* FIXME: size? via S_FMT? */
138 .video_format = MPEG_VIDEO_FORMAT_D1,
139#endif
140};
141
142/* ---------------------------------------------------------------------- */
143
144static int saa6752hs_chip_command(struct i2c_client* client,
145 enum saa6752hs_command command)
146{
147 unsigned char buf[3];
148 unsigned long timeout;
149 int status = 0;
150
151 // execute the command
152 switch(command) {
153 case SAA6752HS_COMMAND_RESET:
154 buf[0] = 0x00;
155 break;
156
157 case SAA6752HS_COMMAND_STOP:
158 buf[0] = 0x03;
159 break;
160
161 case SAA6752HS_COMMAND_START:
162 buf[0] = 0x02;
163 break;
164
165 case SAA6752HS_COMMAND_PAUSE:
166 buf[0] = 0x04;
167 break;
168
169 case SAA6752HS_COMMAND_RECONFIGURE:
170 buf[0] = 0x05;
171 break;
172
173 case SAA6752HS_COMMAND_SLEEP:
174 buf[0] = 0x06;
175 break;
176
177 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
178 buf[0] = 0x07;
179 break;
180
181 default:
182 return -EINVAL;
183 }
184
185 // set it and wait for it to be so
186 i2c_master_send(client, buf, 1);
187 timeout = jiffies + HZ * 3;
188 for (;;) {
189 // get the current status
190 buf[0] = 0x10;
191 i2c_master_send(client, buf, 1);
192 i2c_master_recv(client, buf, 1);
193
194 if (!(buf[0] & 0x20))
195 break;
196 if (time_after(jiffies,timeout)) {
197 status = -ETIMEDOUT;
198 break;
199 }
200
201 // wait a bit
202 msleep(10);
203 }
204
205 // delay a bit to let encoder settle
206 msleep(50);
207
208 // done
209 return status;
210}
211
212
213static int saa6752hs_set_bitrate(struct i2c_client* client,
214 struct v4l2_mpeg_compression* params)
215{
216 u8 buf[3];
217
218 // set the bitrate mode
219 buf[0] = 0x71;
220 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
221 i2c_master_send(client, buf, 2);
222
223 // set the video bitrate
224 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
225 // set the target bitrate
226 buf[0] = 0x80;
227 buf[1] = params->vi_bitrate.target >> 8;
228 buf[2] = params->vi_bitrate.target & 0xff;
229 i2c_master_send(client, buf, 3);
230
231 // set the max bitrate
232 buf[0] = 0x81;
233 buf[1] = params->vi_bitrate.max >> 8;
234 buf[2] = params->vi_bitrate.max & 0xff;
235 i2c_master_send(client, buf, 3);
236 } else {
237 // set the target bitrate (no max bitrate for CBR)
238 buf[0] = 0x81;
239 buf[1] = params->vi_bitrate.target >> 8;
240 buf[2] = params->vi_bitrate.target & 0xff;
241 i2c_master_send(client, buf, 3);
242 }
243
244 // set the audio bitrate
245 buf[0] = 0x94;
246 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
247 i2c_master_send(client, buf, 2);
248
249 // set the total bitrate
250 buf[0] = 0xb1;
251 buf[1] = params->st_bitrate.target >> 8;
252 buf[2] = params->st_bitrate.target & 0xff;
253 i2c_master_send(client, buf, 3);
254
255 // return success
256 return 0;
257}
258
259
260static void saa6752hs_set_params(struct i2c_client* client,
261 struct v4l2_mpeg_compression* params)
262{
263 struct saa6752hs_state *h = i2c_get_clientdata(client);
264
265 /* check PIDs */
266 if (params->ts_pid_pmt <= MPEG_PID_MAX)
267 h->params.ts_pid_pmt = params->ts_pid_pmt;
268 if (params->ts_pid_pcr <= MPEG_PID_MAX)
269 h->params.ts_pid_pcr = params->ts_pid_pcr;
270 if (params->ts_pid_video <= MPEG_PID_MAX)
271 h->params.ts_pid_video = params->ts_pid_video;
272 if (params->ts_pid_audio <= MPEG_PID_MAX)
273 h->params.ts_pid_audio = params->ts_pid_audio;
274
275 /* check bitrate parameters */
276 if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
277 (params->vi_bitrate.mode == V4L2_BITRATE_VBR))
278 h->params.vi_bitrate.mode = params->vi_bitrate.mode;
279 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
280 h->params.st_bitrate.target = params->st_bitrate.target;
281 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
282 h->params.vi_bitrate.target = params->vi_bitrate.target;
283 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
284 h->params.vi_bitrate.max = params->vi_bitrate.max;
285 if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
286 h->params.au_bitrate.target = params->au_bitrate.target;
287
288 /* aspect ratio */
289 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
290 params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9)
291 h->params.vi_aspect_ratio = params->vi_aspect_ratio;
292
293 /* range checks */
294 if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
295 h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
296 if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
297 h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
298 if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
299 h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
300 if (h->params.au_bitrate.target <= 256)
301 h->params.au_bitrate.target = 256;
302 else
303 h->params.au_bitrate.target = 384;
304}
305
306static int saa6752hs_init(struct i2c_client* client)
307{
308 unsigned char buf[9], buf2[4];
309 struct saa6752hs_state *h;
310 u32 crc;
311 unsigned char localPAT[256];
312 unsigned char localPMT[256];
313
314 h = i2c_get_clientdata(client);
315
316 // Set video format - must be done first as it resets other settings
317 buf[0] = 0x41;
318 buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
319 i2c_master_send(client, buf, 2);
320
321 // set bitrate
322 saa6752hs_set_bitrate(client, &h->params);
323
324 // Set GOP structure {3, 13}
325 buf[0] = 0x72;
326 buf[1] = 0x03;
327 buf[2] = 0x0D;
328 i2c_master_send(client,buf,3);
329
330 // Set minimum Q-scale {4}
331 buf[0] = 0x82;
332 buf[1] = 0x04;
333 i2c_master_send(client,buf,2);
334
335 // Set maximum Q-scale {12}
336 buf[0] = 0x83;
337 buf[1] = 0x0C;
338 i2c_master_send(client,buf,2);
339
340 // Set Output Protocol
341 buf[0] = 0xD0;
342 buf[1] = 0x81;
343 i2c_master_send(client,buf,2);
344
345 // Set video output stream format {TS}
346 buf[0] = 0xB0;
347 buf[1] = 0x05;
348 i2c_master_send(client,buf,2);
349
350 /* compute PAT */
351 memcpy(localPAT, PAT, sizeof(PAT));
352 localPAT[17] = 0xe0 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
353 localPAT[18] = h->params.ts_pid_pmt & 0xff;
354 crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4);
355 localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF;
356 localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF;
357 localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF;
358 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
359
360 /* compute PMT */
361 memcpy(localPMT, PMT, sizeof(PMT));
362 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
363 localPMT[4] = h->params.ts_pid_pmt & 0xff;
364 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
365 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
366 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
367 localPMT[21] = h->params.ts_pid_video & 0xFF;
368 localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F);
369 localPMT[26] = h->params.ts_pid_audio & 0xFF;
370 crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4);
371 localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF;
372 localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF;
373 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
374 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
375
376 // Set Audio PID
377 buf[0] = 0xC1;
378 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
379 buf[2] = h->params.ts_pid_audio & 0xFF;
380 i2c_master_send(client,buf,3);
381
382 // Set Video PID
383 buf[0] = 0xC0;
384 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
385 buf[2] = h->params.ts_pid_video & 0xFF;
386 i2c_master_send(client,buf,3);
387
388 // Set PCR PID
389 buf[0] = 0xC4;
390 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
391 buf[2] = h->params.ts_pid_pcr & 0xFF;
392 i2c_master_send(client,buf,3);
393
394 // Send SI tables
395 i2c_master_send(client,localPAT,sizeof(PAT));
396 i2c_master_send(client,localPMT,sizeof(PMT));
397
398 // mute then unmute audio. This removes buzzing artefacts
399 buf[0] = 0xa4;
400 buf[1] = 1;
401 i2c_master_send(client, buf, 2);
402 buf[1] = 0;
403 i2c_master_send(client, buf, 2);
404
405 // start it going
406 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
407
408 // readout current state
409 buf[0] = 0xE1;
410 buf[1] = 0xA7;
411 buf[2] = 0xFE;
412 buf[3] = 0x82;
413 buf[4] = 0xB0;
414 i2c_master_send(client, buf, 5);
415 i2c_master_recv(client, buf2, 4);
416
417 // change aspect ratio
418 buf[0] = 0xE0;
419 buf[1] = 0xA7;
420 buf[2] = 0xFE;
421 buf[3] = 0x82;
422 buf[4] = 0xB0;
423 buf[5] = buf2[0];
424 switch(h->params.vi_aspect_ratio) {
425 case V4L2_MPEG_ASPECT_16_9:
426 buf[6] = buf2[1] | 0x40;
427 break;
428 case V4L2_MPEG_ASPECT_4_3:
429 default:
430 buf[6] = buf2[1] & 0xBF;
431 break;
432 break;
433 }
434 buf[7] = buf2[2];
435 buf[8] = buf2[3];
436 i2c_master_send(client, buf, 9);
437
438 // return success
439 return 0;
440}
441
442static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
443{
444 struct saa6752hs_state *h;
445
446 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
447
448 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
449 return -ENOMEM;
450 memset(h,0,sizeof(*h));
451 h->client = client_template;
452 h->params = param_defaults;
453 h->client.adapter = adap;
454 h->client.addr = addr;
455
456 i2c_set_clientdata(&h->client, h);
457 i2c_attach_client(&h->client);
458 return 0;
459}
460
461static int saa6752hs_probe(struct i2c_adapter *adap)
462{
463 if (adap->class & I2C_CLASS_TV_ANALOG)
464 return i2c_probe(adap, &addr_data, saa6752hs_attach);
465 return 0;
466}
467
468static int saa6752hs_detach(struct i2c_client *client)
469{
470 struct saa6752hs_state *h;
471
472 h = i2c_get_clientdata(client);
473 i2c_detach_client(client);
474 kfree(h);
475 return 0;
476}
477
478static int
479saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
480{
481 struct saa6752hs_state *h = i2c_get_clientdata(client);
482 struct v4l2_mpeg_compression *params = arg;
483 int err = 0;
484
485 switch (cmd) {
486 case VIDIOC_S_MPEGCOMP:
487 if (NULL == params) {
488 /* apply settings and start encoder */
489 saa6752hs_init(client);
490 break;
491 }
492 saa6752hs_set_params(client, params);
493 /* fall through */
494 case VIDIOC_G_MPEGCOMP:
495 *params = h->params;
496 break;
497 default:
498 /* nothing */
499 break;
500 }
501
502 return err;
503}
504
505/* ----------------------------------------------------------------------- */
506
507static struct i2c_driver driver = {
508 .owner = THIS_MODULE,
509 .name = "i2c saa6752hs MPEG encoder",
510 .id = I2C_DRIVERID_SAA6752HS,
511 .flags = I2C_DF_NOTIFY,
512 .attach_adapter = saa6752hs_probe,
513 .detach_client = saa6752hs_detach,
514 .command = saa6752hs_command,
515};
516
517static struct i2c_client client_template =
518{
519 I2C_DEVNAME("saa6752hs"),
520 .flags = I2C_CLIENT_ALLOW_USE,
521 .driver = &driver,
522};
523
524static int __init saa6752hs_init_module(void)
525{
526 return i2c_add_driver(&driver);
527}
528
529static void __exit saa6752hs_cleanup_module(void)
530{
531 i2c_del_driver(&driver);
532}
533
534module_init(saa6752hs_init_module);
535module_exit(saa6752hs_cleanup_module);
536
537/*
538 * Overrides for Emacs so that we follow Linus's tabbing style.
539 * ---------------------------------------------------------------------------
540 * Local variables:
541 * c-basic-offset: 8
542 * End:
543 */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
new file mode 100644
index 000000000000..180d3175ea5b
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -0,0 +1,2018 @@
1
2/*
3 * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $
4 *
5 * device driver for philips saa7134 based TV cards
6 * card-specific stuff.
7 *
8 * (c) 2001-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
26#include <linux/module.h>
27
28#include "saa7134-reg.h"
29#include "saa7134.h"
30
31/* commly used strings */
32static char name_mute[] = "mute";
33static char name_radio[] = "Radio";
34static char name_tv[] = "Television";
35static char name_tv_mono[] = "TV (mono only)";
36static char name_comp1[] = "Composite1";
37static char name_comp2[] = "Composite2";
38static char name_comp3[] = "Composite3";
39static char name_comp4[] = "Composite4";
40static char name_svideo[] = "S-Video";
41
42/* ------------------------------------------------------------------ */
43/* board config info */
44
45struct saa7134_board saa7134_boards[] = {
46 [SAA7134_BOARD_UNKNOWN] = {
47 .name = "UNKNOWN/GENERIC",
48 .audio_clock = 0x00187de7,
49 .tuner_type = TUNER_ABSENT,
50 .inputs = {{
51 .name = "default",
52 .vmux = 0,
53 .amux = LINE1,
54 }},
55 },
56 [SAA7134_BOARD_PROTEUS_PRO] = {
57 /* /me */
58 .name = "Proteus Pro [philips reference design]",
59 .audio_clock = 0x00187de7,
60 .tuner_type = TUNER_PHILIPS_PAL,
61 .inputs = {{
62 .name = name_comp1,
63 .vmux = 0,
64 .amux = LINE1,
65 },{
66 .name = name_tv,
67 .vmux = 1,
68 .amux = TV,
69 .tv = 1,
70 },{
71 .name = name_tv_mono,
72 .vmux = 1,
73 .amux = LINE2,
74 .tv = 1,
75 }},
76 .radio = {
77 .name = name_radio,
78 .amux = LINE2,
79 },
80 },
81 [SAA7134_BOARD_FLYVIDEO3000] = {
82 /* "Marco d'Itri" <md@Linux.IT> */
83 .name = "LifeView FlyVIDEO3000",
84 .audio_clock = 0x00200000,
85 .tuner_type = TUNER_PHILIPS_PAL,
86 .gpiomask = 0xe000,
87 .inputs = {{
88 .name = name_tv,
89 .vmux = 1,
90 .amux = TV,
91 .gpio = 0x8000,
92 .tv = 1,
93 },{
94 .name = name_tv_mono,
95 .vmux = 1,
96 .amux = LINE2,
97 .gpio = 0x0000,
98 .tv = 1,
99 },{
100 .name = name_comp1,
101 .vmux = 0,
102 .amux = LINE2,
103 .gpio = 0x4000,
104 },{
105 .name = name_comp2,
106 .vmux = 3,
107 .amux = LINE2,
108 .gpio = 0x4000,
109 },{
110 .name = name_svideo,
111 .vmux = 8,
112 .amux = LINE2,
113 .gpio = 0x4000,
114 }},
115 .radio = {
116 .name = name_radio,
117 .amux = LINE2,
118 .gpio = 0x2000,
119 },
120 },
121 [SAA7134_BOARD_FLYVIDEO2000] = {
122 /* "TC Wan" <tcwan@cs.usm.my> */
123 .name = "LifeView FlyVIDEO2000",
124 .audio_clock = 0x00200000,
125 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
126 .gpiomask = 0xe000,
127 .inputs = {{
128 .name = name_tv,
129 .vmux = 1,
130 .amux = LINE2,
131 .gpio = 0x0000,
132 .tv = 1,
133 },{
134 .name = name_comp1,
135 .vmux = 0,
136 .amux = LINE2,
137 .gpio = 0x4000,
138 },{
139 .name = name_comp2,
140 .vmux = 3,
141 .amux = LINE2,
142 .gpio = 0x4000,
143 },{
144 .name = name_svideo,
145 .vmux = 8,
146 .amux = LINE2,
147 .gpio = 0x4000,
148 }},
149 .radio = {
150 .name = name_radio,
151 .amux = LINE2,
152 .gpio = 0x2000,
153 },
154 .mute = {
155 .name = name_mute,
156 .amux = LINE2,
157 .gpio = 0x8000,
158 },
159 },
160 [SAA7134_BOARD_FLYTVPLATINUM_MINI] = {
161 /* "Arnaud Quette" <aquette@free.fr> */
162 .name = "LifeView FlyTV Platinum Mini",
163 .audio_clock = 0x00200000,
164 .tuner_type = TUNER_PHILIPS_TDA8290,
165 .inputs = {{
166 .name = name_tv,
167 .vmux = 1,
168 .amux = LINE2,
169 .tv = 1,
170 },{
171 .name = name_comp1,
172 .vmux = 0,
173 .amux = LINE2,
174 },{
175 .name = name_svideo,
176 .vmux = 8,
177 .amux = LINE2,
178 }},
179 },
180 [SAA7134_BOARD_FLYTVPLATINUM_FM] = {
181 /* LifeView FlyTV Platinum FM (LR214WF) */
182 /* "Peter Missel <peter.missel@onlinehome.de> */
183 .name = "LifeView FlyTV Platinum FM",
184 .audio_clock = 0x00200000,
185 .tuner_type = TUNER_PHILIPS_TDA8290,
186// .gpiomask = 0xe000,
187 .inputs = {{
188 .name = name_tv,
189 .vmux = 1,
190 .amux = TV,
191// .gpio = 0x0000,
192 .tv = 1,
193 },{
194/* .name = name_tv_mono,
195 .vmux = 1,
196 .amux = LINE2,
197 .gpio = 0x0000,
198 .tv = 1,
199 },{
200*/ .name = name_comp1, /* Composite signal on S-Video input */
201 .vmux = 0,
202 .amux = LINE2,
203// .gpio = 0x4000,
204 },{
205 .name = name_comp2, /* Composite input */
206 .vmux = 3,
207 .amux = LINE2,
208// .gpio = 0x4000,
209 },{
210 .name = name_svideo, /* S-Video signal on S-Video input */
211 .vmux = 8,
212 .amux = LINE2,
213// .gpio = 0x4000,
214 }},
215/* .radio = {
216 .name = name_radio,
217 .amux = LINE2,
218 .gpio = 0x2000,
219 },
220*/ },
221 [SAA7134_BOARD_EMPRESS] = {
222 /* "Gert Vervoort" <gert.vervoort@philips.com> */
223 .name = "EMPRESS",
224 .audio_clock = 0x00187de7,
225 .tuner_type = TUNER_PHILIPS_PAL,
226 .inputs = {{
227 .name = name_comp1,
228 .vmux = 0,
229 .amux = LINE1,
230 },{
231 .name = name_svideo,
232 .vmux = 8,
233 .amux = LINE1,
234 },{
235 .name = name_tv,
236 .vmux = 1,
237 .amux = LINE2,
238 .tv = 1,
239 }},
240 .radio = {
241 .name = name_radio,
242 .amux = LINE2,
243 },
244 .mpeg = SAA7134_MPEG_EMPRESS,
245 .video_out = CCIR656,
246 },
247 [SAA7134_BOARD_MONSTERTV] = {
248 /* "K.Ohta" <alpha292@bremen.or.jp> */
249 .name = "SKNet Monster TV",
250 .audio_clock = 0x00187de7,
251 .tuner_type = TUNER_PHILIPS_NTSC_M,
252 .inputs = {{
253 .name = name_tv,
254 .vmux = 1,
255 .amux = TV,
256 .tv = 1,
257 },{
258 .name = name_comp1,
259 .vmux = 0,
260 .amux = LINE1,
261 },{
262 .name = name_svideo,
263 .vmux = 8,
264 .amux = LINE1,
265 }},
266 .radio = {
267 .name = name_radio,
268 .amux = LINE2,
269 },
270 },
271 [SAA7134_BOARD_MD9717] = {
272 .name = "Tevion MD 9717",
273 .audio_clock = 0x00200000,
274 .tuner_type = TUNER_PHILIPS_PAL,
275 .inputs = {{
276 .name = name_tv,
277 .vmux = 1,
278 .amux = TV,
279 .tv = 1,
280 },{
281 /* workaround for problems with normal TV sound */
282 .name = name_tv_mono,
283 .vmux = 1,
284 .amux = LINE2,
285 .tv = 1,
286 },{
287 .name = name_comp1,
288 .vmux = 2,
289 .amux = LINE1,
290 },{
291 .name = name_comp2,
292 .vmux = 3,
293 .amux = LINE1,
294 },{
295 .name = name_svideo,
296 .vmux = 8,
297 .amux = LINE1,
298 }},
299 .radio = {
300 .name = name_radio,
301 .amux = LINE2,
302 },
303 },
304 [SAA7134_BOARD_TVSTATION_RDS] = {
305 /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
306 .name = "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
307 .audio_clock = 0x00200000,
308 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
309 .tda9887_conf = TDA9887_PRESENT,
310 .inputs = {{
311 .name = name_tv,
312 .vmux = 1,
313 .amux = TV,
314 .tv = 1,
315 },{
316 .name = name_tv_mono,
317 .vmux = 1,
318 .amux = LINE2,
319 .tv = 1,
320 },{
321
322 .name = name_svideo,
323 .vmux = 8,
324 .amux = LINE1,
325 },{
326 .name = name_comp1,
327 .vmux = 3,
328 .amux = LINE1,
329 },{
330
331 .name = "CVid over SVid",
332 .vmux = 0,
333 .amux = LINE1,
334 }},
335 .radio = {
336 .name = name_radio,
337 .amux = LINE2,
338 },
339 },
340 [SAA7134_BOARD_TVSTATION_DVR] = {
341 .name = "KNC One TV-Station DVR",
342 .audio_clock = 0x00200000,
343 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
344 .tda9887_conf = TDA9887_PRESENT,
345 .gpiomask = 0x820000,
346 .inputs = {{
347 .name = name_tv,
348 .vmux = 1,
349 .amux = LINE2,
350 .tv = 1,
351 .gpio = 0x20000,
352 },{
353 .name = name_svideo,
354 .vmux = 8,
355 .amux = LINE1,
356 .gpio = 0x20000,
357 },{
358 .name = name_comp1,
359 .vmux = 3,
360 .amux = LINE1,
361 .gpio = 0x20000,
362 }},
363 .radio = {
364 .name = name_radio,
365 .amux = LINE2,
366 .gpio = 0x20000,
367 },
368 .mpeg = SAA7134_MPEG_EMPRESS,
369 .video_out = CCIR656,
370 },
371 [SAA7134_BOARD_CINERGY400] = {
372 .name = "Terratec Cinergy 400 TV",
373 .audio_clock = 0x00200000,
374 .tuner_type = TUNER_PHILIPS_PAL,
375 .inputs = {{
376 .name = name_tv,
377 .vmux = 1,
378 .amux = TV,
379 .tv = 1,
380 },{
381 .name = name_comp1,
382 .vmux = 4,
383 .amux = LINE1,
384 },{
385 .name = name_svideo,
386 .vmux = 8,
387 .amux = LINE1,
388 },{
389 .name = name_comp2, // CVideo over SVideo Connector
390 .vmux = 0,
391 .amux = LINE1,
392 }}
393 },
394 [SAA7134_BOARD_MD5044] = {
395 .name = "Medion 5044",
396 .audio_clock = 0x00187de7, // was: 0x00200000,
397 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
398 .tda9887_conf = TDA9887_PRESENT,
399 .inputs = {{
400 .name = name_tv,
401 .vmux = 1,
402 .amux = TV,
403 .tv = 1,
404 },{
405 /* workaround for problems with normal TV sound */
406 .name = name_tv_mono,
407 .vmux = 1,
408 .amux = LINE2,
409 .tv = 1,
410 },{
411 .name = name_comp1,
412 .vmux = 0,
413 .amux = LINE2,
414 },{
415 .name = name_comp2,
416 .vmux = 3,
417 .amux = LINE2,
418 },{
419 .name = name_svideo,
420 .vmux = 8,
421 .amux = LINE2,
422 }},
423 .radio = {
424 .name = name_radio,
425 .amux = LINE2,
426 },
427 },
428 [SAA7134_BOARD_KWORLD] = {
429 .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
430 .audio_clock = 0x00187de7,
431 .tuner_type = TUNER_PHILIPS_NTSC_M,
432 .inputs = {{
433 .name = name_svideo,
434 .vmux = 8,
435 .amux = LINE1,
436 },{
437 .name = name_comp1,
438 .vmux = 3,
439 .amux = LINE1,
440 },{
441 .name = name_tv,
442 .vmux = 1,
443 .amux = LINE2,
444 .tv = 1,
445 }},
446 },
447 [SAA7134_BOARD_CINERGY600] = {
448 .name = "Terratec Cinergy 600 TV",
449 .audio_clock = 0x00200000,
450 .tuner_type = TUNER_PHILIPS_PAL,
451 .tda9887_conf = TDA9887_PRESENT,
452 .inputs = {{
453 .name = name_tv,
454 .vmux = 1,
455 .amux = TV,
456 .tv = 1,
457 },{
458 .name = name_comp1,
459 .vmux = 4,
460 .amux = LINE1,
461 },{
462 .name = name_svideo,
463 .vmux = 8,
464 .amux = LINE1,
465 },{
466 .name = name_comp2, // CVideo over SVideo Connector
467 .vmux = 0,
468 .amux = LINE1,
469 }},
470 .radio = {
471 .name = name_radio,
472 .amux = LINE2,
473 },
474 },
475 [SAA7134_BOARD_MD7134] = {
476 .name = "Medion 7134",
477 //.audio_clock = 0x00200000,
478 .audio_clock = 0x00187de7,
479 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
480 .tda9887_conf = TDA9887_PRESENT,
481 .mpeg = SAA7134_MPEG_DVB,
482 .inputs = {{
483 .name = name_tv,
484 .vmux = 1,
485 .amux = TV,
486 .tv = 1,
487 },{
488 .name = name_comp1,
489 .vmux = 0,
490 .amux = LINE1,
491 },{
492 .name = name_svideo,
493 .vmux = 8,
494 .amux = LINE1,
495 }},
496 .radio = {
497 .name = name_radio,
498 .amux = LINE2,
499 },
500 },
501 [SAA7134_BOARD_TYPHOON_90031] = {
502 /* aka Typhoon "TV+Radio", Art.Nr 90031 */
503 /* Tom Zoerner <tomzo at users sourceforge net> */
504 .name = "Typhoon TV+Radio 90031",
505 .audio_clock = 0x00200000,
506 .tuner_type = TUNER_PHILIPS_PAL,
507 .tda9887_conf = TDA9887_PRESENT,
508 .inputs = {{
509 .name = name_tv,
510 .vmux = 1,
511 .amux = TV,
512 .tv = 1,
513 },{
514 .name = name_comp1,
515 .vmux = 3,
516 .amux = LINE1,
517 },{
518 .name = name_svideo,
519 .vmux = 8,
520 .amux = LINE1,
521 }},
522 .radio = {
523 .name = name_radio,
524 .amux = LINE2,
525 },
526 },
527 [SAA7134_BOARD_ELSA] = {
528 .name = "ELSA EX-VISION 300TV",
529 .audio_clock = 0x00187de7,
530 .tuner_type = TUNER_HITACHI_NTSC,
531 .inputs = {{
532 .name = name_svideo,
533 .vmux = 8,
534 .amux = LINE1,
535 },{
536 .name = name_comp1,
537 .vmux = 0,
538 .amux = LINE1,
539 },{
540 .name = name_tv,
541 .vmux = 4,
542 .amux = LINE2,
543 .tv = 1,
544 }},
545 },
546 [SAA7134_BOARD_ELSA_500TV] = {
547 .name = "ELSA EX-VISION 500TV",
548 .audio_clock = 0x00187de7,
549 .tuner_type = TUNER_HITACHI_NTSC,
550 .inputs = {{
551 .name = name_svideo,
552 .vmux = 7,
553 .amux = LINE1,
554 },{
555 .name = name_tv,
556 .vmux = 8,
557 .amux = TV,
558 .tv = 1,
559 },{
560 .name = name_tv_mono,
561 .vmux = 8,
562 .amux = LINE2,
563 .tv = 1,
564 }},
565 },
566 [SAA7134_BOARD_ASUSTeK_TVFM7134] = {
567 .name = "ASUS TV-FM 7134",
568 .audio_clock = 0x00187de7,
569 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
570 .tda9887_conf = TDA9887_PRESENT,
571 .inputs = {{
572 .name = name_tv,
573 .vmux = 1,
574 .amux = TV,
575 .tv = 1,
576 },{
577 .name = name_comp1,
578 .vmux = 4,
579 .amux = LINE2,
580 },{
581 .name = name_svideo,
582 .vmux = 6,
583 .amux = LINE2,
584 }},
585 .radio = {
586 .name = name_radio,
587 .amux = LINE1,
588 },
589 },
590 [SAA7135_BOARD_ASUSTeK_TVFM7135] = {
591 .name = "ASUS TV-FM 7135",
592 .audio_clock = 0x00187de7,
593 .tuner_type = TUNER_PHILIPS_TDA8290,
594 .gpiomask = 0x200000,
595 .inputs = {{
596 .name = name_tv,
597 .vmux = 1,
598 .amux = TV,
599 .gpio = 0x0000,
600 .tv = 1,
601 },{
602 .name = name_comp1,
603 .vmux = 4,
604 .amux = LINE2,
605 .gpio = 0x0000,
606 },{
607 .name = name_svideo,
608 .vmux = 6,
609 .amux = LINE2,
610 .gpio = 0x0000,
611 }},
612 .radio = {
613 .name = name_radio,
614 .amux = TV,
615 .gpio = 0x200000,
616 },
617 },
618 [SAA7134_BOARD_VA1000POWER] = {
619 .name = "AOPEN VA1000 POWER",
620 .audio_clock = 0x00187de7,
621 .tuner_type = TUNER_PHILIPS_NTSC,
622 .inputs = {{
623 .name = name_svideo,
624 .vmux = 8,
625 .amux = LINE1,
626 },{
627 .name = name_comp1,
628 .vmux = 3,
629 .amux = LINE1,
630 },{
631 .name = name_tv,
632 .vmux = 1,
633 .amux = LINE2,
634 .tv = 1,
635 }},
636 },
637 [SAA7134_BOARD_10MOONSTVMASTER] = {
638 /* "lilicheng" <llc@linuxfans.org> */
639 .name = "10MOONS PCI TV CAPTURE CARD",
640 .audio_clock = 0x00200000,
641 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
642 .gpiomask = 0xe000,
643 .inputs = {{
644 .name = name_tv,
645 .vmux = 1,
646 .amux = LINE2,
647 .gpio = 0x0000,
648 .tv = 1,
649 },{
650 .name = name_comp1,
651 .vmux = 0,
652 .amux = LINE2,
653 .gpio = 0x4000,
654 },{
655 .name = name_comp2,
656 .vmux = 3,
657 .amux = LINE2,
658 .gpio = 0x4000,
659 },{
660 .name = name_svideo,
661 .vmux = 8,
662 .amux = LINE2,
663 .gpio = 0x4000,
664 }},
665 .radio = {
666 .name = name_radio,
667 .amux = LINE2,
668 .gpio = 0x2000,
669 },
670 .mute = {
671 .name = name_mute,
672 .amux = LINE2,
673 .gpio = 0x8000,
674 },
675 },
676 [SAA7134_BOARD_BMK_MPEX_NOTUNER] = {
677 /* "Andrew de Quincey" <adq@lidskialf.net> */
678 .name = "BMK MPEX No Tuner",
679 .audio_clock = 0x200000,
680 .tuner_type = TUNER_ABSENT,
681 .inputs = {{
682 .name = name_comp1,
683 .vmux = 4,
684 .amux = LINE1,
685 },{
686 .name = name_comp2,
687 .vmux = 3,
688 .amux = LINE1,
689 },{
690 .name = name_comp3,
691 .vmux = 0,
692 .amux = LINE1,
693 },{
694 .name = name_comp4,
695 .vmux = 1,
696 .amux = LINE1,
697 },{
698 .name = name_svideo,
699 .vmux = 8,
700 .amux = LINE1,
701 }},
702 .mpeg = SAA7134_MPEG_EMPRESS,
703 .video_out = CCIR656,
704 },
705 [SAA7134_BOARD_VIDEOMATE_TV] = {
706 .name = "Compro VideoMate TV",
707 .audio_clock = 0x00187de7,
708 .tuner_type = TUNER_PHILIPS_NTSC_M,
709 .inputs = {{
710 .name = name_svideo,
711 .vmux = 8,
712 .amux = LINE1,
713 },{
714 .name = name_comp1,
715 .vmux = 3,
716 .amux = LINE1,
717 },{
718 .name = name_tv,
719 .vmux = 1,
720 .amux = LINE2,
721 .tv = 1,
722 }},
723 },
724 [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
725 .name = "Compro VideoMate TV Gold+",
726 .audio_clock = 0x00187de7,
727 .tuner_type = TUNER_PHILIPS_NTSC_M,
728 .gpiomask = 0x800c0000,
729 .inputs = {{
730 .name = name_svideo,
731 .vmux = 8,
732 .amux = LINE1,
733 .gpio = 0x06c00012,
734 },{
735 .name = name_comp1,
736 .vmux = 3,
737 .amux = LINE1,
738 .gpio = 0x0ac20012,
739 },{
740 .name = name_tv,
741 .vmux = 1,
742 .amux = LINE2,
743 .gpio = 0x08c20012,
744 .tv = 1,
745 }},
746 },
747 [SAA7134_BOARD_CRONOS_PLUS] = {
748 /* gpio pins:
749 0 .. 3 BASE_ID
750 4 .. 7 PROTECT_ID
751 8 .. 11 USER_OUT
752 12 .. 13 USER_IN
753 14 .. 15 VIDIN_SEL */
754 .name = "Matrox CronosPlus",
755 .tuner_type = TUNER_ABSENT,
756 .gpiomask = 0xcf00,
757 .inputs = {{
758 .name = name_comp1,
759 .vmux = 0,
760 .gpio = 2 << 14,
761 },{
762 .name = name_comp2,
763 .vmux = 0,
764 .gpio = 1 << 14,
765 },{
766 .name = name_comp3,
767 .vmux = 0,
768 .gpio = 0 << 14,
769 },{
770 .name = name_comp4,
771 .vmux = 0,
772 .gpio = 3 << 14,
773 },{
774 .name = name_svideo,
775 .vmux = 8,
776 .gpio = 2 << 14,
777 }},
778 },
779 [SAA7134_BOARD_MD2819] = {
780 .name = "AverMedia M156 / Medion 2819",
781 .audio_clock = 0x00187de7,
782 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
783 .tda9887_conf = TDA9887_PRESENT,
784 .inputs = {{
785 .name = name_tv,
786 .vmux = 1,
787 .amux = TV,
788 .tv = 1,
789 },{
790 .name = name_comp1,
791 .vmux = 0,
792 .amux = LINE2,
793 },{
794 .name = name_comp2,
795 .vmux = 3,
796 .amux = LINE2,
797 },{
798 .name = name_svideo,
799 .vmux = 8,
800 .amux = LINE2,
801 }},
802 .radio = {
803 .name = name_radio,
804 .amux = LINE2,
805 },
806 },
807 [SAA7134_BOARD_BMK_MPEX_TUNER] = {
808 /* "Greg Wickham <greg.wickham@grangenet.net> */
809 .name = "BMK MPEX Tuner",
810 .audio_clock = 0x200000,
811 .tuner_type = TUNER_PHILIPS_PAL,
812 .inputs = {{
813 .name = name_comp1,
814 .vmux = 1,
815 .amux = LINE1,
816 },{
817 .name = name_svideo,
818 .vmux = 8,
819 .amux = LINE1,
820 },{
821 .name = name_tv,
822 .vmux = 3,
823 .amux = TV,
824 .tv = 1,
825 }},
826 .mpeg = SAA7134_MPEG_EMPRESS,
827 .video_out = CCIR656,
828 },
829 [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
830 .name = "ASUS TV-FM 7133",
831 .audio_clock = 0x00187de7,
832 // probably wrong, the 7133 one is the NTSC version ...
833 // .tuner_type = TUNER_PHILIPS_FM1236_MK3
834 .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
835 .tda9887_conf = TDA9887_PRESENT,
836 .inputs = {{
837 .name = name_tv,
838 .vmux = 1,
839 .amux = TV,
840 .tv = 1,
841 },{
842 .name = name_comp1,
843 .vmux = 4,
844 .amux = LINE2,
845 },{
846 .name = name_svideo,
847 .vmux = 6,
848 .amux = LINE2,
849 }},
850 .radio = {
851 .name = name_radio,
852 .amux = LINE1,
853 },
854 },
855 [SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
856 .name = "Pinnacle PCTV Stereo (saa7134)",
857 .audio_clock = 0x00187de7,
858 .tuner_type = TUNER_MT2032,
859 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
860 .inputs = {{
861 .name = name_tv,
862 .vmux = 3,
863 .amux = TV,
864 .tv = 1,
865 },{
866 .name = name_comp1,
867 .vmux = 0,
868 .amux = LINE2,
869 },{
870 .name = name_comp2,
871 .vmux = 1,
872 .amux = LINE2,
873 },{
874 .name = name_svideo,
875 .vmux = 8,
876 .amux = LINE2,
877 }},
878 },
879 [SAA7134_BOARD_MANLI_MTV002] = {
880 /* Ognjen Nastic <ognjen@logosoft.ba> */
881 .name = "Manli MuchTV M-TV002",
882 .audio_clock = 0x00200000,
883 .tuner_type = TUNER_PHILIPS_PAL,
884 .inputs = {{
885 .name = name_svideo,
886 .vmux = 8,
887 .amux = LINE1,
888 },{
889 .name = name_comp1,
890 .vmux = 1,
891 .amux = LINE1,
892 },{
893 .name = name_tv,
894 .vmux = 3,
895 .amux = LINE2,
896 .tv = 1,
897 }},
898 .radio = {
899 .name = name_radio,
900 .amux = LINE2,
901 },
902 .mute = {
903 .name = name_mute,
904 .amux = LINE1,
905 },
906 },
907 [SAA7134_BOARD_MANLI_MTV001] = {
908 /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
909 .name = "Manli MuchTV M-TV001",
910 .audio_clock = 0x00200000,
911 .tuner_type = TUNER_PHILIPS_PAL,
912 .inputs = {{
913 .name = name_svideo,
914 .vmux = 8,
915 .amux = LINE1,
916 },{
917 .name = name_comp1,
918 .vmux = 1,
919 .amux = LINE1,
920 },{
921 .name = name_tv,
922 .vmux = 3,
923 .amux = LINE2,
924 .tv = 1,
925 }},
926 },
927 [SAA7134_BOARD_TG3000TV] = {
928 /* TransGear 3000TV */
929 .name = "Nagase Sangyo TransGear 3000TV",
930 .audio_clock = 0x00187de7,
931 .tuner_type = TUNER_PHILIPS_NTSC_M,
932 .inputs = {{
933 .name = name_tv,
934 .vmux = 1,
935 .amux = LINE2,
936 .tv = 1,
937 },{
938 .name = name_comp1,
939 .vmux = 3,
940 .amux = LINE2,
941 },{
942 .name = name_svideo,
943 .vmux = 8,
944 .amux = LINE2,
945 }},
946 },
947 [SAA7134_BOARD_ECS_TVP3XP] = {
948 .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
949 .audio_clock = 0x187de7, // xtal 32.1 MHz
950 .tuner_type = TUNER_PHILIPS_PAL,
951 .inputs = {{
952 .name = name_tv,
953 .vmux = 1,
954 .amux = TV,
955 .tv = 1,
956 },{
957 .name = name_tv_mono,
958 .vmux = 1,
959 .amux = LINE2,
960 .tv = 1,
961 },{
962 .name = name_comp1,
963 .vmux = 3,
964 .amux = LINE1,
965 },{
966 .name = name_svideo,
967 .vmux = 8,
968 .amux = LINE1,
969 },{
970 .name = "CVid over SVid",
971 .vmux = 0,
972 .amux = LINE1,
973 }},
974 .radio = {
975 .name = name_radio,
976 .amux = LINE2,
977 },
978 },
979 [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
980 .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
981 .audio_clock = 0x187de7,
982 .tuner_type = TUNER_PHILIPS_NTSC,
983 .inputs = {{
984 .name = name_tv,
985 .vmux = 1,
986 .amux = TV,
987 .tv = 1,
988 },{
989 .name = name_tv_mono,
990 .vmux = 1,
991 .amux = LINE2,
992 .tv = 1,
993 },{
994 .name = name_comp1,
995 .vmux = 3,
996 .amux = LINE1,
997 },{
998 .name = name_svideo,
999 .vmux = 8,
1000 .amux = LINE1,
1001 },{
1002 .name = "CVid over SVid",
1003 .vmux = 0,
1004 .amux = LINE1,
1005 }},
1006 .radio = {
1007 .name = name_radio,
1008 .amux = LINE2,
1009 },
1010 },
1011 [SAA7134_BOARD_AVACSSMARTTV] = {
1012 /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
1013 .name = "AVACS SmartTV",
1014 .audio_clock = 0x00187de7,
1015 .tuner_type = TUNER_PHILIPS_PAL,
1016 .inputs = {{
1017 .name = name_tv,
1018 .vmux = 1,
1019 .amux = TV,
1020 .tv = 1,
1021 },{
1022 .name = name_tv_mono,
1023 .vmux = 1,
1024 .amux = LINE2,
1025 .tv = 1,
1026 },{
1027 .name = name_comp1,
1028 .vmux = 0,
1029 .amux = LINE2,
1030 },{
1031 .name = name_comp2,
1032 .vmux = 3,
1033 .amux = LINE2,
1034 },{
1035 .name = name_svideo,
1036 .vmux = 8,
1037 .amux = LINE2,
1038 }},
1039 .radio = {
1040 .name = name_radio,
1041 .amux = LINE2,
1042 .gpio = 0x200000,
1043 },
1044 },
1045 [SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
1046 /* Michael Smith <msmith@cbnco.com> */
1047 .name = "AVerMedia DVD EZMaker",
1048 .audio_clock = 0x00187de7,
1049 .tuner_type = TUNER_ABSENT,
1050 .inputs = {{
1051 .name = name_comp1,
1052 .vmux = 3,
1053 },{
1054 .name = name_svideo,
1055 .vmux = 8,
1056 }},
1057 },
1058 [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
1059 /* toshii@netbsd.org */
1060 .name = "Noval Prime TV 7133",
1061 .audio_clock = 0x00200000,
1062 .tuner_type = TUNER_ALPS_TSBH1_NTSC,
1063 .inputs = {{
1064 .name = name_comp1,
1065 .vmux = 3,
1066 },{
1067 .name = name_tv,
1068 .vmux = 1,
1069 .amux = TV,
1070 .tv = 1,
1071 },{
1072 .name = name_svideo,
1073 .vmux = 8,
1074 }},
1075 },
1076 [SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
1077 .name = "AverMedia AverTV Studio 305",
1078 .audio_clock = 0x00187de7,
1079 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1080 .tda9887_conf = TDA9887_PRESENT,
1081 .gpiomask = 0x3,
1082 .inputs = {{
1083 .name = name_tv,
1084 .vmux = 1,
1085 .amux = LINE2,
1086 .tv = 1,
1087 },{
1088 .name = name_comp1,
1089 .vmux = 0,
1090 .amux = LINE2,
1091 },{
1092 .name = name_comp2,
1093 .vmux = 3,
1094 .amux = LINE2,
1095 },{
1096 .name = name_svideo,
1097 .vmux = 8,
1098 .amux = LINE2,
1099 }},
1100 .radio = {
1101 .name = name_radio,
1102 .amux = LINE2,
1103 },
1104 .mute = {
1105 .name = name_mute,
1106 .amux = LINE1,
1107 },
1108 },
1109 [SAA7133_BOARD_UPMOST_PURPLE_TV] = {
1110 .name = "UPMOST PURPLE TV",
1111 .audio_clock = 0x00187de7,
1112 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
1113 .tda9887_conf = TDA9887_PRESENT,
1114 .inputs = {{
1115 .name = name_tv,
1116 .vmux = 7,
1117 .amux = TV,
1118 .tv = 1,
1119 },{
1120 .name = name_svideo,
1121 .vmux = 7,
1122 .amux = LINE1,
1123 }},
1124 },
1125 [SAA7134_BOARD_ITEMS_MTV005] = {
1126 /* Norman Jonas <normanjonas@arcor.de> */
1127 .name = "Items MuchTV Plus / IT-005",
1128 .audio_clock = 0x00187de7,
1129 .tuner_type = TUNER_PHILIPS_PAL,
1130 .inputs = {{
1131 .name = name_tv,
1132 .vmux = 3,
1133 .amux = TV,
1134 .tv = 1,
1135 },{
1136 .name = name_comp1,
1137 .vmux = 1,
1138 .amux = LINE1,
1139 },{
1140 .name = name_svideo,
1141 .vmux = 8,
1142 .amux = LINE1,
1143 }},
1144 .radio = {
1145 .name = name_radio,
1146 .amux = LINE2,
1147 },
1148 },
1149 [SAA7134_BOARD_CINERGY200] = {
1150 .name = "Terratec Cinergy 200 TV",
1151 .audio_clock = 0x00200000,
1152 .tuner_type = TUNER_PHILIPS_PAL,
1153 .inputs = {{
1154 .name = name_tv,
1155 .vmux = 1,
1156 .amux = LINE2,
1157 .tv = 1,
1158 },{
1159 .name = name_comp1,
1160 .vmux = 4,
1161 .amux = LINE1,
1162 },{
1163 .name = name_svideo,
1164 .vmux = 8,
1165 .amux = LINE1,
1166 },{
1167 .name = name_comp2, // CVideo over SVideo Connector
1168 .vmux = 0,
1169 .amux = LINE1,
1170 }},
1171 .mute = {
1172 .name = name_mute,
1173 .amux = LINE2,
1174 },
1175 },
1176 [SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
1177 /* Alain St-Denis <alain@topaze.homeip.net> */
1178 .name = "Compro VideoMate TV PVR/FM",
1179 .audio_clock = 0x00187de7,
1180 .tuner_type = TUNER_PHILIPS_NTSC_M,
1181 .gpiomask = 0x808c0080,
1182 .inputs = {{
1183 .name = name_svideo,
1184 .vmux = 8,
1185 .amux = LINE1,
1186 .gpio = 0x00080,
1187 },{
1188 .name = name_comp1,
1189 .vmux = 3,
1190 .amux = LINE1,
1191 .gpio = 0x00080,
1192 },{
1193 .name = name_tv,
1194 .vmux = 1,
1195 .amux = LINE2_LEFT,
1196 .tv = 1,
1197 .gpio = 0x00080,
1198 }},
1199 .radio = {
1200 .name = name_radio,
1201 .amux = LINE2,
1202 .gpio = 0x80000,
1203 },
1204 .mute = {
1205 .name = name_mute,
1206 .amux = LINE2,
1207 .gpio = 0x40000,
1208 },
1209 },
1210 [SAA7134_BOARD_SABRENT_SBTTVFM] = {
1211 /* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
1212 .name = "Sabrent SBT-TVFM (saa7130)",
1213 .audio_clock = 0x00187de7,
1214 .tuner_type = TUNER_PHILIPS_NTSC_M,
1215 .inputs = {{
1216 .name = name_comp1,
1217 .vmux = 1,
1218 .amux = LINE2,
1219 },{
1220 .name = name_tv,
1221 .vmux = 3,
1222 .amux = LINE2,
1223 .tv = 1,
1224 },{
1225 .name = name_svideo,
1226 .vmux = 8,
1227 .amux = LINE2,
1228 }},
1229 .radio = {
1230 .name = name_radio,
1231 .amux = LINE2,
1232 },
1233 },
1234 [SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
1235 /* Helge Jensen <helge.jensen@slog.dk> */
1236 .name = ":Zolid Xpert TV7134",
1237 .audio_clock = 0x00187de7,
1238 .tuner_type = TUNER_PHILIPS_NTSC,
1239 .inputs = {{
1240 .name = name_svideo,
1241 .vmux = 8,
1242 .amux = LINE1,
1243 },{
1244 .name = name_comp1,
1245 .vmux = 3,
1246 .amux = LINE1,
1247 },{
1248 .name = name_tv,
1249 .vmux = 1,
1250 .amux = LINE2,
1251 .tv = 1,
1252 }},
1253 },
1254 [SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
1255 /* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
1256 .name = "Empire PCI TV-Radio LE",
1257 .audio_clock = 0x00187de7,
1258 .tuner_type = TUNER_PHILIPS_PAL,
1259 .gpiomask = 0x4000,
1260 .inputs = {{
1261 .name = name_tv_mono,
1262 .vmux = 1,
1263 .amux = LINE2,
1264 .gpio = 0x8000,
1265 .tv = 1,
1266 },{
1267 .name = name_comp1,
1268 .vmux = 3,
1269 .amux = LINE1,
1270 .gpio = 0x8000,
1271 },{
1272 .name = name_svideo,
1273 .vmux = 6,
1274 .amux = LINE1,
1275 .gpio = 0x8000,
1276 }},
1277 .radio = {
1278 .name = name_radio,
1279 .amux = LINE1,
1280 .gpio = 0x8000,
1281 },
1282 .mute = {
1283 .name = name_mute,
1284 .amux = TV,
1285 .gpio =0x8000,
1286 }
1287 },
1288 [SAA7134_BOARD_AVERMEDIA_307] = {
1289 /*
1290 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
1291 Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
1292 */
1293 .name = "Avermedia AVerTV Studio 307",
1294 .audio_clock = 0x00187de7,
1295 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1296 .tda9887_conf = TDA9887_PRESENT,
1297 .gpiomask = 0x03,
1298 .inputs = {{
1299 .name = name_tv,
1300 .vmux = 1,
1301 .amux = TV,
1302 .tv = 1,
1303 .gpio = 0x00,
1304 },{
1305 .name = name_comp1,
1306 .vmux = 0,
1307 .amux = LINE2,
1308 .gpio = 0x00,
1309 },{
1310 .name = name_comp2,
1311 .vmux = 3,
1312 .amux = LINE2,
1313 .gpio = 0x00,
1314 },{
1315 .name = name_svideo,
1316 .vmux = 8,
1317 .amux = LINE2,
1318 .gpio = 0x00,
1319 }},
1320 .radio = {
1321 .name = name_radio,
1322 .amux = LINE1,
1323 .gpio = 0x01,
1324 },
1325 },
1326 [SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
1327 /* Jon Westgate <oryn@oryn.fsck.tv> */
1328 .name = "AVerMedia Cardbus TV/Radio",
1329 .audio_clock = 0x00200000,
1330 .tuner_type = TUNER_PHILIPS_PAL,
1331 .inputs = {{
1332 .name = name_tv,
1333 .vmux = 1,
1334 .amux = LINE2,
1335 .tv = 1,
1336 },{
1337 .name = name_comp1,
1338 .vmux = 3,
1339 .amux = LINE2,
1340 },{
1341 .name = name_svideo,
1342 .vmux = 8,
1343 .amux = LINE2,
1344 }},
1345 .radio = {
1346 .name = name_radio,
1347 .amux = LINE1,
1348 },
1349 },
1350 [SAA7134_BOARD_CINERGY400_CARDBUS] = {
1351 .name = "Terratec Cinergy 400 mobile",
1352 .audio_clock = 0x187de7,
1353 .tuner_type = TUNER_ALPS_TSBE5_PAL,
1354 .tda9887_conf = TDA9887_PRESENT,
1355 .inputs = {{
1356 .name = name_tv,
1357 .vmux = 1,
1358 .amux = TV,
1359 .tv = 1,
1360 },{
1361 .name = name_tv_mono,
1362 .vmux = 1,
1363 .amux = LINE2,
1364 .tv = 1,
1365 },{
1366 .name = name_comp1,
1367 .vmux = 3,
1368 .amux = LINE1,
1369 },{
1370 .name = name_svideo,
1371 .vmux = 8,
1372 .amux = LINE1,
1373 }},
1374 },
1375 [SAA7134_BOARD_CINERGY600_MK3] = {
1376 .name = "Terratec Cinergy 600 TV MK3",
1377 .audio_clock = 0x00200000,
1378 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1379 .tda9887_conf = TDA9887_PRESENT,
1380 .inputs = {{
1381 .name = name_tv,
1382 .vmux = 1,
1383 .amux = TV,
1384 .tv = 1,
1385 },{
1386 .name = name_comp1,
1387 .vmux = 4,
1388 .amux = LINE1,
1389 },{
1390 .name = name_svideo,
1391 .vmux = 8,
1392 .amux = LINE1,
1393 },{
1394 .name = name_comp2, // CVideo over SVideo Connector
1395 .vmux = 0,
1396 .amux = LINE1,
1397 }},
1398 .radio = {
1399 .name = name_radio,
1400 .amux = LINE2,
1401 },
1402 },
1403 [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
1404 /* Dylan Walkden <dylan_walkden@hotmail.com> */
1405 .name = "Compro VideoMate Gold+ Pal",
1406 .audio_clock = 0x00187de7,
1407 .tuner_type = TUNER_PHILIPS_PAL,
1408 .gpiomask = 0x1ce780,
1409 .inputs = {{
1410 .name = name_svideo,
1411 .vmux = 0, // CVideo over SVideo Connector - ok?
1412 .amux = LINE1,
1413 .gpio = 0x008080,
1414 },{
1415 .name = name_comp1,
1416 .vmux = 3,
1417 .amux = LINE1,
1418 .gpio = 0x008080,
1419 },{
1420 .name = name_tv,
1421 .vmux = 1,
1422 .amux = TV,
1423 .tv = 1,
1424 .gpio = 0x008080,
1425 }},
1426 .radio = {
1427 .name = name_radio,
1428 .amux = LINE2,
1429 .gpio = 0x80000,
1430 },
1431 .mute = {
1432 .name = name_mute,
1433 .amux = LINE2,
1434 .gpio = 0x0c8000,
1435 },
1436 },
1437 [SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
1438 .name = "Pinnacle PCTV 300i DVB-T + PAL",
1439 .audio_clock = 0x00187de7,
1440 .tuner_type = TUNER_MT2032,
1441 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
1442 .mpeg = SAA7134_MPEG_DVB,
1443 .inputs = {{
1444 .name = name_tv,
1445 .vmux = 3,
1446 .amux = TV,
1447 .tv = 1,
1448 },{
1449 .name = name_comp1,
1450 .vmux = 0,
1451 .amux = LINE2,
1452 },{
1453 .name = name_comp2,
1454 .vmux = 1,
1455 .amux = LINE2,
1456 },{
1457 .name = name_svideo,
1458 .vmux = 8,
1459 .amux = LINE2,
1460 }},
1461 },
1462 [SAA7134_BOARD_PROVIDEO_PV952] = {
1463 /* andreas.kretschmer@web.de */
1464 .name = "ProVideo PV952",
1465 .audio_clock = 0x00187de7,
1466 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1467 .tda9887_conf = TDA9887_PRESENT,
1468 .inputs = {{
1469 .name = name_comp1,
1470 .vmux = 0,
1471 .amux = LINE1,
1472 },{
1473 .name = name_tv,
1474 .vmux = 1,
1475 .amux = TV,
1476 .tv = 1,
1477 },{
1478 .name = name_tv_mono,
1479 .vmux = 1,
1480 .amux = LINE2,
1481 .tv = 1,
1482 }},
1483 .radio = {
1484 .name = name_radio,
1485 .amux = LINE2,
1486 },
1487 },
1488 [SAA7134_BOARD_AVERMEDIA_305] = {
1489 /* much like the "studio" version but without radio
1490 * and another tuner (sirspiritus@yandex.ru) */
1491 .name = "AverMedia AverTV/305",
1492 .audio_clock = 0x00187de7,
1493 .tuner_type = TUNER_PHILIPS_FQ1216ME,
1494 .tda9887_conf = TDA9887_PRESENT,
1495 .gpiomask = 0x3,
1496 .inputs = {{
1497 .name = name_tv,
1498 .vmux = 1,
1499 .amux = LINE2,
1500 .tv = 1,
1501 },{
1502 .name = name_comp1,
1503 .vmux = 0,
1504 .amux = LINE2,
1505 },{
1506 .name = name_comp2,
1507 .vmux = 3,
1508 .amux = LINE2,
1509 },{
1510 .name = name_svideo,
1511 .vmux = 8,
1512 .amux = LINE2,
1513 }},
1514 .mute = {
1515 .name = name_mute,
1516 .amux = LINE1,
1517 },
1518 },
1519 [SAA7134_BOARD_FLYDVBTDUO] = {
1520 /* LifeView FlyDVB-T DUO */
1521 /* "Nico Sabbi <nsabbi@tiscali.it> */
1522 .name = "LifeView FlyDVB-T DUO",
1523 .audio_clock = 0x00200000,
1524 .tuner_type = TUNER_PHILIPS_TDA8290,
1525// .gpiomask = 0xe000,
1526 .inputs = {{
1527 .name = name_tv,
1528 .vmux = 1,
1529 .amux = TV,
1530// .gpio = 0x0000,
1531 .tv = 1,
1532 },{
1533 .name = name_comp1, /* Composite signal on S-Video input */
1534 .vmux = 0,
1535 .amux = LINE2,
1536// .gpio = 0x4000,
1537 },{
1538 .name = name_comp2, /* Composite input */
1539 .vmux = 3,
1540 .amux = LINE2,
1541// .gpio = 0x4000,
1542 },{
1543 .name = name_svideo, /* S-Video signal on S-Video input */
1544 .vmux = 8,
1545 .amux = LINE2,
1546// .gpio = 0x4000,
1547 }},
1548 },
1549};
1550const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
1551
1552/* ------------------------------------------------------------------ */
1553/* PCI ids + subsystem IDs */
1554
1555struct pci_device_id saa7134_pci_tbl[] = {
1556 {
1557 .vendor = PCI_VENDOR_ID_PHILIPS,
1558 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1559 .subvendor = PCI_VENDOR_ID_PHILIPS,
1560 .subdevice = 0x2001,
1561 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1562 },{
1563 .vendor = PCI_VENDOR_ID_PHILIPS,
1564 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1565 .subvendor = PCI_VENDOR_ID_PHILIPS,
1566 .subdevice = 0x2001,
1567 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1568 },{
1569 .vendor = PCI_VENDOR_ID_PHILIPS,
1570 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1571 .subvendor = PCI_VENDOR_ID_PHILIPS,
1572 .subdevice = 0x6752,
1573 .driver_data = SAA7134_BOARD_EMPRESS,
1574 },{
1575 .vendor = PCI_VENDOR_ID_PHILIPS,
1576 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1577 .subvendor = 0x1131,
1578 .subdevice = 0x4e85,
1579 .driver_data = SAA7134_BOARD_MONSTERTV,
1580 },{
1581 .vendor = PCI_VENDOR_ID_PHILIPS,
1582 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1583 .subvendor = 0x153B,
1584 .subdevice = 0x1142,
1585 .driver_data = SAA7134_BOARD_CINERGY400,
1586 },{
1587 .vendor = PCI_VENDOR_ID_PHILIPS,
1588 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1589 .subvendor = 0x153B,
1590 .subdevice = 0x1143,
1591 .driver_data = SAA7134_BOARD_CINERGY600,
1592 },{
1593 .vendor = PCI_VENDOR_ID_PHILIPS,
1594 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1595 .subvendor = 0x153B,
1596 .subdevice = 0x1158,
1597 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
1598 },{
1599 .vendor = PCI_VENDOR_ID_PHILIPS,
1600 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1601 .subvendor = 0x153b,
1602 .subdevice = 0x1162,
1603 .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
1604 },{
1605 .vendor = PCI_VENDOR_ID_PHILIPS,
1606 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1607 .subvendor = 0x5168,
1608 .subdevice = 0x0138,
1609 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1610 },{
1611 .vendor = PCI_VENDOR_ID_PHILIPS,
1612 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1613 .subvendor = 0x4e42, //"Typhoon PCI Capture TV Card" Art.No. 50673
1614 .subdevice = 0x0138,
1615 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1616 },{
1617 .vendor = PCI_VENDOR_ID_PHILIPS,
1618 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1619 .subvendor = 0x5168,
1620 .subdevice = 0x0138,
1621 .driver_data = SAA7134_BOARD_FLYVIDEO2000,
1622 },{
1623 .vendor = PCI_VENDOR_ID_PHILIPS,
1624 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1625 .subvendor = 0x5168,
1626 .subdevice = 0x0212, /* minipci, LR212 */
1627 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
1628 },{
1629 .vendor = PCI_VENDOR_ID_PHILIPS,
1630 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1631 .subvendor = 0x5168,
1632 .subdevice = 0x0214, /* Standard PCI, LR214WF */
1633 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
1634 },{
1635 .vendor = PCI_VENDOR_ID_PHILIPS,
1636 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1637 .subvendor = 0x16be,
1638 .subdevice = 0x0003,
1639 .driver_data = SAA7134_BOARD_MD7134,
1640 },{
1641 .vendor = PCI_VENDOR_ID_PHILIPS,
1642 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1643 .subvendor = 0x1048,
1644 .subdevice = 0x226b,
1645 .driver_data = SAA7134_BOARD_ELSA,
1646 },{
1647 .vendor = PCI_VENDOR_ID_PHILIPS,
1648 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1649 .subvendor = 0x1048,
1650 .subdevice = 0x226b,
1651 .driver_data = SAA7134_BOARD_ELSA_500TV,
1652 },{
1653 .vendor = PCI_VENDOR_ID_PHILIPS,
1654 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1655 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1656 .subdevice = 0x4842,
1657 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1658 },{
1659 .vendor = PCI_VENDOR_ID_PHILIPS,
1660 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1661 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1662 .subdevice = 0x4845,
1663 .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
1664 },{
1665 .vendor = PCI_VENDOR_ID_PHILIPS,
1666 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1667 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1668 .subdevice = 0x4830,
1669 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1670 },{
1671 .vendor = PCI_VENDOR_ID_PHILIPS,
1672 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1673 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1674 .subdevice = 0x4843,
1675 .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
1676 },{
1677 .vendor = PCI_VENDOR_ID_PHILIPS,
1678 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1679 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1680 .subdevice = 0x4840,
1681 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1682 },{
1683 .vendor = PCI_VENDOR_ID_PHILIPS,
1684 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1685 .subvendor = PCI_VENDOR_ID_PHILIPS,
1686 .subdevice = 0xfe01,
1687 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1688 },{
1689 .vendor = PCI_VENDOR_ID_PHILIPS,
1690 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1691 .subvendor = 0x1894,
1692 .subdevice = 0xfe01,
1693 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1694 },{
1695 .vendor = PCI_VENDOR_ID_PHILIPS,
1696 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1697 .subvendor = 0x1894,
1698 .subdevice = 0xa006,
1699 .driver_data = SAA7134_BOARD_TVSTATION_DVR,
1700 },{
1701 .vendor = PCI_VENDOR_ID_PHILIPS,
1702 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1703 .subvendor = 0x1131,
1704 .subdevice = 0x7133,
1705 .driver_data = SAA7134_BOARD_VA1000POWER,
1706 },{
1707 .vendor = PCI_VENDOR_ID_PHILIPS,
1708 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1709 .subvendor = PCI_VENDOR_ID_PHILIPS,
1710 .subdevice = 0x2001,
1711 .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
1712 },{
1713 .vendor = PCI_VENDOR_ID_PHILIPS,
1714 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1715 .subvendor = 0x185b,
1716 .subdevice = 0xc100,
1717 .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
1718 },{
1719 .vendor = PCI_VENDOR_ID_PHILIPS,
1720 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1721 .subvendor = 0x185b,
1722 .subdevice = 0xc100,
1723 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
1724 },{
1725 .vendor = PCI_VENDOR_ID_PHILIPS,
1726 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1727 .subvendor = PCI_VENDOR_ID_MATROX,
1728 .subdevice = 0x48d0,
1729 .driver_data = SAA7134_BOARD_CRONOS_PLUS,
1730 },{
1731 .vendor = PCI_VENDOR_ID_PHILIPS,
1732 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1733 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1734 .subdevice = 0xa70b,
1735 .driver_data = SAA7134_BOARD_MD2819,
1736 },{
1737 .vendor = PCI_VENDOR_ID_PHILIPS,
1738 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1739 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1740 .subdevice = 0x2115,
1741 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
1742 },{
1743 .vendor = PCI_VENDOR_ID_PHILIPS,
1744 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1745 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1746 .subdevice = 0x2108,
1747 .driver_data = SAA7134_BOARD_AVERMEDIA_305,
1748 },{
1749 .vendor = PCI_VENDOR_ID_PHILIPS,
1750 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1751 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1752 .subdevice = 0x10ff,
1753 .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
1754 },{
1755 /* AVerMedia CardBus */
1756 .vendor = PCI_VENDOR_ID_PHILIPS,
1757 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1758 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1759 .subdevice = 0xd6ee,
1760 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
1761 },{
1762 /* TransGear 3000TV */
1763 .vendor = PCI_VENDOR_ID_PHILIPS,
1764 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1765 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1766 .subdevice = 0x050c,
1767 .driver_data = SAA7134_BOARD_TG3000TV,
1768 },{
1769 .vendor = PCI_VENDOR_ID_PHILIPS,
1770 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1771 .subvendor = 0x11bd,
1772 .subdevice = 0x002b,
1773 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
1774 },{
1775 .vendor = PCI_VENDOR_ID_PHILIPS,
1776 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1777 .subvendor = 0x11bd,
1778 .subdevice = 0x002d,
1779 .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
1780 },{
1781 .vendor = PCI_VENDOR_ID_PHILIPS,
1782 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1783 .subvendor = 0x1019,
1784 .subdevice = 0x4cb4,
1785 .driver_data = SAA7134_BOARD_ECS_TVP3XP,
1786 },{
1787 .vendor = PCI_VENDOR_ID_PHILIPS,
1788 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1789 .subvendor = 0x1019,
1790 .subdevice = 0x4cb5,
1791 .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
1792 },{
1793 .vendor = PCI_VENDOR_ID_PHILIPS,
1794 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1795 .subvendor = 0x12ab,
1796 .subdevice = 0x0800,
1797 .driver_data = SAA7133_BOARD_UPMOST_PURPLE_TV,
1798 },{
1799 .vendor = PCI_VENDOR_ID_PHILIPS,
1800 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1801 .subvendor = 0x153B,
1802 .subdevice = 0x1152,
1803 .driver_data = SAA7134_BOARD_CINERGY200,
1804 },{
1805 .vendor = PCI_VENDOR_ID_PHILIPS,
1806 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1807 .subvendor = 0x185b,
1808 .subdevice = 0xc100,
1809 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
1810 },{
1811 .vendor = PCI_VENDOR_ID_PHILIPS,
1812 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1813 .subvendor = 0x1131,
1814 .subdevice = 0,
1815 .driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
1816 },{
1817 .vendor = PCI_VENDOR_ID_PHILIPS,
1818 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1819 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1820 .subdevice = 0x9715,
1821 .driver_data = SAA7134_BOARD_AVERMEDIA_307,
1822 },{
1823 .vendor = PCI_VENDOR_ID_PHILIPS,
1824 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1825 .subvendor = 0x185b,
1826 .subdevice = 0xc200,
1827 .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
1828 },{
1829 .vendor = PCI_VENDOR_ID_PHILIPS,
1830 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1831 .subvendor = 0x1540,
1832 .subdevice = 0x9524,
1833 .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
1834
1835 },{
1836 .vendor = PCI_VENDOR_ID_PHILIPS,
1837 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1838 .subvendor = 0x5168,
1839 .subdevice = 0x0306,
1840 .driver_data = SAA7134_BOARD_FLYDVBTDUO,
1841
1842 },{
1843 /* --- boards without eeprom + subsystem ID --- */
1844 .vendor = PCI_VENDOR_ID_PHILIPS,
1845 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1846 .subvendor = PCI_VENDOR_ID_PHILIPS,
1847 .subdevice = 0,
1848 .driver_data = SAA7134_BOARD_NOAUTO,
1849 },{
1850 .vendor = PCI_VENDOR_ID_PHILIPS,
1851 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1852 .subvendor = PCI_VENDOR_ID_PHILIPS,
1853 .subdevice = 0,
1854 .driver_data = SAA7134_BOARD_NOAUTO,
1855 },{
1856
1857 /* --- default catch --- */
1858 .vendor = PCI_VENDOR_ID_PHILIPS,
1859 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1860 .subvendor = PCI_ANY_ID,
1861 .subdevice = PCI_ANY_ID,
1862 .driver_data = SAA7134_BOARD_UNKNOWN,
1863 },{
1864 .vendor = PCI_VENDOR_ID_PHILIPS,
1865 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1866 .subvendor = PCI_ANY_ID,
1867 .subdevice = PCI_ANY_ID,
1868 .driver_data = SAA7134_BOARD_UNKNOWN,
1869 },{
1870 .vendor = PCI_VENDOR_ID_PHILIPS,
1871 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1872 .subvendor = PCI_ANY_ID,
1873 .subdevice = PCI_ANY_ID,
1874 .driver_data = SAA7134_BOARD_UNKNOWN,
1875 },{
1876 .vendor = PCI_VENDOR_ID_PHILIPS,
1877 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1878 .subvendor = PCI_ANY_ID,
1879 .subdevice = PCI_ANY_ID,
1880 .driver_data = SAA7134_BOARD_UNKNOWN,
1881 },{
1882 /* --- end of list --- */
1883 }
1884};
1885MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
1886
1887/* ----------------------------------------------------------- */
1888/* flyvideo tweaks */
1889
1890#if 0
1891static struct {
1892 char *model;
1893 int tuner_type;
1894} fly_list[0x20] = {
1895 /* default catch ... */
1896 [ 0 ... 0x1f ] = {
1897 .model = "UNKNOWN",
1898 .tuner_type = TUNER_ABSENT,
1899 },
1900 /* ... the ones known so far */
1901 [ 0x05 ] = {
1902 .model = "PAL-BG",
1903 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
1904 },
1905 [ 0x10 ] = {
1906 .model = "PAL-BG / PAL-DK",
1907 .tuner_type = TUNER_PHILIPS_PAL,
1908 },
1909 [ 0x15 ] = {
1910 .model = "NTSC",
1911 .tuner_type = TUNER_ABSENT /* FIXME */,
1912 },
1913};
1914#endif
1915
1916static void board_flyvideo(struct saa7134_dev *dev)
1917{
1918#if 0
1919 /* non-working attempt to detect the correct tuner type ... */
1920 u32 value;
1921 int index;
1922
1923 value = dev->gpio_value;
1924 index = (value & 0x1f00) >> 8;
1925 printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
1926 dev->name, value, fly_list[index].model,
1927 fly_list[index].tuner_type);
1928 dev->tuner_type = fly_list[index].tuner_type;
1929#endif
1930 printk("%s: there are different flyvideo cards with different tuners\n"
1931 "%s: out there, you might have to use the tuner=<nr> insmod\n"
1932 "%s: option to override the default value.\n",
1933 dev->name, dev->name, dev->name);
1934}
1935
1936/* ----------------------------------------------------------- */
1937
1938int saa7134_board_init1(struct saa7134_dev *dev)
1939{
1940 // Always print gpio, often manufacturers encode tuner type and other info.
1941 saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
1942 dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
1943 printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
1944
1945 switch (dev->board) {
1946 case SAA7134_BOARD_FLYVIDEO2000:
1947 case SAA7134_BOARD_FLYVIDEO3000:
1948 dev->has_remote = 1;
1949 board_flyvideo(dev);
1950 break;
1951 case SAA7134_BOARD_CINERGY400:
1952 case SAA7134_BOARD_CINERGY600:
1953 case SAA7134_BOARD_CINERGY600_MK3:
1954 case SAA7134_BOARD_ECS_TVP3XP:
1955 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
1956 case SAA7134_BOARD_MD2819:
1957 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
1958 case SAA7134_BOARD_AVERMEDIA_305:
1959 case SAA7134_BOARD_AVERMEDIA_307:
1960// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
1961 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
1962 dev->has_remote = 1;
1963 break;
1964 case SAA7134_BOARD_AVACSSMARTTV:
1965 dev->has_remote = 1;
1966 break;
1967 case SAA7134_BOARD_MD5044:
1968 printk("%s: seems there are two different versions of the MD5044\n"
1969 "%s: (with the same ID) out there. If sound doesn't work for\n"
1970 "%s: you try the audio_clock_override=0x200000 insmod option.\n",
1971 dev->name,dev->name,dev->name);
1972 break;
1973 case SAA7134_BOARD_CINERGY400_CARDBUS:
1974 /* power-up tuner chip */
1975 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
1976 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
1977 msleep(1);
1978 break;
1979 }
1980 if (dev->has_remote)
1981 dev->irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
1982 SAA7134_IRQ2_INTE_GPIO18A |
1983 SAA7134_IRQ2_INTE_GPIO16 );
1984 return 0;
1985}
1986
1987/* stuff which needs working i2c */
1988int saa7134_board_init2(struct saa7134_dev *dev)
1989{
1990 unsigned char buf;
1991 int board;
1992
1993 switch (dev->board) {
1994 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
1995 case SAA7134_BOARD_BMK_MPEX_TUNER:
1996 dev->i2c_client.addr = 0x60;
1997 board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0)
1998 ? SAA7134_BOARD_BMK_MPEX_NOTUNER
1999 : SAA7134_BOARD_BMK_MPEX_TUNER;
2000 if (board == dev->board)
2001 break;
2002 dev->board = board;
2003 printk("%s: board type fixup: %s\n", dev->name,
2004 saa7134_boards[dev->board].name);
2005 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
2006 if (TUNER_ABSENT != dev->tuner_type)
2007 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
2008 break;
2009 }
2010 return 0;
2011}
2012
2013/* ----------------------------------------------------------- */
2014/*
2015 * Local variables:
2016 * c-basic-offset: 8
2017 * End:
2018 */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
new file mode 100644
index 000000000000..d506cafba8ff
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -0,0 +1,1237 @@
1/*
2 * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * driver core
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/config.h>
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/kmod.h>
32#include <linux/sound.h>
33#include <linux/interrupt.h>
34#include <linux/delay.h>
35
36#include "saa7134-reg.h"
37#include "saa7134.h"
38
39MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43/* ------------------------------------------------------------------ */
44
45static unsigned int irq_debug = 0;
46module_param(irq_debug, int, 0644);
47MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
48
49static unsigned int core_debug = 0;
50module_param(core_debug, int, 0644);
51MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
52
53static unsigned int gpio_tracking = 0;
54module_param(gpio_tracking, int, 0644);
55MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
56
57static unsigned int oss = 0;
58module_param(oss, int, 0444);
59MODULE_PARM_DESC(oss,"register oss devices (default: no)");
60
61static unsigned int latency = UNSET;
62module_param(latency, int, 0444);
63MODULE_PARM_DESC(latency,"pci latency timer");
64
65static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
66static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
67static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
68static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
69static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
70static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
71static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
72
73module_param_array(video_nr, int, NULL, 0444);
74module_param_array(vbi_nr, int, NULL, 0444);
75module_param_array(radio_nr, int, NULL, 0444);
76module_param_array(dsp_nr, int, NULL, 0444);
77module_param_array(mixer_nr, int, NULL, 0444);
78module_param_array(tuner, int, NULL, 0444);
79module_param_array(card, int, NULL, 0444);
80
81MODULE_PARM_DESC(video_nr, "video device number");
82MODULE_PARM_DESC(vbi_nr, "vbi device number");
83MODULE_PARM_DESC(radio_nr, "radio device number");
84MODULE_PARM_DESC(dsp_nr, "oss dsp device number");
85MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
86MODULE_PARM_DESC(tuner, "tuner type");
87MODULE_PARM_DESC(card, "card type");
88
89static DECLARE_MUTEX(devlist_lock);
90LIST_HEAD(saa7134_devlist);
91static LIST_HEAD(mops_list);
92static unsigned int saa7134_devcount;
93
94#define dprintk(fmt, arg...) if (core_debug) \
95 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
96
97/* ------------------------------------------------------------------ */
98/* debug help functions */
99
100static const char *v4l1_ioctls[] = {
101 "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
102 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
103 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
104 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
105 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
106#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
107
108static const char *v4l2_ioctls[] = {
109 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
110 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
111 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
112 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
113 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
114 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
115 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
116 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
117 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
118 "S_MODULATOR"
119};
120#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
121
122static const char *osspcm_ioctls[] = {
123 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
124 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
125 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
126 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
127 "SETDUPLEX", "GETODELAY"
128};
129#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
130
131void saa7134_print_ioctl(char *name, unsigned int cmd)
132{
133 char *dir;
134
135 switch (_IOC_DIR(cmd)) {
136 case _IOC_NONE: dir = "--"; break;
137 case _IOC_READ: dir = "r-"; break;
138 case _IOC_WRITE: dir = "-w"; break;
139 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
140 default: dir = "??"; break;
141 }
142 switch (_IOC_TYPE(cmd)) {
143 case 'v':
144 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
145 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
146 v4l1_ioctls[_IOC_NR(cmd)] : "???");
147 break;
148 case 'V':
149 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
150 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
151 v4l2_ioctls[_IOC_NR(cmd)] : "???");
152 break;
153 case 'P':
154 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
155 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
156 osspcm_ioctls[_IOC_NR(cmd)] : "???");
157 break;
158 case 'M':
159 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
160 name, cmd, dir, _IOC_NR(cmd));
161 break;
162 default:
163 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
164 name, cmd, dir, _IOC_NR(cmd));
165 }
166}
167
168void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
169{
170 unsigned long mode,status;
171
172 if (!gpio_tracking)
173 return;
174 /* rising SAA7134_GPIO_GPRESCAN reads the status */
175 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
176 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
177 mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff;
178 status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
179 printk(KERN_DEBUG
180 "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
181 dev->name, mode, (~mode) & status, mode & status, msg);
182}
183
184/* ------------------------------------------------------------------ */
185
186#if 0
187static char *dec1_bits[8] = {
188 "DCSTD0", "DCSCT1", "WIPA", "GLIMB",
189 "GLIMT", "SLTCA", "HLCK"
190};
191static char *dec2_bits[8] = {
192 "RDCAP", "COPRO", "COLSTR", "TYPE3",
193 NULL, "FIDT", "HLVLN", "INTL"
194};
195static char *scale1_bits[8] = {
196 "VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
197};
198static char *scale2_bits[8] = {
199 "TRERR", "CFERR", "LDERR", "WASRST",
200 "FIDSCI", "FIDSCO", "D6^D5", "TASK"
201};
202
203static void dump_statusreg(struct saa7134_dev *dev, int reg,
204 char *regname, char **bits)
205{
206 int value,i;
207
208 value = saa_readb(reg);
209 printk(KERN_DEBUG "%s: %s:", dev->name, regname);
210 for (i = 7; i >= 0; i--) {
211 if (NULL == bits[i])
212 continue;
213 printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
214 }
215 printk("\n");
216}
217
218static void dump_statusregs(struct saa7134_dev *dev)
219{
220 dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
221 dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
222 dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
223 dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
224}
225#endif
226
227/* ----------------------------------------------------------- */
228/* delayed request_module */
229
230#ifdef CONFIG_MODULES
231
232static int need_empress;
233static int need_dvb;
234
235static int pending_call(struct notifier_block *self, unsigned long state,
236 void *module)
237{
238 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
239 return NOTIFY_DONE;
240
241 if (need_empress)
242 request_module("saa7134-empress");
243 if (need_dvb)
244 request_module("saa7134-dvb");
245 return NOTIFY_DONE;
246}
247
248static int pending_registered;
249static struct notifier_block pending_notifier = {
250 .notifier_call = pending_call,
251};
252
253static void request_module_depend(char *name, int *flag)
254{
255 switch (THIS_MODULE->state) {
256 case MODULE_STATE_COMING:
257 if (!pending_registered) {
258 register_module_notifier(&pending_notifier);
259 pending_registered = 1;
260 }
261 *flag = 1;
262 break;
263 case MODULE_STATE_LIVE:
264 request_module(name);
265 break;
266 default:
267 /* nothing */;
268 break;
269 }
270}
271
272#else
273
274#define request_module_depend(name,flag)
275
276#endif /* CONFIG_MODULES */
277
278/* ------------------------------------------------------------------ */
279
280/* nr of (saa7134-)pages for the given buffer size */
281static int saa7134_buffer_pages(int size)
282{
283 size = PAGE_ALIGN(size);
284 size += PAGE_SIZE; /* for non-page-aligned buffers */
285 size /= 4096;
286 return size;
287}
288
289/* calc max # of buffers from size (must not exceed the 4MB virtual
290 * address space per DMA channel) */
291int saa7134_buffer_count(unsigned int size, unsigned int count)
292{
293 unsigned int maxcount;
294
295 maxcount = 1024 / saa7134_buffer_pages(size);
296 if (count > maxcount)
297 count = maxcount;
298 return count;
299}
300
301int saa7134_buffer_startpage(struct saa7134_buf *buf)
302{
303 return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
304}
305
306unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
307{
308 unsigned long base;
309
310 base = saa7134_buffer_startpage(buf) * 4096;
311 base += buf->vb.dma.sglist[0].offset;
312 return base;
313}
314
315/* ------------------------------------------------------------------ */
316
317int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
318{
319 u32 *cpu;
320 dma_addr_t dma_addr;
321
322 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
323 if (NULL == cpu)
324 return -ENOMEM;
325 pt->size = SAA7134_PGTABLE_SIZE;
326 pt->cpu = cpu;
327 pt->dma = dma_addr;
328 return 0;
329}
330
331int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
332 struct scatterlist *list, unsigned int length,
333 unsigned int startpage)
334{
335 u32 *ptr;
336 unsigned int i,p;
337
338 BUG_ON(NULL == pt || NULL == pt->cpu);
339
340 ptr = pt->cpu + startpage;
341 for (i = 0; i < length; i++, list++)
342 for (p = 0; p * 4096 < list->length; p++, ptr++)
343 *ptr = sg_dma_address(list) - list->offset;
344 return 0;
345}
346
347void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
348{
349 if (NULL == pt->cpu)
350 return;
351 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
352 pt->cpu = NULL;
353}
354
355/* ------------------------------------------------------------------ */
356
357void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
358{
359 if (in_interrupt())
360 BUG();
361
362 videobuf_waiton(&buf->vb,0,0);
363 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
364 videobuf_dma_free(&buf->vb.dma);
365 buf->vb.state = STATE_NEEDS_INIT;
366}
367
368/* ------------------------------------------------------------------ */
369
370int saa7134_buffer_queue(struct saa7134_dev *dev,
371 struct saa7134_dmaqueue *q,
372 struct saa7134_buf *buf)
373{
374 struct saa7134_buf *next = NULL;
375
376 assert_spin_locked(&dev->slock);
377 dprintk("buffer_queue %p\n",buf);
378 if (NULL == q->curr) {
379 if (!q->need_two) {
380 q->curr = buf;
381 buf->activate(dev,buf,NULL);
382 } else if (list_empty(&q->queue)) {
383 list_add_tail(&buf->vb.queue,&q->queue);
384 buf->vb.state = STATE_QUEUED;
385 } else {
386 next = list_entry(q->queue.next,struct saa7134_buf,
387 vb.queue);
388 q->curr = buf;
389 buf->activate(dev,buf,next);
390 }
391 } else {
392 list_add_tail(&buf->vb.queue,&q->queue);
393 buf->vb.state = STATE_QUEUED;
394 }
395 return 0;
396}
397
398void saa7134_buffer_finish(struct saa7134_dev *dev,
399 struct saa7134_dmaqueue *q,
400 unsigned int state)
401{
402 assert_spin_locked(&dev->slock);
403 dprintk("buffer_finish %p\n",q->curr);
404
405 /* finish current buffer */
406 q->curr->vb.state = state;
407 do_gettimeofday(&q->curr->vb.ts);
408 wake_up(&q->curr->vb.done);
409 q->curr = NULL;
410}
411
412void saa7134_buffer_next(struct saa7134_dev *dev,
413 struct saa7134_dmaqueue *q)
414{
415 struct saa7134_buf *buf,*next = NULL;
416
417 assert_spin_locked(&dev->slock);
418 BUG_ON(NULL != q->curr);
419
420 if (!list_empty(&q->queue)) {
421 /* activate next one from queue */
422 buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
423 dprintk("buffer_next %p [prev=%p/next=%p]\n",
424 buf,q->queue.prev,q->queue.next);
425 list_del(&buf->vb.queue);
426 if (!list_empty(&q->queue))
427 next = list_entry(q->queue.next,struct saa7134_buf,
428 vb.queue);
429 q->curr = buf;
430 buf->activate(dev,buf,next);
431 dprintk("buffer_next #2 prev=%p/next=%p\n",
432 q->queue.prev,q->queue.next);
433 } else {
434 /* nothing to do -- just stop DMA */
435 dprintk("buffer_next %p\n",NULL);
436 saa7134_set_dmabits(dev);
437 del_timer(&q->timeout);
438 }
439}
440
441void saa7134_buffer_timeout(unsigned long data)
442{
443 struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
444 struct saa7134_dev *dev = q->dev;
445 unsigned long flags;
446
447 spin_lock_irqsave(&dev->slock,flags);
448
449 /* try to reset the hardware (SWRST) */
450 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
451 saa_writeb(SAA7134_REGION_ENABLE, 0x80);
452 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
453
454 /* flag current buffer as failed,
455 try to start over with the next one. */
456 if (q->curr) {
457 dprintk("timeout on %p\n",q->curr);
458 saa7134_buffer_finish(dev,q,STATE_ERROR);
459 }
460 saa7134_buffer_next(dev,q);
461 spin_unlock_irqrestore(&dev->slock,flags);
462}
463
464/* ------------------------------------------------------------------ */
465
466int saa7134_set_dmabits(struct saa7134_dev *dev)
467{
468 u32 split, task=0, ctrl=0, irq=0;
469 enum v4l2_field cap = V4L2_FIELD_ANY;
470 enum v4l2_field ov = V4L2_FIELD_ANY;
471
472 assert_spin_locked(&dev->slock);
473
474 /* video capture -- dma 0 + video task A */
475 if (dev->video_q.curr) {
476 task |= 0x01;
477 ctrl |= SAA7134_MAIN_CTRL_TE0;
478 irq |= SAA7134_IRQ1_INTE_RA0_1 |
479 SAA7134_IRQ1_INTE_RA0_0;
480 cap = dev->video_q.curr->vb.field;
481 }
482
483 /* video capture -- dma 1+2 (planar modes) */
484 if (dev->video_q.curr &&
485 dev->video_q.curr->fmt->planar) {
486 ctrl |= SAA7134_MAIN_CTRL_TE4 |
487 SAA7134_MAIN_CTRL_TE5;
488 }
489
490 /* screen overlay -- dma 0 + video task B */
491 if (dev->ovenable) {
492 task |= 0x10;
493 ctrl |= SAA7134_MAIN_CTRL_TE1;
494 ov = dev->ovfield;
495 }
496
497 /* vbi capture -- dma 0 + vbi task A+B */
498 if (dev->vbi_q.curr) {
499 task |= 0x22;
500 ctrl |= SAA7134_MAIN_CTRL_TE2 |
501 SAA7134_MAIN_CTRL_TE3;
502 irq |= SAA7134_IRQ1_INTE_RA0_7 |
503 SAA7134_IRQ1_INTE_RA0_6 |
504 SAA7134_IRQ1_INTE_RA0_5 |
505 SAA7134_IRQ1_INTE_RA0_4;
506 }
507
508 /* audio capture -- dma 3 */
509 if (dev->oss.dma_running) {
510 ctrl |= SAA7134_MAIN_CTRL_TE6;
511 irq |= SAA7134_IRQ1_INTE_RA3_1 |
512 SAA7134_IRQ1_INTE_RA3_0;
513 }
514
515 /* TS capture -- dma 5 */
516 if (dev->ts_q.curr) {
517 ctrl |= SAA7134_MAIN_CTRL_TE5;
518 irq |= SAA7134_IRQ1_INTE_RA2_3 |
519 SAA7134_IRQ1_INTE_RA2_2 |
520 SAA7134_IRQ1_INTE_RA2_1 |
521 SAA7134_IRQ1_INTE_RA2_0;
522 }
523
524 /* set task conditions + field handling */
525 if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
526 /* default config -- use full frames */
527 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
528 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
529 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x02);
530 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x02);
531 split = 0;
532 } else {
533 /* split fields between tasks */
534 if (V4L2_FIELD_TOP == cap) {
535 /* odd A, even B, repeat */
536 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
537 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
538 } else {
539 /* odd B, even A, repeat */
540 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
541 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
542 }
543 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x01);
544 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x01);
545 split = 1;
546 }
547
548 /* irqs */
549 saa_writeb(SAA7134_REGION_ENABLE, task);
550 saa_writel(SAA7134_IRQ1, irq);
551 saa_andorl(SAA7134_MAIN_CTRL,
552 SAA7134_MAIN_CTRL_TE0 |
553 SAA7134_MAIN_CTRL_TE1 |
554 SAA7134_MAIN_CTRL_TE2 |
555 SAA7134_MAIN_CTRL_TE3 |
556 SAA7134_MAIN_CTRL_TE4 |
557 SAA7134_MAIN_CTRL_TE5 |
558 SAA7134_MAIN_CTRL_TE6,
559 ctrl);
560 dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
561 task, ctrl, irq, split ? "no" : "yes");
562
563 return 0;
564}
565
566/* ------------------------------------------------------------------ */
567/* IRQ handler + helpers */
568
569static char *irqbits[] = {
570 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
571 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
572 "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
573 "GPIO16?", "GPIO18", "GPIO22", "GPIO23"
574};
575#define IRQBITS ARRAY_SIZE(irqbits)
576
577static void print_irqstatus(struct saa7134_dev *dev, int loop,
578 unsigned long report, unsigned long status)
579{
580 unsigned int i;
581
582 printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
583 dev->name,loop,jiffies,report,status);
584 for (i = 0; i < IRQBITS; i++) {
585 if (!(report & (1 << i)))
586 continue;
587 printk(" %s",irqbits[i]);
588 }
589 if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
590 printk(" | RA0=%s,%s,%s,%ld",
591 (status & 0x40) ? "vbi" : "video",
592 (status & 0x20) ? "b" : "a",
593 (status & 0x10) ? "odd" : "even",
594 (status & 0x0f));
595 }
596 printk("\n");
597}
598
599static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
600{
601 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
602 unsigned long report,status;
603 int loop, handled = 0;
604
605 for (loop = 0; loop < 10; loop++) {
606 report = saa_readl(SAA7134_IRQ_REPORT);
607 status = saa_readl(SAA7134_IRQ_STATUS);
608 if (0 == report) {
609 if (irq_debug > 1)
610 printk(KERN_DEBUG "%s/irq: no (more) work\n",
611 dev->name);
612 goto out;
613 }
614 handled = 1;
615 saa_writel(SAA7134_IRQ_REPORT,report);
616 if (irq_debug)
617 print_irqstatus(dev,loop,report,status);
618
619#if 0
620 if (report & SAA7134_IRQ_REPORT_CONF_ERR)
621 dump_statusregs(dev);
622#endif
623
624 if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
625 saa7134_irq_video_intl(dev);
626
627 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
628 (status & 0x60) == 0)
629 saa7134_irq_video_done(dev,status);
630
631 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
632 (status & 0x40) == 0x40)
633 saa7134_irq_vbi_done(dev,status);
634
635 if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
636 card_has_mpeg(dev))
637 saa7134_irq_ts_done(dev,status);
638
639 if ((report & SAA7134_IRQ_REPORT_DONE_RA3))
640 saa7134_irq_oss_done(dev,status);
641
642 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
643 SAA7134_IRQ_REPORT_GPIO18)) &&
644 dev->remote)
645 saa7134_input_irq(dev);
646 }
647
648 if (10 == loop) {
649 print_irqstatus(dev,loop,report,status);
650 if (report & SAA7134_IRQ_REPORT_PE) {
651 /* disable all parity error */
652 printk(KERN_WARNING "%s/irq: looping -- "
653 "clearing PE (parity error!) enable bit\n",dev->name);
654 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
655 } else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
656 SAA7134_IRQ_REPORT_GPIO18)) {
657 /* disable gpio IRQs */
658 printk(KERN_WARNING "%s/irq: looping -- "
659 "clearing GPIO enable bits\n",dev->name);
660 saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
661 SAA7134_IRQ2_INTE_GPIO18));
662 } else {
663 /* disable all irqs */
664 printk(KERN_WARNING "%s/irq: looping -- "
665 "clearing all enable bits\n",dev->name);
666 saa_writel(SAA7134_IRQ1,0);
667 saa_writel(SAA7134_IRQ2,0);
668 }
669 }
670
671 out:
672 return IRQ_RETVAL(handled);
673}
674
675/* ------------------------------------------------------------------ */
676
677/* early init (no i2c, no irq) */
678static int saa7134_hwinit1(struct saa7134_dev *dev)
679{
680 dprintk("hwinit1\n");
681
682 saa_writel(SAA7134_IRQ1, 0);
683 saa_writel(SAA7134_IRQ2, 0);
684 init_MUTEX(&dev->lock);
685 spin_lock_init(&dev->slock);
686
687 saa7134_track_gpio(dev,"pre-init");
688 saa7134_video_init1(dev);
689 saa7134_vbi_init1(dev);
690 if (card_has_mpeg(dev))
691 saa7134_ts_init1(dev);
692 saa7134_input_init1(dev);
693
694 switch (dev->pci->device) {
695 case PCI_DEVICE_ID_PHILIPS_SAA7134:
696 case PCI_DEVICE_ID_PHILIPS_SAA7133:
697 case PCI_DEVICE_ID_PHILIPS_SAA7135:
698 saa7134_oss_init1(dev);
699 break;
700 }
701
702 /* RAM FIFO config */
703 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
704 saa_writel(SAA7134_THRESHOULD,0x02020202);
705
706 /* enable audio + video processing */
707 saa_writel(SAA7134_MAIN_CTRL,
708 SAA7134_MAIN_CTRL_VPLLE |
709 SAA7134_MAIN_CTRL_APLLE |
710 SAA7134_MAIN_CTRL_EXOSC |
711 SAA7134_MAIN_CTRL_EVFE1 |
712 SAA7134_MAIN_CTRL_EVFE2 |
713 SAA7134_MAIN_CTRL_ESFE |
714 SAA7134_MAIN_CTRL_EBADC |
715 SAA7134_MAIN_CTRL_EBDAC);
716
717 /* enable peripheral devices */
718 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
719
720 /* set vertical line numbering start (vbi needs this) */
721 saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
722
723 return 0;
724}
725
726/* late init (with i2c + irq) */
727static int saa7134_hwinit2(struct saa7134_dev *dev)
728{
729 dprintk("hwinit2\n");
730
731 saa7134_video_init2(dev);
732 saa7134_tvaudio_init2(dev);
733
734 /* enable IRQ's */
735 saa_writel(SAA7134_IRQ1, 0);
736 saa_writel(SAA7134_IRQ2, dev->irq2_mask);
737
738 return 0;
739}
740
741/* shutdown */
742static int saa7134_hwfini(struct saa7134_dev *dev)
743{
744 dprintk("hwfini\n");
745
746 switch (dev->pci->device) {
747 case PCI_DEVICE_ID_PHILIPS_SAA7134:
748 case PCI_DEVICE_ID_PHILIPS_SAA7133:
749 case PCI_DEVICE_ID_PHILIPS_SAA7135:
750 saa7134_oss_fini(dev);
751 break;
752 }
753 if (card_has_mpeg(dev))
754 saa7134_ts_fini(dev);
755 saa7134_input_fini(dev);
756 saa7134_vbi_fini(dev);
757 saa7134_video_fini(dev);
758 saa7134_tvaudio_fini(dev);
759 return 0;
760}
761
762static void __devinit must_configure_manually(void)
763{
764 unsigned int i,p;
765
766 printk(KERN_WARNING
767 "saa7134: <rant>\n"
768 "saa7134: Congratulations! Your TV card vendor saved a few\n"
769 "saa7134: cents for a eeprom, thus your pci board has no\n"
770 "saa7134: subsystem ID and I can't identify it automatically\n"
771 "saa7134: </rant>\n"
772 "saa7134: I feel better now. Ok, here are the good news:\n"
773 "saa7134: You can use the card=<nr> insmod option to specify\n"
774 "saa7134: which board do you have. The list:\n");
775 for (i = 0; i < saa7134_bcount; i++) {
776 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
777 i,saa7134_boards[i].name);
778 for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
779 if (saa7134_pci_tbl[p].driver_data != i)
780 continue;
781 printk(" %04x:%04x",
782 saa7134_pci_tbl[p].subvendor,
783 saa7134_pci_tbl[p].subdevice);
784 }
785 printk("\n");
786 }
787}
788
789static struct video_device *vdev_init(struct saa7134_dev *dev,
790 struct video_device *template,
791 char *type)
792{
793 struct video_device *vfd;
794
795 vfd = video_device_alloc();
796 if (NULL == vfd)
797 return NULL;
798 *vfd = *template;
799 vfd->minor = -1;
800 vfd->dev = &dev->pci->dev;
801 vfd->release = video_device_release;
802 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
803 dev->name, type, saa7134_boards[dev->board].name);
804 return vfd;
805}
806
807static void saa7134_unregister_video(struct saa7134_dev *dev)
808{
809 if (dev->video_dev) {
810 if (-1 != dev->video_dev->minor)
811 video_unregister_device(dev->video_dev);
812 else
813 video_device_release(dev->video_dev);
814 dev->video_dev = NULL;
815 }
816 if (dev->vbi_dev) {
817 if (-1 != dev->vbi_dev->minor)
818 video_unregister_device(dev->vbi_dev);
819 else
820 video_device_release(dev->vbi_dev);
821 dev->vbi_dev = NULL;
822 }
823 if (dev->radio_dev) {
824 if (-1 != dev->radio_dev->minor)
825 video_unregister_device(dev->radio_dev);
826 else
827 video_device_release(dev->radio_dev);
828 dev->radio_dev = NULL;
829 }
830}
831
832static void mpeg_ops_attach(struct saa7134_mpeg_ops *ops,
833 struct saa7134_dev *dev)
834{
835 int err;
836
837 if (NULL != dev->mops)
838 return;
839 if (saa7134_boards[dev->board].mpeg != ops->type)
840 return;
841 err = ops->init(dev);
842 if (0 != err)
843 return;
844 dev->mops = ops;
845}
846
847static void mpeg_ops_detach(struct saa7134_mpeg_ops *ops,
848 struct saa7134_dev *dev)
849{
850 if (NULL == dev->mops)
851 return;
852 if (dev->mops != ops)
853 return;
854 dev->mops->fini(dev);
855 dev->mops = NULL;
856}
857
858static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
859 const struct pci_device_id *pci_id)
860{
861 struct saa7134_dev *dev;
862 struct list_head *item;
863 struct saa7134_mpeg_ops *mops;
864 int err;
865
866 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
867 if (NULL == dev)
868 return -ENOMEM;
869 memset(dev,0,sizeof(*dev));
870
871 /* pci init */
872 dev->pci = pci_dev;
873 if (pci_enable_device(pci_dev)) {
874 err = -EIO;
875 goto fail1;
876 }
877
878 dev->nr = saa7134_devcount;
879 sprintf(dev->name,"saa%x[%d]",pci_dev->device,dev->nr);
880
881 /* pci quirks */
882 if (pci_pci_problems) {
883 if (pci_pci_problems & PCIPCI_TRITON)
884 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
885 if (pci_pci_problems & PCIPCI_NATOMA)
886 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
887 if (pci_pci_problems & PCIPCI_VIAETBF)
888 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
889 if (pci_pci_problems & PCIPCI_VSFX)
890 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
891#ifdef PCIPCI_ALIMAGIK
892 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
893 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
894 dev->name);
895 latency = 0x0A;
896 }
897#endif
898 }
899 if (UNSET != latency) {
900 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
901 dev->name,latency);
902 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
903 }
904
905 /* print pci info */
906 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
907 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
908 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
909 "latency: %d, mmio: 0x%lx\n", dev->name,
910 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
911 dev->pci_lat,pci_resource_start(pci_dev,0));
912 pci_set_master(pci_dev);
913 if (!pci_dma_supported(pci_dev,0xffffffff)) {
914 printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
915 err = -EIO;
916 goto fail1;
917 }
918
919 /* board config */
920 dev->board = pci_id->driver_data;
921 if (card[dev->nr] >= 0 &&
922 card[dev->nr] < saa7134_bcount)
923 dev->board = card[dev->nr];
924 if (SAA7134_BOARD_NOAUTO == dev->board) {
925 must_configure_manually();
926 dev->board = SAA7134_BOARD_UNKNOWN;
927 }
928 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
929 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
930 if (UNSET != tuner[dev->nr])
931 dev->tuner_type = tuner[dev->nr];
932 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
933 dev->name,pci_dev->subsystem_vendor,
934 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
935 dev->board, card[dev->nr] == dev->board ?
936 "insmod option" : "autodetected");
937
938 /* get mmio */
939 if (!request_mem_region(pci_resource_start(pci_dev,0),
940 pci_resource_len(pci_dev,0),
941 dev->name)) {
942 err = -EBUSY;
943 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
944 dev->name,pci_resource_start(pci_dev,0));
945 goto fail1;
946 }
947 dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
948 dev->bmmio = (__u8 __iomem *)dev->lmmio;
949 if (NULL == dev->lmmio) {
950 err = -EIO;
951 printk(KERN_ERR "%s: can't ioremap() MMIO memory\n",
952 dev->name);
953 goto fail2;
954 }
955
956 /* initialize hardware #1 */
957 dev->irq2_mask =
958 SAA7134_IRQ2_INTE_DEC3 |
959 SAA7134_IRQ2_INTE_DEC2 |
960 SAA7134_IRQ2_INTE_DEC1 |
961 SAA7134_IRQ2_INTE_DEC0 |
962 SAA7134_IRQ2_INTE_PE |
963 SAA7134_IRQ2_INTE_AR;
964 saa7134_board_init1(dev);
965 saa7134_hwinit1(dev);
966
967 /* get irq */
968 err = request_irq(pci_dev->irq, saa7134_irq,
969 SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
970 if (err < 0) {
971 printk(KERN_ERR "%s: can't get IRQ %d\n",
972 dev->name,pci_dev->irq);
973 goto fail3;
974 }
975
976 /* wait a bit, register i2c bus */
977 msleep(100);
978 saa7134_i2c_register(dev);
979
980 /* initialize hardware #2 */
981 saa7134_board_init2(dev);
982 saa7134_hwinit2(dev);
983
984 /* load i2c helpers */
985 if (TUNER_ABSENT != dev->tuner_type)
986 request_module("tuner");
987 if (dev->tda9887_conf)
988 request_module("tda9887");
989 if (card_is_empress(dev)) {
990 request_module("saa6752hs");
991 request_module_depend("saa7134-empress",&need_empress);
992 }
993 if (card_is_dvb(dev))
994 request_module_depend("saa7134-dvb",&need_dvb);
995
996 v4l2_prio_init(&dev->prio);
997
998 /* register v4l devices */
999 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
1000 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
1001 video_nr[dev->nr]);
1002 if (err < 0) {
1003 printk(KERN_INFO "%s: can't register video device\n",
1004 dev->name);
1005 goto fail4;
1006 }
1007 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
1008 dev->name,dev->video_dev->minor & 0x1f);
1009
1010 dev->vbi_dev = vdev_init(dev,&saa7134_vbi_template,"vbi");
1011 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
1012 vbi_nr[dev->nr]);
1013 if (err < 0)
1014 goto fail4;
1015 printk(KERN_INFO "%s: registered device vbi%d\n",
1016 dev->name,dev->vbi_dev->minor & 0x1f);
1017
1018 if (card_has_radio(dev)) {
1019 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
1020 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
1021 radio_nr[dev->nr]);
1022 if (err < 0)
1023 goto fail4;
1024 printk(KERN_INFO "%s: registered device radio%d\n",
1025 dev->name,dev->radio_dev->minor & 0x1f);
1026 }
1027
1028 /* register oss devices */
1029 switch (dev->pci->device) {
1030 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1031 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1032 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1033 if (oss) {
1034 err = dev->oss.minor_dsp =
1035 register_sound_dsp(&saa7134_dsp_fops,
1036 dsp_nr[dev->nr]);
1037 if (err < 0) {
1038 goto fail4;
1039 }
1040 printk(KERN_INFO "%s: registered device dsp%d\n",
1041 dev->name,dev->oss.minor_dsp >> 4);
1042
1043 err = dev->oss.minor_mixer =
1044 register_sound_mixer(&saa7134_mixer_fops,
1045 mixer_nr[dev->nr]);
1046 if (err < 0)
1047 goto fail5;
1048 printk(KERN_INFO "%s: registered device mixer%d\n",
1049 dev->name,dev->oss.minor_mixer >> 4);
1050 }
1051 break;
1052 }
1053
1054 /* everything worked */
1055 pci_set_drvdata(pci_dev,dev);
1056 saa7134_devcount++;
1057
1058 down(&devlist_lock);
1059 list_for_each(item,&mops_list) {
1060 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1061 mpeg_ops_attach(mops, dev);
1062 }
1063 list_add_tail(&dev->devlist,&saa7134_devlist);
1064 up(&devlist_lock);
1065
1066 /* check for signal */
1067 saa7134_irq_video_intl(dev);
1068 return 0;
1069
1070 fail5:
1071 switch (dev->pci->device) {
1072 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1073 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1074 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1075 if (oss)
1076 unregister_sound_dsp(dev->oss.minor_dsp);
1077 break;
1078 }
1079 fail4:
1080 saa7134_unregister_video(dev);
1081 saa7134_i2c_unregister(dev);
1082 free_irq(pci_dev->irq, dev);
1083 fail3:
1084 saa7134_hwfini(dev);
1085 iounmap(dev->lmmio);
1086 fail2:
1087 release_mem_region(pci_resource_start(pci_dev,0),
1088 pci_resource_len(pci_dev,0));
1089 fail1:
1090 kfree(dev);
1091 return err;
1092}
1093
1094static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1095{
1096 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1097 struct list_head *item;
1098 struct saa7134_mpeg_ops *mops;
1099
1100 /* debugging ... */
1101 if (irq_debug) {
1102 u32 report = saa_readl(SAA7134_IRQ_REPORT);
1103 u32 status = saa_readl(SAA7134_IRQ_STATUS);
1104 print_irqstatus(dev,42,report,status);
1105 }
1106
1107 /* disable peripheral devices */
1108 saa_writeb(SAA7134_SPECIAL_MODE,0);
1109
1110 /* shutdown hardware */
1111 saa_writel(SAA7134_IRQ1,0);
1112 saa_writel(SAA7134_IRQ2,0);
1113 saa_writel(SAA7134_MAIN_CTRL,0);
1114
1115 /* shutdown subsystems */
1116 saa7134_hwfini(dev);
1117
1118 /* unregister */
1119 down(&devlist_lock);
1120 list_del(&dev->devlist);
1121 list_for_each(item,&mops_list) {
1122 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1123 mpeg_ops_detach(mops, dev);
1124 }
1125 up(&devlist_lock);
1126 saa7134_devcount--;
1127
1128 saa7134_i2c_unregister(dev);
1129 switch (dev->pci->device) {
1130 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1131 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1132 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1133 if (oss) {
1134 unregister_sound_mixer(dev->oss.minor_mixer);
1135 unregister_sound_dsp(dev->oss.minor_dsp);
1136 }
1137 break;
1138 }
1139 saa7134_unregister_video(dev);
1140
1141 /* release ressources */
1142 free_irq(pci_dev->irq, dev);
1143 iounmap(dev->lmmio);
1144 release_mem_region(pci_resource_start(pci_dev,0),
1145 pci_resource_len(pci_dev,0));
1146
1147#if 0 /* causes some trouble when reinserting the driver ... */
1148 pci_disable_device(pci_dev);
1149#endif
1150 pci_set_drvdata(pci_dev, NULL);
1151
1152 /* free memory */
1153 kfree(dev);
1154}
1155
1156/* ----------------------------------------------------------- */
1157
1158int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
1159{
1160 struct list_head *item;
1161 struct saa7134_dev *dev;
1162
1163 down(&devlist_lock);
1164 list_for_each(item,&saa7134_devlist) {
1165 dev = list_entry(item, struct saa7134_dev, devlist);
1166 mpeg_ops_attach(ops, dev);
1167 }
1168 list_add_tail(&ops->next,&mops_list);
1169 up(&devlist_lock);
1170 return 0;
1171}
1172
1173void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
1174{
1175 struct list_head *item;
1176 struct saa7134_dev *dev;
1177
1178 down(&devlist_lock);
1179 list_del(&ops->next);
1180 list_for_each(item,&saa7134_devlist) {
1181 dev = list_entry(item, struct saa7134_dev, devlist);
1182 mpeg_ops_detach(ops, dev);
1183 }
1184 up(&devlist_lock);
1185}
1186
1187EXPORT_SYMBOL(saa7134_ts_register);
1188EXPORT_SYMBOL(saa7134_ts_unregister);
1189
1190/* ----------------------------------------------------------- */
1191
1192static struct pci_driver saa7134_pci_driver = {
1193 .name = "saa7134",
1194 .id_table = saa7134_pci_tbl,
1195 .probe = saa7134_initdev,
1196 .remove = __devexit_p(saa7134_finidev),
1197};
1198
1199static int saa7134_init(void)
1200{
1201 INIT_LIST_HEAD(&saa7134_devlist);
1202 printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
1203 (SAA7134_VERSION_CODE >> 16) & 0xff,
1204 (SAA7134_VERSION_CODE >> 8) & 0xff,
1205 SAA7134_VERSION_CODE & 0xff);
1206#ifdef SNAPSHOT
1207 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n",
1208 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1209#endif
1210 return pci_module_init(&saa7134_pci_driver);
1211}
1212
1213static void saa7134_fini(void)
1214{
1215#ifdef CONFIG_MODULES
1216 if (pending_registered)
1217 unregister_module_notifier(&pending_notifier);
1218#endif
1219 pci_unregister_driver(&saa7134_pci_driver);
1220}
1221
1222module_init(saa7134_init);
1223module_exit(saa7134_fini);
1224
1225/* ----------------------------------------------------------- */
1226
1227EXPORT_SYMBOL(saa7134_print_ioctl);
1228EXPORT_SYMBOL(saa7134_i2c_call_clients);
1229EXPORT_SYMBOL(saa7134_devlist);
1230EXPORT_SYMBOL(saa7134_boards);
1231
1232/* ----------------------------------------------------------- */
1233/*
1234 * Local variables:
1235 * c-basic-offset: 8
1236 * End:
1237 */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
new file mode 100644
index 000000000000..dd4a6c8ee65f
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -0,0 +1,266 @@
1/*
2 * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/kthread.h>
28#include <linux/suspend.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33#include "dvb-pll.h"
34#include "mt352.h"
35#include "mt352_priv.h" /* FIXME */
36#include "tda1004x.h"
37
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL");
40
41static unsigned int antenna_pwr = 0;
42module_param(antenna_pwr, int, 0444);
43MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
44
45/* ------------------------------------------------------------------ */
46
47static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
48{
49 u32 ok;
50
51 if (!on) {
52 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
53 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
54 return 0;
55 }
56
57 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
58 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
59 udelay(10);
60
61 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
62 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
63 udelay(10);
64 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
65 udelay(10);
66 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
67 printk("%s: %s %s\n", dev->name, __FUNCTION__,
68 ok ? "on" : "off");
69
70 if (!ok)
71 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
72 return ok;
73}
74
75static int mt352_pinnacle_init(struct dvb_frontend* fe)
76{
77 static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
78 static u8 reset [] = { RESET, 0x80 };
79 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
80 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
81 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
82 static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
83 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
84 static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
85 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
86 struct saa7134_dev *dev= fe->dvb->priv;
87
88 printk("%s: %s called\n",dev->name,__FUNCTION__);
89
90 mt352_write(fe, clock_config, sizeof(clock_config));
91 udelay(200);
92 mt352_write(fe, reset, sizeof(reset));
93 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
94 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
95 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
96 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
97
98 mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
99 mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
100 mt352_write(fe, irq_cfg, sizeof(irq_cfg));
101 return 0;
102}
103
104static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
105 struct dvb_frontend_parameters* params,
106 u8* pllbuf)
107{
108 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
109 static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
110 struct saa7134_dev *dev = fe->dvb->priv;
111 struct v4l2_frequency f;
112
113 /* set frequency (mt2050) */
114 f.tuner = 0;
115 f.type = V4L2_TUNER_DIGITAL_TV;
116 f.frequency = params->frequency / 1000 * 16 / 1000;
117 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
118 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
119 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
120
121 pinnacle_antenna_pwr(dev, antenna_pwr);
122
123 /* mt352 setup */
124 mt352_pinnacle_init(fe);
125 pllbuf[0] = 0xc2;
126 pllbuf[1] = 0x00;
127 pllbuf[2] = 0x00;
128 pllbuf[3] = 0x80;
129 pllbuf[4] = 0x00;
130 return 0;
131}
132
133static struct mt352_config pinnacle_300i = {
134 .demod_address = 0x3c >> 1,
135 .adc_clock = 20333,
136 .if2 = 36150,
137 .no_tuner = 1,
138 .demod_init = mt352_pinnacle_init,
139 .pll_set = mt352_pinnacle_pll_set,
140};
141
142/* ------------------------------------------------------------------ */
143
144static int medion_cardbus_init(struct dvb_frontend* fe)
145{
146 /* anything to do here ??? */
147 return 0;
148}
149
150static int medion_cardbus_pll_set(struct dvb_frontend* fe,
151 struct dvb_frontend_parameters* params)
152{
153 struct saa7134_dev *dev = fe->dvb->priv;
154 struct v4l2_frequency f;
155
156 /*
157 * this instructs tuner.o to set the frequency, the call will
158 * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
159 * tda9887.o will see that as well.
160 */
161 f.tuner = 0;
162 f.type = V4L2_TUNER_DIGITAL_TV;
163 f.frequency = params->frequency / 1000 * 16 / 1000;
164 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
165 return 0;
166}
167
168static int fe_request_firmware(struct dvb_frontend* fe,
169 const struct firmware **fw, char* name)
170{
171 struct saa7134_dev *dev = fe->dvb->priv;
172 return request_firmware(fw, name, &dev->pci->dev);
173}
174
175struct tda1004x_config medion_cardbus = {
176 .demod_address = 0x08, /* not sure this is correct */
177 .invert = 0,
178 .invert_oclk = 0,
179 .pll_init = medion_cardbus_init,
180 .pll_set = medion_cardbus_pll_set,
181 .request_firmware = fe_request_firmware,
182};
183
184/* ------------------------------------------------------------------ */
185
186static int dvb_init(struct saa7134_dev *dev)
187{
188 /* init struct videobuf_dvb */
189 dev->ts.nr_bufs = 32;
190 dev->ts.nr_packets = 32*4;
191 dev->dvb.name = dev->name;
192 videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
193 dev->pci, &dev->slock,
194 V4L2_BUF_TYPE_VIDEO_CAPTURE,
195 V4L2_FIELD_ALTERNATE,
196 sizeof(struct saa7134_buf),
197 dev);
198
199 switch (dev->board) {
200 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
201 printk("%s: pinnacle 300i dvb setup\n",dev->name);
202 dev->dvb.frontend = mt352_attach(&pinnacle_300i,
203 &dev->i2c_adap);
204 break;
205 case SAA7134_BOARD_MD7134:
206 dev->dvb.frontend = tda10046_attach(&medion_cardbus,
207 &dev->i2c_adap);
208 if (NULL == dev->dvb.frontend)
209 printk("%s: Hmm, looks like this is the old MD7134 "
210 "version without DVB-T support\n",dev->name);
211 break;
212 default:
213 printk("%s: Huh? unknown DVB card?\n",dev->name);
214 break;
215 }
216
217 if (NULL == dev->dvb.frontend) {
218 printk("%s: frontend initialization failed\n",dev->name);
219 return -1;
220 }
221
222 /* register everything else */
223 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
224}
225
226static int dvb_fini(struct saa7134_dev *dev)
227{
228 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
229
230 printk("%s: %s\n",dev->name,__FUNCTION__);
231
232 switch (dev->board) {
233 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
234 /* otherwise we don't detect the tuner on next insmod */
235 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
236 break;
237 };
238 videobuf_dvb_unregister(&dev->dvb);
239 return 0;
240}
241
242static struct saa7134_mpeg_ops dvb_ops = {
243 .type = SAA7134_MPEG_DVB,
244 .init = dvb_init,
245 .fini = dvb_fini,
246};
247
248static int __init dvb_register(void)
249{
250 return saa7134_ts_register(&dvb_ops);
251}
252
253static void __exit dvb_unregister(void)
254{
255 saa7134_ts_unregister(&dvb_ops);
256}
257
258module_init(dvb_register);
259module_exit(dvb_unregister);
260
261/* ------------------------------------------------------------------ */
262/*
263 * Local variables:
264 * c-basic-offset: 8
265 * End:
266 */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
new file mode 100644
index 000000000000..2021e099e35a
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -0,0 +1,436 @@
1/*
2 * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28
29#include "saa7134-reg.h"
30#include "saa7134.h"
31
32#include <media/saa6752hs.h>
33
34/* ------------------------------------------------------------------ */
35
36MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
37MODULE_LICENSE("GPL");
38
39static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
40module_param_array(empress_nr, int, NULL, 0444);
41MODULE_PARM_DESC(empress_nr,"ts device number");
42
43static unsigned int debug = 0;
44module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug,"enable debug messages");
46
47#define dprintk(fmt, arg...) if (debug) \
48 printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg)
49
50/* ------------------------------------------------------------------ */
51
52static void ts_reset_encoder(struct saa7134_dev* dev)
53{
54 if (!dev->empress_started)
55 return;
56
57 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
58 msleep(10);
59 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
60 msleep(100);
61 dev->empress_started = 0;
62}
63
64static int ts_init_encoder(struct saa7134_dev* dev)
65{
66 ts_reset_encoder(dev);
67 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
68 dev->empress_started = 1;
69 return 0;
70}
71
72/* ------------------------------------------------------------------ */
73
74static int ts_open(struct inode *inode, struct file *file)
75{
76 int minor = iminor(inode);
77 struct saa7134_dev *h,*dev = NULL;
78 struct list_head *list;
79 int err;
80
81 list_for_each(list,&saa7134_devlist) {
82 h = list_entry(list, struct saa7134_dev, devlist);
83 if (h->empress_dev && h->empress_dev->minor == minor)
84 dev = h;
85 }
86 if (NULL == dev)
87 return -ENODEV;
88
89 dprintk("open minor=%d\n",minor);
90 err = -EBUSY;
91 if (down_trylock(&dev->empress_tsq.lock))
92 goto done;
93 if (dev->empress_users)
94 goto done_up;
95
96 dev->empress_users++;
97 file->private_data = dev;
98 err = 0;
99
100done_up:
101 up(&dev->empress_tsq.lock);
102done:
103 return err;
104}
105
106static int ts_release(struct inode *inode, struct file *file)
107{
108 struct saa7134_dev *dev = file->private_data;
109
110 if (dev->empress_tsq.streaming)
111 videobuf_streamoff(&dev->empress_tsq);
112 down(&dev->empress_tsq.lock);
113 if (dev->empress_tsq.reading)
114 videobuf_read_stop(&dev->empress_tsq);
115 videobuf_mmap_free(&dev->empress_tsq);
116 dev->empress_users--;
117
118 /* stop the encoder */
119 ts_reset_encoder(dev);
120
121 up(&dev->empress_tsq.lock);
122 return 0;
123}
124
125static ssize_t
126ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
127{
128 struct saa7134_dev *dev = file->private_data;
129
130 if (!dev->empress_started)
131 ts_init_encoder(dev);
132
133 return videobuf_read_stream(&dev->empress_tsq,
134 data, count, ppos, 0,
135 file->f_flags & O_NONBLOCK);
136}
137
138static unsigned int
139ts_poll(struct file *file, struct poll_table_struct *wait)
140{
141 struct saa7134_dev *dev = file->private_data;
142
143 return videobuf_poll_stream(file, &dev->empress_tsq, wait);
144}
145
146
147static int
148ts_mmap(struct file *file, struct vm_area_struct * vma)
149{
150 struct saa7134_dev *dev = file->private_data;
151
152 return videobuf_mmap_mapper(&dev->empress_tsq, vma);
153}
154
155/*
156 * This function is _not_ called directly, but from
157 * video_generic_ioctl (and maybe others). userspace
158 * copying is done already, arg is a kernel pointer.
159 */
160static int ts_do_ioctl(struct inode *inode, struct file *file,
161 unsigned int cmd, void *arg)
162{
163 struct saa7134_dev *dev = file->private_data;
164
165 if (debug > 1)
166 saa7134_print_ioctl(dev->name,cmd);
167 switch (cmd) {
168 case VIDIOC_QUERYCAP:
169 {
170 struct v4l2_capability *cap = arg;
171
172 memset(cap,0,sizeof(*cap));
173 strcpy(cap->driver, "saa7134");
174 strlcpy(cap->card, saa7134_boards[dev->board].name,
175 sizeof(cap->card));
176 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
177 cap->version = SAA7134_VERSION_CODE;
178 cap->capabilities =
179 V4L2_CAP_VIDEO_CAPTURE |
180 V4L2_CAP_READWRITE |
181 V4L2_CAP_STREAMING;
182 return 0;
183 }
184
185 /* --- input switching --------------------------------------- */
186 case VIDIOC_ENUMINPUT:
187 {
188 struct v4l2_input *i = arg;
189
190 if (i->index != 0)
191 return -EINVAL;
192 i->type = V4L2_INPUT_TYPE_CAMERA;
193 strcpy(i->name,"CCIR656");
194 return 0;
195 }
196 case VIDIOC_G_INPUT:
197 {
198 int *i = arg;
199 *i = 0;
200 return 0;
201 }
202 case VIDIOC_S_INPUT:
203 {
204 int *i = arg;
205
206 if (*i != 0)
207 return -EINVAL;
208 return 0;
209 }
210 /* --- capture ioctls ---------------------------------------- */
211
212 case VIDIOC_ENUM_FMT:
213 {
214 struct v4l2_fmtdesc *f = arg;
215 int index;
216
217 index = f->index;
218 if (index != 0)
219 return -EINVAL;
220
221 memset(f,0,sizeof(*f));
222 f->index = index;
223 strlcpy(f->description, "MPEG TS", sizeof(f->description));
224 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
225 f->pixelformat = V4L2_PIX_FMT_MPEG;
226 return 0;
227 }
228
229 case VIDIOC_G_FMT:
230 {
231 struct v4l2_format *f = arg;
232
233 memset(f,0,sizeof(*f));
234 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
235
236 /* FIXME: translate subsampling type EMPRESS into
237 * width/height: */
238 f->fmt.pix.width = 720; /* D1 */
239 f->fmt.pix.height = 576;
240 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
241 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
242 return 0;
243 }
244
245 case VIDIOC_S_FMT:
246 {
247 struct v4l2_format *f = arg;
248
249 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
250 return -EINVAL;
251
252 /*
253 FIXME: translate and round width/height into EMPRESS
254 subsample type:
255
256 type | PAL | NTSC
257 ---------------------------
258 SIF | 352x288 | 352x240
259 1/2 D1 | 352x576 | 352x480
260 2/3 D1 | 480x576 | 480x480
261 D1 | 720x576 | 720x480
262 */
263
264 f->fmt.pix.width = 720; /* D1 */
265 f->fmt.pix.height = 576;
266 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
267 f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets;
268 return 0;
269 }
270
271 case VIDIOC_REQBUFS:
272 return videobuf_reqbufs(&dev->empress_tsq,arg);
273
274 case VIDIOC_QUERYBUF:
275 return videobuf_querybuf(&dev->empress_tsq,arg);
276
277 case VIDIOC_QBUF:
278 return videobuf_qbuf(&dev->empress_tsq,arg);
279
280 case VIDIOC_DQBUF:
281 return videobuf_dqbuf(&dev->empress_tsq,arg,
282 file->f_flags & O_NONBLOCK);
283
284 case VIDIOC_STREAMON:
285 return videobuf_streamon(&dev->empress_tsq);
286
287 case VIDIOC_STREAMOFF:
288 return videobuf_streamoff(&dev->empress_tsq);
289
290 case VIDIOC_QUERYCTRL:
291 case VIDIOC_G_CTRL:
292 case VIDIOC_S_CTRL:
293 return saa7134_common_ioctl(dev, cmd, arg);
294
295 case VIDIOC_S_MPEGCOMP:
296 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
297 ts_init_encoder(dev);
298 return 0;
299 case VIDIOC_G_MPEGCOMP:
300 saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
301 return 0;
302
303 default:
304 return -ENOIOCTLCMD;
305 }
306 return 0;
307}
308
309static int ts_ioctl(struct inode *inode, struct file *file,
310 unsigned int cmd, unsigned long arg)
311{
312 return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
313}
314
315static struct file_operations ts_fops =
316{
317 .owner = THIS_MODULE,
318 .open = ts_open,
319 .release = ts_release,
320 .read = ts_read,
321 .poll = ts_poll,
322 .mmap = ts_mmap,
323 .ioctl = ts_ioctl,
324 .llseek = no_llseek,
325};
326
327/* ----------------------------------------------------------- */
328
329static struct video_device saa7134_empress_template =
330{
331 .name = "saa7134-empress",
332 .type = 0 /* FIXME */,
333 .type2 = 0 /* FIXME */,
334 .hardware = 0,
335 .fops = &ts_fops,
336 .minor = -1,
337};
338
339static void empress_signal_update(void* data)
340{
341 struct saa7134_dev* dev = (struct saa7134_dev*) data;
342
343 if (dev->nosignal) {
344 dprintk("no video signal\n");
345 ts_reset_encoder(dev);
346 } else {
347 dprintk("video signal acquired\n");
348 if (dev->empress_users)
349 ts_init_encoder(dev);
350 }
351}
352
353static void empress_signal_change(struct saa7134_dev *dev)
354{
355 schedule_work(&dev->empress_workqueue);
356}
357
358
359static int empress_init(struct saa7134_dev *dev)
360{
361 int err;
362
363 dprintk("%s: %s\n",dev->name,__FUNCTION__);
364 dev->empress_dev = video_device_alloc();
365 if (NULL == dev->empress_dev)
366 return -ENOMEM;
367 *(dev->empress_dev) = saa7134_empress_template;
368 dev->empress_dev->dev = &dev->pci->dev;
369 dev->empress_dev->release = video_device_release;
370 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
371 "%s empress (%s)", dev->name,
372 saa7134_boards[dev->board].name);
373
374 INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
375
376 err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
377 empress_nr[dev->nr]);
378 if (err < 0) {
379 printk(KERN_INFO "%s: can't register video device\n",
380 dev->name);
381 video_device_release(dev->empress_dev);
382 dev->empress_dev = NULL;
383 return err;
384 }
385 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
386 dev->name,dev->empress_dev->minor & 0x1f);
387
388 videobuf_queue_init(&dev->empress_tsq, &saa7134_ts_qops,
389 dev->pci, &dev->slock,
390 V4L2_BUF_TYPE_VIDEO_CAPTURE,
391 V4L2_FIELD_ALTERNATE,
392 sizeof(struct saa7134_buf),
393 dev);
394
395 empress_signal_update(dev);
396 return 0;
397}
398
399static int empress_fini(struct saa7134_dev *dev)
400{
401 dprintk("%s: %s\n",dev->name,__FUNCTION__);
402
403 if (NULL == dev->empress_dev)
404 return 0;
405 flush_scheduled_work();
406 video_unregister_device(dev->empress_dev);
407 dev->empress_dev = NULL;
408 return 0;
409}
410
411static struct saa7134_mpeg_ops empress_ops = {
412 .type = SAA7134_MPEG_EMPRESS,
413 .init = empress_init,
414 .fini = empress_fini,
415 .signal_change = empress_signal_change,
416};
417
418static int __init empress_register(void)
419{
420 return saa7134_ts_register(&empress_ops);
421}
422
423static void __exit empress_unregister(void)
424{
425 saa7134_ts_unregister(&empress_ops);
426}
427
428module_init(empress_register);
429module_exit(empress_unregister);
430
431/* ----------------------------------------------------------- */
432/*
433 * Local variables:
434 * c-basic-offset: 8
435 * End:
436 */
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
new file mode 100644
index 000000000000..702bb63d9813
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -0,0 +1,453 @@
1/*
2 * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * i2c interface support
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ----------------------------------------------------------- */
36
37static unsigned int i2c_debug = 0;
38module_param(i2c_debug, int, 0644);
39MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
40
41static unsigned int i2c_scan = 0;
42module_param(i2c_scan, int, 0444);
43MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
44
45#define d1printk if (1 == i2c_debug) printk
46#define d2printk if (2 == i2c_debug) printk
47
48#define I2C_WAIT_DELAY 32
49#define I2C_WAIT_RETRY 16
50
51/* ----------------------------------------------------------- */
52
53static char *str_i2c_status[] = {
54 "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
55 "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
56 "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
57};
58
59enum i2c_status {
60 IDLE = 0, // no I2C command pending
61 DONE_STOP = 1, // I2C command done and STOP executed
62 BUSY = 2, // executing I2C command
63 TO_SCL = 3, // executing I2C command, time out on clock stretching
64 TO_ARB = 4, // time out on arbitration trial, still trying
65 DONE_WRITE = 5, // I2C command done and awaiting next write command
66 DONE_READ = 6, // I2C command done and awaiting next read command
67 DONE_WRITE_TO = 7, // see 5, and time out on status echo
68 DONE_READ_TO = 8, // see 6, and time out on status echo
69 NO_DEVICE = 9, // no acknowledge on device slave address
70 NO_ACKN = 10, // no acknowledge after data byte transfer
71 BUS_ERR = 11, // bus error
72 ARB_LOST = 12, // arbitration lost during transfer
73 SEQ_ERR = 13, // erroneous programming sequence
74 ST_ERR = 14, // wrong status echoing
75 SW_ERR = 15 // software error
76};
77
78static char *str_i2c_attr[] = {
79 "NOP", "STOP", "CONTINUE", "START"
80};
81
82enum i2c_attr {
83 NOP = 0, // no operation on I2C bus
84 STOP = 1, // stop condition, no associated byte transfer
85 CONTINUE = 2, // continue with byte transfer
86 START = 3 // start condition with byte transfer
87};
88
89static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
90{
91 enum i2c_status status;
92
93 status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
94 d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name,
95 str_i2c_status[status]);
96 return status;
97}
98
99static inline void i2c_set_status(struct saa7134_dev *dev,
100 enum i2c_status status)
101{
102 d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name,
103 str_i2c_status[status]);
104 saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
105}
106
107static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
108{
109 d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name,
110 str_i2c_attr[attr]);
111 saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
112}
113
114static inline int i2c_is_error(enum i2c_status status)
115{
116 switch (status) {
117 case NO_DEVICE:
118 case NO_ACKN:
119 case BUS_ERR:
120 case ARB_LOST:
121 case SEQ_ERR:
122 case ST_ERR:
123 return TRUE;
124 default:
125 return FALSE;
126 }
127}
128
129static inline int i2c_is_idle(enum i2c_status status)
130{
131 switch (status) {
132 case IDLE:
133 case DONE_STOP:
134 return TRUE;
135 default:
136 return FALSE;
137 }
138}
139
140static inline int i2c_is_busy(enum i2c_status status)
141{
142 switch (status) {
143 case BUSY:
144 return TRUE;
145 default:
146 return FALSE;
147 }
148}
149
150static int i2c_is_busy_wait(struct saa7134_dev *dev)
151{
152 enum i2c_status status;
153 int count;
154
155 for (count = 0; count < I2C_WAIT_RETRY; count++) {
156 status = i2c_get_status(dev);
157 if (!i2c_is_busy(status))
158 break;
159 saa_wait(I2C_WAIT_DELAY);
160 }
161 if (I2C_WAIT_RETRY == count)
162 return FALSE;
163 return TRUE;
164}
165
166static int i2c_reset(struct saa7134_dev *dev)
167{
168 enum i2c_status status;
169 int count;
170
171 d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
172 status = i2c_get_status(dev);
173 if (!i2c_is_error(status))
174 return TRUE;
175 i2c_set_status(dev,status);
176
177 for (count = 0; count < I2C_WAIT_RETRY; count++) {
178 status = i2c_get_status(dev);
179 if (!i2c_is_error(status))
180 break;
181 udelay(I2C_WAIT_DELAY);
182 }
183 if (I2C_WAIT_RETRY == count)
184 return FALSE;
185
186 if (!i2c_is_idle(status))
187 return FALSE;
188
189 i2c_set_attr(dev,NOP);
190 return TRUE;
191}
192
193static inline int i2c_send_byte(struct saa7134_dev *dev,
194 enum i2c_attr attr,
195 unsigned char data)
196{
197 enum i2c_status status;
198 __u32 dword;
199
200#if 0
201 i2c_set_attr(dev,attr);
202 saa_writeb(SAA7134_I2C_DATA, data);
203#else
204 /* have to write both attr + data in one 32bit word */
205 dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
206 dword &= 0x0f;
207 dword |= (attr << 6);
208 dword |= ((__u32)data << 8);
209 dword |= 0x00 << 16; /* 100 kHz */
210// dword |= 0x40 << 16; /* 400 kHz */
211 dword |= 0xf0 << 24;
212 saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
213#endif
214 d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
215
216 if (!i2c_is_busy_wait(dev))
217 return -EIO;
218 status = i2c_get_status(dev);
219 if (i2c_is_error(status))
220 return -EIO;
221 return 0;
222}
223
224static inline int i2c_recv_byte(struct saa7134_dev *dev)
225{
226 enum i2c_status status;
227 unsigned char data;
228
229 i2c_set_attr(dev,CONTINUE);
230 if (!i2c_is_busy_wait(dev))
231 return -EIO;
232 status = i2c_get_status(dev);
233 if (i2c_is_error(status))
234 return -EIO;
235 data = saa_readb(SAA7134_I2C_DATA);
236 d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data);
237 return data;
238}
239
240static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
241 struct i2c_msg *msgs, int num)
242{
243 struct saa7134_dev *dev = i2c_adap->algo_data;
244 enum i2c_status status;
245 unsigned char data;
246 int addr,rc,i,byte;
247
248 status = i2c_get_status(dev);
249 if (!i2c_is_idle(status))
250 if (!i2c_reset(dev))
251 return -EIO;
252
253 d2printk("start xfer\n");
254 d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
255 for (i = 0; i < num; i++) {
256 if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
257 /* send address */
258 d2printk("send address\n");
259 addr = msgs[i].addr << 1;
260 if (msgs[i].flags & I2C_M_RD)
261 addr |= 1;
262 if (i > 0 && msgs[i].flags & I2C_M_RD) {
263 /* workaround for a saa7134 i2c bug
264 * needed to talk to the mt352 demux
265 * thanks to pinnacle for the hint */
266 int quirk = 0xfd;
267 d1printk(" [%02x quirk]",quirk);
268 i2c_send_byte(dev,START,quirk);
269 i2c_recv_byte(dev);
270 }
271 d1printk(" < %02x", addr);
272 rc = i2c_send_byte(dev,START,addr);
273 if (rc < 0)
274 goto err;
275 }
276 if (msgs[i].flags & I2C_M_RD) {
277 /* read bytes */
278 d2printk("read bytes\n");
279 for (byte = 0; byte < msgs[i].len; byte++) {
280 d1printk(" =");
281 rc = i2c_recv_byte(dev);
282 if (rc < 0)
283 goto err;
284 d1printk("%02x", rc);
285 msgs[i].buf[byte] = rc;
286 }
287 } else {
288 /* write bytes */
289 d2printk("write bytes\n");
290 for (byte = 0; byte < msgs[i].len; byte++) {
291 data = msgs[i].buf[byte];
292 d1printk(" %02x", data);
293 rc = i2c_send_byte(dev,CONTINUE,data);
294 if (rc < 0)
295 goto err;
296 }
297 }
298 }
299 d2printk("xfer done\n");
300 d1printk(" >");
301 i2c_set_attr(dev,STOP);
302 rc = -EIO;
303 if (!i2c_is_busy_wait(dev))
304 goto err;
305 status = i2c_get_status(dev);
306 if (i2c_is_error(status))
307 goto err;
308
309 d1printk("\n");
310 return num;
311 err:
312 if (1 == i2c_debug) {
313 status = i2c_get_status(dev);
314 printk(" ERROR: %s\n",str_i2c_status[status]);
315 }
316 return rc;
317}
318
319/* ----------------------------------------------------------- */
320
321static int algo_control(struct i2c_adapter *adapter,
322 unsigned int cmd, unsigned long arg)
323{
324 return 0;
325}
326
327static u32 functionality(struct i2c_adapter *adap)
328{
329 return I2C_FUNC_SMBUS_EMUL;
330}
331
332static int attach_inform(struct i2c_client *client)
333{
334 struct saa7134_dev *dev = client->adapter->algo_data;
335 int tuner = dev->tuner_type;
336 int conf = dev->tda9887_conf;
337
338 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
339 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&conf);
340 return 0;
341}
342
343static struct i2c_algorithm saa7134_algo = {
344 .name = "saa7134",
345 .id = I2C_ALGO_SAA7134,
346 .master_xfer = saa7134_i2c_xfer,
347 .algo_control = algo_control,
348 .functionality = functionality,
349};
350
351static struct i2c_adapter saa7134_adap_template = {
352 .owner = THIS_MODULE,
353#ifdef I2C_CLASS_TV_ANALOG
354 .class = I2C_CLASS_TV_ANALOG,
355#endif
356 I2C_DEVNAME("saa7134"),
357 .id = I2C_ALGO_SAA7134,
358 .algo = &saa7134_algo,
359 .client_register = attach_inform,
360};
361
362static struct i2c_client saa7134_client_template = {
363 I2C_DEVNAME("saa7134 internal"),
364};
365
366/* ----------------------------------------------------------- */
367
368static int
369saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
370{
371 unsigned char buf;
372 int i,err;
373
374 dev->i2c_client.addr = 0xa0 >> 1;
375 buf = 0;
376 if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
377 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
378 dev->name,err);
379 return -1;
380 }
381 if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
382 printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
383 dev->name,err);
384 return -1;
385 }
386 for (i = 0; i < len; i++) {
387 if (0 == (i % 16))
388 printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i);
389 printk(" %02x",eedata[i]);
390 if (15 == (i % 16))
391 printk("\n");
392 }
393 return 0;
394}
395
396static char *i2c_devs[128] = {
397 [ 0x20 ] = "mpeg encoder (saa6752hs)",
398 [ 0xa0 >> 1 ] = "eeprom",
399 [ 0xc0 >> 1 ] = "tuner (analog)",
400 [ 0x86 >> 1 ] = "tda9887",
401};
402
403static void do_i2c_scan(char *name, struct i2c_client *c)
404{
405 unsigned char buf;
406 int i,rc;
407
408 for (i = 0; i < 128; i++) {
409 c->addr = i;
410 rc = i2c_master_recv(c,&buf,0);
411 if (rc < 0)
412 continue;
413 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
414 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
415 }
416}
417
418void saa7134_i2c_call_clients(struct saa7134_dev *dev,
419 unsigned int cmd, void *arg)
420{
421 BUG_ON(NULL == dev->i2c_adap.algo_data);
422 i2c_clients_command(&dev->i2c_adap, cmd, arg);
423}
424
425int saa7134_i2c_register(struct saa7134_dev *dev)
426{
427 dev->i2c_adap = saa7134_adap_template;
428 dev->i2c_adap.dev.parent = &dev->pci->dev;
429 strcpy(dev->i2c_adap.name,dev->name);
430 dev->i2c_adap.algo_data = dev;
431 i2c_add_adapter(&dev->i2c_adap);
432
433 dev->i2c_client = saa7134_client_template;
434 dev->i2c_client.adapter = &dev->i2c_adap;
435
436 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
437 if (i2c_scan)
438 do_i2c_scan(dev->name,&dev->i2c_client);
439 return 0;
440}
441
442int saa7134_i2c_unregister(struct saa7134_dev *dev)
443{
444 i2c_del_adapter(&dev->i2c_adap);
445 return 0;
446}
447
448/* ----------------------------------------------------------- */
449/*
450 * Local variables:
451 * c-basic-offset: 8
452 * End:
453 */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
new file mode 100644
index 000000000000..727d437e07df
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -0,0 +1,491 @@
1/*
2 * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * handle saa7134 IR remotes via linux kernel input layer.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/sched.h>
27#include <linux/interrupt.h>
28#include <linux/input.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33static unsigned int disable_ir = 0;
34module_param(disable_ir, int, 0444);
35MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
36
37static unsigned int ir_debug = 0;
38module_param(ir_debug, int, 0644);
39MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
40
41#define dprintk(fmt, arg...) if (ir_debug) \
42 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
43
44/* ---------------------------------------------------------------------- */
45
46static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
47 [ 15 ] = KEY_KP0,
48 [ 3 ] = KEY_KP1,
49 [ 4 ] = KEY_KP2,
50 [ 5 ] = KEY_KP3,
51 [ 7 ] = KEY_KP4,
52 [ 8 ] = KEY_KP5,
53 [ 9 ] = KEY_KP6,
54 [ 11 ] = KEY_KP7,
55 [ 12 ] = KEY_KP8,
56 [ 13 ] = KEY_KP9,
57
58 [ 14 ] = KEY_TUNER, // Air/Cable
59 [ 17 ] = KEY_VIDEO, // Video
60 [ 21 ] = KEY_AUDIO, // Audio
61 [ 0 ] = KEY_POWER, // Pover
62 [ 2 ] = KEY_ZOOM, // Fullscreen
63 [ 27 ] = KEY_MUTE, // Mute
64 [ 20 ] = KEY_VOLUMEUP,
65 [ 23 ] = KEY_VOLUMEDOWN,
66 [ 18 ] = KEY_CHANNELUP, // Channel +
67 [ 19 ] = KEY_CHANNELDOWN, // Channel -
68 [ 6 ] = KEY_AGAIN, // Recal
69 [ 16 ] = KEY_KPENTER, // Enter
70
71#if 1 /* FIXME */
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
74#endif
75};
76
77static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
78 [ 0 ] = KEY_KP0,
79 [ 1 ] = KEY_KP1,
80 [ 2 ] = KEY_KP2,
81 [ 3 ] = KEY_KP3,
82 [ 4 ] = KEY_KP4,
83 [ 5 ] = KEY_KP5,
84 [ 6 ] = KEY_KP6,
85 [ 7 ] = KEY_KP7,
86 [ 8 ] = KEY_KP8,
87 [ 9 ] = KEY_KP9,
88
89 [ 0x0a ] = KEY_POWER,
90 [ 0x0b ] = KEY_PROG1, // app
91 [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
92 [ 0x0d ] = KEY_CHANNELUP, // channel
93 [ 0x0e ] = KEY_CHANNELDOWN, // channel-
94 [ 0x0f ] = KEY_VOLUMEUP,
95 [ 0x10 ] = KEY_VOLUMEDOWN,
96 [ 0x11 ] = KEY_TUNER, // AV
97 [ 0x12 ] = KEY_NUMLOCK, // -/--
98 [ 0x13 ] = KEY_AUDIO, // audio
99 [ 0x14 ] = KEY_MUTE,
100 [ 0x15 ] = KEY_UP,
101 [ 0x16 ] = KEY_DOWN,
102 [ 0x17 ] = KEY_LEFT,
103 [ 0x18 ] = KEY_RIGHT,
104 [ 0x19 ] = BTN_LEFT,
105 [ 0x1a ] = BTN_RIGHT,
106 [ 0x1b ] = KEY_WWW, // text
107 [ 0x1c ] = KEY_REWIND,
108 [ 0x1d ] = KEY_FORWARD,
109 [ 0x1e ] = KEY_RECORD,
110 [ 0x1f ] = KEY_PLAY,
111 [ 0x20 ] = KEY_PREVIOUSSONG,
112 [ 0x21 ] = KEY_NEXTSONG,
113 [ 0x22 ] = KEY_PAUSE,
114 [ 0x23 ] = KEY_STOP,
115};
116
117/* Alfons Geser <a.geser@cox.net>
118 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
119static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
120 [ 18 ] = KEY_POWER,
121 [ 1 ] = KEY_TV, // DVR
122 [ 21 ] = KEY_DVD, // DVD
123 [ 23 ] = KEY_AUDIO, // music
124 // DVR mode / DVD mode / music mode
125
126 [ 27 ] = KEY_MUTE, // mute
127 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
128 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
129 [ 22 ] = KEY_ZOOM, // full screen
130 [ 28 ] = KEY_VIDEO, // video source / eject / delall
131 [ 29 ] = KEY_RESTART, // playback / angle / del
132 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
133 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
134
135 [ 49 ] = KEY_HELP, // help
136 [ 50 ] = KEY_MODE, // num/memo
137 [ 51 ] = KEY_ESC, // cancel
138
139 [ 12 ] = KEY_UP, // up
140 [ 16 ] = KEY_DOWN, // down
141 [ 8 ] = KEY_LEFT, // left
142 [ 4 ] = KEY_RIGHT, // right
143 [ 3 ] = KEY_SELECT, // select
144
145 [ 31 ] = KEY_REWIND, // rewind
146 [ 32 ] = KEY_PLAYPAUSE, // play/pause
147 [ 41 ] = KEY_FORWARD, // forward
148 [ 20 ] = KEY_AGAIN, // repeat
149 [ 43 ] = KEY_RECORD, // recording
150 [ 44 ] = KEY_STOP, // stop
151 [ 45 ] = KEY_PLAY, // play
152 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
153
154 [ 0 ] = KEY_KP0,
155 [ 5 ] = KEY_KP1,
156 [ 6 ] = KEY_KP2,
157 [ 7 ] = KEY_KP3,
158 [ 9 ] = KEY_KP4,
159 [ 10 ] = KEY_KP5,
160 [ 11 ] = KEY_KP6,
161 [ 13 ] = KEY_KP7,
162 [ 14 ] = KEY_KP8,
163 [ 15 ] = KEY_KP9,
164
165 [ 42 ] = KEY_VOLUMEUP,
166 [ 17 ] = KEY_VOLUMEDOWN,
167 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
168 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
169
170 [ 19 ] = KEY_KPENTER, // enter
171 [ 33 ] = KEY_KPDOT, // . (decimal dot)
172};
173
174static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
175 [ 30 ] = KEY_POWER, // power
176 [ 28 ] = KEY_SEARCH, // scan
177 [ 7 ] = KEY_SELECT, // source
178
179 [ 22 ] = KEY_VOLUMEUP,
180 [ 20 ] = KEY_VOLUMEDOWN,
181 [ 31 ] = KEY_CHANNELUP,
182 [ 23 ] = KEY_CHANNELDOWN,
183 [ 24 ] = KEY_MUTE,
184
185 [ 2 ] = KEY_KP0,
186 [ 1 ] = KEY_KP1,
187 [ 11 ] = KEY_KP2,
188 [ 27 ] = KEY_KP3,
189 [ 5 ] = KEY_KP4,
190 [ 9 ] = KEY_KP5,
191 [ 21 ] = KEY_KP6,
192 [ 6 ] = KEY_KP7,
193 [ 10 ] = KEY_KP8,
194 [ 18 ] = KEY_KP9,
195 [ 16 ] = KEY_KPDOT,
196
197 [ 3 ] = KEY_TUNER, // tv/fm
198 [ 4 ] = KEY_REWIND, // fm tuning left or function left
199 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
200
201 [ 0 ] = KEY_RECORD,
202 [ 8 ] = KEY_STOP,
203 [ 17 ] = KEY_PLAY,
204
205 [ 25 ] = KEY_ZOOM,
206 [ 14 ] = KEY_MENU, // function
207 [ 19 ] = KEY_AGAIN, // recall
208 [ 29 ] = KEY_RESTART, // reset
209
210// FIXME
211 [ 13 ] = KEY_F21, // mts
212 [ 15 ] = KEY_F22, // min
213 [ 26 ] = KEY_F23, // freeze
214};
215
216/* Alex Hermann <gaaf@gmx.net> */
217static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
218 [ 40 ] = KEY_KP1,
219 [ 24 ] = KEY_KP2,
220 [ 56 ] = KEY_KP3,
221 [ 36 ] = KEY_KP4,
222 [ 20 ] = KEY_KP5,
223 [ 52 ] = KEY_KP6,
224 [ 44 ] = KEY_KP7,
225 [ 28 ] = KEY_KP8,
226 [ 60 ] = KEY_KP9,
227 [ 34 ] = KEY_KP0,
228
229 [ 32 ] = KEY_TV, // TV/FM
230 [ 16 ] = KEY_CD, // CD
231 [ 48 ] = KEY_TEXT, // TELETEXT
232 [ 0 ] = KEY_POWER, // POWER
233
234 [ 8 ] = KEY_VIDEO, // VIDEO
235 [ 4 ] = KEY_AUDIO, // AUDIO
236 [ 12 ] = KEY_ZOOM, // FULL SCREEN
237
238 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
239 [ 50 ] = KEY_REWIND, // LOOP - ???
240 [ 2 ] = KEY_PRINT, // PREVIEW - ???
241
242 [ 42 ] = KEY_SEARCH, // AUTOSCAN
243 [ 26 ] = KEY_SLEEP, // FREEZE - ???
244 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
245 [ 10 ] = KEY_MUTE, // MUTE
246
247 [ 38 ] = KEY_RECORD, // RECORD
248 [ 22 ] = KEY_PAUSE, // PAUSE
249 [ 54 ] = KEY_STOP, // STOP
250 [ 6 ] = KEY_PLAY, // PLAY
251
252 [ 46 ] = KEY_RED, // <RED>
253 [ 33 ] = KEY_GREEN, // <GREEN>
254 [ 14 ] = KEY_YELLOW, // <YELLOW>
255 [ 1 ] = KEY_BLUE, // <BLUE>
256
257 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
258 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
259 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
260 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
261};
262
263static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
264 [ 20 ] = KEY_MUTE,
265 [ 36 ] = KEY_ZOOM,
266
267 [ 1 ] = KEY_DVD,
268 [ 35 ] = KEY_RADIO,
269 [ 0 ] = KEY_TV,
270
271 [ 10 ] = KEY_REWIND,
272 [ 8 ] = KEY_PLAYPAUSE,
273 [ 15 ] = KEY_FORWARD,
274
275 [ 2 ] = KEY_PREVIOUS,
276 [ 7 ] = KEY_STOP,
277 [ 6 ] = KEY_NEXT,
278
279 [ 12 ] = KEY_UP,
280 [ 14 ] = KEY_DOWN,
281 [ 11 ] = KEY_LEFT,
282 [ 13 ] = KEY_RIGHT,
283 [ 17 ] = KEY_OK,
284
285 [ 3 ] = KEY_MENU,
286 [ 9 ] = KEY_SETUP,
287 [ 5 ] = KEY_VIDEO,
288 [ 34 ] = KEY_CHANNEL,
289
290 [ 18 ] = KEY_VOLUMEUP,
291 [ 21 ] = KEY_VOLUMEDOWN,
292 [ 16 ] = KEY_CHANNELUP,
293 [ 19 ] = KEY_CHANNELDOWN,
294
295 [ 4 ] = KEY_RECORD,
296
297 [ 22 ] = KEY_KP1,
298 [ 23 ] = KEY_KP2,
299 [ 24 ] = KEY_KP3,
300 [ 25 ] = KEY_KP4,
301 [ 26 ] = KEY_KP5,
302 [ 27 ] = KEY_KP6,
303 [ 28 ] = KEY_KP7,
304 [ 29 ] = KEY_KP8,
305 [ 30 ] = KEY_KP9,
306 [ 31 ] = KEY_KP0,
307
308 [ 32 ] = KEY_LANGUAGE,
309 [ 33 ] = KEY_SLEEP,
310};
311/* ---------------------------------------------------------------------- */
312
313static int build_key(struct saa7134_dev *dev)
314{
315 struct saa7134_ir *ir = dev->remote;
316 u32 gpio, data;
317
318 /* rising SAA7134_GPIO_GPRESCAN reads the status */
319 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
320 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
321
322 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
323 if (ir->polling) {
324 if (ir->last_gpio == gpio)
325 return 0;
326 ir->last_gpio = gpio;
327 }
328
329 data = ir_extract_bits(gpio, ir->mask_keycode);
330 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
331 gpio, ir->mask_keycode, data);
332
333 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
334 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
335 ir_input_keydown(&ir->dev,&ir->ir,data,data);
336 } else {
337 ir_input_nokey(&ir->dev,&ir->ir);
338 }
339 return 0;
340}
341
342/* ---------------------------------------------------------------------- */
343
344void saa7134_input_irq(struct saa7134_dev *dev)
345{
346 struct saa7134_ir *ir = dev->remote;
347
348 if (!ir->polling)
349 build_key(dev);
350}
351
352static void saa7134_input_timer(unsigned long data)
353{
354 struct saa7134_dev *dev = (struct saa7134_dev*)data;
355 struct saa7134_ir *ir = dev->remote;
356 unsigned long timeout;
357
358 build_key(dev);
359 timeout = jiffies + (ir->polling * HZ / 1000);
360 mod_timer(&ir->timer, timeout);
361}
362
363int saa7134_input_init1(struct saa7134_dev *dev)
364{
365 struct saa7134_ir *ir;
366 IR_KEYTAB_TYPE *ir_codes = NULL;
367 u32 mask_keycode = 0;
368 u32 mask_keydown = 0;
369 u32 mask_keyup = 0;
370 int polling = 0;
371 int ir_type = IR_TYPE_OTHER;
372
373 if (!dev->has_remote)
374 return -ENODEV;
375 if (disable_ir)
376 return -ENODEV;
377
378 /* detect & configure */
379 switch (dev->board) {
380 case SAA7134_BOARD_FLYVIDEO2000:
381 case SAA7134_BOARD_FLYVIDEO3000:
382 ir_codes = flyvideo_codes;
383 mask_keycode = 0xEC00000;
384 mask_keydown = 0x0040000;
385 break;
386 case SAA7134_BOARD_CINERGY400:
387 case SAA7134_BOARD_CINERGY600:
388 case SAA7134_BOARD_CINERGY600_MK3:
389 ir_codes = cinergy_codes;
390 mask_keycode = 0x00003f;
391 mask_keyup = 0x040000;
392 break;
393 case SAA7134_BOARD_ECS_TVP3XP:
394 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
395 ir_codes = eztv_codes;
396 mask_keycode = 0x00017c;
397 mask_keyup = 0x000002;
398 polling = 50; // ms
399 break;
400 case SAA7134_BOARD_AVACSSMARTTV:
401 ir_codes = avacssmart_codes;
402 mask_keycode = 0x00001F;
403 mask_keyup = 0x000020;
404 polling = 50; // ms
405 break;
406 case SAA7134_BOARD_MD2819:
407 case SAA7134_BOARD_AVERMEDIA_305:
408 case SAA7134_BOARD_AVERMEDIA_307:
409 ir_codes = md2819_codes;
410 mask_keycode = 0x0007C8;
411 mask_keydown = 0x000010;
412 polling = 50; // ms
413 /* Set GPIO pin2 to high to enable the IR controller */
414 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
415 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
416 break;
417 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
418 ir_codes = videomate_tv_pvr_codes;
419 mask_keycode = 0x00003F;
420 mask_keyup = 0x400000;
421 polling = 50; // ms
422 break;
423 }
424 if (NULL == ir_codes) {
425 printk("%s: Oops: IR config error [card=%d]\n",
426 dev->name, dev->board);
427 return -ENODEV;
428 }
429
430 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
431 if (NULL == ir)
432 return -ENOMEM;
433 memset(ir,0,sizeof(*ir));
434
435 /* init hardware-specific stuff */
436 ir->mask_keycode = mask_keycode;
437 ir->mask_keydown = mask_keydown;
438 ir->mask_keyup = mask_keyup;
439 ir->polling = polling;
440
441 /* init input device */
442 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
443 saa7134_boards[dev->board].name);
444 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
445 pci_name(dev->pci));
446
447 ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
448 ir->dev.name = ir->name;
449 ir->dev.phys = ir->phys;
450 ir->dev.id.bustype = BUS_PCI;
451 ir->dev.id.version = 1;
452 if (dev->pci->subsystem_vendor) {
453 ir->dev.id.vendor = dev->pci->subsystem_vendor;
454 ir->dev.id.product = dev->pci->subsystem_device;
455 } else {
456 ir->dev.id.vendor = dev->pci->vendor;
457 ir->dev.id.product = dev->pci->device;
458 }
459
460 /* all done */
461 dev->remote = ir;
462 if (ir->polling) {
463 init_timer(&ir->timer);
464 ir->timer.function = saa7134_input_timer;
465 ir->timer.data = (unsigned long)dev;
466 ir->timer.expires = jiffies + HZ;
467 add_timer(&ir->timer);
468 }
469
470 input_register_device(&dev->remote->dev);
471 printk("%s: registered input device for IR\n",dev->name);
472 return 0;
473}
474
475void saa7134_input_fini(struct saa7134_dev *dev)
476{
477 if (NULL == dev->remote)
478 return;
479
480 input_unregister_device(&dev->remote->dev);
481 if (dev->remote->polling)
482 del_timer_sync(&dev->remote->timer);
483 kfree(dev->remote);
484 dev->remote = NULL;
485}
486
487/* ----------------------------------------------------------------------
488 * Local variables:
489 * c-basic-offset: 8
490 * End:
491 */
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
new file mode 100644
index 000000000000..6b6a643bf1cd
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -0,0 +1,857 @@
1/*
2 * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * oss dsp interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30#include <linux/soundcard.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int oss_debug = 0;
38module_param(oss_debug, int, 0644);
39MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
40
41static unsigned int oss_rate = 0;
42module_param(oss_rate, int, 0444);
43MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44
45#define dprintk(fmt, arg...) if (oss_debug) \
46 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
47
48/* ------------------------------------------------------------------ */
49
50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
51{
52 blksize &= ~0xff;
53 if (blksize < 0x100)
54 blksize = 0x100;
55 if (blksize > 0x10000)
56 blksize = 0x10000;
57
58 if (blocks < 2)
59 blocks = 2;
60 while ((blksize * blocks) & ~PAGE_MASK)
61 blocks++;
62 if ((blksize * blocks) > 1024*1024)
63 blocks = 1024*1024 / blksize;
64
65 dev->oss.blocks = blocks;
66 dev->oss.blksize = blksize;
67 dev->oss.bufsize = blksize * blocks;
68
69 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
70 blocks,blksize,blksize * blocks / 1024);
71 return 0;
72}
73
74static int dsp_buffer_init(struct saa7134_dev *dev)
75{
76 int err;
77
78 if (!dev->oss.bufsize)
79 BUG();
80 videobuf_dma_init(&dev->oss.dma);
81 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
82 dev->oss.bufsize >> PAGE_SHIFT);
83 if (0 != err)
84 return err;
85 return 0;
86}
87
88static int dsp_buffer_free(struct saa7134_dev *dev)
89{
90 if (!dev->oss.blksize)
91 BUG();
92 videobuf_dma_free(&dev->oss.dma);
93 dev->oss.blocks = 0;
94 dev->oss.blksize = 0;
95 dev->oss.bufsize = 0;
96 return 0;
97}
98
99static void dsp_dma_start(struct saa7134_dev *dev)
100{
101 dev->oss.dma_blk = 0;
102 dev->oss.dma_running = 1;
103 saa7134_set_dmabits(dev);
104}
105
106static void dsp_dma_stop(struct saa7134_dev *dev)
107{
108 dev->oss.dma_blk = -1;
109 dev->oss.dma_running = 0;
110 saa7134_set_dmabits(dev);
111}
112
113static int dsp_rec_start(struct saa7134_dev *dev)
114{
115 int err, bswap, sign;
116 u32 fmt, control;
117 unsigned long flags;
118
119 /* prepare buffer */
120 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
121 return err;
122 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt)))
123 goto fail1;
124 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
125 dev->oss.dma.sglist,
126 dev->oss.dma.sglen,
127 0)))
128 goto fail2;
129
130 /* sample format */
131 switch (dev->oss.afmt) {
132 case AFMT_U8:
133 case AFMT_S8: fmt = 0x00; break;
134 case AFMT_U16_LE:
135 case AFMT_U16_BE:
136 case AFMT_S16_LE:
137 case AFMT_S16_BE: fmt = 0x01; break;
138 default:
139 err = -EINVAL;
140 goto fail2;
141 }
142
143 switch (dev->oss.afmt) {
144 case AFMT_S8:
145 case AFMT_S16_LE:
146 case AFMT_S16_BE: sign = 1; break;
147 default: sign = 0; break;
148 }
149
150 switch (dev->oss.afmt) {
151 case AFMT_U16_BE:
152 case AFMT_S16_BE: bswap = 1; break;
153 default: bswap = 0; break;
154 }
155
156 switch (dev->pci->device) {
157 case PCI_DEVICE_ID_PHILIPS_SAA7134:
158 if (1 == dev->oss.channels)
159 fmt |= (1 << 3);
160 if (2 == dev->oss.channels)
161 fmt |= (3 << 3);
162 if (sign)
163 fmt |= 0x04;
164 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
165
166 saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
167 saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8);
168 saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
169 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
170 break;
171 case PCI_DEVICE_ID_PHILIPS_SAA7133:
172 case PCI_DEVICE_ID_PHILIPS_SAA7135:
173 if (1 == dev->oss.channels)
174 fmt |= (1 << 4);
175 if (2 == dev->oss.channels)
176 fmt |= (2 << 4);
177 if (!sign)
178 fmt |= 0x04;
179 saa_writel(0x588 >> 2, dev->oss.blksize -4);
180 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
181 break;
182 }
183 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
184 dev->oss.afmt, dev->oss.channels, fmt,
185 bswap ? 'b' : '-');
186
187 /* dma: setup channel 6 (= AUDIO) */
188 control = SAA7134_RS_CONTROL_BURST_16 |
189 SAA7134_RS_CONTROL_ME |
190 (dev->oss.pt.dma >> 12);
191 if (bswap)
192 control |= SAA7134_RS_CONTROL_BSWAP;
193 saa_writel(SAA7134_RS_BA1(6),0);
194 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
195 saa_writel(SAA7134_RS_PITCH(6),0);
196 saa_writel(SAA7134_RS_CONTROL(6),control);
197
198 /* start dma */
199 dev->oss.recording_on = 1;
200 spin_lock_irqsave(&dev->slock,flags);
201 dsp_dma_start(dev);
202 spin_unlock_irqrestore(&dev->slock,flags);
203 return 0;
204
205 fail2:
206 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
207 fail1:
208 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
209 return err;
210}
211
212static int dsp_rec_stop(struct saa7134_dev *dev)
213{
214 unsigned long flags;
215
216 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk);
217
218 /* stop dma */
219 dev->oss.recording_on = 0;
220 spin_lock_irqsave(&dev->slock,flags);
221 dsp_dma_stop(dev);
222 spin_unlock_irqrestore(&dev->slock,flags);
223
224 /* unlock buffer */
225 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
226 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
227 return 0;
228}
229
230/* ------------------------------------------------------------------ */
231
232static int dsp_open(struct inode *inode, struct file *file)
233{
234 int minor = iminor(inode);
235 struct saa7134_dev *h,*dev = NULL;
236 struct list_head *list;
237 int err;
238
239 list_for_each(list,&saa7134_devlist) {
240 h = list_entry(list, struct saa7134_dev, devlist);
241 if (h->oss.minor_dsp == minor)
242 dev = h;
243 }
244 if (NULL == dev)
245 return -ENODEV;
246
247 down(&dev->oss.lock);
248 err = -EBUSY;
249 if (dev->oss.users_dsp)
250 goto fail1;
251 dev->oss.users_dsp++;
252 file->private_data = dev;
253
254 dev->oss.afmt = AFMT_U8;
255 dev->oss.channels = 1;
256 dev->oss.read_count = 0;
257 dev->oss.read_offset = 0;
258 dsp_buffer_conf(dev,PAGE_SIZE,64);
259 err = dsp_buffer_init(dev);
260 if (0 != err)
261 goto fail2;
262
263 up(&dev->oss.lock);
264 return 0;
265
266 fail2:
267 dev->oss.users_dsp--;
268 fail1:
269 up(&dev->oss.lock);
270 return err;
271}
272
273static int dsp_release(struct inode *inode, struct file *file)
274{
275 struct saa7134_dev *dev = file->private_data;
276
277 down(&dev->oss.lock);
278 if (dev->oss.recording_on)
279 dsp_rec_stop(dev);
280 dsp_buffer_free(dev);
281 dev->oss.users_dsp--;
282 file->private_data = NULL;
283 up(&dev->oss.lock);
284 return 0;
285}
286
287static ssize_t dsp_read(struct file *file, char __user *buffer,
288 size_t count, loff_t *ppos)
289{
290 struct saa7134_dev *dev = file->private_data;
291 DECLARE_WAITQUEUE(wait, current);
292 unsigned int bytes;
293 unsigned long flags;
294 int err,ret = 0;
295
296 add_wait_queue(&dev->oss.wq, &wait);
297 down(&dev->oss.lock);
298 while (count > 0) {
299 /* wait for data if needed */
300 if (0 == dev->oss.read_count) {
301 if (!dev->oss.recording_on) {
302 err = dsp_rec_start(dev);
303 if (err < 0) {
304 if (0 == ret)
305 ret = err;
306 break;
307 }
308 }
309 if (dev->oss.recording_on &&
310 !dev->oss.dma_running) {
311 /* recover from overruns */
312 spin_lock_irqsave(&dev->slock,flags);
313 dsp_dma_start(dev);
314 spin_unlock_irqrestore(&dev->slock,flags);
315 }
316 if (file->f_flags & O_NONBLOCK) {
317 if (0 == ret)
318 ret = -EAGAIN;
319 break;
320 }
321 up(&dev->oss.lock);
322 set_current_state(TASK_INTERRUPTIBLE);
323 if (0 == dev->oss.read_count)
324 schedule();
325 set_current_state(TASK_RUNNING);
326 down(&dev->oss.lock);
327 if (signal_pending(current)) {
328 if (0 == ret)
329 ret = -EINTR;
330 break;
331 }
332 }
333
334 /* copy data to userspace */
335 bytes = count;
336 if (bytes > dev->oss.read_count)
337 bytes = dev->oss.read_count;
338 if (bytes > dev->oss.bufsize - dev->oss.read_offset)
339 bytes = dev->oss.bufsize - dev->oss.read_offset;
340 if (copy_to_user(buffer + ret,
341 dev->oss.dma.vmalloc + dev->oss.read_offset,
342 bytes)) {
343 if (0 == ret)
344 ret = -EFAULT;
345 break;
346 }
347
348 ret += bytes;
349 count -= bytes;
350 dev->oss.read_count -= bytes;
351 dev->oss.read_offset += bytes;
352 if (dev->oss.read_offset == dev->oss.bufsize)
353 dev->oss.read_offset = 0;
354 }
355 up(&dev->oss.lock);
356 remove_wait_queue(&dev->oss.wq, &wait);
357 return ret;
358}
359
360static ssize_t dsp_write(struct file *file, const char __user *buffer,
361 size_t count, loff_t *ppos)
362{
363 return -EINVAL;
364}
365
366static int dsp_ioctl(struct inode *inode, struct file *file,
367 unsigned int cmd, unsigned long arg)
368{
369 struct saa7134_dev *dev = file->private_data;
370 void __user *argp = (void __user *) arg;
371 int __user *p = argp;
372 int val = 0;
373
374 if (oss_debug > 1)
375 saa7134_print_ioctl(dev->name,cmd);
376 switch (cmd) {
377 case OSS_GETVERSION:
378 return put_user(SOUND_VERSION, p);
379 case SNDCTL_DSP_GETCAPS:
380 return 0;
381
382 case SNDCTL_DSP_SPEED:
383 if (get_user(val, p))
384 return -EFAULT;
385 /* fall through */
386 case SOUND_PCM_READ_RATE:
387 return put_user(dev->oss.rate, p);
388
389 case SNDCTL_DSP_STEREO:
390 if (get_user(val, p))
391 return -EFAULT;
392 down(&dev->oss.lock);
393 dev->oss.channels = val ? 2 : 1;
394 if (dev->oss.recording_on) {
395 dsp_rec_stop(dev);
396 dsp_rec_start(dev);
397 }
398 up(&dev->oss.lock);
399 return put_user(dev->oss.channels-1, p);
400
401 case SNDCTL_DSP_CHANNELS:
402 if (get_user(val, p))
403 return -EFAULT;
404 if (val != 1 && val != 2)
405 return -EINVAL;
406 down(&dev->oss.lock);
407 dev->oss.channels = val;
408 if (dev->oss.recording_on) {
409 dsp_rec_stop(dev);
410 dsp_rec_start(dev);
411 }
412 up(&dev->oss.lock);
413 /* fall through */
414 case SOUND_PCM_READ_CHANNELS:
415 return put_user(dev->oss.channels, p);
416
417 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
418 return put_user(AFMT_U8 | AFMT_S8 |
419 AFMT_U16_LE | AFMT_U16_BE |
420 AFMT_S16_LE | AFMT_S16_BE, p);
421
422 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
423 if (get_user(val, p))
424 return -EFAULT;
425 switch (val) {
426 case AFMT_QUERY:
427 /* nothing to do */
428 break;
429 case AFMT_U8:
430 case AFMT_S8:
431 case AFMT_U16_LE:
432 case AFMT_U16_BE:
433 case AFMT_S16_LE:
434 case AFMT_S16_BE:
435 down(&dev->oss.lock);
436 dev->oss.afmt = val;
437 if (dev->oss.recording_on) {
438 dsp_rec_stop(dev);
439 dsp_rec_start(dev);
440 }
441 up(&dev->oss.lock);
442 return put_user(dev->oss.afmt, p);
443 default:
444 return -EINVAL;
445 }
446
447 case SOUND_PCM_READ_BITS:
448 switch (dev->oss.afmt) {
449 case AFMT_U8:
450 case AFMT_S8:
451 return put_user(8, p);
452 case AFMT_U16_LE:
453 case AFMT_U16_BE:
454 case AFMT_S16_LE:
455 case AFMT_S16_BE:
456 return put_user(16, p);
457 default:
458 return -EINVAL;
459 }
460
461 case SNDCTL_DSP_NONBLOCK:
462 file->f_flags |= O_NONBLOCK;
463 return 0;
464
465 case SNDCTL_DSP_RESET:
466 down(&dev->oss.lock);
467 if (dev->oss.recording_on)
468 dsp_rec_stop(dev);
469 up(&dev->oss.lock);
470 return 0;
471 case SNDCTL_DSP_GETBLKSIZE:
472 return put_user(dev->oss.blksize, p);
473
474 case SNDCTL_DSP_SETFRAGMENT:
475 if (get_user(val, p))
476 return -EFAULT;
477 if (dev->oss.recording_on)
478 return -EBUSY;
479 dsp_buffer_free(dev);
480 /* used to be arg >> 16 instead of val >> 16; fixed */
481 dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff);
482 dsp_buffer_init(dev);
483 return 0;
484
485 case SNDCTL_DSP_SYNC:
486 /* NOP */
487 return 0;
488
489 case SNDCTL_DSP_GETISPACE:
490 {
491 audio_buf_info info;
492 info.fragsize = dev->oss.blksize;
493 info.fragstotal = dev->oss.blocks;
494 info.bytes = dev->oss.read_count;
495 info.fragments = info.bytes / info.fragsize;
496 if (copy_to_user(argp, &info, sizeof(info)))
497 return -EFAULT;
498 return 0;
499 }
500 default:
501 return -EINVAL;
502 }
503}
504
505static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
506{
507 struct saa7134_dev *dev = file->private_data;
508 unsigned int mask = 0;
509
510 poll_wait(file, &dev->oss.wq, wait);
511
512 if (0 == dev->oss.read_count) {
513 down(&dev->oss.lock);
514 if (!dev->oss.recording_on)
515 dsp_rec_start(dev);
516 up(&dev->oss.lock);
517 } else
518 mask |= (POLLIN | POLLRDNORM);
519 return mask;
520}
521
522struct file_operations saa7134_dsp_fops = {
523 .owner = THIS_MODULE,
524 .open = dsp_open,
525 .release = dsp_release,
526 .read = dsp_read,
527 .write = dsp_write,
528 .ioctl = dsp_ioctl,
529 .poll = dsp_poll,
530 .llseek = no_llseek,
531};
532
533/* ------------------------------------------------------------------ */
534
535static int
536mixer_recsrc_7134(struct saa7134_dev *dev)
537{
538 int analog_io,rate;
539
540 switch (dev->oss.input) {
541 case TV:
542 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
543 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
544 break;
545 case LINE1:
546 case LINE2:
547 case LINE2_LEFT:
548 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
549 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
550 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
551 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
552 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
553 break;
554 }
555 return 0;
556}
557
558static int
559mixer_recsrc_7133(struct saa7134_dev *dev)
560{
561 u32 value = 0xbbbbbb;
562
563 switch (dev->oss.input) {
564 case TV:
565 value = 0xbbbb10; /* MAIN */
566 break;
567 case LINE1:
568 value = 0xbbbb32; /* AUX1 */
569 break;
570 case LINE2:
571 case LINE2_LEFT:
572 value = 0xbbbb54; /* AUX2 */
573 break;
574 }
575 saa_dsp_writel(dev, 0x46c >> 2, value);
576 return 0;
577}
578
579static int
580mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
581{
582 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
583
584 dev->oss.count++;
585 dev->oss.input = src;
586 dprintk("mixer input = %s\n",iname[dev->oss.input]);
587
588 switch (dev->pci->device) {
589 case PCI_DEVICE_ID_PHILIPS_SAA7134:
590 mixer_recsrc_7134(dev);
591 break;
592 case PCI_DEVICE_ID_PHILIPS_SAA7133:
593 case PCI_DEVICE_ID_PHILIPS_SAA7135:
594 mixer_recsrc_7133(dev);
595 break;
596 }
597 return 0;
598}
599
600static int
601mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
602{
603 switch (dev->pci->device) {
604 case PCI_DEVICE_ID_PHILIPS_SAA7134:
605 switch (src) {
606 case TV:
607 /* nothing */
608 break;
609 case LINE1:
610 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10,
611 (100 == level) ? 0x00 : 0x10);
612 break;
613 case LINE2:
614 case LINE2_LEFT:
615 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
616 (100 == level) ? 0x00 : 0x20);
617 break;
618 }
619 break;
620 case PCI_DEVICE_ID_PHILIPS_SAA7133:
621 case PCI_DEVICE_ID_PHILIPS_SAA7135:
622 /* nothing */
623 break;
624 }
625 return 0;
626}
627
628/* ------------------------------------------------------------------ */
629
630static int mixer_open(struct inode *inode, struct file *file)
631{
632 int minor = iminor(inode);
633 struct saa7134_dev *h,*dev = NULL;
634 struct list_head *list;
635
636 list_for_each(list,&saa7134_devlist) {
637 h = list_entry(list, struct saa7134_dev, devlist);
638 if (h->oss.minor_mixer == minor)
639 dev = h;
640 }
641 if (NULL == dev)
642 return -ENODEV;
643
644 file->private_data = dev;
645 return 0;
646}
647
648static int mixer_release(struct inode *inode, struct file *file)
649{
650 file->private_data = NULL;
651 return 0;
652}
653
654static int mixer_ioctl(struct inode *inode, struct file *file,
655 unsigned int cmd, unsigned long arg)
656{
657 struct saa7134_dev *dev = file->private_data;
658 enum saa7134_audio_in input;
659 int val,ret;
660 void __user *argp = (void __user *) arg;
661 int __user *p = argp;
662
663 if (oss_debug > 1)
664 saa7134_print_ioctl(dev->name,cmd);
665 switch (cmd) {
666 case OSS_GETVERSION:
667 return put_user(SOUND_VERSION, p);
668 case SOUND_MIXER_INFO:
669 {
670 mixer_info info;
671 memset(&info,0,sizeof(info));
672 strlcpy(info.id, "TV audio", sizeof(info.id));
673 strlcpy(info.name, dev->name, sizeof(info.name));
674 info.modify_counter = dev->oss.count;
675 if (copy_to_user(argp, &info, sizeof(info)))
676 return -EFAULT;
677 return 0;
678 }
679 case SOUND_OLD_MIXER_INFO:
680 {
681 _old_mixer_info info;
682 memset(&info,0,sizeof(info));
683 strlcpy(info.id, "TV audio", sizeof(info.id));
684 strlcpy(info.name, dev->name, sizeof(info.name));
685 if (copy_to_user(argp, &info, sizeof(info)))
686 return -EFAULT;
687 return 0;
688 }
689 case MIXER_READ(SOUND_MIXER_CAPS):
690 return put_user(SOUND_CAP_EXCL_INPUT, p);
691 case MIXER_READ(SOUND_MIXER_STEREODEVS):
692 return put_user(0, p);
693 case MIXER_READ(SOUND_MIXER_RECMASK):
694 case MIXER_READ(SOUND_MIXER_DEVMASK):
695 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
696 if (32000 == dev->oss.rate)
697 val |= SOUND_MASK_VIDEO;
698 return put_user(val, p);
699
700 case MIXER_WRITE(SOUND_MIXER_RECSRC):
701 if (get_user(val, p))
702 return -EFAULT;
703 input = dev->oss.input;
704 if (32000 == dev->oss.rate &&
705 val & SOUND_MASK_VIDEO && dev->oss.input != TV)
706 input = TV;
707 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1)
708 input = LINE1;
709 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2)
710 input = LINE2;
711 if (input != dev->oss.input)
712 mixer_recsrc(dev,input);
713 /* fall throuth */
714 case MIXER_READ(SOUND_MIXER_RECSRC):
715 switch (dev->oss.input) {
716 case TV: ret = SOUND_MASK_VIDEO; break;
717 case LINE1: ret = SOUND_MASK_LINE1; break;
718 case LINE2: ret = SOUND_MASK_LINE2; break;
719 default: ret = 0;
720 }
721 return put_user(ret, p);
722
723 case MIXER_WRITE(SOUND_MIXER_VIDEO):
724 case MIXER_READ(SOUND_MIXER_VIDEO):
725 if (32000 != dev->oss.rate)
726 return -EINVAL;
727 return put_user(100 | 100 << 8, p);
728
729 case MIXER_WRITE(SOUND_MIXER_LINE1):
730 if (get_user(val, p))
731 return -EFAULT;
732 val &= 0xff;
733 val = (val <= 50) ? 50 : 100;
734 dev->oss.line1 = val;
735 mixer_level(dev,LINE1,dev->oss.line1);
736 /* fall throuth */
737 case MIXER_READ(SOUND_MIXER_LINE1):
738 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p);
739
740 case MIXER_WRITE(SOUND_MIXER_LINE2):
741 if (get_user(val, p))
742 return -EFAULT;
743 val &= 0xff;
744 val = (val <= 50) ? 50 : 100;
745 dev->oss.line2 = val;
746 mixer_level(dev,LINE2,dev->oss.line2);
747 /* fall throuth */
748 case MIXER_READ(SOUND_MIXER_LINE2):
749 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p);
750
751 default:
752 return -EINVAL;
753 }
754}
755
756struct file_operations saa7134_mixer_fops = {
757 .owner = THIS_MODULE,
758 .open = mixer_open,
759 .release = mixer_release,
760 .ioctl = mixer_ioctl,
761 .llseek = no_llseek,
762};
763
764/* ------------------------------------------------------------------ */
765
766int saa7134_oss_init1(struct saa7134_dev *dev)
767{
768 /* general */
769 init_MUTEX(&dev->oss.lock);
770 init_waitqueue_head(&dev->oss.wq);
771
772 switch (dev->pci->device) {
773 case PCI_DEVICE_ID_PHILIPS_SAA7133:
774 case PCI_DEVICE_ID_PHILIPS_SAA7135:
775 saa_writel(0x588 >> 2, 0x00000fff);
776 saa_writel(0x58c >> 2, 0x00543210);
777 saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
778 break;
779 }
780
781 /* dsp */
782 dev->oss.rate = 32000;
783 if (oss_rate)
784 dev->oss.rate = oss_rate;
785 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
786
787 /* mixer */
788 dev->oss.line1 = 50;
789 dev->oss.line2 = 50;
790 mixer_level(dev,LINE1,dev->oss.line1);
791 mixer_level(dev,LINE2,dev->oss.line2);
792 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
793
794 return 0;
795}
796
797int saa7134_oss_fini(struct saa7134_dev *dev)
798{
799 /* nothing */
800 return 0;
801}
802
803void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
804{
805 int next_blk, reg = 0;
806
807 spin_lock(&dev->slock);
808 if (UNSET == dev->oss.dma_blk) {
809 dprintk("irq: recording stopped\n");
810 goto done;
811 }
812 if (0 != (status & 0x0f000000))
813 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
814 if (0 == (status & 0x10000000)) {
815 /* odd */
816 if (0 == (dev->oss.dma_blk & 0x01))
817 reg = SAA7134_RS_BA1(6);
818 } else {
819 /* even */
820 if (0 == (dev->oss.dma_blk & 0x00))
821 reg = SAA7134_RS_BA2(6);
822 }
823 if (0 == reg) {
824 dprintk("irq: field oops [%s]\n",
825 (status & 0x10000000) ? "even" : "odd");
826 goto done;
827 }
828 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
829 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count,
830 dev->oss.bufsize);
831 dsp_dma_stop(dev);
832 goto done;
833 }
834
835 /* next block addr */
836 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
837 saa_writel(reg,next_blk * dev->oss.blksize);
838 if (oss_debug > 2)
839 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
840 (status & 0x10000000) ? "even" : "odd ", next_blk,
841 next_blk * dev->oss.blksize);
842
843 /* update status & wake waiting readers */
844 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
845 dev->oss.read_count += dev->oss.blksize;
846 wake_up(&dev->oss.wq);
847
848 done:
849 spin_unlock(&dev->slock);
850}
851
852/* ----------------------------------------------------------- */
853/*
854 * Local variables:
855 * c-basic-offset: 8
856 * End:
857 */
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
new file mode 100644
index 000000000000..87734f22af7d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -0,0 +1,366 @@
1/*
2 * $Id: saa7134-reg.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 *
4 * philips saa7134 registers
5 */
6
7/* ------------------------------------------------------------------ */
8/*
9 * PCI ID's
10 */
11#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
12# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
13#endif
14#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
15# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
16#endif
17#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
18# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
19#endif
20#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
21# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
22#endif
23
24/* ------------------------------------------------------------------ */
25/*
26 * registers -- 32 bit
27 */
28
29/* DMA channels, n = 0 ... 6 */
30#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
31#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
32#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
33#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
34#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
35#define SAA7134_RS_CONTROL_BSWAP (0x01 << 24)
36#define SAA7134_RS_CONTROL_BURST_2 (0x01 << 21)
37#define SAA7134_RS_CONTROL_BURST_4 (0x02 << 21)
38#define SAA7134_RS_CONTROL_BURST_8 (0x03 << 21)
39#define SAA7134_RS_CONTROL_BURST_16 (0x04 << 21)
40#define SAA7134_RS_CONTROL_BURST_32 (0x05 << 21)
41#define SAA7134_RS_CONTROL_BURST_64 (0x06 << 21)
42#define SAA7134_RS_CONTROL_BURST_MAX (0x07 << 21)
43#define SAA7134_RS_CONTROL_ME (0x01 << 20)
44#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
45#define SAA7134_THRESHOULD (0x2a4 >> 2)
46
47/* main control */
48#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
49#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
50#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
51#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
52#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
53#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
54#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
55#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
56#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
57#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
58#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
59#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
60#define SAA7134_MAIN_CTRL_TE3 (1 << 3)
61#define SAA7134_MAIN_CTRL_TE2 (1 << 2)
62#define SAA7134_MAIN_CTRL_TE1 (1 << 1)
63#define SAA7134_MAIN_CTRL_TE0 (1 << 0)
64
65/* DMA status */
66#define SAA7134_DMA_STATUS (0x2ac >> 2)
67
68/* audio / video status */
69#define SAA7134_AV_STATUS (0x2c0 >> 2)
70#define SAA7134_AV_STATUS_STEREO (1 << 17)
71#define SAA7134_AV_STATUS_DUAL (1 << 16)
72#define SAA7134_AV_STATUS_PILOT (1 << 15)
73#define SAA7134_AV_STATUS_SMB (1 << 14)
74#define SAA7134_AV_STATUS_DMB (1 << 13)
75#define SAA7134_AV_STATUS_VDSP (1 << 12)
76#define SAA7134_AV_STATUS_IIC_STATUS (3 << 10)
77#define SAA7134_AV_STATUS_MVM (7 << 7)
78#define SAA7134_AV_STATUS_FIDT (1 << 6)
79#define SAA7134_AV_STATUS_INTL (1 << 5)
80#define SAA7134_AV_STATUS_RDCAP (1 << 4)
81#define SAA7134_AV_STATUS_PWR_ON (1 << 3)
82#define SAA7134_AV_STATUS_LOAD_ERR (1 << 2)
83#define SAA7134_AV_STATUS_TRIG_ERR (1 << 1)
84#define SAA7134_AV_STATUS_CONF_ERR (1 << 0)
85
86/* interrupt */
87#define SAA7134_IRQ1 (0x2c4 >> 2)
88#define SAA7134_IRQ1_INTE_RA3_1 (1 << 25)
89#define SAA7134_IRQ1_INTE_RA3_0 (1 << 24)
90#define SAA7134_IRQ1_INTE_RA2_3 (1 << 19)
91#define SAA7134_IRQ1_INTE_RA2_2 (1 << 18)
92#define SAA7134_IRQ1_INTE_RA2_1 (1 << 17)
93#define SAA7134_IRQ1_INTE_RA2_0 (1 << 16)
94#define SAA7134_IRQ1_INTE_RA1_3 (1 << 11)
95#define SAA7134_IRQ1_INTE_RA1_2 (1 << 10)
96#define SAA7134_IRQ1_INTE_RA1_1 (1 << 9)
97#define SAA7134_IRQ1_INTE_RA1_0 (1 << 8)
98#define SAA7134_IRQ1_INTE_RA0_7 (1 << 7)
99#define SAA7134_IRQ1_INTE_RA0_6 (1 << 6)
100#define SAA7134_IRQ1_INTE_RA0_5 (1 << 5)
101#define SAA7134_IRQ1_INTE_RA0_4 (1 << 4)
102#define SAA7134_IRQ1_INTE_RA0_3 (1 << 3)
103#define SAA7134_IRQ1_INTE_RA0_2 (1 << 2)
104#define SAA7134_IRQ1_INTE_RA0_1 (1 << 1)
105#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0)
106
107#define SAA7134_IRQ2 (0x2c8 >> 2)
108#define SAA7134_IRQ2_INTE_GPIO23A (1 << 17)
109#define SAA7134_IRQ2_INTE_GPIO23 (1 << 16)
110#define SAA7134_IRQ2_INTE_GPIO22A (1 << 15)
111#define SAA7134_IRQ2_INTE_GPIO22 (1 << 14)
112#define SAA7134_IRQ2_INTE_GPIO18A (1 << 13)
113#define SAA7134_IRQ2_INTE_GPIO18 (1 << 12)
114#define SAA7134_IRQ2_INTE_GPIO16 (1 << 11) /* not certain */
115#define SAA7134_IRQ2_INTE_SC2 (1 << 10)
116#define SAA7134_IRQ2_INTE_SC1 (1 << 9)
117#define SAA7134_IRQ2_INTE_SC0 (1 << 8)
118#define SAA7134_IRQ2_INTE_DEC5 (1 << 7)
119#define SAA7134_IRQ2_INTE_DEC4 (1 << 6)
120#define SAA7134_IRQ2_INTE_DEC3 (1 << 5)
121#define SAA7134_IRQ2_INTE_DEC2 (1 << 4)
122#define SAA7134_IRQ2_INTE_DEC1 (1 << 3)
123#define SAA7134_IRQ2_INTE_DEC0 (1 << 2)
124#define SAA7134_IRQ2_INTE_PE (1 << 1)
125#define SAA7134_IRQ2_INTE_AR (1 << 0)
126
127#define SAA7134_IRQ_REPORT (0x2cc >> 2)
128#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17)
129#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16)
130#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15)
131#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14) /* not certain */
132#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)
133#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)
134#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
135#define SAA7134_IRQ_REPORT_MMC (1 << 10)
136#define SAA7134_IRQ_REPORT_FIDT (1 << 9)
137#define SAA7134_IRQ_REPORT_INTL (1 << 8)
138#define SAA7134_IRQ_REPORT_RDCAP (1 << 7)
139#define SAA7134_IRQ_REPORT_PWR_ON (1 << 6)
140#define SAA7134_IRQ_REPORT_PE (1 << 5)
141#define SAA7134_IRQ_REPORT_AR (1 << 4)
142#define SAA7134_IRQ_REPORT_DONE_RA3 (1 << 3)
143#define SAA7134_IRQ_REPORT_DONE_RA2 (1 << 2)
144#define SAA7134_IRQ_REPORT_DONE_RA1 (1 << 1)
145#define SAA7134_IRQ_REPORT_DONE_RA0 (1 << 0)
146#define SAA7134_IRQ_STATUS (0x2d0 >> 2)
147
148
149/* ------------------------------------------------------------------ */
150/*
151 * registers -- 8 bit
152 */
153
154/* video decoder */
155#define SAA7134_INCR_DELAY 0x101
156#define SAA7134_ANALOG_IN_CTRL1 0x102
157#define SAA7134_ANALOG_IN_CTRL2 0x103
158#define SAA7134_ANALOG_IN_CTRL3 0x104
159#define SAA7134_ANALOG_IN_CTRL4 0x105
160#define SAA7134_HSYNC_START 0x106
161#define SAA7134_HSYNC_STOP 0x107
162#define SAA7134_SYNC_CTRL 0x108
163#define SAA7134_LUMA_CTRL 0x109
164#define SAA7134_DEC_LUMA_BRIGHT 0x10a
165#define SAA7134_DEC_LUMA_CONTRAST 0x10b
166#define SAA7134_DEC_CHROMA_SATURATION 0x10c
167#define SAA7134_DEC_CHROMA_HUE 0x10d
168#define SAA7134_CHROMA_CTRL1 0x10e
169#define SAA7134_CHROMA_GAIN 0x10f
170#define SAA7134_CHROMA_CTRL2 0x110
171#define SAA7134_MODE_DELAY_CTRL 0x111
172
173#define SAA7134_ANALOG_ADC 0x114
174#define SAA7134_VGATE_START 0x115
175#define SAA7134_VGATE_STOP 0x116
176#define SAA7134_MISC_VGATE_MSB 0x117
177#define SAA7134_RAW_DATA_GAIN 0x118
178#define SAA7134_RAW_DATA_OFFSET 0x119
179#define SAA7134_STATUS_VIDEO1 0x11e
180#define SAA7134_STATUS_VIDEO2 0x11f
181
182/* video scaler */
183#define SAA7134_SOURCE_TIMING1 0x000
184#define SAA7134_SOURCE_TIMING2 0x001
185#define SAA7134_REGION_ENABLE 0x004
186#define SAA7134_SCALER_STATUS0 0x006
187#define SAA7134_SCALER_STATUS1 0x007
188#define SAA7134_START_GREEN 0x00c
189#define SAA7134_START_BLUE 0x00d
190#define SAA7134_START_RED 0x00e
191#define SAA7134_GREEN_PATH(x) (0x010 +x)
192#define SAA7134_BLUE_PATH(x) (0x020 +x)
193#define SAA7134_RED_PATH(x) (0x030 +x)
194
195#define TASK_A 0x040
196#define TASK_B 0x080
197#define SAA7134_TASK_CONDITIONS(t) (0x000 +t)
198#define SAA7134_FIELD_HANDLING(t) (0x001 +t)
199#define SAA7134_DATA_PATH(t) (0x002 +t)
200#define SAA7134_VBI_H_START1(t) (0x004 +t)
201#define SAA7134_VBI_H_START2(t) (0x005 +t)
202#define SAA7134_VBI_H_STOP1(t) (0x006 +t)
203#define SAA7134_VBI_H_STOP2(t) (0x007 +t)
204#define SAA7134_VBI_V_START1(t) (0x008 +t)
205#define SAA7134_VBI_V_START2(t) (0x009 +t)
206#define SAA7134_VBI_V_STOP1(t) (0x00a +t)
207#define SAA7134_VBI_V_STOP2(t) (0x00b +t)
208#define SAA7134_VBI_H_LEN1(t) (0x00c +t)
209#define SAA7134_VBI_H_LEN2(t) (0x00d +t)
210#define SAA7134_VBI_V_LEN1(t) (0x00e +t)
211#define SAA7134_VBI_V_LEN2(t) (0x00f +t)
212
213#define SAA7134_VIDEO_H_START1(t) (0x014 +t)
214#define SAA7134_VIDEO_H_START2(t) (0x015 +t)
215#define SAA7134_VIDEO_H_STOP1(t) (0x016 +t)
216#define SAA7134_VIDEO_H_STOP2(t) (0x017 +t)
217#define SAA7134_VIDEO_V_START1(t) (0x018 +t)
218#define SAA7134_VIDEO_V_START2(t) (0x019 +t)
219#define SAA7134_VIDEO_V_STOP1(t) (0x01a +t)
220#define SAA7134_VIDEO_V_STOP2(t) (0x01b +t)
221#define SAA7134_VIDEO_PIXELS1(t) (0x01c +t)
222#define SAA7134_VIDEO_PIXELS2(t) (0x01d +t)
223#define SAA7134_VIDEO_LINES1(t) (0x01e +t)
224#define SAA7134_VIDEO_LINES2(t) (0x01f +t)
225
226#define SAA7134_H_PRESCALE(t) (0x020 +t)
227#define SAA7134_ACC_LENGTH(t) (0x021 +t)
228#define SAA7134_LEVEL_CTRL(t) (0x022 +t)
229#define SAA7134_FIR_PREFILTER_CTRL(t) (0x023 +t)
230#define SAA7134_LUMA_BRIGHT(t) (0x024 +t)
231#define SAA7134_LUMA_CONTRAST(t) (0x025 +t)
232#define SAA7134_CHROMA_SATURATION(t) (0x026 +t)
233#define SAA7134_VBI_H_SCALE_INC1(t) (0x028 +t)
234#define SAA7134_VBI_H_SCALE_INC2(t) (0x029 +t)
235#define SAA7134_VBI_PHASE_OFFSET_LUMA(t) (0x02a +t)
236#define SAA7134_VBI_PHASE_OFFSET_CHROMA(t) (0x02b +t)
237#define SAA7134_H_SCALE_INC1(t) (0x02c +t)
238#define SAA7134_H_SCALE_INC2(t) (0x02d +t)
239#define SAA7134_H_PHASE_OFF_LUMA(t) (0x02e +t)
240#define SAA7134_H_PHASE_OFF_CHROMA(t) (0x02f +t)
241#define SAA7134_V_SCALE_RATIO1(t) (0x030 +t)
242#define SAA7134_V_SCALE_RATIO2(t) (0x031 +t)
243#define SAA7134_V_FILTER(t) (0x032 +t)
244#define SAA7134_V_PHASE_OFFSET0(t) (0x034 +t)
245#define SAA7134_V_PHASE_OFFSET1(t) (0x035 +t)
246#define SAA7134_V_PHASE_OFFSET2(t) (0x036 +t)
247#define SAA7134_V_PHASE_OFFSET3(t) (0x037 +t)
248
249/* clipping & dma */
250#define SAA7134_OFMT_VIDEO_A 0x300
251#define SAA7134_OFMT_DATA_A 0x301
252#define SAA7134_OFMT_VIDEO_B 0x302
253#define SAA7134_OFMT_DATA_B 0x303
254#define SAA7134_ALPHA_NOCLIP 0x304
255#define SAA7134_ALPHA_CLIP 0x305
256#define SAA7134_UV_PIXEL 0x308
257#define SAA7134_CLIP_RED 0x309
258#define SAA7134_CLIP_GREEN 0x30a
259#define SAA7134_CLIP_BLUE 0x30b
260
261/* i2c bus */
262#define SAA7134_I2C_ATTR_STATUS 0x180
263#define SAA7134_I2C_DATA 0x181
264#define SAA7134_I2C_CLOCK_SELECT 0x182
265#define SAA7134_I2C_TIMER 0x183
266
267/* audio */
268#define SAA7134_NICAM_ADD_DATA1 0x140
269#define SAA7134_NICAM_ADD_DATA2 0x141
270#define SAA7134_NICAM_STATUS 0x142
271#define SAA7134_AUDIO_STATUS 0x143
272#define SAA7134_NICAM_ERROR_COUNT 0x144
273#define SAA7134_IDENT_SIF 0x145
274#define SAA7134_LEVEL_READOUT1 0x146
275#define SAA7134_LEVEL_READOUT2 0x147
276#define SAA7134_NICAM_ERROR_LOW 0x148
277#define SAA7134_NICAM_ERROR_HIGH 0x149
278#define SAA7134_DCXO_IDENT_CTRL 0x14a
279#define SAA7134_DEMODULATOR 0x14b
280#define SAA7134_AGC_GAIN_SELECT 0x14c
281#define SAA7134_CARRIER1_FREQ0 0x150
282#define SAA7134_CARRIER1_FREQ1 0x151
283#define SAA7134_CARRIER1_FREQ2 0x152
284#define SAA7134_CARRIER2_FREQ0 0x154
285#define SAA7134_CARRIER2_FREQ1 0x155
286#define SAA7134_CARRIER2_FREQ2 0x156
287#define SAA7134_NUM_SAMPLES0 0x158
288#define SAA7134_NUM_SAMPLES1 0x159
289#define SAA7134_NUM_SAMPLES2 0x15a
290#define SAA7134_AUDIO_FORMAT_CTRL 0x15b
291#define SAA7134_MONITOR_SELECT 0x160
292#define SAA7134_FM_DEEMPHASIS 0x161
293#define SAA7134_FM_DEMATRIX 0x162
294#define SAA7134_CHANNEL1_LEVEL 0x163
295#define SAA7134_CHANNEL2_LEVEL 0x164
296#define SAA7134_NICAM_CONFIG 0x165
297#define SAA7134_NICAM_LEVEL_ADJUST 0x166
298#define SAA7134_STEREO_DAC_OUTPUT_SELECT 0x167
299#define SAA7134_I2S_OUTPUT_FORMAT 0x168
300#define SAA7134_I2S_OUTPUT_SELECT 0x169
301#define SAA7134_I2S_OUTPUT_LEVEL 0x16a
302#define SAA7134_DSP_OUTPUT_SELECT 0x16b
303#define SAA7134_AUDIO_MUTE_CTRL 0x16c
304#define SAA7134_SIF_SAMPLE_FREQ 0x16d
305#define SAA7134_ANALOG_IO_SELECT 0x16e
306#define SAA7134_AUDIO_CLOCK0 0x170
307#define SAA7134_AUDIO_CLOCK1 0x171
308#define SAA7134_AUDIO_CLOCK2 0x172
309#define SAA7134_AUDIO_PLL_CTRL 0x173
310#define SAA7134_AUDIO_CLOCKS_PER_FIELD0 0x174
311#define SAA7134_AUDIO_CLOCKS_PER_FIELD1 0x175
312#define SAA7134_AUDIO_CLOCKS_PER_FIELD2 0x176
313
314/* video port output */
315#define SAA7134_VIDEO_PORT_CTRL0 0x190
316#define SAA7134_VIDEO_PORT_CTRL1 0x191
317#define SAA7134_VIDEO_PORT_CTRL2 0x192
318#define SAA7134_VIDEO_PORT_CTRL3 0x193
319#define SAA7134_VIDEO_PORT_CTRL4 0x194
320#define SAA7134_VIDEO_PORT_CTRL5 0x195
321#define SAA7134_VIDEO_PORT_CTRL6 0x196
322#define SAA7134_VIDEO_PORT_CTRL7 0x197
323#define SAA7134_VIDEO_PORT_CTRL8 0x198
324
325/* transport stream interface */
326#define SAA7134_TS_PARALLEL 0x1a0
327#define SAA7134_TS_PARALLEL_SERIAL 0x1a1
328#define SAA7134_TS_SERIAL0 0x1a2
329#define SAA7134_TS_SERIAL1 0x1a3
330#define SAA7134_TS_DMA0 0x1a4
331#define SAA7134_TS_DMA1 0x1a5
332#define SAA7134_TS_DMA2 0x1a6
333
334/* GPIO Controls */
335#define SAA7134_GPIO_GPRESCAN 0x80
336#define SAA7134_GPIO_27_25 0x0E
337
338#define SAA7134_GPIO_GPMODE0 0x1B0
339#define SAA7134_GPIO_GPMODE1 0x1B1
340#define SAA7134_GPIO_GPMODE2 0x1B2
341#define SAA7134_GPIO_GPMODE3 0x1B3
342#define SAA7134_GPIO_GPSTATUS0 0x1B4
343#define SAA7134_GPIO_GPSTATUS1 0x1B5
344#define SAA7134_GPIO_GPSTATUS2 0x1B6
345#define SAA7134_GPIO_GPSTATUS3 0x1B7
346
347/* I2S output */
348#define SAA7134_I2S_AUDIO_OUTPUT 0x1c0
349
350/* test modes */
351#define SAA7134_SPECIAL_MODE 0x1d0
352
353/* audio -- saa7133 + saa7135 only */
354#define SAA7135_DSP_RWSTATE 0x580
355#define SAA7135_DSP_RWSTATE_ERR (1 << 3)
356#define SAA7135_DSP_RWSTATE_IDA (1 << 2)
357#define SAA7135_DSP_RWSTATE_RDB (1 << 1)
358#define SAA7135_DSP_RWSTATE_WRR (1 << 0)
359
360/* ------------------------------------------------------------------ */
361/*
362 * Local variables:
363 * c-basic-offset: 8
364 * End:
365 */
366
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
new file mode 100644
index 000000000000..345eb2a8c28d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -0,0 +1,243 @@
1/*
2 * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int ts_debug = 0;
38module_param(ts_debug, int, 0644);
39MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
40
41#define dprintk(fmt, arg...) if (ts_debug) \
42 printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
43
44/* ------------------------------------------------------------------ */
45
46static int buffer_activate(struct saa7134_dev *dev,
47 struct saa7134_buf *buf,
48 struct saa7134_buf *next)
49{
50 u32 control;
51
52 dprintk("buffer_activate [%p]",buf);
53 buf->vb.state = STATE_ACTIVE;
54 buf->top_seen = 0;
55
56 /* dma: setup channel 5 (= TS) */
57 control = SAA7134_RS_CONTROL_BURST_16 |
58 SAA7134_RS_CONTROL_ME |
59 (buf->pt->dma >> 12);
60
61 if (NULL == next)
62 next = buf;
63 if (V4L2_FIELD_TOP == buf->vb.field) {
64 dprintk("- [top] buf=%p next=%p\n",buf,next);
65 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
66 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
67 } else {
68 dprintk("- [bottom] buf=%p next=%p\n",buf,next);
69 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
70 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
71 }
72 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
73 saa_writel(SAA7134_RS_CONTROL(5),control);
74
75 /* start DMA */
76 saa7134_set_dmabits(dev);
77
78 mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
79 return 0;
80}
81
82static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
83 enum v4l2_field field)
84{
85 struct saa7134_dev *dev = q->priv_data;
86 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
87 unsigned int lines, llength, size;
88 int err;
89
90 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
91
92 llength = TS_PACKET_SIZE;
93 lines = dev->ts.nr_packets;
94
95 size = lines * llength;
96 if (0 != buf->vb.baddr && buf->vb.bsize < size)
97 return -EINVAL;
98
99 if (buf->vb.size != size) {
100 saa7134_dma_free(dev,buf);
101 }
102
103 if (STATE_NEEDS_INIT == buf->vb.state) {
104 buf->vb.width = llength;
105 buf->vb.height = lines;
106 buf->vb.size = size;
107 buf->pt = &dev->ts.pt_ts;
108
109 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
110 if (err)
111 goto oops;
112 err = saa7134_pgtable_build(dev->pci,buf->pt,
113 buf->vb.dma.sglist,
114 buf->vb.dma.sglen,
115 saa7134_buffer_startpage(buf));
116 if (err)
117 goto oops;
118 }
119 buf->vb.state = STATE_PREPARED;
120 buf->activate = buffer_activate;
121 buf->vb.field = field;
122 return 0;
123
124 oops:
125 saa7134_dma_free(dev,buf);
126 return err;
127}
128
129static int
130buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
131{
132 struct saa7134_dev *dev = q->priv_data;
133
134 *size = TS_PACKET_SIZE * dev->ts.nr_packets;
135 if (0 == *count)
136 *count = dev->ts.nr_bufs;
137 *count = saa7134_buffer_count(*size,*count);
138 return 0;
139}
140
141static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
142{
143 struct saa7134_dev *dev = q->priv_data;
144 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
145
146 saa7134_buffer_queue(dev,&dev->ts_q,buf);
147}
148
149static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
150{
151 struct saa7134_dev *dev = q->priv_data;
152 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
153
154 saa7134_dma_free(dev,buf);
155}
156
157struct videobuf_queue_ops saa7134_ts_qops = {
158 .buf_setup = buffer_setup,
159 .buf_prepare = buffer_prepare,
160 .buf_queue = buffer_queue,
161 .buf_release = buffer_release,
162};
163EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164
165/* ----------------------------------------------------------- */
166/* exported stuff */
167
168static unsigned int tsbufs = 4;
169module_param(tsbufs, int, 0444);
170MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
171
172static unsigned int ts_nr_packets = 30;
173module_param(ts_nr_packets, int, 0444);
174MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
175
176int saa7134_ts_init1(struct saa7134_dev *dev)
177{
178 /* sanitycheck insmod options */
179 if (tsbufs < 2)
180 tsbufs = 2;
181 if (tsbufs > VIDEO_MAX_FRAME)
182 tsbufs = VIDEO_MAX_FRAME;
183 if (ts_nr_packets < 4)
184 ts_nr_packets = 4;
185 if (ts_nr_packets > 312)
186 ts_nr_packets = 312;
187 dev->ts.nr_bufs = tsbufs;
188 dev->ts.nr_packets = ts_nr_packets;
189
190 INIT_LIST_HEAD(&dev->ts_q.queue);
191 init_timer(&dev->ts_q.timeout);
192 dev->ts_q.timeout.function = saa7134_buffer_timeout;
193 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
194 dev->ts_q.dev = dev;
195 dev->ts_q.need_two = 1;
196 saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
197
198 /* init TS hw */
199 saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* deactivate TS softreset */
200 saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
201 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
202 saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
203 saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
204 saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
205
206 return 0;
207}
208
209int saa7134_ts_fini(struct saa7134_dev *dev)
210{
211 saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
212 return 0;
213}
214
215
216void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
217{
218 enum v4l2_field field;
219
220 spin_lock(&dev->slock);
221 if (dev->ts_q.curr) {
222 field = dev->ts_q.curr->vb.field;
223 if (field == V4L2_FIELD_TOP) {
224 if ((status & 0x100000) != 0x000000)
225 goto done;
226 } else {
227 if ((status & 0x100000) != 0x100000)
228 goto done;
229 }
230 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
231 }
232 saa7134_buffer_next(dev,&dev->ts_q);
233
234 done:
235 spin_unlock(&dev->slock);
236}
237
238/* ----------------------------------------------------------- */
239/*
240 * Local variables:
241 * c-basic-offset: 8
242 * End:
243 */
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
new file mode 100644
index 000000000000..ecac13c006d5
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -0,0 +1,1031 @@
1/*
2 * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * tv audio decoder (fm stereo, nicam, ...)
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/smp_lock.h>
32#include <asm/div64.h>
33
34#include "saa7134-reg.h"
35#include "saa7134.h"
36
37/* ------------------------------------------------------------------ */
38
39static unsigned int audio_debug = 0;
40module_param(audio_debug, int, 0644);
41MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
42
43static unsigned int audio_ddep = 0;
44module_param(audio_ddep, int, 0644);
45MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
46
47static int audio_clock_override = UNSET;
48module_param(audio_clock_override, int, 0644);
49
50static int audio_clock_tweak = 0;
51module_param(audio_clock_tweak, int, 0644);
52MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
53
54#define dprintk(fmt, arg...) if (audio_debug) \
55 printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg)
56#define d2printk(fmt, arg...) if (audio_debug > 1) \
57 printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
58
59#define print_regb(reg) printk("%s: reg 0x%03x [%-16s]: 0x%02x\n", \
60 dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
61
62/* msecs */
63#define SCAN_INITIAL_DELAY 1000
64#define SCAN_SAMPLE_DELAY 200
65#define SCAN_SUBCARRIER_DELAY 2000
66
67/* ------------------------------------------------------------------ */
68/* saa7134 code */
69
70static struct mainscan {
71 char *name;
72 v4l2_std_id std;
73 int carr;
74} mainscan[] = {
75 {
76 .name = "M",
77 .std = V4L2_STD_NTSC | V4L2_STD_PAL_M,
78 .carr = 4500,
79 },{
80 .name = "BG",
81 .std = V4L2_STD_PAL_BG,
82 .carr = 5500,
83 },{
84 .name = "I",
85 .std = V4L2_STD_PAL_I,
86 .carr = 6000,
87 },{
88 .name = "DKL",
89 .std = V4L2_STD_PAL_DK | V4L2_STD_SECAM,
90 .carr = 6500,
91 }
92};
93
94static struct saa7134_tvaudio tvaudio[] = {
95 {
96 .name = "PAL-B/G FM-stereo",
97 .std = V4L2_STD_PAL,
98 .mode = TVAUDIO_FM_BG_STEREO,
99 .carr1 = 5500,
100 .carr2 = 5742,
101 },{
102 .name = "PAL-D/K1 FM-stereo",
103 .std = V4L2_STD_PAL,
104 .carr1 = 6500,
105 .carr2 = 6258,
106 .mode = TVAUDIO_FM_BG_STEREO,
107 },{
108 .name = "PAL-D/K2 FM-stereo",
109 .std = V4L2_STD_PAL,
110 .carr1 = 6500,
111 .carr2 = 6742,
112 .mode = TVAUDIO_FM_BG_STEREO,
113 },{
114 .name = "PAL-D/K3 FM-stereo",
115 .std = V4L2_STD_PAL,
116 .carr1 = 6500,
117 .carr2 = 5742,
118 .mode = TVAUDIO_FM_BG_STEREO,
119 },{
120 .name = "PAL-B/G NICAM",
121 .std = V4L2_STD_PAL,
122 .carr1 = 5500,
123 .carr2 = 5850,
124 .mode = TVAUDIO_NICAM_FM,
125 },{
126 .name = "PAL-I NICAM",
127 .std = V4L2_STD_PAL,
128 .carr1 = 6000,
129 .carr2 = 6552,
130 .mode = TVAUDIO_NICAM_FM,
131 },{
132 .name = "PAL-D/K NICAM",
133 .std = V4L2_STD_PAL,
134 .carr1 = 6500,
135 .carr2 = 5850,
136 .mode = TVAUDIO_NICAM_FM,
137 },{
138 .name = "SECAM-L NICAM",
139 .std = V4L2_STD_SECAM,
140 .carr1 = 6500,
141 .carr2 = 5850,
142 .mode = TVAUDIO_NICAM_AM,
143 },{
144 .name = "SECAM-D/K",
145 .std = V4L2_STD_SECAM,
146 .carr1 = 6500,
147 .carr2 = -1,
148 .mode = TVAUDIO_FM_MONO,
149 },{
150 .name = "NTSC-M",
151 .std = V4L2_STD_NTSC,
152 .carr1 = 4500,
153 .carr2 = -1,
154 .mode = TVAUDIO_FM_MONO,
155 },{
156 .name = "NTSC-A2 FM-stereo",
157 .std = V4L2_STD_NTSC,
158 .carr1 = 4500,
159 .carr2 = 4724,
160 .mode = TVAUDIO_FM_K_STEREO,
161 }
162};
163#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
164
165/* ------------------------------------------------------------------ */
166
167static void tvaudio_init(struct saa7134_dev *dev)
168{
169 int clock = saa7134_boards[dev->board].audio_clock;
170
171 if (UNSET != audio_clock_override)
172 clock = audio_clock_override;
173
174 /* init all audio registers */
175 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
176 if (need_resched())
177 schedule();
178 else
179 udelay(10);
180
181 saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
182 saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
183 saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
184 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01);
185
186 saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
187 saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
188 saa_writeb(SAA7134_MONITOR_SELECT, 0xa0);
189 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
190}
191
192static u32 tvaudio_carr2reg(u32 carrier)
193{
194 u64 a = carrier;
195
196 a <<= 24;
197 do_div(a,12288);
198 return a;
199}
200
201static void tvaudio_setcarrier(struct saa7134_dev *dev,
202 int primary, int secondary)
203{
204 if (-1 == secondary)
205 secondary = primary;
206 saa_writel(SAA7134_CARRIER1_FREQ0 >> 2, tvaudio_carr2reg(primary));
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208}
209
210static void mute_input_7134(struct saa7134_dev *dev)
211{
212 unsigned int mute;
213 struct saa7134_input *in;
214 int ausel=0, ics=0, ocs=0;
215 int mask;
216
217 /* look what is to do ... */
218 in = dev->input;
219 mute = (dev->ctl_mute ||
220 (dev->automute && (&card(dev).radio) != in));
221 if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
222 card(dev).mute.name) {
223 /* 7130 - we'll mute using some unconnected audio input */
224 if (mute)
225 in = &card(dev).mute;
226 }
227 if (dev->hw_mute == mute &&
228 dev->hw_input == in) {
229 dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
230 mute,in->name);
231 return;
232 }
233
234 dprintk("ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n",
235 dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
236 dev->hw_mute = mute;
237 dev->hw_input = in;
238
239 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
240 /* 7134 mute */
241 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb);
242
243 /* switch internal audio mux */
244 switch (in->amux) {
245 case TV: ausel=0xc0; ics=0x00; ocs=0x02; break;
246 case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break;
247 case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break;
248 case LINE2_LEFT: ausel=0x80; ics=0x08; ocs=0x05; break;
249 }
250 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
251 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
252 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
253
254 /* switch gpio-connected external audio mux */
255 if (0 == card(dev).gpiomask)
256 return;
257 mask = card(dev).gpiomask;
258 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
259 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
260 saa7134_track_gpio(dev,in->name);
261}
262
263static void tvaudio_setmode(struct saa7134_dev *dev,
264 struct saa7134_tvaudio *audio,
265 char *note)
266{
267 int acpf, tweak = 0;
268
269 if (dev->tvnorm->id == V4L2_STD_NTSC) {
270 acpf = 0x19066;
271 } else {
272 acpf = 0x1e000;
273 }
274 if (audio_clock_tweak > -1024 && audio_clock_tweak < 1024)
275 tweak = audio_clock_tweak;
276
277 if (note)
278 dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n",
279 note,audio->name,
280 audio->carr1 / 1000, audio->carr1 % 1000,
281 audio->carr2 / 1000, audio->carr2 % 1000,
282 acpf, tweak);
283
284 acpf += tweak;
285 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, (acpf & 0x0000ff) >> 0);
286 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, (acpf & 0x00ff00) >> 8);
287 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, (acpf & 0x030000) >> 16);
288 tvaudio_setcarrier(dev,audio->carr1,audio->carr2);
289
290 switch (audio->mode) {
291 case TVAUDIO_FM_MONO:
292 case TVAUDIO_FM_BG_STEREO:
293 saa_writeb(SAA7134_DEMODULATOR, 0x00);
294 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
295 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
296 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
297 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
298 break;
299 case TVAUDIO_FM_K_STEREO:
300 saa_writeb(SAA7134_DEMODULATOR, 0x00);
301 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x01);
302 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
303 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
304 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
305 break;
306 case TVAUDIO_NICAM_FM:
307 saa_writeb(SAA7134_DEMODULATOR, 0x10);
308 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
309 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
310 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
311 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
312 break;
313 case TVAUDIO_NICAM_AM:
314 saa_writeb(SAA7134_DEMODULATOR, 0x12);
315 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
316 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
317 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
318 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
319 break;
320 case TVAUDIO_FM_SAT_STEREO:
321 /* not implemented (yet) */
322 break;
323 }
324}
325
326static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
327{
328 DECLARE_WAITQUEUE(wait, current);
329
330 add_wait_queue(&dev->thread.wq, &wait);
331 if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) {
332 if (timeout < 0) {
333 set_current_state(TASK_INTERRUPTIBLE);
334 schedule();
335 } else {
336#if 0
337 /* hmm, that one doesn't return on wakeup ... */
338 msleep_interruptible(timeout);
339#else
340 set_current_state(TASK_INTERRUPTIBLE);
341 schedule_timeout(msecs_to_jiffies(timeout));
342#endif
343 }
344 }
345 remove_wait_queue(&dev->thread.wq, &wait);
346 return dev->thread.scan1 != dev->thread.scan2;
347}
348
349static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
350{
351 __s32 left,right,value;
352
353 if (audio_debug > 1) {
354 int i;
355 dprintk("debug %d:",scan->carr);
356 for (i = -150; i <= 150; i += 30) {
357 tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i);
358 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
359 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
360 return -1;
361 value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
362 if (0 == i)
363 printk(" # %6d # ",value >> 16);
364 else
365 printk(" %6d",value >> 16);
366 }
367 printk("\n");
368 }
369
370 if (dev->tvnorm->id & scan->std) {
371 tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90);
372 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
373 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
374 return -1;
375 left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
376
377 tvaudio_setcarrier(dev,scan->carr+90,scan->carr+90);
378 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
379 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
380 return -1;
381 right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
382
383 left >>= 16;
384 right >>= 16;
385 value = left > right ? left - right : right - left;
386 dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n",
387 scan->carr / 1000, scan->carr % 1000,
388 scan->name, value, left, right);
389 } else {
390 value = 0;
391 dprintk("skipping %d.%03d MHz [%4s]\n",
392 scan->carr / 1000, scan->carr % 1000, scan->name);
393 }
394 return value;
395}
396
397#if 0
398static void sifdebug_dump_regs(struct saa7134_dev *dev)
399{
400 print_regb(AUDIO_STATUS);
401 print_regb(IDENT_SIF);
402 print_regb(LEVEL_READOUT1);
403 print_regb(LEVEL_READOUT2);
404 print_regb(DCXO_IDENT_CTRL);
405 print_regb(DEMODULATOR);
406 print_regb(AGC_GAIN_SELECT);
407 print_regb(MONITOR_SELECT);
408 print_regb(FM_DEEMPHASIS);
409 print_regb(FM_DEMATRIX);
410 print_regb(SIF_SAMPLE_FREQ);
411 print_regb(ANALOG_IO_SELECT);
412}
413#endif
414
415static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
416{
417 __u32 idp,nicam;
418 int retval = -1;
419
420 switch (audio->mode) {
421 case TVAUDIO_FM_MONO:
422 return V4L2_TUNER_SUB_MONO;
423 case TVAUDIO_FM_K_STEREO:
424 case TVAUDIO_FM_BG_STEREO:
425 idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5;
426 dprintk("getstereo: fm/stereo: idp=0x%x\n",idp);
427 if (0x03 == (idp & 0x03))
428 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
429 else if (0x05 == (idp & 0x05))
430 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
431 else if (0x01 == (idp & 0x01))
432 retval = V4L2_TUNER_SUB_MONO;
433 break;
434 case TVAUDIO_FM_SAT_STEREO:
435 /* not implemented (yet) */
436 break;
437 case TVAUDIO_NICAM_FM:
438 case TVAUDIO_NICAM_AM:
439 nicam = saa_readb(SAA7134_NICAM_STATUS);
440 dprintk("getstereo: nicam=0x%x\n",nicam);
441 switch (nicam & 0x0b) {
442 case 0x09:
443 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
444 break;
445 case 0x0a:
446 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
447 break;
448 case 0x08:
449 default:
450 retval = V4L2_TUNER_SUB_MONO;
451 break;
452 }
453 break;
454 }
455 if (retval != -1)
456 dprintk("found audio subchannels:%s%s%s%s\n",
457 (retval & V4L2_TUNER_SUB_MONO) ? " mono" : "",
458 (retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
459 (retval & V4L2_TUNER_SUB_LANG1) ? " lang1" : "",
460 (retval & V4L2_TUNER_SUB_LANG2) ? " lang2" : "");
461 return retval;
462}
463
464static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio,
465 u32 mode)
466{
467 static char *name[] = {
468 [ V4L2_TUNER_MODE_MONO ] = "mono",
469 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
470 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
471 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
472 };
473 static u32 fm[] = {
474 [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */
475 [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */
476 [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */
477 [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */
478 };
479 u32 reg;
480
481 switch (audio->mode) {
482 case TVAUDIO_FM_MONO:
483 /* nothing to do ... */
484 break;
485 case TVAUDIO_FM_K_STEREO:
486 case TVAUDIO_FM_BG_STEREO:
487 dprintk("setstereo [fm] => %s\n",
488 name[ mode % ARRAY_SIZE(name) ]);
489 reg = fm[ mode % ARRAY_SIZE(fm) ];
490 saa_writeb(SAA7134_FM_DEMATRIX, reg);
491 break;
492 case TVAUDIO_FM_SAT_STEREO:
493 case TVAUDIO_NICAM_AM:
494 case TVAUDIO_NICAM_FM:
495 /* FIXME */
496 break;
497 }
498 return 0;
499}
500
501static int tvaudio_thread(void *data)
502{
503 struct saa7134_dev *dev = data;
504 int carr_vals[ARRAY_SIZE(mainscan)];
505 unsigned int i, audio, nscan;
506 int max1,max2,carrier,rx,mode,lastmode,default_carrier;
507
508 daemonize("%s", dev->name);
509 allow_signal(SIGTERM);
510 for (;;) {
511 tvaudio_sleep(dev,-1);
512 if (dev->thread.shutdown || signal_pending(current))
513 goto done;
514
515 restart:
516 dev->thread.scan1 = dev->thread.scan2;
517 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
518 dev->tvaudio = NULL;
519 tvaudio_init(dev);
520 if (dev->ctl_automute)
521 dev->automute = 1;
522 mute_input_7134(dev);
523
524 /* give the tuner some time */
525 if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY))
526 goto restart;
527
528 max1 = 0;
529 max2 = 0;
530 nscan = 0;
531 carrier = 0;
532 default_carrier = 0;
533 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
534 if (!(dev->tvnorm->id & mainscan[i].std))
535 continue;
536 if (!default_carrier)
537 default_carrier = mainscan[i].carr;
538 nscan++;
539 }
540
541 if (1 == nscan) {
542 /* only one candidate -- skip scan ;) */
543 max1 = 12345;
544 carrier = default_carrier;
545 } else {
546 /* scan for the main carrier */
547 saa_writeb(SAA7134_MONITOR_SELECT,0x00);
548 tvaudio_setmode(dev,&tvaudio[0],NULL);
549 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
550 carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i);
551 if (dev->thread.scan1 != dev->thread.scan2)
552 goto restart;
553 }
554 for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) {
555 if (max1 < carr_vals[i]) {
556 max2 = max1;
557 max1 = carr_vals[i];
558 carrier = mainscan[i].carr;
559 } else if (max2 < carr_vals[i]) {
560 max2 = carr_vals[i];
561 }
562 }
563 }
564
565 if (0 != carrier && max1 > 2000 && max1 > max2*3) {
566 /* found good carrier */
567 dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n",
568 dev->tvnorm->name, carrier/1000, carrier%1000,
569 max1, max2);
570 dev->last_carrier = carrier;
571
572 } else if (0 != dev->last_carrier) {
573 /* no carrier -- try last detected one as fallback */
574 carrier = dev->last_carrier;
575 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
576 "using %d.%03d MHz [last detected]\n",
577 dev->name, carrier/1000, carrier%1000);
578
579 } else {
580 /* no carrier + no fallback -- use default */
581 carrier = default_carrier;
582 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
583 "using %d.%03d MHz [default]\n",
584 dev->name, carrier/1000, carrier%1000);
585 }
586 tvaudio_setcarrier(dev,carrier,carrier);
587 dev->automute = 0;
588 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
589 saa7134_tvaudio_setmute(dev);
590
591 /* find the exact tv audio norm */
592 for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
593 if (dev->tvnorm->id != UNSET &&
594 !(dev->tvnorm->id & tvaudio[i].std))
595 continue;
596 if (tvaudio[i].carr1 != carrier)
597 continue;
598
599 if (UNSET == audio)
600 audio = i;
601 tvaudio_setmode(dev,&tvaudio[i],"trying");
602 if (tvaudio_sleep(dev,SCAN_SUBCARRIER_DELAY))
603 goto restart;
604 if (-1 != tvaudio_getstereo(dev,&tvaudio[i])) {
605 audio = i;
606 break;
607 }
608 }
609 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x30);
610 if (UNSET == audio)
611 continue;
612 tvaudio_setmode(dev,&tvaudio[audio],"using");
613 tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
614 dev->tvaudio = &tvaudio[audio];
615
616 lastmode = 42;
617 for (;;) {
618 if (tvaudio_sleep(dev,5000))
619 goto restart;
620 if (dev->thread.shutdown || signal_pending(current))
621 break;
622 if (UNSET == dev->thread.mode) {
623 rx = tvaudio_getstereo(dev,&tvaudio[i]);
624 mode = saa7134_tvaudio_rx2mode(rx);
625 } else {
626 mode = dev->thread.mode;
627 }
628 if (lastmode != mode) {
629 tvaudio_setstereo(dev,&tvaudio[audio],mode);
630 lastmode = mode;
631 }
632 }
633 }
634
635 done:
636 complete_and_exit(&dev->thread.exit, 0);
637 return 0;
638}
639
640/* ------------------------------------------------------------------ */
641/* saa7133 / saa7135 code */
642
643static char *stdres[0x20] = {
644 [0x00] = "no standard detected",
645 [0x01] = "B/G (in progress)",
646 [0x02] = "D/K (in progress)",
647 [0x03] = "M (in progress)",
648
649 [0x04] = "B/G A2",
650 [0x05] = "B/G NICAM",
651 [0x06] = "D/K A2 (1)",
652 [0x07] = "D/K A2 (2)",
653 [0x08] = "D/K A2 (3)",
654 [0x09] = "D/K NICAM",
655 [0x0a] = "L NICAM",
656 [0x0b] = "I NICAM",
657
658 [0x0c] = "M Korea",
659 [0x0d] = "M BTSC ",
660 [0x0e] = "M EIAJ",
661
662 [0x0f] = "FM radio / IF 10.7 / 50 deemp",
663 [0x10] = "FM radio / IF 10.7 / 75 deemp",
664 [0x11] = "FM radio / IF sel / 50 deemp",
665 [0x12] = "FM radio / IF sel / 75 deemp",
666
667 [0x13 ... 0x1e ] = "unknown",
668 [0x1f] = "??? [in progress]",
669};
670
671#define DSP_RETRY 32
672#define DSP_DELAY 16
673
674static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
675{
676 int state, count = DSP_RETRY;
677
678 state = saa_readb(SAA7135_DSP_RWSTATE);
679 if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
680 printk("%s: dsp access error\n",dev->name);
681 /* FIXME: send ack ... */
682 return -EIO;
683 }
684 while (0 == (state & bit)) {
685 if (unlikely(0 == count)) {
686 printk("%s: dsp access wait timeout [bit=%s]\n",
687 dev->name,
688 (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" :
689 (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" :
690 (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" :
691 "???");
692 return -EIO;
693 }
694 saa_wait(DSP_DELAY);
695 state = saa_readb(SAA7135_DSP_RWSTATE);
696 count--;
697 }
698 return 0;
699}
700
701#if 0
702static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
703{
704 int err;
705
706 d2printk("dsp read reg 0x%x\n", reg<<2);
707 saa_readl(reg);
708 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
709 if (err < 0)
710 return err;
711 *value = saa_readl(reg);
712 d2printk("dsp read => 0x%06x\n", *value & 0xffffff);
713 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
714 if (err < 0)
715 return err;
716 return 0;
717}
718#endif
719
720int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
721{
722 int err;
723
724 d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value);
725 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
726 if (err < 0)
727 return err;
728 saa_writel(reg,value);
729 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
730 if (err < 0)
731 return err;
732 return 0;
733}
734
735static int getstereo_7133(struct saa7134_dev *dev)
736{
737 int retval = V4L2_TUNER_SUB_MONO;
738 u32 value;
739
740 value = saa_readl(0x528 >> 2);
741 if (value & 0x20)
742 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
743 if (value & 0x40)
744 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
745 return retval;
746}
747
748static int mute_input_7133(struct saa7134_dev *dev)
749{
750 u32 reg = 0;
751 int mask;
752
753 switch (dev->input->amux) {
754 case TV:
755 reg = 0x02;
756 break;
757 case LINE1:
758 reg = 0x00;
759 break;
760 case LINE2:
761 case LINE2_LEFT:
762 reg = 0x01;
763 break;
764 }
765 if (dev->ctl_mute)
766 reg = 0x07;
767 saa_writel(0x594 >> 2, reg);
768
769 /* switch gpio-connected external audio mux */
770 if (0 != card(dev).gpiomask) {
771 mask = card(dev).gpiomask;
772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio);
774 saa7134_track_gpio(dev,dev->input->name);
775 }
776 return 0;
777}
778
779static int tvaudio_thread_ddep(void *data)
780{
781 struct saa7134_dev *dev = data;
782 u32 value, norms, clock;
783
784 daemonize("%s", dev->name);
785 allow_signal(SIGTERM);
786
787 clock = saa7134_boards[dev->board].audio_clock;
788 if (UNSET != audio_clock_override)
789 clock = audio_clock_override;
790 saa_writel(0x598 >> 2, clock);
791
792 /* unmute */
793 saa_dsp_writel(dev, 0x474 >> 2, 0x00);
794 saa_dsp_writel(dev, 0x450 >> 2, 0x00);
795
796 for (;;) {
797 tvaudio_sleep(dev,-1);
798 if (dev->thread.shutdown || signal_pending(current))
799 goto done;
800
801 restart:
802 dev->thread.scan1 = dev->thread.scan2;
803 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
804
805 if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) {
806 /* insmod option override */
807 norms = (audio_ddep << 2) | 0x01;
808 dprintk("ddep override: %s\n",stdres[audio_ddep]);
809 } else if (&card(dev).radio == dev->input) {
810 dprintk("FM Radio\n");
811 norms = (0x0f << 2) | 0x01;
812 } else {
813 /* (let chip) scan for sound carrier */
814 norms = 0;
815 if (dev->tvnorm->id & V4L2_STD_PAL) {
816 dprintk("PAL scan\n");
817 norms |= 0x2c; /* B/G + D/K + I */
818 }
819 if (dev->tvnorm->id & V4L2_STD_NTSC) {
820 dprintk("NTSC scan\n");
821 norms |= 0x40; /* M */
822 }
823 if (dev->tvnorm->id & V4L2_STD_SECAM) {
824 dprintk("SECAM scan\n");
825 norms |= 0x18; /* L + D/K */
826 }
827 if (0 == norms)
828 norms = 0x7c; /* all */
829 dprintk("scanning:%s%s%s%s%s\n",
830 (norms & 0x04) ? " B/G" : "",
831 (norms & 0x08) ? " D/K" : "",
832 (norms & 0x10) ? " L/L'" : "",
833 (norms & 0x20) ? " I" : "",
834 (norms & 0x40) ? " M" : "");
835 }
836
837 /* kick automatic standard detection */
838 saa_dsp_writel(dev, 0x454 >> 2, 0);
839 saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80);
840
841 /* setup crossbars */
842 saa_dsp_writel(dev, 0x464 >> 2, 0x000000);
843 saa_dsp_writel(dev, 0x470 >> 2, 0x101010);
844
845 if (tvaudio_sleep(dev,3000))
846 goto restart;
847 value = saa_readl(0x528 >> 2) & 0xffffff;
848
849 dprintk("tvaudio thread status: 0x%x [%s%s%s]\n",
850 value, stdres[value & 0x1f],
851 (value & 0x000020) ? ",stereo" : "",
852 (value & 0x000040) ? ",dual" : "");
853 dprintk("detailed status: "
854 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
855 (value & 0x000080) ? " A2/EIAJ pilot tone " : "",
856 (value & 0x000100) ? " A2/EIAJ dual " : "",
857 (value & 0x000200) ? " A2/EIAJ stereo " : "",
858 (value & 0x000400) ? " A2/EIAJ noise mute " : "",
859
860 (value & 0x000800) ? " BTSC/FM radio pilot " : "",
861 (value & 0x001000) ? " SAP carrier " : "",
862 (value & 0x002000) ? " BTSC stereo noise mute " : "",
863 (value & 0x004000) ? " SAP noise mute " : "",
864 (value & 0x008000) ? " VDSP " : "",
865
866 (value & 0x010000) ? " NICST " : "",
867 (value & 0x020000) ? " NICDU " : "",
868 (value & 0x040000) ? " NICAM muted " : "",
869 (value & 0x080000) ? " NICAM reserve sound " : "",
870
871 (value & 0x100000) ? " init done " : "");
872 }
873
874 done:
875 complete_and_exit(&dev->thread.exit, 0);
876 return 0;
877}
878
879/* ------------------------------------------------------------------ */
880/* common stuff + external entry points */
881
882static void saa7134_enable_i2s(struct saa7134_dev *dev)
883{
884 int i2s_format;
885
886 if (!card_is_empress(dev))
887 return;
888 i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
889
890 /* enable I2S audio output for the mpeg encoder */
891 saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
892 saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
893 saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
894 saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
895}
896
897int saa7134_tvaudio_rx2mode(u32 rx)
898{
899 u32 mode;
900
901 mode = V4L2_TUNER_MODE_MONO;
902 if (rx & V4L2_TUNER_SUB_STEREO)
903 mode = V4L2_TUNER_MODE_STEREO;
904 else if (rx & V4L2_TUNER_SUB_LANG1)
905 mode = V4L2_TUNER_MODE_LANG1;
906 else if (rx & V4L2_TUNER_SUB_LANG2)
907 mode = V4L2_TUNER_MODE_LANG2;
908 return mode;
909}
910
911void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
912{
913 switch (dev->pci->device) {
914 case PCI_DEVICE_ID_PHILIPS_SAA7130:
915 case PCI_DEVICE_ID_PHILIPS_SAA7134:
916 mute_input_7134(dev);
917 break;
918 case PCI_DEVICE_ID_PHILIPS_SAA7133:
919 case PCI_DEVICE_ID_PHILIPS_SAA7135:
920 mute_input_7133(dev);
921 break;
922 }
923}
924
925void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
926 struct saa7134_input *in)
927{
928 dev->input = in;
929 switch (dev->pci->device) {
930 case PCI_DEVICE_ID_PHILIPS_SAA7130:
931 case PCI_DEVICE_ID_PHILIPS_SAA7134:
932 mute_input_7134(dev);
933 break;
934 case PCI_DEVICE_ID_PHILIPS_SAA7133:
935 case PCI_DEVICE_ID_PHILIPS_SAA7135:
936 mute_input_7133(dev);
937 break;
938 }
939 saa7134_enable_i2s(dev);
940}
941
942void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
943{
944 switch (dev->pci->device) {
945 case PCI_DEVICE_ID_PHILIPS_SAA7134:
946 saa_writeb(SAA7134_CHANNEL1_LEVEL, level & 0x1f);
947 saa_writeb(SAA7134_CHANNEL2_LEVEL, level & 0x1f);
948 saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
949 break;
950 }
951}
952
953int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
954{
955 int retval = V4L2_TUNER_SUB_MONO;
956
957 switch (dev->pci->device) {
958 case PCI_DEVICE_ID_PHILIPS_SAA7134:
959 if (dev->tvaudio)
960 retval = tvaudio_getstereo(dev,dev->tvaudio);
961 break;
962 case PCI_DEVICE_ID_PHILIPS_SAA7133:
963 case PCI_DEVICE_ID_PHILIPS_SAA7135:
964 retval = getstereo_7133(dev);
965 break;
966 }
967 return retval;
968}
969
970int saa7134_tvaudio_init2(struct saa7134_dev *dev)
971{
972 DECLARE_MUTEX_LOCKED(sem);
973 int (*my_thread)(void *data) = NULL;
974
975 switch (dev->pci->device) {
976 case PCI_DEVICE_ID_PHILIPS_SAA7134:
977 my_thread = tvaudio_thread;
978 break;
979 case PCI_DEVICE_ID_PHILIPS_SAA7133:
980 case PCI_DEVICE_ID_PHILIPS_SAA7135:
981 my_thread = tvaudio_thread_ddep;
982 break;
983 }
984
985 dev->thread.pid = -1;
986 if (my_thread) {
987 /* start tvaudio thread */
988 init_waitqueue_head(&dev->thread.wq);
989 init_completion(&dev->thread.exit);
990 dev->thread.pid = kernel_thread(my_thread,dev,0);
991 if (dev->thread.pid < 0)
992 printk(KERN_WARNING "%s: kernel_thread() failed\n",
993 dev->name);
994 saa7134_tvaudio_do_scan(dev);
995 }
996
997 saa7134_enable_i2s(dev);
998 return 0;
999}
1000
1001int saa7134_tvaudio_fini(struct saa7134_dev *dev)
1002{
1003 /* shutdown tvaudio thread */
1004 if (dev->thread.pid >= 0) {
1005 dev->thread.shutdown = 1;
1006 wake_up_interruptible(&dev->thread.wq);
1007 wait_for_completion(&dev->thread.exit);
1008 }
1009 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
1010 return 0;
1011}
1012
1013int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1014{
1015 if (dev->thread.pid >= 0) {
1016 dev->thread.mode = UNSET;
1017 dev->thread.scan2++;
1018 wake_up_interruptible(&dev->thread.wq);
1019 } else {
1020 dev->automute = 0;
1021 saa7134_tvaudio_setmute(dev);
1022 }
1023 return 0;
1024}
1025
1026/* ----------------------------------------------------------- */
1027/*
1028 * Local variables:
1029 * c-basic-offset: 8
1030 * End:
1031 */
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
new file mode 100644
index 000000000000..86954cc7c377
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -0,0 +1,270 @@
1/*
2 * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34/* ------------------------------------------------------------------ */
35
36static unsigned int vbi_debug = 0;
37module_param(vbi_debug, int, 0644);
38MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
39
40static unsigned int vbibufs = 4;
41module_param(vbibufs, int, 0444);
42MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
43
44#define dprintk(fmt, arg...) if (vbi_debug) \
45 printk(KERN_DEBUG "%s/vbi: " fmt, dev->name , ## arg)
46
47/* ------------------------------------------------------------------ */
48
49#define VBI_LINE_COUNT 16
50#define VBI_LINE_LENGTH 2048
51#define VBI_SCALE 0x200
52
53static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
54 int task)
55{
56 struct saa7134_tvnorm *norm = dev->tvnorm;
57
58 /* setup video scaler */
59 saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start & 0xff);
60 saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
61 saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
62 saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
63 saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff);
64 saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
65 saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff);
66 saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8);
67
68 saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
69 saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
70 saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
71 saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
72
73 saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
74 saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
75 saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
76 saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
77
78 saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
79}
80
81/* ------------------------------------------------------------------ */
82
83static int buffer_activate(struct saa7134_dev *dev,
84 struct saa7134_buf *buf,
85 struct saa7134_buf *next)
86{
87 unsigned long control,base;
88
89 dprintk("buffer_activate [%p]\n",buf);
90 buf->vb.state = STATE_ACTIVE;
91 buf->top_seen = 0;
92
93 task_init(dev,buf,TASK_A);
94 task_init(dev,buf,TASK_B);
95 saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
96 saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
97
98 /* DMA: setup channel 2+3 (= VBI Task A+B) */
99 base = saa7134_buffer_base(buf);
100 control = SAA7134_RS_CONTROL_BURST_16 |
101 SAA7134_RS_CONTROL_ME |
102 (buf->pt->dma >> 12);
103 saa_writel(SAA7134_RS_BA1(2),base);
104 saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
105 saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
106 saa_writel(SAA7134_RS_CONTROL(2),control);
107 saa_writel(SAA7134_RS_BA1(3),base);
108 saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
109 saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
110 saa_writel(SAA7134_RS_CONTROL(3),control);
111
112 /* start DMA */
113 saa7134_set_dmabits(dev);
114 mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
115
116 return 0;
117}
118
119static int buffer_prepare(struct videobuf_queue *q,
120 struct videobuf_buffer *vb,
121 enum v4l2_field field)
122{
123 struct saa7134_fh *fh = q->priv_data;
124 struct saa7134_dev *dev = fh->dev;
125 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
126 struct saa7134_tvnorm *norm = dev->tvnorm;
127 unsigned int lines, llength, size;
128 int err;
129
130 lines = norm->vbi_v_stop - norm->vbi_v_start +1;
131 if (lines > VBI_LINE_COUNT)
132 lines = VBI_LINE_COUNT;
133#if 1
134 llength = VBI_LINE_LENGTH;
135#else
136 llength = (norm->h_stop - norm->h_start +1) * 2;
137 if (llength > VBI_LINE_LENGTH)
138 llength = VBI_LINE_LENGTH;
139#endif
140 size = lines * llength * 2;
141 if (0 != buf->vb.baddr && buf->vb.bsize < size)
142 return -EINVAL;
143
144 if (buf->vb.size != size)
145 saa7134_dma_free(dev,buf);
146
147 if (STATE_NEEDS_INIT == buf->vb.state) {
148 buf->vb.width = llength;
149 buf->vb.height = lines;
150 buf->vb.size = size;
151 buf->pt = &fh->pt_vbi;
152
153 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
154 if (err)
155 goto oops;
156 err = saa7134_pgtable_build(dev->pci,buf->pt,
157 buf->vb.dma.sglist,
158 buf->vb.dma.sglen,
159 saa7134_buffer_startpage(buf));
160 if (err)
161 goto oops;
162 }
163 buf->vb.state = STATE_PREPARED;
164 buf->activate = buffer_activate;
165 buf->vb.field = field;
166 return 0;
167
168 oops:
169 saa7134_dma_free(dev,buf);
170 return err;
171}
172
173static int
174buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
175{
176 struct saa7134_fh *fh = q->priv_data;
177 struct saa7134_dev *dev = fh->dev;
178 int llength,lines;
179
180 lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
181#if 1
182 llength = VBI_LINE_LENGTH;
183#else
184 llength = (norm->h_stop - norm->h_start +1) * 2;
185 if (llength > VBI_LINE_LENGTH)
186 llength = VBI_LINE_LENGTH;
187#endif
188 *size = lines * llength * 2;
189 if (0 == *count)
190 *count = vbibufs;
191 *count = saa7134_buffer_count(*size,*count);
192 return 0;
193}
194
195static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
196{
197 struct saa7134_fh *fh = q->priv_data;
198 struct saa7134_dev *dev = fh->dev;
199 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
200
201 saa7134_buffer_queue(dev,&dev->vbi_q,buf);
202}
203
204static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
205{
206 struct saa7134_fh *fh = q->priv_data;
207 struct saa7134_dev *dev = fh->dev;
208 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
209
210 saa7134_dma_free(dev,buf);
211}
212
213struct videobuf_queue_ops saa7134_vbi_qops = {
214 .buf_setup = buffer_setup,
215 .buf_prepare = buffer_prepare,
216 .buf_queue = buffer_queue,
217 .buf_release = buffer_release,
218};
219
220/* ------------------------------------------------------------------ */
221
222int saa7134_vbi_init1(struct saa7134_dev *dev)
223{
224 INIT_LIST_HEAD(&dev->vbi_q.queue);
225 init_timer(&dev->vbi_q.timeout);
226 dev->vbi_q.timeout.function = saa7134_buffer_timeout;
227 dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
228 dev->vbi_q.dev = dev;
229
230 if (vbibufs < 2)
231 vbibufs = 2;
232 if (vbibufs > VIDEO_MAX_FRAME)
233 vbibufs = VIDEO_MAX_FRAME;
234 return 0;
235}
236
237int saa7134_vbi_fini(struct saa7134_dev *dev)
238{
239 /* nothing */
240 return 0;
241}
242
243void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
244{
245 spin_lock(&dev->slock);
246 if (dev->vbi_q.curr) {
247 dev->vbi_fieldcount++;
248 /* make sure we have seen both fields */
249 if ((status & 0x10) == 0x00) {
250 dev->vbi_q.curr->top_seen = 1;
251 goto done;
252 }
253 if (!dev->vbi_q.curr->top_seen)
254 goto done;
255
256 dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
257 saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE);
258 }
259 saa7134_buffer_next(dev,&dev->vbi_q);
260
261 done:
262 spin_unlock(&dev->slock);
263}
264
265/* ----------------------------------------------------------- */
266/*
267 * Local variables:
268 * c-basic-offset: 8
269 * End:
270 */
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
new file mode 100644
index 000000000000..5d66060026ff
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -0,0 +1,2406 @@
1/*
2 * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34#define V4L2_I2C_CLIENTS 1
35
36/* ------------------------------------------------------------------ */
37
38static unsigned int video_debug = 0;
39static unsigned int gbuffers = 8;
40static unsigned int noninterlaced = 0;
41static unsigned int gbufsize = 720*576*4;
42static unsigned int gbufsize_max = 720*576*4;
43module_param(video_debug, int, 0644);
44MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
45module_param(gbuffers, int, 0444);
46MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
47module_param(noninterlaced, int, 0644);
48MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
49
50#define dprintk(fmt, arg...) if (video_debug) \
51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
52
53/* ------------------------------------------------------------------ */
54/* data structs for video */
55
56static int video_out[][9] = {
57 [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
58};
59
60static struct saa7134_format formats[] = {
61 {
62 .name = "8 bpp gray",
63 .fourcc = V4L2_PIX_FMT_GREY,
64 .depth = 8,
65 .pm = 0x06,
66 },{
67 .name = "15 bpp RGB, le",
68 .fourcc = V4L2_PIX_FMT_RGB555,
69 .depth = 16,
70 .pm = 0x13 | 0x80,
71 },{
72 .name = "15 bpp RGB, be",
73 .fourcc = V4L2_PIX_FMT_RGB555X,
74 .depth = 16,
75 .pm = 0x13 | 0x80,
76 .bswap = 1,
77 },{
78 .name = "16 bpp RGB, le",
79 .fourcc = V4L2_PIX_FMT_RGB565,
80 .depth = 16,
81 .pm = 0x10 | 0x80,
82 },{
83 .name = "16 bpp RGB, be",
84 .fourcc = V4L2_PIX_FMT_RGB565X,
85 .depth = 16,
86 .pm = 0x10 | 0x80,
87 .bswap = 1,
88 },{
89 .name = "24 bpp RGB, le",
90 .fourcc = V4L2_PIX_FMT_BGR24,
91 .depth = 24,
92 .pm = 0x11,
93 },{
94 .name = "24 bpp RGB, be",
95 .fourcc = V4L2_PIX_FMT_RGB24,
96 .depth = 24,
97 .pm = 0x11,
98 .bswap = 1,
99 },{
100 .name = "32 bpp RGB, le",
101 .fourcc = V4L2_PIX_FMT_BGR32,
102 .depth = 32,
103 .pm = 0x12,
104 },{
105 .name = "32 bpp RGB, be",
106 .fourcc = V4L2_PIX_FMT_RGB32,
107 .depth = 32,
108 .pm = 0x12,
109 .bswap = 1,
110 .wswap = 1,
111 },{
112 .name = "4:2:2 packed, YUYV",
113 .fourcc = V4L2_PIX_FMT_YUYV,
114 .depth = 16,
115 .pm = 0x00,
116 .bswap = 1,
117 .yuv = 1,
118 },{
119 .name = "4:2:2 packed, UYVY",
120 .fourcc = V4L2_PIX_FMT_UYVY,
121 .depth = 16,
122 .pm = 0x00,
123 .yuv = 1,
124 },{
125 .name = "4:2:2 planar, Y-Cb-Cr",
126 .fourcc = V4L2_PIX_FMT_YUV422P,
127 .depth = 16,
128 .pm = 0x09,
129 .yuv = 1,
130 .planar = 1,
131 .hshift = 1,
132 .vshift = 0,
133 },{
134 .name = "4:2:0 planar, Y-Cb-Cr",
135 .fourcc = V4L2_PIX_FMT_YUV420,
136 .depth = 12,
137 .pm = 0x0a,
138 .yuv = 1,
139 .planar = 1,
140 .hshift = 1,
141 .vshift = 1,
142 },{
143 .name = "4:2:0 planar, Y-Cb-Cr",
144 .fourcc = V4L2_PIX_FMT_YVU420,
145 .depth = 12,
146 .pm = 0x0a,
147 .yuv = 1,
148 .planar = 1,
149 .uvswap = 1,
150 .hshift = 1,
151 .vshift = 1,
152 }
153};
154#define FORMATS ARRAY_SIZE(formats)
155
156#define NORM_625_50 \
157 .h_start = 0, \
158 .h_stop = 719, \
159 .video_v_start = 24, \
160 .video_v_stop = 311, \
161 .vbi_v_start = 7, \
162 .vbi_v_stop = 22, \
163 .src_timing = 4
164
165#define NORM_525_60 \
166 .h_start = 0, \
167 .h_stop = 703, \
168 .video_v_start = 22, \
169 .video_v_stop = 22+239, \
170 .vbi_v_start = 10, /* FIXME */ \
171 .vbi_v_stop = 21, /* FIXME */ \
172 .src_timing = 1
173
174static struct saa7134_tvnorm tvnorms[] = {
175 {
176 .name = "PAL", /* autodetect */
177 .id = V4L2_STD_PAL,
178 NORM_625_50,
179
180 .sync_control = 0x18,
181 .luma_control = 0x40,
182 .chroma_ctrl1 = 0x81,
183 .chroma_gain = 0x2a,
184 .chroma_ctrl2 = 0x06,
185 .vgate_misc = 0x1c,
186
187 },{
188 .name = "PAL-BG",
189 .id = V4L2_STD_PAL_BG,
190 NORM_625_50,
191
192 .sync_control = 0x18,
193 .luma_control = 0x40,
194 .chroma_ctrl1 = 0x81,
195 .chroma_gain = 0x2a,
196 .chroma_ctrl2 = 0x06,
197 .vgate_misc = 0x1c,
198
199 },{
200 .name = "PAL-I",
201 .id = V4L2_STD_PAL_I,
202 NORM_625_50,
203
204 .sync_control = 0x18,
205 .luma_control = 0x40,
206 .chroma_ctrl1 = 0x81,
207 .chroma_gain = 0x2a,
208 .chroma_ctrl2 = 0x06,
209 .vgate_misc = 0x1c,
210
211 },{
212 .name = "PAL-DK",
213 .id = V4L2_STD_PAL_DK,
214 NORM_625_50,
215
216 .sync_control = 0x18,
217 .luma_control = 0x40,
218 .chroma_ctrl1 = 0x81,
219 .chroma_gain = 0x2a,
220 .chroma_ctrl2 = 0x06,
221 .vgate_misc = 0x1c,
222
223 },{
224 .name = "NTSC",
225 .id = V4L2_STD_NTSC,
226 NORM_525_60,
227
228 .sync_control = 0x59,
229 .luma_control = 0x40,
230 .chroma_ctrl1 = 0x89,
231 .chroma_gain = 0x2a,
232 .chroma_ctrl2 = 0x0e,
233 .vgate_misc = 0x18,
234
235 },{
236 .name = "SECAM",
237 .id = V4L2_STD_SECAM,
238 NORM_625_50,
239
240 .sync_control = 0x18, /* old: 0x58, */
241 .luma_control = 0x1b,
242 .chroma_ctrl1 = 0xd1,
243 .chroma_gain = 0x80,
244 .chroma_ctrl2 = 0x00,
245 .vgate_misc = 0x1c,
246
247 },{
248 .name = "PAL-M",
249 .id = V4L2_STD_PAL_M,
250 NORM_525_60,
251
252 .sync_control = 0x59,
253 .luma_control = 0x40,
254 .chroma_ctrl1 = 0xb9,
255 .chroma_gain = 0x2a,
256 .chroma_ctrl2 = 0x0e,
257 .vgate_misc = 0x18,
258
259 },{
260 .name = "PAL-Nc",
261 .id = V4L2_STD_PAL_Nc,
262 NORM_625_50,
263
264 .sync_control = 0x18,
265 .luma_control = 0x40,
266 .chroma_ctrl1 = 0xa1,
267 .chroma_gain = 0x2a,
268 .chroma_ctrl2 = 0x06,
269 .vgate_misc = 0x1c,
270
271 },{
272 .name = "PAL-60",
273 .id = V4L2_STD_PAL_60,
274
275 .h_start = 0,
276 .h_stop = 719,
277 .video_v_start = 22,
278 .video_v_stop = 22+239,
279 .vbi_v_start = 10, /* FIXME */
280 .vbi_v_stop = 21, /* FIXME */
281 .src_timing = 1,
282
283 .sync_control = 0x18,
284 .luma_control = 0x40,
285 .chroma_ctrl1 = 0x81,
286 .chroma_gain = 0x2a,
287 .chroma_ctrl2 = 0x06,
288 .vgate_misc = 0x1c,
289 }
290};
291#define TVNORMS ARRAY_SIZE(tvnorms)
292
293#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)
294#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)
295#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)
296#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)
297#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)
298
299static const struct v4l2_queryctrl no_ctrl = {
300 .name = "42",
301 .flags = V4L2_CTRL_FLAG_DISABLED,
302};
303static const struct v4l2_queryctrl video_ctrls[] = {
304 /* --- video --- */
305 {
306 .id = V4L2_CID_BRIGHTNESS,
307 .name = "Brightness",
308 .minimum = 0,
309 .maximum = 255,
310 .step = 1,
311 .default_value = 128,
312 .type = V4L2_CTRL_TYPE_INTEGER,
313 },{
314 .id = V4L2_CID_CONTRAST,
315 .name = "Contrast",
316 .minimum = 0,
317 .maximum = 127,
318 .step = 1,
319 .default_value = 68,
320 .type = V4L2_CTRL_TYPE_INTEGER,
321 },{
322 .id = V4L2_CID_SATURATION,
323 .name = "Saturation",
324 .minimum = 0,
325 .maximum = 127,
326 .step = 1,
327 .default_value = 64,
328 .type = V4L2_CTRL_TYPE_INTEGER,
329 },{
330 .id = V4L2_CID_HUE,
331 .name = "Hue",
332 .minimum = -128,
333 .maximum = 127,
334 .step = 1,
335 .default_value = 0,
336 .type = V4L2_CTRL_TYPE_INTEGER,
337 },{
338 .id = V4L2_CID_VFLIP,
339 .name = "vertical flip",
340 .minimum = 0,
341 .maximum = 1,
342 .type = V4L2_CTRL_TYPE_BOOLEAN,
343 },
344 /* --- audio --- */
345 {
346 .id = V4L2_CID_AUDIO_MUTE,
347 .name = "Mute",
348 .minimum = 0,
349 .maximum = 1,
350 .type = V4L2_CTRL_TYPE_BOOLEAN,
351 },{
352 .id = V4L2_CID_AUDIO_VOLUME,
353 .name = "Volume",
354 .minimum = -15,
355 .maximum = 15,
356 .step = 1,
357 .default_value = 0,
358 .type = V4L2_CTRL_TYPE_INTEGER,
359 },
360 /* --- private --- */
361 {
362 .id = V4L2_CID_PRIVATE_INVERT,
363 .name = "Invert",
364 .minimum = 0,
365 .maximum = 1,
366 .type = V4L2_CTRL_TYPE_BOOLEAN,
367 },{
368 .id = V4L2_CID_PRIVATE_Y_ODD,
369 .name = "y offset odd field",
370 .minimum = 0,
371 .maximum = 128,
372 .default_value = 0,
373 .type = V4L2_CTRL_TYPE_INTEGER,
374 },{
375 .id = V4L2_CID_PRIVATE_Y_EVEN,
376 .name = "y offset even field",
377 .minimum = 0,
378 .maximum = 128,
379 .default_value = 0,
380 .type = V4L2_CTRL_TYPE_INTEGER,
381 },{
382 .id = V4L2_CID_PRIVATE_AUTOMUTE,
383 .name = "automute",
384 .minimum = 0,
385 .maximum = 1,
386 .default_value = 1,
387 .type = V4L2_CTRL_TYPE_BOOLEAN,
388 }
389};
390static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
391
392static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
393{
394 unsigned int i;
395
396 for (i = 0; i < CTRLS; i++)
397 if (video_ctrls[i].id == id)
398 return video_ctrls+i;
399 return NULL;
400}
401
402static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
403{
404 unsigned int i;
405
406 for (i = 0; i < FORMATS; i++)
407 if (formats[i].fourcc == fourcc)
408 return formats+i;
409 return NULL;
410}
411
412/* ----------------------------------------------------------------------- */
413/* resource management */
414
415static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
416{
417 if (fh->resources & bit)
418 /* have it already allocated */
419 return 1;
420
421 /* is it free? */
422 down(&dev->lock);
423 if (dev->resources & bit) {
424 /* no, someone else uses it */
425 up(&dev->lock);
426 return 0;
427 }
428 /* it's free, grab it */
429 fh->resources |= bit;
430 dev->resources |= bit;
431 dprintk("res: get %d\n",bit);
432 up(&dev->lock);
433 return 1;
434}
435
436static
437int res_check(struct saa7134_fh *fh, unsigned int bit)
438{
439 return (fh->resources & bit);
440}
441
442static
443int res_locked(struct saa7134_dev *dev, unsigned int bit)
444{
445 return (dev->resources & bit);
446}
447
448static
449void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
450{
451 if ((fh->resources & bits) != bits)
452 BUG();
453
454 down(&dev->lock);
455 fh->resources &= ~bits;
456 dev->resources &= ~bits;
457 dprintk("res: put %d\n",bits);
458 up(&dev->lock);
459}
460
461/* ------------------------------------------------------------------ */
462
463static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
464{
465 int luma_control,sync_control,mux;
466
467 dprintk("set tv norm = %s\n",norm->name);
468 dev->tvnorm = norm;
469
470 mux = card_in(dev,dev->ctl_input).vmux;
471 luma_control = norm->luma_control;
472 sync_control = norm->sync_control;
473
474 if (mux > 5)
475 luma_control |= 0x80; /* svideo */
476 if (noninterlaced || dev->nosignal)
477 sync_control |= 0x20;
478
479 /* setup cropping */
480 dev->crop_bounds.left = norm->h_start;
481 dev->crop_defrect.left = norm->h_start;
482 dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
483 dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
484
485 dev->crop_bounds.top = (norm->vbi_v_stop+1)*2;
486 dev->crop_defrect.top = norm->video_v_start*2;
487 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
488 - dev->crop_bounds.top;
489 dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
490
491 dev->crop_current = dev->crop_defrect;
492
493 /* setup video decoder */
494 saa_writeb(SAA7134_INCR_DELAY, 0x08);
495 saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux);
496 saa_writeb(SAA7134_ANALOG_IN_CTRL2, 0x00);
497
498 saa_writeb(SAA7134_ANALOG_IN_CTRL3, 0x90);
499 saa_writeb(SAA7134_ANALOG_IN_CTRL4, 0x90);
500 saa_writeb(SAA7134_HSYNC_START, 0xeb);
501 saa_writeb(SAA7134_HSYNC_STOP, 0xe0);
502 saa_writeb(SAA7134_SOURCE_TIMING1, norm->src_timing);
503
504 saa_writeb(SAA7134_SYNC_CTRL, sync_control);
505 saa_writeb(SAA7134_LUMA_CTRL, luma_control);
506 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
507 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, dev->ctl_contrast);
508
509 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
510 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
511 saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1);
512 saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain);
513
514 saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2);
515 saa_writeb(SAA7134_MODE_DELAY_CTRL, 0x00);
516
517 saa_writeb(SAA7134_ANALOG_ADC, 0x01);
518 saa_writeb(SAA7134_VGATE_START, 0x11);
519 saa_writeb(SAA7134_VGATE_STOP, 0xfe);
520 saa_writeb(SAA7134_MISC_VGATE_MSB, norm->vgate_misc);
521 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
522 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
523
524#ifdef V4L2_I2C_CLIENTS
525 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
526#else
527 {
528 /* pass down info to the i2c chips (v4l1) */
529 struct video_channel c;
530 memset(&c,0,sizeof(c));
531 c.channel = dev->ctl_input;
532 c.norm = VIDEO_MODE_PAL;
533 if (norm->id & V4L2_STD_NTSC)
534 c.norm = VIDEO_MODE_NTSC;
535 if (norm->id & V4L2_STD_SECAM)
536 c.norm = VIDEO_MODE_SECAM;
537 saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
538 }
539#endif
540}
541
542static void video_mux(struct saa7134_dev *dev, int input)
543{
544 dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
545 dev->ctl_input = input;
546 set_tvnorm(dev,dev->tvnorm);
547 saa7134_tvaudio_setinput(dev,&card_in(dev,input));
548}
549
550static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
551{
552 static const struct {
553 int xpsc;
554 int xacl;
555 int xc2_1;
556 int xdcg;
557 int vpfy;
558 } vals[] = {
559 /* XPSC XACL XC2_1 XDCG VPFY */
560 { 1, 0, 0, 0, 0 },
561 { 2, 2, 1, 2, 2 },
562 { 3, 4, 1, 3, 2 },
563 { 4, 8, 1, 4, 2 },
564 { 5, 8, 1, 4, 2 },
565 { 6, 8, 1, 4, 3 },
566 { 7, 8, 1, 4, 3 },
567 { 8, 15, 0, 4, 3 },
568 { 9, 15, 0, 4, 3 },
569 { 10, 16, 1, 5, 3 },
570 };
571 static const int count = ARRAY_SIZE(vals);
572 int i;
573
574 for (i = 0; i < count; i++)
575 if (vals[i].xpsc == prescale)
576 break;
577 if (i == count)
578 return;
579
580 saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
581 saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
582 saa_writeb(SAA7134_LEVEL_CTRL(task),
583 (vals[i].xc2_1 << 3) | (vals[i].xdcg));
584 saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
585 (vals[i].vpfy << 2) | vals[i].vpfy);
586}
587
588static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
589{
590 int val,mirror;
591
592 saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale & 0xff);
593 saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
594
595 mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
596 if (yscale < 2048) {
597 /* LPI */
598 dprintk("yscale LPI yscale=%d\n",yscale);
599 saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
600 saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
601 saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
602 } else {
603 /* ACM */
604 val = 0x40 * 1024 / yscale;
605 dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
606 saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
607 saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
608 saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
609 }
610 saa_writeb(SAA7134_LUMA_BRIGHT(task), 0x80);
611}
612
613static void set_size(struct saa7134_dev *dev, int task,
614 int width, int height, int interlace)
615{
616 int prescale,xscale,yscale,y_even,y_odd;
617 int h_start, h_stop, v_start, v_stop;
618 int div = interlace ? 2 : 1;
619
620 /* setup video scaler */
621 h_start = dev->crop_current.left;
622 v_start = dev->crop_current.top/2;
623 h_stop = (dev->crop_current.left + dev->crop_current.width -1);
624 v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2;
625
626 saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff);
627 saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
628 saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff);
629 saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8);
630 saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff);
631 saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
632 saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff);
633 saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8);
634
635 prescale = dev->crop_current.width / width;
636 if (0 == prescale)
637 prescale = 1;
638 xscale = 1024 * dev->crop_current.width / prescale / width;
639 yscale = 512 * div * dev->crop_current.height / height;
640 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
641 set_h_prescale(dev,task,prescale);
642 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
643 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
644 set_v_scale(dev,task,yscale);
645
646 saa_writeb(SAA7134_VIDEO_PIXELS1(task), width & 0xff);
647 saa_writeb(SAA7134_VIDEO_PIXELS2(task), width >> 8);
648 saa_writeb(SAA7134_VIDEO_LINES1(task), height/div & 0xff);
649 saa_writeb(SAA7134_VIDEO_LINES2(task), height/div >> 8);
650
651 /* deinterlace y offsets */
652 y_odd = dev->ctl_y_odd;
653 y_even = dev->ctl_y_even;
654 saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
655 saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
656 saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
657 saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
658}
659
660/* ------------------------------------------------------------------ */
661
662struct cliplist {
663 __u16 position;
664 __u8 enable;
665 __u8 disable;
666};
667
668static void sort_cliplist(struct cliplist *cl, int entries)
669{
670 struct cliplist swap;
671 int i,j,n;
672
673 for (i = entries-2; i >= 0; i--) {
674 for (n = 0, j = 0; j <= i; j++) {
675 if (cl[j].position > cl[j+1].position) {
676 swap = cl[j];
677 cl[j] = cl[j+1];
678 cl[j+1] = swap;
679 n++;
680 }
681 }
682 if (0 == n)
683 break;
684 }
685}
686
687static void set_cliplist(struct saa7134_dev *dev, int reg,
688 struct cliplist *cl, int entries, char *name)
689{
690 __u8 winbits = 0;
691 int i;
692
693 for (i = 0; i < entries; i++) {
694 winbits |= cl[i].enable;
695 winbits &= ~cl[i].disable;
696 if (i < 15 && cl[i].position == cl[i+1].position)
697 continue;
698 saa_writeb(reg + 0, winbits);
699 saa_writeb(reg + 2, cl[i].position & 0xff);
700 saa_writeb(reg + 3, cl[i].position >> 8);
701 dprintk("clip: %s winbits=%02x pos=%d\n",
702 name,winbits,cl[i].position);
703 reg += 8;
704 }
705 for (; reg < 0x400; reg += 8) {
706 saa_writeb(reg+ 0, 0);
707 saa_writeb(reg + 1, 0);
708 saa_writeb(reg + 2, 0);
709 saa_writeb(reg + 3, 0);
710 }
711}
712
713static int clip_range(int val)
714{
715 if (val < 0)
716 val = 0;
717 return val;
718}
719
720static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
721 int nclips, int interlace)
722{
723 struct cliplist col[16], row[16];
724 int cols, rows, i;
725 int div = interlace ? 2 : 1;
726
727 memset(col,0,sizeof(col)); cols = 0;
728 memset(row,0,sizeof(row)); rows = 0;
729 for (i = 0; i < nclips && i < 8; i++) {
730 col[cols].position = clip_range(clips[i].c.left);
731 col[cols].enable = (1 << i);
732 cols++;
733 col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
734 col[cols].disable = (1 << i);
735 cols++;
736 row[rows].position = clip_range(clips[i].c.top / div);
737 row[rows].enable = (1 << i);
738 rows++;
739 row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
740 / div);
741 row[rows].disable = (1 << i);
742 rows++;
743 }
744 sort_cliplist(col,cols);
745 sort_cliplist(row,rows);
746 set_cliplist(dev,0x380,col,cols,"cols");
747 set_cliplist(dev,0x384,row,rows,"rows");
748 return 0;
749}
750
751static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752{
753 enum v4l2_field field;
754 int maxw, maxh;
755
756 if (NULL == dev->ovbuf.base)
757 return -EINVAL;
758 if (NULL == dev->ovfmt)
759 return -EINVAL;
760 if (win->w.width < 48 || win->w.height < 32)
761 return -EINVAL;
762 if (win->clipcount > 2048)
763 return -EINVAL;
764
765 field = win->field;
766 maxw = dev->crop_current.width;
767 maxh = dev->crop_current.height;
768
769 if (V4L2_FIELD_ANY == field) {
770 field = (win->w.height > maxh/2)
771 ? V4L2_FIELD_INTERLACED
772 : V4L2_FIELD_TOP;
773 }
774 switch (field) {
775 case V4L2_FIELD_TOP:
776 case V4L2_FIELD_BOTTOM:
777 maxh = maxh / 2;
778 break;
779 case V4L2_FIELD_INTERLACED:
780 break;
781 default:
782 return -EINVAL;
783 }
784
785 win->field = field;
786 if (win->w.width > maxw)
787 win->w.width = maxw;
788 if (win->w.height > maxh)
789 win->w.height = maxh;
790 return 0;
791}
792
793static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
794{
795 unsigned long base,control,bpl;
796 int err;
797
798 err = verify_preview(dev,&fh->win);
799 if (0 != err)
800 return err;
801
802 dev->ovfield = fh->win.field;
803 dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
804 fh->win.w.width,fh->win.w.height,
805 fh->win.w.left,fh->win.w.top,
806 dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
807
808 /* setup window + clipping */
809 set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
810 V4L2_FIELD_HAS_BOTH(dev->ovfield));
811 setup_clipping(dev,fh->clips,fh->nclips,
812 V4L2_FIELD_HAS_BOTH(dev->ovfield));
813 if (dev->ovfmt->yuv)
814 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
815 else
816 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
817 saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
818
819 /* dma: setup channel 1 (= Video Task B) */
820 base = (unsigned long)dev->ovbuf.base;
821 base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
822 base += dev->ovfmt->depth/8 * fh->win.w.left;
823 bpl = dev->ovbuf.fmt.bytesperline;
824 control = SAA7134_RS_CONTROL_BURST_16;
825 if (dev->ovfmt->bswap)
826 control |= SAA7134_RS_CONTROL_BSWAP;
827 if (dev->ovfmt->wswap)
828 control |= SAA7134_RS_CONTROL_WSWAP;
829 if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
830 saa_writel(SAA7134_RS_BA1(1),base);
831 saa_writel(SAA7134_RS_BA2(1),base+bpl);
832 saa_writel(SAA7134_RS_PITCH(1),bpl*2);
833 saa_writel(SAA7134_RS_CONTROL(1),control);
834 } else {
835 saa_writel(SAA7134_RS_BA1(1),base);
836 saa_writel(SAA7134_RS_BA2(1),base);
837 saa_writel(SAA7134_RS_PITCH(1),bpl);
838 saa_writel(SAA7134_RS_CONTROL(1),control);
839 }
840
841 /* start dma */
842 dev->ovenable = 1;
843 saa7134_set_dmabits(dev);
844
845 return 0;
846}
847
848static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
849{
850 dev->ovenable = 0;
851 saa7134_set_dmabits(dev);
852 return 0;
853}
854
855/* ------------------------------------------------------------------ */
856
857static int buffer_activate(struct saa7134_dev *dev,
858 struct saa7134_buf *buf,
859 struct saa7134_buf *next)
860{
861 unsigned long base,control,bpl;
862 unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
863
864 dprintk("buffer_activate buf=%p\n",buf);
865 buf->vb.state = STATE_ACTIVE;
866 buf->top_seen = 0;
867
868 set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
869 V4L2_FIELD_HAS_BOTH(buf->vb.field));
870 if (buf->fmt->yuv)
871 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
872 else
873 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
874 saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
875
876 /* DMA: setup channel 0 (= Video Task A0) */
877 base = saa7134_buffer_base(buf);
878 if (buf->fmt->planar)
879 bpl = buf->vb.width;
880 else
881 bpl = (buf->vb.width * buf->fmt->depth) / 8;
882 control = SAA7134_RS_CONTROL_BURST_16 |
883 SAA7134_RS_CONTROL_ME |
884 (buf->pt->dma >> 12);
885 if (buf->fmt->bswap)
886 control |= SAA7134_RS_CONTROL_BSWAP;
887 if (buf->fmt->wswap)
888 control |= SAA7134_RS_CONTROL_WSWAP;
889 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
890 /* interlaced */
891 saa_writel(SAA7134_RS_BA1(0),base);
892 saa_writel(SAA7134_RS_BA2(0),base+bpl);
893 saa_writel(SAA7134_RS_PITCH(0),bpl*2);
894 } else {
895 /* non-interlaced */
896 saa_writel(SAA7134_RS_BA1(0),base);
897 saa_writel(SAA7134_RS_BA2(0),base);
898 saa_writel(SAA7134_RS_PITCH(0),bpl);
899 }
900 saa_writel(SAA7134_RS_CONTROL(0),control);
901
902 if (buf->fmt->planar) {
903 /* DMA: setup channel 4+5 (= planar task A) */
904 bpl_uv = bpl >> buf->fmt->hshift;
905 lines_uv = buf->vb.height >> buf->fmt->vshift;
906 base2 = base + bpl * buf->vb.height;
907 base3 = base2 + bpl_uv * lines_uv;
908 if (buf->fmt->uvswap)
909 tmp = base2, base2 = base3, base3 = tmp;
910 dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
911 bpl_uv,lines_uv,base2,base3);
912 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
913 /* interlaced */
914 saa_writel(SAA7134_RS_BA1(4),base2);
915 saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
916 saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
917 saa_writel(SAA7134_RS_BA1(5),base3);
918 saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
919 saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
920 } else {
921 /* non-interlaced */
922 saa_writel(SAA7134_RS_BA1(4),base2);
923 saa_writel(SAA7134_RS_BA2(4),base2);
924 saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
925 saa_writel(SAA7134_RS_BA1(5),base3);
926 saa_writel(SAA7134_RS_BA2(5),base3);
927 saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
928 }
929 saa_writel(SAA7134_RS_CONTROL(4),control);
930 saa_writel(SAA7134_RS_CONTROL(5),control);
931 }
932
933 /* start DMA */
934 saa7134_set_dmabits(dev);
935 mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
936 return 0;
937}
938
939static int buffer_prepare(struct videobuf_queue *q,
940 struct videobuf_buffer *vb,
941 enum v4l2_field field)
942{
943 struct saa7134_fh *fh = q->priv_data;
944 struct saa7134_dev *dev = fh->dev;
945 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
946 unsigned int size;
947 int err;
948
949 /* sanity checks */
950 if (NULL == fh->fmt)
951 return -EINVAL;
952 if (fh->width < 48 ||
953 fh->height < 32 ||
954 fh->width/4 > dev->crop_current.width ||
955 fh->height/4 > dev->crop_current.height ||
956 fh->width > dev->crop_bounds.width ||
957 fh->height > dev->crop_bounds.height)
958 return -EINVAL;
959 size = (fh->width * fh->height * fh->fmt->depth) >> 3;
960 if (0 != buf->vb.baddr && buf->vb.bsize < size)
961 return -EINVAL;
962
963 dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
964 vb->i,fh->width,fh->height,size,v4l2_field_names[field],
965 fh->fmt->name);
966 if (buf->vb.width != fh->width ||
967 buf->vb.height != fh->height ||
968 buf->vb.size != size ||
969 buf->vb.field != field ||
970 buf->fmt != fh->fmt) {
971 saa7134_dma_free(dev,buf);
972 }
973
974 if (STATE_NEEDS_INIT == buf->vb.state) {
975 buf->vb.width = fh->width;
976 buf->vb.height = fh->height;
977 buf->vb.size = size;
978 buf->vb.field = field;
979 buf->fmt = fh->fmt;
980 buf->pt = &fh->pt_cap;
981
982 err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf);
983 if (err)
984 goto oops;
985 err = saa7134_pgtable_build(dev->pci,buf->pt,
986 buf->vb.dma.sglist,
987 buf->vb.dma.sglen,
988 saa7134_buffer_startpage(buf));
989 if (err)
990 goto oops;
991 }
992 buf->vb.state = STATE_PREPARED;
993 buf->activate = buffer_activate;
994 return 0;
995
996 oops:
997 saa7134_dma_free(dev,buf);
998 return err;
999}
1000
1001static int
1002buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1003{
1004 struct saa7134_fh *fh = q->priv_data;
1005
1006 *size = fh->fmt->depth * fh->width * fh->height >> 3;
1007 if (0 == *count)
1008 *count = gbuffers;
1009 *count = saa7134_buffer_count(*size,*count);
1010 return 0;
1011}
1012
1013static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1014{
1015 struct saa7134_fh *fh = q->priv_data;
1016 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1017
1018 saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
1019}
1020
1021static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1022{
1023 struct saa7134_fh *fh = q->priv_data;
1024 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1025
1026 saa7134_dma_free(fh->dev,buf);
1027}
1028
1029static struct videobuf_queue_ops video_qops = {
1030 .buf_setup = buffer_setup,
1031 .buf_prepare = buffer_prepare,
1032 .buf_queue = buffer_queue,
1033 .buf_release = buffer_release,
1034};
1035
1036/* ------------------------------------------------------------------ */
1037
1038static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
1039{
1040 const struct v4l2_queryctrl* ctrl;
1041
1042 ctrl = ctrl_by_id(c->id);
1043 if (NULL == ctrl)
1044 return -EINVAL;
1045 switch (c->id) {
1046 case V4L2_CID_BRIGHTNESS:
1047 c->value = dev->ctl_bright;
1048 break;
1049 case V4L2_CID_HUE:
1050 c->value = dev->ctl_hue;
1051 break;
1052 case V4L2_CID_CONTRAST:
1053 c->value = dev->ctl_contrast;
1054 break;
1055 case V4L2_CID_SATURATION:
1056 c->value = dev->ctl_saturation;
1057 break;
1058 case V4L2_CID_AUDIO_MUTE:
1059 c->value = dev->ctl_mute;
1060 break;
1061 case V4L2_CID_AUDIO_VOLUME:
1062 c->value = dev->ctl_volume;
1063 break;
1064 case V4L2_CID_PRIVATE_INVERT:
1065 c->value = dev->ctl_invert;
1066 break;
1067 case V4L2_CID_VFLIP:
1068 c->value = dev->ctl_mirror;
1069 break;
1070 case V4L2_CID_PRIVATE_Y_EVEN:
1071 c->value = dev->ctl_y_even;
1072 break;
1073 case V4L2_CID_PRIVATE_Y_ODD:
1074 c->value = dev->ctl_y_odd;
1075 break;
1076 case V4L2_CID_PRIVATE_AUTOMUTE:
1077 c->value = dev->ctl_automute;
1078 break;
1079 default:
1080 return -EINVAL;
1081 }
1082 return 0;
1083}
1084
1085static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
1086 struct v4l2_control *c)
1087{
1088 const struct v4l2_queryctrl* ctrl;
1089 unsigned long flags;
1090 int restart_overlay = 0;
1091
1092 ctrl = ctrl_by_id(c->id);
1093 if (NULL == ctrl)
1094 return -EINVAL;
1095 dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
1096 switch (ctrl->type) {
1097 case V4L2_CTRL_TYPE_BOOLEAN:
1098 case V4L2_CTRL_TYPE_MENU:
1099 case V4L2_CTRL_TYPE_INTEGER:
1100 if (c->value < ctrl->minimum)
1101 c->value = ctrl->minimum;
1102 if (c->value > ctrl->maximum)
1103 c->value = ctrl->maximum;
1104 break;
1105 default:
1106 /* nothing */;
1107 };
1108 switch (c->id) {
1109 case V4L2_CID_BRIGHTNESS:
1110 dev->ctl_bright = c->value;
1111 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
1112 break;
1113 case V4L2_CID_HUE:
1114 dev->ctl_hue = c->value;
1115 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
1116 break;
1117 case V4L2_CID_CONTRAST:
1118 dev->ctl_contrast = c->value;
1119 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1120 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1121 break;
1122 case V4L2_CID_SATURATION:
1123 dev->ctl_saturation = c->value;
1124 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1125 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1126 break;
1127 case V4L2_CID_AUDIO_MUTE:
1128 dev->ctl_mute = c->value;
1129 saa7134_tvaudio_setmute(dev);
1130 break;
1131 case V4L2_CID_AUDIO_VOLUME:
1132 dev->ctl_volume = c->value;
1133 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
1134 break;
1135 case V4L2_CID_PRIVATE_INVERT:
1136 dev->ctl_invert = c->value;
1137 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1138 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1139 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1140 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1141 break;
1142 case V4L2_CID_VFLIP:
1143 dev->ctl_mirror = c->value;
1144 restart_overlay = 1;
1145 break;
1146 case V4L2_CID_PRIVATE_Y_EVEN:
1147 dev->ctl_y_even = c->value;
1148 restart_overlay = 1;
1149 break;
1150 case V4L2_CID_PRIVATE_Y_ODD:
1151 dev->ctl_y_odd = c->value;
1152 restart_overlay = 1;
1153 break;
1154 case V4L2_CID_PRIVATE_AUTOMUTE:
1155 dev->ctl_automute = c->value;
1156 if (dev->tda9887_conf) {
1157 if (dev->ctl_automute)
1158 dev->tda9887_conf |= TDA9887_AUTOMUTE;
1159 else
1160 dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
1161 saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
1162 &dev->tda9887_conf);
1163 }
1164 break;
1165 default:
1166 return -EINVAL;
1167 }
1168 if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
1169 spin_lock_irqsave(&dev->slock,flags);
1170 stop_preview(dev,fh);
1171 start_preview(dev,fh);
1172 spin_unlock_irqrestore(&dev->slock,flags);
1173 }
1174 return 0;
1175}
1176
1177/* ------------------------------------------------------------------ */
1178
1179static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
1180{
1181 struct videobuf_queue* q = NULL;
1182
1183 switch (fh->type) {
1184 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1185 q = &fh->cap;
1186 break;
1187 case V4L2_BUF_TYPE_VBI_CAPTURE:
1188 q = &fh->vbi;
1189 break;
1190 default:
1191 BUG();
1192 }
1193 return q;
1194}
1195
1196static int saa7134_resource(struct saa7134_fh *fh)
1197{
1198 int res = 0;
1199
1200 switch (fh->type) {
1201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1202 res = RESOURCE_VIDEO;
1203 break;
1204 case V4L2_BUF_TYPE_VBI_CAPTURE:
1205 res = RESOURCE_VBI;
1206 break;
1207 default:
1208 BUG();
1209 }
1210 return res;
1211}
1212
1213static int video_open(struct inode *inode, struct file *file)
1214{
1215 int minor = iminor(inode);
1216 struct saa7134_dev *h,*dev = NULL;
1217 struct saa7134_fh *fh;
1218 struct list_head *list;
1219 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1220 int radio = 0;
1221
1222 list_for_each(list,&saa7134_devlist) {
1223 h = list_entry(list, struct saa7134_dev, devlist);
1224 if (h->video_dev && (h->video_dev->minor == minor))
1225 dev = h;
1226 if (h->radio_dev && (h->radio_dev->minor == minor)) {
1227 radio = 1;
1228 dev = h;
1229 }
1230 if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
1231 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1232 dev = h;
1233 }
1234 }
1235 if (NULL == dev)
1236 return -ENODEV;
1237
1238 dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
1239 v4l2_type_names[type]);
1240
1241 /* allocate + initialize per filehandle data */
1242 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
1243 if (NULL == fh)
1244 return -ENOMEM;
1245 memset(fh,0,sizeof(*fh));
1246 file->private_data = fh;
1247 fh->dev = dev;
1248 fh->radio = radio;
1249 fh->type = type;
1250 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1251 fh->width = 720;
1252 fh->height = 576;
1253 v4l2_prio_open(&dev->prio,&fh->prio);
1254
1255 videobuf_queue_init(&fh->cap, &video_qops,
1256 dev->pci, &dev->slock,
1257 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1258 V4L2_FIELD_INTERLACED,
1259 sizeof(struct saa7134_buf),
1260 fh);
1261 videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
1262 dev->pci, &dev->slock,
1263 V4L2_BUF_TYPE_VBI_CAPTURE,
1264 V4L2_FIELD_SEQ_TB,
1265 sizeof(struct saa7134_buf),
1266 fh);
1267 saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
1268 saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
1269
1270 if (fh->radio) {
1271 /* switch to radio mode */
1272 saa7134_tvaudio_setinput(dev,&card(dev).radio);
1273 saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
1274 } else {
1275 /* switch to video/vbi mode */
1276 video_mux(dev,dev->ctl_input);
1277 }
1278 return 0;
1279}
1280
1281static ssize_t
1282video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1283{
1284 struct saa7134_fh *fh = file->private_data;
1285
1286 switch (fh->type) {
1287 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1288 if (res_locked(fh->dev,RESOURCE_VIDEO))
1289 return -EBUSY;
1290 return videobuf_read_one(saa7134_queue(fh),
1291 data, count, ppos,
1292 file->f_flags & O_NONBLOCK);
1293 case V4L2_BUF_TYPE_VBI_CAPTURE:
1294 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1295 return -EBUSY;
1296 return videobuf_read_stream(saa7134_queue(fh),
1297 data, count, ppos, 1,
1298 file->f_flags & O_NONBLOCK);
1299 break;
1300 default:
1301 BUG();
1302 return 0;
1303 }
1304}
1305
1306static unsigned int
1307video_poll(struct file *file, struct poll_table_struct *wait)
1308{
1309 struct saa7134_fh *fh = file->private_data;
1310 struct videobuf_buffer *buf = NULL;
1311
1312 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1313 return videobuf_poll_stream(file, &fh->vbi, wait);
1314
1315 if (res_check(fh,RESOURCE_VIDEO)) {
1316 if (!list_empty(&fh->cap.stream))
1317 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
1318 } else {
1319 down(&fh->cap.lock);
1320 if (UNSET == fh->cap.read_off) {
1321 /* need to capture a new frame */
1322 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1323 up(&fh->cap.lock);
1324 return POLLERR;
1325 }
1326 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1327 up(&fh->cap.lock);
1328 return POLLERR;
1329 }
1330 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1331 fh->cap.read_off = 0;
1332 }
1333 up(&fh->cap.lock);
1334 buf = fh->cap.read_buf;
1335 }
1336
1337 if (!buf)
1338 return POLLERR;
1339
1340 poll_wait(file, &buf->done, wait);
1341 if (buf->state == STATE_DONE ||
1342 buf->state == STATE_ERROR)
1343 return POLLIN|POLLRDNORM;
1344 return 0;
1345}
1346
1347static int video_release(struct inode *inode, struct file *file)
1348{
1349 struct saa7134_fh *fh = file->private_data;
1350 struct saa7134_dev *dev = fh->dev;
1351 unsigned long flags;
1352
1353 /* turn off overlay */
1354 if (res_check(fh, RESOURCE_OVERLAY)) {
1355 spin_lock_irqsave(&dev->slock,flags);
1356 stop_preview(dev,fh);
1357 spin_unlock_irqrestore(&dev->slock,flags);
1358 res_free(dev,fh,RESOURCE_OVERLAY);
1359 }
1360
1361 /* stop video capture */
1362 if (res_check(fh, RESOURCE_VIDEO)) {
1363 videobuf_streamoff(&fh->cap);
1364 res_free(dev,fh,RESOURCE_VIDEO);
1365 }
1366 if (fh->cap.read_buf) {
1367 buffer_release(&fh->cap,fh->cap.read_buf);
1368 kfree(fh->cap.read_buf);
1369 }
1370
1371 /* stop vbi capture */
1372 if (res_check(fh, RESOURCE_VBI)) {
1373 if (fh->vbi.streaming)
1374 videobuf_streamoff(&fh->vbi);
1375 if (fh->vbi.reading)
1376 videobuf_read_stop(&fh->vbi);
1377 res_free(dev,fh,RESOURCE_VBI);
1378 }
1379
1380 /* free stuff */
1381 videobuf_mmap_free(&fh->cap);
1382 videobuf_mmap_free(&fh->vbi);
1383 saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1384 saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1385
1386 v4l2_prio_close(&dev->prio,&fh->prio);
1387 file->private_data = NULL;
1388 kfree(fh);
1389 return 0;
1390}
1391
1392static int
1393video_mmap(struct file *file, struct vm_area_struct * vma)
1394{
1395 struct saa7134_fh *fh = file->private_data;
1396
1397 return videobuf_mmap_mapper(saa7134_queue(fh), vma);
1398}
1399
1400/* ------------------------------------------------------------------ */
1401
1402static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
1403{
1404 struct saa7134_tvnorm *norm = dev->tvnorm;
1405
1406 f->fmt.vbi.sampling_rate = 6750000 * 4;
1407 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1408 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1409 f->fmt.vbi.offset = 64 * 4;
1410 f->fmt.vbi.start[0] = norm->vbi_v_start;
1411 f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
1412 f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
1413 f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1414 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1415
1416#if 0
1417 if (V4L2_STD_PAL == norm->id) {
1418 /* FIXME */
1419 f->fmt.vbi.start[0] += 3;
1420 f->fmt.vbi.start[1] += 3*2;
1421 }
1422#endif
1423}
1424
1425static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1426 struct v4l2_format *f)
1427{
1428 switch (f->type) {
1429 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1430 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1431 f->fmt.pix.width = fh->width;
1432 f->fmt.pix.height = fh->height;
1433 f->fmt.pix.field = fh->cap.field;
1434 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1435 f->fmt.pix.bytesperline =
1436 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1437 f->fmt.pix.sizeimage =
1438 f->fmt.pix.height * f->fmt.pix.bytesperline;
1439 return 0;
1440 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1441 f->fmt.win = fh->win;
1442 return 0;
1443 case V4L2_BUF_TYPE_VBI_CAPTURE:
1444 saa7134_vbi_fmt(dev,f);
1445 return 0;
1446 default:
1447 return -EINVAL;
1448 }
1449}
1450
1451static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1452 struct v4l2_format *f)
1453{
1454 int err;
1455
1456 switch (f->type) {
1457 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1458 {
1459 struct saa7134_format *fmt;
1460 enum v4l2_field field;
1461 unsigned int maxw, maxh;
1462
1463 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1464 if (NULL == fmt)
1465 return -EINVAL;
1466
1467 field = f->fmt.pix.field;
1468 maxw = min(dev->crop_current.width*4, dev->crop_bounds.width);
1469 maxh = min(dev->crop_current.height*4, dev->crop_bounds.height);
1470
1471 if (V4L2_FIELD_ANY == field) {
1472 field = (f->fmt.pix.height > maxh/2)
1473 ? V4L2_FIELD_INTERLACED
1474 : V4L2_FIELD_BOTTOM;
1475 }
1476 switch (field) {
1477 case V4L2_FIELD_TOP:
1478 case V4L2_FIELD_BOTTOM:
1479 maxh = maxh / 2;
1480 break;
1481 case V4L2_FIELD_INTERLACED:
1482 break;
1483 default:
1484 return -EINVAL;
1485 }
1486
1487 f->fmt.pix.field = field;
1488 if (f->fmt.pix.width < 48)
1489 f->fmt.pix.width = 48;
1490 if (f->fmt.pix.height < 32)
1491 f->fmt.pix.height = 32;
1492 if (f->fmt.pix.width > maxw)
1493 f->fmt.pix.width = maxw;
1494 if (f->fmt.pix.height > maxh)
1495 f->fmt.pix.height = maxh;
1496 f->fmt.pix.width &= ~0x03;
1497 f->fmt.pix.bytesperline =
1498 (f->fmt.pix.width * fmt->depth) >> 3;
1499 f->fmt.pix.sizeimage =
1500 f->fmt.pix.height * f->fmt.pix.bytesperline;
1501
1502 return 0;
1503 }
1504 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1505 err = verify_preview(dev,&f->fmt.win);
1506 if (0 != err)
1507 return err;
1508 return 0;
1509 case V4L2_BUF_TYPE_VBI_CAPTURE:
1510 saa7134_vbi_fmt(dev,f);
1511 return 0;
1512 default:
1513 return -EINVAL;
1514 }
1515}
1516
1517static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1518 struct v4l2_format *f)
1519{
1520 unsigned long flags;
1521 int err;
1522
1523 switch (f->type) {
1524 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1525 err = saa7134_try_fmt(dev,fh,f);
1526 if (0 != err)
1527 return err;
1528
1529 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1530 fh->width = f->fmt.pix.width;
1531 fh->height = f->fmt.pix.height;
1532 fh->cap.field = f->fmt.pix.field;
1533 return 0;
1534 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1535 err = verify_preview(dev,&f->fmt.win);
1536 if (0 != err)
1537 return err;
1538
1539 down(&dev->lock);
1540 fh->win = f->fmt.win;
1541 fh->nclips = f->fmt.win.clipcount;
1542 if (fh->nclips > 8)
1543 fh->nclips = 8;
1544 if (copy_from_user(fh->clips,f->fmt.win.clips,
1545 sizeof(struct v4l2_clip)*fh->nclips)) {
1546 up(&dev->lock);
1547 return -EFAULT;
1548 }
1549
1550 if (res_check(fh, RESOURCE_OVERLAY)) {
1551 spin_lock_irqsave(&dev->slock,flags);
1552 stop_preview(dev,fh);
1553 start_preview(dev,fh);
1554 spin_unlock_irqrestore(&dev->slock,flags);
1555 }
1556 up(&dev->lock);
1557 return 0;
1558 case V4L2_BUF_TYPE_VBI_CAPTURE:
1559 saa7134_vbi_fmt(dev,f);
1560 return 0;
1561 default:
1562 return -EINVAL;
1563 }
1564}
1565
1566int saa7134_common_ioctl(struct saa7134_dev *dev,
1567 unsigned int cmd, void *arg)
1568{
1569 int err;
1570
1571 switch (cmd) {
1572 case VIDIOC_QUERYCTRL:
1573 {
1574 const struct v4l2_queryctrl *ctrl;
1575 struct v4l2_queryctrl *c = arg;
1576
1577 if ((c->id < V4L2_CID_BASE ||
1578 c->id >= V4L2_CID_LASTP1) &&
1579 (c->id < V4L2_CID_PRIVATE_BASE ||
1580 c->id >= V4L2_CID_PRIVATE_LASTP1))
1581 return -EINVAL;
1582 ctrl = ctrl_by_id(c->id);
1583 *c = (NULL != ctrl) ? *ctrl : no_ctrl;
1584 return 0;
1585 }
1586 case VIDIOC_G_CTRL:
1587 return get_control(dev,arg);
1588 case VIDIOC_S_CTRL:
1589 {
1590 down(&dev->lock);
1591 err = set_control(dev,NULL,arg);
1592 up(&dev->lock);
1593 return err;
1594 }
1595 /* --- input switching --------------------------------------- */
1596 case VIDIOC_ENUMINPUT:
1597 {
1598 struct v4l2_input *i = arg;
1599 unsigned int n;
1600
1601 n = i->index;
1602 if (n >= SAA7134_INPUT_MAX)
1603 return -EINVAL;
1604 if (NULL == card_in(dev,i->index).name)
1605 return -EINVAL;
1606 memset(i,0,sizeof(*i));
1607 i->index = n;
1608 i->type = V4L2_INPUT_TYPE_CAMERA;
1609 strcpy(i->name,card_in(dev,n).name);
1610 if (card_in(dev,n).tv)
1611 i->type = V4L2_INPUT_TYPE_TUNER;
1612 i->audioset = 1;
1613 if (n == dev->ctl_input) {
1614 int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
1615 int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
1616
1617 if (0 != (v1 & 0x40))
1618 i->status |= V4L2_IN_ST_NO_H_LOCK;
1619 if (0 != (v2 & 0x40))
1620 i->status |= V4L2_IN_ST_NO_SYNC;
1621 if (0 != (v2 & 0x0e))
1622 i->status |= V4L2_IN_ST_MACROVISION;
1623 }
1624 for (n = 0; n < TVNORMS; n++)
1625 i->std |= tvnorms[n].id;
1626 return 0;
1627 }
1628 case VIDIOC_G_INPUT:
1629 {
1630 int *i = arg;
1631 *i = dev->ctl_input;
1632 return 0;
1633 }
1634 case VIDIOC_S_INPUT:
1635 {
1636 int *i = arg;
1637
1638 if (*i < 0 || *i >= SAA7134_INPUT_MAX)
1639 return -EINVAL;
1640 if (NULL == card_in(dev,*i).name)
1641 return -EINVAL;
1642 down(&dev->lock);
1643 video_mux(dev,*i);
1644 up(&dev->lock);
1645 return 0;
1646 }
1647
1648 }
1649 return 0;
1650}
1651EXPORT_SYMBOL(saa7134_common_ioctl);
1652
1653/*
1654 * This function is _not_ called directly, but from
1655 * video_generic_ioctl (and maybe others). userspace
1656 * copying is done already, arg is a kernel pointer.
1657 */
1658static int video_do_ioctl(struct inode *inode, struct file *file,
1659 unsigned int cmd, void *arg)
1660{
1661 struct saa7134_fh *fh = file->private_data;
1662 struct saa7134_dev *dev = fh->dev;
1663 unsigned long flags;
1664 int err;
1665
1666 if (video_debug > 1)
1667 saa7134_print_ioctl(dev->name,cmd);
1668
1669 switch (cmd) {
1670 case VIDIOC_S_CTRL:
1671 case VIDIOC_S_STD:
1672 case VIDIOC_S_INPUT:
1673 case VIDIOC_S_TUNER:
1674 case VIDIOC_S_FREQUENCY:
1675 err = v4l2_prio_check(&dev->prio,&fh->prio);
1676 if (0 != err)
1677 return err;
1678 }
1679
1680 switch (cmd) {
1681 case VIDIOC_QUERYCAP:
1682 {
1683 struct v4l2_capability *cap = arg;
1684
1685 memset(cap,0,sizeof(*cap));
1686 strcpy(cap->driver, "saa7134");
1687 strlcpy(cap->card, saa7134_boards[dev->board].name,
1688 sizeof(cap->card));
1689 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1690 cap->version = SAA7134_VERSION_CODE;
1691 cap->capabilities =
1692 V4L2_CAP_VIDEO_CAPTURE |
1693 V4L2_CAP_VIDEO_OVERLAY |
1694 V4L2_CAP_VBI_CAPTURE |
1695 V4L2_CAP_TUNER |
1696 V4L2_CAP_READWRITE |
1697 V4L2_CAP_STREAMING;
1698 return 0;
1699 }
1700
1701 /* --- tv standards ------------------------------------------ */
1702 case VIDIOC_ENUMSTD:
1703 {
1704 struct v4l2_standard *e = arg;
1705 unsigned int i;
1706
1707 i = e->index;
1708 if (i >= TVNORMS)
1709 return -EINVAL;
1710 err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1711 tvnorms[e->index].name);
1712 e->index = i;
1713 if (err < 0)
1714 return err;
1715 return 0;
1716 }
1717 case VIDIOC_G_STD:
1718 {
1719 v4l2_std_id *id = arg;
1720
1721 *id = dev->tvnorm->id;
1722 return 0;
1723 }
1724 case VIDIOC_S_STD:
1725 {
1726 v4l2_std_id *id = arg;
1727 unsigned int i;
1728
1729 for (i = 0; i < TVNORMS; i++)
1730 if (*id == tvnorms[i].id)
1731 break;
1732 if (i == TVNORMS)
1733 for (i = 0; i < TVNORMS; i++)
1734 if (*id & tvnorms[i].id)
1735 break;
1736 if (i == TVNORMS)
1737 return -EINVAL;
1738
1739 down(&dev->lock);
1740 if (res_check(fh, RESOURCE_OVERLAY)) {
1741 spin_lock_irqsave(&dev->slock,flags);
1742 stop_preview(dev,fh);
1743 set_tvnorm(dev,&tvnorms[i]);
1744 start_preview(dev,fh);
1745 spin_unlock_irqrestore(&dev->slock,flags);
1746 } else
1747 set_tvnorm(dev,&tvnorms[i]);
1748 saa7134_tvaudio_do_scan(dev);
1749 up(&dev->lock);
1750 return 0;
1751 }
1752
1753 case VIDIOC_CROPCAP:
1754 {
1755 struct v4l2_cropcap *cap = arg;
1756
1757 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1758 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1759 return -EINVAL;
1760 cap->bounds = dev->crop_bounds;
1761 cap->defrect = dev->crop_defrect;
1762 cap->pixelaspect.numerator = 1;
1763 cap->pixelaspect.denominator = 1;
1764 if (dev->tvnorm->id & V4L2_STD_525_60) {
1765 cap->pixelaspect.numerator = 11;
1766 cap->pixelaspect.denominator = 10;
1767 }
1768 if (dev->tvnorm->id & V4L2_STD_625_50) {
1769 cap->pixelaspect.numerator = 54;
1770 cap->pixelaspect.denominator = 59;
1771 }
1772 return 0;
1773 }
1774
1775 case VIDIOC_G_CROP:
1776 {
1777 struct v4l2_crop * crop = arg;
1778
1779 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1780 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1781 return -EINVAL;
1782 crop->c = dev->crop_current;
1783 return 0;
1784 }
1785 case VIDIOC_S_CROP:
1786 {
1787 struct v4l2_crop *crop = arg;
1788 struct v4l2_rect *b = &dev->crop_bounds;
1789
1790 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1791 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1792 return -EINVAL;
1793 if (crop->c.height < 0)
1794 return -EINVAL;
1795 if (crop->c.width < 0)
1796 return -EINVAL;
1797
1798 if (res_locked(fh->dev,RESOURCE_OVERLAY))
1799 return -EBUSY;
1800 if (res_locked(fh->dev,RESOURCE_VIDEO))
1801 return -EBUSY;
1802
1803 if (crop->c.top < b->top)
1804 crop->c.top = b->top;
1805 if (crop->c.top > b->top + b->height)
1806 crop->c.top = b->top + b->height;
1807 if (crop->c.height > b->top - crop->c.top + b->height)
1808 crop->c.height = b->top - crop->c.top + b->height;
1809
1810 if (crop->c.left < b->left)
1811 crop->c.top = b->left;
1812 if (crop->c.left > b->left + b->width)
1813 crop->c.top = b->left + b->width;
1814 if (crop->c.width > b->left - crop->c.left + b->width)
1815 crop->c.width = b->left - crop->c.left + b->width;
1816
1817 dev->crop_current = crop->c;
1818 return 0;
1819 }
1820
1821 /* --- tuner ioctls ------------------------------------------ */
1822 case VIDIOC_G_TUNER:
1823 {
1824 struct v4l2_tuner *t = arg;
1825 int n;
1826
1827 if (0 != t->index)
1828 return -EINVAL;
1829 memset(t,0,sizeof(*t));
1830 for (n = 0; n < SAA7134_INPUT_MAX; n++)
1831 if (card_in(dev,n).tv)
1832 break;
1833 if (NULL != card_in(dev,n).name) {
1834 strcpy(t->name, "Television");
1835 t->capability = V4L2_TUNER_CAP_NORM |
1836 V4L2_TUNER_CAP_STEREO |
1837 V4L2_TUNER_CAP_LANG1 |
1838 V4L2_TUNER_CAP_LANG2;
1839 t->rangehigh = 0xffffffffUL;
1840 t->rxsubchans = saa7134_tvaudio_getstereo(dev);
1841 t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1842 }
1843 if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
1844 t->signal = 0xffff;
1845 return 0;
1846 }
1847 case VIDIOC_S_TUNER:
1848 {
1849 struct v4l2_tuner *t = arg;
1850 int rx,mode;
1851
1852 mode = dev->thread.mode;
1853 if (UNSET == mode) {
1854 rx = saa7134_tvaudio_getstereo(dev);
1855 mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1856 }
1857 if (mode != t->audmode) {
1858 dev->thread.mode = t->audmode;
1859 }
1860 return 0;
1861 }
1862 case VIDIOC_G_FREQUENCY:
1863 {
1864 struct v4l2_frequency *f = arg;
1865
1866 memset(f,0,sizeof(*f));
1867 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1868 f->frequency = dev->ctl_freq;
1869 return 0;
1870 }
1871 case VIDIOC_S_FREQUENCY:
1872 {
1873 struct v4l2_frequency *f = arg;
1874
1875 if (0 != f->tuner)
1876 return -EINVAL;
1877 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1878 return -EINVAL;
1879 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1880 return -EINVAL;
1881 down(&dev->lock);
1882 dev->ctl_freq = f->frequency;
1883#ifdef V4L2_I2C_CLIENTS
1884 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
1885#else
1886 saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
1887#endif
1888 saa7134_tvaudio_do_scan(dev);
1889 up(&dev->lock);
1890 return 0;
1891 }
1892
1893 /* --- control ioctls ---------------------------------------- */
1894 case VIDIOC_ENUMINPUT:
1895 case VIDIOC_G_INPUT:
1896 case VIDIOC_S_INPUT:
1897 case VIDIOC_QUERYCTRL:
1898 case VIDIOC_G_CTRL:
1899 case VIDIOC_S_CTRL:
1900 return saa7134_common_ioctl(dev, cmd, arg);
1901
1902 case VIDIOC_G_AUDIO:
1903 {
1904 struct v4l2_audio *a = arg;
1905
1906 memset(a,0,sizeof(*a));
1907 strcpy(a->name,"audio");
1908 return 0;
1909 }
1910 case VIDIOC_S_AUDIO:
1911 return 0;
1912 case VIDIOC_G_PARM:
1913 {
1914 struct v4l2_captureparm *parm = arg;
1915 memset(parm,0,sizeof(*parm));
1916 return 0;
1917 }
1918
1919 case VIDIOC_G_PRIORITY:
1920 {
1921 enum v4l2_priority *p = arg;
1922
1923 *p = v4l2_prio_max(&dev->prio);
1924 return 0;
1925 }
1926 case VIDIOC_S_PRIORITY:
1927 {
1928 enum v4l2_priority *prio = arg;
1929
1930 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1931 }
1932
1933 /* --- preview ioctls ---------------------------------------- */
1934 case VIDIOC_ENUM_FMT:
1935 {
1936 struct v4l2_fmtdesc *f = arg;
1937 enum v4l2_buf_type type;
1938 unsigned int index;
1939
1940 index = f->index;
1941 type = f->type;
1942 switch (type) {
1943 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1944 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1945 if (index >= FORMATS)
1946 return -EINVAL;
1947 if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1948 formats[index].planar)
1949 return -EINVAL;
1950 memset(f,0,sizeof(*f));
1951 f->index = index;
1952 f->type = type;
1953 strlcpy(f->description,formats[index].name,sizeof(f->description));
1954 f->pixelformat = formats[index].fourcc;
1955 break;
1956 case V4L2_BUF_TYPE_VBI_CAPTURE:
1957 if (0 != index)
1958 return -EINVAL;
1959 memset(f,0,sizeof(*f));
1960 f->index = index;
1961 f->type = type;
1962 f->pixelformat = V4L2_PIX_FMT_GREY;
1963 strcpy(f->description,"vbi data");
1964 break;
1965 default:
1966 return -EINVAL;
1967 }
1968 return 0;
1969 }
1970 case VIDIOC_G_FBUF:
1971 {
1972 struct v4l2_framebuffer *fb = arg;
1973
1974 *fb = dev->ovbuf;
1975 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
1976 return 0;
1977 }
1978 case VIDIOC_S_FBUF:
1979 {
1980 struct v4l2_framebuffer *fb = arg;
1981 struct saa7134_format *fmt;
1982
1983 if(!capable(CAP_SYS_ADMIN) &&
1984 !capable(CAP_SYS_RAWIO))
1985 return -EPERM;
1986
1987 /* check args */
1988 fmt = format_by_fourcc(fb->fmt.pixelformat);
1989 if (NULL == fmt)
1990 return -EINVAL;
1991
1992 /* ok, accept it */
1993 dev->ovbuf = *fb;
1994 dev->ovfmt = fmt;
1995 if (0 == dev->ovbuf.fmt.bytesperline)
1996 dev->ovbuf.fmt.bytesperline =
1997 dev->ovbuf.fmt.width*fmt->depth/8;
1998 return 0;
1999 }
2000 case VIDIOC_OVERLAY:
2001 {
2002 int *on = arg;
2003
2004 if (*on) {
2005 if (!res_get(dev,fh,RESOURCE_OVERLAY))
2006 return -EBUSY;
2007 spin_lock_irqsave(&dev->slock,flags);
2008 start_preview(dev,fh);
2009 spin_unlock_irqrestore(&dev->slock,flags);
2010 }
2011 if (!*on) {
2012 if (!res_check(fh, RESOURCE_OVERLAY))
2013 return -EINVAL;
2014 spin_lock_irqsave(&dev->slock,flags);
2015 stop_preview(dev,fh);
2016 spin_unlock_irqrestore(&dev->slock,flags);
2017 res_free(dev,fh,RESOURCE_OVERLAY);
2018 }
2019 return 0;
2020 }
2021
2022 /* --- capture ioctls ---------------------------------------- */
2023 case VIDIOC_G_FMT:
2024 {
2025 struct v4l2_format *f = arg;
2026 return saa7134_g_fmt(dev,fh,f);
2027 }
2028 case VIDIOC_S_FMT:
2029 {
2030 struct v4l2_format *f = arg;
2031 return saa7134_s_fmt(dev,fh,f);
2032 }
2033 case VIDIOC_TRY_FMT:
2034 {
2035 struct v4l2_format *f = arg;
2036 return saa7134_try_fmt(dev,fh,f);
2037 }
2038
2039 case VIDIOCGMBUF:
2040 {
2041 struct video_mbuf *mbuf = arg;
2042 struct videobuf_queue *q;
2043 struct v4l2_requestbuffers req;
2044 unsigned int i;
2045
2046 q = saa7134_queue(fh);
2047 memset(&req,0,sizeof(req));
2048 req.type = q->type;
2049 req.count = gbuffers;
2050 req.memory = V4L2_MEMORY_MMAP;
2051 err = videobuf_reqbufs(q,&req);
2052 if (err < 0)
2053 return err;
2054 memset(mbuf,0,sizeof(*mbuf));
2055 mbuf->frames = req.count;
2056 mbuf->size = 0;
2057 for (i = 0; i < mbuf->frames; i++) {
2058 mbuf->offsets[i] = q->bufs[i]->boff;
2059 mbuf->size += q->bufs[i]->bsize;
2060 }
2061 return 0;
2062 }
2063 case VIDIOC_REQBUFS:
2064 return videobuf_reqbufs(saa7134_queue(fh),arg);
2065
2066 case VIDIOC_QUERYBUF:
2067 return videobuf_querybuf(saa7134_queue(fh),arg);
2068
2069 case VIDIOC_QBUF:
2070 return videobuf_qbuf(saa7134_queue(fh),arg);
2071
2072 case VIDIOC_DQBUF:
2073 return videobuf_dqbuf(saa7134_queue(fh),arg,
2074 file->f_flags & O_NONBLOCK);
2075
2076 case VIDIOC_STREAMON:
2077 {
2078 int res = saa7134_resource(fh);
2079
2080 if (!res_get(dev,fh,res))
2081 return -EBUSY;
2082 return videobuf_streamon(saa7134_queue(fh));
2083 }
2084 case VIDIOC_STREAMOFF:
2085 {
2086 int res = saa7134_resource(fh);
2087
2088 err = videobuf_streamoff(saa7134_queue(fh));
2089 if (err < 0)
2090 return err;
2091 res_free(dev,fh,res);
2092 return 0;
2093 }
2094
2095 default:
2096 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2097 video_do_ioctl);
2098 }
2099 return 0;
2100}
2101
2102static int video_ioctl(struct inode *inode, struct file *file,
2103 unsigned int cmd, unsigned long arg)
2104{
2105 return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
2106}
2107
2108static int radio_do_ioctl(struct inode *inode, struct file *file,
2109 unsigned int cmd, void *arg)
2110{
2111 struct saa7134_fh *fh = file->private_data;
2112 struct saa7134_dev *dev = fh->dev;
2113
2114 if (video_debug > 1)
2115 saa7134_print_ioctl(dev->name,cmd);
2116 switch (cmd) {
2117 case VIDIOC_QUERYCAP:
2118 {
2119 struct v4l2_capability *cap = arg;
2120
2121 memset(cap,0,sizeof(*cap));
2122 strcpy(cap->driver, "saa7134");
2123 strlcpy(cap->card, saa7134_boards[dev->board].name,
2124 sizeof(cap->card));
2125 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
2126 cap->version = SAA7134_VERSION_CODE;
2127 cap->capabilities = V4L2_CAP_TUNER;
2128 return 0;
2129 }
2130 case VIDIOC_G_TUNER:
2131 {
2132 struct v4l2_tuner *t = arg;
2133
2134 if (0 != t->index)
2135 return -EINVAL;
2136
2137 memset(t,0,sizeof(*t));
2138 strcpy(t->name, "Radio");
2139 t->rangelow = (int)(65*16);
2140 t->rangehigh = (int)(108*16);
2141
2142#ifdef V4L2_I2C_CLIENTS
2143 saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);
2144#else
2145 {
2146 struct video_tuner vt;
2147 memset(&vt,0,sizeof(vt));
2148 saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
2149 t->signal = vt.signal;
2150 }
2151#endif
2152 return 0;
2153 }
2154 case VIDIOC_ENUMINPUT:
2155 {
2156 struct v4l2_input *i = arg;
2157
2158 if (i->index != 0)
2159 return -EINVAL;
2160 strcpy(i->name,"Radio");
2161 i->type = V4L2_INPUT_TYPE_TUNER;
2162 return 0;
2163 }
2164 case VIDIOC_G_INPUT:
2165 {
2166 int *i = arg;
2167 *i = 0;
2168 return 0;
2169 }
2170 case VIDIOC_G_AUDIO:
2171 {
2172 struct v4l2_audio *a = arg;
2173
2174 memset(a,0,sizeof(*a));
2175 strcpy(a->name,"Radio");
2176 return 0;
2177 }
2178 case VIDIOC_G_STD:
2179 {
2180 v4l2_std_id *id = arg;
2181 *id = 0;
2182 return 0;
2183 }
2184 case VIDIOC_S_AUDIO:
2185 case VIDIOC_S_TUNER:
2186 case VIDIOC_S_INPUT:
2187 case VIDIOC_S_STD:
2188 return 0;
2189
2190 case VIDIOC_QUERYCTRL:
2191 {
2192 const struct v4l2_queryctrl *ctrl;
2193 struct v4l2_queryctrl *c = arg;
2194
2195 if (c->id < V4L2_CID_BASE ||
2196 c->id >= V4L2_CID_LASTP1)
2197 return -EINVAL;
2198 if (c->id == V4L2_CID_AUDIO_MUTE) {
2199 ctrl = ctrl_by_id(c->id);
2200 *c = *ctrl;
2201 } else
2202 *c = no_ctrl;
2203 return 0;
2204 }
2205
2206 case VIDIOC_G_CTRL:
2207 case VIDIOC_S_CTRL:
2208 case VIDIOC_G_FREQUENCY:
2209 case VIDIOC_S_FREQUENCY:
2210 return video_do_ioctl(inode,file,cmd,arg);
2211
2212 default:
2213 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2214 radio_do_ioctl);
2215 }
2216 return 0;
2217}
2218
2219static int radio_ioctl(struct inode *inode, struct file *file,
2220 unsigned int cmd, unsigned long arg)
2221{
2222 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
2223}
2224
2225static struct file_operations video_fops =
2226{
2227 .owner = THIS_MODULE,
2228 .open = video_open,
2229 .release = video_release,
2230 .read = video_read,
2231 .poll = video_poll,
2232 .mmap = video_mmap,
2233 .ioctl = video_ioctl,
2234 .llseek = no_llseek,
2235};
2236
2237static struct file_operations radio_fops =
2238{
2239 .owner = THIS_MODULE,
2240 .open = video_open,
2241 .release = video_release,
2242 .ioctl = radio_ioctl,
2243 .llseek = no_llseek,
2244};
2245
2246/* ----------------------------------------------------------- */
2247/* exported stuff */
2248
2249struct video_device saa7134_video_template =
2250{
2251 .name = "saa7134-video",
2252 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2253 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2254 .hardware = 0,
2255 .fops = &video_fops,
2256 .minor = -1,
2257};
2258
2259struct video_device saa7134_vbi_template =
2260{
2261 .name = "saa7134-vbi",
2262 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
2263 .hardware = 0,
2264 .fops = &video_fops,
2265 .minor = -1,
2266};
2267
2268struct video_device saa7134_radio_template =
2269{
2270 .name = "saa7134-radio",
2271 .type = VID_TYPE_TUNER,
2272 .hardware = 0,
2273 .fops = &radio_fops,
2274 .minor = -1,
2275};
2276
2277int saa7134_video_init1(struct saa7134_dev *dev)
2278{
2279 /* sanitycheck insmod options */
2280 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2281 gbuffers = 2;
2282 if (gbufsize < 0 || gbufsize > gbufsize_max)
2283 gbufsize = gbufsize_max;
2284 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
2285
2286 /* put some sensible defaults into the data structures ... */
2287 dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
2288 dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
2289 dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value;
2290 dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
2291 dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
2292 dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
2293 dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
2294 dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
2295
2296 if (dev->tda9887_conf && dev->ctl_automute)
2297 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2298 dev->automute = 0;
2299
2300 INIT_LIST_HEAD(&dev->video_q.queue);
2301 init_timer(&dev->video_q.timeout);
2302 dev->video_q.timeout.function = saa7134_buffer_timeout;
2303 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
2304 dev->video_q.dev = dev;
2305
2306 if (saa7134_boards[dev->board].video_out) {
2307 /* enable video output */
2308 int vo = saa7134_boards[dev->board].video_out;
2309 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2310 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
2311 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2312 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2313 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2314 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
2315 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
2316 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2317 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2318 }
2319
2320 return 0;
2321}
2322
2323int saa7134_video_init2(struct saa7134_dev *dev)
2324{
2325 /* init video hw */
2326 set_tvnorm(dev,&tvnorms[0]);
2327 video_mux(dev,0);
2328 saa7134_tvaudio_setmute(dev);
2329 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
2330 return 0;
2331}
2332
2333int saa7134_video_fini(struct saa7134_dev *dev)
2334{
2335 /* nothing */
2336 return 0;
2337}
2338
2339void saa7134_irq_video_intl(struct saa7134_dev *dev)
2340{
2341 static const char *st[] = {
2342 "(no signal)", "NTSC", "PAL", "SECAM" };
2343 u32 st1,st2;
2344
2345 st1 = saa_readb(SAA7134_STATUS_VIDEO1);
2346 st2 = saa_readb(SAA7134_STATUS_VIDEO2);
2347 dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
2348 (st1 & 0x40) ? "not locked" : "locked",
2349 (st2 & 0x40) ? "no" : "yes",
2350 st[st1 & 0x03]);
2351 dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
2352
2353 if (dev->nosignal) {
2354 /* no video signal -> mute audio */
2355 if (dev->ctl_automute)
2356 dev->automute = 1;
2357 saa7134_tvaudio_setmute(dev);
2358 saa_setb(SAA7134_SYNC_CTRL, 0x20);
2359 } else {
2360 /* wake up tvaudio audio carrier scan thread */
2361 saa7134_tvaudio_do_scan(dev);
2362 if (!noninterlaced)
2363 saa_clearb(SAA7134_SYNC_CTRL, 0x20);
2364 }
2365 if (dev->mops && dev->mops->signal_change)
2366 dev->mops->signal_change(dev);
2367}
2368
2369void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
2370{
2371 enum v4l2_field field;
2372
2373 spin_lock(&dev->slock);
2374 if (dev->video_q.curr) {
2375 dev->video_fieldcount++;
2376 field = dev->video_q.curr->vb.field;
2377 if (V4L2_FIELD_HAS_BOTH(field)) {
2378 /* make sure we have seen both fields */
2379 if ((status & 0x10) == 0x00) {
2380 dev->video_q.curr->top_seen = 1;
2381 goto done;
2382 }
2383 if (!dev->video_q.curr->top_seen)
2384 goto done;
2385 } else if (field == V4L2_FIELD_TOP) {
2386 if ((status & 0x10) != 0x10)
2387 goto done;
2388 } else if (field == V4L2_FIELD_BOTTOM) {
2389 if ((status & 0x10) != 0x00)
2390 goto done;
2391 }
2392 dev->video_q.curr->vb.field_count = dev->video_fieldcount;
2393 saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
2394 }
2395 saa7134_buffer_next(dev,&dev->video_q);
2396
2397 done:
2398 spin_unlock(&dev->slock);
2399}
2400
2401/* ----------------------------------------------------------- */
2402/*
2403 * Local variables:
2404 * c-basic-offset: 8
2405 * End:
2406 */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
new file mode 100644
index 000000000000..ac90a9853236
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -0,0 +1,618 @@
1/*
2 * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
3 *
4 * v4l2 device driver for philips saa7134 based TV cards
5 *
6 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
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#include <linux/version.h>
24#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12)
25
26#include <linux/pci.h>
27#include <linux/i2c.h>
28#include <linux/videodev.h>
29#include <linux/kdev_t.h>
30#include <linux/input.h>
31
32#include <asm/io.h>
33
34#include <media/tuner.h>
35#include <media/audiochip.h>
36#include <media/id.h>
37#include <media/ir-common.h>
38#include <media/video-buf.h>
39#include <media/video-buf-dvb.h>
40
41#ifndef TRUE
42# define TRUE (1==1)
43#endif
44#ifndef FALSE
45# define FALSE (1==0)
46#endif
47#define UNSET (-1U)
48
49/* 2.4 / 2.5 driver compatibility stuff */
50
51/* ----------------------------------------------------------- */
52/* enums */
53
54enum saa7134_tvaudio_mode {
55 TVAUDIO_FM_MONO = 1,
56 TVAUDIO_FM_BG_STEREO = 2,
57 TVAUDIO_FM_SAT_STEREO = 3,
58 TVAUDIO_FM_K_STEREO = 4,
59 TVAUDIO_NICAM_AM = 5,
60 TVAUDIO_NICAM_FM = 6,
61};
62
63enum saa7134_audio_in {
64 TV = 1,
65 LINE1 = 2,
66 LINE2 = 3,
67 LINE2_LEFT,
68};
69
70enum saa7134_video_out {
71 CCIR656 = 1,
72};
73
74/* ----------------------------------------------------------- */
75/* static data */
76
77struct saa7134_tvnorm {
78 char *name;
79 v4l2_std_id id;
80
81 /* video decoder */
82 unsigned int sync_control;
83 unsigned int luma_control;
84 unsigned int chroma_ctrl1;
85 unsigned int chroma_gain;
86 unsigned int chroma_ctrl2;
87 unsigned int vgate_misc;
88
89 /* video scaler */
90 unsigned int h_start;
91 unsigned int h_stop;
92 unsigned int video_v_start;
93 unsigned int video_v_stop;
94 unsigned int vbi_v_start;
95 unsigned int vbi_v_stop;
96 unsigned int src_timing;
97};
98
99struct saa7134_tvaudio {
100 char *name;
101 v4l2_std_id std;
102 enum saa7134_tvaudio_mode mode;
103 int carr1;
104 int carr2;
105};
106
107struct saa7134_format {
108 char *name;
109 unsigned int fourcc;
110 unsigned int depth;
111 unsigned int pm;
112 unsigned int vshift; /* vertical downsampling (for planar yuv) */
113 unsigned int hshift; /* horizontal downsampling (for planar yuv) */
114 unsigned int bswap:1;
115 unsigned int wswap:1;
116 unsigned int yuv:1;
117 unsigned int planar:1;
118 unsigned int uvswap:1;
119};
120
121/* ----------------------------------------------------------- */
122/* card configuration */
123
124#define SAA7134_BOARD_NOAUTO UNSET
125#define SAA7134_BOARD_UNKNOWN 0
126#define SAA7134_BOARD_PROTEUS_PRO 1
127#define SAA7134_BOARD_FLYVIDEO3000 2
128#define SAA7134_BOARD_FLYVIDEO2000 3
129#define SAA7134_BOARD_EMPRESS 4
130#define SAA7134_BOARD_MONSTERTV 5
131#define SAA7134_BOARD_MD9717 6
132#define SAA7134_BOARD_TVSTATION_RDS 7
133#define SAA7134_BOARD_CINERGY400 8
134#define SAA7134_BOARD_MD5044 9
135#define SAA7134_BOARD_KWORLD 10
136#define SAA7134_BOARD_CINERGY600 11
137#define SAA7134_BOARD_MD7134 12
138#define SAA7134_BOARD_TYPHOON_90031 13
139#define SAA7134_BOARD_ELSA 14
140#define SAA7134_BOARD_ELSA_500TV 15
141#define SAA7134_BOARD_ASUSTeK_TVFM7134 16
142#define SAA7134_BOARD_VA1000POWER 17
143#define SAA7134_BOARD_BMK_MPEX_NOTUNER 18
144#define SAA7134_BOARD_VIDEOMATE_TV 19
145#define SAA7134_BOARD_CRONOS_PLUS 20
146#define SAA7134_BOARD_10MOONSTVMASTER 21
147#define SAA7134_BOARD_MD2819 22
148#define SAA7134_BOARD_BMK_MPEX_TUNER 23
149#define SAA7134_BOARD_TVSTATION_DVR 24
150#define SAA7134_BOARD_ASUSTEK_TVFM7133 25
151#define SAA7134_BOARD_PINNACLE_PCTV_STEREO 26
152#define SAA7134_BOARD_MANLI_MTV002 27
153#define SAA7134_BOARD_MANLI_MTV001 28
154#define SAA7134_BOARD_TG3000TV 29
155#define SAA7134_BOARD_ECS_TVP3XP 30
156#define SAA7134_BOARD_ECS_TVP3XP_4CB5 31
157#define SAA7134_BOARD_AVACSSMARTTV 32
158#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
159#define SAA7134_BOARD_NOVAC_PRIMETV7133 34
160#define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
161#define SAA7133_BOARD_UPMOST_PURPLE_TV 36
162#define SAA7134_BOARD_ITEMS_MTV005 37
163#define SAA7134_BOARD_CINERGY200 38
164#define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
165#define SAA7134_BOARD_VIDEOMATE_TV_PVR 40
166#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41
167#define SAA7134_BOARD_SABRENT_SBTTVFM 42
168#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
169#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
170#define SAA7134_BOARD_AVERMEDIA_307 45
171#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
172#define SAA7134_BOARD_CINERGY400_CARDBUS 47
173#define SAA7134_BOARD_CINERGY600_MK3 48
174#define SAA7134_BOARD_VIDEOMATE_GOLD_PLUS 49
175#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
176#define SAA7134_BOARD_PROVIDEO_PV952 51
177#define SAA7134_BOARD_AVERMEDIA_305 52
178#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
179#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
180#define SAA7134_BOARD_FLYDVBTDUO 55
181
182#define SAA7134_MAXBOARDS 8
183#define SAA7134_INPUT_MAX 8
184
185struct saa7134_input {
186 char *name;
187 unsigned int vmux;
188 enum saa7134_audio_in amux;
189 unsigned int gpio;
190 unsigned int tv:1;
191};
192
193enum saa7134_mpeg_type {
194 SAA7134_MPEG_UNUSED,
195 SAA7134_MPEG_EMPRESS,
196 SAA7134_MPEG_DVB,
197};
198
199struct saa7134_board {
200 char *name;
201 unsigned int audio_clock;
202
203 /* input switching */
204 unsigned int gpiomask;
205 struct saa7134_input inputs[SAA7134_INPUT_MAX];
206 struct saa7134_input radio;
207 struct saa7134_input mute;
208
209 /* i2c chip info */
210 unsigned int tuner_type;
211 unsigned int tda9887_conf;
212
213 /* peripheral I/O */
214 enum saa7134_video_out video_out;
215 enum saa7134_mpeg_type mpeg;
216};
217
218#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
219#define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
220#define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
221#define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
222#define card(dev) (saa7134_boards[dev->board])
223#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
224
225/* ----------------------------------------------------------- */
226/* device / file handle status */
227
228#define RESOURCE_OVERLAY 1
229#define RESOURCE_VIDEO 2
230#define RESOURCE_VBI 4
231
232#define INTERLACE_AUTO 0
233#define INTERLACE_ON 1
234#define INTERLACE_OFF 2
235
236#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
237
238struct saa7134_dev;
239struct saa7134_dma;
240
241/* saa7134 page table */
242struct saa7134_pgtable {
243 unsigned int size;
244 u32 *cpu;
245 dma_addr_t dma;
246};
247
248/* tvaudio thread status */
249struct saa7134_thread {
250 pid_t pid;
251 struct completion exit;
252 wait_queue_head_t wq;
253 unsigned int shutdown;
254 unsigned int scan1;
255 unsigned int scan2;
256 unsigned int mode;
257};
258
259/* buffer for one video/vbi/ts frame */
260struct saa7134_buf {
261 /* common v4l buffer stuff -- must be first */
262 struct videobuf_buffer vb;
263
264 /* saa7134 specific */
265 struct saa7134_format *fmt;
266 unsigned int top_seen;
267 int (*activate)(struct saa7134_dev *dev,
268 struct saa7134_buf *buf,
269 struct saa7134_buf *next);
270
271 /* page tables */
272 struct saa7134_pgtable *pt;
273};
274
275struct saa7134_dmaqueue {
276 struct saa7134_dev *dev;
277 struct saa7134_buf *curr;
278 struct list_head queue;
279 struct timer_list timeout;
280 unsigned int need_two;
281};
282
283/* video filehandle status */
284struct saa7134_fh {
285 struct saa7134_dev *dev;
286 unsigned int radio;
287 enum v4l2_buf_type type;
288 unsigned int resources;
289#ifdef VIDIOC_G_PRIORITY
290 enum v4l2_priority prio;
291#endif
292
293 /* video overlay */
294 struct v4l2_window win;
295 struct v4l2_clip clips[8];
296 unsigned int nclips;
297
298 /* video capture */
299 struct saa7134_format *fmt;
300 unsigned int width,height;
301 struct videobuf_queue cap;
302 struct saa7134_pgtable pt_cap;
303
304 /* vbi capture */
305 struct videobuf_queue vbi;
306 struct saa7134_pgtable pt_vbi;
307};
308
309/* oss dsp status */
310struct saa7134_oss {
311 struct semaphore lock;
312 int minor_mixer;
313 int minor_dsp;
314 unsigned int users_dsp;
315
316 /* mixer */
317 enum saa7134_audio_in input;
318 unsigned int count;
319 unsigned int line1;
320 unsigned int line2;
321
322 /* dsp */
323 unsigned int afmt;
324 unsigned int rate;
325 unsigned int channels;
326 unsigned int recording_on;
327 unsigned int dma_running;
328 unsigned int blocks;
329 unsigned int blksize;
330 unsigned int bufsize;
331 struct saa7134_pgtable pt;
332 struct videobuf_dmabuf dma;
333 wait_queue_head_t wq;
334 unsigned int dma_blk;
335 unsigned int read_offset;
336 unsigned int read_count;
337};
338
339/* IR input */
340struct saa7134_ir {
341 struct input_dev dev;
342 struct ir_input_state ir;
343 char name[32];
344 char phys[32];
345 u32 mask_keycode;
346 u32 mask_keydown;
347 u32 mask_keyup;
348 int polling;
349 u32 last_gpio;
350 struct timer_list timer;
351};
352
353/* ts/mpeg status */
354struct saa7134_ts {
355 /* TS capture */
356 struct saa7134_pgtable pt_ts;
357 int nr_packets;
358 int nr_bufs;
359};
360
361/* ts/mpeg ops */
362struct saa7134_mpeg_ops {
363 enum saa7134_mpeg_type type;
364 struct list_head next;
365 int (*init)(struct saa7134_dev *dev);
366 int (*fini)(struct saa7134_dev *dev);
367 void (*signal_change)(struct saa7134_dev *dev);
368};
369
370/* global device status */
371struct saa7134_dev {
372 struct list_head devlist;
373 struct semaphore lock;
374 spinlock_t slock;
375#ifdef VIDIOC_G_PRIORITY
376 struct v4l2_prio_state prio;
377#endif
378
379 /* various device info */
380 unsigned int resources;
381 struct video_device *video_dev;
382 struct video_device *radio_dev;
383 struct video_device *vbi_dev;
384 struct saa7134_oss oss;
385
386 /* infrared remote */
387 int has_remote;
388 struct saa7134_ir *remote;
389
390 /* pci i/o */
391 char name[32];
392 int nr;
393 struct pci_dev *pci;
394 unsigned char pci_rev,pci_lat;
395 __u32 __iomem *lmmio;
396 __u8 __iomem *bmmio;
397
398 /* config info */
399 unsigned int board;
400 unsigned int tuner_type;
401 unsigned int tda9887_conf;
402 unsigned int gpio_value;
403 unsigned int irq2_mask;
404
405 /* i2c i/o */
406 struct i2c_adapter i2c_adap;
407 struct i2c_client i2c_client;
408 unsigned char eedata[64];
409
410 /* video overlay */
411 struct v4l2_framebuffer ovbuf;
412 struct saa7134_format *ovfmt;
413 unsigned int ovenable;
414 enum v4l2_field ovfield;
415
416 /* video+ts+vbi capture */
417 struct saa7134_dmaqueue video_q;
418 struct saa7134_dmaqueue vbi_q;
419 unsigned int video_fieldcount;
420 unsigned int vbi_fieldcount;
421
422 /* various v4l controls */
423 struct saa7134_tvnorm *tvnorm; /* video */
424 struct saa7134_tvaudio *tvaudio;
425 unsigned int ctl_input;
426 int ctl_bright;
427 int ctl_contrast;
428 int ctl_hue;
429 int ctl_saturation;
430 int ctl_freq;
431 int ctl_mute; /* audio */
432 int ctl_volume;
433 int ctl_invert; /* private */
434 int ctl_mirror;
435 int ctl_y_odd;
436 int ctl_y_even;
437 int ctl_automute;
438
439 /* crop */
440 struct v4l2_rect crop_bounds;
441 struct v4l2_rect crop_defrect;
442 struct v4l2_rect crop_current;
443
444 /* other global state info */
445 unsigned int automute;
446 struct saa7134_thread thread;
447 struct saa7134_input *input;
448 struct saa7134_input *hw_input;
449 unsigned int hw_mute;
450 int last_carrier;
451 int nosignal;
452
453 /* SAA7134_MPEG_* */
454 struct saa7134_ts ts;
455 struct saa7134_dmaqueue ts_q;
456 struct saa7134_mpeg_ops *mops;
457
458 /* SAA7134_MPEG_EMPRESS only */
459 struct video_device *empress_dev;
460 struct videobuf_queue empress_tsq;
461 unsigned int empress_users;
462 struct work_struct empress_workqueue;
463 int empress_started;
464
465 /* SAA7134_MPEG_DVB only */
466 struct videobuf_dvb dvb;
467};
468
469/* ----------------------------------------------------------- */
470
471#define saa_readl(reg) readl(dev->lmmio + (reg))
472#define saa_writel(reg,value) writel((value), dev->lmmio + (reg));
473#define saa_andorl(reg,mask,value) \
474 writel((readl(dev->lmmio+(reg)) & ~(mask)) |\
475 ((value) & (mask)), dev->lmmio+(reg))
476#define saa_setl(reg,bit) saa_andorl((reg),(bit),(bit))
477#define saa_clearl(reg,bit) saa_andorl((reg),(bit),0)
478
479#define saa_readb(reg) readb(dev->bmmio + (reg))
480#define saa_writeb(reg,value) writeb((value), dev->bmmio + (reg));
481#define saa_andorb(reg,mask,value) \
482 writeb((readb(dev->bmmio+(reg)) & ~(mask)) |\
483 ((value) & (mask)), dev->bmmio+(reg))
484#define saa_setb(reg,bit) saa_andorb((reg),(bit),(bit))
485#define saa_clearb(reg,bit) saa_andorb((reg),(bit),0)
486
487#define saa_wait(us) { udelay(us); }
488
489/* ----------------------------------------------------------- */
490/* saa7134-core.c */
491
492extern struct list_head saa7134_devlist;
493
494void saa7134_print_ioctl(char *name, unsigned int cmd);
495void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
496
497#define SAA7134_PGTABLE_SIZE 4096
498
499int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
500int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
501 struct scatterlist *list, unsigned int length,
502 unsigned int startpage);
503void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
504
505int saa7134_buffer_count(unsigned int size, unsigned int count);
506int saa7134_buffer_startpage(struct saa7134_buf *buf);
507unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
508
509int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
510 struct saa7134_buf *buf);
511void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
512 unsigned int state);
513void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
514void saa7134_buffer_timeout(unsigned long data);
515void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
516
517int saa7134_set_dmabits(struct saa7134_dev *dev);
518
519/* ----------------------------------------------------------- */
520/* saa7134-cards.c */
521
522extern struct saa7134_board saa7134_boards[];
523extern const unsigned int saa7134_bcount;
524extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
525
526extern int saa7134_board_init1(struct saa7134_dev *dev);
527extern int saa7134_board_init2(struct saa7134_dev *dev);
528
529
530/* ----------------------------------------------------------- */
531/* saa7134-i2c.c */
532
533int saa7134_i2c_register(struct saa7134_dev *dev);
534int saa7134_i2c_unregister(struct saa7134_dev *dev);
535void saa7134_i2c_call_clients(struct saa7134_dev *dev,
536 unsigned int cmd, void *arg);
537
538
539/* ----------------------------------------------------------- */
540/* saa7134-video.c */
541
542extern struct video_device saa7134_video_template;
543extern struct video_device saa7134_radio_template;
544
545int saa7134_common_ioctl(struct saa7134_dev *dev,
546 unsigned int cmd, void *arg);
547
548int saa7134_video_init1(struct saa7134_dev *dev);
549int saa7134_video_init2(struct saa7134_dev *dev);
550int saa7134_video_fini(struct saa7134_dev *dev);
551void saa7134_irq_video_intl(struct saa7134_dev *dev);
552void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
553
554
555/* ----------------------------------------------------------- */
556/* saa7134-ts.c */
557
558#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
559
560extern struct videobuf_queue_ops saa7134_ts_qops;
561
562int saa7134_ts_init1(struct saa7134_dev *dev);
563int saa7134_ts_fini(struct saa7134_dev *dev);
564void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
565
566int saa7134_ts_register(struct saa7134_mpeg_ops *ops);
567void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
568
569/* ----------------------------------------------------------- */
570/* saa7134-vbi.c */
571
572extern struct videobuf_queue_ops saa7134_vbi_qops;
573extern struct video_device saa7134_vbi_template;
574
575int saa7134_vbi_init1(struct saa7134_dev *dev);
576int saa7134_vbi_fini(struct saa7134_dev *dev);
577void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status);
578
579
580/* ----------------------------------------------------------- */
581/* saa7134-tvaudio.c */
582
583int saa7134_tvaudio_rx2mode(u32 rx);
584
585void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
586void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
587 struct saa7134_input *in);
588void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
589int saa7134_tvaudio_getstereo(struct saa7134_dev *dev);
590
591int saa7134_tvaudio_init2(struct saa7134_dev *dev);
592int saa7134_tvaudio_fini(struct saa7134_dev *dev);
593int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
594
595int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
596
597/* ----------------------------------------------------------- */
598/* saa7134-oss.c */
599
600extern struct file_operations saa7134_dsp_fops;
601extern struct file_operations saa7134_mixer_fops;
602
603int saa7134_oss_init1(struct saa7134_dev *dev);
604int saa7134_oss_fini(struct saa7134_dev *dev);
605void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
606
607/* ----------------------------------------------------------- */
608/* saa7134-input.c */
609
610int saa7134_input_init1(struct saa7134_dev *dev);
611void saa7134_input_fini(struct saa7134_dev *dev);
612void saa7134_input_irq(struct saa7134_dev *dev);
613
614/*
615 * Local variables:
616 * c-basic-offset: 8
617 * End:
618 */
diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h
new file mode 100644
index 000000000000..f305ec802ea6
--- /dev/null
+++ b/drivers/media/video/saa7146.h
@@ -0,0 +1,115 @@
1/*
2 saa7146.h - definitions philips saa7146 based cards
3 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __SAA7146__
21#define __SAA7146__
22
23#define SAA7146_VERSION_CODE 0x000101
24
25#include <linux/types.h>
26#include <linux/wait.h>
27
28#include <linux/videodev.h>
29
30#ifndef O_NONCAP
31#define O_NONCAP O_TRUNC
32#endif
33
34#define MAX_GBUFFERS 2
35#define FBUF_SIZE 0x190000
36
37#ifdef __KERNEL__
38
39struct saa7146_window
40{
41 int x, y;
42 ushort width, height;
43 ushort bpp, bpl;
44 ushort swidth, sheight;
45 short cropx, cropy;
46 ushort cropwidth, cropheight;
47 unsigned long vidadr;
48 int color_fmt;
49 ushort depth;
50};
51
52/* Per-open data for handling multiple opens on one device */
53struct device_open
54{
55 int isopen;
56 int noncapturing;
57 struct saa7146 *dev;
58};
59#define MAX_OPENS 3
60
61struct saa7146
62{
63 struct video_device video_dev;
64 struct video_picture picture;
65 struct video_audio audio_dev;
66 struct video_info vidinfo;
67 int user;
68 int cap;
69 int capuser;
70 int irqstate; /* irq routine is state driven */
71 int writemode;
72 int playmode;
73 unsigned int nr;
74 unsigned long irq; /* IRQ used by SAA7146 card */
75 unsigned short id;
76 struct pci_dev *dev;
77 unsigned char revision;
78 unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */
79 unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */
80 struct saa7146_window win;
81 unsigned char __iomem *saa7146_mem; /* pointer to mapped IO memory */
82 struct device_open open_data[MAX_OPENS];
83#define MAX_MARKS 16
84 /* for a/v sync */
85 int endmark[MAX_MARKS], endmarkhead, endmarktail;
86 u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2,
87 *dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out,
88 *pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in,
89 *pagea1out, *pagea2in, *pagea2out;
90 wait_queue_head_t i2cq, debiq, audq, vidq;
91 u8 *vidbuf, *audbuf, *osdbuf, *dmadebi;
92 int audhead, vidhead, osdhead, audtail, vidtail, osdtail;
93 spinlock_t lock; /* the device lock */
94};
95#endif
96
97#ifdef _ALPHA_SAA7146
98#define saawrite(dat,adr) writel((dat), saa->saa7146_adr+(adr))
99#define saaread(adr) readl(saa->saa7146_adr+(adr))
100#else
101#define saawrite(dat,adr) writel((dat), saa->saa7146_mem+(adr))
102#define saaread(adr) readl(saa->saa7146_mem+(adr))
103#endif
104
105#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr)
106#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr)
107#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr)
108
109/* bitmask of attached hardware found */
110#define SAA7146_UNKNOWN 0x00000000
111#define SAA7146_SAA7111 0x00000001
112#define SAA7146_SAA7121 0x00000002
113#define SAA7146_IBMMPEG 0x00000004
114
115#endif
diff --git a/drivers/media/video/saa7146reg.h b/drivers/media/video/saa7146reg.h
new file mode 100644
index 000000000000..6cc910f50a4b
--- /dev/null
+++ b/drivers/media/video/saa7146reg.h
@@ -0,0 +1,283 @@
1/*
2 saa7146.h - definitions philips saa7146 based cards
3 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __SAA7146_REG__
21#define __SAA7146_REG__
22#define SAA7146_BASE_ODD1 0x00
23#define SAA7146_BASE_EVEN1 0x04
24#define SAA7146_PROT_ADDR1 0x08
25#define SAA7146_PITCH1 0x0c
26#define SAA7146_PAGE1 0x10
27#define SAA7146_NUM_LINE_BYTE1 0x14
28#define SAA7146_BASE_ODD2 0x18
29#define SAA7146_BASE_EVEN2 0x1c
30#define SAA7146_PROT_ADDR2 0x20
31#define SAA7146_PITCH2 0x24
32#define SAA7146_PAGE2 0x28
33#define SAA7146_NUM_LINE_BYTE2 0x2c
34#define SAA7146_BASE_ODD3 0x30
35#define SAA7146_BASE_EVEN3 0x34
36#define SAA7146_PROT_ADDR3 0x38
37#define SAA7146_PITCH3 0x3c
38#define SAA7146_PAGE3 0x40
39#define SAA7146_NUM_LINE_BYTE3 0x44
40#define SAA7146_PCI_BT_V1 0x48
41#define SAA7146_PCI_BT_V2 0x49
42#define SAA7146_PCI_BT_V3 0x4a
43#define SAA7146_PCI_BT_DEBI 0x4b
44#define SAA7146_PCI_BT_A 0x4c
45#define SAA7146_DD1_INIT 0x50
46#define SAA7146_DD1_STREAM_B 0x54
47#define SAA7146_DD1_STREAM_A 0x56
48#define SAA7146_BRS_CTRL 0x58
49#define SAA7146_HPS_CTRL 0x5c
50#define SAA7146_HPS_V_SCALE 0x60
51#define SAA7146_HPS_V_GAIN 0x64
52#define SAA7146_HPS_H_PRESCALE 0x68
53#define SAA7146_HPS_H_SCALE 0x6c
54#define SAA7146_BCS_CTRL 0x70
55#define SAA7146_CHROMA_KEY_RANGE 0x74
56#define SAA7146_CLIP_FORMAT_CTRL 0x78
57#define SAA7146_DEBI_CONFIG 0x7c
58#define SAA7146_DEBI_COMMAND 0x80
59#define SAA7146_DEBI_PAGE 0x84
60#define SAA7146_DEBI_AD 0x88
61#define SAA7146_I2C_TRANSFER 0x8c
62#define SAA7146_I2C_STATUS 0x90
63#define SAA7146_BASE_A1_IN 0x94
64#define SAA7146_PROT_A1_IN 0x98
65#define SAA7146_PAGE_A1_IN 0x9C
66#define SAA7146_BASE_A1_OUT 0xa0
67#define SAA7146_PROT_A1_OUT 0xa4
68#define SAA7146_PAGE_A1_OUT 0xa8
69#define SAA7146_BASE_A2_IN 0xac
70#define SAA7146_PROT_A2_IN 0xb0
71#define SAA7146_PAGE_A2_IN 0xb4
72#define SAA7146_BASE_A2_OUT 0xb8
73#define SAA7146_PROT_A2_OUT 0xbc
74#define SAA7146_PAGE_A2_OUT 0xc0
75#define SAA7146_RPS_PAGE0 0xc4
76#define SAA7146_RPS_PAGE1 0xc8
77#define SAA7146_RPS_THRESH0 0xcc
78#define SAA7146_RPS_THRESH1 0xd0
79#define SAA7146_RPS_TOV0 0xd4
80#define SAA7146_RPS_TOV1 0xd8
81#define SAA7146_IER 0xdc
82#define SAA7146_GPIO_CTRL 0xe0
83#define SAA7146_EC1SSR 0xe4
84#define SAA7146_EC2SSR 0xe8
85#define SAA7146_ECT1R 0xec
86#define SAA7146_ECT2R 0xf0
87#define SAA7146_ACON1 0xf4
88#define SAA7146_ACON2 0xf8
89#define SAA7146_MC1 0xfc
90#define SAA7146_MC2 0x100
91#define SAA7146_RPS_ADDR0 0x104
92#define SAA7146_RPS_ADDR1 0x108
93#define SAA7146_ISR 0x10c
94#define SAA7146_PSR 0x110
95#define SAA7146_SSR 0x114
96#define SAA7146_EC1R 0x118
97#define SAA7146_EC2R 0x11c
98#define SAA7146_VDP1 0x120
99#define SAA7146_VDP2 0x124
100#define SAA7146_VDP3 0x128
101#define SAA7146_ADP1 0x12c
102#define SAA7146_ADP2 0x130
103#define SAA7146_ADP3 0x134
104#define SAA7146_ADP4 0x138
105#define SAA7146_DDP 0x13c
106#define SAA7146_LEVEL_REP 0x140
107#define SAA7146_FB_BUFFER1 0x144
108#define SAA7146_FB_BUFFER2 0x148
109#define SAA7146_A_TIME_SLOT1 0x180
110#define SAA7146_A_TIME_SLOT2 0x1C0
111
112/* bitfield defines */
113#define MASK_31 0x80000000
114#define MASK_30 0x40000000
115#define MASK_29 0x20000000
116#define MASK_28 0x10000000
117#define MASK_27 0x08000000
118#define MASK_26 0x04000000
119#define MASK_25 0x02000000
120#define MASK_24 0x01000000
121#define MASK_23 0x00800000
122#define MASK_22 0x00400000
123#define MASK_21 0x00200000
124#define MASK_20 0x00100000
125#define MASK_19 0x00080000
126#define MASK_18 0x00040000
127#define MASK_17 0x00020000
128#define MASK_16 0x00010000
129#define MASK_15 0x00008000
130#define MASK_14 0x00004000
131#define MASK_13 0x00002000
132#define MASK_12 0x00001000
133#define MASK_11 0x00000800
134#define MASK_10 0x00000400
135#define MASK_09 0x00000200
136#define MASK_08 0x00000100
137#define MASK_07 0x00000080
138#define MASK_06 0x00000040
139#define MASK_05 0x00000020
140#define MASK_04 0x00000010
141#define MASK_03 0x00000008
142#define MASK_02 0x00000004
143#define MASK_01 0x00000002
144#define MASK_00 0x00000001
145#define MASK_B0 0x000000ff
146#define MASK_B1 0x0000ff00
147#define MASK_B2 0x00ff0000
148#define MASK_B3 0xff000000
149#define MASK_W0 0x0000ffff
150#define MASK_W1 0xffff0000
151#define MASK_PA 0xfffffffc
152#define MASK_PR 0xfffffffe
153#define MASK_ER 0xffffffff
154#define MASK_NONE 0x00000000
155
156#define SAA7146_PAGE_MAP_EN MASK_11
157/* main control register 1 */
158#define SAA7146_MC1_MRST_N MASK_15
159#define SAA7146_MC1_ERPS1 MASK_13
160#define SAA7146_MC1_ERPS0 MASK_12
161#define SAA7146_MC1_EDP MASK_11
162#define SAA7146_MC1_EVP MASK_10
163#define SAA7146_MC1_EAP MASK_09
164#define SAA7146_MC1_EI2C MASK_08
165#define SAA7146_MC1_TR_E_DEBI MASK_07
166#define SAA7146_MC1_TR_E_1 MASK_06
167#define SAA7146_MC1_TR_E_2 MASK_05
168#define SAA7146_MC1_TR_E_3 MASK_04
169#define SAA7146_MC1_TR_E_A2_OUT MASK_03
170#define SAA7146_MC1_TR_E_A2_IN MASK_02
171#define SAA7146_MC1_TR_E_A1_OUT MASK_01
172#define SAA7146_MC1_TR_E_A1_IN MASK_00
173/* main control register 2 */
174#define SAA7146_MC2_RPS_SIG4 MASK_15
175#define SAA7146_MC2_RPS_SIG3 MASK_14
176#define SAA7146_MC2_RPS_SIG2 MASK_13
177#define SAA7146_MC2_RPS_SIG1 MASK_12
178#define SAA7146_MC2_RPS_SIG0 MASK_11
179#define SAA7146_MC2_UPLD_D1_B MASK_10
180#define SAA7146_MC2_UPLD_D1_A MASK_09
181#define SAA7146_MC2_UPLD_BRS MASK_08
182#define SAA7146_MC2_UPLD_HPS_H MASK_06
183#define SAA7146_MC2_UPLD_HPS_V MASK_05
184#define SAA7146_MC2_UPLD_DMA3 MASK_04
185#define SAA7146_MC2_UPLD_DMA2 MASK_03
186#define SAA7146_MC2_UPLD_DMA1 MASK_02
187#define SAA7146_MC2_UPLD_DEBI MASK_01
188#define SAA7146_MC2_UPLD_I2C MASK_00
189/* Primary Status Register and Interrupt Enable/Status Registers */
190#define SAA7146_PSR_PPEF MASK_31
191#define SAA7146_PSR_PABO MASK_30
192#define SAA7146_PSR_PPED MASK_29
193#define SAA7146_PSR_RPS_I1 MASK_28
194#define SAA7146_PSR_RPS_I0 MASK_27
195#define SAA7146_PSR_RPS_LATE1 MASK_26
196#define SAA7146_PSR_RPS_LATE0 MASK_25
197#define SAA7146_PSR_RPS_E1 MASK_24
198#define SAA7146_PSR_RPS_E0 MASK_23
199#define SAA7146_PSR_RPS_TO1 MASK_22
200#define SAA7146_PSR_RPS_TO0 MASK_21
201#define SAA7146_PSR_UPLD MASK_20
202#define SAA7146_PSR_DEBI_S MASK_19
203#define SAA7146_PSR_DEBI_E MASK_18
204#define SAA7146_PSR_I2C_S MASK_17
205#define SAA7146_PSR_I2C_E MASK_16
206#define SAA7146_PSR_A2_IN MASK_15
207#define SAA7146_PSR_A2_OUT MASK_14
208#define SAA7146_PSR_A1_IN MASK_13
209#define SAA7146_PSR_A1_OUT MASK_12
210#define SAA7146_PSR_AFOU MASK_11
211#define SAA7146_PSR_V_PE MASK_10
212#define SAA7146_PSR_VFOU MASK_09
213#define SAA7146_PSR_FIDA MASK_08
214#define SAA7146_PSR_FIDB MASK_07
215#define SAA7146_PSR_PIN3 MASK_06
216#define SAA7146_PSR_PIN2 MASK_05
217#define SAA7146_PSR_PIN1 MASK_04
218#define SAA7146_PSR_PIN0 MASK_03
219#define SAA7146_PSR_ECS MASK_02
220#define SAA7146_PSR_EC3S MASK_01
221#define SAA7146_PSR_EC0S MASK_00
222/* Secondary Status Register */
223#define SAA7146_SSR_PRQ MASK_31
224#define SAA7146_SSR_PMA MASK_30
225#define SAA7146_SSR_RPS_RE1 MASK_29
226#define SAA7146_SSR_RPS_PE1 MASK_28
227#define SAA7146_SSR_RPS_A1 MASK_27
228#define SAA7146_SSR_RPS_RE0 MASK_26
229#define SAA7146_SSR_RPS_PE0 MASK_25
230#define SAA7146_SSR_RPS_A0 MASK_24
231#define SAA7146_SSR_DEBI_TO MASK_23
232#define SAA7146_SSR_DEBI_EF MASK_22
233#define SAA7146_SSR_I2C_EA MASK_21
234#define SAA7146_SSR_I2C_EW MASK_20
235#define SAA7146_SSR_I2C_ER MASK_19
236#define SAA7146_SSR_I2C_EL MASK_18
237#define SAA7146_SSR_I2C_EF MASK_17
238#define SAA7146_SSR_V3P MASK_16
239#define SAA7146_SSR_V2P MASK_15
240#define SAA7146_SSR_V1P MASK_14
241#define SAA7146_SSR_VF3 MASK_13
242#define SAA7146_SSR_VF2 MASK_12
243#define SAA7146_SSR_VF1 MASK_11
244#define SAA7146_SSR_AF2_IN MASK_10
245#define SAA7146_SSR_AF2_OUT MASK_09
246#define SAA7146_SSR_AF1_IN MASK_08
247#define SAA7146_SSR_AF1_OUT MASK_07
248#define SAA7146_SSR_VGT MASK_05
249#define SAA7146_SSR_LNQG MASK_04
250#define SAA7146_SSR_EC5S MASK_03
251#define SAA7146_SSR_EC4S MASK_02
252#define SAA7146_SSR_EC2S MASK_01
253#define SAA7146_SSR_EC1S MASK_00
254/* I2C status register */
255#define SAA7146_I2C_ABORT MASK_07
256#define SAA7146_I2C_SPERR MASK_06
257#define SAA7146_I2C_APERR MASK_05
258#define SAA7146_I2C_DTERR MASK_04
259#define SAA7146_I2C_DRERR MASK_03
260#define SAA7146_I2C_AL MASK_02
261#define SAA7146_I2C_ERR MASK_01
262#define SAA7146_I2C_BUSY MASK_00
263/* output formats */
264#define SAA7146_YUV422 0
265#define SAA7146_RGB16 0
266#define SAA7146_YUV444 1
267#define SAA7146_RGB24 1
268#define SAA7146_ARGB32 2
269#define SAA7146_YUV411 3
270#define SAA7146_ARGB15 3
271#define SAA7146_YUV2 4
272#define SAA7146_RGAB15 4
273#define SAA7146_Y8 6
274#define SAA7146_YUV8 7
275#define SAA7146_RGB8 7
276#define SAA7146_YUV444p 8
277#define SAA7146_YUV422p 9
278#define SAA7146_YUV420p 10
279#define SAA7146_YUV1620 11
280#define SAA7146_Y1 13
281#define SAA7146_Y2 14
282#define SAA7146_YUV1 15
283#endif
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
new file mode 100644
index 000000000000..5f0b224c3cb6
--- /dev/null
+++ b/drivers/media/video/saa7185.c
@@ -0,0 +1,524 @@
1/*
2 * saa7185 - Philips SAA7185B video encoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 *
6 * Slight changes for video timing and attachment output by
7 * Wolfgang Scherr <scherr@net4you.net>
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/errno.h>
31#include <linux/fs.h>
32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/pci.h>
37#include <linux/signal.h>
38#include <asm/io.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <linux/sched.h>
42#include <asm/segment.h>
43#include <linux/types.h>
44
45#include <linux/videodev.h>
46#include <asm/uaccess.h>
47
48MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
49MODULE_AUTHOR("Dave Perks");
50MODULE_LICENSE("GPL");
51
52#include <linux/i2c.h>
53#include <linux/i2c-dev.h>
54
55#define I2C_NAME(s) (s)->name
56
57#include <linux/video_encoder.h>
58
59static int debug = 0;
60module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
63#define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
68
69/* ----------------------------------------------------------------------- */
70
71struct saa7185 {
72 unsigned char reg[128];
73
74 int norm;
75 int enable;
76 int bright;
77 int contrast;
78 int hue;
79 int sat;
80};
81
82#define I2C_SAA7185 0x88
83
84/* ----------------------------------------------------------------------- */
85
86static inline int
87saa7185_read (struct i2c_client *client)
88{
89 return i2c_smbus_read_byte(client);
90}
91
92static int
93saa7185_write (struct i2c_client *client,
94 u8 reg,
95 u8 value)
96{
97 struct saa7185 *encoder = i2c_get_clientdata(client);
98
99 dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value);
100 encoder->reg[reg] = value;
101 return i2c_smbus_write_byte_data(client, reg, value);
102}
103
104static int
105saa7185_write_block (struct i2c_client *client,
106 const u8 *data,
107 unsigned int len)
108{
109 int ret = -1;
110 u8 reg;
111
112 /* the adv7175 has an autoincrement function, use it if
113 * the adapter understands raw I2C */
114 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
115 /* do raw I2C, not smbus compatible */
116 struct saa7185 *encoder = i2c_get_clientdata(client);
117 struct i2c_msg msg;
118 u8 block_data[32];
119
120 msg.addr = client->addr;
121 msg.flags = 0;
122 while (len >= 2) {
123 msg.buf = (char *) block_data;
124 msg.len = 0;
125 block_data[msg.len++] = reg = data[0];
126 do {
127 block_data[msg.len++] =
128 encoder->reg[reg++] = data[1];
129 len -= 2;
130 data += 2;
131 } while (len >= 2 && data[0] == reg &&
132 msg.len < 32);
133 if ((ret = i2c_transfer(client->adapter,
134 &msg, 1)) < 0)
135 break;
136 }
137 } else {
138 /* do some slow I2C emulation kind of thing */
139 while (len >= 2) {
140 reg = *data++;
141 if ((ret = saa7185_write(client, reg,
142 *data++)) < 0)
143 break;
144 len -= 2;
145 }
146 }
147
148 return ret;
149}
150
151/* ----------------------------------------------------------------------- */
152
153static const unsigned char init_common[] = {
154 0x3a, 0x0f, /* CBENB=0, V656=0, VY2C=1,
155 * YUV2C=1, MY2C=1, MUV2C=1 */
156
157 0x42, 0x6b, /* OVLY0=107 */
158 0x43, 0x00, /* OVLU0=0 white */
159 0x44, 0x00, /* OVLV0=0 */
160 0x45, 0x22, /* OVLY1=34 */
161 0x46, 0xac, /* OVLU1=172 yellow */
162 0x47, 0x0e, /* OVLV1=14 */
163 0x48, 0x03, /* OVLY2=3 */
164 0x49, 0x1d, /* OVLU2=29 cyan */
165 0x4a, 0xac, /* OVLV2=172 */
166 0x4b, 0xf0, /* OVLY3=240 */
167 0x4c, 0xc8, /* OVLU3=200 green */
168 0x4d, 0xb9, /* OVLV3=185 */
169 0x4e, 0xd4, /* OVLY4=212 */
170 0x4f, 0x38, /* OVLU4=56 magenta */
171 0x50, 0x47, /* OVLV4=71 */
172 0x51, 0xc1, /* OVLY5=193 */
173 0x52, 0xe3, /* OVLU5=227 red */
174 0x53, 0x54, /* OVLV5=84 */
175 0x54, 0xa3, /* OVLY6=163 */
176 0x55, 0x54, /* OVLU6=84 blue */
177 0x56, 0xf2, /* OVLV6=242 */
178 0x57, 0x90, /* OVLY7=144 */
179 0x58, 0x00, /* OVLU7=0 black */
180 0x59, 0x00, /* OVLV7=0 */
181
182 0x5a, 0x00, /* CHPS=0 */
183 0x5b, 0x76, /* GAINU=118 */
184 0x5c, 0xa5, /* GAINV=165 */
185 0x5d, 0x3c, /* BLCKL=60 */
186 0x5e, 0x3a, /* BLNNL=58 */
187 0x5f, 0x3a, /* CCRS=0, BLNVB=58 */
188 0x60, 0x00, /* NULL */
189
190 /* 0x61 - 0x66 set according to norm */
191
192 0x67, 0x00, /* 0 : caption 1st byte odd field */
193 0x68, 0x00, /* 0 : caption 2nd byte odd field */
194 0x69, 0x00, /* 0 : caption 1st byte even field */
195 0x6a, 0x00, /* 0 : caption 2nd byte even field */
196
197 0x6b, 0x91, /* MODIN=2, PCREF=0, SCCLN=17 */
198 0x6c, 0x20, /* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0,
199 * CBLF=0, ORCV2=0, PRCV2=0 */
200 0x6d, 0x00, /* SRCM1=0, CCEN=0 */
201
202 0x6e, 0x0e, /* HTRIG=0x005, approx. centered, at
203 * least for PAL */
204 0x6f, 0x00, /* HTRIG upper bits */
205 0x70, 0x20, /* PHRES=0, SBLN=1, VTRIG=0 */
206
207 /* The following should not be needed */
208
209 0x71, 0x15, /* BMRQ=0x115 */
210 0x72, 0x90, /* EMRQ=0x690 */
211 0x73, 0x61, /* EMRQ=0x690, BMRQ=0x115 */
212 0x74, 0x00, /* NULL */
213 0x75, 0x00, /* NULL */
214 0x76, 0x00, /* NULL */
215 0x77, 0x15, /* BRCV=0x115 */
216 0x78, 0x90, /* ERCV=0x690 */
217 0x79, 0x61, /* ERCV=0x690, BRCV=0x115 */
218
219 /* Field length controls */
220
221 0x7a, 0x70, /* FLC=0 */
222
223 /* The following should not be needed if SBLN = 1 */
224
225 0x7b, 0x16, /* FAL=22 */
226 0x7c, 0x35, /* LAL=244 */
227 0x7d, 0x20, /* LAL=244, FAL=22 */
228};
229
230static const unsigned char init_pal[] = {
231 0x61, 0x1e, /* FISE=0, PAL=1, SCBW=1, RTCE=1,
232 * YGS=1, INPI=0, DOWN=0 */
233 0x62, 0xc8, /* DECTYP=1, BSTA=72 */
234 0x63, 0xcb, /* FSC0 */
235 0x64, 0x8a, /* FSC1 */
236 0x65, 0x09, /* FSC2 */
237 0x66, 0x2a, /* FSC3 */
238};
239
240static const unsigned char init_ntsc[] = {
241 0x61, 0x1d, /* FISE=1, PAL=0, SCBW=1, RTCE=1,
242 * YGS=1, INPI=0, DOWN=0 */
243 0x62, 0xe6, /* DECTYP=1, BSTA=102 */
244 0x63, 0x1f, /* FSC0 */
245 0x64, 0x7c, /* FSC1 */
246 0x65, 0xf0, /* FSC2 */
247 0x66, 0x21, /* FSC3 */
248};
249
250static int
251saa7185_command (struct i2c_client *client,
252 unsigned int cmd,
253 void *arg)
254{
255 struct saa7185 *encoder = i2c_get_clientdata(client);
256
257 switch (cmd) {
258
259 case 0:
260 saa7185_write_block(client, init_common,
261 sizeof(init_common));
262 switch (encoder->norm) {
263
264 case VIDEO_MODE_NTSC:
265 saa7185_write_block(client, init_ntsc,
266 sizeof(init_ntsc));
267 break;
268
269 case VIDEO_MODE_PAL:
270 saa7185_write_block(client, init_pal,
271 sizeof(init_pal));
272 break;
273 }
274
275 break;
276
277 case ENCODER_GET_CAPABILITIES:
278 {
279 struct video_encoder_capability *cap = arg;
280
281 cap->flags =
282 VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
283 VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
284 cap->inputs = 1;
285 cap->outputs = 1;
286 }
287 break;
288
289 case ENCODER_SET_NORM:
290 {
291 int *iarg = arg;
292
293 //saa7185_write_block(client, init_common, sizeof(init_common));
294
295 switch (*iarg) {
296
297 case VIDEO_MODE_NTSC:
298 saa7185_write_block(client, init_ntsc,
299 sizeof(init_ntsc));
300 break;
301
302 case VIDEO_MODE_PAL:
303 saa7185_write_block(client, init_pal,
304 sizeof(init_pal));
305 break;
306
307 case VIDEO_MODE_SECAM:
308 default:
309 return -EINVAL;
310
311 }
312 encoder->norm = *iarg;
313 }
314 break;
315
316 case ENCODER_SET_INPUT:
317 {
318 int *iarg = arg;
319
320 /* RJ: *iarg = 0: input is from SA7111
321 *iarg = 1: input is from ZR36060 */
322
323 switch (*iarg) {
324
325 case 0:
326 /* Switch RTCE to 1 */
327 saa7185_write(client, 0x61,
328 (encoder->reg[0x61] & 0xf7) | 0x08);
329 saa7185_write(client, 0x6e, 0x01);
330 break;
331
332 case 1:
333 /* Switch RTCE to 0 */
334 saa7185_write(client, 0x61,
335 (encoder->reg[0x61] & 0xf7) | 0x00);
336 /* SW: a slight sync problem... */
337 saa7185_write(client, 0x6e, 0x00);
338 break;
339
340 default:
341 return -EINVAL;
342
343 }
344 }
345 break;
346
347 case ENCODER_SET_OUTPUT:
348 {
349 int *iarg = arg;
350
351 /* not much choice of outputs */
352 if (*iarg != 0) {
353 return -EINVAL;
354 }
355 }
356 break;
357
358 case ENCODER_ENABLE_OUTPUT:
359 {
360 int *iarg = arg;
361
362 encoder->enable = !!*iarg;
363 saa7185_write(client, 0x61,
364 (encoder->reg[0x61] & 0xbf) |
365 (encoder->enable ? 0x00 : 0x40));
366 }
367 break;
368
369 default:
370 return -EINVAL;
371 }
372
373 return 0;
374}
375
376/* ----------------------------------------------------------------------- */
377
378/*
379 * Generic i2c probe
380 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
381 */
382static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
383static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
384
385static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
386static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
387static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
388static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
389static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
390
391static struct i2c_client_address_data addr_data = {
392 .normal_i2c = normal_i2c,
393 .normal_i2c_range = normal_i2c_range,
394 .probe = probe,
395 .probe_range = probe_range,
396 .ignore = ignore,
397 .ignore_range = ignore_range,
398 .force = force
399};
400
401static struct i2c_driver i2c_driver_saa7185;
402
403static int
404saa7185_detect_client (struct i2c_adapter *adapter,
405 int address,
406 int kind)
407{
408 int i;
409 struct i2c_client *client;
410 struct saa7185 *encoder;
411
412 dprintk(1,
413 KERN_INFO
414 "saa7185.c: detecting saa7185 client on address 0x%x\n",
415 address << 1);
416
417 /* Check if the adapter supports the needed features */
418 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
419 return 0;
420
421 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
422 if (client == 0)
423 return -ENOMEM;
424 memset(client, 0, sizeof(struct i2c_client));
425 client->addr = address;
426 client->adapter = adapter;
427 client->driver = &i2c_driver_saa7185;
428 client->flags = I2C_CLIENT_ALLOW_USE;
429 strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
430
431 encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
432 if (encoder == NULL) {
433 kfree(client);
434 return -ENOMEM;
435 }
436 memset(encoder, 0, sizeof(struct saa7185));
437 encoder->norm = VIDEO_MODE_NTSC;
438 encoder->enable = 1;
439 i2c_set_clientdata(client, encoder);
440
441 i = i2c_attach_client(client);
442 if (i) {
443 kfree(client);
444 kfree(encoder);
445 return i;
446 }
447
448 i = saa7185_write_block(client, init_common, sizeof(init_common));
449 if (i >= 0) {
450 i = saa7185_write_block(client, init_ntsc,
451 sizeof(init_ntsc));
452 }
453 if (i < 0) {
454 dprintk(1, KERN_ERR "%s_attach: init error %d\n",
455 I2C_NAME(client), i);
456 } else {
457 dprintk(1,
458 KERN_INFO
459 "%s_attach: chip version %d at address 0x%x\n",
460 I2C_NAME(client), saa7185_read(client) >> 5,
461 client->addr << 1);
462 }
463
464 return 0;
465}
466
467static int
468saa7185_attach_adapter (struct i2c_adapter *adapter)
469{
470 dprintk(1,
471 KERN_INFO
472 "saa7185.c: starting probe for adapter %s (0x%x)\n",
473 I2C_NAME(adapter), adapter->id);
474 return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
475}
476
477static int
478saa7185_detach_client (struct i2c_client *client)
479{
480 struct saa7185 *encoder = i2c_get_clientdata(client);
481 int err;
482
483 err = i2c_detach_client(client);
484 if (err) {
485 return err;
486 }
487
488 saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
489 //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
490
491 kfree(encoder);
492 kfree(client);
493
494 return 0;
495}
496
497/* ----------------------------------------------------------------------- */
498
499static struct i2c_driver i2c_driver_saa7185 = {
500 .owner = THIS_MODULE,
501 .name = "saa7185", /* name */
502
503 .id = I2C_DRIVERID_SAA7185B,
504 .flags = I2C_DF_NOTIFY,
505
506 .attach_adapter = saa7185_attach_adapter,
507 .detach_client = saa7185_detach_client,
508 .command = saa7185_command,
509};
510
511static int __init
512saa7185_init (void)
513{
514 return i2c_add_driver(&i2c_driver_saa7185);
515}
516
517static void __exit
518saa7185_exit (void)
519{
520 i2c_del_driver(&i2c_driver_saa7185);
521}
522
523module_init(saa7185_init);
524module_exit(saa7185_exit);
diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h
new file mode 100644
index 000000000000..f92f21cfbcac
--- /dev/null
+++ b/drivers/media/video/saa7196.h
@@ -0,0 +1,117 @@
1/*
2 Definitions for the Philips SAA7196 digital video decoder,
3 scaler, and clock generator circuit (DESCpro), as used in
4 the PlanB video input of the Powermac 7x00/8x00 series.
5
6 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
7
8 The register defines are shamelessly copied from the meteor
9 driver out of NetBSD (with permission),
10 and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
11 (Thanks !)
12
13 Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
14
15 The default values used for PlanB are my mistakes.
16*/
17
18/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
19
20#ifndef _SAA7196_H_
21#define _SAA7196_H_
22
23#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/
24#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */
25
26/* Decoder part: */
27#define SAA7196_IDEL 0x00 /* Increment delay */
28#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */
29#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */
30#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */
31#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */
32#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */
33#define SAA7196_LUMC 0x06 /* Luminance control */
34#define SAA7196_HUEC 0x07 /* Hue control */
35#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */
36#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */
37#define SAA7196_PALS 0x0a /* PAL switch sensitivity */
38#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */
39#define SAA7196_CGAINC 0x0c /* Chroma gain control */
40#define SAA7196_STDC 0x0d /* Standard/Mode control */
41#define SAA7196_IOCC 0x0e /* I/O and Clock Control */
42#define SAA7196_CTRL1 0x0f /* Control #1 */
43#define SAA7196_CTRL2 0x10 /* Control #2 */
44#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */
45#define SAA7196_CSAT 0x12 /* Chroma Saturation */
46#define SAA7196_CONT 0x13 /* Luminance Contrast */
47#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */
48#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */
49#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */
50#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */
51#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */
52#define SAA7196_BRIG 0x19 /* Luminance Brightness */
53
54/* Scaler part: */
55#define SAA7196_FMTS 0x20 /* Formats and sequence */
56#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */
57#define SAA7196_INPIX 0x22 /* Input data pixel/line */
58#define SAA7196_HWS 0x23 /* Horiz. window start */
59#define SAA7196_HFILT 0x24 /* Horiz. filter */
60#define SAA7196_OUTLINE 0x25 /* Output data lines/field */
61#define SAA7196_INLINE 0x26 /* Input data lines/field */
62#define SAA7196_VWS 0x27 /* Vertical window start */
63#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */
64#define SAA7196_VBS 0x29 /* Vertical Bypass start */
65#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */
66#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */
67#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */
68#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */
69#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */
70#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */
71#define SAA7196_DPATH 0x30 /* Data path setting */
72
73/* Initialization default values: */
74
75unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = {
76
77/* PAL, 768x576 (no scaling), composite video-in */
78/* Decoder: */
79 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
80 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98,
81 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
82 0xe9, 0xa2,
83/* Padding */
84 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
85/* Scaler: */
86 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
87 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
88 0x87 },
89
90/* NTSC, 640x480? (no scaling), composite video-in */
91/* Decoder: */
92 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00,
93 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98,
94 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2,
95 0xe9, 0x98,
96/* Padding */
97 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
98/* Scaler: */
99 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d,
100 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
101 0x87 },
102
103/* SECAM, 768x576 (no scaling), composite video-in */
104/* Decoder: */
105 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
106 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98,
107 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
108 0xe9, 0xa2,
109/* Padding */
110 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
111/* Scaler: */
112 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
113 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
114 0x87 }
115 };
116
117#endif /* _SAA7196_H_ */
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
new file mode 100644
index 000000000000..b57743571087
--- /dev/null
+++ b/drivers/media/video/stradis.c
@@ -0,0 +1,2258 @@
1/*
2 * stradis.c - stradis 4:2:2 mpeg decoder driver
3 *
4 * Stradis 4:2:2 MPEG-2 Decoder Driver
5 * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
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#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/major.h>
28#include <linux/slab.h>
29#include <linux/mm.h>
30#include <linux/init.h>
31#include <linux/poll.h>
32#include <linux/pci.h>
33#include <linux/signal.h>
34#include <asm/io.h>
35#include <linux/ioport.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/types.h>
40#include <linux/types.h>
41#include <linux/interrupt.h>
42#include <asm/uaccess.h>
43#include <linux/vmalloc.h>
44#include <linux/videodev.h>
45
46#include "saa7146.h"
47#include "saa7146reg.h"
48#include "ibmmpeg2.h"
49#include "saa7121.h"
50#include "cs8420.h"
51
52#define DEBUG(x) /* debug driver */
53#undef IDEBUG /* debug irq handler */
54#undef MDEBUG /* debug memory management */
55
56#define SAA7146_MAX 6
57
58static struct saa7146 saa7146s[SAA7146_MAX];
59
60static int saa_num = 0; /* number of SAA7146s in use */
61
62static int video_nr = -1;
63module_param(video_nr, int, 0);
64MODULE_LICENSE("GPL");
65
66
67#define nDebNormal 0x00480000
68#define nDebNoInc 0x00480000
69#define nDebVideo 0xd0480000
70#define nDebAudio 0xd0400000
71#define nDebDMA 0x02c80000
72
73#define oDebNormal 0x13c80000
74#define oDebNoInc 0x13c80000
75#define oDebVideo 0xd1080000
76#define oDebAudio 0xd1080000
77#define oDebDMA 0x03080000
78
79#define NewCard (saa->boardcfg[3])
80#define ChipControl (saa->boardcfg[1])
81#define NTSCFirstActive (saa->boardcfg[4])
82#define PALFirstActive (saa->boardcfg[5])
83#define NTSCLastActive (saa->boardcfg[54])
84#define PALLastActive (saa->boardcfg[55])
85#define Have2MB (saa->boardcfg[18] & 0x40)
86#define HaveCS8420 (saa->boardcfg[18] & 0x04)
87#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20)
88#define HaveCS3310 (saa->boardcfg[18] & 0x01)
89#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31])
90#define HaveCS4341 (saa->boardcfg[40] == 2)
91#define SDIType (saa->boardcfg[27])
92#define CurrentMode (saa->boardcfg[2])
93
94#define debNormal (NewCard ? nDebNormal : oDebNormal)
95#define debNoInc (NewCard ? nDebNoInc : oDebNoInc)
96#define debVideo (NewCard ? nDebVideo : oDebVideo)
97#define debAudio (NewCard ? nDebAudio : oDebAudio)
98#define debDMA (NewCard ? nDebDMA : oDebDMA)
99
100#ifdef USE_RESCUE_EEPROM_SDM275
101static unsigned char rescue_eeprom[64] = {
1020x00,0x01,0x04,0x13,0x26,0x0f,0x10,0x00,0x00,0x00,0x43,0x63,0x22,0x01,0x29,0x15,0x73,0x00,0x1f, 'd', 'e', 'c', 'x', 'l', 'd', 'v', 'a',0x02,0x00,0x01,0x00,0xcc,0xa4,0x63,0x09,0xe2,0x10,0x00,0x0a,0x00,0x02,0x02, 'd', 'e', 'c', 'x', 'l', 'a',0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103};
104#endif
105
106/* ----------------------------------------------------------------------- */
107/* Hardware I2C functions */
108static void I2CWipe(struct saa7146 *saa)
109{
110 int i;
111 /* set i2c to ~=100kHz, abort transfer, clear busy */
112 saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);
113 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
114 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
115 /* wait for i2c registers to be programmed */
116 for (i = 0; i < 1000 &&
117 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
118 schedule();
119 saawrite(0x600, SAA7146_I2C_STATUS);
120 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
121 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
122 /* wait for i2c registers to be programmed */
123 for (i = 0; i < 1000 &&
124 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
125 schedule();
126 saawrite(0x600, SAA7146_I2C_STATUS);
127 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
128 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
129 /* wait for i2c registers to be programmed */
130 for (i = 0; i < 1000 &&
131 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
132 schedule();
133}
134
135/* read I2C */
136static int I2CRead(struct saa7146 *saa, unsigned char addr,
137 unsigned char subaddr, int dosub)
138{
139 int i;
140
141 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
142 I2CWipe(saa);
143 for (i = 0; i < 1000 &&
144 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
145 schedule();
146 if (i == 1000)
147 I2CWipe(saa);
148 if (dosub)
149 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |
150 ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);
151 else
152 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |
153 0xf1, SAA7146_I2C_TRANSFER);
154 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
155 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
156 /* wait for i2c registers to be programmed */
157 for (i = 0; i < 1000 &&
158 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
159 schedule();
160 /* wait for valid data */
161 for (i = 0; i < 1000 &&
162 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
163 schedule();
164 if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)
165 return -1;
166 if (i == 1000)
167 printk("i2c setup read timeout\n");
168 saawrite(0x41, SAA7146_I2C_TRANSFER);
169 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
170 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
171 /* wait for i2c registers to be programmed */
172 for (i = 0; i < 1000 &&
173 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
174 schedule();
175 /* wait for valid data */
176 for (i = 0; i < 1000 &&
177 (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)
178 schedule();
179 if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)
180 return -1;
181 if (i == 1000)
182 printk("i2c read timeout\n");
183 return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
184}
185
186/* set both to write both bytes, reset it to write only b1 */
187
188static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1,
189 unsigned char b2, int both)
190{
191 int i;
192 u32 data;
193
194 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
195 I2CWipe(saa);
196 for (i = 0; i < 1000 &&
197 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
198 schedule();
199 if (i == 1000)
200 I2CWipe(saa);
201 data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);
202 if (both)
203 data |= ((b2 & 0xff) << 8) | 0xe5;
204 else
205 data |= 0xd1;
206 saawrite(data, SAA7146_I2C_TRANSFER);
207 saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,
208 SAA7146_MC2);
209 return 0;
210}
211
212static void attach_inform(struct saa7146 *saa, int id)
213{
214 int i;
215
216 DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id));
217 if (id == 0xa0) { /* we have rev2 or later board, fill in info */
218 for (i = 0; i < 64; i++)
219 saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1);
220#ifdef USE_RESCUE_EEPROM_SDM275
221 if (saa->boardcfg[0] != 0) {
222 printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr);
223 for (i = 0; i < 64; i++)
224 saa->boardcfg[i] = rescue_eeprom[i];
225 }
226#endif
227 printk("stradis%d: config =", saa->nr);
228 for (i = 0; i < 51; i++) {
229 printk(" %02x",saa->boardcfg[i]);
230 }
231 printk("\n");
232 }
233}
234
235static void I2CBusScan(struct saa7146 *saa)
236{
237 int i;
238 for (i = 0; i < 0xff; i += 2)
239 if ((I2CRead(saa, i, 0, 0)) >= 0)
240 attach_inform(saa, i);
241}
242
243static int debiwait_maxwait = 0;
244
245static int wait_for_debi_done(struct saa7146 *saa)
246{
247 int i;
248
249 /* wait for registers to be programmed */
250 for (i = 0; i < 100000 &&
251 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)
252 saaread(SAA7146_MC2);
253 /* wait for transfer to complete */
254 for (i = 0; i < 500000 &&
255 (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)
256 saaread(SAA7146_MC2);
257 if (i > debiwait_maxwait)
258 printk("wait-for-debi-done maxwait: %d\n",
259 debiwait_maxwait = i);
260
261 if (i == 500000)
262 return -1;
263 return 0;
264}
265
266static int debiwrite(struct saa7146 *saa, u32 config, int addr,
267 u32 val, int count)
268{
269 u32 cmd;
270 if (count <= 0 || count > 32764)
271 return -1;
272 if (wait_for_debi_done(saa) < 0)
273 return -1;
274 saawrite(config, SAA7146_DEBI_CONFIG);
275 if (count <= 4) /* immediate transfer */
276 saawrite(val, SAA7146_DEBI_AD);
277 else /* block transfer */
278 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
279 saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);
280 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
281 SAA7146_MC2);
282 return 0;
283}
284
285static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count)
286{
287 u32 result = 0;
288
289 if (count > 32764 || count <= 0)
290 return 0;
291 if (wait_for_debi_done(saa) < 0)
292 return 0;
293 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
294 saawrite((count << 17) | 0x10000 | (addr & 0xffff),
295 SAA7146_DEBI_COMMAND);
296 saawrite(config, SAA7146_DEBI_CONFIG);
297 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
298 SAA7146_MC2);
299 if (count > 4) /* not an immediate transfer */
300 return count;
301 wait_for_debi_done(saa);
302 result = saaread(SAA7146_DEBI_AD);
303 if (count == 1)
304 result &= 0xff;
305 if (count == 2)
306 result &= 0xffff;
307 if (count == 3)
308 result &= 0xffffff;
309 return result;
310}
311
312#if 0 /* unused */
313/* MUST be a multiple of 8 bytes and 8-byte aligned and < 32768 bytes */
314/* data copied into saa->dmadebi buffer, caller must re-enable interrupts */
315static void ibm_block_dram_read(struct saa7146 *saa, int address, int bytes)
316{
317 int i, j;
318 u32 *buf;
319 buf = (u32 *) saa->dmadebi;
320 if (bytes > 0x7000)
321 bytes = 0x7000;
322 saawrite(0, SAA7146_IER); /* disable interrupts */
323 for (i=0; i < 10000 &&
324 (debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
325 & 0x8000); i++)
326 saaread(SAA7146_MC2);
327 if (i == 10000)
328 printk(KERN_ERR "stradis%d: dram_busy never cleared\n",
329 saa->nr);
330 debiwrite(saa, debNormal, IBM_MP2_SRC_ADDR, (address<<16) |
331 (address>>16), 4);
332 debiwrite(saa, debNormal, IBM_MP2_BLOCK_SIZE, bytes, 2);
333 debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 0x8a10, 2);
334 for (j = 0; j < bytes/4; j++) {
335 for (i = 0; i < 10000 &&
336 (!(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
337 & 0x4000)); i++)
338 saaread(SAA7146_MC2);
339 if (i == 10000)
340 printk(KERN_ERR "stradis%d: dram_ready never set\n",
341 saa->nr);
342 buf[j] = debiread(saa, debNormal, IBM_MP2_DRAM_DATA, 4);
343 }
344}
345#endif /* unused */
346
347static void do_irq_send_data(struct saa7146 *saa)
348{
349 int split, audbytes, vidbytes;
350
351 saawrite(SAA7146_PSR_PIN1, SAA7146_IER);
352 /* if special feature mode in effect, disable audio sending */
353 if (saa->playmode != VID_PLAY_NORMAL)
354 saa->audtail = saa->audhead = 0;
355 if (saa->audhead <= saa->audtail)
356 audbytes = saa->audtail - saa->audhead;
357 else
358 audbytes = 65536 - (saa->audhead - saa->audtail);
359 if (saa->vidhead <= saa->vidtail)
360 vidbytes = saa->vidtail - saa->vidhead;
361 else
362 vidbytes = 524288 - (saa->vidhead - saa->vidtail);
363 if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {
364 saawrite(0, SAA7146_IER);
365 return;
366 }
367 /* if at least 1 block audio waiting and audio fifo isn't full */
368 if (audbytes >= 2048 && (debiread(saa, debNormal,
369 IBM_MP2_AUD_FIFO, 2) & 0xff) < 60) {
370 if (saa->audhead > saa->audtail)
371 split = 65536 - saa->audhead;
372 else
373 split = 0;
374 audbytes = 2048;
375 if (split > 0 && split < 2048) {
376 memcpy(saa->dmadebi, saa->audbuf + saa->audhead,
377 split);
378 saa->audhead = 0;
379 audbytes -= split;
380 } else
381 split = 0;
382 memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,
383 audbytes);
384 saa->audhead += audbytes;
385 saa->audhead &= 0xffff;
386 debiwrite(saa, debAudio, (NewCard? IBM_MP2_AUD_FIFO :
387 IBM_MP2_AUD_FIFOW), 0, 2048);
388 wake_up_interruptible(&saa->audq);
389 /* if at least 1 block video waiting and video fifo isn't full */
390 } else if (vidbytes >= 30720 && (debiread(saa, debNormal,
391 IBM_MP2_FIFO, 2)) < 16384) {
392 if (saa->vidhead > saa->vidtail)
393 split = 524288 - saa->vidhead;
394 else
395 split = 0;
396 vidbytes = 30720;
397 if (split > 0 && split < 30720) {
398 memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead,
399 split);
400 saa->vidhead = 0;
401 vidbytes -= split;
402 } else
403 split = 0;
404 memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead,
405 vidbytes);
406 saa->vidhead += vidbytes;
407 saa->vidhead &= 0x7ffff;
408 debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO :
409 IBM_MP2_FIFOW), 0, 30720);
410 wake_up_interruptible(&saa->vidq);
411 }
412 saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);
413}
414
415static void send_osd_data(struct saa7146 *saa)
416{
417 int size = saa->osdtail - saa->osdhead;
418 if (size > 30720)
419 size = 30720;
420 /* ensure some multiple of 8 bytes is transferred */
421 size = 8 * ((size + 8)>>3);
422 if (size) {
423 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR,
424 (saa->osdhead>>3), 2);
425 memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size);
426 saa->osdhead += size;
427 /* block transfer of next 8 bytes to ~32k bytes */
428 debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size);
429 }
430 if (saa->osdhead >= saa->osdtail) {
431 saa->osdhead = saa->osdtail = 0;
432 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
433 }
434}
435
436static irqreturn_t saa7146_irq(int irq, void *dev_id, struct pt_regs *regs)
437{
438 struct saa7146 *saa = (struct saa7146 *) dev_id;
439 u32 stat, astat;
440 int count;
441 int handled = 0;
442
443 count = 0;
444 while (1) {
445 /* get/clear interrupt status bits */
446 stat = saaread(SAA7146_ISR);
447 astat = stat & saaread(SAA7146_IER);
448 if (!astat)
449 break;
450 handled = 1;
451 saawrite(astat, SAA7146_ISR);
452 if (astat & SAA7146_PSR_DEBI_S) {
453 do_irq_send_data(saa);
454 }
455 if (astat & SAA7146_PSR_PIN1) {
456 int istat;
457 /* the following read will trigger DEBI_S */
458 istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
459 if (istat & 1) {
460 saawrite(0, SAA7146_IER);
461 send_osd_data(saa);
462 saawrite(SAA7146_PSR_DEBI_S |
463 SAA7146_PSR_PIN1, SAA7146_IER);
464 }
465 if (istat & 0x20) { /* Video Start */
466 saa->vidinfo.frame_count++;
467 }
468 if (istat & 0x400) { /* Picture Start */
469 /* update temporal reference */
470 }
471 if (istat & 0x200) { /* Picture Resolution Change */
472 /* read new resolution */
473 }
474 if (istat & 0x100) { /* New User Data found */
475 /* read new user data */
476 }
477 if (istat & 0x1000) { /* new GOP/SMPTE */
478 /* read new SMPTE */
479 }
480 if (istat & 0x8000) { /* Sequence Start Code */
481 /* reset frame counter, load sizes */
482 saa->vidinfo.frame_count = 0;
483 saa->vidinfo.h_size = 704;
484 saa->vidinfo.v_size = 480;
485#if 0
486 if (saa->endmarkhead != saa->endmarktail) {
487 saa->audhead =
488 saa->endmark[saa->endmarkhead];
489 saa->endmarkhead++;
490 if (saa->endmarkhead >= MAX_MARKS)
491 saa->endmarkhead = 0;
492 }
493#endif
494 }
495 if (istat & 0x4000) { /* Sequence Error Code */
496 if (saa->endmarkhead != saa->endmarktail) {
497 saa->audhead =
498 saa->endmark[saa->endmarkhead];
499 saa->endmarkhead++;
500 if (saa->endmarkhead >= MAX_MARKS)
501 saa->endmarkhead = 0;
502 }
503 }
504 }
505#ifdef IDEBUG
506 if (astat & SAA7146_PSR_PPEF) {
507 IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr));
508 }
509 if (astat & SAA7146_PSR_PABO) {
510 IDEBUG(printk("stradis%d irq: PABO\n", saa->nr));
511 }
512 if (astat & SAA7146_PSR_PPED) {
513 IDEBUG(printk("stradis%d irq: PPED\n", saa->nr));
514 }
515 if (astat & SAA7146_PSR_RPS_I1) {
516 IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr));
517 }
518 if (astat & SAA7146_PSR_RPS_I0) {
519 IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr));
520 }
521 if (astat & SAA7146_PSR_RPS_LATE1) {
522 IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr));
523 }
524 if (astat & SAA7146_PSR_RPS_LATE0) {
525 IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr));
526 }
527 if (astat & SAA7146_PSR_RPS_E1) {
528 IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr));
529 }
530 if (astat & SAA7146_PSR_RPS_E0) {
531 IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr));
532 }
533 if (astat & SAA7146_PSR_RPS_TO1) {
534 IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr));
535 }
536 if (astat & SAA7146_PSR_RPS_TO0) {
537 IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr));
538 }
539 if (astat & SAA7146_PSR_UPLD) {
540 IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr));
541 }
542 if (astat & SAA7146_PSR_DEBI_E) {
543 IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr));
544 }
545 if (astat & SAA7146_PSR_I2C_S) {
546 IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr));
547 }
548 if (astat & SAA7146_PSR_I2C_E) {
549 IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr));
550 }
551 if (astat & SAA7146_PSR_A2_IN) {
552 IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr));
553 }
554 if (astat & SAA7146_PSR_A2_OUT) {
555 IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr));
556 }
557 if (astat & SAA7146_PSR_A1_IN) {
558 IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr));
559 }
560 if (astat & SAA7146_PSR_A1_OUT) {
561 IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr));
562 }
563 if (astat & SAA7146_PSR_AFOU) {
564 IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr));
565 }
566 if (astat & SAA7146_PSR_V_PE) {
567 IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr));
568 }
569 if (astat & SAA7146_PSR_VFOU) {
570 IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr));
571 }
572 if (astat & SAA7146_PSR_FIDA) {
573 IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr));
574 }
575 if (astat & SAA7146_PSR_FIDB) {
576 IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr));
577 }
578 if (astat & SAA7146_PSR_PIN3) {
579 IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr));
580 }
581 if (astat & SAA7146_PSR_PIN2) {
582 IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr));
583 }
584 if (astat & SAA7146_PSR_PIN0) {
585 IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr));
586 }
587 if (astat & SAA7146_PSR_ECS) {
588 IDEBUG(printk("stradis%d irq: ECS\n", saa->nr));
589 }
590 if (astat & SAA7146_PSR_EC3S) {
591 IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr));
592 }
593 if (astat & SAA7146_PSR_EC0S) {
594 IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr));
595 }
596#endif
597 count++;
598 if (count > 15)
599 printk(KERN_WARNING "stradis%d: irq loop %d\n",
600 saa->nr, count);
601 if (count > 20) {
602 saawrite(0, SAA7146_IER);
603 printk(KERN_ERR
604 "stradis%d: IRQ loop cleared\n", saa->nr);
605 }
606 }
607 return IRQ_RETVAL(handled);
608}
609
610static int ibm_send_command(struct saa7146 *saa,
611 int command, int data, int chain)
612{
613 int i;
614
615 if (chain)
616 debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1) | 1, 2);
617 else
618 debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2);
619 debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2);
620 debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2);
621 for (i = 0; i < 100 &&
622 (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++)
623 schedule();
624 if (i == 100)
625 return -1;
626 return 0;
627}
628
629static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
630{
631 I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2);
632 I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2);
633}
634
635static void initialize_cs4341(struct saa7146 *saa)
636{
637 int i;
638 for (i = 0; i < 200; i++) {
639 /* auto mute off, power on, no de-emphasis */
640 /* I2S data up to 24-bit 64xFs internal SCLK */
641 I2CWrite(saa, 0x22, 0x01, 0x11, 2);
642 /* ATAPI mixer settings */
643 I2CWrite(saa, 0x22, 0x02, 0x49, 2);
644 /* attenuation left 3db */
645 I2CWrite(saa, 0x22, 0x03, 0x00, 2);
646 /* attenuation right 3db */
647 I2CWrite(saa, 0x22, 0x04, 0x00, 2);
648 I2CWrite(saa, 0x22, 0x01, 0x10, 2);
649 if (I2CRead(saa, 0x22, 0x02, 1) == 0x49)
650 break;
651 schedule();
652 }
653 printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i);
654 return;
655}
656
657static void initialize_cs8420(struct saa7146 *saa, int pro)
658{
659 int i;
660 u8 *sequence;
661 if (pro)
662 sequence = mode8420pro;
663 else
664 sequence = mode8420con;
665 for (i = 0; i < INIT8420LEN; i++)
666 I2CWrite(saa, 0x20, init8420[i * 2],
667 init8420[i * 2 + 1], 2);
668 for (i = 0; i < MODE8420LEN; i++)
669 I2CWrite(saa, 0x20, sequence[i * 2],
670 sequence[i * 2 + 1], 2);
671 printk("stradis%d: CS8420 initialized\n", saa->nr);
672}
673
674static void initialize_saa7121(struct saa7146 *saa, int dopal)
675{
676 int i, mod;
677 u8 *sequence;
678 if (dopal)
679 sequence = init7121pal;
680 else
681 sequence = init7121ntsc;
682 mod = saaread(SAA7146_PSR) & 0x08;
683 /* initialize PAL/NTSC video encoder */
684 for (i = 0; i < INIT7121LEN; i++) {
685 if (NewCard) { /* handle new card encoder differences */
686 if (sequence[i*2] == 0x3a)
687 I2CWrite(saa, 0x88, 0x3a, 0x13, 2);
688 else if (sequence[i*2] == 0x6b)
689 I2CWrite(saa, 0x88, 0x6b, 0x20, 2);
690 else if (sequence[i*2] == 0x6c)
691 I2CWrite(saa, 0x88, 0x6c,
692 dopal ? 0x09 : 0xf5, 2);
693 else if (sequence[i*2] == 0x6d)
694 I2CWrite(saa, 0x88, 0x6d,
695 dopal ? 0x20 : 0x00, 2);
696 else if (sequence[i*2] == 0x7a)
697 I2CWrite(saa, 0x88, 0x7a,
698 dopal ? (PALFirstActive - 1) :
699 (NTSCFirstActive - 4), 2);
700 else if (sequence[i*2] == 0x7b)
701 I2CWrite(saa, 0x88, 0x7b,
702 dopal ? PALLastActive :
703 NTSCLastActive, 2);
704 else I2CWrite(saa, 0x88, sequence[i * 2],
705 sequence[i * 2 + 1], 2);
706 } else {
707 if (sequence[i*2] == 0x6b && mod)
708 I2CWrite(saa, 0x88, 0x6b,
709 (sequence[i * 2 + 1] ^ 0x09), 2);
710 else if (sequence[i*2] == 0x7a)
711 I2CWrite(saa, 0x88, 0x7a,
712 dopal ? (PALFirstActive - 1) :
713 (NTSCFirstActive - 4), 2);
714 else if (sequence[i*2] == 0x7b)
715 I2CWrite(saa, 0x88, 0x7b,
716 dopal ? PALLastActive :
717 NTSCLastActive, 2);
718 else
719 I2CWrite(saa, 0x88, sequence[i * 2],
720 sequence[i * 2 + 1], 2);
721 }
722 }
723}
724
725static void set_genlock_offset(struct saa7146 *saa, int noffset)
726{
727 int nCode;
728 int PixelsPerLine = 858;
729 if (CurrentMode == VIDEO_MODE_PAL)
730 PixelsPerLine = 864;
731 if (noffset > 500)
732 noffset = 500;
733 else if (noffset < -500)
734 noffset = -500;
735 nCode = noffset + 0x100;
736 if (nCode == 1)
737 nCode = 0x401;
738 else if (nCode < 1) nCode = 0x400 + PixelsPerLine + nCode;
739 debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);
740}
741
742static void set_out_format(struct saa7146 *saa, int mode)
743{
744 initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1));
745 saa->boardcfg[2] = mode;
746 /* do not adjust analog video parameters here, use saa7121 init */
747 /* you will affect the SDI output on the new card */
748 if (mode == VIDEO_MODE_PAL) { /* PAL */
749 debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2);
750 mdelay(50);
751 saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1);
752 if (NewCard) {
753 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
754 0xe100, 2);
755 mdelay(50);
756 }
757 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
758 NewCard ? 0xe500: 0x6500, 2);
759 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
760 (1 << 8) |
761 (NewCard ? PALFirstActive : PALFirstActive-6), 2);
762 } else { /* NTSC */
763 debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2);
764 mdelay(50);
765 saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1);
766 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
767 NewCard ? 0xe100: 0x6100, 2);
768 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
769 (1 << 8) |
770 (NewCard ? NTSCFirstActive : NTSCFirstActive-6), 2);
771 }
772}
773
774
775/* Intialize bitmangler to map from a byte value to the mangled word that
776 * must be output to program the Xilinx part through the DEBI port.
777 * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0
778 * transfer FPGA code, init IBM chip, transfer IBM microcode
779 * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0
780 */
781static u16 bitmangler[256];
782
783static int initialize_fpga(struct video_code *bitdata)
784{
785 int i, num, startindex, failure = 0, loadtwo, loadfile = 0;
786 u16 *dmabuf;
787 u8 *newdma;
788 struct saa7146 *saa;
789
790 /* verify fpga code */
791 for (startindex = 0; startindex < bitdata->datasize; startindex++)
792 if (bitdata->data[startindex] == 255)
793 break;
794 if (startindex == bitdata->datasize) {
795 printk(KERN_INFO "stradis: bad fpga code\n");
796 return -1;
797 }
798 /* initialize all detected cards */
799 for (num = 0; num < saa_num; num++) {
800 saa = &saa7146s[num];
801 if (saa->boardcfg[0] > 20)
802 continue; /* card was programmed */
803 loadtwo = (saa->boardcfg[18] & 0x10);
804 if (!NewCard) /* we have an old board */
805 for (i = 0; i < 256; i++)
806 bitmangler[i] = ((i & 0x01) << 15) |
807 ((i & 0x02) << 6) | ((i & 0x04) << 4) |
808 ((i & 0x08) << 9) | ((i & 0x10) << 7) |
809 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
810 ((i & 0x80) >> 7);
811 else /* else we have a new board */
812 for (i = 0; i < 256; i++)
813 bitmangler[i] = ((i & 0x01) << 7) |
814 ((i & 0x02) << 5) | ((i & 0x04) << 3) |
815 ((i & 0x08) << 1) | ((i & 0x10) >> 1) |
816 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
817 ((i & 0x80) >> 7);
818
819 dmabuf = (u16 *) saa->dmadebi;
820 newdma = (u8 *) saa->dmadebi;
821 if (NewCard) { /* SDM2xxx */
822 if (!strncmp(bitdata->loadwhat, "decoder2", 8))
823 continue; /* fpga not for this card */
824 if (!strncmp(&saa->boardcfg[42],
825 bitdata->loadwhat, 8)) {
826 loadfile = 1;
827 } else if (loadtwo && !strncmp(&saa->boardcfg[19],
828 bitdata->loadwhat, 8)) {
829 loadfile = 2;
830 } else if (!saa->boardcfg[42] && /* special */
831 !strncmp("decxl", bitdata->loadwhat, 8)) {
832 loadfile = 1;
833 } else
834 continue; /* fpga not for this card */
835 if (loadfile != 1 && loadfile != 2) {
836 continue; /* skip to next card */
837 }
838 if (saa->boardcfg[0] && loadfile == 1 )
839 continue; /* skip to next card */
840 if (saa->boardcfg[0] != 1 && loadfile == 2)
841 continue; /* skip to next card */
842 saa->boardcfg[0]++; /* mark fpga handled */
843 printk("stradis%d: loading %s\n", saa->nr,
844 bitdata->loadwhat);
845 if (loadtwo && loadfile == 2)
846 goto send_fpga_stuff;
847 /* turn on the Audio interface to set PROG low */
848 saawrite(0x00400040, SAA7146_GPIO_CTRL);
849 saaread(SAA7146_PSR); /* ensure posted write */
850 /* wait for everyone to reset */
851 mdelay(10);
852 saawrite(0x00400000, SAA7146_GPIO_CTRL);
853 } else { /* original card */
854 if (strncmp(bitdata->loadwhat, "decoder2", 8))
855 continue; /* fpga not for this card */
856 /* Pull the Xilinx PROG signal WS3 low */
857 saawrite(0x02000200, SAA7146_MC1);
858 /* Turn on the Audio interface so can set PROG low */
859 saawrite(0x000000c0, SAA7146_ACON1);
860 /* Pull the Xilinx INIT signal (GPIO2) low */
861 saawrite(0x00400000, SAA7146_GPIO_CTRL);
862 /* Make sure everybody resets */
863 saaread(SAA7146_PSR); /* ensure posted write */
864 mdelay(10);
865 /* Release the Xilinx PROG signal */
866 saawrite(0x00000000, SAA7146_ACON1);
867 /* Turn off the Audio interface */
868 saawrite(0x02000000, SAA7146_MC1);
869 }
870 /* Release Xilinx INIT signal (WS2) */
871 saawrite(0x00000000, SAA7146_GPIO_CTRL);
872 /* Wait for the INIT to go High */
873 for (i = 0; i < 10000 &&
874 !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
875 schedule();
876 if (i == 1000) {
877 printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr);
878 return -1;
879 }
880send_fpga_stuff:
881 if (NewCard) {
882 for (i = startindex; i < bitdata->datasize; i++)
883 newdma[i - startindex] =
884 bitmangler[bitdata->data[i]];
885 debiwrite(saa, 0x01420000, 0, 0,
886 ((bitdata->datasize - startindex) + 5));
887 if (loadtwo) {
888 if (loadfile == 1) {
889 printk("stradis%d: "
890 "awaiting 2nd FPGA bitfile\n",
891 saa->nr);
892 continue; /* skip to next card */
893 }
894
895 }
896 } else {
897 for (i = startindex; i < bitdata->datasize; i++)
898 dmabuf[i - startindex] =
899 bitmangler[bitdata->data[i]];
900 debiwrite(saa, 0x014a0000, 0, 0,
901 ((bitdata->datasize - startindex) + 5) * 2);
902 }
903 for (i = 0; i < 1000 &&
904 !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
905 schedule();
906 if (i == 1000) {
907 printk(KERN_INFO "stradis%d: FPGA load failed\n",
908 saa->nr);
909 failure++;
910 continue;
911 }
912 if (!NewCard) {
913 /* Pull the Xilinx INIT signal (GPIO2) low */
914 saawrite(0x00400000, SAA7146_GPIO_CTRL);
915 saaread(SAA7146_PSR); /* ensure posted write */
916 mdelay(2);
917 saawrite(0x00000000, SAA7146_GPIO_CTRL);
918 mdelay(2);
919 }
920 printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr);
921 saa->boardcfg[0] = 26; /* mark fpga programmed */
922 /* set VXCO to its lowest frequency */
923 debiwrite(saa, debNormal, XILINX_PWM, 0, 2);
924 if (NewCard) {
925 /* mute CS3310 */
926 if (HaveCS3310)
927 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
928 0, 2);
929 /* set VXCO to PWM mode, release reset, blank on */
930 debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2);
931 mdelay(10);
932 /* unmute CS3310 */
933 if (HaveCS3310)
934 debiwrite(saa, debNormal, XILINX_CTL0,
935 0x2020, 2);
936 }
937 /* set source Black */
938 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
939 saa->boardcfg[4] = 22; /* set NTSC First Active Line */
940 saa->boardcfg[5] = 23; /* set PAL First Active Line */
941 saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */
942 saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */
943 set_out_format(saa, VIDEO_MODE_NTSC);
944 mdelay(50);
945 /* begin IBM chip init */
946 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
947 saaread(SAA7146_PSR); /* wait for reset */
948 mdelay(5);
949 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
950 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
951 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2);
952 debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2);
953 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
954 if (NewCard) {
955 mdelay(5);
956 /* set i2s rate converter to 48KHz */
957 debiwrite(saa, debNormal, 0x80c0, 6, 2);
958 /* we must init CS8420 first since rev b pulls i2s */
959 /* master clock low and CS4341 needs i2s master to */
960 /* run the i2c port. */
961 if (HaveCS8420) {
962 /* 0=consumer, 1=pro */
963 initialize_cs8420(saa, 0);
964 }
965 mdelay(5);
966 if (HaveCS4341)
967 initialize_cs4341(saa);
968 }
969 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
970 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
971 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
972 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
973 if (NewCard)
974 set_genlock_offset(saa, 0);
975 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
976#if 0
977 /* enable genlock */
978 debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);
979#else
980 /* disable genlock */
981 debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);
982#endif
983 }
984 return failure;
985}
986
987static int do_ibm_reset(struct saa7146 *saa)
988{
989 /* failure if decoder not previously programmed */
990 if (saa->boardcfg[0] < 37)
991 return -EIO;
992 /* mute CS3310 */
993 if (HaveCS3310)
994 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2);
995 /* disable interrupts */
996 saawrite(0, SAA7146_IER);
997 saa->audhead = saa->audtail = 0;
998 saa->vidhead = saa->vidtail = 0;
999 /* tristate debi bus, disable debi transfers */
1000 saawrite(0x00880000, SAA7146_MC1);
1001 /* ensure posted write */
1002 saaread(SAA7146_MC1);
1003 mdelay(50);
1004 /* re-enable debi transfers */
1005 saawrite(0x00880088, SAA7146_MC1);
1006 /* set source Black */
1007 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
1008 /* begin IBM chip init */
1009 set_out_format(saa, CurrentMode);
1010 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
1011 saaread(SAA7146_PSR); /* wait for reset */
1012 mdelay(5);
1013 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
1014 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
1015 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1016 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
1017 if (NewCard) {
1018 mdelay(5);
1019 /* set i2s rate converter to 48KHz */
1020 debiwrite(saa, debNormal, 0x80c0, 6, 2);
1021 /* we must init CS8420 first since rev b pulls i2s */
1022 /* master clock low and CS4341 needs i2s master to */
1023 /* run the i2c port. */
1024 if (HaveCS8420) {
1025 /* 0=consumer, 1=pro */
1026 initialize_cs8420(saa, 1);
1027 }
1028 mdelay(5);
1029 if (HaveCS4341)
1030 initialize_cs4341(saa);
1031 }
1032 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
1033 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
1034 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
1035 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
1036 if (NewCard)
1037 set_genlock_offset(saa, 0);
1038 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
1039 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1040 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1041 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1042 (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) {
1043 printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr);
1044 }
1045 if (HaveCS3310) {
1046 int i = CS3310MaxLvl;
1047 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
1048 }
1049 /* start video decoder */
1050 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1051 /* 256k vid, 3520 bytes aud */
1052 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2);
1053 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1054 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1055 /* enable buffer threshold irq */
1056 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1057 /* clear pending interrupts */
1058 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1059 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1060 return 0;
1061}
1062
1063/* load the decoder microcode */
1064static int initialize_ibmmpeg2(struct video_code *microcode)
1065{
1066 int i, num;
1067 struct saa7146 *saa;
1068
1069 for (num = 0; num < saa_num; num++) {
1070 saa = &saa7146s[num];
1071 /* check that FPGA is loaded */
1072 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2);
1073 if ((i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2)) !=
1074 0xa55a) {
1075 printk(KERN_INFO "stradis%d: %04x != 0xa55a\n",
1076 saa->nr, i);
1077#if 0
1078 return -1;
1079#endif
1080 }
1081 if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) {
1082 if (saa->boardcfg[0] > 27)
1083 continue; /* skip to next card */
1084 /* load video control store */
1085 saa->boardcfg[1] = 0x13; /* no-sync default */
1086 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1087 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1088 for (i = 0; i < microcode->datasize / 2; i++)
1089 debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA,
1090 (microcode->data[i * 2] << 8) |
1091 microcode->data[i * 2 + 1], 2);
1092 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1093 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1094 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1095 ChipControl, 2);
1096 saa->boardcfg[0] = 28;
1097 }
1098 if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) {
1099 if (saa->boardcfg[0] > 35)
1100 continue; /* skip to next card */
1101 /* load audio control store */
1102 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1103 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1104 for (i = 0; i < microcode->datasize; i++)
1105 debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA,
1106 microcode->data[i], 1);
1107 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1108 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1109 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1110 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1111 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1112 0xe000, 1)) {
1113 printk(KERN_ERR
1114 "stradis%d: IBM config failed\n",
1115 saa->nr);
1116 return -1;
1117 }
1118 /* set PWM to center value */
1119 if (NewCard) {
1120 debiwrite(saa, debNormal, XILINX_PWM,
1121 saa->boardcfg[14] +
1122 (saa->boardcfg[13]<<8), 2);
1123 } else
1124 debiwrite(saa, debNormal, XILINX_PWM,
1125 0x46, 2);
1126 if (HaveCS3310) {
1127 i = CS3310MaxLvl;
1128 debiwrite(saa, debNormal,
1129 XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
1130 }
1131 printk(KERN_INFO
1132 "stradis%d: IBM MPEGCD%d Initialized\n",
1133 saa->nr, 18 + (debiread(saa, debNormal,
1134 IBM_MP2_CHIP_CONTROL, 2) >> 12));
1135 /* start video decoder */
1136 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1137 ChipControl, 2);
1138 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD,
1139 0x4037, 2); /* 256k vid, 3520 bytes aud */
1140 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1141 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1142 /* enable buffer threshold irq */
1143 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1144 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1145 /* enable gpio irq */
1146 saawrite(0x00002000, SAA7146_GPIO_CTRL);
1147 /* enable decoder output to HPS */
1148 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1149 saa->boardcfg[0] = 37;
1150 }
1151 }
1152 return 0;
1153}
1154
1155static u32 palette2fmt[] =
1156{ /* some of these YUV translations are wrong */
1157 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000,
1158 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000,
1159 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000
1160};
1161static int bpp2fmt[4] =
1162{
1163 VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24,
1164 VIDEO_PALETTE_RGB32
1165};
1166
1167/* I wish I could find a formula to calculate these... */
1168static u32 h_prescale[64] =
1169{
1170 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808,
1171 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460,
1172 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f,
1173 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000,
1174 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000,
1175 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000,
1176 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000,
1177 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000,
1178 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000,
1179 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000,
1180 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,
1181};
1182static u32 v_gain[64] =
1183{
1184 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff,
1185 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff,
1186 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff,
1187 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1188 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1189 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1190 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1191 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1192 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1193 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1194 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1195};
1196
1197
1198static void saa7146_set_winsize(struct saa7146 *saa)
1199{
1200 u32 format;
1201 int offset, yacl, ysci;
1202 saa->win.color_fmt = format =
1203 (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] :
1204 palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]];
1205 offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl;
1206 saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1);
1207 saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1);
1208 saawrite(saa->win.bpl * 2, SAA7146_PITCH1);
1209 saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight,
1210 SAA7146_PROT_ADDR1);
1211 saawrite(0, SAA7146_PAGE1);
1212 saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
1213 offset = (704 / (saa->win.width - 1)) & 0x3f;
1214 saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE);
1215 offset = (720896 / saa->win.width) / (offset + 1);
1216 saawrite((offset<<12)|0x0c, SAA7146_HPS_H_SCALE);
1217 if (CurrentMode == VIDEO_MODE_NTSC) {
1218 yacl = /*(480 / saa->win.height - 1) & 0x3f*/ 0;
1219 ysci = 1024 - (saa->win.height * 1024 / 480);
1220 } else {
1221 yacl = /*(576 / saa->win.height - 1) & 0x3f*/ 0;
1222 ysci = 1024 - (saa->win.height * 1024 / 576);
1223 }
1224 saawrite((1<<31)|(ysci<<21)|(yacl<<15), SAA7146_HPS_V_SCALE);
1225 saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN);
1226 saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V |
1227 SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 |
1228 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H),
1229 SAA7146_MC2);
1230}
1231
1232/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area
1233 * bitmap is fixed width, 128 bytes (1024 pixels represented)
1234 * arranged most-sigificant-bit-left in 32-bit words
1235 * based on saa7146 clipping hardware, it swaps bytes if LE
1236 * much of this makes up for egcs brain damage -- so if you
1237 * are wondering "why did he do this?" it is because the C
1238 * was adjusted to generate the optimal asm output without
1239 * writing non-portable __asm__ directives.
1240 */
1241
1242static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h)
1243{
1244 register int startword, endword;
1245 register u32 bitsleft, bitsright;
1246 u32 *temp;
1247 if (x < 0) {
1248 w += x;
1249 x = 0;
1250 }
1251 if (y < 0) {
1252 h += y;
1253 y = 0;
1254 }
1255 if (w <= 0 || h <= 0 || x > 1023 || y > 639)
1256 return; /* throw away bad clips */
1257 if (x + w > 1024)
1258 w = 1024 - x;
1259 if (y + h > 640)
1260 h = 640 - y;
1261 startword = (x >> 5);
1262 endword = ((x + w) >> 5);
1263 bitsleft = (0xffffffff >> (x & 31));
1264 bitsright = (0xffffffff << (~((x + w) - (endword<<5))));
1265 temp = &clipmap[(y<<5) + startword];
1266 w = endword - startword;
1267 if (!w) {
1268 bitsleft |= bitsright;
1269 for (y = 0; y < h; y++) {
1270 *temp |= bitsleft;
1271 temp += 32;
1272 }
1273 } else {
1274 for (y = 0; y < h; y++) {
1275 *temp++ |= bitsleft;
1276 for (x = 1; x < w; x++)
1277 *temp++ = 0xffffffff;
1278 *temp |= bitsright;
1279 temp += (32 - w);
1280 }
1281 }
1282}
1283
1284static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr)
1285{
1286 int i, width, height;
1287 u32 *clipmap;
1288
1289 clipmap = saa->dmavid2;
1290 if((width=saa->win.width)>1023)
1291 width = 1023; /* sanity check */
1292 if((height=saa->win.height)>640)
1293 height = 639; /* sanity check */
1294 if (ncr > 0) { /* rectangles pased */
1295 /* convert rectangular clips to a bitmap */
1296 memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
1297 for (i = 0; i < ncr; i++)
1298 clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
1299 cr[i].width, cr[i].height);
1300 }
1301 /* clip against viewing window AND screen
1302 so we do not have to rely on the user program
1303 */
1304 clip_draw_rectangle(clipmap,(saa->win.x+width>saa->win.swidth) ?
1305 (saa->win.swidth-saa->win.x) : width, 0, 1024, 768);
1306 clip_draw_rectangle(clipmap,0,(saa->win.y+height>saa->win.sheight) ?
1307 (saa->win.sheight-saa->win.y) : height,1024,768);
1308 if (saa->win.x<0)
1309 clip_draw_rectangle(clipmap, 0, 0, -(saa->win.x), 768);
1310 if (saa->win.y<0)
1311 clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y));
1312}
1313
1314static int saa_ioctl(struct inode *inode, struct file *file,
1315 unsigned int cmd, unsigned long argl)
1316{
1317 struct saa7146 *saa = file->private_data;
1318 void __user *arg = (void __user *)argl;
1319
1320 switch (cmd) {
1321 case VIDIOCGCAP:
1322 {
1323 struct video_capability b;
1324 strcpy(b.name, saa->video_dev.name);
1325 b.type = VID_TYPE_CAPTURE |
1326 VID_TYPE_OVERLAY |
1327 VID_TYPE_CLIPPING |
1328 VID_TYPE_FRAMERAM |
1329 VID_TYPE_SCALES;
1330 b.channels = 1;
1331 b.audios = 1;
1332 b.maxwidth = 768;
1333 b.maxheight = 576;
1334 b.minwidth = 32;
1335 b.minheight = 32;
1336 if (copy_to_user(arg, &b, sizeof(b)))
1337 return -EFAULT;
1338 return 0;
1339 }
1340 case VIDIOCGPICT:
1341 {
1342 struct video_picture p = saa->picture;
1343 if (saa->win.depth == 8)
1344 p.palette = VIDEO_PALETTE_HI240;
1345 if (saa->win.depth == 15)
1346 p.palette = VIDEO_PALETTE_RGB555;
1347 if (saa->win.depth == 16)
1348 p.palette = VIDEO_PALETTE_RGB565;
1349 if (saa->win.depth == 24)
1350 p.palette = VIDEO_PALETTE_RGB24;
1351 if (saa->win.depth == 32)
1352 p.palette = VIDEO_PALETTE_RGB32;
1353 if (copy_to_user(arg, &p, sizeof(p)))
1354 return -EFAULT;
1355 return 0;
1356 }
1357 case VIDIOCSPICT:
1358 {
1359 struct video_picture p;
1360 u32 format;
1361 if (copy_from_user(&p, arg, sizeof(p)))
1362 return -EFAULT;
1363 if (p.palette < sizeof(palette2fmt) / sizeof(u32)) {
1364 format = palette2fmt[p.palette];
1365 saa->win.color_fmt = format;
1366 saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
1367 }
1368 saawrite(((p.brightness & 0xff00) << 16) |
1369 ((p.contrast & 0xfe00) << 7) |
1370 ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
1371 saa->picture = p;
1372 /* upload changed registers */
1373 saawrite(((SAA7146_MC2_UPLD_HPS_H |
1374 SAA7146_MC2_UPLD_HPS_V) << 16) |
1375 SAA7146_MC2_UPLD_HPS_H | SAA7146_MC2_UPLD_HPS_V,
1376 SAA7146_MC2);
1377 return 0;
1378 }
1379 case VIDIOCSWIN:
1380 {
1381 struct video_window vw;
1382 struct video_clip *vcp = NULL;
1383
1384 if (copy_from_user(&vw, arg, sizeof(vw)))
1385 return -EFAULT;
1386
1387 if (vw.flags || vw.width < 16 || vw.height < 16) { /* stop capture */
1388 saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
1389 return -EINVAL;
1390 }
1391 if (saa->win.bpp < 4) { /* 32-bit align start and adjust width */
1392 int i = vw.x;
1393 vw.x = (vw.x + 3) & ~3;
1394 i = vw.x - i;
1395 vw.width -= i;
1396 }
1397 saa->win.x = vw.x;
1398 saa->win.y = vw.y;
1399 saa->win.width = vw.width;
1400 if (saa->win.width > 768)
1401 saa->win.width = 768;
1402 saa->win.height = vw.height;
1403 if (CurrentMode == VIDEO_MODE_NTSC) {
1404 if (saa->win.height > 480)
1405 saa->win.height = 480;
1406 } else {
1407 if (saa->win.height > 576)
1408 saa->win.height = 576;
1409 }
1410
1411 /* stop capture */
1412 saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
1413 saa7146_set_winsize(saa);
1414
1415 /*
1416 * Do any clips.
1417 */
1418 if (vw.clipcount < 0) {
1419 if (copy_from_user(saa->dmavid2, vw.clips,
1420 VIDEO_CLIPMAP_SIZE))
1421 return -EFAULT;
1422 }
1423 else if (vw.clipcount > 16384) {
1424 return -EINVAL;
1425 } else if (vw.clipcount > 0) {
1426 if ((vcp = vmalloc(sizeof(struct video_clip) *
1427 (vw.clipcount))) == NULL)
1428 return -ENOMEM;
1429 if (copy_from_user(vcp, vw.clips,
1430 sizeof(struct video_clip) *
1431 vw.clipcount)) {
1432 vfree(vcp);
1433 return -EFAULT;
1434 }
1435 } else /* nothing clipped */
1436 memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);
1437 make_clip_tab(saa, vcp, vw.clipcount);
1438 if (vw.clipcount > 0)
1439 vfree(vcp);
1440
1441 /* start capture & clip dma if we have an address */
1442 if ((saa->cap & 3) && saa->win.vidadr != 0)
1443 saawrite(((SAA7146_MC1_TR_E_1 |
1444 SAA7146_MC1_TR_E_2) << 16) | 0xffff,
1445 SAA7146_MC1);
1446 return 0;
1447 }
1448 case VIDIOCGWIN:
1449 {
1450 struct video_window vw;
1451 vw.x = saa->win.x;
1452 vw.y = saa->win.y;
1453 vw.width = saa->win.width;
1454 vw.height = saa->win.height;
1455 vw.chromakey = 0;
1456 vw.flags = 0;
1457 if (copy_to_user(arg, &vw, sizeof(vw)))
1458 return -EFAULT;
1459 return 0;
1460 }
1461 case VIDIOCCAPTURE:
1462 {
1463 int v;
1464 if (copy_from_user(&v, arg, sizeof(v)))
1465 return -EFAULT;
1466 if (v == 0) {
1467 saa->cap &= ~1;
1468 saawrite((SAA7146_MC1_TR_E_1 << 16),
1469 SAA7146_MC1);
1470 } else {
1471 if (saa->win.vidadr == 0 || saa->win.width == 0
1472 || saa->win.height == 0)
1473 return -EINVAL;
1474 saa->cap |= 1;
1475 saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
1476 SAA7146_MC1);
1477 }
1478 return 0;
1479 }
1480 case VIDIOCGFBUF:
1481 {
1482 struct video_buffer v;
1483 v.base = (void *) saa->win.vidadr;
1484 v.height = saa->win.sheight;
1485 v.width = saa->win.swidth;
1486 v.depth = saa->win.depth;
1487 v.bytesperline = saa->win.bpl;
1488 if (copy_to_user(arg, &v, sizeof(v)))
1489 return -EFAULT;
1490 return 0;
1491
1492 }
1493 case VIDIOCSFBUF:
1494 {
1495 struct video_buffer v;
1496 if (!capable(CAP_SYS_ADMIN))
1497 return -EPERM;
1498 if (copy_from_user(&v, arg, sizeof(v)))
1499 return -EFAULT;
1500 if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
1501 v.depth != 24 && v.depth != 32 && v.width > 16 &&
1502 v.height > 16 && v.bytesperline > 16)
1503 return -EINVAL;
1504 if (v.base)
1505 saa->win.vidadr = (unsigned long) v.base;
1506 saa->win.sheight = v.height;
1507 saa->win.swidth = v.width;
1508 saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
1509 saa->win.depth = v.depth;
1510 saa->win.bpl = v.bytesperline;
1511
1512 DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
1513 v.base, v.width, v.height, saa->win.bpp, saa->win.bpl));
1514 saa7146_set_winsize(saa);
1515 return 0;
1516 }
1517 case VIDIOCKEY:
1518 {
1519 /* Will be handled higher up .. */
1520 return 0;
1521 }
1522
1523 case VIDIOCGAUDIO:
1524 {
1525 struct video_audio v;
1526 v = saa->audio_dev;
1527 v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
1528 v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
1529 strcpy(v.name, "MPEG");
1530 v.mode = VIDEO_SOUND_STEREO;
1531 if (copy_to_user(arg, &v, sizeof(v)))
1532 return -EFAULT;
1533 return 0;
1534 }
1535 case VIDIOCSAUDIO:
1536 {
1537 struct video_audio v;
1538 int i;
1539 if (copy_from_user(&v, arg, sizeof(v)))
1540 return -EFAULT;
1541 i = (~(v.volume>>8))&0xff;
1542 if (!HaveCS4341) {
1543 if (v.flags & VIDEO_AUDIO_MUTE) {
1544 debiwrite(saa, debNormal,
1545 IBM_MP2_FRNT_ATTEN,
1546 0xffff, 2);
1547 }
1548 if (!(v.flags & VIDEO_AUDIO_MUTE))
1549 debiwrite(saa, debNormal,
1550 IBM_MP2_FRNT_ATTEN,
1551 0x0000, 2);
1552 if (v.flags & VIDEO_AUDIO_VOLUME)
1553 debiwrite(saa, debNormal,
1554 IBM_MP2_FRNT_ATTEN,
1555 (i<<8)|i, 2);
1556 } else {
1557 if (v.flags & VIDEO_AUDIO_MUTE)
1558 cs4341_setlevel(saa, 0xff, 0xff);
1559 if (!(v.flags & VIDEO_AUDIO_MUTE))
1560 cs4341_setlevel(saa, 0, 0);
1561 if (v.flags & VIDEO_AUDIO_VOLUME)
1562 cs4341_setlevel(saa, i, i);
1563 }
1564 saa->audio_dev = v;
1565 return 0;
1566 }
1567
1568 case VIDIOCGUNIT:
1569 {
1570 struct video_unit vu;
1571 vu.video = saa->video_dev.minor;
1572 vu.vbi = VIDEO_NO_UNIT;
1573 vu.radio = VIDEO_NO_UNIT;
1574 vu.audio = VIDEO_NO_UNIT;
1575 vu.teletext = VIDEO_NO_UNIT;
1576 if (copy_to_user(arg, &vu, sizeof(vu)))
1577 return -EFAULT;
1578 return 0;
1579 }
1580 case VIDIOCSPLAYMODE:
1581 {
1582 struct video_play_mode pmode;
1583 if (copy_from_user((void *) &pmode, arg,
1584 sizeof(struct video_play_mode)))
1585 return -EFAULT;
1586 switch (pmode.mode) {
1587 case VID_PLAY_VID_OUT_MODE:
1588 if (pmode.p1 != VIDEO_MODE_NTSC &&
1589 pmode.p1 != VIDEO_MODE_PAL)
1590 return -EINVAL;
1591 set_out_format(saa, pmode.p1);
1592 return 0;
1593 case VID_PLAY_GENLOCK:
1594 debiwrite(saa, debNormal,
1595 XILINX_CTL0,
1596 (pmode.p1 ? 0x8000 : 0x8080),
1597 2);
1598 if (NewCard)
1599 set_genlock_offset(saa,
1600 pmode.p2);
1601 return 0;
1602 case VID_PLAY_NORMAL:
1603 debiwrite(saa, debNormal,
1604 IBM_MP2_CHIP_CONTROL,
1605 ChipControl, 2);
1606 ibm_send_command(saa,
1607 IBM_MP2_PLAY, 0, 0);
1608 saa->playmode = pmode.mode;
1609 return 0;
1610 case VID_PLAY_PAUSE:
1611 /* IBM removed the PAUSE command */
1612 /* they say use SINGLE_FRAME now */
1613 case VID_PLAY_SINGLE_FRAME:
1614 ibm_send_command(saa,
1615 IBM_MP2_SINGLE_FRAME,
1616 0, 0);
1617 if (saa->playmode == pmode.mode) {
1618 debiwrite(saa, debNormal,
1619 IBM_MP2_CHIP_CONTROL,
1620 ChipControl, 2);
1621 }
1622 saa->playmode = pmode.mode;
1623 return 0;
1624 case VID_PLAY_FAST_FORWARD:
1625 ibm_send_command(saa,
1626 IBM_MP2_FAST_FORWARD, 0, 0);
1627 saa->playmode = pmode.mode;
1628 return 0;
1629 case VID_PLAY_SLOW_MOTION:
1630 ibm_send_command(saa,
1631 IBM_MP2_SLOW_MOTION,
1632 pmode.p1, 0);
1633 saa->playmode = pmode.mode;
1634 return 0;
1635 case VID_PLAY_IMMEDIATE_NORMAL:
1636 /* ensure transfers resume */
1637 debiwrite(saa, debNormal,
1638 IBM_MP2_CHIP_CONTROL,
1639 ChipControl, 2);
1640 ibm_send_command(saa,
1641 IBM_MP2_IMED_NORM_PLAY, 0, 0);
1642 saa->playmode = VID_PLAY_NORMAL;
1643 return 0;
1644 case VID_PLAY_SWITCH_CHANNELS:
1645 saa->audhead = saa->audtail = 0;
1646 saa->vidhead = saa->vidtail = 0;
1647 ibm_send_command(saa,
1648 IBM_MP2_FREEZE_FRAME, 0, 1);
1649 ibm_send_command(saa,
1650 IBM_MP2_RESET_AUD_RATE, 0, 1);
1651 debiwrite(saa, debNormal,
1652 IBM_MP2_CHIP_CONTROL, 0, 2);
1653 ibm_send_command(saa,
1654 IBM_MP2_CHANNEL_SWITCH, 0, 1);
1655 debiwrite(saa, debNormal,
1656 IBM_MP2_CHIP_CONTROL,
1657 ChipControl, 2);
1658 ibm_send_command(saa,
1659 IBM_MP2_PLAY, 0, 0);
1660 saa->playmode = VID_PLAY_NORMAL;
1661 return 0;
1662 case VID_PLAY_FREEZE_FRAME:
1663 ibm_send_command(saa,
1664 IBM_MP2_FREEZE_FRAME, 0, 0);
1665 saa->playmode = pmode.mode;
1666 return 0;
1667 case VID_PLAY_STILL_MODE:
1668 ibm_send_command(saa,
1669 IBM_MP2_SET_STILL_MODE, 0, 0);
1670 saa->playmode = pmode.mode;
1671 return 0;
1672 case VID_PLAY_MASTER_MODE:
1673 if (pmode.p1 == VID_PLAY_MASTER_NONE)
1674 saa->boardcfg[1] = 0x13;
1675 else if (pmode.p1 ==
1676 VID_PLAY_MASTER_VIDEO)
1677 saa->boardcfg[1] = 0x23;
1678 else if (pmode.p1 ==
1679 VID_PLAY_MASTER_AUDIO)
1680 saa->boardcfg[1] = 0x43;
1681 else
1682 return -EINVAL;
1683 debiwrite(saa, debNormal,
1684 IBM_MP2_CHIP_CONTROL,
1685 ChipControl, 2);
1686 return 0;
1687 case VID_PLAY_ACTIVE_SCANLINES:
1688 if (CurrentMode == VIDEO_MODE_PAL) {
1689 if (pmode.p1 < 1 ||
1690 pmode.p2 > 625)
1691 return -EINVAL;
1692 saa->boardcfg[5] = pmode.p1;
1693 saa->boardcfg[55] = (pmode.p1 +
1694 (pmode.p2/2) - 1) &
1695 0xff;
1696 } else {
1697 if (pmode.p1 < 4 ||
1698 pmode.p2 > 525)
1699 return -EINVAL;
1700 saa->boardcfg[4] = pmode.p1;
1701 saa->boardcfg[54] = (pmode.p1 +
1702 (pmode.p2/2) - 4) &
1703 0xff;
1704 }
1705 set_out_format(saa, CurrentMode);
1706 case VID_PLAY_RESET:
1707 return do_ibm_reset(saa);
1708 case VID_PLAY_END_MARK:
1709 if (saa->endmarktail <
1710 saa->endmarkhead) {
1711 if (saa->endmarkhead -
1712 saa->endmarktail < 2)
1713 return -ENOSPC;
1714 } else if (saa->endmarkhead <=
1715 saa->endmarktail) {
1716 if (saa->endmarktail -
1717 saa->endmarkhead >
1718 (MAX_MARKS - 2))
1719 return -ENOSPC;
1720 } else
1721 return -ENOSPC;
1722 saa->endmark[saa->endmarktail] =
1723 saa->audtail;
1724 saa->endmarktail++;
1725 if (saa->endmarktail >= MAX_MARKS)
1726 saa->endmarktail = 0;
1727 }
1728 return -EINVAL;
1729 }
1730 case VIDIOCSWRITEMODE:
1731 {
1732 int mode;
1733 if (copy_from_user((void *) &mode, arg, sizeof(int)))
1734 return -EFAULT;
1735 if (mode == VID_WRITE_MPEG_AUD ||
1736 mode == VID_WRITE_MPEG_VID ||
1737 mode == VID_WRITE_CC ||
1738 mode == VID_WRITE_TTX ||
1739 mode == VID_WRITE_OSD) {
1740 saa->writemode = mode;
1741 return 0;
1742 }
1743 return -EINVAL;
1744 }
1745 case VIDIOCSMICROCODE:
1746 {
1747 struct video_code ucode;
1748 __u8 *udata;
1749 int i;
1750 if (copy_from_user(&ucode, arg, sizeof(ucode)))
1751 return -EFAULT;
1752 if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
1753 strncmp(ucode.loadwhat, "dec", 3))
1754 return -EINVAL;
1755 if ((udata = vmalloc(ucode.datasize)) == NULL)
1756 return -ENOMEM;
1757 if (copy_from_user(udata, ucode.data, ucode.datasize)) {
1758 vfree(udata);
1759 return -EFAULT;
1760 }
1761 ucode.data = udata;
1762 if (!strncmp(ucode.loadwhat, "decoder.aud", 11)
1763 || !strncmp(ucode.loadwhat, "decoder.vid", 11))
1764 i = initialize_ibmmpeg2(&ucode);
1765 else
1766 i = initialize_fpga(&ucode);
1767 vfree(udata);
1768 if (i)
1769 return -EINVAL;
1770 return 0;
1771
1772 }
1773 case VIDIOCGCHAN: /* this makes xawtv happy */
1774 {
1775 struct video_channel v;
1776 if (copy_from_user(&v, arg, sizeof(v)))
1777 return -EFAULT;
1778 v.flags = VIDEO_VC_AUDIO;
1779 v.tuners = 0;
1780 v.type = VID_TYPE_MPEG_DECODER;
1781 v.norm = CurrentMode;
1782 strcpy(v.name, "MPEG2");
1783 if (copy_to_user(arg, &v, sizeof(v)))
1784 return -EFAULT;
1785 return 0;
1786 }
1787 case VIDIOCSCHAN: /* this makes xawtv happy */
1788 {
1789 struct video_channel v;
1790 if (copy_from_user(&v, arg, sizeof(v)))
1791 return -EFAULT;
1792 /* do nothing */
1793 return 0;
1794 }
1795 default:
1796 return -ENOIOCTLCMD;
1797 }
1798 return 0;
1799}
1800
1801static int saa_mmap(struct file *file, struct vm_area_struct *vma)
1802{
1803 struct saa7146 *saa = file->private_data;
1804 printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
1805 return -EINVAL;
1806}
1807
1808static ssize_t saa_read(struct file *file, char __user *buf,
1809 size_t count, loff_t *ppos)
1810{
1811 return -EINVAL;
1812}
1813
1814static ssize_t saa_write(struct file *file, const char __user *buf,
1815 size_t count, loff_t *ppos)
1816{
1817 struct saa7146 *saa = file->private_data;
1818 unsigned long todo = count;
1819 int blocksize, split;
1820 unsigned long flags;
1821
1822 while (todo > 0) {
1823 if (saa->writemode == VID_WRITE_MPEG_AUD) {
1824 spin_lock_irqsave(&saa->lock, flags);
1825 if (saa->audhead <= saa->audtail)
1826 blocksize = 65536-(saa->audtail - saa->audhead);
1827 else
1828 blocksize = saa->audhead - saa->audtail;
1829 spin_unlock_irqrestore(&saa->lock, flags);
1830 if (blocksize < 16384) {
1831 saawrite(SAA7146_PSR_DEBI_S |
1832 SAA7146_PSR_PIN1, SAA7146_IER);
1833 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1834 /* wait for buffer space to open */
1835 interruptible_sleep_on(&saa->audq);
1836 }
1837 spin_lock_irqsave(&saa->lock, flags);
1838 if (saa->audhead <= saa->audtail) {
1839 blocksize = 65536-(saa->audtail - saa->audhead);
1840 split = 65536 - saa->audtail;
1841 } else {
1842 blocksize = saa->audhead - saa->audtail;
1843 split = 65536;
1844 }
1845 spin_unlock_irqrestore(&saa->lock, flags);
1846 blocksize--;
1847 if (blocksize > todo)
1848 blocksize = todo;
1849 /* double check that we really have space */
1850 if (!blocksize)
1851 return -ENOSPC;
1852 if (split < blocksize) {
1853 if (copy_from_user(saa->audbuf +
1854 saa->audtail, buf, split))
1855 return -EFAULT;
1856 buf += split;
1857 todo -= split;
1858 blocksize -= split;
1859 saa->audtail = 0;
1860 }
1861 if (copy_from_user(saa->audbuf + saa->audtail, buf,
1862 blocksize))
1863 return -EFAULT;
1864 saa->audtail += blocksize;
1865 todo -= blocksize;
1866 buf += blocksize;
1867 saa->audtail &= 0xffff;
1868 } else if (saa->writemode == VID_WRITE_MPEG_VID) {
1869 spin_lock_irqsave(&saa->lock, flags);
1870 if (saa->vidhead <= saa->vidtail)
1871 blocksize=524288-(saa->vidtail - saa->vidhead);
1872 else
1873 blocksize = saa->vidhead - saa->vidtail;
1874 spin_unlock_irqrestore(&saa->lock, flags);
1875 if (blocksize < 65536) {
1876 saawrite(SAA7146_PSR_DEBI_S |
1877 SAA7146_PSR_PIN1, SAA7146_IER);
1878 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1879 /* wait for buffer space to open */
1880 interruptible_sleep_on(&saa->vidq);
1881 }
1882 spin_lock_irqsave(&saa->lock, flags);
1883 if (saa->vidhead <= saa->vidtail) {
1884 blocksize=524288-(saa->vidtail - saa->vidhead);
1885 split = 524288 - saa->vidtail;
1886 } else {
1887 blocksize = saa->vidhead - saa->vidtail;
1888 split = 524288;
1889 }
1890 spin_unlock_irqrestore(&saa->lock, flags);
1891 blocksize--;
1892 if (blocksize > todo)
1893 blocksize = todo;
1894 /* double check that we really have space */
1895 if (!blocksize)
1896 return -ENOSPC;
1897 if (split < blocksize) {
1898 if (copy_from_user(saa->vidbuf +
1899 saa->vidtail, buf, split))
1900 return -EFAULT;
1901 buf += split;
1902 todo -= split;
1903 blocksize -= split;
1904 saa->vidtail = 0;
1905 }
1906 if (copy_from_user(saa->vidbuf + saa->vidtail, buf,
1907 blocksize))
1908 return -EFAULT;
1909 saa->vidtail += blocksize;
1910 todo -= blocksize;
1911 buf += blocksize;
1912 saa->vidtail &= 0x7ffff;
1913 } else if (saa->writemode == VID_WRITE_OSD) {
1914 if (count > 131072)
1915 return -ENOSPC;
1916 if (copy_from_user(saa->osdbuf, buf, count))
1917 return -EFAULT;
1918 buf += count;
1919 saa->osdhead = 0;
1920 saa->osdtail = count;
1921 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);
1922 debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);
1923 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);
1924 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
1925 debiread(saa, debNormal,
1926 IBM_MP2_DISP_MODE, 2) | 1, 2);
1927 /* trigger osd data transfer */
1928 saawrite(SAA7146_PSR_DEBI_S |
1929 SAA7146_PSR_PIN1, SAA7146_IER);
1930 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1931 }
1932 }
1933 return count;
1934}
1935
1936static int saa_open(struct inode *inode, struct file *file)
1937{
1938 struct saa7146 *saa = NULL;
1939 unsigned int minor = iminor(inode);
1940 int i;
1941
1942 for (i = 0; i < SAA7146_MAX; i++) {
1943 if (saa7146s[i].video_dev.minor == minor) {
1944 saa = &saa7146s[i];
1945 }
1946 }
1947 if (saa == NULL) {
1948 return -ENODEV;
1949 }
1950 file->private_data = saa;
1951
1952 //saa->video_dev.busy = 0; /* old hack to support multiple open */
1953 saa->user++;
1954 if (saa->user > 1)
1955 return 0; /* device open already, don't reset */
1956 saa->writemode = VID_WRITE_MPEG_VID; /* default to video */
1957 return 0;
1958}
1959
1960static int saa_release(struct inode *inode, struct file *file)
1961{
1962 struct saa7146 *saa = file->private_data;
1963 saa->user--;
1964 //saa->video_dev.busy = 0; /* old hack to support multiple open */
1965 if (saa->user > 0) /* still someone using device */
1966 return 0;
1967 saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */
1968 return 0;
1969}
1970
1971static struct file_operations saa_fops =
1972{
1973 .owner = THIS_MODULE,
1974 .open = saa_open,
1975 .release = saa_release,
1976 .ioctl = saa_ioctl,
1977 .read = saa_read,
1978 .llseek = no_llseek,
1979 .write = saa_write,
1980 .mmap = saa_mmap,
1981};
1982
1983/* template for video_device-structure */
1984static struct video_device saa_template =
1985{
1986 .name = "SAA7146A",
1987 .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
1988 .hardware = VID_HARDWARE_SAA7146,
1989 .fops = &saa_fops,
1990 .minor = -1,
1991};
1992
1993static int configure_saa7146(struct pci_dev *dev, int num)
1994{
1995 int result;
1996 struct saa7146 *saa;
1997
1998 saa = &saa7146s[num];
1999
2000 saa->endmarkhead = saa->endmarktail = 0;
2001 saa->win.x = saa->win.y = 0;
2002 saa->win.width = saa->win.cropwidth = 720;
2003 saa->win.height = saa->win.cropheight = 480;
2004 saa->win.cropx = saa->win.cropy = 0;
2005 saa->win.bpp = 2;
2006 saa->win.depth = 16;
2007 saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];
2008 saa->win.bpl = 1024 * saa->win.bpp;
2009 saa->win.swidth = 1024;
2010 saa->win.sheight = 768;
2011 saa->picture.brightness = 32768;
2012 saa->picture.contrast = 38768;
2013 saa->picture.colour = 32768;
2014 saa->cap = 0;
2015 saa->dev = dev;
2016 saa->nr = num;
2017 saa->playmode = VID_PLAY_NORMAL;
2018 memset(saa->boardcfg, 0, 64); /* clear board config area */
2019 saa->saa7146_mem = NULL;
2020 saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =
2021 saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =
2022 saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =
2023 saa->pagea1out = saa->pagea2in = saa->pagea2out =
2024 saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =
2025 saa->pageRPS2 = NULL;
2026 saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;
2027 saa->audhead = saa->vidtail = 0;
2028
2029 init_waitqueue_head(&saa->i2cq);
2030 init_waitqueue_head(&saa->audq);
2031 init_waitqueue_head(&saa->debiq);
2032 init_waitqueue_head(&saa->vidq);
2033 spin_lock_init(&saa->lock);
2034
2035 if (pci_enable_device(dev))
2036 return -EIO;
2037
2038 saa->id = dev->device;
2039 saa->irq = dev->irq;
2040 saa->video_dev.minor = -1;
2041 saa->saa7146_adr = pci_resource_start(dev, 0);
2042 pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision);
2043
2044 saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
2045 if (!saa->saa7146_mem)
2046 return -EIO;
2047
2048 memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
2049 saawrite(0, SAA7146_IER); /* turn off all interrupts */
2050 result = request_irq(saa->irq, saa7146_irq,
2051 SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);
2052 if (result == -EINVAL)
2053 printk(KERN_ERR "stradis%d: Bad irq number or handler\n",
2054 num);
2055 if (result == -EBUSY)
2056 printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"
2057 " config in BIOS\n", num, saa->irq);
2058 if (result < 0) {
2059 iounmap(saa->saa7146_mem);
2060 return result;
2061 }
2062 pci_set_master(dev);
2063 if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
2064 iounmap(saa->saa7146_mem);
2065 return -1;
2066 }
2067 return 0;
2068}
2069
2070static int init_saa7146(int i)
2071{
2072 struct saa7146 *saa = &saa7146s[i];
2073
2074 saa->user = 0;
2075 /* reset the saa7146 */
2076 saawrite(0xffff0000, SAA7146_MC1);
2077 mdelay(5);
2078 /* enable debi and i2c transfers and pins */
2079 saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |
2080 SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);
2081 /* ensure proper state of chip */
2082 saawrite(0x00000000, SAA7146_PAGE1);
2083 saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);
2084 saawrite(0x00000000, SAA7146_PAGE2);
2085 saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);
2086 saawrite(0x00000000, SAA7146_DD1_INIT);
2087 saawrite(0x00000000, SAA7146_DD1_STREAM_B);
2088 saawrite(0x00000000, SAA7146_DD1_STREAM_A);
2089 saawrite(0x00000000, SAA7146_BRS_CTRL);
2090 saawrite(0x80400040, SAA7146_BCS_CTRL);
2091 saawrite(0x0000e000 /*| (1<<29)*/, SAA7146_HPS_CTRL);
2092 saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);
2093 saawrite(0x00000000, SAA7146_ACON1);
2094 saawrite(0x00000000, SAA7146_ACON2);
2095 saawrite(0x00000600, SAA7146_I2C_STATUS);
2096 saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |
2097 SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |
2098 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |
2099 SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,
2100 SAA7146_MC2);
2101 /* setup arbitration control registers */
2102 saawrite(0x1412121a, SAA7146_PCI_BT_V1);
2103
2104 /* allocate 32k dma buffer + 4k for page table */
2105 if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
2106 printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i);
2107 return -1;
2108 }
2109#if 0
2110 saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */
2111 saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);
2112 for (i = 0; i < 12; i++) /* setup mmu page table */
2113 saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));
2114#endif
2115 saa->audhead = saa->vidhead = saa->osdhead = 0;
2116 saa->audtail = saa->vidtail = saa->osdtail = 0;
2117 if (saa->vidbuf == NULL)
2118 if ((saa->vidbuf = vmalloc(524288)) == NULL) {
2119 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2120 return -ENOMEM;
2121 }
2122 if (saa->audbuf == NULL)
2123 if ((saa->audbuf = vmalloc(65536)) == NULL) {
2124 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2125 vfree(saa->vidbuf);
2126 saa->vidbuf = NULL;
2127 return -ENOMEM;
2128 }
2129 if (saa->osdbuf == NULL)
2130 if ((saa->osdbuf = vmalloc(131072)) == NULL) {
2131 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2132 vfree(saa->vidbuf);
2133 vfree(saa->audbuf);
2134 saa->vidbuf = saa->audbuf = NULL;
2135 return -ENOMEM;
2136 }
2137 /* allocate 81920 byte buffer for clipping */
2138 if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
2139 printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr);
2140 vfree(saa->vidbuf);
2141 vfree(saa->audbuf);
2142 vfree(saa->osdbuf);
2143 saa->vidbuf = saa->audbuf = saa->osdbuf = NULL;
2144 saa->dmavid2 = NULL;
2145 return -1;
2146 }
2147 memset(saa->dmavid2, 0x00, VIDEO_CLIPMAP_SIZE); /* clip everything */
2148 /* setup clipping registers */
2149 saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
2150 saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);
2151 saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,
2152 SAA7146_PROT_ADDR2);
2153 saawrite(256, SAA7146_PITCH2);
2154 saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
2155 saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
2156 SAA7146_MC2);
2157 I2CBusScan(saa);
2158 return 0;
2159}
2160
2161static void release_saa(void)
2162{
2163 u8 command;
2164 int i;
2165 struct saa7146 *saa;
2166
2167 for (i = 0; i < saa_num; i++) {
2168 saa = &saa7146s[i];
2169
2170 /* turn off all capturing, DMA and IRQs */
2171 saawrite(0xffff0000, SAA7146_MC1); /* reset chip */
2172 saawrite(0, SAA7146_MC2);
2173 saawrite(0, SAA7146_IER);
2174 saawrite(0xffffffffUL, SAA7146_ISR);
2175
2176 /* disable PCI bus-mastering */
2177 pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
2178 command &= ~PCI_COMMAND_MASTER;
2179 pci_write_config_byte(saa->dev, PCI_COMMAND, command);
2180
2181 /* unmap and free memory */
2182 saa->audhead = saa->audtail = saa->osdhead = 0;
2183 saa->vidhead = saa->vidtail = saa->osdtail = 0;
2184 vfree(saa->vidbuf);
2185 vfree(saa->audbuf);
2186 vfree(saa->osdbuf);
2187 if (saa->dmavid2)
2188 kfree((void *) saa->dmavid2);
2189 saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
2190 saa->dmavid2 = NULL;
2191 if (saa->dmadebi)
2192 kfree((void *) saa->dmadebi);
2193 if (saa->dmavid1)
2194 kfree((void *) saa->dmavid1);
2195 if (saa->dmavid2)
2196 kfree((void *) saa->dmavid2);
2197 if (saa->dmavid3)
2198 kfree((void *) saa->dmavid3);
2199 if (saa->dmaa1in)
2200 kfree((void *) saa->dmaa1in);
2201 if (saa->dmaa1out)
2202 kfree((void *) saa->dmaa1out);
2203 if (saa->dmaa2in)
2204 kfree((void *) saa->dmaa2in);
2205 if (saa->dmaa2out)
2206 kfree((void *) saa->dmaa2out);
2207 if (saa->dmaRPS1)
2208 kfree((void *) saa->dmaRPS1);
2209 if (saa->dmaRPS2)
2210 kfree((void *) saa->dmaRPS2);
2211 free_irq(saa->irq, saa);
2212 if (saa->saa7146_mem)
2213 iounmap(saa->saa7146_mem);
2214 if (saa->video_dev.minor != -1)
2215 video_unregister_device(&saa->video_dev);
2216 }
2217}
2218
2219
2220static int __init stradis_init (void)
2221{
2222 struct pci_dev *dev = NULL;
2223 int result = 0, i;
2224
2225 saa_num = 0;
2226
2227 while ((dev = pci_find_device(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, dev))) {
2228 if (!dev->subsystem_vendor)
2229 printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num);
2230 else
2231 printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num);
2232 result = configure_saa7146(dev, saa_num++);
2233 if (result)
2234 return result;
2235 }
2236 if (saa_num)
2237 printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num);
2238 else
2239 return -EINVAL;
2240 for (i = 0; i < saa_num; i++)
2241 if (init_saa7146(i) < 0) {
2242 release_saa();
2243 return -EIO;
2244 }
2245 return 0;
2246}
2247
2248
2249static void __exit stradis_exit (void)
2250{
2251 release_saa();
2252 printk(KERN_INFO "stradis: module cleanup complete\n");
2253}
2254
2255
2256module_init(stradis_init);
2257module_exit(stradis_exit);
2258
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
new file mode 100644
index 000000000000..376a4a439e9b
--- /dev/null
+++ b/drivers/media/video/tda7432.c
@@ -0,0 +1,556 @@
1/*
2 * For the STS-Thompson TDA7432 audio processor chip
3 *
4 * Handles audio functions: volume, balance, tone, loudness
5 * This driver will not complain if used with any
6 * other i2c device with the same address.
7 *
8 * Muting and tone control by Jonathan Isom <jisom@ematic.com>
9 *
10 * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
11 * This code is placed under the terms of the GNU General Public License
12 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
13 * Which was based on tda8425.c by Greg Alexander (c) 1998
14 *
15 * OPTIONS:
16 * debug - set to 1 if you'd like to see debug messages
17 * set to 2 if you'd like to be inundated with debug messages
18 *
19 * loudness - set between 0 and 15 for varying degrees of loudness effect
20 *
21 * maxvol - set maximium volume to +20db (1), default is 0db(0)
22 *
23 *
24 * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db
25 * store if muted so we can return it
26 * change balance only if flaged to
27 * Revision: 0.6 - added tone controls
28 * Revision: 0.5 - Fixed odd balance problem
29 * Revision: 0.4 - added muting
30 * Revision: 0.3 - Fixed silly reversed volume controls. :)
31 * Revision: 0.2 - Cleaned up #defines
32 * fixed volume control
33 * Added I2C_DRIVERID_TDA7432
34 * added loudness insmod control
35 * Revision: 0.1 - initial version
36 */
37
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/kernel.h>
41#include <linux/sched.h>
42#include <linux/string.h>
43#include <linux/timer.h>
44#include <linux/delay.h>
45#include <linux/errno.h>
46#include <linux/slab.h>
47#include <linux/videodev.h>
48#include <linux/i2c.h>
49#include <linux/i2c-algo-bit.h>
50
51#include "bttv.h"
52#include <media/audiochip.h>
53#include <media/id.h>
54
55#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32
57#endif
58
59MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
60MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
61MODULE_LICENSE("GPL");
62
63static int maxvol;
64static int loudness; /* disable loudness by default */
65static int debug; /* insmod parameter */
66module_param(debug, int, S_IRUGO | S_IWUSR);
67module_param(loudness, int, S_IRUGO);
68MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
69module_param(maxvol, int, S_IRUGO | S_IWUSR);
70
71
72/* Address to scan (I2C address of this chip) */
73static unsigned short normal_i2c[] = {
74 I2C_TDA7432 >> 1,
75 I2C_CLIENT_END,
76};
77static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END };
78I2C_CLIENT_INSMOD;
79
80/* Structure of address and subaddresses for the tda7432 */
81
82struct tda7432 {
83 int addr;
84 int input;
85 int volume;
86 int muted;
87 int bass, treble;
88 int lf, lr, rf, rr;
89 int loud;
90 struct i2c_client c;
91};
92static struct i2c_driver driver;
93static struct i2c_client client_template;
94
95#define dprintk if (debug) printk
96#define d2printk if (debug > 1) printk
97
98/* The TDA7432 is made by STS-Thompson
99 * http://www.st.com
100 * http://us.st.com/stonline/books/pdf/docs/4056.pdf
101 *
102 * TDA7432: I2C-bus controlled basic audio processor
103 *
104 * The TDA7432 controls basic audio functions like volume, balance,
105 * and tone control (including loudness). It also has four channel
106 * output (for front and rear). Since most vidcap cards probably
107 * don't have 4 channel output, this driver will set front & rear
108 * together (no independent control).
109 */
110
111 /* Subaddresses for TDA7432 */
112
113#define TDA7432_IN 0x00 /* Input select */
114#define TDA7432_VL 0x01 /* Volume */
115#define TDA7432_TN 0x02 /* Bass, Treble (Tone) */
116#define TDA7432_LF 0x03 /* Attenuation LF (Left Front) */
117#define TDA7432_LR 0x04 /* Attenuation LR (Left Rear) */
118#define TDA7432_RF 0x05 /* Attenuation RF (Right Front) */
119#define TDA7432_RR 0x06 /* Attenuation RR (Right Rear) */
120#define TDA7432_LD 0x07 /* Loudness */
121
122
123 /* Masks for bits in TDA7432 subaddresses */
124
125/* Many of these not used - just for documentation */
126
127/* Subaddress 0x00 - Input selection and bass control */
128
129/* Bits 0,1,2 control input:
130 * 0x00 - Stereo input
131 * 0x02 - Mono input
132 * 0x03 - Mute (Using Attenuators Plays better with modules)
133 * Mono probably isn't used - I'm guessing only the stereo
134 * input is connected on most cards, so we'll set it to stereo.
135 *
136 * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut
137 * Bit 4 controls bass range: 0/1 is extended/standard bass range
138 *
139 * Highest 3 bits not used
140 */
141
142#define TDA7432_STEREO_IN 0
143#define TDA7432_MONO_IN 2 /* Probably won't be used */
144#define TDA7432_BASS_SYM 1 << 3
145#define TDA7432_BASS_NORM 1 << 4
146
147/* Subaddress 0x01 - Volume */
148
149/* Lower 7 bits control volume from -79dB to +32dB in 1dB steps
150 * Recommended maximum is +20 dB
151 *
152 * +32dB: 0x00
153 * +20dB: 0x0c
154 * 0dB: 0x20
155 * -79dB: 0x6f
156 *
157 * MSB (bit 7) controls loudness: 1/0 is loudness on/off
158 */
159
160#define TDA7432_VOL_0DB 0x20
161#define TDA7432_LD_ON 1 << 7
162
163
164/* Subaddress 0x02 - Tone control */
165
166/* Bits 0,1,2 control absolute treble gain from 0dB to 14dB
167 * 0x0 is 14dB, 0x7 is 0dB
168 *
169 * Bit 3 controls treble attenuation/gain (sign)
170 * 1 = gain (+)
171 * 0 = attenuation (-)
172 *
173 * Bits 4,5,6 control absolute bass gain from 0dB to 14dB
174 * (This is only true for normal base range, set in 0x00)
175 * 0x0 << 4 is 14dB, 0x7 is 0dB
176 *
177 * Bit 7 controls bass attenuation/gain (sign)
178 * 1 << 7 = gain (+)
179 * 0 << 7 = attenuation (-)
180 *
181 * Example:
182 * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble
183 */
184
185#define TDA7432_TREBLE_0DB 0xf
186#define TDA7432_TREBLE 7
187#define TDA7432_TREBLE_GAIN 1 << 3
188#define TDA7432_BASS_0DB 0xf
189#define TDA7432_BASS 7 << 4
190#define TDA7432_BASS_GAIN 1 << 7
191
192
193/* Subaddress 0x03 - Left Front attenuation */
194/* Subaddress 0x04 - Left Rear attenuation */
195/* Subaddress 0x05 - Right Front attenuation */
196/* Subaddress 0x06 - Right Rear attenuation */
197
198/* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB
199 * in 1.5dB steps.
200 *
201 * 0x00 is 0dB
202 * 0x1f is -37.5dB
203 *
204 * Bit 5 mutes that channel when set (1 = mute, 0 = unmute)
205 * We'll use the mute on the input, though (above)
206 * Bits 6,7 unused
207 */
208
209#define TDA7432_ATTEN_0DB 0x00
210#define TDA7432_MUTE 0x1 << 5
211
212
213/* Subaddress 0x07 - Loudness Control */
214
215/* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps
216 * when bit 4 is NOT set
217 *
218 * 0x0 is 0dB
219 * 0xf is -15dB
220 *
221 * If bit 4 is set, then there is a flat attenuation according to
222 * the lower 4 bits, as above.
223 *
224 * Bits 5,6,7 unused
225 */
226
227
228
229/* Begin code */
230
231static int tda7432_write(struct i2c_client *client, int subaddr, int val)
232{
233 unsigned char buffer[2];
234 d2printk("tda7432: In tda7432_write\n");
235 dprintk("tda7432: Writing %d 0x%x\n", subaddr, val);
236 buffer[0] = subaddr;
237 buffer[1] = val;
238 if (2 != i2c_master_send(client,buffer,2)) {
239 printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n",
240 subaddr, val);
241 return -1;
242 }
243 return 0;
244}
245
246/* I don't think we ever actually _read_ the chip... */
247#if 0
248static int tda7432_read(struct i2c_client *client)
249{
250 unsigned char buffer;
251 d2printk("tda7432: In tda7432_read\n");
252 if (1 != i2c_master_recv(client,&buffer,1)) {
253 printk(KERN_WARNING "tda7432: I/O error, trying (read)\n");
254 return -1;
255 }
256 dprintk("tda7432: Read 0x%02x\n", buffer);
257 return buffer;
258}
259#endif
260
261static int tda7432_set(struct i2c_client *client)
262{
263 struct tda7432 *t = i2c_get_clientdata(client);
264 unsigned char buf[16];
265 d2printk("tda7432: In tda7432_set\n");
266
267 dprintk(KERN_INFO
268 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
269 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud);
270 buf[0] = TDA7432_IN;
271 buf[1] = t->input;
272 buf[2] = t->volume;
273 buf[3] = t->bass;
274 buf[4] = t->treble;
275 buf[5] = t->lf;
276 buf[6] = t->lr;
277 buf[7] = t->rf;
278 buf[8] = t->rr;
279 buf[9] = t->loud;
280 if (10 != i2c_master_send(client,buf,10)) {
281 printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n");
282 return -1;
283 }
284
285 return 0;
286}
287
288static void do_tda7432_init(struct i2c_client *client)
289{
290 struct tda7432 *t = i2c_get_clientdata(client);
291 d2printk("tda7432: In tda7432_init\n");
292
293 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
294 TDA7432_BASS_SYM | /* Symmetric bass cut */
295 TDA7432_BASS_NORM; /* Normal bass range */
296 t->volume = 0x3b ; /* -27dB Volume */
297 if (loudness) /* Turn loudness on? */
298 t->volume |= TDA7432_LD_ON;
299 t->muted = VIDEO_AUDIO_MUTE;
300 t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */
301 t->bass = TDA7432_BASS_0DB; /* 0dB Bass */
302 t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
303 t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
304 t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
305 t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
306 t->loud = loudness; /* insmod parameter */
307
308 tda7432_set(client);
309}
310
311/* *********************** *
312 * i2c interface functions *
313 * *********************** */
314
315static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
316{
317 struct tda7432 *t;
318 struct i2c_client *client;
319 d2printk("tda7432: In tda7432_attach\n");
320
321 t = kmalloc(sizeof *t,GFP_KERNEL);
322 if (!t)
323 return -ENOMEM;
324 memset(t,0,sizeof *t);
325
326 client = &t->c;
327 memcpy(client,&client_template,sizeof(struct i2c_client));
328 client->adapter = adap;
329 client->addr = addr;
330 i2c_set_clientdata(client, t);
331
332 do_tda7432_init(client);
333 printk(KERN_INFO "tda7432: init\n");
334
335 i2c_attach_client(client);
336 return 0;
337}
338
339static int tda7432_probe(struct i2c_adapter *adap)
340{
341#ifdef I2C_CLASS_TV_ANALOG
342 if (adap->class & I2C_CLASS_TV_ANALOG)
343 return i2c_probe(adap, &addr_data, tda7432_attach);
344#else
345 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
346 return i2c_probe(adap, &addr_data, tda7432_attach);
347#endif
348 return 0;
349}
350
351static int tda7432_detach(struct i2c_client *client)
352{
353 struct tda7432 *t = i2c_get_clientdata(client);
354
355 do_tda7432_init(client);
356 i2c_detach_client(client);
357
358 kfree(t);
359 return 0;
360}
361
362static int tda7432_command(struct i2c_client *client,
363 unsigned int cmd, void *arg)
364{
365 struct tda7432 *t = i2c_get_clientdata(client);
366 d2printk("tda7432: In tda7432_command\n");
367
368 switch (cmd) {
369 /* --- v4l ioctls --- */
370 /* take care: bttv does userspace copying, we'll get a
371 kernel pointer here... */
372
373 /* Query card - scale from TDA7432 settings to V4L settings */
374 case VIDIOCGAUDIO:
375 {
376 struct video_audio *va = arg;
377 dprintk("tda7432: VIDIOCGAUDIO\n");
378
379 va->flags |= VIDEO_AUDIO_VOLUME |
380 VIDEO_AUDIO_BASS |
381 VIDEO_AUDIO_TREBLE |
382 VIDEO_AUDIO_MUTABLE;
383 if (t->muted)
384 va->flags |= VIDEO_AUDIO_MUTE;
385 va->mode |= VIDEO_SOUND_STEREO;
386 /* Master volume control
387 * V4L volume is min 0, max 65535
388 * TDA7432 Volume:
389 * Min (-79dB) is 0x6f
390 * Max (+20dB) is 0x07 (630)
391 * Max (0dB) is 0x20 (829)
392 * (Mask out bit 7 of vol - it's for the loudness setting)
393 */
394 if (!maxvol){ /* max +20db */
395 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630;
396 } else { /* max 0db */
397 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 829;
398 }
399
400 /* Balance depends on L,R attenuation
401 * V4L balance is 0 to 65535, middle is 32768
402 * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f
403 * to scale up to V4L numbers, mult by 1057
404 * attenuation exists for lf, lr, rf, rr
405 * we use only lf and rf (front channels)
406 */
407
408 if ( (t->lf) < (t->rf) )
409 /* right is attenuated, balance shifted left */
410 va->balance = (32768 - 1057*(t->rf));
411 else
412 /* left is attenuated, balance shifted right */
413 va->balance = (32768 + 1057*(t->lf));
414
415 /* Bass/treble 4 bits each */
416 va->bass=t->bass;
417 if(va->bass >= 0x8)
418 va->bass = ~(va->bass - 0x8) & 0xf;
419 va->bass = (va->bass << 12)+(va->bass << 8)+(va->bass << 4)+(va->bass);
420 va->treble=t->treble;
421 if(va->treble >= 0x8)
422 va->treble = ~(va->treble - 0x8) & 0xf;
423 va->treble = (va->treble << 12)+(va->treble << 8)+(va->treble << 4)+(va->treble);
424
425 break; /* VIDIOCGAUDIO case */
426 }
427
428 /* Set card - scale from V4L settings to TDA7432 settings */
429 case VIDIOCSAUDIO:
430 {
431 struct video_audio *va = arg;
432 dprintk("tda7432: VIDEOCSAUDIO\n");
433
434 if(va->flags & VIDEO_AUDIO_VOLUME){
435 if(!maxvol){ /* max +20db */
436 t->volume = 0x6f - ((va->volume)/630);
437 } else { /* max 0db */
438 t->volume = 0x6f - ((va->volume)/829);
439 }
440
441 if (loudness) /* Turn on the loudness bit */
442 t->volume |= TDA7432_LD_ON;
443
444 tda7432_write(client,TDA7432_VL, t->volume);
445 }
446
447 if(va->flags & VIDEO_AUDIO_BASS)
448 {
449 t->bass = va->bass >> 12;
450 if(t->bass>= 0x8)
451 t->bass = (~t->bass & 0xf) + 0x8 ;
452 }
453 if(va->flags & VIDEO_AUDIO_TREBLE)
454 {
455 t->treble= va->treble >> 12;
456 if(t->treble>= 0x8)
457 t->treble = (~t->treble & 0xf) + 0x8 ;
458 }
459 if(va->flags & (VIDEO_AUDIO_TREBLE| VIDEO_AUDIO_BASS))
460 tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble );
461
462 if(va->flags & VIDEO_AUDIO_BALANCE) {
463 if (va->balance < 32768)
464 {
465 /* shifted to left, attenuate right */
466 t->rr = (32768 - va->balance)/1057;
467 t->rf = t->rr;
468 t->lr = TDA7432_ATTEN_0DB;
469 t->lf = TDA7432_ATTEN_0DB;
470 }
471 else if(va->balance > 32769)
472 {
473 /* shifted to right, attenuate left */
474 t->lf = (va->balance - 32768)/1057;
475 t->lr = t->lf;
476 t->rr = TDA7432_ATTEN_0DB;
477 t->rf = TDA7432_ATTEN_0DB;
478 }
479 else
480 {
481 /* centered */
482 t->rr = TDA7432_ATTEN_0DB;
483 t->rf = TDA7432_ATTEN_0DB;
484 t->lf = TDA7432_ATTEN_0DB;
485 t->lr = TDA7432_ATTEN_0DB;
486 }
487 }
488
489 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
490 if (t->muted)
491 {
492 /* Mute & update balance*/
493 tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE);
494 tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE);
495 tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE);
496 tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE);
497 } else {
498 tda7432_write(client,TDA7432_LF, t->lf);
499 tda7432_write(client,TDA7432_LR, t->lr);
500 tda7432_write(client,TDA7432_RF, t->rf);
501 tda7432_write(client,TDA7432_RR, t->rr);
502 }
503
504 break;
505
506 } /* end of VIDEOCSAUDIO case */
507
508 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
509
510 /* nothing */
511 d2printk("tda7432: Default\n");
512
513 } /* end of (cmd) switch */
514
515 return 0;
516}
517
518static struct i2c_driver driver = {
519 .owner = THIS_MODULE,
520 .name = "i2c tda7432 driver",
521 .id = I2C_DRIVERID_TDA7432,
522 .flags = I2C_DF_NOTIFY,
523 .attach_adapter = tda7432_probe,
524 .detach_client = tda7432_detach,
525 .command = tda7432_command,
526};
527
528static struct i2c_client client_template =
529{
530 I2C_DEVNAME("tda7432"),
531 .driver = &driver,
532};
533
534static int __init tda7432_init(void)
535{
536 if ( (loudness < 0) || (loudness > 15) ) {
537 printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
538 return -EINVAL;
539 }
540
541 return i2c_add_driver(&driver);
542}
543
544static void __exit tda7432_fini(void)
545{
546 i2c_del_driver(&driver);
547}
548
549module_init(tda7432_init);
550module_exit(tda7432_fini);
551
552/*
553 * Local variables:
554 * c-basic-offset: 8
555 * End:
556 */
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
new file mode 100644
index 000000000000..b27cc348d95c
--- /dev/null
+++ b/drivers/media/video/tda8290.c
@@ -0,0 +1,224 @@
1/*
2 * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls the philips tda8290+75 tuner chip combo.
6 */
7#include <linux/i2c.h>
8#include <linux/videodev.h>
9#include <linux/delay.h>
10#include <media/tuner.h>
11
12/* ---------------------------------------------------------------------- */
13
14struct freq_entry {
15 u16 freq;
16 u8 value;
17};
18
19static struct freq_entry band_table[] = {
20 { 0x2DF4, 0x1C },
21 { 0x2574, 0x14 },
22 { 0x22B4, 0x0C },
23 { 0x20D4, 0x0B },
24 { 0x1E74, 0x3B },
25 { 0x1C34, 0x33 },
26 { 0x16F4, 0x5B },
27 { 0x1454, 0x53 },
28 { 0x12D4, 0x52 },
29 { 0x1034, 0x4A },
30 { 0x0EE4, 0x7A },
31 { 0x0D34, 0x72 },
32 { 0x0B54, 0x9A },
33 { 0x0914, 0x91 },
34 { 0x07F4, 0x89 },
35 { 0x0774, 0xB9 },
36 { 0x067B, 0xB1 },
37 { 0x0634, 0xD9 },
38 { 0x05A4, 0xD8 }, // FM radio
39 { 0x0494, 0xD0 },
40 { 0x03BC, 0xC8 },
41 { 0x0394, 0xF8 }, // 57250000 Hz
42 { 0x0000, 0xF0 }, // 0
43};
44
45static struct freq_entry div_table[] = {
46 { 0x1C34, 3 },
47 { 0x0D34, 2 },
48 { 0x067B, 1 },
49 { 0x0000, 0 },
50};
51
52static struct freq_entry agc_table[] = {
53 { 0x22B4, 0x8F },
54 { 0x0B54, 0x9F },
55 { 0x09A4, 0x8F },
56 { 0x0554, 0x9F },
57 { 0x0000, 0xBF },
58};
59
60static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
61{
62 while(table->freq && table->freq > freq)
63 table++;
64 return table->value;
65}
66
67/* ---------------------------------------------------------------------- */
68
69static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 };
70static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
71static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
72 0x7C, 0x04, 0xA3, 0x3F,
73 0x2A, 0x04, 0xFF, 0x00,
74 0x00, 0x40 };
75static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
76static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
77static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
78static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
79static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
80static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
81static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
82static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
83static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
84static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
85static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
86static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
87static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
88
89static struct i2c_msg i2c_msg_init[] = {
90 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
91 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
92 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
93 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
94};
95
96static struct i2c_msg i2c_msg_prolog[] = {
97// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode },
98 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off },
99 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset },
100 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
101};
102
103static struct i2c_msg i2c_msg_config[] = {
104// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq },
105 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 },
106 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF },
107 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 },
108 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 },
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 },
110};
111
112static struct i2c_msg i2c_msg_epilog[] = {
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 },
114 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F },
115 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 },
116 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
117 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on },
118};
119
120static int tda8290_tune(struct i2c_client *c)
121{
122 struct tuner *t = i2c_get_clientdata(c);
123 struct i2c_msg easy_mode =
124 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
125 struct i2c_msg set_freq =
126 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
127
128 i2c_transfer(c->adapter, &easy_mode, 1);
129 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog));
130
131 i2c_transfer(c->adapter, &set_freq, 1);
132 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config));
133
134 msleep(550);
135 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog));
136 return 0;
137}
138
139static void set_frequency(struct tuner *t, u16 ifc)
140{
141 u32 N = (((t->freq<<3)+ifc)&0x3fffc);
142
143 N = N >> get_freq_entry(div_table, t->freq);
144 t->i2c_set_freq[0] = 0;
145 t->i2c_set_freq[1] = (unsigned char)(N>>8);
146 t->i2c_set_freq[2] = (unsigned char) N;
147 t->i2c_set_freq[3] = 0x40;
148 t->i2c_set_freq[4] = 0x52;
149 t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
150 t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq);
151 t->i2c_set_freq[7] = 0x8f;
152}
153
154#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
155#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
156#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
157#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
158
159static void set_audio(struct tuner *t)
160{
161 t->i2c_easy_mode[0] = 0x01;
162
163 if (t->std & V4L2_STD_MN)
164 t->i2c_easy_mode[1] = 0x01;
165 else if (t->std & V4L2_STD_B)
166 t->i2c_easy_mode[1] = 0x02;
167 else if (t->std & V4L2_STD_GH)
168 t->i2c_easy_mode[1] = 0x04;
169 else if (t->std & V4L2_STD_PAL_I)
170 t->i2c_easy_mode[1] = 0x08;
171 else if (t->std & V4L2_STD_DK)
172 t->i2c_easy_mode[1] = 0x10;
173 else if (t->std & V4L2_STD_SECAM_L)
174 t->i2c_easy_mode[1] = 0x20;
175}
176
177static void set_tv_freq(struct i2c_client *c, unsigned int freq)
178{
179 struct tuner *t = i2c_get_clientdata(c);
180
181 set_audio(t);
182 set_frequency(t, 864);
183 tda8290_tune(c);
184}
185
186static void set_radio_freq(struct i2c_client *c, unsigned int freq)
187{
188 struct tuner *t = i2c_get_clientdata(c);
189 set_frequency(t, 704);
190 tda8290_tune(c);
191}
192
193static int has_signal(struct i2c_client *c)
194{
195 unsigned char i2c_get_afc[1] = { 0x1B };
196 unsigned char afc = 0;
197
198 i2c_master_send(c, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
199 i2c_master_recv(c, &afc, 1);
200 return (afc & 0x80)? 65535:0;
201}
202
203int tda8290_init(struct i2c_client *c)
204{
205 struct tuner *t = i2c_get_clientdata(c);
206
207 strlcpy(c->name, "tda8290+75", sizeof(c->name));
208 tuner_info("tuner: type set to %s\n", c->name);
209 t->tv_freq = set_tv_freq;
210 t->radio_freq = set_radio_freq;
211 t->has_signal = has_signal;
212
213 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge));
214 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init));
215 return 0;
216}
217
218/*
219 * Overrides for Emacs so that we follow Linus's tabbing style.
220 * ---------------------------------------------------------------------------
221 * Local variables:
222 * c-basic-offset: 8
223 * End:
224 */
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
new file mode 100644
index 000000000000..b5177c6f54f6
--- /dev/null
+++ b/drivers/media/video/tda9840.c
@@ -0,0 +1,254 @@
1 /*
2 tda9840 - i2c-driver for the tda9840 by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tda9840 is a stereo/dual sound processor with digital
7 identification. It can be found at address 0x84 on the i2c-bus.
8
9 For detailed informations download the specifications directly
10 from SGS Thomson at http://www.st.com
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/ioctl.h>
29#include <linux/i2c.h>
30
31#include "tda9840.h"
32
33static int debug = 0; /* insmod parameter */
34module_param(debug, int, 0644);
35MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
36#define dprintk(args...) \
37 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
38
39#define SWITCH 0x00
40#define LEVEL_ADJUST 0x02
41#define STEREO_ADJUST 0x03
42#define TEST 0x04
43
44/* addresses to scan, found only at 0x42 (7-Bit) */
45static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END };
46static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
47
48/* magic definition of all other variables and things */
49I2C_CLIENT_INSMOD;
50
51static struct i2c_driver driver;
52static struct i2c_client client_template;
53
54static int command(struct i2c_client *client, unsigned int cmd, void *arg)
55{
56 int result;
57 int byte = *(int *)arg;
58
59 switch (cmd) {
60 case TDA9840_SWITCH:
61
62 dprintk("TDA9840_SWITCH: 0x%02x\n", byte);
63
64 if (byte != TDA9840_SET_MONO
65 && byte != TDA9840_SET_MUTE
66 && byte != TDA9840_SET_STEREO
67 && byte != TDA9840_SET_LANG1
68 && byte != TDA9840_SET_LANG2
69 && byte != TDA9840_SET_BOTH
70 && byte != TDA9840_SET_BOTH_R
71 && byte != TDA9840_SET_EXTERNAL) {
72 return -EINVAL;
73 }
74
75 result = i2c_smbus_write_byte_data(client, SWITCH, byte);
76 if (result)
77 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
78 break;
79
80 case TDA9840_LEVEL_ADJUST:
81
82 dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte);
83
84 /* check for correct range */
85 if (byte > 25 || byte < -20)
86 return -EINVAL;
87
88 /* calculate actual value to set, see specs, page 18 */
89 byte /= 5;
90 if (0 < byte)
91 byte += 0x8;
92 else
93 byte = -byte;
94
95 result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte);
96 if (result)
97 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
98 break;
99
100 case TDA9840_STEREO_ADJUST:
101
102 dprintk("TDA9840_STEREO_ADJUST: %d\n", byte);
103
104 /* check for correct range */
105 if (byte > 25 || byte < -24)
106 return -EINVAL;
107
108 /* calculate actual value to set */
109 byte /= 5;
110 if (0 < byte)
111 byte += 0x20;
112 else
113 byte = -byte;
114
115 result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte);
116 if (result)
117 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
118 break;
119
120 case TDA9840_DETECT: {
121 int *ret = (int *)arg;
122
123 byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST);
124 if (byte == -1) {
125 dprintk("i2c_smbus_read_byte_data() failed\n");
126 return -EIO;
127 }
128
129 if (0 != (byte & 0x80)) {
130 dprintk("TDA9840_DETECT: register contents invalid\n");
131 return -EINVAL;
132 }
133
134 dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte);
135 *ret = ((byte & 0x60) >> 5);
136 result = 0;
137 break;
138 }
139 case TDA9840_TEST:
140 dprintk("TDA9840_TEST: 0x%02x\n", byte);
141
142 /* mask out irrelevant bits */
143 byte &= 0x3;
144
145 result = i2c_smbus_write_byte_data(client, TEST, byte);
146 if (result)
147 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
148 break;
149 default:
150 return -ENOIOCTLCMD;
151 }
152
153 if (result)
154 return -EIO;
155
156 return 0;
157}
158
159static int detect(struct i2c_adapter *adapter, int address, int kind)
160{
161 struct i2c_client *client;
162 int result = 0;
163
164 int byte = 0x0;
165
166 /* let's see whether this adapter can support what we need */
167 if (0 == i2c_check_functionality(adapter,
168 I2C_FUNC_SMBUS_READ_BYTE_DATA |
169 I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
170 return 0;
171 }
172
173 /* allocate memory for client structure */
174 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
175 if (0 == client) {
176 printk("not enough kernel memory\n");
177 return -ENOMEM;
178 }
179
180 /* fill client structure */
181 memcpy(client, &client_template, sizeof(struct i2c_client));
182 client->addr = address;
183 client->adapter = adapter;
184
185 /* tell the i2c layer a new client has arrived */
186 if (0 != (result = i2c_attach_client(client))) {
187 kfree(client);
188 return result;
189 }
190
191 /* set initial values for level & stereo - adjustment, mode */
192 byte = 0;
193 result = command(client, TDA9840_LEVEL_ADJUST, &byte);
194 result += command(client, TDA9840_STEREO_ADJUST, &byte);
195 byte = TDA9840_SET_MONO;
196 result = command(client, TDA9840_SWITCH, &byte);
197 if (result) {
198 dprintk("could not initialize tda9840\n");
199 return -ENODEV;
200 }
201
202 printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
203 return 0;
204}
205
206static int attach(struct i2c_adapter *adapter)
207{
208 /* let's see whether this is a know adapter we can attach to */
209 if (adapter->id != I2C_ALGO_SAA7146) {
210 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
211 return -ENODEV;
212 }
213
214 return i2c_probe(adapter, &addr_data, &detect);
215}
216
217static int detach(struct i2c_client *client)
218{
219 int ret = i2c_detach_client(client);
220 kfree(client);
221 return ret;
222}
223
224static struct i2c_driver driver = {
225 .owner = THIS_MODULE,
226 .name = "tda9840",
227 .id = I2C_DRIVERID_TDA9840,
228 .flags = I2C_DF_NOTIFY,
229 .attach_adapter = attach,
230 .detach_client = detach,
231 .command = command,
232};
233
234static struct i2c_client client_template = {
235 I2C_DEVNAME("tda9840"),
236 .driver = &driver,
237};
238
239static int __init this_module_init(void)
240{
241 return i2c_add_driver(&driver);
242}
243
244static void __exit this_module_exit(void)
245{
246 i2c_del_driver(&driver);
247}
248
249module_init(this_module_init);
250module_exit(this_module_exit);
251
252MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
253MODULE_DESCRIPTION("tda9840 driver");
254MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h
new file mode 100644
index 000000000000..28021053bd09
--- /dev/null
+++ b/drivers/media/video/tda9840.h
@@ -0,0 +1,35 @@
1#ifndef __INCLUDED_TDA9840__
2#define __INCLUDED_TDA9840__
3
4#define I2C_TDA9840 0x42
5
6#define TDA9840_DETECT _IOR('v',1,int)
7/* return values for TDA9840_DETCT */
8#define TDA9840_MONO_DETECT 0x0
9#define TDA9840_DUAL_DETECT 0x1
10#define TDA9840_STEREO_DETECT 0x2
11#define TDA9840_INCORRECT_DETECT 0x3
12
13#define TDA9840_SWITCH _IOW('v',2,int)
14/* modes than can be set with TDA9840_SWITCH */
15#define TDA9840_SET_MUTE 0x00
16#define TDA9840_SET_MONO 0x10
17#define TDA9840_SET_STEREO 0x2a
18#define TDA9840_SET_LANG1 0x12
19#define TDA9840_SET_LANG2 0x1e
20#define TDA9840_SET_BOTH 0x1a
21#define TDA9840_SET_BOTH_R 0x16
22#define TDA9840_SET_EXTERNAL 0x7a
23
24/* values may range between +2.5 and -2.0;
25 the value has to be multiplied with 10 */
26#define TDA9840_LEVEL_ADJUST _IOW('v',3,int)
27
28/* values may range between +2.5 and -2.4;
29 the value has to be multiplied with 10 */
30#define TDA9840_STEREO_ADJUST _IOW('v',4,int)
31
32/* currently not implemented */
33#define TDA9840_TEST _IOW('v',5,int)
34
35#endif
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
new file mode 100644
index 000000000000..4f1114c033a1
--- /dev/null
+++ b/drivers/media/video/tda9875.c
@@ -0,0 +1,423 @@
1/*
2 * For the TDA9875 chip
3 * (The TDA9875 is used on the Diamond DTV2000 french version
4 * Other cards probably use these chips as well.)
5 * This driver will not complain if used with any
6 * other i2c device with the same address.
7 *
8 * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source and
9 * Eric Sandeen
10 * This code is placed under the terms of the GNU General Public License
11 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
12 * Which was based on tda8425.c by Greg Alexander (c) 1998
13 *
14 * OPTIONS:
15 * debug - set to 1 if you'd like to see debug messages
16 *
17 * Revision: 0.1 - original version
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/string.h>
24#include <linux/timer.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h>
31#include <linux/init.h>
32
33#include "bttv.h"
34#include <media/audiochip.h>
35#include <media/id.h>
36
37static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR);
39MODULE_LICENSE("GPL");
40
41
42/* Addresses to scan */
43static unsigned short normal_i2c[] = {
44 I2C_TDA9875 >> 1,
45 I2C_CLIENT_END
46};
47static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
48I2C_CLIENT_INSMOD;
49
50/* This is a superset of the TDA9875 */
51struct tda9875 {
52 int mode;
53 int rvol, lvol;
54 int bass, treble;
55 struct i2c_client c;
56};
57
58static struct i2c_driver driver;
59static struct i2c_client client_template;
60
61#define dprintk if (debug) printk
62
63/* The TDA9875 is made by Philips Semiconductor
64 * http://www.semiconductors.philips.com
65 * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
66 *
67 */
68
69 /* subaddresses for TDA9875 */
70#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
71#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
72#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
73#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
74
75#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
76#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
77#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
78#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
79
80#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
81#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
82#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
83#define TDA9875_MVL 0x1a /* Main volume gauche */
84#define TDA9875_MVR 0x1b /* Main volume droite */
85#define TDA9875_MBA 0x1d /* Main Basse */
86#define TDA9875_MTR 0x1e /* Main treble */
87#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
88#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
89#define TDA9875_AVR 0x21 /* Auxilary volume droite */
90#define TDA9875_ABA 0x22 /* Auxilary Basse */
91#define TDA9875_ATR 0x23 /* Auxilary treble */
92
93#define TDA9875_MSR 0x02 /* Monitor select register */
94#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
95#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
96#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
97#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
98#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
99#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
100#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
101#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
102#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
103
104/* values */
105#define TDA9875_MUTE_ON 0xff /* general mute */
106#define TDA9875_MUTE_OFF 0xcc /* general no mute */
107
108
109
110/* Begin code */
111
112static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char val)
113{
114 unsigned char buffer[2];
115 dprintk("In tda9875_write\n");
116 dprintk("Writing %d 0x%x\n", subaddr, val);
117 buffer[0] = subaddr;
118 buffer[1] = val;
119 if (2 != i2c_master_send(client,buffer,2)) {
120 printk(KERN_WARNING "tda9875: I/O error, trying (write %d 0x%x)\n",
121 subaddr, val);
122 return -1;
123 }
124 return 0;
125}
126
127#if 0
128static int tda9875_read(struct i2c_client *client)
129{
130 unsigned char buffer;
131 dprintk("In tda9875_read\n");
132 if (1 != i2c_master_recv(client,&buffer,1)) {
133 printk(KERN_WARNING "tda9875: I/O error, trying (read)\n");
134 return -1;
135 }
136 dprintk("Read 0x%02x\n", buffer);
137 return buffer;
138}
139#endif
140
141static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
142{
143 unsigned char write[1];
144 unsigned char read[1];
145 struct i2c_msg msgs[2] = {
146 { addr, 0, 1, write },
147 { addr, I2C_M_RD, 1, read }
148 };
149 write[0] = reg;
150
151 if (2 != i2c_transfer(adap,msgs,2)) {
152 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
153 return -1;
154 }
155 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
156 return read[0];
157}
158
159static void tda9875_set(struct i2c_client *client)
160{
161 struct tda9875 *tda = i2c_get_clientdata(client);
162 unsigned char a;
163
164 dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",
165 tda->lvol,tda->rvol,tda->bass,tda->treble);
166
167
168 a = tda->lvol & 0xff;
169 tda9875_write(client, TDA9875_MVL, a);
170 a =tda->rvol & 0xff;
171 tda9875_write(client, TDA9875_MVR, a);
172 a =tda->bass & 0xff;
173 tda9875_write(client, TDA9875_MBA, a);
174 a =tda->treble & 0xff;
175 tda9875_write(client, TDA9875_MTR, a);
176}
177
178static void do_tda9875_init(struct i2c_client *client)
179{
180 struct tda9875 *t = i2c_get_clientdata(client);
181 dprintk("In tda9875_init\n");
182 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/
183 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/
184 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/
185 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/
186 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/
187 tda9875_write(client, TDA9875_C2MSB, 0x00 ); /*Car2(NICAM) MSB XMHz*/
188 tda9875_write(client, TDA9875_C2MIB, 0x00 ); /*Car2(NICAM) MIB XMHz*/
189 tda9875_write(client, TDA9875_C2LSB, 0x00 ); /*Car2(NICAM) LSB XMHz*/
190 tda9875_write(client, TDA9875_DCR, 0x00 ); /*Demod config 0x00*/
191 tda9875_write(client, TDA9875_DEEM, 0x44 ); /*DE-Emph 0b0100 0100*/
192 tda9875_write(client, TDA9875_FMAT, 0x00 ); /*FM Matrix reg 0x00*/
193 tda9875_write(client, TDA9875_SC1, 0x00 ); /* SCART 1 (SC1)*/
194 tda9875_write(client, TDA9875_SC2, 0x01 ); /* SCART 2 (sc2)*/
195
196 tda9875_write(client, TDA9875_CH1V, 0x10 ); /* Channel volume 1 mute*/
197 tda9875_write(client, TDA9875_CH2V, 0x10 ); /* Channel volume 2 mute */
198 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
199 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
200 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
201 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
202 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
203 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
204 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
205 tda9875_write(client, TDA9875_MBA, 0x00 ); /* Main Bass Main 0dB*/
206 tda9875_write(client, TDA9875_MTR, 0x00 ); /* Main Treble Main 0dB*/
207 tda9875_write(client, TDA9875_ACS, 0x44 ); /* Aux chan select (dac)*/
208 tda9875_write(client, TDA9875_AVL, 0x00 ); /* Vol Aux left 0dB*/
209 tda9875_write(client, TDA9875_AVR, 0x00 ); /* Vol Aux right 0dB*/
210 tda9875_write(client, TDA9875_ABA, 0x00 ); /* Aux Bass Main 0dB*/
211 tda9875_write(client, TDA9875_ATR, 0x00 ); /* Aux Aigus Main 0dB*/
212
213 tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */
214
215 t->mode=AUDIO_UNMUTE;
216 t->lvol=t->rvol =0; /* 0dB */
217 t->bass=0; /* 0dB */
218 t->treble=0; /* 0dB */
219 tda9875_set(client);
220
221}
222
223
224/* *********************** *
225 * i2c interface functions *
226 * *********************** */
227
228static int tda9875_checkit(struct i2c_adapter *adap, int addr)
229{
230 int dic,rev;
231
232 dic=i2c_read_register(adap,addr,254);
233 rev=i2c_read_register(adap,addr,255);
234
235 if(dic==0 || dic==2) { // tda9875 and tda9875A
236 printk("tda9875: TDA9875%s Rev.%d detected at 0x%x\n",
237 dic==0?"":"A", rev,addr<<1);
238 return 1;
239 }
240 printk("tda9875: no such chip at 0x%x (dic=0x%x rev=0x%x)\n",addr<<1,dic,rev);
241 return(0);
242}
243
244static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
245{
246 struct tda9875 *t;
247 struct i2c_client *client;
248 dprintk("In tda9875_attach\n");
249
250 t = kmalloc(sizeof *t,GFP_KERNEL);
251 if (!t)
252 return -ENOMEM;
253 memset(t,0,sizeof *t);
254
255 client = &t->c;
256 memcpy(client,&client_template,sizeof(struct i2c_client));
257 client->adapter = adap;
258 client->addr = addr;
259 i2c_set_clientdata(client, t);
260
261 if(!tda9875_checkit(adap,addr)) {
262 kfree(t);
263 return 1;
264 }
265
266 do_tda9875_init(client);
267 printk(KERN_INFO "tda9875: init\n");
268
269 i2c_attach_client(client);
270 return 0;
271}
272
273static int tda9875_probe(struct i2c_adapter *adap)
274{
275#ifdef I2C_CLASS_TV_ANALOG
276 if (adap->class & I2C_CLASS_TV_ANALOG)
277 return i2c_probe(adap, &addr_data, tda9875_attach);
278#else
279 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
280 return i2c_probe(adap, &addr_data, tda9875_attach);
281#endif
282 return 0;
283}
284
285static int tda9875_detach(struct i2c_client *client)
286{
287 struct tda9875 *t = i2c_get_clientdata(client);
288
289 do_tda9875_init(client);
290 i2c_detach_client(client);
291
292 kfree(t);
293 return 0;
294}
295
296static int tda9875_command(struct i2c_client *client,
297 unsigned int cmd, void *arg)
298{
299 struct tda9875 *t = i2c_get_clientdata(client);
300
301 dprintk("In tda9875_command...\n");
302
303 switch (cmd) {
304 /* --- v4l ioctls --- */
305 /* take care: bttv does userspace copying, we'll get a
306 kernel pointer here... */
307 case VIDIOCGAUDIO:
308 {
309 struct video_audio *va = arg;
310 int left,right;
311
312 dprintk("VIDIOCGAUDIO\n");
313
314 va->flags |= VIDEO_AUDIO_VOLUME |
315 VIDEO_AUDIO_BASS |
316 VIDEO_AUDIO_TREBLE;
317
318 /* min is -84 max is 24 */
319 left = (t->lvol+84)*606;
320 right = (t->rvol+84)*606;
321 va->volume=max(left,right);
322 va->balance=(32768*min(left,right))/
323 (va->volume ? va->volume : 1);
324 va->balance=(left<right)?
325 (65535-va->balance) : va->balance;
326 va->bass = (t->bass+12)*2427; /* min -12 max +15 */
327 va->treble = (t->treble+12)*2730;/* min -12 max +12 */
328 va->mode |= VIDEO_SOUND_MONO;
329
330 break; /* VIDIOCGAUDIO case */
331 }
332
333 case VIDIOCSAUDIO:
334 {
335 struct video_audio *va = arg;
336 int left,right;
337
338 dprintk("VIDEOCSAUDIO...\n");
339 left = (min(65536 - va->balance,32768) *
340 va->volume) / 32768;
341 right = (min(va->balance,(__u16)32768) *
342 va->volume) / 32768;
343 t->lvol = ((left/606)-84) & 0xff;
344 if (t->lvol > 24)
345 t->lvol = 24;
346 if (t->lvol < -84)
347 t->lvol = -84 & 0xff;
348
349 t->rvol = ((right/606)-84) & 0xff;
350 if (t->rvol > 24)
351 t->rvol = 24;
352 if (t->rvol < -84)
353 t->rvol = -84 & 0xff;
354
355 t->bass = ((va->bass/2400)-12) & 0xff;
356 if (t->bass > 15)
357 t->bass = 15;
358 if (t->bass < -12)
359 t->bass = -12 & 0xff;
360
361 t->treble = ((va->treble/2700)-12) & 0xff;
362 if (t->treble > 12)
363 t->treble = 12;
364 if (t->treble < -12)
365 t->treble = -12 & 0xff;
366
367
368
369//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
370
371
372 tda9875_set(client);
373
374 break;
375
376 } /* end of VIDEOCSAUDIO case */
377
378 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
379
380 /* nothing */
381 dprintk("Default\n");
382
383 } /* end of (cmd) switch */
384
385 return 0;
386}
387
388
389static struct i2c_driver driver = {
390 .owner = THIS_MODULE,
391 .name = "i2c tda9875 driver",
392 .id = I2C_DRIVERID_TDA9875,
393 .flags = I2C_DF_NOTIFY,
394 .attach_adapter = tda9875_probe,
395 .detach_client = tda9875_detach,
396 .command = tda9875_command,
397};
398
399static struct i2c_client client_template =
400{
401 I2C_DEVNAME("tda9875"),
402 .driver = &driver,
403};
404
405static int __init tda9875_init(void)
406{
407 return i2c_add_driver(&driver);
408}
409
410static void __exit tda9875_fini(void)
411{
412 i2c_del_driver(&driver);
413}
414
415module_init(tda9875_init);
416module_exit(tda9875_fini);
417
418/*
419 * Local variables:
420 * c-basic-offset: 8
421 * End:
422 */
423
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
new file mode 100644
index 000000000000..7fb063a27961
--- /dev/null
+++ b/drivers/media/video/tda9887.c
@@ -0,0 +1,801 @@
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/i2c.h>
5#include <linux/types.h>
6#include <linux/videodev.h>
7#include <linux/init.h>
8#include <linux/errno.h>
9#include <linux/slab.h>
10#include <linux/delay.h>
11
12#include <media/audiochip.h>
13#include <media/tuner.h>
14#include <media/id.h>
15
16/* Chips:
17 TDA9885 (PAL, NTSC)
18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20
21 found on:
22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134)
26*/
27
28
29/* Addresses to scan */
30static unsigned short normal_i2c[] = {
31 0x84 >>1,
32 0x86 >>1,
33 0x96 >>1,
34 I2C_CLIENT_END,
35};
36static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
37I2C_CLIENT_INSMOD;
38
39/* insmod options */
40static unsigned int debug = 0;
41module_param(debug, int, 0644);
42MODULE_LICENSE("GPL");
43
44/* ---------------------------------------------------------------------- */
45
46#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: "
48#define dprintk if (debug) printk
49
50struct tda9887 {
51 struct i2c_client client;
52 v4l2_std_id std;
53 unsigned int radio;
54 unsigned int config;
55 unsigned int pinnacle_id;
56 unsigned int using_v4l2;
57};
58
59struct tvnorm {
60 v4l2_std_id std;
61 char *name;
62 unsigned char b;
63 unsigned char c;
64 unsigned char e;
65};
66
67static struct i2c_driver driver;
68static struct i2c_client client_template;
69
70/* ---------------------------------------------------------------------- */
71
72//
73// TDA defines
74//
75
76//// first reg (b)
77#define cVideoTrapBypassOFF 0x00 // bit b0
78#define cVideoTrapBypassON 0x01 // bit b0
79
80#define cAutoMuteFmInactive 0x00 // bit b1
81#define cAutoMuteFmActive 0x02 // bit b1
82
83#define cIntercarrier 0x00 // bit b2
84#define cQSS 0x04 // bit b2
85
86#define cPositiveAmTV 0x00 // bit b3:4
87#define cFmRadio 0x08 // bit b3:4
88#define cNegativeFmTV 0x10 // bit b3:4
89
90
91#define cForcedMuteAudioON 0x20 // bit b5
92#define cForcedMuteAudioOFF 0x00 // bit b5
93
94#define cOutputPort1Active 0x00 // bit b6
95#define cOutputPort1Inactive 0x40 // bit b6
96
97#define cOutputPort2Active 0x00 // bit b7
98#define cOutputPort2Inactive 0x80 // bit b7
99
100
101//// second reg (c)
102#define cDeemphasisOFF 0x00 // bit c5
103#define cDeemphasisON 0x20 // bit c5
104
105#define cDeemphasis75 0x00 // bit c6
106#define cDeemphasis50 0x40 // bit c6
107
108#define cAudioGain0 0x00 // bit c7
109#define cAudioGain6 0x80 // bit c7
110
111
112//// third reg (e)
113#define cAudioIF_4_5 0x00 // bit e0:1
114#define cAudioIF_5_5 0x01 // bit e0:1
115#define cAudioIF_6_0 0x02 // bit e0:1
116#define cAudioIF_6_5 0x03 // bit e0:1
117
118
119#define cVideoIF_58_75 0x00 // bit e2:4
120#define cVideoIF_45_75 0x04 // bit e2:4
121#define cVideoIF_38_90 0x08 // bit e2:4
122#define cVideoIF_38_00 0x0C // bit e2:4
123#define cVideoIF_33_90 0x10 // bit e2:4
124#define cVideoIF_33_40 0x14 // bit e2:4
125#define cRadioIF_45_75 0x18 // bit e2:4
126#define cRadioIF_38_90 0x1C // bit e2:4
127
128
129#define cTunerGainNormal 0x00 // bit e5
130#define cTunerGainLow 0x20 // bit e5
131
132#define cGating_18 0x00 // bit e6
133#define cGating_36 0x40 // bit e6
134
135#define cAgcOutON 0x80 // bit e7
136#define cAgcOutOFF 0x00 // bit e7
137
138/* ---------------------------------------------------------------------- */
139
140static struct tvnorm tvnorms[] = {
141 {
142 .std = V4L2_STD_PAL_BG,
143 .name = "PAL-BG",
144 .b = ( cNegativeFmTV |
145 cQSS ),
146 .c = ( cDeemphasisON |
147 cDeemphasis50 ),
148 .e = ( cAudioIF_5_5 |
149 cVideoIF_38_90 ),
150 },{
151 .std = V4L2_STD_PAL_I,
152 .name = "PAL-I",
153 .b = ( cNegativeFmTV |
154 cQSS ),
155 .c = ( cDeemphasisON |
156 cDeemphasis50 ),
157 .e = ( cAudioIF_6_0 |
158 cVideoIF_38_90 ),
159 },{
160 .std = V4L2_STD_PAL_DK,
161 .name = "PAL-DK",
162 .b = ( cNegativeFmTV |
163 cQSS ),
164 .c = ( cDeemphasisON |
165 cDeemphasis50 ),
166 .e = ( cAudioIF_6_5 |
167 cVideoIF_38_00 ),
168 },{
169 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N,
170 .name = "PAL-M/N",
171 .b = ( cNegativeFmTV |
172 cQSS ),
173 .c = ( cDeemphasisON |
174 cDeemphasis75 ),
175 .e = ( cAudioIF_4_5 |
176 cVideoIF_45_75 ),
177 },{
178 .std = V4L2_STD_SECAM_L,
179 .name = "SECAM-L",
180 .b = ( cPositiveAmTV |
181 cQSS ),
182 .e = ( cAudioIF_6_5 |
183 cVideoIF_38_90 ),
184 },{
185 .std = V4L2_STD_SECAM_DK,
186 .name = "SECAM-DK",
187 .b = ( cNegativeFmTV |
188 cQSS ),
189 .c = ( cDeemphasisON |
190 cDeemphasis50 ),
191 .e = ( cAudioIF_6_5 |
192 cVideoIF_38_00 ),
193 },{
194 .std = V4L2_STD_NTSC_M,
195 .name = "NTSC-M",
196 .b = ( cNegativeFmTV |
197 cQSS ),
198 .c = ( cDeemphasisON |
199 cDeemphasis50 ),
200 .e = ( cGating_36 |
201 cAudioIF_4_5 |
202 cVideoIF_45_75 ),
203 },{
204 .std = V4L2_STD_NTSC_M_JP,
205 .name = "NTSC-JP",
206 .b = ( cNegativeFmTV |
207 cQSS ),
208 .c = ( cDeemphasisON |
209 cDeemphasis50 ),
210 .e = ( cGating_36 |
211 cAudioIF_4_5 |
212 cVideoIF_58_75 ),
213 }
214};
215
216static struct tvnorm radio = {
217 .name = "radio",
218 .b = ( cFmRadio |
219 cQSS ),
220 .c = ( cDeemphasisON |
221 cDeemphasis50 ),
222 .e = ( cAudioIF_5_5 |
223 cRadioIF_38_90 ),
224};
225
226/* ---------------------------------------------------------------------- */
227
228static void dump_read_message(unsigned char *buf)
229{
230 static char *afc[16] = {
231 "- 12.5 kHz",
232 "- 37.5 kHz",
233 "- 62.5 kHz",
234 "- 87.5 kHz",
235 "-112.5 kHz",
236 "-137.5 kHz",
237 "-162.5 kHz",
238 "-187.5 kHz [min]",
239 "+187.5 kHz [max]",
240 "+162.5 kHz",
241 "+137.5 kHz",
242 "+112.5 kHz",
243 "+ 87.5 kHz",
244 "+ 62.5 kHz",
245 "+ 37.5 kHz",
246 "+ 12.5 kHz",
247 };
248 printk(PREFIX "read: 0x%2x\n", buf[0]);
249 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
250 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
251 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
252 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
253 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
254}
255
256static void dump_write_message(unsigned char *buf)
257{
258 static char *sound[4] = {
259 "AM/TV",
260 "FM/radio",
261 "FM/TV",
262 "FM/radio"
263 };
264 static char *adjust[32] = {
265 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
266 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
267 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
268 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
269 };
270 static char *deemph[4] = {
271 "no", "no", "75", "50"
272 };
273 static char *carrier[4] = {
274 "4.5 MHz",
275 "5.5 MHz",
276 "6.0 MHz",
277 "6.5 MHz / AM"
278 };
279 static char *vif[8] = {
280 "58.75 MHz",
281 "45.75 MHz",
282 "38.9 MHz",
283 "38.0 MHz",
284 "33.9 MHz",
285 "33.4 MHz",
286 "45.75 MHz + pin13",
287 "38.9 MHz + pin13",
288 };
289 static char *rif[4] = {
290 "44 MHz",
291 "52 MHz",
292 "52 MHz",
293 "44 MHz",
294 };
295
296 printk(PREFIX "write: byte B 0x%02x\n",buf[1]);
297 printk(" B0 video mode : %s\n",
298 (buf[1] & 0x01) ? "video trap" : "sound trap");
299 printk(" B1 auto mute fm : %s\n",
300 (buf[1] & 0x02) ? "yes" : "no");
301 printk(" B2 carrier mode : %s\n",
302 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
303 printk(" B3-4 tv sound/radio : %s\n",
304 sound[(buf[1] & 0x18) >> 3]);
305 printk(" B5 force mute audio: %s\n",
306 (buf[1] & 0x20) ? "yes" : "no");
307 printk(" B6 output port 1 : %s\n",
308 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
309 printk(" B7 output port 2 : %s\n",
310 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
311
312 printk(PREFIX "write: byte C 0x%02x\n",buf[2]);
313 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
314 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
315 printk(" C7 audio gain : %s\n",
316 (buf[2] & 0x80) ? "-6" : "0");
317
318 printk(PREFIX "write: byte E 0x%02x\n",buf[3]);
319 printk(" E0-1 sound carrier : %s\n",
320 carrier[(buf[3] & 0x03)]);
321 printk(" E6 l pll ganting : %s\n",
322 (buf[3] & 0x40) ? "36" : "13");
323
324 if (buf[1] & 0x08) {
325 /* radio */
326 printk(" E2-4 video if : %s\n",
327 rif[(buf[3] & 0x0c) >> 2]);
328 printk(" E7 vif agc output : %s\n",
329 (buf[3] & 0x80)
330 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
331 : "fm radio carrier afc");
332 } else {
333 /* video */
334 printk(" E2-4 video if : %s\n",
335 vif[(buf[3] & 0x1c) >> 2]);
336 printk(" E5 tuner gain : %s\n",
337 (buf[3] & 0x80)
338 ? ((buf[3] & 0x20) ? "external" : "normal")
339 : ((buf[3] & 0x20) ? "minimum" : "normal"));
340 printk(" E7 vif agc output : %s\n",
341 (buf[3] & 0x80)
342 ? ((buf[3] & 0x20)
343 ? "pin3 port, pin22 vif agc out"
344 : "pin22 port, pin3 vif acg ext in")
345 : "pin3+pin22 port");
346 }
347 printk("--\n");
348}
349
350/* ---------------------------------------------------------------------- */
351
352static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
353{
354 struct tvnorm *norm = NULL;
355 int i;
356
357 if (t->radio) {
358 norm = &radio;
359 } else {
360 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
361 if (tvnorms[i].std & t->std) {
362 norm = tvnorms+i;
363 break;
364 }
365 }
366 }
367 if (NULL == norm) {
368 dprintk(PREFIX "Oops: no tvnorm entry found\n");
369 return -1;
370 }
371
372 dprintk(PREFIX "configure for: %s\n",norm->name);
373 buf[1] = norm->b;
374 buf[2] = norm->c;
375 buf[3] = norm->e;
376 return 0;
377}
378
379static unsigned int port1 = UNSET;
380static unsigned int port2 = UNSET;
381static unsigned int qss = UNSET;
382static unsigned int adjust = 0x10;
383module_param(port1, int, 0644);
384module_param(port2, int, 0644);
385module_param(qss, int, 0644);
386module_param(adjust, int, 0644);
387
388static int tda9887_set_insmod(struct tda9887 *t, char *buf)
389{
390 if (UNSET != port1) {
391 if (port1)
392 buf[1] |= cOutputPort1Inactive;
393 else
394 buf[1] &= ~cOutputPort1Inactive;
395 }
396 if (UNSET != port2) {
397 if (port2)
398 buf[1] |= cOutputPort2Inactive;
399 else
400 buf[1] &= ~cOutputPort2Inactive;
401 }
402
403 if (UNSET != qss) {
404 if (qss)
405 buf[1] |= cQSS;
406 else
407 buf[1] &= ~cQSS;
408 }
409
410 if (adjust >= 0x00 && adjust < 0x20)
411 buf[2] |= adjust;
412 return 0;
413}
414
415static int tda9887_set_config(struct tda9887 *t, char *buf)
416{
417 if (t->config & TDA9887_PORT1_ACTIVE)
418 buf[1] &= ~cOutputPort1Inactive;
419 if (t->config & TDA9887_PORT1_INACTIVE)
420 buf[1] |= cOutputPort1Inactive;
421 if (t->config & TDA9887_PORT2_ACTIVE)
422 buf[1] &= ~cOutputPort2Inactive;
423 if (t->config & TDA9887_PORT2_INACTIVE)
424 buf[1] |= cOutputPort2Inactive;
425
426 if (t->config & TDA9887_QSS)
427 buf[1] |= cQSS;
428 if (t->config & TDA9887_INTERCARRIER)
429 buf[1] &= ~cQSS;
430
431 if (t->config & TDA9887_AUTOMUTE)
432 buf[1] |= cAutoMuteFmActive;
433 if (t->config & TDA9887_DEEMPHASIS_MASK) {
434 buf[2] &= ~0x60;
435 switch (t->config & TDA9887_DEEMPHASIS_MASK) {
436 case TDA9887_DEEMPHASIS_NONE:
437 buf[2] |= cDeemphasisOFF;
438 break;
439 case TDA9887_DEEMPHASIS_50:
440 buf[2] |= cDeemphasisON | cDeemphasis50;
441 break;
442 case TDA9887_DEEMPHASIS_75:
443 buf[2] |= cDeemphasisON | cDeemphasis75;
444 break;
445 }
446 }
447 return 0;
448}
449
450/* ---------------------------------------------------------------------- */
451
452static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
453{
454 unsigned int bCarrierMode = UNSET;
455
456 if (t->std & V4L2_STD_625_50) {
457 if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
458 bCarrierMode = cIntercarrier;
459 } else {
460 bCarrierMode = cQSS;
461 }
462 }
463 if (t->std & V4L2_STD_525_60) {
464 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
465 bCarrierMode = cIntercarrier;
466 } else {
467 bCarrierMode = cQSS;
468 }
469 }
470
471 if (bCarrierMode != UNSET) {
472 buf[1] &= ~0x04;
473 buf[1] |= bCarrierMode;
474 }
475 return 0;
476}
477
478/* ---------------------------------------------------------------------- */
479
480static char pal[] = "-";
481module_param_string(pal, pal, 0644, sizeof(pal));
482static char secam[] = "-";
483module_param_string(secam, secam, 0644, sizeof(secam));
484
485static int tda9887_fixup_std(struct tda9887 *t)
486{
487 /* get more precise norm info from insmod option */
488 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
489 switch (pal[0]) {
490 case 'b':
491 case 'B':
492 case 'g':
493 case 'G':
494 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n");
495 t->std = V4L2_STD_PAL_BG;
496 break;
497 case 'i':
498 case 'I':
499 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n");
500 t->std = V4L2_STD_PAL_I;
501 break;
502 case 'd':
503 case 'D':
504 case 'k':
505 case 'K':
506 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
507 t->std = V4L2_STD_PAL_DK;
508 break;
509 }
510 }
511 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
512 switch (secam[0]) {
513 case 'd':
514 case 'D':
515 case 'k':
516 case 'K':
517 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n");
518 t->std = V4L2_STD_SECAM_DK;
519 break;
520 case 'l':
521 case 'L':
522 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
523 t->std = V4L2_STD_SECAM_L;
524 break;
525 }
526 }
527 return 0;
528}
529
530static int tda9887_status(struct tda9887 *t)
531{
532 unsigned char buf[1];
533 int rc;
534
535 memset(buf,0,sizeof(buf));
536 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
537 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc);
538 dump_read_message(buf);
539 return 0;
540}
541
542static int tda9887_configure(struct tda9887 *t)
543{
544 unsigned char buf[4];
545 int rc;
546
547 memset(buf,0,sizeof(buf));
548 tda9887_set_tvnorm(t,buf);
549 buf[1] |= cOutputPort1Inactive;
550 buf[1] |= cOutputPort2Inactive;
551 if (UNSET != t->pinnacle_id) {
552 tda9887_set_pinnacle(t,buf);
553 }
554 tda9887_set_config(t,buf);
555 tda9887_set_insmod(t,buf);
556
557#if 0
558 /* This as-is breaks some cards, must be fixed in a
559 * card-specific way, probably using TDA9887_SET_CONFIG to
560 * turn on/off port2 */
561 if (t->std & V4L2_STD_SECAM_L) {
562 /* secam fixup (FIXME: move this to tvnorms array?) */
563 buf[1] &= ~cOutputPort2Inactive;
564 }
565#endif
566
567 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
568 buf[1],buf[2],buf[3]);
569 if (debug > 1)
570 dump_write_message(buf);
571
572 if (4 != (rc = i2c_master_send(&t->client,buf,4)))
573 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc);
574
575 if (debug > 2) {
576 msleep_interruptible(1000);
577 tda9887_status(t);
578 }
579 return 0;
580}
581
582/* ---------------------------------------------------------------------- */
583
584static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
585{
586 struct tda9887 *t;
587
588 client_template.adapter = adap;
589 client_template.addr = addr;
590
591 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
592
593 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
594 return -ENOMEM;
595 memset(t,0,sizeof(*t));
596 t->client = client_template;
597 t->std = 0;
598 t->pinnacle_id = UNSET;
599 i2c_set_clientdata(&t->client, t);
600 i2c_attach_client(&t->client);
601
602 return 0;
603}
604
605static int tda9887_probe(struct i2c_adapter *adap)
606{
607#ifdef I2C_CLASS_TV_ANALOG
608 if (adap->class & I2C_CLASS_TV_ANALOG)
609 return i2c_probe(adap, &addr_data, tda9887_attach);
610#else
611 switch (adap->id) {
612 case I2C_ALGO_BIT | I2C_HW_B_BT848:
613 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
614 case I2C_ALGO_SAA7134:
615 return i2c_probe(adap, &addr_data, tda9887_attach);
616 break;
617 }
618#endif
619 return 0;
620}
621
622static int tda9887_detach(struct i2c_client *client)
623{
624 struct tda9887 *t = i2c_get_clientdata(client);
625
626 i2c_detach_client(client);
627 kfree(t);
628 return 0;
629}
630
631#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
632 printk(PREFIX "switching to v4l2\n"); \
633 t->using_v4l2 = 1;
634#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
635 printk(PREFIX "ignore v4l1 call\n"); \
636 return 0; }
637
638static int
639tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
640{
641 struct tda9887 *t = i2c_get_clientdata(client);
642
643 switch (cmd) {
644
645 /* --- configuration --- */
646 case AUDC_SET_RADIO:
647 t->radio = 1;
648 tda9887_configure(t);
649 break;
650
651 case AUDC_CONFIG_PINNACLE:
652 {
653 int *i = arg;
654
655 t->pinnacle_id = *i;
656 tda9887_configure(t);
657 break;
658 }
659 case TDA9887_SET_CONFIG:
660 {
661 int *i = arg;
662
663 t->config = *i;
664 tda9887_configure(t);
665 break;
666 }
667 /* --- v4l ioctls --- */
668 /* take care: bttv does userspace copying, we'll get a
669 kernel pointer here... */
670 case VIDIOCSCHAN:
671 {
672 static const v4l2_std_id map[] = {
673 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
674 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
675 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
676 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
677 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
678 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
679 };
680 struct video_channel *vc = arg;
681
682 CHECK_V4L2;
683 t->radio = 0;
684 if (vc->norm < ARRAY_SIZE(map))
685 t->std = map[vc->norm];
686 tda9887_fixup_std(t);
687 tda9887_configure(t);
688 break;
689 }
690 case VIDIOC_S_STD:
691 {
692 v4l2_std_id *id = arg;
693
694 SWITCH_V4L2;
695 t->radio = 0;
696 t->std = *id;
697 tda9887_fixup_std(t);
698 tda9887_configure(t);
699 break;
700 }
701 case VIDIOC_S_FREQUENCY:
702 {
703 struct v4l2_frequency *f = arg;
704
705 SWITCH_V4L2;
706 if (V4L2_TUNER_ANALOG_TV == f->type) {
707 if (t->radio == 0)
708 return 0;
709 t->radio = 0;
710 }
711 if (V4L2_TUNER_RADIO == f->type) {
712 if (t->radio == 1)
713 return 0;
714 t->radio = 1;
715 }
716 tda9887_configure(t);
717 break;
718 }
719 case VIDIOC_G_TUNER:
720 {
721 static int AFC_BITS_2_kHz[] = {
722 -12500, -37500, -62500, -97500,
723 -112500, -137500, -162500, -187500,
724 187500, 162500, 137500, 112500,
725 97500 , 62500, 37500 , 12500
726 };
727 struct v4l2_tuner* tuner = arg;
728
729 if (t->radio) {
730 __u8 reg = 0;
731 tuner->afc=0;
732 if (1 == i2c_master_recv(&t->client,&reg,1))
733 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
734 }
735 break;
736 }
737 default:
738 /* nothing */
739 break;
740 }
741 return 0;
742}
743
744static int tda9887_suspend(struct device * dev, u32 state, u32 level)
745{
746 dprintk("tda9887: suspend\n");
747 return 0;
748}
749
750static int tda9887_resume(struct device * dev, u32 level)
751{
752 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
753 struct tda9887 *t = i2c_get_clientdata(c);
754
755 dprintk("tda9887: resume\n");
756 tda9887_configure(t);
757 return 0;
758}
759
760/* ----------------------------------------------------------------------- */
761
762static struct i2c_driver driver = {
763 .owner = THIS_MODULE,
764 .name = "i2c tda9887 driver",
765 .id = -1, /* FIXME */
766 .flags = I2C_DF_NOTIFY,
767 .attach_adapter = tda9887_probe,
768 .detach_client = tda9887_detach,
769 .command = tda9887_command,
770 .driver = {
771 .suspend = tda9887_suspend,
772 .resume = tda9887_resume,
773 },
774};
775static struct i2c_client client_template =
776{
777 I2C_DEVNAME("tda9887"),
778 .flags = I2C_CLIENT_ALLOW_USE,
779 .driver = &driver,
780};
781
782static int __init tda9887_init_module(void)
783{
784 return i2c_add_driver(&driver);
785}
786
787static void __exit tda9887_cleanup_module(void)
788{
789 i2c_del_driver(&driver);
790}
791
792module_init(tda9887_init_module);
793module_exit(tda9887_cleanup_module);
794
795/*
796 * Overrides for Emacs so that we follow Linus's tabbing style.
797 * ---------------------------------------------------------------------------
798 * Local variables:
799 * c-basic-offset: 8
800 * End:
801 */
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
new file mode 100644
index 000000000000..3ec39550bf46
--- /dev/null
+++ b/drivers/media/video/tea6415c.c
@@ -0,0 +1,223 @@
1 /*
2 tea6415c - i2c-driver for the tea6415c by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tea6415c is a bus controlled video-matrix-switch
7 with 8 inputs and 6 outputs.
8 It is cascadable, i.e. it can be found at the addresses
9 0x86 and 0x06 on the i2c-bus.
10
11 For detailed informations download the specifications directly
12 from SGS Thomson at http://www.st.com
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License vs published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/ioctl.h>
31#include <linux/i2c.h>
32
33#include "tea6415c.h"
34
35static int debug = 0; /* insmod parameter */
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
38#define dprintk(args...) \
39 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
40
41#define TEA6415C_NUM_INPUTS 8
42#define TEA6415C_NUM_OUTPUTS 6
43
44/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
45static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
46static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
47
48/* magic definition of all other variables and things */
49I2C_CLIENT_INSMOD;
50
51static struct i2c_driver driver;
52static struct i2c_client client_template;
53
54/* this function is called by i2c_probe */
55static int detect(struct i2c_adapter *adapter, int address, int kind)
56{
57 struct i2c_client *client = NULL;
58 int err = 0;
59
60 /* let's see whether this adapter can support what we need */
61 if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
62 return 0;
63 }
64
65 /* allocate memory for client structure */
66 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
67 if (0 == client) {
68 return -ENOMEM;
69 }
70
71 /* fill client structure */
72 memcpy(client, &client_template, sizeof(struct i2c_client));
73 client->addr = address;
74 client->adapter = adapter;
75
76 /* tell the i2c layer a new client has arrived */
77 if (0 != (err = i2c_attach_client(client))) {
78 kfree(client);
79 return err;
80 }
81
82 printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
83
84 return 0;
85}
86
87static int attach(struct i2c_adapter *adapter)
88{
89 /* let's see whether this is a know adapter we can attach to */
90 if (adapter->id != I2C_ALGO_SAA7146) {
91 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
92 return -ENODEV;
93 }
94
95 return i2c_probe(adapter, &addr_data, &detect);
96}
97
98static int detach(struct i2c_client *client)
99{
100 int ret = i2c_detach_client(client);
101 kfree(client);
102 return ret;
103}
104
105/* makes a connection between the input-pin 'i' and the output-pin 'o'
106 for the tea6415c-client 'client' */
107static int switch_matrix(struct i2c_client *client, int i, int o)
108{
109 u8 byte = 0;
110 int ret;
111
112 dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o);
113
114 /* check if the pins are valid */
115 if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
116 && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
117 return -1;
118
119 /* to understand this, have a look at the tea6415c-specs (p.5) */
120 switch (o) {
121 case 18:
122 byte = 0x00;
123 break;
124 case 14:
125 byte = 0x20;
126 break;
127 case 16:
128 byte = 0x10;
129 break;
130 case 17:
131 byte = 0x08;
132 break;
133 case 15:
134 byte = 0x18;
135 break;
136 case 13:
137 byte = 0x28;
138 break;
139 };
140
141 switch (i) {
142 case 5:
143 byte |= 0x00;
144 break;
145 case 8:
146 byte |= 0x04;
147 break;
148 case 3:
149 byte |= 0x02;
150 break;
151 case 20:
152 byte |= 0x06;
153 break;
154 case 6:
155 byte |= 0x01;
156 break;
157 case 10:
158 byte |= 0x05;
159 break;
160 case 1:
161 byte |= 0x03;
162 break;
163 case 11:
164 byte |= 0x07;
165 break;
166 };
167
168 ret = i2c_smbus_write_byte(client, byte);
169 if (ret) {
170 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
171 return -EIO;
172 }
173
174 return ret;
175}
176
177static int command(struct i2c_client *client, unsigned int cmd, void *arg)
178{
179 struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
180 int result = 0;
181
182 switch (cmd) {
183 case TEA6415C_SWITCH:
184 result = switch_matrix(client, v->in, v->out);
185 break;
186 default:
187 return -ENOIOCTLCMD;
188 }
189
190 return result;
191}
192
193static struct i2c_driver driver = {
194 .owner = THIS_MODULE,
195 .name = "tea6415c",
196 .id = I2C_DRIVERID_TEA6415C,
197 .flags = I2C_DF_NOTIFY,
198 .attach_adapter = attach,
199 .detach_client = detach,
200 .command = command,
201};
202
203static struct i2c_client client_template = {
204 I2C_DEVNAME("tea6415c"),
205 .driver = &driver,
206};
207
208static int __init this_module_init(void)
209{
210 return i2c_add_driver(&driver);
211}
212
213static void __exit this_module_exit(void)
214{
215 i2c_del_driver(&driver);
216}
217
218module_init(this_module_init);
219module_exit(this_module_exit);
220
221MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
222MODULE_DESCRIPTION("tea6415c driver");
223MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
new file mode 100644
index 000000000000..f84ed80050b3
--- /dev/null
+++ b/drivers/media/video/tea6415c.h
@@ -0,0 +1,39 @@
1#ifndef __INCLUDED_TEA6415C__
2#define __INCLUDED_TEA6415C__
3
4/* possible i2c-addresses */
5#define I2C_TEA6415C_1 0x03
6#define I2C_TEA6415C_2 0x43
7
8/* the tea6415c's design is quite brain-dead. although there are
9 8 inputs and 6 outputs, these aren't enumerated in any way. because
10 I don't want to say "connect input pin 20 to output pin 17", I define
11 a "virtual" pin-order. */
12
13/* input pins */
14#define TEA6415C_OUTPUT1 18
15#define TEA6415C_OUTPUT2 14
16#define TEA6415C_OUTPUT3 16
17#define TEA6415C_OUTPUT4 17
18#define TEA6415C_OUTPUT5 13
19#define TEA6415C_OUTPUT6 15
20
21/* output pins */
22#define TEA6415C_INPUT1 5
23#define TEA6415C_INPUT2 8
24#define TEA6415C_INPUT3 3
25#define TEA6415C_INPUT4 20
26#define TEA6415C_INPUT5 6
27#define TEA6415C_INPUT6 10
28#define TEA6415C_INPUT7 1
29#define TEA6415C_INPUT8 11
30
31struct tea6415c_multiplex
32{
33 int in; /* input-pin */
34 int out; /* output-pin */
35};
36
37#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex)
38
39#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
new file mode 100644
index 000000000000..bd10710fd909
--- /dev/null
+++ b/drivers/media/video/tea6420.c
@@ -0,0 +1,200 @@
1 /*
2 tea6420 - i2c-driver for the tea6420 by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
7 4 stereo outputs and gain control for each output.
8 It is cascadable, i.e. it can be found at the adresses 0x98
9 and 0x9a on the i2c-bus.
10
11 For detailed informations download the specifications directly
12 from SGS Thomson at http://www.st.com
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/ioctl.h>
31#include <linux/i2c.h>
32
33#include "tea6420.h"
34
35static int debug = 0; /* insmod parameter */
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
38#define dprintk(args...) \
39 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
40
41/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
42static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END };
43static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
44
45/* magic definition of all other variables and things */
46I2C_CLIENT_INSMOD;
47
48static struct i2c_driver driver;
49static struct i2c_client client_template;
50
51/* make a connection between the input 'i' and the output 'o'
52 with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
53static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
54{
55 u8 byte = 0;
56 int ret;
57
58 dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g);
59
60 /* check if the paramters are valid */
61 if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
62 return -1;
63
64 byte = ((o - 1) << 5);
65 byte |= (i - 1);
66
67 /* to understand this, have a look at the tea6420-specs (p.5) */
68 switch (g) {
69 case 0:
70 byte |= (3 << 3);
71 break;
72 case 2:
73 byte |= (2 << 3);
74 break;
75 case 4:
76 byte |= (1 << 3);
77 break;
78 case 6:
79 break;
80 }
81
82 ret = i2c_smbus_write_byte(client, byte);
83 if (ret) {
84 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
85 return -EIO;
86 }
87
88 return 0;
89}
90
91/* this function is called by i2c_probe */
92static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
93{
94 struct i2c_client *client;
95 int err = 0, i = 0;
96
97 /* let's see whether this adapter can support what we need */
98 if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
99 return 0;
100 }
101
102 /* allocate memory for client structure */
103 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
104 if (0 == client) {
105 return -ENOMEM;
106 }
107 memset(client, 0x0, sizeof(struct i2c_client));
108
109 /* fill client structure */
110 memcpy(client, &client_template, sizeof(struct i2c_client));
111 client->addr = address;
112 client->adapter = adapter;
113
114 /* tell the i2c layer a new client has arrived */
115 if (0 != (err = i2c_attach_client(client))) {
116 kfree(client);
117 return err;
118 }
119
120 /* set initial values: set "mute"-input to all outputs at gain 0 */
121 err = 0;
122 for (i = 1; i < 5; i++) {
123 err += tea6420_switch(client, 6, i, 0);
124 }
125 if (err) {
126 dprintk("could not initialize tea6420\n");
127 kfree(client);
128 return -ENODEV;
129 }
130
131 printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
132
133 return 0;
134}
135
136static int attach(struct i2c_adapter *adapter)
137{
138 /* let's see whether this is a know adapter we can attach to */
139 if (adapter->id != I2C_ALGO_SAA7146) {
140 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
141 return -ENODEV;
142 }
143
144 return i2c_probe(adapter, &addr_data, &tea6420_detect);
145}
146
147static int detach(struct i2c_client *client)
148{
149 int ret = i2c_detach_client(client);
150 kfree(client);
151 return ret;
152}
153
154static int command(struct i2c_client *client, unsigned int cmd, void *arg)
155{
156 struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
157 int result = 0;
158
159 switch (cmd) {
160 case TEA6420_SWITCH:
161 result = tea6420_switch(client, a->in, a->out, a->gain);
162 break;
163 default:
164 return -ENOIOCTLCMD;
165 }
166
167 return result;
168}
169
170static struct i2c_driver driver = {
171 .owner = THIS_MODULE,
172 .name = "tea6420",
173 .id = I2C_DRIVERID_TEA6420,
174 .flags = I2C_DF_NOTIFY,
175 .attach_adapter = attach,
176 .detach_client = detach,
177 .command = command,
178};
179
180static struct i2c_client client_template = {
181 I2C_DEVNAME("tea6420"),
182 .driver = &driver,
183};
184
185static int __init this_module_init(void)
186{
187 return i2c_add_driver(&driver);
188}
189
190static void __exit this_module_exit(void)
191{
192 i2c_del_driver(&driver);
193}
194
195module_init(this_module_init);
196module_exit(this_module_exit);
197
198MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
199MODULE_DESCRIPTION("tea6420 driver");
200MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
new file mode 100644
index 000000000000..ea664df15ad4
--- /dev/null
+++ b/drivers/media/video/tea6420.h
@@ -0,0 +1,17 @@
1#ifndef __INCLUDED_TEA6420__
2#define __INCLUDED_TEA6420__
3
4/* possible addresses */
5#define I2C_TEA6420_1 0x4c
6#define I2C_TEA6420_2 0x4d
7
8struct tea6420_multiplex
9{
10 int in; /* input of audio switch */
11 int out; /* output of audio switch */
12 int gain; /* gain of connection */
13};
14
15#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex)
16
17#endif
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
new file mode 100644
index 000000000000..6b20aa902a8f
--- /dev/null
+++ b/drivers/media/video/tuner-3036.c
@@ -0,0 +1,220 @@
1/*
2 * Driver for Philips SAB3036 "CITAC" tuner control chip.
3 *
4 * Author: Phil Blundell <philb@gnu.org>
5 *
6 * The SAB3036 is just about different enough from the chips that
7 * tuner.c copes with to make it not worth the effort to crowbar
8 * the support into that file. So instead we have a separate driver.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/timer.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25
26#include <linux/i2c.h>
27#include <linux/videodev.h>
28
29#include <media/tuner.h>
30
31static int debug; /* insmod parameter */
32static int this_adap;
33
34static struct i2c_client client_template;
35
36/* Addresses to scan */
37static unsigned short normal_i2c[] = {I2C_CLIENT_END};
38static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END};
39static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
40static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
41static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
42static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
43static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
44
45static struct i2c_client_address_data addr_data = {
46 normal_i2c, normal_i2c_range,
47 probe, probe_range,
48 ignore, ignore_range,
49 force
50};
51
52/* ---------------------------------------------------------------------- */
53
54static unsigned char
55tuner_getstatus (struct i2c_client *c)
56{
57 unsigned char byte;
58 if (i2c_master_recv(c, &byte, 1) != 1)
59 printk(KERN_ERR "tuner-3036: I/O error.\n");
60 return byte;
61}
62
63#define TUNER_FL 0x80
64
65static int
66tuner_islocked (struct i2c_client *c)
67{
68 return (tuner_getstatus(c) & TUNER_FL);
69}
70
71/* ---------------------------------------------------------------------- */
72
73static void
74set_tv_freq(struct i2c_client *c, int freq)
75{
76 u16 div = ((freq * 20) / 16);
77 unsigned long give_up = jiffies + HZ;
78 unsigned char buffer[2];
79
80 if (debug)
81 printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div);
82
83 /* Select high tuning current */
84 buffer[0] = 0x29;
85 buffer[1] = 0x3e;
86
87 if (i2c_master_send(c, buffer, 2) != 2)
88 printk("tuner: i2c i/o error 1\n");
89
90 buffer[0] = 0x80 | ((div>>8) & 0x7f);
91 buffer[1] = div & 0xff;
92
93 if (i2c_master_send(c, buffer, 2) != 2)
94 printk("tuner: i2c i/o error 2\n");
95
96 while (!tuner_islocked(c) && time_before(jiffies, give_up))
97 schedule();
98
99 if (!tuner_islocked(c))
100 printk(KERN_WARNING "tuner: failed to achieve PLL lock\n");
101
102 /* Select low tuning current and engage AFC */
103 buffer[0] = 0x29;
104 buffer[1] = 0xb2;
105
106 if (i2c_master_send(c, buffer, 2) != 2)
107 printk("tuner: i2c i/o error 3\n");
108
109 if (debug)
110 printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c));
111}
112
113/* ---------------------------------------------------------------------- */
114
115static int
116tuner_attach(struct i2c_adapter *adap, int addr, int kind)
117{
118 static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 };
119
120 struct i2c_client *client;
121
122 if (this_adap > 0)
123 return -1;
124 this_adap++;
125
126 client_template.adapter = adap;
127 client_template.addr = addr;
128
129 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
130 if (client == NULL)
131 return -ENOMEM;
132 memcpy(client, &client_template, sizeof(struct i2c_client));
133
134 printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client));
135
136 i2c_attach_client(client);
137
138 if (i2c_master_send(client, buffer, 2) != 2)
139 printk("tuner: i2c i/o error 1\n");
140 if (i2c_master_send(client, buffer+2, 2) != 2)
141 printk("tuner: i2c i/o error 2\n");
142 if (i2c_master_send(client, buffer+4, 2) != 2)
143 printk("tuner: i2c i/o error 3\n");
144 return 0;
145}
146
147static int
148tuner_detach(struct i2c_client *c)
149{
150 return 0;
151}
152
153static int
154tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
155{
156 int *iarg = (int*)arg;
157
158 switch (cmd)
159 {
160 case TUNER_SET_TVFREQ:
161 set_tv_freq(client, *iarg);
162 break;
163
164 default:
165 return -EINVAL;
166 }
167 return 0;
168}
169
170static int
171tuner_probe(struct i2c_adapter *adap)
172{
173 this_adap = 0;
174 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_LP))
175 return i2c_probe(adap, &addr_data, tuner_attach);
176 return 0;
177}
178
179/* ----------------------------------------------------------------------- */
180
181static struct i2c_driver
182i2c_driver_tuner =
183{
184 .owner = THIS_MODULE,
185 .name = "sab3036",
186 .id = I2C_DRIVERID_SAB3036,
187 .flags = I2C_DF_NOTIFY,
188 .attach_adapter = tuner_probe,
189 .detach_client = tuner_detach,
190 .command = tuner_command
191};
192
193static struct i2c_client client_template =
194{
195 .driver = &i2c_driver_tuner,
196 .name = "SAB3036",
197};
198
199static int __init
200tuner3036_init(void)
201{
202 i2c_add_driver(&i2c_driver_tuner);
203 return 0;
204}
205
206static void __exit
207tuner3036_exit(void)
208{
209 i2c_del_driver(&i2c_driver_tuner);
210}
211
212MODULE_DESCRIPTION("SAB3036 tuner driver");
213MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
214MODULE_LICENSE("GPL");
215
216module_param(debug, int, 0);
217MODULE_PARM_DESC(debug,"Enable debugging output");
218
219module_init(tuner3036_init);
220module_exit(tuner3036_exit);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
new file mode 100644
index 000000000000..2f4e18d20b7a
--- /dev/null
+++ b/drivers/media/video/tuner-core.c
@@ -0,0 +1,443 @@
1/*
2 * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * core core, i.e. kernel interfaces, registering and so on
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/string.h>
13#include <linux/timer.h>
14#include <linux/delay.h>
15#include <linux/errno.h>
16#include <linux/slab.h>
17#include <linux/poll.h>
18#include <linux/i2c.h>
19#include <linux/types.h>
20#include <linux/videodev.h>
21#include <linux/init.h>
22
23#include <media/tuner.h>
24#include <media/audiochip.h>
25
26#define UNSET (-1U)
27
28/* standard i2c insmod options */
29static unsigned short normal_i2c[] = {
30 0x4b, /* tda8290 */
31 I2C_CLIENT_END
32};
33static unsigned short normal_i2c_range[] = {
34 0x60, 0x6f,
35 I2C_CLIENT_END
36};
37I2C_CLIENT_INSMOD;
38
39/* insmod options used at init time => read/only */
40static unsigned int addr = 0;
41module_param(addr, int, 0444);
42
43/* insmod options used at runtime => read/write */
44unsigned int tuner_debug = 0;
45module_param(tuner_debug, int, 0644);
46
47static unsigned int tv_range[2] = { 44, 958 };
48static unsigned int radio_range[2] = { 65, 108 };
49
50module_param_array(tv_range, int, NULL, 0644);
51module_param_array(radio_range, int, NULL, 0644);
52
53MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
54MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
55MODULE_LICENSE("GPL");
56
57static int this_adap;
58
59static struct i2c_driver driver;
60static struct i2c_client client_template;
61
62/* ---------------------------------------------------------------------- */
63
64// Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
65static void set_tv_freq(struct i2c_client *c, unsigned int freq)
66{
67 struct tuner *t = i2c_get_clientdata(c);
68
69 if (t->type == UNSET) {
70 tuner_info("tuner type not set\n");
71 return;
72 }
73 if (NULL == t->tv_freq) {
74 tuner_info("Huh? tv_set is NULL?\n");
75 return;
76 }
77 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
78 /* FIXME: better do that chip-specific, but
79 right now we don't have that in the config
80 struct and this way is still better than no
81 check at all */
82 tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
83 freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
84 return;
85 }
86 t->tv_freq(c,freq);
87}
88
89static void set_radio_freq(struct i2c_client *c, unsigned int freq)
90{
91 struct tuner *t = i2c_get_clientdata(c);
92
93 if (t->type == UNSET) {
94 tuner_info("tuner type not set\n");
95 return;
96 }
97 if (NULL == t->radio_freq) {
98 tuner_info("no radio tuning for this one, sorry.\n");
99 return;
100 }
101 if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
102 tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
103 freq/16,freq%16*100/16,
104 radio_range[0],radio_range[1]);
105 return;
106 }
107 t->radio_freq(c,freq);
108}
109
110static void set_freq(struct i2c_client *c, unsigned long freq)
111{
112 struct tuner *t = i2c_get_clientdata(c);
113
114 switch (t->mode) {
115 case V4L2_TUNER_RADIO:
116 tuner_dbg("radio freq set to %lu.%02lu\n",
117 freq/16,freq%16*100/16);
118 set_radio_freq(c,freq);
119 break;
120 case V4L2_TUNER_ANALOG_TV:
121 case V4L2_TUNER_DIGITAL_TV:
122 tuner_dbg("tv freq set to %lu.%02lu\n",
123 freq/16,freq%16*100/16);
124 set_tv_freq(c, freq);
125 break;
126 }
127 t->freq = freq;
128}
129
130static void set_type(struct i2c_client *c, unsigned int type)
131{
132 struct tuner *t = i2c_get_clientdata(c);
133
134 /* sanity check */
135 if (type == UNSET || type == TUNER_ABSENT)
136 return;
137 if (type >= tuner_count)
138 return;
139
140 if (NULL == t->i2c.dev.driver) {
141 /* not registered yet */
142 t->type = type;
143 return;
144 }
145 if (t->initialized)
146 /* run only once */
147 return;
148
149 t->initialized = 1;
150 t->type = type;
151 switch (t->type) {
152 case TUNER_MT2032:
153 microtune_init(c);
154 break;
155 case TUNER_PHILIPS_TDA8290:
156 tda8290_init(c);
157 break;
158 default:
159 default_tuner_init(c);
160 break;
161 }
162}
163
164static char pal[] = "-";
165module_param_string(pal, pal, 0644, sizeof(pal));
166
167static int tuner_fixup_std(struct tuner *t)
168{
169 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
170 /* get more precise norm info from insmod option */
171 switch (pal[0]) {
172 case 'b':
173 case 'B':
174 case 'g':
175 case 'G':
176 tuner_dbg("insmod fixup: PAL => PAL-BG\n");
177 t->std = V4L2_STD_PAL_BG;
178 break;
179 case 'i':
180 case 'I':
181 tuner_dbg("insmod fixup: PAL => PAL-I\n");
182 t->std = V4L2_STD_PAL_I;
183 break;
184 case 'd':
185 case 'D':
186 case 'k':
187 case 'K':
188 tuner_dbg("insmod fixup: PAL => PAL-DK\n");
189 t->std = V4L2_STD_PAL_DK;
190 break;
191 }
192 }
193 return 0;
194}
195
196/* ---------------------------------------------------------------------- */
197
198static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
199{
200 struct tuner *t;
201
202 if (this_adap > 0)
203 return -1;
204 this_adap++;
205
206 client_template.adapter = adap;
207 client_template.addr = addr;
208
209 t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
210 if (NULL == t)
211 return -ENOMEM;
212 memset(t,0,sizeof(struct tuner));
213 memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
214 i2c_set_clientdata(&t->i2c, t);
215 t->type = UNSET;
216 t->radio_if2 = 10700*1000; // 10.7MHz - FM radio
217
218 i2c_attach_client(&t->i2c);
219 tuner_info("chip found @ 0x%x (%s)\n",
220 addr << 1, adap->name);
221 set_type(&t->i2c, t->type);
222 return 0;
223}
224
225static int tuner_probe(struct i2c_adapter *adap)
226{
227 if (0 != addr) {
228 normal_i2c[0] = addr;
229 normal_i2c_range[0] = addr;
230 normal_i2c_range[1] = addr;
231 }
232 this_adap = 0;
233
234 if (adap->class & I2C_CLASS_TV_ANALOG)
235 return i2c_probe(adap, &addr_data, tuner_attach);
236 return 0;
237}
238
239static int tuner_detach(struct i2c_client *client)
240{
241 struct tuner *t = i2c_get_clientdata(client);
242
243 i2c_detach_client(&t->i2c);
244 kfree(t);
245 return 0;
246}
247
248#define SWITCH_V4L2 if (!t->using_v4l2 && tuner_debug) \
249 tuner_info("switching to v4l2\n"); \
250 t->using_v4l2 = 1;
251#define CHECK_V4L2 if (t->using_v4l2) { if (tuner_debug) \
252 tuner_info("ignore v4l1 call\n"); \
253 return 0; }
254
255static int
256tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
257{
258 struct tuner *t = i2c_get_clientdata(client);
259 unsigned int *iarg = (int*)arg;
260
261 switch (cmd) {
262
263 /* --- configuration --- */
264 case TUNER_SET_TYPE:
265 set_type(client,*iarg);
266 break;
267 case AUDC_SET_RADIO:
268 if (V4L2_TUNER_RADIO != t->mode) {
269 set_tv_freq(client,400 * 16);
270 t->mode = V4L2_TUNER_RADIO;
271 }
272 break;
273 case AUDC_CONFIG_PINNACLE:
274 switch (*iarg) {
275 case 2:
276 tuner_dbg("pinnacle pal\n");
277 t->radio_if2 = 33300 * 1000;
278 break;
279 case 3:
280 tuner_dbg("pinnacle ntsc\n");
281 t->radio_if2 = 41300 * 1000;
282 break;
283 }
284 break;
285
286 /* --- v4l ioctls --- */
287 /* take care: bttv does userspace copying, we'll get a
288 kernel pointer here... */
289 case VIDIOCSCHAN:
290 {
291 static const v4l2_std_id map[] = {
292 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
293 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
294 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
295 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
296 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
297 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
298 };
299 struct video_channel *vc = arg;
300
301 CHECK_V4L2;
302 t->mode = V4L2_TUNER_ANALOG_TV;
303 if (vc->norm < ARRAY_SIZE(map))
304 t->std = map[vc->norm];
305 tuner_fixup_std(t);
306 if (t->freq)
307 set_tv_freq(client,t->freq);
308 return 0;
309 }
310 case VIDIOCSFREQ:
311 {
312 unsigned long *v = arg;
313
314 CHECK_V4L2;
315 set_freq(client,*v);
316 return 0;
317 }
318 case VIDIOCGTUNER:
319 {
320 struct video_tuner *vt = arg;
321
322 CHECK_V4L2;
323 if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
324 vt->signal = t->has_signal(client);
325 return 0;
326 }
327 case VIDIOCGAUDIO:
328 {
329 struct video_audio *va = arg;
330
331 CHECK_V4L2;
332 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
333 va->mode = t->is_stereo(client)
334 ? VIDEO_SOUND_STEREO
335 : VIDEO_SOUND_MONO;
336 return 0;
337 }
338
339 case VIDIOC_S_STD:
340 {
341 v4l2_std_id *id = arg;
342
343 SWITCH_V4L2;
344 t->mode = V4L2_TUNER_ANALOG_TV;
345 t->std = *id;
346 tuner_fixup_std(t);
347 if (t->freq)
348 set_freq(client,t->freq);
349 break;
350 }
351 case VIDIOC_S_FREQUENCY:
352 {
353 struct v4l2_frequency *f = arg;
354
355 SWITCH_V4L2;
356 if (V4L2_TUNER_RADIO == f->type &&
357 V4L2_TUNER_RADIO != t->mode)
358 set_tv_freq(client,400*16);
359 t->mode = f->type;
360 t->freq = f->frequency;
361 set_freq(client,t->freq);
362 break;
363 }
364 case VIDIOC_G_TUNER:
365 {
366 struct v4l2_tuner *tuner = arg;
367
368 SWITCH_V4L2;
369 if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
370 tuner->signal = t->has_signal(client);
371 break;
372 }
373 default:
374 /* nothing */
375 break;
376 }
377
378 return 0;
379}
380
381static int tuner_suspend(struct device * dev, u32 state, u32 level)
382{
383 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
384 struct tuner *t = i2c_get_clientdata(c);
385
386 tuner_dbg("suspend\n");
387 /* FIXME: power down ??? */
388 return 0;
389}
390
391static int tuner_resume(struct device * dev, u32 level)
392{
393 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
394 struct tuner *t = i2c_get_clientdata(c);
395
396 tuner_dbg("resume\n");
397 if (t->freq)
398 set_freq(c,t->freq);
399 return 0;
400}
401
402/* ----------------------------------------------------------------------- */
403
404static struct i2c_driver driver = {
405 .owner = THIS_MODULE,
406 .name = "tuner",
407 .id = I2C_DRIVERID_TUNER,
408 .flags = I2C_DF_NOTIFY,
409 .attach_adapter = tuner_probe,
410 .detach_client = tuner_detach,
411 .command = tuner_command,
412 .driver = {
413 .suspend = tuner_suspend,
414 .resume = tuner_resume,
415 },
416};
417static struct i2c_client client_template =
418{
419 I2C_DEVNAME("(tuner unset)"),
420 .flags = I2C_CLIENT_ALLOW_USE,
421 .driver = &driver,
422};
423
424static int __init tuner_init_module(void)
425{
426 return i2c_add_driver(&driver);
427}
428
429static void __exit tuner_cleanup_module(void)
430{
431 i2c_del_driver(&driver);
432}
433
434module_init(tuner_init_module);
435module_exit(tuner_cleanup_module);
436
437/*
438 * Overrides for Emacs so that we follow Linus's tabbing style.
439 * ---------------------------------------------------------------------------
440 * Local variables:
441 * c-basic-offset: 8
442 * End:
443 */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
new file mode 100644
index 000000000000..48c6ceff1dc2
--- /dev/null
+++ b/drivers/media/video/tuner-simple.c
@@ -0,0 +1,474 @@
1/*
2 * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls all those simple 4-control-bytes style tuners.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <media/tuner.h>
11
12/* ---------------------------------------------------------------------- */
13
14/* tv standard selection for Temic 4046 FM5
15 this value takes the low bits of control byte 2
16 from datasheet Rev.01, Feb.00
17 standard BG I L L2 D
18 picture IF 38.9 38.9 38.9 33.95 38.9
19 sound 1 33.4 32.9 32.4 40.45 32.4
20 sound 2 33.16
21 NICAM 33.05 32.348 33.05 33.05
22 */
23#define TEMIC_SET_PAL_I 0x05
24#define TEMIC_SET_PAL_DK 0x09
25#define TEMIC_SET_PAL_L 0x0a // SECAM ?
26#define TEMIC_SET_PAL_L2 0x0b // change IF !
27#define TEMIC_SET_PAL_BG 0x0c
28
29/* tv tuner system standard selection for Philips FQ1216ME
30 this value takes the low bits of control byte 2
31 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
32 standard BG DK I L L`
33 picture carrier 38.90 38.90 38.90 38.90 33.95
34 colour 34.47 34.47 34.47 34.47 38.38
35 sound 1 33.40 32.40 32.90 32.40 40.45
36 sound 2 33.16 - - - -
37 NICAM 33.05 33.05 32.35 33.05 39.80
38 */
39#define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
40#define PHILIPS_SET_PAL_BGDK 0x09
41#define PHILIPS_SET_PAL_L2 0x0a
42#define PHILIPS_SET_PAL_L 0x0b
43
44/* system switching for Philips FI1216MF MK2
45 from datasheet "1996 Jul 09",
46 standard BG L L'
47 picture carrier 38.90 38.90 33.95
48 colour 34.47 34.37 38.38
49 sound 1 33.40 32.40 40.45
50 sound 2 33.16 - -
51 NICAM 33.05 33.05 39.80
52 */
53#define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
54#define PHILIPS_MF_SET_PAL_L 0x03 // France
55#define PHILIPS_MF_SET_PAL_L2 0x02 // L'
56
57
58/* ---------------------------------------------------------------------- */
59
60struct tunertype
61{
62 char *name;
63 unsigned char Vendor;
64 unsigned char Type;
65
66 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
67 unsigned short thresh2; /* band switch VHF_HI <=> UHF */
68 unsigned char VHF_L;
69 unsigned char VHF_H;
70 unsigned char UHF;
71 unsigned char config;
72 unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL,
73 732 =16*45.75 NTSCi,
74 940 =16*58.75 NTSC-Japan
75 704 =16*44 ATSC */
76};
77
78/*
79 * The floats in the tuner struct are computed at compile time
80 * by gcc and cast back to integers. Thus we don't violate the
81 * "no float in kernel" rule.
82 */
83static struct tunertype tuners[] = {
84 { "Temic PAL (4002 FH5)", TEMIC, PAL,
85 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
86 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
87 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
88 { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC,
89 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
90 { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
91 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
92
93 { "NoTuner", NoTuner, NOTUNER,
94 0,0,0x00,0x00,0x00,0x00,0x00},
95 { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
96 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
97 { "Temic NTSC (4032 FY5)", TEMIC, NTSC,
98 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
99 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
100 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
101
102 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
103 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
104 { "Alps HSBH1", TEMIC, NTSC,
105 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
106 { "Alps TSBE1",TEMIC,PAL,
107 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
108 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
109 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
110
111 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
112 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
113 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
114 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
115 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
116 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
117 { "Alps TSCH6",Alps,NTSC,
118 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
119
120 { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
121 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
122 { "Philips NTSC_M (MK2)",Philips,NTSC,
123 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
124 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
125 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
126 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
127 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
128
129 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
130 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
131 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
132 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
133 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
134 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
135 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137
138 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
139 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
140 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
141 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
142 { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I,
143 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
144 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
145 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
146
147 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
148 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
149 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
150 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
151 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
152 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
153 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
154 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
155
156 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
157 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
158 { "MT20xx universal", Microtune,PAL|NTSC,
159 /* see mt20xx.c for details */ },
160 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
161 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
162 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
163 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
164
165 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
166 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
167 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
168 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
169 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
170 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
171 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
172 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
173
174 { "HITACHI V7-J180AT", HITACHI, NTSC,
175 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 },
176 { "Philips PAL_MK (FI1216 MK)", Philips, PAL,
177 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
178 { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC,
179 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
180 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
181 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
182
183 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
184 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
185 { "Microtune 4049 FM5",Microtune,PAL,
186 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
187 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
188 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
189 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
190 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
191
192 { "Tenna TNF 8831 BGFF)", Philips, PAL,
193 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
194 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
195 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
196 { "TCL 2002N", TCL, NTSC,
197 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
198 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
199 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
200
201 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
202 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
203 { "Philips FQ1286", Philips, NTSC,
204 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested
205 { "tda8290+75", Philips,PAL|NTSC,
206 /* see tda8290.c for details */ },
207 { "LG PAL (TAPE series)", LGINNOTEK, PAL,
208 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
209
210 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
211 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
212 { "Philips FQ1236A MK4", Philips, NTSC,
213 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
214
215};
216unsigned const int tuner_count = ARRAY_SIZE(tuners);
217
218/* ---------------------------------------------------------------------- */
219
220static int tuner_getstatus(struct i2c_client *c)
221{
222 unsigned char byte;
223
224 if (1 != i2c_master_recv(c,&byte,1))
225 return 0;
226 return byte;
227}
228
229#define TUNER_POR 0x80
230#define TUNER_FL 0x40
231#define TUNER_MODE 0x38
232#define TUNER_AFC 0x07
233
234#define TUNER_STEREO 0x10 /* radio mode */
235#define TUNER_SIGNAL 0x07 /* radio mode */
236
237static int tuner_signal(struct i2c_client *c)
238{
239 return (tuner_getstatus(c) & TUNER_SIGNAL)<<13;
240}
241
242static int tuner_stereo(struct i2c_client *c)
243{
244 return (tuner_getstatus (c) & TUNER_STEREO);
245}
246
247#if 0 /* unused */
248static int tuner_islocked (struct i2c_client *c)
249{
250 return (tuner_getstatus (c) & TUNER_FL);
251}
252
253static int tuner_afcstatus (struct i2c_client *c)
254{
255 return (tuner_getstatus (c) & TUNER_AFC) - 2;
256}
257
258static int tuner_mode (struct i2c_client *c)
259{
260 return (tuner_getstatus (c) & TUNER_MODE) >> 3;
261}
262#endif
263
264/* ---------------------------------------------------------------------- */
265
266static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
267{
268 struct tuner *t = i2c_get_clientdata(c);
269 u8 config;
270 u16 div;
271 struct tunertype *tun;
272 unsigned char buffer[4];
273 int rc;
274
275 tun = &tuners[t->type];
276 if (freq < tun->thresh1) {
277 config = tun->VHF_L;
278 tuner_dbg("tv: VHF lowrange\n");
279 } else if (freq < tun->thresh2) {
280 config = tun->VHF_H;
281 tuner_dbg("tv: VHF high range\n");
282 } else {
283 config = tun->UHF;
284 tuner_dbg("tv: UHF range\n");
285 }
286
287
288 /* tv norm specific stuff for multi-norm tuners */
289 switch (t->type) {
290 case TUNER_PHILIPS_SECAM: // FI1216MF
291 /* 0x01 -> ??? no change ??? */
292 /* 0x02 -> PAL BDGHI / SECAM L */
293 /* 0x04 -> ??? PAL others / SECAM others ??? */
294 config &= ~0x02;
295 if (t->std & V4L2_STD_SECAM)
296 config |= 0x02;
297 break;
298
299 case TUNER_TEMIC_4046FM5:
300 config &= ~0x0f;
301
302 if (t->std & V4L2_STD_PAL_BG) {
303 config |= TEMIC_SET_PAL_BG;
304
305 } else if (t->std & V4L2_STD_PAL_I) {
306 config |= TEMIC_SET_PAL_I;
307
308 } else if (t->std & V4L2_STD_PAL_DK) {
309 config |= TEMIC_SET_PAL_DK;
310
311 } else if (t->std & V4L2_STD_SECAM_L) {
312 config |= TEMIC_SET_PAL_L;
313
314 }
315 break;
316
317 case TUNER_PHILIPS_FQ1216ME:
318 config &= ~0x0f;
319
320 if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
321 config |= PHILIPS_SET_PAL_BGDK;
322
323 } else if (t->std & V4L2_STD_PAL_I) {
324 config |= PHILIPS_SET_PAL_I;
325
326 } else if (t->std & V4L2_STD_SECAM_L) {
327 config |= PHILIPS_SET_PAL_L;
328
329 }
330 break;
331
332 case TUNER_PHILIPS_ATSC:
333 /* 0x00 -> ATSC antenna input 1 */
334 /* 0x01 -> ATSC antenna input 2 */
335 /* 0x02 -> NTSC antenna input 1 */
336 /* 0x03 -> NTSC antenna input 2 */
337 config &= ~0x03;
338 if (!(t->std & V4L2_STD_ATSC))
339 config |= 2;
340 /* FIXME: input */
341 break;
342
343 case TUNER_MICROTUNE_4042FI5:
344 /* Set the charge pump for fast tuning */
345 tun->config |= 0x40;
346 break;
347 }
348
349 /*
350 * Philips FI1216MK2 remark from specification :
351 * for channel selection involving band switching, and to ensure
352 * smooth tuning to the desired channel without causing
353 * unnecessary charge pump action, it is recommended to consider
354 * the difference between wanted channel frequency and the
355 * current channel frequency. Unnecessary charge pump action
356 * will result in very low tuning voltage which may drive the
357 * oscillator to extreme conditions.
358 *
359 * Progfou: specification says to send config data before
360 * frequency in case (wanted frequency < current frequency).
361 */
362
363 div=freq + tun->IFPCoff;
364 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
365 buffer[0] = tun->config;
366 buffer[1] = config;
367 buffer[2] = (div>>8) & 0x7f;
368 buffer[3] = div & 0xff;
369 } else {
370 buffer[0] = (div>>8) & 0x7f;
371 buffer[1] = div & 0xff;
372 buffer[2] = tun->config;
373 buffer[3] = config;
374 }
375 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
376 buffer[0],buffer[1],buffer[2],buffer[3]);
377
378 if (4 != (rc = i2c_master_send(c,buffer,4)))
379 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
380
381 if (t->type == TUNER_MICROTUNE_4042FI5) {
382 // FIXME - this may also work for other tuners
383 unsigned long timeout = jiffies + msecs_to_jiffies(1);
384 u8 status_byte = 0;
385
386 /* Wait until the PLL locks */
387 for (;;) {
388 if (time_after(jiffies,timeout))
389 return;
390 if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
391 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
392 break;
393 }
394 /* bit 6 is PLL locked indicator */
395 if (status_byte & 0x40)
396 break;
397 udelay(10);
398 }
399
400 /* Set the charge pump for optimized phase noise figure */
401 tun->config &= ~0x40;
402 buffer[0] = (div>>8) & 0x7f;
403 buffer[1] = div & 0xff;
404 buffer[2] = tun->config;
405 buffer[3] = config;
406 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
407 buffer[0],buffer[1],buffer[2],buffer[3]);
408
409 if (4 != (rc = i2c_master_send(c,buffer,4)))
410 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
411 }
412}
413
414static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
415{
416 struct tunertype *tun;
417 struct tuner *t = i2c_get_clientdata(c);
418 unsigned char buffer[4];
419 unsigned div;
420 int rc;
421
422 tun=&tuners[t->type];
423 div = freq + (int)(16*10.7);
424 buffer[2] = tun->config;
425
426 switch (t->type) {
427 case TUNER_PHILIPS_FM1216ME_MK3:
428 case TUNER_PHILIPS_FM1236_MK3:
429 buffer[3] = 0x19;
430 break;
431 case TUNER_PHILIPS_FM1256_IH3:
432 div = (20 * freq)/16 + 333 * 2;
433 buffer[2] = 0x80;
434 buffer[3] = 0x19;
435 break;
436 case TUNER_LG_PAL_FM:
437 buffer[3] = 0xa5;
438 break;
439 default:
440 buffer[3] = 0xa4;
441 break;
442 }
443 buffer[0] = (div>>8) & 0x7f;
444 buffer[1] = div & 0xff;
445
446 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
447 buffer[0],buffer[1],buffer[2],buffer[3]);
448
449 if (4 != (rc = i2c_master_send(c,buffer,4)))
450 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
451}
452
453int default_tuner_init(struct i2c_client *c)
454{
455 struct tuner *t = i2c_get_clientdata(c);
456
457 tuner_info("type set to %d (%s)\n",
458 t->type, tuners[t->type].name);
459 strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
460
461 t->tv_freq = default_set_tv_freq;
462 t->radio_freq = default_set_radio_freq;
463 t->has_signal = tuner_signal;
464 t->is_stereo = tuner_stereo;
465 return 0;
466}
467
468/*
469 * Overrides for Emacs so that we follow Linus's tabbing style.
470 * ---------------------------------------------------------------------------
471 * Local variables:
472 * c-basic-offset: 8
473 * End:
474 */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
new file mode 100644
index 000000000000..065eb4007b1d
--- /dev/null
+++ b/drivers/media/video/tvaudio.c
@@ -0,0 +1,1740 @@
1/*
2 * experimental driver for simple i2c audio chips.
3 *
4 * Copyright (c) 2000 Gerd Knorr
5 * based on code by:
6 * Eric Sandeen (eric_sandeen@bigfoot.com)
7 * Steve VanDeBogart (vandebo@uclink.berkeley.edu)
8 * Greg Alexander (galexand@acm.org)
9 *
10 * This code is placed under the terms of the GNU General Public License
11 *
12 * OPTIONS:
13 * debug - set to 1 if you'd like to see debug messages
14 *
15 */
16
17#include <linux/config.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/string.h>
23#include <linux/timer.h>
24#include <linux/delay.h>
25#include <linux/errno.h>
26#include <linux/slab.h>
27#include <linux/videodev.h>
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30#include <linux/init.h>
31#include <linux/smp_lock.h>
32
33#include <media/audiochip.h>
34#include <media/id.h>
35
36#include "tvaudio.h"
37
38/* ---------------------------------------------------------------------- */
39/* insmod args */
40
41static int debug = 0; /* insmod parameter */
42module_param(debug, int, 0644);
43
44MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
45MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
46MODULE_LICENSE("GPL");
47
48#define UNSET (-1U)
49#define dprintk if (debug) printk
50
51/* ---------------------------------------------------------------------- */
52/* our structs */
53
54#define MAXREGS 64
55
56struct CHIPSTATE;
57typedef int (*getvalue)(int);
58typedef int (*checkit)(struct CHIPSTATE*);
59typedef int (*initialize)(struct CHIPSTATE*);
60typedef int (*getmode)(struct CHIPSTATE*);
61typedef void (*setmode)(struct CHIPSTATE*, int mode);
62typedef void (*checkmode)(struct CHIPSTATE*);
63
64/* i2c command */
65typedef struct AUDIOCMD {
66 int count; /* # of bytes to send */
67 unsigned char bytes[MAXREGS+1]; /* addr, data, data, ... */
68} audiocmd;
69
70/* chip description */
71struct CHIPDESC {
72 char *name; /* chip name */
73 int id; /* ID */
74 int addr_lo, addr_hi; /* i2c address range */
75 int registers; /* # of registers */
76
77 int *insmodopt;
78 checkit checkit;
79 initialize initialize;
80 int flags;
81#define CHIP_HAS_VOLUME 1
82#define CHIP_HAS_BASSTREBLE 2
83#define CHIP_HAS_INPUTSEL 4
84
85 /* various i2c command sequences */
86 audiocmd init;
87
88 /* which register has which value */
89 int leftreg,rightreg,treblereg,bassreg;
90
91 /* initialize with (defaults to 65535/65535/32768/32768 */
92 int leftinit,rightinit,trebleinit,bassinit;
93
94 /* functions to convert the values (v4l -> chip) */
95 getvalue volfunc,treblefunc,bassfunc;
96
97 /* get/set mode */
98 getmode getmode;
99 setmode setmode;
100
101 /* check / autoswitch audio after channel switches */
102 checkmode checkmode;
103
104 /* input switch register + values for v4l inputs */
105 int inputreg;
106 int inputmap[8];
107 int inputmute;
108 int inputmask;
109};
110static struct CHIPDESC chiplist[];
111
112/* current state of the chip */
113struct CHIPSTATE {
114 struct i2c_client c;
115
116 /* index into CHIPDESC array */
117 int type;
118
119 /* shadow register set */
120 audiocmd shadow;
121
122 /* current settings */
123 __u16 left,right,treble,bass,mode;
124 int prevmode;
125 int norm;
126
127 /* thread */
128 pid_t tpid;
129 struct completion texit;
130 wait_queue_head_t wq;
131 struct timer_list wt;
132 int done;
133 int watch_stereo;
134};
135
136#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
137
138/* ---------------------------------------------------------------------- */
139/* i2c addresses */
140
141static unsigned short normal_i2c[] = {
142 I2C_TDA8425 >> 1,
143 I2C_TEA6300 >> 1,
144 I2C_TEA6420 >> 1,
145 I2C_TDA9840 >> 1,
146 I2C_TDA985x_L >> 1,
147 I2C_TDA985x_H >> 1,
148 I2C_TDA9874 >> 1,
149 I2C_PIC16C54 >> 1,
150 I2C_CLIENT_END };
151static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
152I2C_CLIENT_INSMOD;
153
154static struct i2c_driver driver;
155static struct i2c_client client_template;
156
157
158/* ---------------------------------------------------------------------- */
159/* i2c I/O functions */
160
161static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
162{
163 unsigned char buffer[2];
164
165 if (-1 == subaddr) {
166 dprintk("%s: chip_write: 0x%x\n",
167 i2c_clientname(&chip->c), val);
168 chip->shadow.bytes[1] = val;
169 buffer[0] = val;
170 if (1 != i2c_master_send(&chip->c,buffer,1)) {
171 printk(KERN_WARNING "%s: I/O error (write 0x%x)\n",
172 i2c_clientname(&chip->c), val);
173 return -1;
174 }
175 } else {
176 dprintk("%s: chip_write: reg%d=0x%x\n",
177 i2c_clientname(&chip->c), subaddr, val);
178 chip->shadow.bytes[subaddr+1] = val;
179 buffer[0] = subaddr;
180 buffer[1] = val;
181 if (2 != i2c_master_send(&chip->c,buffer,2)) {
182 printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n",
183 i2c_clientname(&chip->c), subaddr, val);
184 return -1;
185 }
186 }
187 return 0;
188}
189
190static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask)
191{
192 if (mask != 0) {
193 if (-1 == subaddr) {
194 val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
195 } else {
196 val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
197 }
198 }
199 return chip_write(chip, subaddr, val);
200}
201
202static int chip_read(struct CHIPSTATE *chip)
203{
204 unsigned char buffer;
205
206 if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
207 printk(KERN_WARNING "%s: I/O error (read)\n",
208 i2c_clientname(&chip->c));
209 return -1;
210 }
211 dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer);
212 return buffer;
213}
214
215static int chip_read2(struct CHIPSTATE *chip, int subaddr)
216{
217 unsigned char write[1];
218 unsigned char read[1];
219 struct i2c_msg msgs[2] = {
220 { chip->c.addr, 0, 1, write },
221 { chip->c.addr, I2C_M_RD, 1, read }
222 };
223 write[0] = subaddr;
224
225 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
226 printk(KERN_WARNING "%s: I/O error (read2)\n",
227 i2c_clientname(&chip->c));
228 return -1;
229 }
230 dprintk("%s: chip_read2: reg%d=0x%x\n",
231 i2c_clientname(&chip->c),subaddr,read[0]);
232 return read[0];
233}
234
235static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
236{
237 int i;
238
239 if (0 == cmd->count)
240 return 0;
241
242 /* update our shadow register set; print bytes if (debug > 0) */
243 dprintk("%s: chip_cmd(%s): reg=%d, data:",
244 i2c_clientname(&chip->c),name,cmd->bytes[0]);
245 for (i = 1; i < cmd->count; i++) {
246 dprintk(" 0x%x",cmd->bytes[i]);
247 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
248 }
249 dprintk("\n");
250
251 /* send data to the chip */
252 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
253 printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name);
254 return -1;
255 }
256 return 0;
257}
258
259/* ---------------------------------------------------------------------- */
260/* kernel thread for doing i2c stuff asyncronly
261 * right now it is used only to check the audio mode (mono/stereo/whatever)
262 * some time after switching to another TV channel, then turn on stereo
263 * if available, ...
264 */
265
266static void chip_thread_wake(unsigned long data)
267{
268 struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
269 wake_up_interruptible(&chip->wq);
270}
271
272static int chip_thread(void *data)
273{
274 DECLARE_WAITQUEUE(wait, current);
275 struct CHIPSTATE *chip = data;
276 struct CHIPDESC *desc = chiplist + chip->type;
277
278 daemonize("%s",i2c_clientname(&chip->c));
279 allow_signal(SIGTERM);
280 dprintk("%s: thread started\n", i2c_clientname(&chip->c));
281
282 for (;;) {
283 add_wait_queue(&chip->wq, &wait);
284 if (!chip->done) {
285 set_current_state(TASK_INTERRUPTIBLE);
286 schedule();
287 }
288 remove_wait_queue(&chip->wq, &wait);
289 try_to_freeze(PF_FREEZE);
290 if (chip->done || signal_pending(current))
291 break;
292 dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
293
294 /* don't do anything for radio or if mode != auto */
295 if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
296 continue;
297
298 /* have a look what's going on */
299 desc->checkmode(chip);
300
301 /* schedule next check */
302 mod_timer(&chip->wt, jiffies+2*HZ);
303 }
304
305 dprintk("%s: thread exiting\n", i2c_clientname(&chip->c));
306 complete_and_exit(&chip->texit, 0);
307 return 0;
308}
309
310static void generic_checkmode(struct CHIPSTATE *chip)
311{
312 struct CHIPDESC *desc = chiplist + chip->type;
313 int mode = desc->getmode(chip);
314
315 if (mode == chip->prevmode)
316 return;
317
318 dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c));
319 chip->prevmode = mode;
320
321 if (mode & VIDEO_SOUND_STEREO)
322 desc->setmode(chip,VIDEO_SOUND_STEREO);
323 else if (mode & VIDEO_SOUND_LANG1)
324 desc->setmode(chip,VIDEO_SOUND_LANG1);
325 else if (mode & VIDEO_SOUND_LANG2)
326 desc->setmode(chip,VIDEO_SOUND_LANG2);
327 else
328 desc->setmode(chip,VIDEO_SOUND_MONO);
329}
330
331/* ---------------------------------------------------------------------- */
332/* audio chip descriptions - defines+functions for tda9840 */
333
334#define TDA9840_SW 0x00
335#define TDA9840_LVADJ 0x02
336#define TDA9840_STADJ 0x03
337#define TDA9840_TEST 0x04
338
339#define TDA9840_MONO 0x10
340#define TDA9840_STEREO 0x2a
341#define TDA9840_DUALA 0x12
342#define TDA9840_DUALB 0x1e
343#define TDA9840_DUALAB 0x1a
344#define TDA9840_DUALBA 0x16
345#define TDA9840_EXTERNAL 0x7a
346
347#define TDA9840_DS_DUAL 0x20 /* Dual sound identified */
348#define TDA9840_ST_STEREO 0x40 /* Stereo sound identified */
349#define TDA9840_PONRES 0x80 /* Power-on reset detected if = 1 */
350
351#define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */
352#define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */
353
354static int tda9840_getmode(struct CHIPSTATE *chip)
355{
356 int val, mode;
357
358 val = chip_read(chip);
359 mode = VIDEO_SOUND_MONO;
360 if (val & TDA9840_DS_DUAL)
361 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
362 if (val & TDA9840_ST_STEREO)
363 mode |= VIDEO_SOUND_STEREO;
364
365 dprintk ("tda9840_getmode(): raw chip read: %d, return: %d\n",
366 val, mode);
367 return mode;
368}
369
370static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
371{
372 int update = 1;
373 int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e;
374
375 switch (mode) {
376 case VIDEO_SOUND_MONO:
377 t |= TDA9840_MONO;
378 break;
379 case VIDEO_SOUND_STEREO:
380 t |= TDA9840_STEREO;
381 break;
382 case VIDEO_SOUND_LANG1:
383 t |= TDA9840_DUALA;
384 break;
385 case VIDEO_SOUND_LANG2:
386 t |= TDA9840_DUALB;
387 break;
388 default:
389 update = 0;
390 }
391
392 if (update)
393 chip_write(chip, TDA9840_SW, t);
394}
395
396/* ---------------------------------------------------------------------- */
397/* audio chip descriptions - defines+functions for tda985x */
398
399/* subaddresses for TDA9855 */
400#define TDA9855_VR 0x00 /* Volume, right */
401#define TDA9855_VL 0x01 /* Volume, left */
402#define TDA9855_BA 0x02 /* Bass */
403#define TDA9855_TR 0x03 /* Treble */
404#define TDA9855_SW 0x04 /* Subwoofer - not connected on DTV2000 */
405
406/* subaddresses for TDA9850 */
407#define TDA9850_C4 0x04 /* Control 1 for TDA9850 */
408
409/* subaddesses for both chips */
410#define TDA985x_C5 0x05 /* Control 2 for TDA9850, Control 1 for TDA9855 */
411#define TDA985x_C6 0x06 /* Control 3 for TDA9850, Control 2 for TDA9855 */
412#define TDA985x_C7 0x07 /* Control 4 for TDA9850, Control 3 for TDA9855 */
413#define TDA985x_A1 0x08 /* Alignment 1 for both chips */
414#define TDA985x_A2 0x09 /* Alignment 2 for both chips */
415#define TDA985x_A3 0x0a /* Alignment 3 for both chips */
416
417/* Masks for bits in TDA9855 subaddresses */
418/* 0x00 - VR in TDA9855 */
419/* 0x01 - VL in TDA9855 */
420/* lower 7 bits control gain from -71dB (0x28) to 16dB (0x7f)
421 * in 1dB steps - mute is 0x27 */
422
423
424/* 0x02 - BA in TDA9855 */
425/* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19)
426 * in .5dB steps - 0 is 0x0E */
427
428
429/* 0x03 - TR in TDA9855 */
430/* 4 bits << 1 control treble gain from -12dB (0x3) to 12dB (0xb)
431 * in 3dB steps - 0 is 0x7 */
432
433/* Masks for bits in both chips' subaddresses */
434/* 0x04 - SW in TDA9855, C4/Control 1 in TDA9850 */
435/* Unique to TDA9855: */
436/* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf)
437 * in 3dB steps - mute is 0x0 */
438
439/* Unique to TDA9850: */
440/* lower 4 bits control stereo noise threshold, over which stereo turns off
441 * set to values of 0x00 through 0x0f for Ster1 through Ster16 */
442
443
444/* 0x05 - C5 - Control 1 in TDA9855 , Control 2 in TDA9850*/
445/* Unique to TDA9855: */
446#define TDA9855_MUTE 1<<7 /* GMU, Mute at outputs */
447#define TDA9855_AVL 1<<6 /* AVL, Automatic Volume Level */
448#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
449#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
450 /* Bits 0 to 3 select various combinations
451 * of line in and line out, only the
452 * interesting ones are defined */
453#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
454#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
455
456/* Unique to TDA9850: */
457/* lower 4 bits contol SAP noise threshold, over which SAP turns off
458 * set to values of 0x00 through 0x0f for SAP1 through SAP16 */
459
460
461/* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */
462/* Common to TDA9855 and TDA9850: */
463#define TDA985x_SAP 3<<6 /* Selects SAP output, mute if not received */
464#define TDA985x_STEREO 1<<6 /* Selects Stereo ouput, mono if not received */
465#define TDA985x_MONO 0 /* Forces Mono output */
466#define TDA985x_LMU 1<<3 /* Mute (LOR/LOL for 9855, OUTL/OUTR for 9850) */
467
468/* Unique to TDA9855: */
469#define TDA9855_TZCM 1<<5 /* If set, don't mute till zero crossing */
470#define TDA9855_VZCM 1<<4 /* If set, don't change volume till zero crossing*/
471#define TDA9855_LINEAR 0 /* Linear Stereo */
472#define TDA9855_PSEUDO 1 /* Pseudo Stereo */
473#define TDA9855_SPAT_30 2 /* Spatial Stereo, 30% anti-phase crosstalk */
474#define TDA9855_SPAT_50 3 /* Spatial Stereo, 52% anti-phase crosstalk */
475#define TDA9855_E_MONO 7 /* Forced mono - mono select elseware, so useless*/
476
477/* 0x07 - C7 - Control 3 in TDA9855, Control 4 in TDA9850 */
478/* Common to both TDA9855 and TDA9850: */
479/* lower 4 bits control input gain from -3.5dB (0x0) to 4dB (0xF)
480 * in .5dB steps - 0dB is 0x7 */
481
482/* 0x08, 0x09 - A1 and A2 (read/write) */
483/* Common to both TDA9855 and TDA9850: */
484/* lower 5 bites are wideband and spectral expander alignment
485 * from 0x00 to 0x1f - nominal at 0x0f and 0x10 (read/write) */
486#define TDA985x_STP 1<<5 /* Stereo Pilot/detect (read-only) */
487#define TDA985x_SAPP 1<<6 /* SAP Pilot/detect (read-only) */
488#define TDA985x_STS 1<<7 /* Stereo trigger 1= <35mV 0= <30mV (write-only)*/
489
490/* 0x0a - A3 */
491/* Common to both TDA9855 and TDA9850: */
492/* lower 3 bits control timing current for alignment: -30% (0x0), -20% (0x1),
493 * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
494#define TDA985x_ADJ 1<<7 /* Stereo adjust on/off (wideband and spectral */
495
496static int tda9855_volume(int val) { return val/0x2e8+0x27; }
497static int tda9855_bass(int val) { return val/0xccc+0x06; }
498static int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; }
499
500static int tda985x_getmode(struct CHIPSTATE *chip)
501{
502 int mode;
503
504 mode = ((TDA985x_STP | TDA985x_SAPP) &
505 chip_read(chip)) >> 4;
506 /* Add mono mode regardless of SAP and stereo */
507 /* Allows forced mono */
508 return mode | VIDEO_SOUND_MONO;
509}
510
511static void tda985x_setmode(struct CHIPSTATE *chip, int mode)
512{
513 int update = 1;
514 int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f;
515
516 switch (mode) {
517 case VIDEO_SOUND_MONO:
518 c6 |= TDA985x_MONO;
519 break;
520 case VIDEO_SOUND_STEREO:
521 c6 |= TDA985x_STEREO;
522 break;
523 case VIDEO_SOUND_LANG1:
524 c6 |= TDA985x_SAP;
525 break;
526 default:
527 update = 0;
528 }
529 if (update)
530 chip_write(chip,TDA985x_C6,c6);
531}
532
533
534/* ---------------------------------------------------------------------- */
535/* audio chip descriptions - defines+functions for tda9873h */
536
537/* Subaddresses for TDA9873H */
538
539#define TDA9873_SW 0x00 /* Switching */
540#define TDA9873_AD 0x01 /* Adjust */
541#define TDA9873_PT 0x02 /* Port */
542
543/* Subaddress 0x00: Switching Data
544 * B7..B0:
545 *
546 * B1, B0: Input source selection
547 * 0, 0 internal
548 * 1, 0 external stereo
549 * 0, 1 external mono
550 */
551#define TDA9873_INP_MASK 3
552#define TDA9873_INTERNAL 0
553#define TDA9873_EXT_STEREO 2
554#define TDA9873_EXT_MONO 1
555
556/* B3, B2: output signal select
557 * B4 : transmission mode
558 * 0, 0, 1 Mono
559 * 1, 0, 0 Stereo
560 * 1, 1, 1 Stereo (reversed channel)
561 * 0, 0, 0 Dual AB
562 * 0, 0, 1 Dual AA
563 * 0, 1, 0 Dual BB
564 * 0, 1, 1 Dual BA
565 */
566
567#define TDA9873_TR_MASK (7 << 2)
568#define TDA9873_TR_MONO 4
569#define TDA9873_TR_STEREO 1 << 4
570#define TDA9873_TR_REVERSE (1 << 3) & (1 << 2)
571#define TDA9873_TR_DUALA 1 << 2
572#define TDA9873_TR_DUALB 1 << 3
573
574/* output level controls
575 * B5: output level switch (0 = reduced gain, 1 = normal gain)
576 * B6: mute (1 = muted)
577 * B7: auto-mute (1 = auto-mute enabled)
578 */
579
580#define TDA9873_GAIN_NORMAL 1 << 5
581#define TDA9873_MUTE 1 << 6
582#define TDA9873_AUTOMUTE 1 << 7
583
584/* Subaddress 0x01: Adjust/standard */
585
586/* Lower 4 bits (C3..C0) control stereo adjustment on R channel (-0.6 - +0.7 dB)
587 * Recommended value is +0 dB
588 */
589
590#define TDA9873_STEREO_ADJ 0x06 /* 0dB gain */
591
592/* Bits C6..C4 control FM stantard
593 * C6, C5, C4
594 * 0, 0, 0 B/G (PAL FM)
595 * 0, 0, 1 M
596 * 0, 1, 0 D/K(1)
597 * 0, 1, 1 D/K(2)
598 * 1, 0, 0 D/K(3)
599 * 1, 0, 1 I
600 */
601#define TDA9873_BG 0
602#define TDA9873_M 1
603#define TDA9873_DK1 2
604#define TDA9873_DK2 3
605#define TDA9873_DK3 4
606#define TDA9873_I 5
607
608/* C7 controls identification response time (1=fast/0=normal)
609 */
610#define TDA9873_IDR_NORM 0
611#define TDA9873_IDR_FAST 1 << 7
612
613
614/* Subaddress 0x02: Port data */
615
616/* E1, E0 free programmable ports P1/P2
617 0, 0 both ports low
618 0, 1 P1 high
619 1, 0 P2 high
620 1, 1 both ports high
621*/
622
623#define TDA9873_PORTS 3
624
625/* E2: test port */
626#define TDA9873_TST_PORT 1 << 2
627
628/* E5..E3 control mono output channel (together with transmission mode bit B4)
629 *
630 * E5 E4 E3 B4 OUTM
631 * 0 0 0 0 mono
632 * 0 0 1 0 DUAL B
633 * 0 1 0 1 mono (from stereo decoder)
634 */
635#define TDA9873_MOUT_MONO 0
636#define TDA9873_MOUT_FMONO 0
637#define TDA9873_MOUT_DUALA 0
638#define TDA9873_MOUT_DUALB 1 << 3
639#define TDA9873_MOUT_ST 1 << 4
640#define TDA9873_MOUT_EXTM (1 << 4 ) & (1 << 3)
641#define TDA9873_MOUT_EXTL 1 << 5
642#define TDA9873_MOUT_EXTR (1 << 5 ) & (1 << 3)
643#define TDA9873_MOUT_EXTLR (1 << 5 ) & (1 << 4)
644#define TDA9873_MOUT_MUTE (1 << 5 ) & (1 << 4) & (1 << 3)
645
646/* Status bits: (chip read) */
647#define TDA9873_PONR 0 /* Power-on reset detected if = 1 */
648#define TDA9873_STEREO 2 /* Stereo sound is identified */
649#define TDA9873_DUAL 4 /* Dual sound is identified */
650
651static int tda9873_getmode(struct CHIPSTATE *chip)
652{
653 int val,mode;
654
655 val = chip_read(chip);
656 mode = VIDEO_SOUND_MONO;
657 if (val & TDA9873_STEREO)
658 mode |= VIDEO_SOUND_STEREO;
659 if (val & TDA9873_DUAL)
660 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
661 dprintk ("tda9873_getmode(): raw chip read: %d, return: %d\n",
662 val, mode);
663 return mode;
664}
665
666static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
667{
668 int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
669 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
670
671 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
672 dprintk("tda9873_setmode(): external input\n");
673 return;
674 }
675
676 dprintk("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
677 dprintk("tda9873_setmode(): sw_data = %d\n", sw_data);
678
679 switch (mode) {
680 case VIDEO_SOUND_MONO:
681 sw_data |= TDA9873_TR_MONO;
682 break;
683 case VIDEO_SOUND_STEREO:
684 sw_data |= TDA9873_TR_STEREO;
685 break;
686 case VIDEO_SOUND_LANG1:
687 sw_data |= TDA9873_TR_DUALA;
688 break;
689 case VIDEO_SOUND_LANG2:
690 sw_data |= TDA9873_TR_DUALB;
691 break;
692 default:
693 chip->mode = 0;
694 return;
695 }
696
697 chip_write(chip, TDA9873_SW, sw_data);
698 dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
699 mode, sw_data);
700}
701
702static int tda9873_checkit(struct CHIPSTATE *chip)
703{
704 int rc;
705
706 if (-1 == (rc = chip_read2(chip,254)))
707 return 0;
708 return (rc & ~0x1f) == 0x80;
709}
710
711
712/* ---------------------------------------------------------------------- */
713/* audio chip description - defines+functions for tda9874h and tda9874a */
714/* Dariusz Kowalewski <darekk@automex.pl> */
715
716/* Subaddresses for TDA9874H and TDA9874A (slave rx) */
717#define TDA9874A_AGCGR 0x00 /* AGC gain */
718#define TDA9874A_GCONR 0x01 /* general config */
719#define TDA9874A_MSR 0x02 /* monitor select */
720#define TDA9874A_C1FRA 0x03 /* carrier 1 freq. */
721#define TDA9874A_C1FRB 0x04 /* carrier 1 freq. */
722#define TDA9874A_C1FRC 0x05 /* carrier 1 freq. */
723#define TDA9874A_C2FRA 0x06 /* carrier 2 freq. */
724#define TDA9874A_C2FRB 0x07 /* carrier 2 freq. */
725#define TDA9874A_C2FRC 0x08 /* carrier 2 freq. */
726#define TDA9874A_DCR 0x09 /* demodulator config */
727#define TDA9874A_FMER 0x0a /* FM de-emphasis */
728#define TDA9874A_FMMR 0x0b /* FM dematrix */
729#define TDA9874A_C1OLAR 0x0c /* ch.1 output level adj. */
730#define TDA9874A_C2OLAR 0x0d /* ch.2 output level adj. */
731#define TDA9874A_NCONR 0x0e /* NICAM config */
732#define TDA9874A_NOLAR 0x0f /* NICAM output level adj. */
733#define TDA9874A_NLELR 0x10 /* NICAM lower error limit */
734#define TDA9874A_NUELR 0x11 /* NICAM upper error limit */
735#define TDA9874A_AMCONR 0x12 /* audio mute control */
736#define TDA9874A_SDACOSR 0x13 /* stereo DAC output select */
737#define TDA9874A_AOSR 0x14 /* analog output select */
738#define TDA9874A_DAICONR 0x15 /* digital audio interface config */
739#define TDA9874A_I2SOSR 0x16 /* I2S-bus output select */
740#define TDA9874A_I2SOLAR 0x17 /* I2S-bus output level adj. */
741#define TDA9874A_MDACOSR 0x18 /* mono DAC output select (tda9874a) */
742#define TDA9874A_ESP 0xFF /* easy standard progr. (tda9874a) */
743
744/* Subaddresses for TDA9874H and TDA9874A (slave tx) */
745#define TDA9874A_DSR 0x00 /* device status */
746#define TDA9874A_NSR 0x01 /* NICAM status */
747#define TDA9874A_NECR 0x02 /* NICAM error count */
748#define TDA9874A_DR1 0x03 /* add. data LSB */
749#define TDA9874A_DR2 0x04 /* add. data MSB */
750#define TDA9874A_LLRA 0x05 /* monitor level read-out LSB */
751#define TDA9874A_LLRB 0x06 /* monitor level read-out MSB */
752#define TDA9874A_SIFLR 0x07 /* SIF level */
753#define TDA9874A_TR2 252 /* test reg. 2 */
754#define TDA9874A_TR1 253 /* test reg. 1 */
755#define TDA9874A_DIC 254 /* device id. code */
756#define TDA9874A_SIC 255 /* software id. code */
757
758
759static int tda9874a_mode = 1; /* 0: A2, 1: NICAM */
760static int tda9874a_GCONR = 0xc0; /* default config. input pin: SIFSEL=0 */
761static int tda9874a_NCONR = 0x01; /* default NICAM config.: AMSEL=0,AMUTE=1 */
762static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */
763static int tda9874a_dic = -1; /* device id. code */
764
765/* insmod options for tda9874a */
766static unsigned int tda9874a_SIF = UNSET;
767static unsigned int tda9874a_AMSEL = UNSET;
768static unsigned int tda9874a_STD = UNSET;
769module_param(tda9874a_SIF, int, 0444);
770module_param(tda9874a_AMSEL, int, 0444);
771module_param(tda9874a_STD, int, 0444);
772
773/*
774 * initialization table for tda9874 decoder:
775 * - carrier 1 freq. registers (3 bytes)
776 * - carrier 2 freq. registers (3 bytes)
777 * - demudulator config register
778 * - FM de-emphasis register (slow identification mode)
779 * Note: frequency registers must be written in single i2c transfer.
780 */
781static struct tda9874a_MODES {
782 char *name;
783 audiocmd cmd;
784} tda9874a_modelist[9] = {
785 { "A2, B/G",
786 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} },
787 { "A2, M (Korea)",
788 { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} },
789 { "A2, D/K (1)",
790 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x82,0x60,0x00, 0x00,0x00 }} },
791 { "A2, D/K (2)",
792 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x8C,0x75,0x55, 0x00,0x00 }} },
793 { "A2, D/K (3)",
794 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x77,0xA0,0x00, 0x00,0x00 }} },
795 { "NICAM, I",
796 { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} },
797 { "NICAM, B/G",
798 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} },
799 { "NICAM, D/K", /* default */
800 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} },
801 { "NICAM, L",
802 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} }
803};
804
805static int tda9874a_setup(struct CHIPSTATE *chip)
806{
807 chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
808 chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
809 chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
810 if(tda9874a_dic == 0x11) {
811 chip_write(chip, TDA9874A_FMMR, 0x80);
812 } else { /* dic == 0x07 */
813 chip_cmd(chip,"tda9874_modelist",&tda9874a_modelist[tda9874a_STD].cmd);
814 chip_write(chip, TDA9874A_FMMR, 0x00);
815 }
816 chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
817 chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
818 chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
819 chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
820 /* Note: If signal quality is poor you may want to change NICAM */
821 /* error limit registers (NLELR and NUELR) to some greater values. */
822 /* Then the sound would remain stereo, but won't be so clear. */
823 chip_write(chip, TDA9874A_NLELR, 0x14); /* default */
824 chip_write(chip, TDA9874A_NUELR, 0x50); /* default */
825
826 if(tda9874a_dic == 0x11) {
827 chip_write(chip, TDA9874A_AMCONR, 0xf9);
828 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
829 chip_write(chip, TDA9874A_AOSR, 0x80);
830 chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
831 chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
832 } else { /* dic == 0x07 */
833 chip_write(chip, TDA9874A_AMCONR, 0xfb);
834 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
835 chip_write(chip, TDA9874A_AOSR, 0x00); // or 0x10
836 }
837 dprintk("tda9874a_setup(): %s [0x%02X].\n",
838 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
839 return 1;
840}
841
842static int tda9874a_getmode(struct CHIPSTATE *chip)
843{
844 int dsr,nsr,mode;
845 int necr; /* just for debugging */
846
847 mode = VIDEO_SOUND_MONO;
848
849 if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))
850 return mode;
851 if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
852 return mode;
853 if(-1 == (necr = chip_read2(chip,TDA9874A_NECR)))
854 return mode;
855
856 /* need to store dsr/nsr somewhere */
857 chip->shadow.bytes[MAXREGS-2] = dsr;
858 chip->shadow.bytes[MAXREGS-1] = nsr;
859
860 if(tda9874a_mode) {
861 /* Note: DSR.RSSF and DSR.AMSTAT bits are also checked.
862 * If NICAM auto-muting is enabled, DSR.AMSTAT=1 indicates
863 * that sound has (temporarily) switched from NICAM to
864 * mono FM (or AM) on 1st sound carrier due to high NICAM bit
865 * error count. So in fact there is no stereo in this case :-(
866 * But changing the mode to VIDEO_SOUND_MONO would switch
867 * external 4052 multiplexer in audio_hook().
868 */
869#if 0
870 if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */
871 mode |= VIDEO_SOUND_STEREO;
872#else
873 if(nsr & 0x02) /* NSR.S/MB=1 */
874 mode |= VIDEO_SOUND_STEREO;
875#endif
876 if(nsr & 0x01) /* NSR.D/SB=1 */
877 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
878 } else {
879 if(dsr & 0x02) /* DSR.IDSTE=1 */
880 mode |= VIDEO_SOUND_STEREO;
881 if(dsr & 0x04) /* DSR.IDDUA=1 */
882 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
883 }
884
885 dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
886 dsr, nsr, necr, mode);
887 return mode;
888}
889
890static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
891{
892 /* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */
893 /* If auto-muting is disabled, we can hear a signal of degrading quality. */
894 if(tda9874a_mode) {
895 if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */
896 tda9874a_NCONR &= 0xfe; /* enable */
897 else
898 tda9874a_NCONR |= 0x01; /* disable */
899 chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
900 }
901
902 /* Note: TDA9874A supports automatic FM dematrixing (FMMR register)
903 * and has auto-select function for audio output (AOSR register).
904 * Old TDA9874H doesn't support these features.
905 * TDA9874A also has additional mono output pin (OUTM), which
906 * on same (all?) tv-cards is not used, anyway (as well as MONOIN).
907 */
908 if(tda9874a_dic == 0x11) {
909 int aosr = 0x80;
910 int mdacosr = (tda9874a_mode) ? 0x82:0x80;
911
912 switch(mode) {
913 case VIDEO_SOUND_MONO:
914 case VIDEO_SOUND_STEREO:
915 break;
916 case VIDEO_SOUND_LANG1:
917 aosr = 0x80; /* auto-select, dual A/A */
918 mdacosr = (tda9874a_mode) ? 0x82:0x80;
919 break;
920 case VIDEO_SOUND_LANG2:
921 aosr = 0xa0; /* auto-select, dual B/B */
922 mdacosr = (tda9874a_mode) ? 0x83:0x81;
923 break;
924 default:
925 chip->mode = 0;
926 return;
927 }
928 chip_write(chip, TDA9874A_AOSR, aosr);
929 chip_write(chip, TDA9874A_MDACOSR, mdacosr);
930
931 dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
932 mode, aosr, mdacosr);
933
934 } else { /* dic == 0x07 */
935 int fmmr,aosr;
936
937 switch(mode) {
938 case VIDEO_SOUND_MONO:
939 fmmr = 0x00; /* mono */
940 aosr = 0x10; /* A/A */
941 break;
942 case VIDEO_SOUND_STEREO:
943 if(tda9874a_mode) {
944 fmmr = 0x00;
945 aosr = 0x00; /* handled by NICAM auto-mute */
946 } else {
947 fmmr = (tda9874a_ESP == 1) ? 0x05 : 0x04; /* stereo */
948 aosr = 0x00;
949 }
950 break;
951 case VIDEO_SOUND_LANG1:
952 fmmr = 0x02; /* dual */
953 aosr = 0x10; /* dual A/A */
954 break;
955 case VIDEO_SOUND_LANG2:
956 fmmr = 0x02; /* dual */
957 aosr = 0x20; /* dual B/B */
958 break;
959 default:
960 chip->mode = 0;
961 return;
962 }
963 chip_write(chip, TDA9874A_FMMR, fmmr);
964 chip_write(chip, TDA9874A_AOSR, aosr);
965
966 dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
967 mode, fmmr, aosr);
968 }
969}
970
971static int tda9874a_checkit(struct CHIPSTATE *chip)
972{
973 int dic,sic; /* device id. and software id. codes */
974
975 if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
976 return 0;
977 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
978 return 0;
979
980 dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
981
982 if((dic == 0x11)||(dic == 0x07)) {
983 printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h");
984 tda9874a_dic = dic; /* remember device id. */
985 return 1;
986 }
987 return 0; /* not found */
988}
989
990static int tda9874a_initialize(struct CHIPSTATE *chip)
991{
992 if (tda9874a_SIF > 2)
993 tda9874a_SIF = 1;
994 if (tda9874a_STD >= 8)
995 tda9874a_STD = 0;
996 if(tda9874a_AMSEL > 1)
997 tda9874a_AMSEL = 0;
998
999 if(tda9874a_SIF == 1)
1000 tda9874a_GCONR = 0xc0; /* sound IF input 1 */
1001 else
1002 tda9874a_GCONR = 0xc1; /* sound IF input 2 */
1003
1004 tda9874a_ESP = tda9874a_STD;
1005 tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
1006
1007 if(tda9874a_AMSEL == 0)
1008 tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
1009 else
1010 tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
1011
1012 tda9874a_setup(chip);
1013 return 0;
1014}
1015
1016
1017/* ---------------------------------------------------------------------- */
1018/* audio chip descriptions - defines+functions for tea6420 */
1019
1020#define TEA6300_VL 0x00 /* volume left */
1021#define TEA6300_VR 0x01 /* volume right */
1022#define TEA6300_BA 0x02 /* bass */
1023#define TEA6300_TR 0x03 /* treble */
1024#define TEA6300_FA 0x04 /* fader control */
1025#define TEA6300_S 0x05 /* switch register */
1026 /* values for those registers: */
1027#define TEA6300_S_SA 0x01 /* stereo A input */
1028#define TEA6300_S_SB 0x02 /* stereo B */
1029#define TEA6300_S_SC 0x04 /* stereo C */
1030#define TEA6300_S_GMU 0x80 /* general mute */
1031
1032#define TEA6320_V 0x00 /* volume (0-5)/loudness off (6)/zero crossing mute(7) */
1033#define TEA6320_FFR 0x01 /* fader front right (0-5) */
1034#define TEA6320_FFL 0x02 /* fader front left (0-5) */
1035#define TEA6320_FRR 0x03 /* fader rear right (0-5) */
1036#define TEA6320_FRL 0x04 /* fader rear left (0-5) */
1037#define TEA6320_BA 0x05 /* bass (0-4) */
1038#define TEA6320_TR 0x06 /* treble (0-4) */
1039#define TEA6320_S 0x07 /* switch register */
1040 /* values for those registers: */
1041#define TEA6320_S_SA 0x07 /* stereo A input */
1042#define TEA6320_S_SB 0x06 /* stereo B */
1043#define TEA6320_S_SC 0x05 /* stereo C */
1044#define TEA6320_S_SD 0x04 /* stereo D */
1045#define TEA6320_S_GMU 0x80 /* general mute */
1046
1047#define TEA6420_S_SA 0x00 /* stereo A input */
1048#define TEA6420_S_SB 0x01 /* stereo B */
1049#define TEA6420_S_SC 0x02 /* stereo C */
1050#define TEA6420_S_SD 0x03 /* stereo D */
1051#define TEA6420_S_SE 0x04 /* stereo E */
1052#define TEA6420_S_GMU 0x05 /* general mute */
1053
1054static int tea6300_shift10(int val) { return val >> 10; }
1055static int tea6300_shift12(int val) { return val >> 12; }
1056
1057/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */
1058/* 0x0c mirror those immediately higher) */
1059static int tea6320_volume(int val) { return (val / (65535/(63-12)) + 12) & 0x3f; }
1060static int tea6320_shift11(int val) { return val >> 11; }
1061static int tea6320_initialize(struct CHIPSTATE * chip)
1062{
1063 chip_write(chip, TEA6320_FFR, 0x3f);
1064 chip_write(chip, TEA6320_FFL, 0x3f);
1065 chip_write(chip, TEA6320_FRR, 0x3f);
1066 chip_write(chip, TEA6320_FRL, 0x3f);
1067
1068 return 0;
1069}
1070
1071
1072/* ---------------------------------------------------------------------- */
1073/* audio chip descriptions - defines+functions for tda8425 */
1074
1075#define TDA8425_VL 0x00 /* volume left */
1076#define TDA8425_VR 0x01 /* volume right */
1077#define TDA8425_BA 0x02 /* bass */
1078#define TDA8425_TR 0x03 /* treble */
1079#define TDA8425_S1 0x08 /* switch functions */
1080 /* values for those registers: */
1081#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1082#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1083#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
1084#define TDA8425_S1_MU 0x20 /* mute bit */
1085#define TDA8425_S1_STEREO 0x18 /* stereo bits */
1086#define TDA8425_S1_STEREO_SPATIAL 0x18 /* spatial stereo */
1087#define TDA8425_S1_STEREO_LINEAR 0x08 /* linear stereo */
1088#define TDA8425_S1_STEREO_PSEUDO 0x10 /* pseudo stereo */
1089#define TDA8425_S1_STEREO_MONO 0x00 /* forced mono */
1090#define TDA8425_S1_ML 0x06 /* language selector */
1091#define TDA8425_S1_ML_SOUND_A 0x02 /* sound a */
1092#define TDA8425_S1_ML_SOUND_B 0x04 /* sound b */
1093#define TDA8425_S1_ML_STEREO 0x06 /* stereo */
1094#define TDA8425_S1_IS 0x01 /* channel selector */
1095
1096
1097static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; }
1098static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
1099
1100static int tda8425_initialize(struct CHIPSTATE *chip)
1101{
1102 struct CHIPDESC *desc = chiplist + chip->type;
1103 int inputmap[8] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1,
1104 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF,
1105 /* off */ TDA8425_S1_OFF, /* on */ TDA8425_S1_CH2};
1106
1107 if (chip->c.adapter->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) {
1108 memcpy (desc->inputmap, inputmap, sizeof (inputmap));
1109 }
1110 return 0;
1111}
1112
1113static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1114{
1115 int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1;
1116
1117 if (mode & VIDEO_SOUND_LANG1) {
1118 s1 |= TDA8425_S1_ML_SOUND_A;
1119 s1 |= TDA8425_S1_STEREO_PSEUDO;
1120
1121 } else if (mode & VIDEO_SOUND_LANG2) {
1122 s1 |= TDA8425_S1_ML_SOUND_B;
1123 s1 |= TDA8425_S1_STEREO_PSEUDO;
1124
1125 } else {
1126 s1 |= TDA8425_S1_ML_STEREO;
1127
1128 if (mode & VIDEO_SOUND_MONO)
1129 s1 |= TDA8425_S1_STEREO_MONO;
1130 if (mode & VIDEO_SOUND_STEREO)
1131 s1 |= TDA8425_S1_STEREO_SPATIAL;
1132 }
1133 chip_write(chip,TDA8425_S1,s1);
1134}
1135
1136
1137/* ---------------------------------------------------------------------- */
1138/* audio chip descriptions - defines+functions for pic16c54 (PV951) */
1139
1140/* the registers of 16C54, I2C sub address. */
1141#define PIC16C54_REG_KEY_CODE 0x01 /* Not use. */
1142#define PIC16C54_REG_MISC 0x02
1143
1144/* bit definition of the RESET register, I2C data. */
1145#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1146 /* code of remote controller */
1147#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1148#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1149#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
1150#define PIC16C54_MISC_SND_MUTE 0x10 /* bit 4, Mute Audio(Line-in and Tuner) */
1151#define PIC16C54_MISC_SND_NOTMUTE 0x20 /* bit 5 */
1152#define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */
1153#define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */
1154
1155/* ---------------------------------------------------------------------- */
1156/* audio chip descriptions - defines+functions for TA8874Z */
1157
1158// write 1st byte
1159#define TA8874Z_LED_STE 0x80
1160#define TA8874Z_LED_BIL 0x40
1161#define TA8874Z_LED_EXT 0x20
1162#define TA8874Z_MONO_SET 0x10
1163#define TA8874Z_MUTE 0x08
1164#define TA8874Z_F_MONO 0x04
1165#define TA8874Z_MODE_SUB 0x02
1166#define TA8874Z_MODE_MAIN 0x01
1167
1168// write 2nd byte
1169//#define TA8874Z_TI 0x80 // test mode
1170#define TA8874Z_SEPARATION 0x3f
1171#define TA8874Z_SEPARATION_DEFAULT 0x10
1172
1173// read
1174#define TA8874Z_B1 0x80
1175#define TA8874Z_B0 0x40
1176#define TA8874Z_CHAG_FLAG 0x20
1177
1178// B1 B0
1179// mono L H
1180// stereo L L
1181// BIL H L
1182
1183static int ta8874z_getmode(struct CHIPSTATE *chip)
1184{
1185 int val, mode;
1186
1187 val = chip_read(chip);
1188 mode = VIDEO_SOUND_MONO;
1189 if (val & TA8874Z_B1){
1190 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
1191 }else if (!(val & TA8874Z_B0)){
1192 mode |= VIDEO_SOUND_STEREO;
1193 }
1194 //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode);
1195 return mode;
1196}
1197
1198static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}};
1199static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}};
1200static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}};
1201static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};
1202
1203static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
1204{
1205 int update = 1;
1206 audiocmd *t = NULL;
1207 dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode);
1208
1209 switch(mode){
1210 case VIDEO_SOUND_MONO:
1211 t = &ta8874z_mono;
1212 break;
1213 case VIDEO_SOUND_STEREO:
1214 t = &ta8874z_stereo;
1215 break;
1216 case VIDEO_SOUND_LANG1:
1217 t = &ta8874z_main;
1218 break;
1219 case VIDEO_SOUND_LANG2:
1220 t = &ta8874z_sub;
1221 break;
1222 default:
1223 update = 0;
1224 }
1225
1226 if(update)
1227 chip_cmd(chip, "TA8874Z", t);
1228}
1229
1230static int ta8874z_checkit(struct CHIPSTATE *chip)
1231{
1232 int rc;
1233 rc = chip_read(chip);
1234 return ((rc & 0x1f) == 0x1f) ? 1 : 0;
1235}
1236
1237/* ---------------------------------------------------------------------- */
1238/* audio chip descriptions - struct CHIPDESC */
1239
1240/* insmod options to enable/disable individual audio chips */
1241int tda8425 = 1;
1242int tda9840 = 1;
1243int tda9850 = 1;
1244int tda9855 = 1;
1245int tda9873 = 1;
1246int tda9874a = 1;
1247int tea6300 = 0; // address clash with msp34xx
1248int tea6320 = 0; // address clash with msp34xx
1249int tea6420 = 1;
1250int pic16c54 = 1;
1251int ta8874z = 0; // address clash with tda9840
1252
1253module_param(tda8425, int, 0444);
1254module_param(tda9840, int, 0444);
1255module_param(tda9850, int, 0444);
1256module_param(tda9855, int, 0444);
1257module_param(tda9873, int, 0444);
1258module_param(tda9874a, int, 0444);
1259module_param(tea6300, int, 0444);
1260module_param(tea6320, int, 0444);
1261module_param(tea6420, int, 0444);
1262module_param(pic16c54, int, 0444);
1263module_param(ta8874z, int, 0444);
1264
1265static struct CHIPDESC chiplist[] = {
1266 {
1267 .name = "tda9840",
1268 .id = I2C_DRIVERID_TDA9840,
1269 .insmodopt = &tda9840,
1270 .addr_lo = I2C_TDA9840 >> 1,
1271 .addr_hi = I2C_TDA9840 >> 1,
1272 .registers = 5,
1273
1274 .getmode = tda9840_getmode,
1275 .setmode = tda9840_setmode,
1276 .checkmode = generic_checkmode,
1277
1278 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1279 /* ,TDA9840_SW, TDA9840_MONO */} }
1280 },
1281 {
1282 .name = "tda9873h",
1283 .id = I2C_DRIVERID_TDA9873,
1284 .checkit = tda9873_checkit,
1285 .insmodopt = &tda9873,
1286 .addr_lo = I2C_TDA985x_L >> 1,
1287 .addr_hi = I2C_TDA985x_H >> 1,
1288 .registers = 3,
1289 .flags = CHIP_HAS_INPUTSEL,
1290
1291 .getmode = tda9873_getmode,
1292 .setmode = tda9873_setmode,
1293 .checkmode = generic_checkmode,
1294
1295 .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
1296 .inputreg = TDA9873_SW,
1297 .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE,
1298 .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},
1299 .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE,
1300
1301 },
1302 {
1303 .name = "tda9874h/a",
1304 .id = I2C_DRIVERID_TDA9874,
1305 .checkit = tda9874a_checkit,
1306 .initialize = tda9874a_initialize,
1307 .insmodopt = &tda9874a,
1308 .addr_lo = I2C_TDA9874 >> 1,
1309 .addr_hi = I2C_TDA9874 >> 1,
1310
1311 .getmode = tda9874a_getmode,
1312 .setmode = tda9874a_setmode,
1313 .checkmode = generic_checkmode,
1314 },
1315 {
1316 .name = "tda9850",
1317 .id = I2C_DRIVERID_TDA9850,
1318 .insmodopt = &tda9850,
1319 .addr_lo = I2C_TDA985x_L >> 1,
1320 .addr_hi = I2C_TDA985x_H >> 1,
1321 .registers = 11,
1322
1323 .getmode = tda985x_getmode,
1324 .setmode = tda985x_setmode,
1325
1326 .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } }
1327 },
1328 {
1329 .name = "tda9855",
1330 .id = I2C_DRIVERID_TDA9855,
1331 .insmodopt = &tda9855,
1332 .addr_lo = I2C_TDA985x_L >> 1,
1333 .addr_hi = I2C_TDA985x_H >> 1,
1334 .registers = 11,
1335 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
1336
1337 .leftreg = TDA9855_VL,
1338 .rightreg = TDA9855_VR,
1339 .bassreg = TDA9855_BA,
1340 .treblereg = TDA9855_TR,
1341 .volfunc = tda9855_volume,
1342 .bassfunc = tda9855_bass,
1343 .treblefunc = tda9855_treble,
1344
1345 .getmode = tda985x_getmode,
1346 .setmode = tda985x_setmode,
1347
1348 .init = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2,
1349 TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT,
1350 TDA985x_STEREO | TDA9855_LINEAR | TDA9855_TZCM | TDA9855_VZCM,
1351 0x07, 0x10, 0x10, 0x03 }}
1352 },
1353 {
1354 .name = "tea6300",
1355 .id = I2C_DRIVERID_TEA6300,
1356 .insmodopt = &tea6300,
1357 .addr_lo = I2C_TEA6300 >> 1,
1358 .addr_hi = I2C_TEA6300 >> 1,
1359 .registers = 6,
1360 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1361
1362 .leftreg = TEA6300_VR,
1363 .rightreg = TEA6300_VL,
1364 .bassreg = TEA6300_BA,
1365 .treblereg = TEA6300_TR,
1366 .volfunc = tea6300_shift10,
1367 .bassfunc = tea6300_shift12,
1368 .treblefunc = tea6300_shift12,
1369
1370 .inputreg = TEA6300_S,
1371 .inputmap = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC },
1372 .inputmute = TEA6300_S_GMU,
1373 },
1374 {
1375 .name = "tea6320",
1376 .id = I2C_DRIVERID_TEA6300,
1377 .initialize = tea6320_initialize,
1378 .insmodopt = &tea6320,
1379 .addr_lo = I2C_TEA6300 >> 1,
1380 .addr_hi = I2C_TEA6300 >> 1,
1381 .registers = 8,
1382 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1383
1384 .leftreg = TEA6320_V,
1385 .rightreg = TEA6320_V,
1386 .bassreg = TEA6320_BA,
1387 .treblereg = TEA6320_TR,
1388 .volfunc = tea6320_volume,
1389 .bassfunc = tea6320_shift11,
1390 .treblefunc = tea6320_shift11,
1391
1392 .inputreg = TEA6320_S,
1393 .inputmap = { TEA6320_S_SA, TEA6420_S_SB, TEA6300_S_SC, TEA6320_S_SD },
1394 .inputmute = TEA6300_S_GMU,
1395 },
1396 {
1397 .name = "tea6420",
1398 .id = I2C_DRIVERID_TEA6420,
1399 .insmodopt = &tea6420,
1400 .addr_lo = I2C_TEA6420 >> 1,
1401 .addr_hi = I2C_TEA6420 >> 1,
1402 .registers = 1,
1403 .flags = CHIP_HAS_INPUTSEL,
1404
1405 .inputreg = -1,
1406 .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC },
1407 .inputmute = TEA6300_S_GMU,
1408 },
1409 {
1410 .name = "tda8425",
1411 .id = I2C_DRIVERID_TDA8425,
1412 .insmodopt = &tda8425,
1413 .addr_lo = I2C_TDA8425 >> 1,
1414 .addr_hi = I2C_TDA8425 >> 1,
1415 .registers = 9,
1416 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1417
1418 .leftreg = TDA8425_VL,
1419 .rightreg = TDA8425_VR,
1420 .bassreg = TDA8425_BA,
1421 .treblereg = TDA8425_TR,
1422 .volfunc = tda8425_shift10,
1423 .bassfunc = tda8425_shift12,
1424 .treblefunc = tda8425_shift12,
1425
1426 .inputreg = TDA8425_S1,
1427 .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
1428 .inputmute = TDA8425_S1_OFF,
1429
1430 .setmode = tda8425_setmode,
1431 .initialize = tda8425_initialize,
1432 },
1433 {
1434 .name = "pic16c54 (PV951)",
1435 .id = I2C_DRIVERID_PIC16C54_PV951,
1436 .insmodopt = &pic16c54,
1437 .addr_lo = I2C_PIC16C54 >> 1,
1438 .addr_hi = I2C_PIC16C54>> 1,
1439 .registers = 2,
1440 .flags = CHIP_HAS_INPUTSEL,
1441
1442 .inputreg = PIC16C54_REG_MISC,
1443 .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
1444 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1445 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1446 PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE,
1447 PIC16C54_MISC_SND_NOTMUTE},
1448 .inputmute = PIC16C54_MISC_SND_MUTE,
1449 },
1450 {
1451 .name = "ta8874z",
1452 .id = -1,
1453 //.id = I2C_DRIVERID_TA8874Z,
1454 .checkit = ta8874z_checkit,
1455 .insmodopt = &ta8874z,
1456 .addr_lo = I2C_TDA9840 >> 1,
1457 .addr_hi = I2C_TDA9840 >> 1,
1458 .registers = 2,
1459
1460 .getmode = ta8874z_getmode,
1461 .setmode = ta8874z_setmode,
1462 .checkmode = generic_checkmode,
1463
1464 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1465 },
1466 { .name = NULL } /* EOF */
1467};
1468
1469
1470/* ---------------------------------------------------------------------- */
1471/* i2c registration */
1472
1473static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1474{
1475 struct CHIPSTATE *chip;
1476 struct CHIPDESC *desc;
1477
1478 chip = kmalloc(sizeof(*chip),GFP_KERNEL);
1479 if (!chip)
1480 return -ENOMEM;
1481 memset(chip,0,sizeof(*chip));
1482 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1483 chip->c.adapter = adap;
1484 chip->c.addr = addr;
1485 i2c_set_clientdata(&chip->c, chip);
1486
1487 /* find description for the chip */
1488 dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1);
1489 for (desc = chiplist; desc->name != NULL; desc++) {
1490 if (0 == *(desc->insmodopt))
1491 continue;
1492 if (addr < desc->addr_lo ||
1493 addr > desc->addr_hi)
1494 continue;
1495 if (desc->checkit && !desc->checkit(chip))
1496 continue;
1497 break;
1498 }
1499 if (desc->name == NULL) {
1500 dprintk("tvaudio: no matching chip description found\n");
1501 return -EIO;
1502 }
1503 printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1);
1504 dprintk("tvaudio: matches:%s%s%s.\n",
1505 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1506 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1507 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
1508
1509 /* fill required data structures */
1510 strcpy(i2c_clientname(&chip->c),desc->name);
1511 chip->type = desc-chiplist;
1512 chip->shadow.count = desc->registers+1;
1513 chip->prevmode = -1;
1514 /* register */
1515 i2c_attach_client(&chip->c);
1516
1517 /* initialization */
1518 if (desc->initialize != NULL)
1519 desc->initialize(chip);
1520 else
1521 chip_cmd(chip,"init",&desc->init);
1522
1523 if (desc->flags & CHIP_HAS_VOLUME) {
1524 chip->left = desc->leftinit ? desc->leftinit : 65535;
1525 chip->right = desc->rightinit ? desc->rightinit : 65535;
1526 chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
1527 chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
1528 }
1529 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1530 chip->treble = desc->trebleinit ? desc->trebleinit : 32768;
1531 chip->bass = desc->bassinit ? desc->bassinit : 32768;
1532 chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1533 chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1534 }
1535
1536 chip->tpid = -1;
1537 if (desc->checkmode) {
1538 /* start async thread */
1539 init_timer(&chip->wt);
1540 chip->wt.function = chip_thread_wake;
1541 chip->wt.data = (unsigned long)chip;
1542 init_waitqueue_head(&chip->wq);
1543 init_completion(&chip->texit);
1544 chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
1545 if (chip->tpid < 0)
1546 printk(KERN_WARNING "%s: kernel_thread() failed\n",
1547 i2c_clientname(&chip->c));
1548 wake_up_interruptible(&chip->wq);
1549 }
1550 return 0;
1551}
1552
1553static int chip_probe(struct i2c_adapter *adap)
1554{
1555 /* don't attach on saa7146 based cards,
1556 because dedicated drivers are used */
1557 if ((adap->id & I2C_ALGO_SAA7146))
1558 return 0;
1559#ifdef I2C_CLASS_TV_ANALOG
1560 if (adap->class & I2C_CLASS_TV_ANALOG)
1561 return i2c_probe(adap, &addr_data, chip_attach);
1562#else
1563 switch (adap->id) {
1564 case I2C_ALGO_BIT | I2C_HW_B_BT848:
1565 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
1566 case I2C_ALGO_SAA7134:
1567 return i2c_probe(adap, &addr_data, chip_attach);
1568 }
1569#endif
1570 return 0;
1571}
1572
1573static int chip_detach(struct i2c_client *client)
1574{
1575 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1576
1577 del_timer_sync(&chip->wt);
1578 if (chip->tpid >= 0) {
1579 /* shutdown async thread */
1580 chip->done = 1;
1581 wake_up_interruptible(&chip->wq);
1582 wait_for_completion(&chip->texit);
1583 }
1584
1585 i2c_detach_client(&chip->c);
1586 kfree(chip);
1587 return 0;
1588}
1589
1590/* ---------------------------------------------------------------------- */
1591/* video4linux interface */
1592
1593static int chip_command(struct i2c_client *client,
1594 unsigned int cmd, void *arg)
1595{
1596 __u16 *sarg = arg;
1597 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1598 struct CHIPDESC *desc = chiplist + chip->type;
1599
1600 dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd);
1601
1602 switch (cmd) {
1603 case AUDC_SET_INPUT:
1604 if (desc->flags & CHIP_HAS_INPUTSEL) {
1605 if (*sarg & 0x80)
1606 chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
1607 else
1608 chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask);
1609 }
1610 break;
1611
1612 case AUDC_SET_RADIO:
1613 dprintk(KERN_DEBUG "tvaudio: AUDC_SET_RADIO\n");
1614 chip->norm = VIDEO_MODE_RADIO;
1615 chip->watch_stereo = 0;
1616 /* del_timer(&chip->wt); */
1617 break;
1618
1619 /* --- v4l ioctls --- */
1620 /* take care: bttv does userspace copying, we'll get a
1621 kernel pointer here... */
1622 case VIDIOCGAUDIO:
1623 {
1624 struct video_audio *va = arg;
1625
1626 if (desc->flags & CHIP_HAS_VOLUME) {
1627 va->flags |= VIDEO_AUDIO_VOLUME;
1628 va->volume = max(chip->left,chip->right);
1629 if (va->volume)
1630 va->balance = (32768*min(chip->left,chip->right))/
1631 va->volume;
1632 else
1633 va->balance = 32768;
1634 }
1635 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1636 va->flags |= VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
1637 va->bass = chip->bass;
1638 va->treble = chip->treble;
1639 }
1640 if (chip->norm != VIDEO_MODE_RADIO) {
1641 if (desc->getmode)
1642 va->mode = desc->getmode(chip);
1643 else
1644 va->mode = VIDEO_SOUND_MONO;
1645 }
1646 break;
1647 }
1648
1649 case VIDIOCSAUDIO:
1650 {
1651 struct video_audio *va = arg;
1652
1653 if (desc->flags & CHIP_HAS_VOLUME) {
1654 chip->left = (min(65536 - va->balance,32768) *
1655 va->volume) / 32768;
1656 chip->right = (min(va->balance,(__u16)32768) *
1657 va->volume) / 32768;
1658 chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
1659 chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
1660 }
1661 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1662 chip->bass = va->bass;
1663 chip->treble = va->treble;
1664 chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1665 chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1666 }
1667 if (desc->setmode && va->mode) {
1668 chip->watch_stereo = 0;
1669 /* del_timer(&chip->wt); */
1670 chip->mode = va->mode;
1671 desc->setmode(chip,va->mode);
1672 }
1673 break;
1674 }
1675 case VIDIOCSCHAN:
1676 {
1677 struct video_channel *vc = arg;
1678
1679 dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n");
1680 chip->norm = vc->norm;
1681 break;
1682 }
1683 case VIDIOCSFREQ:
1684 {
1685 chip->mode = 0; /* automatic */
1686 if (desc->checkmode) {
1687 desc->setmode(chip,VIDEO_SOUND_MONO);
1688 if (chip->prevmode != VIDEO_SOUND_MONO)
1689 chip->prevmode = -1; /* reset previous mode */
1690 mod_timer(&chip->wt, jiffies+2*HZ);
1691 /* the thread will call checkmode() later */
1692 }
1693 }
1694 }
1695 return 0;
1696}
1697
1698
1699static struct i2c_driver driver = {
1700 .owner = THIS_MODULE,
1701 .name = "generic i2c audio driver",
1702 .id = I2C_DRIVERID_TVAUDIO,
1703 .flags = I2C_DF_NOTIFY,
1704 .attach_adapter = chip_probe,
1705 .detach_client = chip_detach,
1706 .command = chip_command,
1707};
1708
1709static struct i2c_client client_template =
1710{
1711 I2C_DEVNAME("(unset)"),
1712 .flags = I2C_CLIENT_ALLOW_USE,
1713 .driver = &driver,
1714};
1715
1716static int __init audiochip_init_module(void)
1717{
1718 struct CHIPDESC *desc;
1719 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
1720 printk(KERN_INFO "tvaudio: known chips: ");
1721 for (desc = chiplist; desc->name != NULL; desc++)
1722 printk("%s%s", (desc == chiplist) ? "" : ",",desc->name);
1723 printk("\n");
1724
1725 return i2c_add_driver(&driver);
1726}
1727
1728static void __exit audiochip_cleanup_module(void)
1729{
1730 i2c_del_driver(&driver);
1731}
1732
1733module_init(audiochip_init_module);
1734module_exit(audiochip_cleanup_module);
1735
1736/*
1737 * Local variables:
1738 * c-basic-offset: 8
1739 * End:
1740 */
diff --git a/drivers/media/video/tvaudio.h b/drivers/media/video/tvaudio.h
new file mode 100644
index 000000000000..af7e116af9a9
--- /dev/null
+++ b/drivers/media/video/tvaudio.h
@@ -0,0 +1,14 @@
1/*
2 * i2c bus addresses for the chips supported by tvaudio.c
3 */
4
5#define I2C_TDA8425 0x82
6#define I2C_TDA9840 0x84 /* also used by TA8874Z */
7#define I2C_TDA985x_L 0xb4 /* also used by 9873 */
8#define I2C_TDA985x_H 0xb6
9#define I2C_TDA9874 0xb0 /* also used by 9875 */
10
11#define I2C_TEA6300 0x80 /* also used by 6320 */
12#define I2C_TEA6420 0x98
13
14#define I2C_PIC16C54 0x96 /* PV951 */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
new file mode 100644
index 000000000000..e1443a0937e3
--- /dev/null
+++ b/drivers/media/video/tveeprom.c
@@ -0,0 +1,587 @@
1/*
2 * tveeprom - eeprom decoder for tvcard configuration eeproms
3 *
4 * Data and decoding routines shamelessly borrowed from bttv-cards.c
5 * eeprom access routine shamelessly borrowed from bttv-if.c
6 * which are:
7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11
12 * Adjustments to fit a more general model and all bugs:
13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/errno.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/types.h>
38#include <linux/videodev.h>
39#include <linux/i2c.h>
40
41#include <media/tuner.h>
42#include <media/tveeprom.h>
43
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar");
46MODULE_LICENSE("GPL");
47
48static int debug = 0;
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-2)");
51
52#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
53
54#define dprintk(num, args...) \
55 do { \
56 if (debug >= num) \
57 printk(KERN_INFO "tveeprom: " args); \
58 } while (0)
59
60#define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
61#define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
62
63/* ----------------------------------------------------------------------- */
64/* some hauppauge specific stuff */
65
66static struct HAUPPAUGE_TUNER_FMT
67{
68 int id;
69 char *name;
70}
71hauppauge_tuner_fmt[] =
72{
73 { 0x00000000, "unknown1" },
74 { 0x00000000, "unknown2" },
75 { 0x00000007, "PAL(B/G)" },
76 { 0x00001000, "NTSC(M)" },
77 { 0x00000010, "PAL(I)" },
78 { 0x00400000, "SECAM(L/L�)" },
79 { 0x00000e00, "PAL(D/K)" },
80 { 0x03000000, "ATSC Digital" },
81};
82
83/* This is the full list of possible tuners. Many thanks to Hauppauge for
84 supplying this information. Note that many tuners where only used for
85 testing and never made it to the outside world. So you will only see
86 a subset in actual produced cards. */
87static struct HAUPPAUGE_TUNER
88{
89 int id;
90 char *name;
91}
92hauppauge_tuner[] =
93{
94 /* 0-9 */
95 { TUNER_ABSENT, "None" },
96 { TUNER_ABSENT, "External" },
97 { TUNER_ABSENT, "Unspecified" },
98 { TUNER_PHILIPS_PAL, "Philips FI1216" },
99 { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
100 { TUNER_PHILIPS_NTSC, "Philips FI1236" },
101 { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
102 { TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
103 { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" },
104 { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
105 /* 10-19 */
106 { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" },
107 { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
108 { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
109 { TUNER_TEMIC_NTSC, "Temic 4032FY5" },
110 { TUNER_TEMIC_PAL, "Temic 4002FH5" },
111 { TUNER_TEMIC_PAL_I, "Temic 4062FY5" },
112 { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" },
113 { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
114 { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" },
115 { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
116 /* 20-29 */
117 { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
118 { TUNER_PHILIPS_PAL, "Philips FM1216" },
119 { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
120 { TUNER_PHILIPS_NTSC, "Philips FM1236" },
121 { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
122 { TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
123 { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
124 { TUNER_ABSENT, "Samsung TCPN9082D" },
125 { TUNER_ABSENT, "Samsung TCPM9092P" },
126 { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
127 /* 30-39 */
128 { TUNER_ABSENT, "Samsung TCPN9085D" },
129 { TUNER_ABSENT, "Samsung TCPB9085P" },
130 { TUNER_ABSENT, "Samsung TCPL9091P" },
131 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
132 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
133 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
134 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
135 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
136 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
137 { TUNER_ABSENT, "Philips FI1256MP" },
138 /* 40-49 */
139 { TUNER_ABSENT, "Samsung TCPQ9091P" },
140 { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
141 { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
142 { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
143 { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
144 { TUNER_ABSENT, "Philips TD1536D FH 44"},
145 { TUNER_LG_NTSC_FM, "LG TP18NSR01F"},
146 { TUNER_LG_PAL_FM, "LG TP18PSB01D"},
147 { TUNER_LG_PAL, "LG TP18PSB11D"},
148 { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"},
149 /* 50-59 */
150 { TUNER_LG_PAL_I, "LG TAPC-I701D"},
151 { TUNER_ABSENT, "Temic 4042FI5"},
152 { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
153 { TUNER_ABSENT, "LG TPI8NSR11F"},
154 { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
155 { TUNER_ABSENT, "Philips FQ1216ME MK3"},
156 { TUNER_ABSENT, "Philips FI1236 MK3"},
157 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
158 { TUNER_ABSENT, "Philips FM1236 MK3"},
159 { TUNER_ABSENT, "Philips FM1216MP MK3"},
160 /* 60-69 */
161 { TUNER_ABSENT, "LG S001D MK3"},
162 { TUNER_ABSENT, "LG M001D MK3"},
163 { TUNER_ABSENT, "LG S701D MK3"},
164 { TUNER_ABSENT, "LG M701D MK3"},
165 { TUNER_ABSENT, "Temic 4146FM5"},
166 { TUNER_ABSENT, "Temic 4136FY5"},
167 { TUNER_ABSENT, "Temic 4106FH5"},
168 { TUNER_ABSENT, "Philips FQ1216LMP MK3"},
169 { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
170 { TUNER_ABSENT, "LG TAPE H701F MK3"},
171 /* 70-79 */
172 { TUNER_ABSENT, "LG TALN H200T"},
173 { TUNER_ABSENT, "LG TALN H250T"},
174 { TUNER_ABSENT, "LG TALN M200T"},
175 { TUNER_ABSENT, "LG TALN Z200T"},
176 { TUNER_ABSENT, "LG TALN S200T"},
177 { TUNER_ABSENT, "Thompson DTT7595"},
178 { TUNER_ABSENT, "Thompson DTT7592"},
179 { TUNER_ABSENT, "Silicon TDA8275C1 8290"},
180 { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"},
181 { TUNER_ABSENT, "Thompson DTT757"},
182 /* 80-89 */
183 { TUNER_ABSENT, "Philips FQ1216LME MK3"},
184 { TUNER_ABSENT, "LG TAPC G701D"},
185 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
186 { TUNER_ABSENT, "TCL 2002MB 3"},
187 { TUNER_ABSENT, "TCL 2002MI 3"},
188 { TUNER_TCL_2002N, "TCL 2002N 6A"},
189 { TUNER_ABSENT, "Philips FQ1236 MK3"},
190 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
191 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
192 { TUNER_ABSENT, "TCL MFPE05 2"},
193 /* 90-99 */
194 { TUNER_ABSENT, "LG TALN H202T"},
195 { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
196 { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"},
197 { TUNER_ABSENT, "Philips FQ1286A MK4"},
198 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
199 { TUNER_ABSENT, "Philips FQ1236 MK5"},
200 { TUNER_ABSENT, "Unspecified"},
201 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"},
202};
203
204static char *sndtype[] = {
205 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D",
206 "MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440",
207 "MSP3445", "MSP3411", "MSP3416", "MSP3425",
208
209 "Type 0x10","Type 0x11","Type 0x12","Type 0x13",
210 "Type 0x14","Type 0x15","Type 0x16","Type 0x17",
211 "Type 0x18","MSP4418","Type 0x1a","MSP4448",
212 "Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f",
213};
214
215static int hasRadioTuner(int tunerType)
216{
217 switch (tunerType) {
218 case 18: //PNPEnv_TUNER_FR1236_MK2:
219 case 23: //PNPEnv_TUNER_FM1236:
220 case 38: //PNPEnv_TUNER_FMR1236:
221 case 16: //PNPEnv_TUNER_FR1216_MK2:
222 case 19: //PNPEnv_TUNER_FR1246_MK2:
223 case 21: //PNPEnv_TUNER_FM1216:
224 case 24: //PNPEnv_TUNER_FM1246:
225 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
226 case 22: //PNPEnv_TUNER_FM1216MF:
227 case 20: //PNPEnv_TUNER_FR1256_MK2:
228 case 25: //PNPEnv_TUNER_FM1256:
229 case 33: //PNPEnv_TUNER_4039FR5:
230 case 42: //PNPEnv_TUNER_4009FR5:
231 case 52: //PNPEnv_TUNER_4049FM5:
232 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
233 case 44: //PNPEnv_TUNER_4009FN5:
234 case 31: //PNPEnv_TUNER_TCPB9085P:
235 case 30: //PNPEnv_TUNER_TCPN9085D:
236 case 46: //PNPEnv_TUNER_TP18NSR01F:
237 case 47: //PNPEnv_TUNER_TP18PSB01D:
238 case 49: //PNPEnv_TUNER_TAPC_I001D:
239 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
240 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
241 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
242 case 58: //PNPEnv_TUNER_FM1236_MK3:
243 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
244 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
245 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
246 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
247 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
248 return 1;
249 }
250 return 0;
251}
252
253void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data)
254{
255 /* ----------------------------------------------
256 ** The hauppauge eeprom format is tagged
257 **
258 ** if packet[0] == 0x84, then packet[0..1] == length
259 ** else length = packet[0] & 3f;
260 ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
261 **
262 ** In our (ivtv) case we're interested in the following:
263 ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
264 ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
265 ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
266 ** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?)
267
268 ** Fun info:
269 ** model: tag [00].07-08 or [06].00-01
270 ** revision: tag [00].09-0b or [06].04-06
271 ** serial#: tag [01].05-07 or [04].04-06
272
273 ** # of inputs/outputs ???
274 */
275
276 int i, j, len, done, beenhere, tag, tuner = 0, t_format = 0;
277 char *t_name = NULL, *t_fmt_name = NULL;
278
279 dprintk(1, "%s\n",__FUNCTION__);
280 tvee->revision = done = len = beenhere = 0;
281 for (i = 0; !done && i < 256; i += len) {
282 dprintk(2, "processing pos = %02x (%02x, %02x)\n",
283 i, eeprom_data[i], eeprom_data[i + 1]);
284
285 if (eeprom_data[i] == 0x84) {
286 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
287 i+=3;
288 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
289 if ((eeprom_data[i] & 0x08)) {
290 /* verify checksum! */
291 done = 1;
292 break;
293 }
294 len = eeprom_data[i] & 0x07;
295 ++i;
296 } else {
297 TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "
298 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
299 return;
300 }
301
302 dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);
303 for(j = 1; j < len; j++) {
304 dprintk(1, "%02x ", eeprom_data[i + j]);
305 }
306 dprintk(1, "\n");
307
308 /* process by tag */
309 tag = eeprom_data[i];
310 switch (tag) {
311 case 0x00:
312 tuner = eeprom_data[i+6];
313 t_format = eeprom_data[i+5];
314 tvee->has_radio = eeprom_data[i+len-1];
315 tvee->model =
316 eeprom_data[i+8] +
317 (eeprom_data[i+9] << 8);
318 tvee->revision = eeprom_data[i+10] +
319 (eeprom_data[i+11] << 8) +
320 (eeprom_data[i+12] << 16);
321 break;
322 case 0x01:
323 tvee->serial_number =
324 eeprom_data[i+6] +
325 (eeprom_data[i+7] << 8) +
326 (eeprom_data[i+8] << 16);
327 break;
328 case 0x02:
329 tvee->audio_processor = eeprom_data[i+2] & 0x0f;
330 break;
331 case 0x04:
332 tvee->serial_number =
333 eeprom_data[i+5] +
334 (eeprom_data[i+6] << 8) +
335 (eeprom_data[i+7] << 16);
336 break;
337 case 0x05:
338 tvee->audio_processor = eeprom_data[i+1] & 0x0f;
339 break;
340 case 0x06:
341 tvee->model =
342 eeprom_data[i+1] +
343 (eeprom_data[i+2] << 8);
344 tvee->revision = eeprom_data[i+5] +
345 (eeprom_data[i+6] << 8) +
346 (eeprom_data[i+7] << 16);
347 break;
348 case 0x0a:
349 if(beenhere == 0) {
350 tuner = eeprom_data[i+2];
351 t_format = eeprom_data[i+1];
352 beenhere = 1;
353 break;
354 } else {
355 break;
356 }
357 case 0x0e:
358 tvee->has_radio = eeprom_data[i+1];
359 break;
360 default:
361 dprintk(1, "Not sure what to do with tag [%02x]\n", tag);
362 /* dump the rest of the packet? */
363 }
364
365 }
366
367 if (!done) {
368 TVEEPROM_KERN_ERR("Ran out of data!\n");
369 return;
370 }
371
372 if (tvee->revision != 0) {
373 tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
374 tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
375 tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f);
376 tvee->rev_str[3] = 32 + ( tvee->revision & 0x3f);
377 tvee->rev_str[4] = 0;
378 }
379
380 if (hasRadioTuner(tuner) && !tvee->has_radio) {
381 TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");
382 TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");
383 tvee->has_radio = 1;
384 }
385
386 if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
387 tvee->tuner_type = hauppauge_tuner[tuner].id;
388 t_name = hauppauge_tuner[tuner].name;
389 } else {
390 t_name = "<unknown>";
391 }
392
393 tvee->tuner_formats = 0;
394 t_fmt_name = "<none>";
395 for (i = 0; i < 8; i++) {
396 if (t_format & (1<<i)) {
397 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
398 /* yuck */
399 t_fmt_name = hauppauge_tuner_fmt[i].name;
400 }
401 }
402
403#if 0
404 if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {
405 tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;
406 t_fmt_name = hauppauge_tuner_fmt[t_format].name;
407 } else {
408 t_fmt_name = "<unknown>";
409 }
410#endif
411
412 TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
413 tvee->model,
414 tvee->rev_str,
415 tvee->serial_number);
416 TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",
417 t_name,
418 tuner,
419 tvee->tuner_type);
420 TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",
421 t_fmt_name,
422 t_format,
423 tvee->tuner_formats);
424
425 TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",
426 STRM(sndtype,tvee->audio_processor),
427 tvee->audio_processor);
428
429}
430EXPORT_SYMBOL(tveeprom_hauppauge_analog);
431
432/* ----------------------------------------------------------------------- */
433/* generic helper functions */
434
435int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
436{
437 unsigned char buf;
438 int err;
439
440 dprintk(1, "%s\n",__FUNCTION__);
441 buf = 0;
442 if (1 != (err = i2c_master_send(c,&buf,1))) {
443 printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",
444 c->name,err);
445 return -1;
446 }
447 if (len != (err = i2c_master_recv(c,eedata,len))) {
448 printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",
449 c->name,err);
450 return -1;
451 }
452 return 0;
453}
454EXPORT_SYMBOL(tveeprom_read);
455
456int tveeprom_dump(unsigned char *eedata, int len)
457{
458 int i;
459
460 dprintk(1, "%s\n",__FUNCTION__);
461 for (i = 0; i < len; i++) {
462 if (0 == (i % 16))
463 printk(KERN_INFO "tveeprom: %02x:",i);
464 printk(" %02x",eedata[i]);
465 if (15 == (i % 16))
466 printk("\n");
467 }
468 return 0;
469}
470EXPORT_SYMBOL(tveeprom_dump);
471
472/* ----------------------------------------------------------------------- */
473/* needed for ivtv.sf.net at the moment. Should go away in the long */
474/* run, just call the exported tveeprom_* directly, there is no point in */
475/* using the indirect way via i2c_driver->command() */
476
477#ifndef I2C_DRIVERID_TVEEPROM
478# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
479#endif
480
481static unsigned short normal_i2c[] = {
482 0xa0 >> 1,
483 I2C_CLIENT_END,
484};
485static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
486I2C_CLIENT_INSMOD;
487
488struct i2c_driver i2c_driver_tveeprom;
489
490static int
491tveeprom_command(struct i2c_client *client,
492 unsigned int cmd,
493 void *arg)
494{
495 struct tveeprom eeprom;
496 u32 *eeprom_props = arg;
497 u8 *buf;
498
499 switch (cmd) {
500 case 0:
501 buf = kmalloc(256,GFP_KERNEL);
502 memset(buf,0,256);
503 tveeprom_read(client,buf,256);
504 tveeprom_hauppauge_analog(&eeprom,buf);
505 kfree(buf);
506 eeprom_props[0] = eeprom.tuner_type;
507 eeprom_props[1] = eeprom.tuner_formats;
508 eeprom_props[2] = eeprom.model;
509 eeprom_props[3] = eeprom.revision;
510 break;
511 default:
512 return -EINVAL;
513 }
514 return 0;
515}
516
517static int
518tveeprom_detect_client(struct i2c_adapter *adapter,
519 int address,
520 int kind)
521{
522 struct i2c_client *client;
523
524 dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
525 adapter->id, address << 1);
526 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
527 if (NULL == client)
528 return -ENOMEM;
529 memset(client, 0, sizeof(struct i2c_client));
530 client->addr = address;
531 client->adapter = adapter;
532 client->driver = &i2c_driver_tveeprom;
533 client->flags = I2C_CLIENT_ALLOW_USE;
534 snprintf(client->name, sizeof(client->name), "tveeprom");
535 i2c_attach_client(client);
536 return 0;
537}
538
539static int
540tveeprom_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
543 if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
544 return 0;
545 return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
546}
547
548static int
549tveeprom_detach_client (struct i2c_client *client)
550{
551 int err;
552
553 err = i2c_detach_client(client);
554 if (err < 0)
555 return err;
556 kfree(client);
557 return 0;
558}
559
560struct i2c_driver i2c_driver_tveeprom = {
561 .owner = THIS_MODULE,
562 .name = "tveeprom",
563 .id = I2C_DRIVERID_TVEEPROM,
564 .flags = I2C_DF_NOTIFY,
565 .attach_adapter = tveeprom_attach_adapter,
566 .detach_client = tveeprom_detach_client,
567 .command = tveeprom_command,
568};
569
570static int __init tveeprom_init(void)
571{
572 return i2c_add_driver(&i2c_driver_tveeprom);
573}
574
575static void __exit tveeprom_exit(void)
576{
577 i2c_del_driver(&i2c_driver_tveeprom);
578}
579
580module_init(tveeprom_init);
581module_exit(tveeprom_exit);
582
583/*
584 * Local variables:
585 * c-basic-offset: 8
586 * End:
587 */
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
new file mode 100644
index 000000000000..eafd7061b310
--- /dev/null
+++ b/drivers/media/video/tvmixer.c
@@ -0,0 +1,367 @@
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/sched.h>
5#include <linux/string.h>
6#include <linux/timer.h>
7#include <linux/delay.h>
8#include <linux/errno.h>
9#include <linux/slab.h>
10#include <linux/i2c.h>
11#include <linux/videodev.h>
12#include <linux/init.h>
13#include <linux/kdev_t.h>
14#include <linux/sound.h>
15#include <linux/soundcard.h>
16
17#include <asm/semaphore.h>
18#include <asm/uaccess.h>
19
20
21#define DEV_MAX 4
22
23static int devnr = -1;
24module_param(devnr, int, 0644);
25
26MODULE_AUTHOR("Gerd Knorr");
27MODULE_LICENSE("GPL");
28
29/* ----------------------------------------------------------------------- */
30
31struct TVMIXER {
32 struct i2c_client *dev;
33 int minor;
34 int count;
35};
36
37static struct TVMIXER devices[DEV_MAX];
38
39static int tvmixer_adapters(struct i2c_adapter *adap);
40static int tvmixer_clients(struct i2c_client *client);
41
42/* ----------------------------------------------------------------------- */
43
44static int mix_to_v4l(int i)
45{
46 int r;
47
48 r = ((i & 0xff) * 65536 + 50) / 100;
49 if (r > 65535) r = 65535;
50 if (r < 0) r = 0;
51 return r;
52}
53
54static int v4l_to_mix(int i)
55{
56 int r;
57
58 r = (i * 100 + 32768) / 65536;
59 if (r > 100) r = 100;
60 if (r < 0) r = 0;
61 return r | (r << 8);
62}
63
64static int v4l_to_mix2(int l, int r)
65{
66 r = (r * 100 + 32768) / 65536;
67 if (r > 100) r = 100;
68 if (r < 0) r = 0;
69 l = (l * 100 + 32768) / 65536;
70 if (l > 100) l = 100;
71 if (l < 0) l = 0;
72 return (r << 8) | l;
73}
74
75static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
76{
77 struct video_audio va;
78 int left,right,ret,val = 0;
79 struct TVMIXER *mix = file->private_data;
80 struct i2c_client *client = mix->dev;
81 void __user *argp = (void __user *)arg;
82 int __user *p = argp;
83
84 if (NULL == client)
85 return -ENODEV;
86
87 if (cmd == SOUND_MIXER_INFO) {
88 mixer_info info;
89 strlcpy(info.id, "tv card", sizeof(info.id));
90 strlcpy(info.name, i2c_clientname(client), sizeof(info.name));
91 info.modify_counter = 42 /* FIXME */;
92 if (copy_to_user(argp, &info, sizeof(info)))
93 return -EFAULT;
94 return 0;
95 }
96 if (cmd == SOUND_OLD_MIXER_INFO) {
97 _old_mixer_info info;
98 strlcpy(info.id, "tv card", sizeof(info.id));
99 strlcpy(info.name, i2c_clientname(client), sizeof(info.name));
100 if (copy_to_user(argp, &info, sizeof(info)))
101 return -EFAULT;
102 return 0;
103 }
104 if (cmd == OSS_GETVERSION)
105 return put_user(SOUND_VERSION, p);
106
107 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
108 if (get_user(val, p))
109 return -EFAULT;
110
111 /* read state */
112 memset(&va,0,sizeof(va));
113 client->driver->command(client,VIDIOCGAUDIO,&va);
114
115 switch (cmd) {
116 case MIXER_READ(SOUND_MIXER_RECMASK):
117 case MIXER_READ(SOUND_MIXER_CAPS):
118 case MIXER_READ(SOUND_MIXER_RECSRC):
119 case MIXER_WRITE(SOUND_MIXER_RECSRC):
120 ret = 0;
121 break;
122
123 case MIXER_READ(SOUND_MIXER_STEREODEVS):
124 ret = SOUND_MASK_VOLUME;
125 break;
126 case MIXER_READ(SOUND_MIXER_DEVMASK):
127 ret = SOUND_MASK_VOLUME;
128 if (va.flags & VIDEO_AUDIO_BASS)
129 ret |= SOUND_MASK_BASS;
130 if (va.flags & VIDEO_AUDIO_TREBLE)
131 ret |= SOUND_MASK_TREBLE;
132 break;
133
134 case MIXER_WRITE(SOUND_MIXER_VOLUME):
135 left = mix_to_v4l(val);
136 right = mix_to_v4l(val >> 8);
137 va.volume = max(left,right);
138 va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
139 va.balance = (left<right) ? (65535-va.balance) : va.balance;
140 if (va.volume)
141 va.flags &= ~VIDEO_AUDIO_MUTE;
142 client->driver->command(client,VIDIOCSAUDIO,&va);
143 client->driver->command(client,VIDIOCGAUDIO,&va);
144 /* fall throuth */
145 case MIXER_READ(SOUND_MIXER_VOLUME):
146 left = (min(65536 - va.balance,32768) *
147 va.volume) / 32768;
148 right = (min(va.balance,(u16)32768) *
149 va.volume) / 32768;
150 ret = v4l_to_mix2(left,right);
151 break;
152
153 case MIXER_WRITE(SOUND_MIXER_BASS):
154 va.bass = mix_to_v4l(val);
155 client->driver->command(client,VIDIOCSAUDIO,&va);
156 client->driver->command(client,VIDIOCGAUDIO,&va);
157 /* fall throuth */
158 case MIXER_READ(SOUND_MIXER_BASS):
159 ret = v4l_to_mix(va.bass);
160 break;
161
162 case MIXER_WRITE(SOUND_MIXER_TREBLE):
163 va.treble = mix_to_v4l(val);
164 client->driver->command(client,VIDIOCSAUDIO,&va);
165 client->driver->command(client,VIDIOCGAUDIO,&va);
166 /* fall throuth */
167 case MIXER_READ(SOUND_MIXER_TREBLE):
168 ret = v4l_to_mix(va.treble);
169 break;
170
171 default:
172 return -EINVAL;
173 }
174 if (put_user(ret, p))
175 return -EFAULT;
176 return 0;
177}
178
179static int tvmixer_open(struct inode *inode, struct file *file)
180{
181 int i, minor = iminor(inode);
182 struct TVMIXER *mix = NULL;
183 struct i2c_client *client = NULL;
184
185 for (i = 0; i < DEV_MAX; i++) {
186 if (devices[i].minor == minor) {
187 mix = devices+i;
188 client = mix->dev;
189 break;
190 }
191 }
192
193 if (NULL == client)
194 return -ENODEV;
195
196 /* lock bttv in memory while the mixer is in use */
197 file->private_data = mix;
198#ifndef I2C_PEC
199 if (client->adapter->inc_use)
200 client->adapter->inc_use(client->adapter);
201#endif
202 if (client->adapter->owner)
203 try_module_get(client->adapter->owner);
204 return 0;
205}
206
207static int tvmixer_release(struct inode *inode, struct file *file)
208{
209 struct TVMIXER *mix = file->private_data;
210 struct i2c_client *client;
211
212 client = mix->dev;
213 if (NULL == client) {
214 return -ENODEV;
215 }
216
217#ifndef I2C_PEC
218 if (client->adapter->dec_use)
219 client->adapter->dec_use(client->adapter);
220#endif
221 if (client->adapter->owner)
222 module_put(client->adapter->owner);
223 return 0;
224}
225
226static struct i2c_driver driver = {
227#ifdef I2C_PEC
228 .owner = THIS_MODULE,
229#endif
230 .name = "tv card mixer driver",
231 .id = I2C_DRIVERID_TVMIXER,
232#ifdef I2C_DF_DUMMY
233 .flags = I2C_DF_DUMMY,
234#else
235 .flags = I2C_DF_NOTIFY,
236 .detach_adapter = tvmixer_adapters,
237#endif
238 .attach_adapter = tvmixer_adapters,
239 .detach_client = tvmixer_clients,
240};
241
242static struct file_operations tvmixer_fops = {
243 .owner = THIS_MODULE,
244 .llseek = no_llseek,
245 .ioctl = tvmixer_ioctl,
246 .open = tvmixer_open,
247 .release = tvmixer_release,
248};
249
250/* ----------------------------------------------------------------------- */
251
252static int tvmixer_adapters(struct i2c_adapter *adap)
253{
254 struct list_head *item;
255 struct i2c_client *client;
256
257 list_for_each(item,&adap->clients) {
258 client = list_entry(item, struct i2c_client, list);
259 tvmixer_clients(client);
260 }
261 return 0;
262}
263
264static int tvmixer_clients(struct i2c_client *client)
265{
266 struct video_audio va;
267 int i,minor;
268
269#ifdef I2C_CLASS_TV_ANALOG
270 if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
271 return -1;
272#else
273 /* TV card ??? */
274 switch (client->adapter->id) {
275 case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
276 case I2C_ALGO_BIT | I2C_HW_B_BT848:
277 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
278 /* ok, have a look ... */
279 break;
280 default:
281 /* ignore that one */
282 return -1;
283 }
284#endif
285
286 /* unregister ?? */
287 for (i = 0; i < DEV_MAX; i++) {
288 if (devices[i].dev == client) {
289 /* unregister */
290 unregister_sound_mixer(devices[i].minor);
291 devices[i].dev = NULL;
292 devices[i].minor = -1;
293 printk("tvmixer: %s unregistered (#1)\n",
294 i2c_clientname(client));
295 return 0;
296 }
297 }
298
299 /* look for a free slot */
300 for (i = 0; i < DEV_MAX; i++)
301 if (NULL == devices[i].dev)
302 break;
303 if (i == DEV_MAX) {
304 printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
305 return -1;
306 }
307
308 /* audio chip with mixer ??? */
309 if (NULL == client->driver->command)
310 return -1;
311 memset(&va,0,sizeof(va));
312 if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
313 return -1;
314 if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
315 return -1;
316
317 /* everything is fine, register */
318 if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
319 printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
320 return -1;
321 }
322
323 devices[i].minor = minor;
324 devices[i].count = 0;
325 devices[i].dev = client;
326 printk("tvmixer: %s (%s) registered with minor %d\n",
327 client->name,client->adapter->name,minor);
328
329 return 0;
330}
331
332/* ----------------------------------------------------------------------- */
333
334static int __init tvmixer_init_module(void)
335{
336 int i;
337
338 for (i = 0; i < DEV_MAX; i++)
339 devices[i].minor = -1;
340
341 return i2c_add_driver(&driver);
342}
343
344static void __exit tvmixer_cleanup_module(void)
345{
346 int i;
347
348 i2c_del_driver(&driver);
349 for (i = 0; i < DEV_MAX; i++) {
350 if (devices[i].minor != -1) {
351 unregister_sound_mixer(devices[i].minor);
352 printk("tvmixer: %s unregistered (#2)\n",
353 i2c_clientname(devices[i].dev));
354 }
355 }
356}
357
358module_init(tvmixer_init_module);
359module_exit(tvmixer_cleanup_module);
360
361/*
362 * Overrides for Emacs so that we follow Linus's tabbing style.
363 * ---------------------------------------------------------------------------
364 * Local variables:
365 * c-basic-offset: 8
366 * End:
367 */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
new file mode 100644
index 000000000000..b0d4bcb027d0
--- /dev/null
+++ b/drivers/media/video/v4l1-compat.c
@@ -0,0 +1,1036 @@
1/*
2 * Video for Linux Two
3 * Backward Compatibility Layer
4 *
5 * Support subroutines for providing V4L2 drivers with backward
6 * compatibility with applications using the old API.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 * Author: Bill Dirks <bdirks@pacbell.net>
14 * et al.
15 *
16 */
17
18#ifndef __KERNEL__
19#define __KERNEL__
20#endif
21
22#include <linux/config.h>
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/types.h>
27#include <linux/kernel.h>
28#include <linux/sched.h>
29#include <linux/smp_lock.h>
30#include <linux/mm.h>
31#include <linux/fs.h>
32#include <linux/file.h>
33#include <linux/string.h>
34#include <linux/errno.h>
35#include <linux/slab.h>
36#include <linux/videodev.h>
37
38#include <asm/uaccess.h>
39#include <asm/system.h>
40#include <asm/pgtable.h>
41
42#ifdef CONFIG_KMOD
43#include <linux/kmod.h>
44#endif
45
46static unsigned int debug = 0;
47module_param(debug, int, 0644);
48MODULE_PARM_DESC(debug,"enable debug messages");
49MODULE_AUTHOR("Bill Dirks");
50MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
51MODULE_LICENSE("GPL");
52
53#define dprintk(fmt, arg...) if (debug) \
54 printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
55
56/*
57 * I O C T L T R A N S L A T I O N
58 *
59 * From here on down is the code for translating the numerous
60 * ioctl commands from the old API to the new API.
61 */
62
63static int
64get_v4l_control(struct inode *inode,
65 struct file *file,
66 int cid,
67 v4l2_kioctl drv)
68{
69 struct v4l2_queryctrl qctrl2;
70 struct v4l2_control ctrl2;
71 int err;
72
73 qctrl2.id = cid;
74 err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
75 if (err < 0)
76 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
77 if (err == 0 &&
78 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
79 {
80 ctrl2.id = qctrl2.id;
81 err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
82 if (err < 0) {
83 dprintk("VIDIOC_G_CTRL: %d\n",err);
84 return 0;
85 }
86 return ((ctrl2.value - qctrl2.minimum) * 65535
87 + (qctrl2.maximum - qctrl2.minimum) / 2)
88 / (qctrl2.maximum - qctrl2.minimum);
89 }
90 return 0;
91}
92
93static int
94set_v4l_control(struct inode *inode,
95 struct file *file,
96 int cid,
97 int value,
98 v4l2_kioctl drv)
99{
100 struct v4l2_queryctrl qctrl2;
101 struct v4l2_control ctrl2;
102 int err;
103
104 qctrl2.id = cid;
105 err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
106 if (err < 0)
107 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
108 if (err == 0 &&
109 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
110 !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
111 {
112 if (value < 0)
113 value = 0;
114 if (value > 65535)
115 value = 65535;
116 if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
117 value = 65535;
118 ctrl2.id = qctrl2.id;
119 ctrl2.value =
120 (value * (qctrl2.maximum - qctrl2.minimum)
121 + 32767)
122 / 65535;
123 ctrl2.value += qctrl2.minimum;
124 err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
125 if (err < 0)
126 dprintk("VIDIOC_S_CTRL: %d\n",err);
127 }
128 return 0;
129}
130
131/* ----------------------------------------------------------------- */
132
133static int palette2pixelformat[] = {
134 [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
135 [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
136 [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
137 [VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24,
138 [VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32,
139 /* yuv packed pixel */
140 [VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV,
141 [VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV,
142 [VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY,
143 /* yuv planar */
144 [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
145 [VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420,
146 [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
147 [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
148 [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
149};
150
151static unsigned int
152palette_to_pixelformat(unsigned int palette)
153{
154 if (palette < ARRAY_SIZE(palette2pixelformat))
155 return palette2pixelformat[palette];
156 else
157 return 0;
158}
159
160static unsigned int
161pixelformat_to_palette(int pixelformat)
162{
163 int palette = 0;
164 switch (pixelformat)
165 {
166 case V4L2_PIX_FMT_GREY:
167 palette = VIDEO_PALETTE_GREY;
168 break;
169 case V4L2_PIX_FMT_RGB555:
170 palette = VIDEO_PALETTE_RGB555;
171 break;
172 case V4L2_PIX_FMT_RGB565:
173 palette = VIDEO_PALETTE_RGB565;
174 break;
175 case V4L2_PIX_FMT_BGR24:
176 palette = VIDEO_PALETTE_RGB24;
177 break;
178 case V4L2_PIX_FMT_BGR32:
179 palette = VIDEO_PALETTE_RGB32;
180 break;
181 /* yuv packed pixel */
182 case V4L2_PIX_FMT_YUYV:
183 palette = VIDEO_PALETTE_YUYV;
184 break;
185 case V4L2_PIX_FMT_UYVY:
186 palette = VIDEO_PALETTE_UYVY;
187 break;
188 /* yuv planar */
189 case V4L2_PIX_FMT_YUV410:
190 palette = VIDEO_PALETTE_YUV420;
191 break;
192 case V4L2_PIX_FMT_YUV420:
193 palette = VIDEO_PALETTE_YUV420;
194 break;
195 case V4L2_PIX_FMT_YUV411P:
196 palette = VIDEO_PALETTE_YUV411P;
197 break;
198 case V4L2_PIX_FMT_YUV422P:
199 palette = VIDEO_PALETTE_YUV422P;
200 break;
201 }
202 return palette;
203}
204
205/* ----------------------------------------------------------------- */
206
207static int poll_one(struct file *file)
208{
209 int retval = 1;
210 poll_table *table;
211 struct poll_wqueues pwq;
212
213 poll_initwait(&pwq);
214 table = &pwq.pt;
215 for (;;) {
216 int mask;
217 set_current_state(TASK_INTERRUPTIBLE);
218 mask = file->f_op->poll(file, table);
219 if (mask & POLLIN)
220 break;
221 table = NULL;
222 if (signal_pending(current)) {
223 retval = -ERESTARTSYS;
224 break;
225 }
226 schedule();
227 }
228 set_current_state(TASK_RUNNING);
229 poll_freewait(&pwq);
230 return retval;
231}
232
233static int count_inputs(struct inode *inode,
234 struct file *file,
235 v4l2_kioctl drv)
236{
237 struct v4l2_input input2;
238 int i;
239
240 for (i = 0;; i++) {
241 memset(&input2,0,sizeof(input2));
242 input2.index = i;
243 if (0 != drv(inode,file,VIDIOC_ENUMINPUT, &input2))
244 break;
245 }
246 return i;
247}
248
249static int check_size(struct inode *inode,
250 struct file *file,
251 v4l2_kioctl drv,
252 int *maxw, int *maxh)
253{
254 struct v4l2_fmtdesc desc2;
255 struct v4l2_format fmt2;
256
257 memset(&desc2,0,sizeof(desc2));
258 memset(&fmt2,0,sizeof(fmt2));
259
260 desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261 if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2))
262 goto done;
263
264 fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
265 fmt2.fmt.pix.width = 10000;
266 fmt2.fmt.pix.height = 10000;
267 fmt2.fmt.pix.pixelformat = desc2.pixelformat;
268 if (0 != drv(inode,file,VIDIOC_TRY_FMT, &fmt2))
269 goto done;
270
271 *maxw = fmt2.fmt.pix.width;
272 *maxh = fmt2.fmt.pix.height;
273
274 done:
275 return 0;
276}
277
278/* ----------------------------------------------------------------- */
279
280/*
281 * This function is exported.
282 */
283int
284v4l_compat_translate_ioctl(struct inode *inode,
285 struct file *file,
286 int cmd,
287 void *arg,
288 v4l2_kioctl drv)
289{
290 struct v4l2_capability *cap2 = NULL;
291 struct v4l2_format *fmt2 = NULL;
292 enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
293
294 struct v4l2_framebuffer fbuf2;
295 struct v4l2_input input2;
296 struct v4l2_tuner tun2;
297 struct v4l2_standard std2;
298 struct v4l2_frequency freq2;
299 struct v4l2_audio aud2;
300 struct v4l2_queryctrl qctrl2;
301 struct v4l2_buffer buf2;
302 v4l2_std_id sid;
303 int i, err = 0;
304
305 switch (cmd) {
306 case VIDIOCGCAP: /* capability */
307 {
308 struct video_capability *cap = arg;
309
310 cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL);
311 memset(cap, 0, sizeof(*cap));
312 memset(cap2, 0, sizeof(*cap2));
313 memset(&fbuf2, 0, sizeof(fbuf2));
314
315 err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
316 if (err < 0) {
317 dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
318 break;
319 }
320 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
321 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
322 if (err < 0) {
323 dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
324 memset(&fbuf2, 0, sizeof(fbuf2));
325 }
326 err = 0;
327 }
328
329 memcpy(cap->name, cap2->card,
330 min(sizeof(cap->name), sizeof(cap2->card)));
331 cap->name[sizeof(cap->name) - 1] = 0;
332 if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
333 cap->type |= VID_TYPE_CAPTURE;
334 if (cap2->capabilities & V4L2_CAP_TUNER)
335 cap->type |= VID_TYPE_TUNER;
336 if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
337 cap->type |= VID_TYPE_TELETEXT;
338 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
339 cap->type |= VID_TYPE_OVERLAY;
340 if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
341 cap->type |= VID_TYPE_CLIPPING;
342
343 cap->channels = count_inputs(inode,file,drv);
344 check_size(inode,file,drv,
345 &cap->maxwidth,&cap->maxheight);
346 cap->audios = 0; /* FIXME */
347 cap->minwidth = 48; /* FIXME */
348 cap->minheight = 32; /* FIXME */
349 break;
350 }
351 case VIDIOCGFBUF: /* get frame buffer */
352 {
353 struct video_buffer *buffer = arg;
354
355 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
356 if (err < 0) {
357 dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
358 break;
359 }
360 buffer->base = fbuf2.base;
361 buffer->height = fbuf2.fmt.height;
362 buffer->width = fbuf2.fmt.width;
363
364 switch (fbuf2.fmt.pixelformat) {
365 case V4L2_PIX_FMT_RGB332:
366 buffer->depth = 8;
367 break;
368 case V4L2_PIX_FMT_RGB555:
369 buffer->depth = 15;
370 break;
371 case V4L2_PIX_FMT_RGB565:
372 buffer->depth = 16;
373 break;
374 case V4L2_PIX_FMT_BGR24:
375 buffer->depth = 24;
376 break;
377 case V4L2_PIX_FMT_BGR32:
378 buffer->depth = 32;
379 break;
380 default:
381 buffer->depth = 0;
382 }
383 if (0 != fbuf2.fmt.bytesperline)
384 buffer->bytesperline = fbuf2.fmt.bytesperline;
385 else {
386 buffer->bytesperline =
387 (buffer->width * buffer->depth + 7) & 7;
388 buffer->bytesperline >>= 3;
389 }
390 break;
391 }
392 case VIDIOCSFBUF: /* set frame buffer */
393 {
394 struct video_buffer *buffer = arg;
395
396 memset(&fbuf2, 0, sizeof(fbuf2));
397 fbuf2.base = buffer->base;
398 fbuf2.fmt.height = buffer->height;
399 fbuf2.fmt.width = buffer->width;
400 switch (buffer->depth) {
401 case 8:
402 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
403 break;
404 case 15:
405 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
406 break;
407 case 16:
408 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
409 break;
410 case 24:
411 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
412 break;
413 case 32:
414 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
415 break;
416 }
417 fbuf2.fmt.bytesperline = buffer->bytesperline;
418 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
419 if (err < 0)
420 dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err);
421 break;
422 }
423 case VIDIOCGWIN: /* get window or capture dimensions */
424 {
425 struct video_window *win = arg;
426
427 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
428 memset(win,0,sizeof(*win));
429 memset(fmt2,0,sizeof(*fmt2));
430
431 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
432 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
433 if (err < 0)
434 dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
435 if (err == 0) {
436 win->x = fmt2->fmt.win.w.left;
437 win->y = fmt2->fmt.win.w.top;
438 win->width = fmt2->fmt.win.w.width;
439 win->height = fmt2->fmt.win.w.height;
440 win->chromakey = fmt2->fmt.win.chromakey;
441 win->clips = NULL;
442 win->clipcount = 0;
443 break;
444 }
445
446 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
447 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
448 if (err < 0) {
449 dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
450 break;
451 }
452 win->x = 0;
453 win->y = 0;
454 win->width = fmt2->fmt.pix.width;
455 win->height = fmt2->fmt.pix.height;
456 win->chromakey = 0;
457 win->clips = NULL;
458 win->clipcount = 0;
459 break;
460 }
461 case VIDIOCSWIN: /* set window and/or capture dimensions */
462 {
463 struct video_window *win = arg;
464 int err1,err2;
465
466 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
467 memset(fmt2,0,sizeof(*fmt2));
468 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
469 drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
470 err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
471 if (err1 < 0)
472 dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
473 if (err1 == 0) {
474 fmt2->fmt.pix.width = win->width;
475 fmt2->fmt.pix.height = win->height;
476 fmt2->fmt.pix.field = V4L2_FIELD_ANY;
477 fmt2->fmt.pix.bytesperline = 0;
478 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
479 if (err < 0)
480 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
481 err);
482 win->width = fmt2->fmt.pix.width;
483 win->height = fmt2->fmt.pix.height;
484 }
485
486 memset(fmt2,0,sizeof(*fmt2));
487 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
488 fmt2->fmt.win.w.left = win->x;
489 fmt2->fmt.win.w.top = win->y;
490 fmt2->fmt.win.w.width = win->width;
491 fmt2->fmt.win.w.height = win->height;
492 fmt2->fmt.win.chromakey = win->chromakey;
493 fmt2->fmt.win.clips = (void __user *)win->clips;
494 fmt2->fmt.win.clipcount = win->clipcount;
495 err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
496 if (err2 < 0)
497 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
498
499 if (err1 != 0 && err2 != 0)
500 err = err1;
501 break;
502 }
503 case VIDIOCCAPTURE: /* turn on/off preview */
504 {
505 int *on = arg;
506
507 if (0 == *on) {
508 /* dirty hack time. But v4l1 has no STREAMOFF
509 * equivalent in the API, and this one at
510 * least comes close ... */
511 drv(inode, file, VIDIOC_STREAMOFF, &captype);
512 }
513 err = drv(inode, file, VIDIOC_OVERLAY, arg);
514 if (err < 0)
515 dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
516 break;
517 }
518 case VIDIOCGCHAN: /* get input information */
519 {
520 struct video_channel *chan = arg;
521
522 memset(&input2,0,sizeof(input2));
523 input2.index = chan->channel;
524 err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
525 if (err < 0) {
526 dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
527 "channel=%d err=%d\n",chan->channel,err);
528 break;
529 }
530 chan->channel = input2.index;
531 memcpy(chan->name, input2.name,
532 min(sizeof(chan->name), sizeof(input2.name)));
533 chan->name[sizeof(chan->name) - 1] = 0;
534 chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
535 chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
536 switch (input2.type) {
537 case V4L2_INPUT_TYPE_TUNER:
538 chan->type = VIDEO_TYPE_TV;
539 break;
540 default:
541 case V4L2_INPUT_TYPE_CAMERA:
542 chan->type = VIDEO_TYPE_CAMERA;
543 break;
544 }
545 chan->norm = 0;
546 err = drv(inode, file, VIDIOC_G_STD, &sid);
547 if (err < 0)
548 dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err);
549 if (err == 0) {
550 if (sid & V4L2_STD_PAL)
551 chan->norm = VIDEO_MODE_PAL;
552 if (sid & V4L2_STD_NTSC)
553 chan->norm = VIDEO_MODE_NTSC;
554 if (sid & V4L2_STD_SECAM)
555 chan->norm = VIDEO_MODE_SECAM;
556 }
557 break;
558 }
559 case VIDIOCSCHAN: /* set input */
560 {
561 struct video_channel *chan = arg;
562
563 sid = 0;
564 err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
565 if (err < 0)
566 dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
567 switch (chan->norm) {
568 case VIDEO_MODE_PAL:
569 sid = V4L2_STD_PAL;
570 break;
571 case VIDEO_MODE_NTSC:
572 sid = V4L2_STD_NTSC;
573 break;
574 case VIDEO_MODE_SECAM:
575 sid = V4L2_STD_SECAM;
576 break;
577 }
578 if (0 != sid) {
579 err = drv(inode, file, VIDIOC_S_STD, &sid);
580 if (err < 0)
581 dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
582 }
583 break;
584 }
585 case VIDIOCGPICT: /* get tone controls & partial capture format */
586 {
587 struct video_picture *pict = arg;
588
589 pict->brightness = get_v4l_control(inode, file,
590 V4L2_CID_BRIGHTNESS,drv);
591 pict->hue = get_v4l_control(inode, file,
592 V4L2_CID_HUE, drv);
593 pict->contrast = get_v4l_control(inode, file,
594 V4L2_CID_CONTRAST, drv);
595 pict->colour = get_v4l_control(inode, file,
596 V4L2_CID_SATURATION, drv);
597 pict->whiteness = get_v4l_control(inode, file,
598 V4L2_CID_WHITENESS, drv);
599
600 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
601 memset(fmt2,0,sizeof(*fmt2));
602 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
603 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
604 if (err < 0) {
605 dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
606 break;
607 }
608#if 0 /* FIXME */
609 pict->depth = fmt2->fmt.pix.depth;
610#endif
611 pict->palette = pixelformat_to_palette(
612 fmt2->fmt.pix.pixelformat);
613 break;
614 }
615 case VIDIOCSPICT: /* set tone controls & partial capture format */
616 {
617 struct video_picture *pict = arg;
618
619 set_v4l_control(inode, file,
620 V4L2_CID_BRIGHTNESS, pict->brightness, drv);
621 set_v4l_control(inode, file,
622 V4L2_CID_HUE, pict->hue, drv);
623 set_v4l_control(inode, file,
624 V4L2_CID_CONTRAST, pict->contrast, drv);
625 set_v4l_control(inode, file,
626 V4L2_CID_SATURATION, pict->colour, drv);
627 set_v4l_control(inode, file,
628 V4L2_CID_WHITENESS, pict->whiteness, drv);
629
630 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
631 memset(fmt2,0,sizeof(*fmt2));
632 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
633 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
634 if (err < 0)
635 dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
636 if (fmt2->fmt.pix.pixelformat !=
637 palette_to_pixelformat(pict->palette)) {
638 fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
639 pict->palette);
640 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
641 if (err < 0)
642 dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
643 }
644
645 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
646 if (err < 0)
647 dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
648 if (fbuf2.fmt.pixelformat !=
649 palette_to_pixelformat(pict->palette)) {
650 fbuf2.fmt.pixelformat = palette_to_pixelformat(
651 pict->palette);
652 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
653 if (err < 0)
654 dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
655 err = 0; /* likely fails for non-root */
656 }
657 break;
658 }
659 case VIDIOCGTUNER: /* get tuner information */
660 {
661 struct video_tuner *tun = arg;
662
663 memset(&tun2,0,sizeof(tun2));
664 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
665 if (err < 0) {
666 dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err);
667 break;
668 }
669 memcpy(tun->name, tun2.name,
670 min(sizeof(tun->name), sizeof(tun2.name)));
671 tun->name[sizeof(tun->name) - 1] = 0;
672 tun->rangelow = tun2.rangelow;
673 tun->rangehigh = tun2.rangehigh;
674 tun->flags = 0;
675 tun->mode = VIDEO_MODE_AUTO;
676
677 for (i = 0; i < 64; i++) {
678 memset(&std2,0,sizeof(std2));
679 std2.index = i;
680 if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
681 break;
682 if (std2.id & V4L2_STD_PAL)
683 tun->flags |= VIDEO_TUNER_PAL;
684 if (std2.id & V4L2_STD_NTSC)
685 tun->flags |= VIDEO_TUNER_NTSC;
686 if (std2.id & V4L2_STD_SECAM)
687 tun->flags |= VIDEO_TUNER_SECAM;
688 }
689
690 err = drv(inode, file, VIDIOC_G_STD, &sid);
691 if (err < 0)
692 dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
693 if (err == 0) {
694 if (sid & V4L2_STD_PAL)
695 tun->mode = VIDEO_MODE_PAL;
696 if (sid & V4L2_STD_NTSC)
697 tun->mode = VIDEO_MODE_NTSC;
698 if (sid & V4L2_STD_SECAM)
699 tun->mode = VIDEO_MODE_SECAM;
700 }
701
702 if (tun2.capability & V4L2_TUNER_CAP_LOW)
703 tun->flags |= VIDEO_TUNER_LOW;
704 if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
705 tun->flags |= VIDEO_TUNER_STEREO_ON;
706 tun->signal = tun2.signal;
707 break;
708 }
709 case VIDIOCSTUNER: /* select a tuner input */
710 {
711#if 0 /* FIXME */
712 err = drv(inode, file, VIDIOC_S_INPUT, &i);
713 if (err < 0)
714 dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
715#else
716 err = 0;
717#endif
718 break;
719 }
720 case VIDIOCGFREQ: /* get frequency */
721 {
722 int *freq = arg;
723
724 freq2.tuner = 0;
725 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
726 if (err < 0)
727 dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err);
728 if (0 == err)
729 *freq = freq2.frequency;
730 break;
731 }
732 case VIDIOCSFREQ: /* set frequency */
733 {
734 int *freq = arg;
735
736 freq2.tuner = 0;
737 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
738 freq2.frequency = *freq;
739 err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
740 if (err < 0)
741 dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n",err);
742 break;
743 }
744 case VIDIOCGAUDIO: /* get audio properties/controls */
745 {
746 struct video_audio *aud = arg;
747
748 err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
749 if (err < 0) {
750 dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err);
751 break;
752 }
753 memcpy(aud->name, aud2.name,
754 min(sizeof(aud->name), sizeof(aud2.name)));
755 aud->name[sizeof(aud->name) - 1] = 0;
756 aud->audio = aud2.index;
757 aud->flags = 0;
758 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
759 if (i >= 0) {
760 aud->volume = i;
761 aud->flags |= VIDEO_AUDIO_VOLUME;
762 }
763 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
764 if (i >= 0) {
765 aud->bass = i;
766 aud->flags |= VIDEO_AUDIO_BASS;
767 }
768 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
769 if (i >= 0) {
770 aud->treble = i;
771 aud->flags |= VIDEO_AUDIO_TREBLE;
772 }
773 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
774 if (i >= 0) {
775 aud->balance = i;
776 aud->flags |= VIDEO_AUDIO_BALANCE;
777 }
778 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
779 if (i >= 0) {
780 if (i)
781 aud->flags |= VIDEO_AUDIO_MUTE;
782 aud->flags |= VIDEO_AUDIO_MUTABLE;
783 }
784 aud->step = 1;
785 qctrl2.id = V4L2_CID_AUDIO_VOLUME;
786 if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
787 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
788 aud->step = qctrl2.step;
789 aud->mode = 0;
790 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
791 if (err < 0) {
792 dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
793 err = 0;
794 break;
795 }
796 if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
797 aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
798 else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
799 aud->mode = VIDEO_SOUND_STEREO;
800 else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
801 aud->mode = VIDEO_SOUND_MONO;
802 break;
803 }
804 case VIDIOCSAUDIO: /* set audio controls */
805 {
806 struct video_audio *aud = arg;
807
808 memset(&aud2,0,sizeof(aud2));
809 memset(&tun2,0,sizeof(tun2));
810
811 aud2.index = aud->audio;
812 err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
813 if (err < 0) {
814 dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err);
815 break;
816 }
817
818 set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
819 aud->volume, drv);
820 set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
821 aud->bass, drv);
822 set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
823 aud->treble, drv);
824 set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
825 aud->balance, drv);
826 set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
827 !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
828
829 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
830 if (err < 0)
831 dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err);
832 if (err == 0) {
833 switch (aud->mode) {
834 default:
835 case VIDEO_SOUND_MONO:
836 case VIDEO_SOUND_LANG1:
837 tun2.audmode = V4L2_TUNER_MODE_MONO;
838 break;
839 case VIDEO_SOUND_STEREO:
840 tun2.audmode = V4L2_TUNER_MODE_STEREO;
841 break;
842 case VIDEO_SOUND_LANG2:
843 tun2.audmode = V4L2_TUNER_MODE_LANG2;
844 break;
845 }
846 err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
847 if (err < 0)
848 dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err);
849 }
850 err = 0;
851 break;
852 }
853#if 0
854 case VIDIOCGMBUF:
855 /* v4l2 drivers must implement that themself. The
856 mmap() differences can't be translated fully
857 transparent, thus there is no point to try that */
858#endif
859 case VIDIOCMCAPTURE: /* capture a frame */
860 {
861 struct video_mmap *mm = arg;
862
863 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
864 memset(&buf2,0,sizeof(buf2));
865 memset(fmt2,0,sizeof(*fmt2));
866
867 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
868 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
869 if (err < 0) {
870 dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
871 break;
872 }
873 if (mm->width != fmt2->fmt.pix.width ||
874 mm->height != fmt2->fmt.pix.height ||
875 palette_to_pixelformat(mm->format) !=
876 fmt2->fmt.pix.pixelformat)
877 {/* New capture format... */
878 fmt2->fmt.pix.width = mm->width;
879 fmt2->fmt.pix.height = mm->height;
880 fmt2->fmt.pix.pixelformat =
881 palette_to_pixelformat(mm->format);
882 fmt2->fmt.pix.field = V4L2_FIELD_ANY;
883 fmt2->fmt.pix.bytesperline = 0;
884 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
885 if (err < 0) {
886 dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
887 break;
888 }
889 }
890 buf2.index = mm->frame;
891 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
892 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
893 if (err < 0) {
894 dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
895 break;
896 }
897 err = drv(inode, file, VIDIOC_QBUF, &buf2);
898 if (err < 0) {
899 dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
900 break;
901 }
902 err = drv(inode, file, VIDIOC_STREAMON, &captype);
903 if (err < 0)
904 dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
905 break;
906 }
907 case VIDIOCSYNC: /* wait for a frame */
908 {
909 int *i = arg;
910
911 buf2.index = *i;
912 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
913 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
914 if (err < 0) {
915 /* No such buffer */
916 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
917 break;
918 }
919 if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
920 /* Buffer is not mapped */
921 err = -EINVAL;
922 break;
923 }
924
925 /* make sure capture actually runs so we don't block forever */
926 err = drv(inode, file, VIDIOC_STREAMON, &captype);
927 if (err < 0) {
928 dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err);
929 break;
930 }
931
932 /* Loop as long as the buffer is queued, but not done */
933 while ((buf2.flags &
934 (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
935 == V4L2_BUF_FLAG_QUEUED)
936 {
937 err = poll_one(file);
938 if (err < 0 || /* error or sleep was interrupted */
939 err == 0) /* timeout? Shouldn't occur. */
940 break;
941 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
942 if (err < 0)
943 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
944 }
945 if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
946 break;
947 do {
948 err = drv(inode, file, VIDIOC_DQBUF, &buf2);
949 if (err < 0)
950 dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
951 } while (err == 0 && buf2.index != *i);
952 break;
953 }
954
955 case VIDIOCGVBIFMT: /* query VBI data capture format */
956 {
957 struct vbi_format *fmt = arg;
958
959 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
960 memset(fmt2, 0, sizeof(*fmt2));
961 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
962
963 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
964 if (err < 0) {
965 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
966 break;
967 }
968 memset(fmt, 0, sizeof(*fmt));
969 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
970 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
971 fmt->sample_format = VIDEO_PALETTE_RAW;
972 fmt->start[0] = fmt2->fmt.vbi.start[0];
973 fmt->count[0] = fmt2->fmt.vbi.count[0];
974 fmt->start[1] = fmt2->fmt.vbi.start[1];
975 fmt->count[1] = fmt2->fmt.vbi.count[1];
976 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
977 break;
978 }
979 case VIDIOCSVBIFMT:
980 {
981 struct vbi_format *fmt = arg;
982
983 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
984 memset(fmt2, 0, sizeof(*fmt2));
985
986 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
987 fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
988 fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate;
989 fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
990 fmt2->fmt.vbi.start[0] = fmt->start[0];
991 fmt2->fmt.vbi.count[0] = fmt->count[0];
992 fmt2->fmt.vbi.start[1] = fmt->start[1];
993 fmt2->fmt.vbi.count[1] = fmt->count[1];
994 fmt2->fmt.vbi.flags = fmt->flags;
995 err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
996 if (err < 0) {
997 dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
998 break;
999 }
1000
1001 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1002 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
1003 VIDEO_PALETTE_RAW != fmt->sample_format ||
1004 fmt2->fmt.vbi.start[0] != fmt->start[0] ||
1005 fmt2->fmt.vbi.count[0] != fmt->count[0] ||
1006 fmt2->fmt.vbi.start[1] != fmt->start[1] ||
1007 fmt2->fmt.vbi.count[1] != fmt->count[1] ||
1008 fmt2->fmt.vbi.flags != fmt->flags) {
1009 err = -EINVAL;
1010 break;
1011 }
1012 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
1013 if (err < 0)
1014 dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
1015 break;
1016 }
1017
1018 default:
1019 err = -ENOIOCTLCMD;
1020 break;
1021 }
1022
1023 if (cap2)
1024 kfree(cap2);
1025 if (fmt2)
1026 kfree(fmt2);
1027 return err;
1028}
1029
1030EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1031
1032/*
1033 * Local variables:
1034 * c-basic-offset: 8
1035 * End:
1036 */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
new file mode 100644
index 000000000000..b5e0cf3448f4
--- /dev/null
+++ b/drivers/media/video/v4l2-common.c
@@ -0,0 +1,282 @@
1/*
2 * Video for Linux Two
3 *
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
6 *
7 * This file replaces the videodev.c file that comes with the
8 * regular kernel distribution.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * Author: Bill Dirks <bdirks@pacbell.net>
16 * based on code by Alan Cox, <alan@cymru.net>
17 *
18 */
19
20/*
21 * Video capture interface for Linux
22 *
23 * A generic video device interface for the LINUX operating system
24 * using a set of device structures/vectors for low level operations.
25 *
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version
29 * 2 of the License, or (at your option) any later version.
30 *
31 * Author: Alan Cox, <alan@redhat.com>
32 *
33 * Fixes:
34 */
35
36/*
37 * Video4linux 1/2 integration by Justin Schoeman
38 * <justin@suntiger.ee.up.ac.za>
39 * 2.4 PROCFS support ported from 2.4 kernels by
40 * Iñaki García Etxebarria <garetxe@euskalnet.net>
41 * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
42 * 2.4 devfs support ported from 2.4 kernels by
43 * Dan Merillat <dan@merillat.org>
44 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
45 */
46
47#include <linux/config.h>
48#include <linux/module.h>
49#include <linux/types.h>
50#include <linux/kernel.h>
51#include <linux/sched.h>
52#include <linux/smp_lock.h>
53#include <linux/mm.h>
54#include <linux/string.h>
55#include <linux/errno.h>
56#include <asm/uaccess.h>
57#include <asm/system.h>
58#include <asm/pgtable.h>
59#include <asm/io.h>
60#include <asm/div64.h>
61
62#ifdef CONFIG_KMOD
63#include <linux/kmod.h>
64#endif
65
66#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
67#include <linux/ust.h>
68#endif
69
70
71#include <linux/videodev.h>
72
73MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
74MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
75MODULE_LICENSE("GPL");
76
77/*
78 *
79 * V 4 L 2 D R I V E R H E L P E R A P I
80 *
81 */
82
83/*
84 * Video Standard Operations (contributed by Michael Schimek)
85 */
86
87#if 0 /* seems to have no users */
88/* This is the recommended method to deal with the framerate fields. More
89 sophisticated drivers will access the fields directly. */
90unsigned int
91v4l2_video_std_fps(struct v4l2_standard *vs)
92{
93 if (vs->frameperiod.numerator > 0)
94 return (((vs->frameperiod.denominator << 8) /
95 vs->frameperiod.numerator) +
96 (1 << 7)) / (1 << 8);
97 return 0;
98}
99EXPORT_SYMBOL(v4l2_video_std_fps);
100#endif
101
102/* Fill in the fields of a v4l2_standard structure according to the
103 'id' and 'transmission' parameters. Returns negative on error. */
104int v4l2_video_std_construct(struct v4l2_standard *vs,
105 int id, char *name)
106{
107 u32 index = vs->index;
108
109 memset(vs, 0, sizeof(struct v4l2_standard));
110 vs->index = index;
111 vs->id = id;
112 if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
113 vs->frameperiod.numerator = 1001;
114 vs->frameperiod.denominator = 30000;
115 vs->framelines = 525;
116 } else {
117 vs->frameperiod.numerator = 1;
118 vs->frameperiod.denominator = 25;
119 vs->framelines = 625;
120 }
121 strlcpy(vs->name,name,sizeof(vs->name));
122 return 0;
123}
124
125
126/* ----------------------------------------------------------------- */
127/* priority handling */
128
129#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
130 val == V4L2_PRIORITY_INTERACTIVE || \
131 val == V4L2_PRIORITY_RECORD)
132
133int v4l2_prio_init(struct v4l2_prio_state *global)
134{
135 memset(global,0,sizeof(*global));
136 return 0;
137}
138
139int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
140 enum v4l2_priority new)
141{
142 if (!V4L2_PRIO_VALID(new))
143 return -EINVAL;
144 if (*local == new)
145 return 0;
146
147 atomic_inc(&global->prios[new]);
148 if (V4L2_PRIO_VALID(*local))
149 atomic_dec(&global->prios[*local]);
150 *local = new;
151 return 0;
152}
153
154int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
155{
156 return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
157}
158
159int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
160{
161 if (V4L2_PRIO_VALID(*local))
162 atomic_dec(&global->prios[*local]);
163 return 0;
164}
165
166enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
167{
168 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
169 return V4L2_PRIORITY_RECORD;
170 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
171 return V4L2_PRIORITY_INTERACTIVE;
172 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
173 return V4L2_PRIORITY_BACKGROUND;
174 return V4L2_PRIORITY_UNSET;
175}
176
177int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
178{
179 if (*local < v4l2_prio_max(global))
180 return -EBUSY;
181 return 0;
182}
183
184
185/* ----------------------------------------------------------------- */
186/* some arrays for pretty-printing debug messages */
187
188char *v4l2_field_names[] = {
189 [V4L2_FIELD_ANY] = "any",
190 [V4L2_FIELD_NONE] = "none",
191 [V4L2_FIELD_TOP] = "top",
192 [V4L2_FIELD_BOTTOM] = "bottom",
193 [V4L2_FIELD_INTERLACED] = "interlaced",
194 [V4L2_FIELD_SEQ_TB] = "seq-tb",
195 [V4L2_FIELD_SEQ_BT] = "seq-bt",
196 [V4L2_FIELD_ALTERNATE] = "alternate",
197};
198
199char *v4l2_type_names[] = {
200 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
201 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
202 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
203 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
204 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
205};
206
207char *v4l2_ioctl_names[256] = {
208#if __GNUC__ >= 3
209 [0 ... 255] = "UNKNOWN",
210#endif
211 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
212 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
213 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
214 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
215 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
216#if 0
217 [_IOC_NR(VIDIOC_G_COMP)] = "VIDIOC_G_COMP",
218 [_IOC_NR(VIDIOC_S_COMP)] = "VIDIOC_S_COMP",
219#endif
220 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
221 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
222 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
223 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
224 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
225 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
226 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
227 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
228 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
229 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
230 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
231 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
232 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
233 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
234 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
235 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
236 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
237 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
238 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
239 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
240 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
241 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
242 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
243 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
244 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
245 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
246 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
247 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
248 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
249 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
250 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
251 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
252 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
253 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
254 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
255 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
256 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
257 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
258 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
259 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
260 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
261};
262
263/* ----------------------------------------------------------------- */
264
265EXPORT_SYMBOL(v4l2_video_std_construct);
266
267EXPORT_SYMBOL(v4l2_prio_init);
268EXPORT_SYMBOL(v4l2_prio_change);
269EXPORT_SYMBOL(v4l2_prio_open);
270EXPORT_SYMBOL(v4l2_prio_close);
271EXPORT_SYMBOL(v4l2_prio_max);
272EXPORT_SYMBOL(v4l2_prio_check);
273
274EXPORT_SYMBOL(v4l2_field_names);
275EXPORT_SYMBOL(v4l2_type_names);
276EXPORT_SYMBOL(v4l2_ioctl_names);
277
278/*
279 * Local variables:
280 * c-basic-offset: 8
281 * End:
282 */
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
new file mode 100644
index 000000000000..31cc4ed9b747
--- /dev/null
+++ b/drivers/media/video/video-buf-dvb.c
@@ -0,0 +1,251 @@
1/*
2 * $Id: video-buf-dvb.c,v 1.7 2004/12/09 12:51:35 kraxel Exp $
3 *
4 * some helper function for simple DVB cards which simply DMA the
5 * complete transport stream and let the computer sort everything else
6 * (i.e. we are using the software demux, ...). Also uses the
7 * video-buf to manage DMA buffers.
8 *
9 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/fs.h>
21#include <linux/kthread.h>
22#include <linux/file.h>
23#include <linux/suspend.h>
24
25#include <media/video-buf.h>
26#include <media/video-buf-dvb.h>
27
28/* ------------------------------------------------------------------ */
29
30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
31MODULE_LICENSE("GPL");
32
33static unsigned int debug = 0;
34module_param(debug, int, 0644);
35MODULE_PARM_DESC(debug,"enable debug messages");
36
37#define dprintk(fmt, arg...) if (debug) \
38 printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name , ## arg)
39
40/* ------------------------------------------------------------------ */
41
42static int videobuf_dvb_thread(void *data)
43{
44 struct videobuf_dvb *dvb = data;
45 struct videobuf_buffer *buf;
46 unsigned long flags;
47 int err;
48
49 dprintk("dvb thread started\n");
50 videobuf_read_start(&dvb->dvbq);
51
52 for (;;) {
53 /* fetch next buffer */
54 buf = list_entry(dvb->dvbq.stream.next,
55 struct videobuf_buffer, stream);
56 list_del(&buf->stream);
57 err = videobuf_waiton(buf,0,1);
58 BUG_ON(0 != err);
59
60 /* no more feeds left or stop_feed() asked us to quit */
61 if (0 == dvb->nfeeds)
62 break;
63 if (kthread_should_stop())
64 break;
65 if (current->flags & PF_FREEZE)
66 refrigerator(PF_FREEZE);
67
68 /* feed buffer data to demux */
69 if (buf->state == STATE_DONE)
70 dvb_dmx_swfilter(&dvb->demux, buf->dma.vmalloc,
71 buf->size);
72
73 /* requeue buffer */
74 list_add_tail(&buf->stream,&dvb->dvbq.stream);
75 spin_lock_irqsave(dvb->dvbq.irqlock,flags);
76 dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf);
77 spin_unlock_irqrestore(dvb->dvbq.irqlock,flags);
78 }
79
80 videobuf_read_stop(&dvb->dvbq);
81 dprintk("dvb thread stopped\n");
82
83 /* Hmm, linux becomes *very* unhappy without this ... */
84 while (!kthread_should_stop()) {
85 set_current_state(TASK_INTERRUPTIBLE);
86 schedule();
87 }
88 return 0;
89}
90
91static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
92{
93 struct dvb_demux *demux = feed->demux;
94 struct videobuf_dvb *dvb = demux->priv;
95 int rc;
96
97 if (!demux->dmx.frontend)
98 return -EINVAL;
99
100 down(&dvb->lock);
101 dvb->nfeeds++;
102 rc = dvb->nfeeds;
103
104 if (NULL != dvb->thread)
105 goto out;
106 dvb->thread = kthread_run(videobuf_dvb_thread,
107 dvb, "%s dvb", dvb->name);
108 if (IS_ERR(dvb->thread)) {
109 rc = PTR_ERR(dvb->thread);
110 dvb->thread = NULL;
111 }
112
113out:
114 up(&dvb->lock);
115 return rc;
116}
117
118static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
119{
120 struct dvb_demux *demux = feed->demux;
121 struct videobuf_dvb *dvb = demux->priv;
122 int err = 0;
123
124 down(&dvb->lock);
125 dvb->nfeeds--;
126 if (0 == dvb->nfeeds && NULL != dvb->thread) {
127 // FIXME: cx8802_cancel_buffers(dev);
128 err = kthread_stop(dvb->thread);
129 dvb->thread = NULL;
130 }
131 up(&dvb->lock);
132 return err;
133}
134
135/* ------------------------------------------------------------------ */
136
137int videobuf_dvb_register(struct videobuf_dvb *dvb,
138 struct module *module,
139 void *adapter_priv)
140{
141 int result;
142
143 init_MUTEX(&dvb->lock);
144
145 /* register adapter */
146 result = dvb_register_adapter(&dvb->adapter, dvb->name, module);
147 if (result < 0) {
148 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
149 dvb->name, result);
150 goto fail_adapter;
151 }
152 dvb->adapter->priv = adapter_priv;
153
154 /* register frontend */
155 result = dvb_register_frontend(dvb->adapter, dvb->frontend);
156 if (result < 0) {
157 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
158 dvb->name, result);
159 goto fail_frontend;
160 }
161
162 /* register demux stuff */
163 dvb->demux.dmx.capabilities =
164 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
165 DMX_MEMORY_BASED_FILTERING;
166 dvb->demux.priv = dvb;
167 dvb->demux.filternum = 256;
168 dvb->demux.feednum = 256;
169 dvb->demux.start_feed = videobuf_dvb_start_feed;
170 dvb->demux.stop_feed = videobuf_dvb_stop_feed;
171 result = dvb_dmx_init(&dvb->demux);
172 if (result < 0) {
173 printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
174 dvb->name, result);
175 goto fail_dmx;
176 }
177
178 dvb->dmxdev.filternum = 256;
179 dvb->dmxdev.demux = &dvb->demux.dmx;
180 dvb->dmxdev.capabilities = 0;
181 result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter);
182 if (result < 0) {
183 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
184 dvb->name, result);
185 goto fail_dmxdev;
186 }
187
188 dvb->fe_hw.source = DMX_FRONTEND_0;
189 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
190 if (result < 0) {
191 printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
192 dvb->name, result);
193 goto fail_fe_hw;
194 }
195
196 dvb->fe_mem.source = DMX_MEMORY_FE;
197 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
198 if (result < 0) {
199 printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
200 dvb->name, result);
201 goto fail_fe_mem;
202 }
203
204 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
205 if (result < 0) {
206 printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
207 dvb->name, result);
208 goto fail_fe_conn;
209 }
210
211 /* register network adapter */
212 dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx);
213 return 0;
214
215fail_fe_conn:
216 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
217fail_fe_mem:
218 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
219fail_fe_hw:
220 dvb_dmxdev_release(&dvb->dmxdev);
221fail_dmxdev:
222 dvb_dmx_release(&dvb->demux);
223fail_dmx:
224 dvb_unregister_frontend(dvb->frontend);
225fail_frontend:
226 dvb_unregister_adapter(dvb->adapter);
227fail_adapter:
228 return result;
229}
230
231void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
232{
233 dvb_net_release(&dvb->net);
234 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
235 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
236 dvb_dmxdev_release(&dvb->dmxdev);
237 dvb_dmx_release(&dvb->demux);
238 dvb_unregister_frontend(dvb->frontend);
239 dvb_unregister_adapter(dvb->adapter);
240}
241
242EXPORT_SYMBOL(videobuf_dvb_register);
243EXPORT_SYMBOL(videobuf_dvb_unregister);
244
245/* ------------------------------------------------------------------ */
246/*
247 * Local variables:
248 * c-basic-offset: 8
249 * compile-command: "make DVB=1"
250 * End:
251 */
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
new file mode 100644
index 000000000000..5afdc7852610
--- /dev/null
+++ b/drivers/media/video/video-buf.c
@@ -0,0 +1,1290 @@
1/*
2 * $Id: video-buf.c,v 1.18 2005/02/24 13:32:30 kraxel Exp $
3 *
4 * generic helper functions for video4linux capture buffers, to handle
5 * memory management and PCI DMA. Right now bttv + saa7134 use it.
6 *
7 * The functions expect the hardware being able to scatter gatter
8 * (i.e. the buffers are not linear in physical memory, but fragmented
9 * into PAGE_SIZE chunks). They also assume the driver does not need
10 * to touch the video data (thus it is probably not useful for USB 1.1
11 * as data often must be uncompressed by the drivers).
12 *
13 * (c) 2001-2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/vmalloc.h>
25#include <linux/pagemap.h>
26#include <linux/slab.h>
27#include <linux/pci.h>
28#include <linux/interrupt.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
31
32#include <media/video-buf.h>
33
34#define MAGIC_DMABUF 0x19721112
35#define MAGIC_BUFFER 0x20040302
36#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
37 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
38
39static int debug = 0;
40module_param(debug, int, 0644);
41
42MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
43MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
44MODULE_LICENSE("GPL");
45
46#define dprintk(level, fmt, arg...) if (debug >= level) \
47 printk(KERN_DEBUG "vbuf: " fmt , ## arg)
48
49struct scatterlist*
50videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
51{
52 struct scatterlist *sglist;
53 struct page *pg;
54 int i;
55
56 sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
57 if (NULL == sglist)
58 return NULL;
59 memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
60 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
61 pg = vmalloc_to_page(virt);
62 if (NULL == pg)
63 goto err;
64 if (PageHighMem(pg))
65 BUG();
66 sglist[i].page = pg;
67 sglist[i].length = PAGE_SIZE;
68 }
69 return sglist;
70
71 err:
72 kfree(sglist);
73 return NULL;
74}
75
76struct scatterlist*
77videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
78{
79 struct scatterlist *sglist;
80 int i = 0;
81
82 if (NULL == pages[0])
83 return NULL;
84 sglist = kmalloc(sizeof(*sglist) * nr_pages, GFP_KERNEL);
85 if (NULL == sglist)
86 return NULL;
87 memset(sglist, 0, sizeof(*sglist) * nr_pages);
88
89 if (NULL == pages[0])
90 goto nopage;
91 if (PageHighMem(pages[0]))
92 /* DMA to highmem pages might not work */
93 goto highmem;
94 sglist[0].page = pages[0];
95 sglist[0].offset = offset;
96 sglist[0].length = PAGE_SIZE - offset;
97 for (i = 1; i < nr_pages; i++) {
98 if (NULL == pages[i])
99 goto nopage;
100 if (PageHighMem(pages[i]))
101 goto highmem;
102 sglist[i].page = pages[i];
103 sglist[i].length = PAGE_SIZE;
104 }
105 return sglist;
106
107 nopage:
108 dprintk(2,"sgl: oops - no page\n");
109 kfree(sglist);
110 return NULL;
111
112 highmem:
113 dprintk(2,"sgl: oops - highmem page\n");
114 kfree(sglist);
115 return NULL;
116}
117
118/* --------------------------------------------------------------------- */
119
120void videobuf_dma_init(struct videobuf_dmabuf *dma)
121{
122 memset(dma,0,sizeof(*dma));
123 dma->magic = MAGIC_DMABUF;
124}
125
126int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
127 unsigned long data, unsigned long size)
128{
129 unsigned long first,last;
130 int err, rw = 0;
131
132 dma->direction = direction;
133 switch (dma->direction) {
134 case PCI_DMA_FROMDEVICE: rw = READ; break;
135 case PCI_DMA_TODEVICE: rw = WRITE; break;
136 default: BUG();
137 }
138
139 first = (data & PAGE_MASK) >> PAGE_SHIFT;
140 last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
141 dma->offset = data & ~PAGE_MASK;
142 dma->nr_pages = last-first+1;
143 dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
144 GFP_KERNEL);
145 if (NULL == dma->pages)
146 return -ENOMEM;
147 dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
148 data,size,dma->nr_pages);
149
150 down_read(&current->mm->mmap_sem);
151 err = get_user_pages(current,current->mm,
152 data & PAGE_MASK, dma->nr_pages,
153 rw == READ, 1, /* force */
154 dma->pages, NULL);
155 up_read(&current->mm->mmap_sem);
156 if (err != dma->nr_pages) {
157 dma->nr_pages = (err >= 0) ? err : 0;
158 dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
159 return err < 0 ? err : -EINVAL;
160 }
161 return 0;
162}
163
164int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
165 int nr_pages)
166{
167 dprintk(1,"init kernel [%d pages]\n",nr_pages);
168 dma->direction = direction;
169 dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
170 if (NULL == dma->vmalloc) {
171 dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages);
172 return -ENOMEM;
173 }
174 memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT);
175 dma->nr_pages = nr_pages;
176 return 0;
177}
178
179int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
180 dma_addr_t addr, int nr_pages)
181{
182 dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n",
183 nr_pages,(unsigned long)addr);
184 dma->direction = direction;
185 if (0 == addr)
186 return -EINVAL;
187
188 dma->bus_addr = addr;
189 dma->nr_pages = nr_pages;
190 return 0;
191}
192
193int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
194{
195 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
196 BUG_ON(0 == dma->nr_pages);
197
198 if (dma->pages) {
199 dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
200 dma->offset);
201 }
202 if (dma->vmalloc) {
203 dma->sglist = videobuf_vmalloc_to_sg
204 (dma->vmalloc,dma->nr_pages);
205 }
206 if (dma->bus_addr) {
207 dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
208 if (NULL != dma->sglist) {
209 dma->sglen = 1;
210 sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
211 dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK;
212 sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE;
213 }
214 }
215 if (NULL == dma->sglist) {
216 dprintk(1,"scatterlist is NULL\n");
217 return -ENOMEM;
218 }
219
220 if (!dma->bus_addr) {
221 dma->sglen = pci_map_sg(dev,dma->sglist,dma->nr_pages,
222 dma->direction);
223 if (0 == dma->sglen) {
224 printk(KERN_WARNING
225 "%s: pci_map_sg failed\n",__FUNCTION__);
226 kfree(dma->sglist);
227 dma->sglist = NULL;
228 dma->sglen = 0;
229 return -EIO;
230 }
231 }
232 return 0;
233}
234
235int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
236{
237 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
238 BUG_ON(!dma->sglen);
239
240 if (!dma->bus_addr)
241 pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction);
242 return 0;
243}
244
245int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
246{
247 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
248 if (!dma->sglen)
249 return 0;
250
251 if (!dma->bus_addr)
252 pci_unmap_sg(dev,dma->sglist,dma->nr_pages,dma->direction);
253 kfree(dma->sglist);
254 dma->sglist = NULL;
255 dma->sglen = 0;
256 return 0;
257}
258
259int videobuf_dma_free(struct videobuf_dmabuf *dma)
260{
261 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
262 BUG_ON(dma->sglen);
263
264 if (dma->pages) {
265 int i;
266 for (i=0; i < dma->nr_pages; i++)
267 page_cache_release(dma->pages[i]);
268 kfree(dma->pages);
269 dma->pages = NULL;
270 }
271 if (dma->vmalloc) {
272 vfree(dma->vmalloc);
273 dma->vmalloc = NULL;
274 }
275 if (dma->bus_addr) {
276 dma->bus_addr = 0;
277 }
278 dma->direction = PCI_DMA_NONE;
279 return 0;
280}
281
282/* --------------------------------------------------------------------- */
283
284void* videobuf_alloc(unsigned int size)
285{
286 struct videobuf_buffer *vb;
287
288 vb = kmalloc(size,GFP_KERNEL);
289 if (NULL != vb) {
290 memset(vb,0,size);
291 videobuf_dma_init(&vb->dma);
292 init_waitqueue_head(&vb->done);
293 vb->magic = MAGIC_BUFFER;
294 }
295 return vb;
296}
297
298int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
299{
300 int retval = 0;
301 DECLARE_WAITQUEUE(wait, current);
302
303 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
304 add_wait_queue(&vb->done, &wait);
305 while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
306 if (non_blocking) {
307 retval = -EAGAIN;
308 break;
309 }
310 set_current_state(intr ? TASK_INTERRUPTIBLE
311 : TASK_UNINTERRUPTIBLE);
312 if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED)
313 schedule();
314 set_current_state(TASK_RUNNING);
315 if (intr && signal_pending(current)) {
316 dprintk(1,"buffer waiton: -EINTR\n");
317 retval = -EINTR;
318 break;
319 }
320 }
321 remove_wait_queue(&vb->done, &wait);
322 return retval;
323}
324
325int
326videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb,
327 struct v4l2_framebuffer *fbuf)
328{
329 int err,pages;
330 dma_addr_t bus;
331
332 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
333 switch (vb->memory) {
334 case V4L2_MEMORY_MMAP:
335 case V4L2_MEMORY_USERPTR:
336 if (0 == vb->baddr) {
337 /* no userspace addr -- kernel bounce buffer */
338 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
339 err = videobuf_dma_init_kernel(&vb->dma,PCI_DMA_FROMDEVICE,
340 pages);
341 if (0 != err)
342 return err;
343 } else {
344 /* dma directly to userspace */
345 err = videobuf_dma_init_user(&vb->dma,PCI_DMA_FROMDEVICE,
346 vb->baddr,vb->bsize);
347 if (0 != err)
348 return err;
349 }
350 break;
351 case V4L2_MEMORY_OVERLAY:
352 if (NULL == fbuf)
353 return -EINVAL;
354 /* FIXME: need sanity checks for vb->boff */
355 bus = (dma_addr_t)fbuf->base + vb->boff;
356 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
357 err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
358 bus, pages);
359 if (0 != err)
360 return err;
361 break;
362 default:
363 BUG();
364 }
365 err = videobuf_dma_pci_map(pci,&vb->dma);
366 if (0 != err)
367 return err;
368
369 return 0;
370}
371
372/* --------------------------------------------------------------------- */
373
374void videobuf_queue_init(struct videobuf_queue* q,
375 struct videobuf_queue_ops *ops,
376 struct pci_dev *pci,
377 spinlock_t *irqlock,
378 enum v4l2_buf_type type,
379 enum v4l2_field field,
380 unsigned int msize,
381 void *priv)
382{
383 memset(q,0,sizeof(*q));
384 q->irqlock = irqlock;
385 q->pci = pci;
386 q->type = type;
387 q->field = field;
388 q->msize = msize;
389 q->ops = ops;
390 q->priv_data = priv;
391
392 init_MUTEX(&q->lock);
393 INIT_LIST_HEAD(&q->stream);
394}
395
396int
397videobuf_queue_is_busy(struct videobuf_queue *q)
398{
399 int i;
400
401 if (q->streaming) {
402 dprintk(1,"busy: streaming active\n");
403 return 1;
404 }
405 if (q->reading) {
406 dprintk(1,"busy: pending read #1\n");
407 return 1;
408 }
409 if (q->read_buf) {
410 dprintk(1,"busy: pending read #2\n");
411 return 1;
412 }
413 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
414 if (NULL == q->bufs[i])
415 continue;
416 if (q->bufs[i]->map) {
417 dprintk(1,"busy: buffer #%d mapped\n",i);
418 return 1;
419 }
420 if (q->bufs[i]->state == STATE_QUEUED) {
421 dprintk(1,"busy: buffer #%d queued\n",i);
422 return 1;
423 }
424 if (q->bufs[i]->state == STATE_ACTIVE) {
425 dprintk(1,"busy: buffer #%d avtive\n",i);
426 return 1;
427 }
428 }
429 return 0;
430}
431
432void
433videobuf_queue_cancel(struct videobuf_queue *q)
434{
435 unsigned long flags;
436 int i;
437
438 /* remove queued buffers from list */
439 spin_lock_irqsave(q->irqlock,flags);
440 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
441 if (NULL == q->bufs[i])
442 continue;
443 if (q->bufs[i]->state == STATE_QUEUED) {
444 list_del(&q->bufs[i]->queue);
445 q->bufs[i]->state = STATE_ERROR;
446 }
447 }
448 spin_unlock_irqrestore(q->irqlock,flags);
449
450 /* free all buffers + clear queue */
451 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
452 if (NULL == q->bufs[i])
453 continue;
454 q->ops->buf_release(q,q->bufs[i]);
455 }
456 INIT_LIST_HEAD(&q->stream);
457}
458
459/* --------------------------------------------------------------------- */
460
461enum v4l2_field
462videobuf_next_field(struct videobuf_queue *q)
463{
464 enum v4l2_field field = q->field;
465
466 BUG_ON(V4L2_FIELD_ANY == field);
467
468 if (V4L2_FIELD_ALTERNATE == field) {
469 if (V4L2_FIELD_TOP == q->last) {
470 field = V4L2_FIELD_BOTTOM;
471 q->last = V4L2_FIELD_BOTTOM;
472 } else {
473 field = V4L2_FIELD_TOP;
474 q->last = V4L2_FIELD_TOP;
475 }
476 }
477 return field;
478}
479
480void
481videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
482 enum v4l2_buf_type type)
483{
484 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
485
486 b->index = vb->i;
487 b->type = type;
488
489 b->memory = vb->memory;
490 switch (b->memory) {
491 case V4L2_MEMORY_MMAP:
492 b->m.offset = vb->boff;
493 b->length = vb->bsize;
494 break;
495 case V4L2_MEMORY_USERPTR:
496 b->m.userptr = vb->baddr;
497 b->length = vb->bsize;
498 break;
499 case V4L2_MEMORY_OVERLAY:
500 b->m.offset = vb->boff;
501 break;
502 }
503
504 b->flags = 0;
505 if (vb->map)
506 b->flags |= V4L2_BUF_FLAG_MAPPED;
507
508 switch (vb->state) {
509 case STATE_PREPARED:
510 case STATE_QUEUED:
511 case STATE_ACTIVE:
512 b->flags |= V4L2_BUF_FLAG_QUEUED;
513 break;
514 case STATE_DONE:
515 case STATE_ERROR:
516 b->flags |= V4L2_BUF_FLAG_DONE;
517 break;
518 case STATE_NEEDS_INIT:
519 case STATE_IDLE:
520 /* nothing */
521 break;
522 }
523
524 if (vb->input != UNSET) {
525 b->flags |= V4L2_BUF_FLAG_INPUT;
526 b->input = vb->input;
527 }
528
529 b->field = vb->field;
530 b->timestamp = vb->ts;
531 b->bytesused = vb->size;
532 b->sequence = vb->field_count >> 1;
533}
534
535int
536videobuf_reqbufs(struct videobuf_queue *q,
537 struct v4l2_requestbuffers *req)
538{
539 unsigned int size,count;
540 int retval;
541
542 if (req->type != q->type)
543 return -EINVAL;
544 if (req->count < 1)
545 return -EINVAL;
546 if (req->memory != V4L2_MEMORY_MMAP &&
547 req->memory != V4L2_MEMORY_USERPTR &&
548 req->memory != V4L2_MEMORY_OVERLAY)
549 return -EINVAL;
550
551 if (q->streaming)
552 return -EBUSY;
553 if (!list_empty(&q->stream))
554 return -EBUSY;
555
556 down(&q->lock);
557 count = req->count;
558 if (count > VIDEO_MAX_FRAME)
559 count = VIDEO_MAX_FRAME;
560 size = 0;
561 q->ops->buf_setup(q,&count,&size);
562 size = PAGE_ALIGN(size);
563 dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
564 count, size, (count*size)>>PAGE_SHIFT);
565
566 retval = videobuf_mmap_setup(q,count,size,req->memory);
567 if (retval < 0)
568 goto done;
569
570 req->count = count;
571
572 done:
573 up(&q->lock);
574 return retval;
575}
576
577int
578videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
579{
580 if (unlikely(b->type != q->type))
581 return -EINVAL;
582 if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME))
583 return -EINVAL;
584 if (unlikely(NULL == q->bufs[b->index]))
585 return -EINVAL;
586 videobuf_status(b,q->bufs[b->index],q->type);
587 return 0;
588}
589
590int
591videobuf_qbuf(struct videobuf_queue *q,
592 struct v4l2_buffer *b)
593{
594 struct videobuf_buffer *buf;
595 enum v4l2_field field;
596 unsigned long flags;
597 int retval;
598
599 down(&q->lock);
600 retval = -EBUSY;
601 if (q->reading)
602 goto done;
603 retval = -EINVAL;
604 if (b->type != q->type)
605 goto done;
606 if (b->index < 0 || b->index >= VIDEO_MAX_FRAME)
607 goto done;
608 buf = q->bufs[b->index];
609 if (NULL == buf)
610 goto done;
611 MAGIC_CHECK(buf->magic,MAGIC_BUFFER);
612 if (buf->memory != b->memory)
613 goto done;
614 if (buf->state == STATE_QUEUED ||
615 buf->state == STATE_ACTIVE)
616 goto done;
617
618 if (b->flags & V4L2_BUF_FLAG_INPUT) {
619 if (b->input >= q->inputs)
620 goto done;
621 buf->input = b->input;
622 } else {
623 buf->input = UNSET;
624 }
625
626 switch (b->memory) {
627 case V4L2_MEMORY_MMAP:
628 if (0 == buf->baddr)
629 goto done;
630 break;
631 case V4L2_MEMORY_USERPTR:
632 if (b->length < buf->bsize)
633 goto done;
634 if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
635 q->ops->buf_release(q,buf);
636 buf->baddr = b->m.userptr;
637 break;
638 case V4L2_MEMORY_OVERLAY:
639 buf->boff = b->m.offset;
640 break;
641 default:
642 goto done;
643 }
644
645 field = videobuf_next_field(q);
646 retval = q->ops->buf_prepare(q,buf,field);
647 if (0 != retval)
648 goto done;
649
650 list_add_tail(&buf->stream,&q->stream);
651 if (q->streaming) {
652 spin_lock_irqsave(q->irqlock,flags);
653 q->ops->buf_queue(q,buf);
654 spin_unlock_irqrestore(q->irqlock,flags);
655 }
656 retval = 0;
657
658 done:
659 up(&q->lock);
660 return retval;
661}
662
663int
664videobuf_dqbuf(struct videobuf_queue *q,
665 struct v4l2_buffer *b, int nonblocking)
666{
667 struct videobuf_buffer *buf;
668 int retval;
669
670 down(&q->lock);
671 retval = -EBUSY;
672 if (q->reading)
673 goto done;
674 retval = -EINVAL;
675 if (b->type != q->type)
676 goto done;
677 if (list_empty(&q->stream))
678 goto done;
679 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
680 retval = videobuf_waiton(buf, nonblocking, 1);
681 if (retval < 0)
682 goto done;
683 switch (buf->state) {
684 case STATE_ERROR:
685 retval = -EIO;
686 /* fall through */
687 case STATE_DONE:
688 videobuf_dma_pci_sync(q->pci,&buf->dma);
689 buf->state = STATE_IDLE;
690 break;
691 default:
692 retval = -EINVAL;
693 goto done;
694 }
695 list_del(&buf->stream);
696 memset(b,0,sizeof(*b));
697 videobuf_status(b,buf,q->type);
698
699 done:
700 up(&q->lock);
701 return retval;
702}
703
704int videobuf_streamon(struct videobuf_queue *q)
705{
706 struct videobuf_buffer *buf;
707 struct list_head *list;
708 unsigned long flags;
709 int retval;
710
711 down(&q->lock);
712 retval = -EBUSY;
713 if (q->reading)
714 goto done;
715 retval = 0;
716 if (q->streaming)
717 goto done;
718 q->streaming = 1;
719 spin_lock_irqsave(q->irqlock,flags);
720 list_for_each(list,&q->stream) {
721 buf = list_entry(list, struct videobuf_buffer, stream);
722 if (buf->state == STATE_PREPARED)
723 q->ops->buf_queue(q,buf);
724 }
725 spin_unlock_irqrestore(q->irqlock,flags);
726
727 done:
728 up(&q->lock);
729 return retval;
730}
731
732int videobuf_streamoff(struct videobuf_queue *q)
733{
734 int retval = -EINVAL;
735
736 down(&q->lock);
737 if (!q->streaming)
738 goto done;
739 videobuf_queue_cancel(q);
740 q->streaming = 0;
741 retval = 0;
742
743 done:
744 up(&q->lock);
745 return retval;
746}
747
748static ssize_t
749videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750 size_t count, loff_t *ppos)
751{
752 enum v4l2_field field;
753 unsigned long flags;
754 int retval;
755
756 /* setup stuff */
757 retval = -ENOMEM;
758 q->read_buf = videobuf_alloc(q->msize);
759 if (NULL == q->read_buf)
760 goto done;
761
762 q->read_buf->memory = V4L2_MEMORY_USERPTR;
763 q->read_buf->baddr = (unsigned long)data;
764 q->read_buf->bsize = count;
765 field = videobuf_next_field(q);
766 retval = q->ops->buf_prepare(q,q->read_buf,field);
767 if (0 != retval)
768 goto done;
769
770 /* start capture & wait */
771 spin_lock_irqsave(q->irqlock,flags);
772 q->ops->buf_queue(q,q->read_buf);
773 spin_unlock_irqrestore(q->irqlock,flags);
774 retval = videobuf_waiton(q->read_buf,0,0);
775 if (0 == retval) {
776 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
777 if (STATE_ERROR == q->read_buf->state)
778 retval = -EIO;
779 else
780 retval = q->read_buf->size;
781 }
782
783 done:
784 /* cleanup */
785 q->ops->buf_release(q,q->read_buf);
786 kfree(q->read_buf);
787 q->read_buf = NULL;
788 return retval;
789}
790
791ssize_t videobuf_read_one(struct videobuf_queue *q,
792 char __user *data, size_t count, loff_t *ppos,
793 int nonblocking)
794{
795 enum v4l2_field field;
796 unsigned long flags;
797 unsigned size, nbufs, bytes;
798 int retval;
799
800 down(&q->lock);
801
802 nbufs = 1; size = 0;
803 q->ops->buf_setup(q,&nbufs,&size);
804 if (NULL == q->read_buf &&
805 count >= size &&
806 !nonblocking) {
807 retval = videobuf_read_zerocopy(q,data,count,ppos);
808 if (retval >= 0 || retval == -EIO)
809 /* ok, all done */
810 goto done;
811 /* fallback to kernel bounce buffer on failures */
812 }
813
814 if (NULL == q->read_buf) {
815 /* need to capture a new frame */
816 retval = -ENOMEM;
817 q->read_buf = videobuf_alloc(q->msize);
818 if (NULL == q->read_buf)
819 goto done;
820 q->read_buf->memory = V4L2_MEMORY_USERPTR;
821 field = videobuf_next_field(q);
822 retval = q->ops->buf_prepare(q,q->read_buf,field);
823 if (0 != retval)
824 goto done;
825 spin_lock_irqsave(q->irqlock,flags);
826 q->ops->buf_queue(q,q->read_buf);
827 spin_unlock_irqrestore(q->irqlock,flags);
828 q->read_off = 0;
829 }
830
831 /* wait until capture is done */
832 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
833 if (0 != retval)
834 goto done;
835 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
836
837 if (STATE_ERROR == q->read_buf->state) {
838 /* catch I/O errors */
839 q->ops->buf_release(q,q->read_buf);
840 kfree(q->read_buf);
841 q->read_buf = NULL;
842 retval = -EIO;
843 goto done;
844 }
845
846 /* copy to userspace */
847 bytes = count;
848 if (bytes > q->read_buf->size - q->read_off)
849 bytes = q->read_buf->size - q->read_off;
850 retval = -EFAULT;
851 if (copy_to_user(data, q->read_buf->dma.vmalloc+q->read_off, bytes))
852 goto done;
853
854 retval = bytes;
855 q->read_off += bytes;
856 if (q->read_off == q->read_buf->size) {
857 /* all data copied, cleanup */
858 q->ops->buf_release(q,q->read_buf);
859 kfree(q->read_buf);
860 q->read_buf = NULL;
861 }
862
863 done:
864 up(&q->lock);
865 return retval;
866}
867
868int videobuf_read_start(struct videobuf_queue *q)
869{
870 enum v4l2_field field;
871 unsigned long flags;
872 int count = 0, size = 0;
873 int err, i;
874
875 q->ops->buf_setup(q,&count,&size);
876 if (count < 2)
877 count = 2;
878 if (count > VIDEO_MAX_FRAME)
879 count = VIDEO_MAX_FRAME;
880 size = PAGE_ALIGN(size);
881
882 err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
883 if (err)
884 return err;
885 for (i = 0; i < count; i++) {
886 field = videobuf_next_field(q);
887 err = q->ops->buf_prepare(q,q->bufs[i],field);
888 if (err)
889 return err;
890 list_add_tail(&q->bufs[i]->stream, &q->stream);
891 }
892 spin_lock_irqsave(q->irqlock,flags);
893 for (i = 0; i < count; i++)
894 q->ops->buf_queue(q,q->bufs[i]);
895 spin_unlock_irqrestore(q->irqlock,flags);
896 q->reading = 1;
897 return 0;
898}
899
900void videobuf_read_stop(struct videobuf_queue *q)
901{
902 int i;
903
904 videobuf_queue_cancel(q);
905 videobuf_mmap_free(q);
906 INIT_LIST_HEAD(&q->stream);
907 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
908 if (NULL == q->bufs[i])
909 continue;
910 kfree(q->bufs[i]);
911 q->bufs[i] = NULL;
912 }
913 q->read_buf = NULL;
914 q->reading = 0;
915}
916
917ssize_t videobuf_read_stream(struct videobuf_queue *q,
918 char __user *data, size_t count, loff_t *ppos,
919 int vbihack, int nonblocking)
920{
921 unsigned int *fc, bytes;
922 int err, retval;
923 unsigned long flags;
924
925 dprintk(2,"%s\n",__FUNCTION__);
926 down(&q->lock);
927 retval = -EBUSY;
928 if (q->streaming)
929 goto done;
930 if (!q->reading) {
931 retval = videobuf_read_start(q);
932 if (retval < 0)
933 goto done;
934 }
935
936 retval = 0;
937 while (count > 0) {
938 /* get / wait for data */
939 if (NULL == q->read_buf) {
940 q->read_buf = list_entry(q->stream.next,
941 struct videobuf_buffer,
942 stream);
943 list_del(&q->read_buf->stream);
944 q->read_off = 0;
945 }
946 err = videobuf_waiton(q->read_buf, nonblocking, 1);
947 if (err < 0) {
948 if (0 == retval)
949 retval = err;
950 break;
951 }
952
953 if (q->read_buf->state == STATE_DONE) {
954 if (vbihack) {
955 /* dirty, undocumented hack -- pass the frame counter
956 * within the last four bytes of each vbi data block.
957 * We need that one to maintain backward compatibility
958 * to all vbi decoding software out there ... */
959 fc = (unsigned int*)q->read_buf->dma.vmalloc;
960 fc += (q->read_buf->size>>2) -1;
961 *fc = q->read_buf->field_count >> 1;
962 dprintk(1,"vbihack: %d\n",*fc);
963 }
964
965 /* copy stuff */
966 bytes = count;
967 if (bytes > q->read_buf->size - q->read_off)
968 bytes = q->read_buf->size - q->read_off;
969 if (copy_to_user(data + retval,
970 q->read_buf->dma.vmalloc + q->read_off,
971 bytes)) {
972 if (0 == retval)
973 retval = -EFAULT;
974 break;
975 }
976 count -= bytes;
977 retval += bytes;
978 q->read_off += bytes;
979 } else {
980 /* some error */
981 q->read_off = q->read_buf->size;
982 if (0 == retval)
983 retval = -EIO;
984 }
985
986 /* requeue buffer when done with copying */
987 if (q->read_off == q->read_buf->size) {
988 list_add_tail(&q->read_buf->stream,
989 &q->stream);
990 spin_lock_irqsave(q->irqlock,flags);
991 q->ops->buf_queue(q,q->read_buf);
992 spin_unlock_irqrestore(q->irqlock,flags);
993 q->read_buf = NULL;
994 }
995 if (retval < 0)
996 break;
997 }
998
999 done:
1000 up(&q->lock);
1001 return retval;
1002}
1003
1004unsigned int videobuf_poll_stream(struct file *file,
1005 struct videobuf_queue *q,
1006 poll_table *wait)
1007{
1008 struct videobuf_buffer *buf = NULL;
1009 unsigned int rc = 0;
1010
1011 down(&q->lock);
1012 if (q->streaming) {
1013 if (!list_empty(&q->stream))
1014 buf = list_entry(q->stream.next,
1015 struct videobuf_buffer, stream);
1016 } else {
1017 if (!q->reading)
1018 videobuf_read_start(q);
1019 if (!q->reading) {
1020 rc = POLLERR;
1021 } else if (NULL == q->read_buf) {
1022 q->read_buf = list_entry(q->stream.next,
1023 struct videobuf_buffer,
1024 stream);
1025 list_del(&q->read_buf->stream);
1026 q->read_off = 0;
1027 }
1028 buf = q->read_buf;
1029 }
1030 if (!buf)
1031 rc = POLLERR;
1032
1033 if (0 == rc) {
1034 poll_wait(file, &buf->done, wait);
1035 if (buf->state == STATE_DONE ||
1036 buf->state == STATE_ERROR)
1037 rc = POLLIN|POLLRDNORM;
1038 }
1039 up(&q->lock);
1040 return rc;
1041}
1042
1043/* --------------------------------------------------------------------- */
1044
1045static void
1046videobuf_vm_open(struct vm_area_struct *vma)
1047{
1048 struct videobuf_mapping *map = vma->vm_private_data;
1049
1050 dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
1051 map->count,vma->vm_start,vma->vm_end);
1052 map->count++;
1053}
1054
1055static void
1056videobuf_vm_close(struct vm_area_struct *vma)
1057{
1058 struct videobuf_mapping *map = vma->vm_private_data;
1059 struct videobuf_queue *q = map->q;
1060 int i;
1061
1062 dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
1063 map->count,vma->vm_start,vma->vm_end);
1064
1065 map->count--;
1066 if (0 == map->count) {
1067 dprintk(1,"munmap %p q=%p\n",map,q);
1068 down(&q->lock);
1069 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1070 if (NULL == q->bufs[i])
1071 continue;
1072 if (q->bufs[i])
1073 ;
1074 if (q->bufs[i]->map != map)
1075 continue;
1076 q->bufs[i]->map = NULL;
1077 q->bufs[i]->baddr = 0;
1078 q->ops->buf_release(q,q->bufs[i]);
1079 }
1080 up(&q->lock);
1081 kfree(map);
1082 }
1083 return;
1084}
1085
1086/*
1087 * Get a anonymous page for the mapping. Make sure we can DMA to that
1088 * memory location with 32bit PCI devices (i.e. don't use highmem for
1089 * now ...). Bounce buffers don't work very well for the data rates
1090 * video capture has.
1091 */
1092static struct page*
1093videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1094 int *type)
1095{
1096 struct page *page;
1097
1098 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1099 vaddr,vma->vm_start,vma->vm_end);
1100 if (vaddr > vma->vm_end)
1101 return NOPAGE_SIGBUS;
1102 page = alloc_page(GFP_USER);
1103 if (!page)
1104 return NOPAGE_OOM;
1105 clear_user_page(page_address(page), vaddr, page);
1106 if (type)
1107 *type = VM_FAULT_MINOR;
1108 return page;
1109}
1110
1111static struct vm_operations_struct videobuf_vm_ops =
1112{
1113 .open = videobuf_vm_open,
1114 .close = videobuf_vm_close,
1115 .nopage = videobuf_vm_nopage,
1116};
1117
1118int videobuf_mmap_setup(struct videobuf_queue *q,
1119 unsigned int bcount, unsigned int bsize,
1120 enum v4l2_memory memory)
1121{
1122 unsigned int i;
1123 int err;
1124
1125 err = videobuf_mmap_free(q);
1126 if (0 != err)
1127 return err;
1128
1129 for (i = 0; i < bcount; i++) {
1130 q->bufs[i] = videobuf_alloc(q->msize);
1131 q->bufs[i]->i = i;
1132 q->bufs[i]->input = UNSET;
1133 q->bufs[i]->memory = memory;
1134 q->bufs[i]->bsize = bsize;
1135 switch (memory) {
1136 case V4L2_MEMORY_MMAP:
1137 q->bufs[i]->boff = bsize * i;
1138 break;
1139 case V4L2_MEMORY_USERPTR:
1140 case V4L2_MEMORY_OVERLAY:
1141 /* nothing */
1142 break;
1143 }
1144 }
1145 dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
1146 bcount,bsize);
1147 return 0;
1148}
1149
1150int videobuf_mmap_free(struct videobuf_queue *q)
1151{
1152 int i;
1153
1154 for (i = 0; i < VIDEO_MAX_FRAME; i++)
1155 if (q->bufs[i] && q->bufs[i]->map)
1156 return -EBUSY;
1157 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1158 if (NULL == q->bufs[i])
1159 continue;
1160 q->ops->buf_release(q,q->bufs[i]);
1161 kfree(q->bufs[i]);
1162 q->bufs[i] = NULL;
1163 }
1164 return 0;
1165}
1166
1167int videobuf_mmap_mapper(struct videobuf_queue *q,
1168 struct vm_area_struct *vma)
1169{
1170 struct videobuf_mapping *map;
1171 unsigned int first,last,size,i;
1172 int retval;
1173
1174 down(&q->lock);
1175 retval = -EINVAL;
1176 if (!(vma->vm_flags & VM_WRITE)) {
1177 dprintk(1,"mmap app bug: PROT_WRITE please\n");
1178 goto done;
1179 }
1180 if (!(vma->vm_flags & VM_SHARED)) {
1181 dprintk(1,"mmap app bug: MAP_SHARED please\n");
1182 goto done;
1183 }
1184
1185 /* look for first buffer to map */
1186 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
1187 if (NULL == q->bufs[first])
1188 continue;
1189 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
1190 continue;
1191 if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1192 break;
1193 }
1194 if (VIDEO_MAX_FRAME == first) {
1195 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
1196 (vma->vm_pgoff << PAGE_SHIFT));
1197 goto done;
1198 }
1199
1200 /* look for last buffer to map */
1201 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
1202 if (NULL == q->bufs[last])
1203 continue;
1204 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
1205 continue;
1206 if (q->bufs[last]->map) {
1207 retval = -EBUSY;
1208 goto done;
1209 }
1210 size += q->bufs[last]->bsize;
1211 if (size == (vma->vm_end - vma->vm_start))
1212 break;
1213 }
1214 if (VIDEO_MAX_FRAME == last) {
1215 dprintk(1,"mmap app bug: size invalid [size=0x%lx]\n",
1216 (vma->vm_end - vma->vm_start));
1217 goto done;
1218 }
1219
1220 /* create mapping + update buffer list */
1221 retval = -ENOMEM;
1222 map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
1223 if (NULL == map)
1224 goto done;
1225 for (size = 0, i = first; i <= last; size += q->bufs[i++]->bsize) {
1226 q->bufs[i]->map = map;
1227 q->bufs[i]->baddr = vma->vm_start + size;
1228 }
1229 map->count = 1;
1230 map->start = vma->vm_start;
1231 map->end = vma->vm_end;
1232 map->q = q;
1233 vma->vm_ops = &videobuf_vm_ops;
1234 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
1235 vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
1236 vma->vm_private_data = map;
1237 dprintk(1,"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
1238 map,q,vma->vm_start,vma->vm_end,vma->vm_pgoff,first,last);
1239 retval = 0;
1240
1241 done:
1242 up(&q->lock);
1243 return retval;
1244}
1245
1246/* --------------------------------------------------------------------- */
1247
1248EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
1249
1250EXPORT_SYMBOL_GPL(videobuf_dma_init);
1251EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
1252EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
1253EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
1254EXPORT_SYMBOL_GPL(videobuf_dma_pci_map);
1255EXPORT_SYMBOL_GPL(videobuf_dma_pci_sync);
1256EXPORT_SYMBOL_GPL(videobuf_dma_pci_unmap);
1257EXPORT_SYMBOL_GPL(videobuf_dma_free);
1258
1259EXPORT_SYMBOL_GPL(videobuf_alloc);
1260EXPORT_SYMBOL_GPL(videobuf_waiton);
1261EXPORT_SYMBOL_GPL(videobuf_iolock);
1262
1263EXPORT_SYMBOL_GPL(videobuf_queue_init);
1264EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
1265EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
1266
1267EXPORT_SYMBOL_GPL(videobuf_next_field);
1268EXPORT_SYMBOL_GPL(videobuf_status);
1269EXPORT_SYMBOL_GPL(videobuf_reqbufs);
1270EXPORT_SYMBOL_GPL(videobuf_querybuf);
1271EXPORT_SYMBOL_GPL(videobuf_qbuf);
1272EXPORT_SYMBOL_GPL(videobuf_dqbuf);
1273EXPORT_SYMBOL_GPL(videobuf_streamon);
1274EXPORT_SYMBOL_GPL(videobuf_streamoff);
1275
1276EXPORT_SYMBOL_GPL(videobuf_read_start);
1277EXPORT_SYMBOL_GPL(videobuf_read_stop);
1278EXPORT_SYMBOL_GPL(videobuf_read_stream);
1279EXPORT_SYMBOL_GPL(videobuf_read_one);
1280EXPORT_SYMBOL_GPL(videobuf_poll_stream);
1281
1282EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
1283EXPORT_SYMBOL_GPL(videobuf_mmap_free);
1284EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
1285
1286/*
1287 * Local variables:
1288 * c-basic-offset: 8
1289 * End:
1290 */
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
new file mode 100644
index 000000000000..c9d5f1a873cc
--- /dev/null
+++ b/drivers/media/video/videocodec.c
@@ -0,0 +1,490 @@
1/*
2 * VIDEO MOTION CODECs internal API for video devices
3 *
4 * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
5 * bound to a master device.
6 *
7 * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
8 *
9 * $Id: videocodec.c,v 1.1.2.8 2003/03/29 07:16:04 rbultje Exp $
10 *
11 * ------------------------------------------------------------------------
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * ------------------------------------------------------------------------
28 */
29
30#define VIDEOCODEC_VERSION "v0.2"
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/types.h>
36#include <linux/slab.h>
37
38// kernel config is here (procfs flag)
39#include <linux/config.h>
40
41#ifdef CONFIG_PROC_FS
42#include <linux/proc_fs.h>
43#include <asm/uaccess.h>
44#endif
45
46#include "videocodec.h"
47
48static int debug = 0;
49module_param(debug, int, 0);
50MODULE_PARM_DESC(debug, "Debug level (0-4)");
51
52#define dprintk(num, format, args...) \
53 do { \
54 if (debug >= num) \
55 printk(format, ##args); \
56 } while (0)
57
58struct attached_list {
59 struct videocodec *codec;
60 struct attached_list *next;
61};
62
63struct codec_list {
64 const struct videocodec *codec;
65 int attached;
66 struct attached_list *list;
67 struct codec_list *next;
68};
69
70static struct codec_list *codeclist_top = NULL;
71
72/* ================================================= */
73/* function prototypes of the master/slave interface */
74/* ================================================= */
75
76struct videocodec *
77videocodec_attach (struct videocodec_master *master)
78{
79 struct codec_list *h = codeclist_top;
80 struct attached_list *a, *ptr;
81 struct videocodec *codec;
82 int res;
83
84 if (!master) {
85 dprintk(1, KERN_ERR "videocodec_attach: no data\n");
86 return NULL;
87 }
88
89 dprintk(2,
90 "videocodec_attach: '%s', type: %x, flags %lx, magic %lx\n",
91 master->name, master->type, master->flags, master->magic);
92
93 if (!h) {
94 dprintk(1,
95 KERN_ERR
96 "videocodec_attach: no device available\n");
97 return NULL;
98 }
99
100 while (h) {
101 // attach only if the slave has at least the flags
102 // expected by the master
103 if ((master->flags & h->codec->flags) == master->flags) {
104 dprintk(4, "videocodec_attach: try '%s'\n",
105 h->codec->name);
106
107 if (!try_module_get(h->codec->owner))
108 return NULL;
109
110 codec =
111 kmalloc(sizeof(struct videocodec), GFP_KERNEL);
112 if (!codec) {
113 dprintk(1,
114 KERN_ERR
115 "videocodec_attach: no mem\n");
116 goto out_module_put;
117 }
118 memcpy(codec, h->codec, sizeof(struct videocodec));
119
120 snprintf(codec->name, sizeof(codec->name),
121 "%s[%d]", codec->name, h->attached);
122 codec->master_data = master;
123 res = codec->setup(codec);
124 if (res == 0) {
125 dprintk(3, "videocodec_attach '%s'\n",
126 codec->name);
127 ptr = (struct attached_list *)
128 kmalloc(sizeof(struct attached_list),
129 GFP_KERNEL);
130 if (!ptr) {
131 dprintk(1,
132 KERN_ERR
133 "videocodec_attach: no memory\n");
134 goto out_kfree;
135 }
136 memset(ptr, 0,
137 sizeof(struct attached_list));
138 ptr->codec = codec;
139
140 a = h->list;
141 if (!a) {
142 h->list = ptr;
143 dprintk(4,
144 "videocodec: first element\n");
145 } else {
146 while (a->next)
147 a = a->next; // find end
148 a->next = ptr;
149 dprintk(4,
150 "videocodec: in after '%s'\n",
151 h->codec->name);
152 }
153
154 h->attached += 1;
155 return codec;
156 } else {
157 kfree(codec);
158 }
159 }
160 h = h->next;
161 }
162
163 dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n");
164 return NULL;
165
166 out_module_put:
167 module_put(h->codec->owner);
168 out_kfree:
169 kfree(codec);
170 return NULL;
171}
172
173int
174videocodec_detach (struct videocodec *codec)
175{
176 struct codec_list *h = codeclist_top;
177 struct attached_list *a, *prev;
178 int res;
179
180 if (!codec) {
181 dprintk(1, KERN_ERR "videocodec_detach: no data\n");
182 return -EINVAL;
183 }
184
185 dprintk(2,
186 "videocodec_detach: '%s', type: %x, flags %lx, magic %lx\n",
187 codec->name, codec->type, codec->flags, codec->magic);
188
189 if (!h) {
190 dprintk(1,
191 KERN_ERR "videocodec_detach: no device left...\n");
192 return -ENXIO;
193 }
194
195 while (h) {
196 a = h->list;
197 prev = NULL;
198 while (a) {
199 if (codec == a->codec) {
200 res = a->codec->unset(a->codec);
201 if (res >= 0) {
202 dprintk(3,
203 "videocodec_detach: '%s'\n",
204 a->codec->name);
205 a->codec->master_data = NULL;
206 } else {
207 dprintk(1,
208 KERN_ERR
209 "videocodec_detach: '%s'\n",
210 a->codec->name);
211 a->codec->master_data = NULL;
212 }
213 if (prev == NULL) {
214 h->list = a->next;
215 dprintk(4,
216 "videocodec: delete first\n");
217 } else {
218 prev->next = a->next;
219 dprintk(4,
220 "videocodec: delete middle\n");
221 }
222 module_put(a->codec->owner);
223 kfree(a->codec);
224 kfree(a);
225 h->attached -= 1;
226 return 0;
227 }
228 prev = a;
229 a = a->next;
230 }
231 h = h->next;
232 }
233
234 dprintk(1, KERN_ERR "videocodec_detach: given codec not found!\n");
235 return -EINVAL;
236}
237
238int
239videocodec_register (const struct videocodec *codec)
240{
241 struct codec_list *ptr, *h = codeclist_top;
242
243 if (!codec) {
244 dprintk(1, KERN_ERR "videocodec_register: no data!\n");
245 return -EINVAL;
246 }
247
248 dprintk(2,
249 "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
250 codec->name, codec->type, codec->flags, codec->magic);
251
252 ptr =
253 (struct codec_list *) kmalloc(sizeof(struct codec_list),
254 GFP_KERNEL);
255 if (!ptr) {
256 dprintk(1, KERN_ERR "videocodec_register: no memory\n");
257 return -ENOMEM;
258 }
259 memset(ptr, 0, sizeof(struct codec_list));
260 ptr->codec = codec;
261
262 if (!h) {
263 codeclist_top = ptr;
264 dprintk(4, "videocodec: hooked in as first element\n");
265 } else {
266 while (h->next)
267 h = h->next; // find the end
268 h->next = ptr;
269 dprintk(4, "videocodec: hooked in after '%s'\n",
270 h->codec->name);
271 }
272
273 return 0;
274}
275
276int
277videocodec_unregister (const struct videocodec *codec)
278{
279 struct codec_list *prev = NULL, *h = codeclist_top;
280
281 if (!codec) {
282 dprintk(1, KERN_ERR "videocodec_unregister: no data!\n");
283 return -EINVAL;
284 }
285
286 dprintk(2,
287 "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
288 codec->name, codec->type, codec->flags, codec->magic);
289
290 if (!h) {
291 dprintk(1,
292 KERN_ERR
293 "videocodec_unregister: no device left...\n");
294 return -ENXIO;
295 }
296
297 while (h) {
298 if (codec == h->codec) {
299 if (h->attached) {
300 dprintk(1,
301 KERN_ERR
302 "videocodec: '%s' is used\n",
303 h->codec->name);
304 return -EBUSY;
305 }
306 dprintk(3, "videocodec: unregister '%s' is ok.\n",
307 h->codec->name);
308 if (prev == NULL) {
309 codeclist_top = h->next;
310 dprintk(4,
311 "videocodec: delete first element\n");
312 } else {
313 prev->next = h->next;
314 dprintk(4,
315 "videocodec: delete middle element\n");
316 }
317 kfree(h);
318 return 0;
319 }
320 prev = h;
321 h = h->next;
322 }
323
324 dprintk(1,
325 KERN_ERR
326 "videocodec_unregister: given codec not found!\n");
327 return -EINVAL;
328}
329
330#ifdef CONFIG_PROC_FS
331/* ============ */
332/* procfs stuff */
333/* ============ */
334
335static char *videocodec_buf = NULL;
336static int videocodec_bufsize = 0;
337
338static int
339videocodec_build_table (void)
340{
341 struct codec_list *h = codeclist_top;
342 struct attached_list *a;
343 int i = 0, size;
344
345 // sum up amount of slaves plus their attached masters
346 while (h) {
347 i += h->attached + 1;
348 h = h->next;
349 }
350#define LINESIZE 100
351 size = LINESIZE * (i + 1);
352
353 dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
354 size);
355
356 if (videocodec_buf)
357 kfree(videocodec_buf);
358 videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
359
360 i = 0;
361 i += scnprintf(videocodec_buf + i, size - 1,
362 "<S>lave or attached <M>aster name type flags magic ");
363 i += scnprintf(videocodec_buf + i, size -i - 1, "(connected as)\n");
364
365 h = codeclist_top;
366 while (h) {
367 if (i > (size - LINESIZE))
368 break; // security check
369 i += scnprintf(videocodec_buf + i, size -i -1,
370 "S %32s %04x %08lx %08lx (TEMPLATE)\n",
371 h->codec->name, h->codec->type,
372 h->codec->flags, h->codec->magic);
373 a = h->list;
374 while (a) {
375 if (i > (size - LINESIZE))
376 break; // security check
377 i += scnprintf(videocodec_buf + i, size -i -1,
378 "M %32s %04x %08lx %08lx (%s)\n",
379 a->codec->master_data->name,
380 a->codec->master_data->type,
381 a->codec->master_data->flags,
382 a->codec->master_data->magic,
383 a->codec->name);
384 a = a->next;
385 }
386 h = h->next;
387 }
388
389 return i;
390}
391
392//The definition:
393//typedef int (read_proc_t)(char *page, char **start, off_t off,
394// int count, int *eof, void *data);
395
396static int
397videocodec_info (char *buffer,
398 char **buffer_location,
399 off_t offset,
400 int buffer_length,
401 int *eof,
402 void *data)
403{
404 int size;
405
406 dprintk(3, "videocodec_info: offset: %ld, len %d / size %d\n",
407 offset, buffer_length, videocodec_bufsize);
408
409 if (offset == 0) {
410 videocodec_bufsize = videocodec_build_table();
411 }
412 if ((offset < 0) || (offset >= videocodec_bufsize)) {
413 dprintk(4,
414 "videocodec_info: call delivers no result, return 0\n");
415 *eof = 1;
416 return 0;
417 }
418
419 if (buffer_length < (videocodec_bufsize - offset)) {
420 dprintk(4, "videocodec_info: %ld needed, %d got\n",
421 videocodec_bufsize - offset, buffer_length);
422 size = buffer_length;
423 } else {
424 dprintk(4, "videocodec_info: last reading of %ld bytes\n",
425 videocodec_bufsize - offset);
426 size = videocodec_bufsize - offset;
427 *eof = 1;
428 }
429
430 memcpy(buffer, videocodec_buf + offset, size);
431 /* doesn't work... */
432 /* copy_to_user(buffer, videocodec_buf+offset, size); */
433 /* *buffer_location = videocodec_buf+offset; */
434
435 return size;
436}
437#endif
438
439/* ===================== */
440/* hook in driver module */
441/* ===================== */
442static int __init
443videocodec_init (void)
444{
445#ifdef CONFIG_PROC_FS
446 static struct proc_dir_entry *videocodec_proc_entry;
447#endif
448
449 printk(KERN_INFO "Linux video codec intermediate layer: %s\n",
450 VIDEOCODEC_VERSION);
451
452#ifdef CONFIG_PROC_FS
453 videocodec_buf = NULL;
454 videocodec_bufsize = 0;
455
456 videocodec_proc_entry = create_proc_entry("videocodecs", 0, NULL);
457 if (videocodec_proc_entry) {
458 videocodec_proc_entry->read_proc = videocodec_info;
459 videocodec_proc_entry->write_proc = NULL;
460 videocodec_proc_entry->data = NULL;
461 videocodec_proc_entry->owner = THIS_MODULE;
462 } else {
463 dprintk(1, KERN_ERR "videocodec: can't init procfs.\n");
464 }
465#endif
466 return 0;
467}
468
469static void __exit
470videocodec_exit (void)
471{
472#ifdef CONFIG_PROC_FS
473 remove_proc_entry("videocodecs", NULL);
474 if (videocodec_buf)
475 kfree(videocodec_buf);
476#endif
477}
478
479EXPORT_SYMBOL(videocodec_attach);
480EXPORT_SYMBOL(videocodec_detach);
481EXPORT_SYMBOL(videocodec_register);
482EXPORT_SYMBOL(videocodec_unregister);
483
484module_init(videocodec_init);
485module_exit(videocodec_exit);
486
487MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
488MODULE_DESCRIPTION("Intermediate API module for video codecs "
489 VIDEOCODEC_VERSION);
490MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h
new file mode 100644
index 000000000000..156ae57096fe
--- /dev/null
+++ b/drivers/media/video/videocodec.h
@@ -0,0 +1,358 @@
1/*
2 * VIDEO MOTION CODECs internal API for video devices
3 *
4 * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
5 * bound to a master device.
6 *
7 * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
8 *
9 * $Id: videocodec.h,v 1.1.2.4 2003/01/14 21:15:03 rbultje Exp $
10 *
11 * ------------------------------------------------------------------------
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * ------------------------------------------------------------------------
28 */
29
30/* =================== */
31/* general description */
32/* =================== */
33
34/* Should ease the (re-)usage of drivers supporting cards with (different)
35 video codecs. The codecs register to this module their functionality,
36 and the processors (masters) can attach to them if they fit.
37
38 The codecs are typically have a "strong" binding to their master - so I
39 don't think it makes sense to have a full blown interfacing as with e.g.
40 i2c. If you have an other opinion, let's discuss & implement it :-)))
41
42 Usage:
43
44 The slave has just to setup the videocodec structure and use two functions:
45 videocodec_register(codecdata);
46 videocodec_unregister(codecdata);
47 The best is just calling them at module (de-)initialisation.
48
49 The master sets up the structure videocodec_master and calls:
50 codecdata=videocodec_attach(master_codecdata);
51 videocodec_detach(codecdata);
52
53 The slave is called during attach/detach via functions setup previously
54 during register. At that time, the master_data pointer is set up
55 and the slave can access any io registers of the master device (in the case
56 the slave is bound to it). Otherwise it doesn't need this functions and
57 therfor they may not be initialized.
58
59 The other fuctions are just for convenience, as they are for shure used by
60 most/all of the codecs. The last ones may be ommited, too.
61
62 See the structure declaration below for more information and which data has
63 to be set up for the master and the slave.
64
65 ----------------------------------------------------------------------------
66 The master should have "knowledge" of the slave and vice versa. So the data
67 structures sent to/from slave via set_data/get_data set_image/get_image are
68 device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
69 ----------------------------------------------------------------------------
70*/
71
72
73/* ========================================== */
74/* description of the videocodec_io structure */
75/* ========================================== */
76
77/*
78 ==== master setup ====
79 name -> name of the device structure for reference and debugging
80 master_data -> data ref. for the master (e.g. the zr36055,57,67)
81 readreg -> ref. to read-fn from register (setup by master, used by slave)
82 writereg -> ref. to write-fn to register (setup by master, used by slave)
83 this two functions do the lowlevel I/O job
84
85 ==== slave functionality setup ====
86 slave_data -> data ref. for the slave (e.g. the zr36050,60)
87 check -> fn-ref. checks availability of an device, returns -EIO on failure or
88 the type on success
89 this makes espcecially sense if a driver module supports more than
90 one codec which may be quite similar to access, nevertheless it
91 is good for a first functionality check
92
93 -- main functions you always need for compression/decompression --
94
95 set_mode -> this fn-ref. resets the entire codec, and sets up the mode
96 with the last defined norm/size (or device default if not
97 available) - it returns 0 if the mode is possible
98 set_size -> this fn-ref. sets the norm and image size for
99 compression/decompression (returns 0 on success)
100 the norm param is defined in videodev.h (VIDEO_MODE_*)
101
102 additional setup may be available, too - but the codec should work with
103 some default values even without this
104
105 set_data -> sets device-specific data (tables, quality etc.)
106 get_data -> query device-specific data (tables, quality etc.)
107
108 if the device delivers interrupts, they may be setup/handled here
109 setup_interrupt -> codec irq setup (not needed for 36050/60)
110 handle_interrupt -> codec irq handling (not needed for 36050/60)
111
112 if the device delivers pictures, they may be handled here
113 put_image -> puts image data to the codec (not needed for 36050/60)
114 get_image -> gets image data from the codec (not needed for 36050/60)
115 the calls include frame numbers and flags (even/odd/...)
116 if needed and a flag which allows blocking until its ready
117*/
118
119/* ============== */
120/* user interface */
121/* ============== */
122
123/*
124 Currently there is only a information display planned, as the layer
125 is not visible for the user space at all.
126
127 Information is available via procfs. The current entry is "/proc/videocodecs"
128 but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
129
130A example for such an output is:
131
132<S>lave or attached <M>aster name type flags magic (connected as)
133S zr36050 0002 0000d001 00000000 (TEMPLATE)
134M zr36055[0] 0001 0000c001 00000000 (zr36050[0])
135M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
136
137*/
138
139
140/* =============================================== */
141/* special defines for the videocodec_io structure */
142/* =============================================== */
143
144#ifndef __LINUX_VIDEOCODEC_H
145#define __LINUX_VIDEOCODEC_H
146
147#include <linux/videodev.h>
148
149//should be in videodev.h ??? (VID_DO_....)
150#define CODEC_DO_COMPRESSION 0
151#define CODEC_DO_EXPANSION 1
152
153/* this are the current codec flags I think they are needed */
154/* -> type value in structure */
155#define CODEC_FLAG_JPEG 0x00000001L // JPEG codec
156#define CODEC_FLAG_MPEG 0x00000002L // MPEG1/2/4 codec
157#define CODEC_FLAG_DIVX 0x00000004L // DIVX codec
158#define CODEC_FLAG_WAVELET 0x00000008L // WAVELET codec
159 // room for other types
160
161#define CODEC_FLAG_MAGIC 0x00000800L // magic key must match
162#define CODEC_FLAG_HARDWARE 0x00001000L // is a hardware codec
163#define CODEC_FLAG_VFE 0x00002000L // has direct video frontend
164#define CODEC_FLAG_ENCODER 0x00004000L // compression capability
165#define CODEC_FLAG_DECODER 0x00008000L // decompression capability
166#define CODEC_FLAG_NEEDIRQ 0x00010000L // needs irq handling
167#define CODEC_FLAG_RDWRPIC 0x00020000L // handles picture I/O
168
169/* a list of modes, some are just examples (is there any HW?) */
170#define CODEC_MODE_BJPG 0x0001 // Baseline JPEG
171#define CODEC_MODE_LJPG 0x0002 // Lossless JPEG
172#define CODEC_MODE_MPEG1 0x0003 // MPEG 1
173#define CODEC_MODE_MPEG2 0x0004 // MPEG 2
174#define CODEC_MODE_MPEG4 0x0005 // MPEG 4
175#define CODEC_MODE_MSDIVX 0x0006 // MS DivX
176#define CODEC_MODE_ODIVX 0x0007 // Open DivX
177#define CODEC_MODE_WAVELET 0x0008 // Wavelet
178
179/* this are the current codec types I want to implement */
180/* -> type value in structure */
181#define CODEC_TYPE_NONE 0
182#define CODEC_TYPE_L64702 1
183#define CODEC_TYPE_ZR36050 2
184#define CODEC_TYPE_ZR36016 3
185#define CODEC_TYPE_ZR36060 4
186
187/* the type of data may be enhanced by future implementations (data-fn.'s) */
188/* -> used in command */
189#define CODEC_G_STATUS 0x0000 /* codec status (query only) */
190#define CODEC_S_CODEC_MODE 0x0001 /* codec mode (baseline JPEG, MPEG1,... */
191#define CODEC_G_CODEC_MODE 0x8001
192#define CODEC_S_VFE 0x0002 /* additional video frontend setup */
193#define CODEC_G_VFE 0x8002
194#define CODEC_S_MMAP 0x0003 /* MMAP setup (if available) */
195
196#define CODEC_S_JPEG_TDS_BYTE 0x0010 /* target data size in bytes */
197#define CODEC_G_JPEG_TDS_BYTE 0x8010
198#define CODEC_S_JPEG_SCALE 0x0011 /* scaling factor for quant. tables */
199#define CODEC_G_JPEG_SCALE 0x8011
200#define CODEC_S_JPEG_HDT_DATA 0x0018 /* huffman-tables */
201#define CODEC_G_JPEG_HDT_DATA 0x8018
202#define CODEC_S_JPEG_QDT_DATA 0x0019 /* quantizing-tables */
203#define CODEC_G_JPEG_QDT_DATA 0x8019
204#define CODEC_S_JPEG_APP_DATA 0x001A /* APP marker */
205#define CODEC_G_JPEG_APP_DATA 0x801A
206#define CODEC_S_JPEG_COM_DATA 0x001B /* COM marker */
207#define CODEC_G_JPEG_COM_DATA 0x801B
208
209#define CODEC_S_PRIVATE 0x1000 /* "private" commands start here */
210#define CODEC_G_PRIVATE 0x9000
211
212#define CODEC_G_FLAG 0x8000 /* this is how 'get' is detected */
213
214/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
215/* -> used in get_image, put_image */
216#define CODEC_TRANSFER_KERNEL 0 /* use "memcopy" */
217#define CODEC_TRANSFER_USER 1 /* use "to/from_user" */
218
219
220/* ========================= */
221/* the structures itself ... */
222/* ========================= */
223
224struct vfe_polarity {
225 int vsync_pol:1;
226 int hsync_pol:1;
227 int field_pol:1;
228 int blank_pol:1;
229 int subimg_pol:1;
230 int poe_pol:1;
231 int pvalid_pol:1;
232 int vclk_pol:1;
233};
234
235struct vfe_settings {
236 __u32 x, y; /* Offsets into image */
237 __u32 width, height; /* Area to capture */
238 __u16 decimation; /* Decimation divider */
239 __u16 flags; /* Flags for capture */
240/* flags are the same as in struct video_capture - see videodev.h:
241#define VIDEO_CAPTURE_ODD 0
242#define VIDEO_CAPTURE_EVEN 1
243*/
244 __u16 quality; /* quality of the video */
245};
246
247struct tvnorm {
248 u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
249};
250
251struct jpeg_com_marker {
252 int len; /* number of usable bytes in data */
253 char data[60];
254};
255
256struct jpeg_app_marker {
257 int appn; /* number app segment */
258 int len; /* number of usable bytes in data */
259 char data[60];
260};
261
262struct videocodec {
263 struct module *owner;
264 /* -- filled in by slave device during register -- */
265 char name[32];
266 unsigned long magic; /* may be used for client<->master attaching */
267 unsigned long flags; /* functionality flags */
268 unsigned int type; /* codec type */
269
270 /* -- these is filled in later during master device attach -- */
271
272 struct videocodec_master *master_data;
273
274 /* -- these are filled in by the slave device during register -- */
275
276 void *data; /* private slave data */
277
278 /* attach/detach client functions (indirect call) */
279 int (*setup) (struct videocodec * codec);
280 int (*unset) (struct videocodec * codec);
281
282 /* main functions, every client needs them for sure! */
283 // set compression or decompression (or freeze, stop, standby, etc)
284 int (*set_mode) (struct videocodec * codec,
285 int mode);
286 // setup picture size and norm (for the codec's video frontend)
287 int (*set_video) (struct videocodec * codec,
288 struct tvnorm * norm,
289 struct vfe_settings * cap,
290 struct vfe_polarity * pol);
291 // other control commands, also mmap setup etc.
292 int (*control) (struct videocodec * codec,
293 int type,
294 int size,
295 void *data);
296
297 /* additional setup/query/processing (may be NULL pointer) */
298 // interrupt setup / handling (for irq's delivered by master)
299 int (*setup_interrupt) (struct videocodec * codec,
300 long mode);
301 int (*handle_interrupt) (struct videocodec * codec,
302 int source,
303 long flag);
304 // picture interface (if any)
305 long (*put_image) (struct videocodec * codec,
306 int tr_type,
307 int block,
308 long *fr_num,
309 long *flag,
310 long size,
311 void *buf);
312 long (*get_image) (struct videocodec * codec,
313 int tr_type,
314 int block,
315 long *fr_num,
316 long *flag,
317 long size,
318 void *buf);
319};
320
321struct videocodec_master {
322 /* -- filled in by master device for registration -- */
323 char name[32];
324 unsigned long magic; /* may be used for client<->master attaching */
325 unsigned long flags; /* functionality flags */
326 unsigned int type; /* master type */
327
328 void *data; /* private master data */
329
330 __u32(*readreg) (struct videocodec * codec,
331 __u16 reg);
332 void (*writereg) (struct videocodec * codec,
333 __u16 reg,
334 __u32 value);
335};
336
337
338/* ================================================= */
339/* function prototypes of the master/slave interface */
340/* ================================================= */
341
342/* attach and detach commands for the master */
343// * master structure needs to be kmalloc'ed before calling attach
344// and free'd after calling detach
345// * returns pointer on success, NULL on failure
346extern struct videocodec *videocodec_attach(struct videocodec_master *);
347// * 0 on success, <0 (errno) on failure
348extern int videocodec_detach(struct videocodec *);
349
350/* register and unregister commands for the slaves */
351// * 0 on success, <0 (errno) on failure
352extern int videocodec_register(const struct videocodec *);
353// * 0 on success, <0 (errno) on failure
354extern int videocodec_unregister(const struct videocodec *);
355
356/* the other calls are directly done via the videocodec structure! */
357
358#endif /*ifndef __LINUX_VIDEOCODEC_H */
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
new file mode 100644
index 000000000000..06df15f75de9
--- /dev/null
+++ b/drivers/media/video/videodev.c
@@ -0,0 +1,436 @@
1/*
2 * Video capture interface for Linux
3 *
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * Author: Alan Cox, <alan@redhat.com>
13 *
14 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
15 * - Added procfs support
16 */
17
18#include <linux/module.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/smp_lock.h>
23#include <linux/mm.h>
24#include <linux/string.h>
25#include <linux/errno.h>
26#include <linux/init.h>
27#include <linux/kmod.h>
28#include <linux/slab.h>
29#include <linux/devfs_fs_kernel.h>
30#include <asm/uaccess.h>
31#include <asm/system.h>
32#include <asm/semaphore.h>
33
34#include <linux/videodev.h>
35
36#define VIDEO_NUM_DEVICES 256
37#define VIDEO_NAME "video4linux"
38
39/*
40 * sysfs stuff
41 */
42
43static ssize_t show_name(struct class_device *cd, char *buf)
44{
45 struct video_device *vfd = container_of(cd, struct video_device, class_dev);
46 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
47}
48
49static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
50
51struct video_device *video_device_alloc(void)
52{
53 struct video_device *vfd;
54
55 vfd = kmalloc(sizeof(*vfd),GFP_KERNEL);
56 if (NULL == vfd)
57 return NULL;
58 memset(vfd,0,sizeof(*vfd));
59 return vfd;
60}
61
62void video_device_release(struct video_device *vfd)
63{
64 kfree(vfd);
65}
66
67static void video_release(struct class_device *cd)
68{
69 struct video_device *vfd = container_of(cd, struct video_device, class_dev);
70
71#if 1 /* needed until all drivers are fixed */
72 if (!vfd->release)
73 return;
74#endif
75 vfd->release(vfd);
76}
77
78static struct class video_class = {
79 .name = VIDEO_NAME,
80 .release = video_release,
81};
82
83/*
84 * Active devices
85 */
86
87static struct video_device *video_device[VIDEO_NUM_DEVICES];
88static DECLARE_MUTEX(videodev_lock);
89
90struct video_device* video_devdata(struct file *file)
91{
92 return video_device[iminor(file->f_dentry->d_inode)];
93}
94
95/*
96 * Open a video device.
97 */
98static int video_open(struct inode *inode, struct file *file)
99{
100 unsigned int minor = iminor(inode);
101 int err = 0;
102 struct video_device *vfl;
103 struct file_operations *old_fops;
104
105 if(minor>=VIDEO_NUM_DEVICES)
106 return -ENODEV;
107 down(&videodev_lock);
108 vfl=video_device[minor];
109 if(vfl==NULL) {
110 up(&videodev_lock);
111 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
112 down(&videodev_lock);
113 vfl=video_device[minor];
114 if (vfl==NULL) {
115 up(&videodev_lock);
116 return -ENODEV;
117 }
118 }
119 old_fops = file->f_op;
120 file->f_op = fops_get(vfl->fops);
121 if(file->f_op->open)
122 err = file->f_op->open(inode,file);
123 if (err) {
124 fops_put(file->f_op);
125 file->f_op = fops_get(old_fops);
126 }
127 fops_put(old_fops);
128 up(&videodev_lock);
129 return err;
130}
131
132/*
133 * helper function -- handles userspace copying for ioctl arguments
134 */
135
136static unsigned int
137video_fix_command(unsigned int cmd)
138{
139 switch (cmd) {
140 case VIDIOC_OVERLAY_OLD:
141 cmd = VIDIOC_OVERLAY;
142 break;
143 case VIDIOC_S_PARM_OLD:
144 cmd = VIDIOC_S_PARM;
145 break;
146 case VIDIOC_S_CTRL_OLD:
147 cmd = VIDIOC_S_CTRL;
148 break;
149 case VIDIOC_G_AUDIO_OLD:
150 cmd = VIDIOC_G_AUDIO;
151 break;
152 case VIDIOC_G_AUDOUT_OLD:
153 cmd = VIDIOC_G_AUDOUT;
154 break;
155 case VIDIOC_CROPCAP_OLD:
156 cmd = VIDIOC_CROPCAP;
157 break;
158 }
159 return cmd;
160}
161
162int
163video_usercopy(struct inode *inode, struct file *file,
164 unsigned int cmd, unsigned long arg,
165 int (*func)(struct inode *inode, struct file *file,
166 unsigned int cmd, void *arg))
167{
168 char sbuf[128];
169 void *mbuf = NULL;
170 void *parg = NULL;
171 int err = -EINVAL;
172
173 cmd = video_fix_command(cmd);
174
175 /* Copy arguments into temp kernel buffer */
176 switch (_IOC_DIR(cmd)) {
177 case _IOC_NONE:
178 parg = NULL;
179 break;
180 case _IOC_READ:
181 case _IOC_WRITE:
182 case (_IOC_WRITE | _IOC_READ):
183 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
184 parg = sbuf;
185 } else {
186 /* too big to allocate from stack */
187 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
188 if (NULL == mbuf)
189 return -ENOMEM;
190 parg = mbuf;
191 }
192
193 err = -EFAULT;
194 if (_IOC_DIR(cmd) & _IOC_WRITE)
195 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
196 goto out;
197 break;
198 }
199
200 /* call driver */
201 err = func(inode, file, cmd, parg);
202 if (err == -ENOIOCTLCMD)
203 err = -EINVAL;
204 if (err < 0)
205 goto out;
206
207 /* Copy results into user buffer */
208 switch (_IOC_DIR(cmd))
209 {
210 case _IOC_READ:
211 case (_IOC_WRITE | _IOC_READ):
212 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
213 err = -EFAULT;
214 break;
215 }
216
217out:
218 if (mbuf)
219 kfree(mbuf);
220 return err;
221}
222
223/*
224 * open/release helper functions -- handle exclusive opens
225 */
226int video_exclusive_open(struct inode *inode, struct file *file)
227{
228 struct video_device *vfl = video_devdata(file);
229 int retval = 0;
230
231 down(&vfl->lock);
232 if (vfl->users) {
233 retval = -EBUSY;
234 } else {
235 vfl->users++;
236 }
237 up(&vfl->lock);
238 return retval;
239}
240
241int video_exclusive_release(struct inode *inode, struct file *file)
242{
243 struct video_device *vfl = video_devdata(file);
244
245 vfl->users--;
246 return 0;
247}
248
249static struct file_operations video_fops;
250
251/**
252 * video_register_device - register video4linux devices
253 * @vfd: video device structure we want to register
254 * @type: type of device to register
255 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
256 * -1 == first free)
257 *
258 * The registration code assigns minor numbers based on the type
259 * requested. -ENFILE is returned in all the device slots for this
260 * category are full. If not then the minor field is set and the
261 * driver initialize function is called (if non %NULL).
262 *
263 * Zero is returned on success.
264 *
265 * Valid types are
266 *
267 * %VFL_TYPE_GRABBER - A frame grabber
268 *
269 * %VFL_TYPE_VTX - A teletext device
270 *
271 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
272 *
273 * %VFL_TYPE_RADIO - A radio card
274 */
275
276int video_register_device(struct video_device *vfd, int type, int nr)
277{
278 int i=0;
279 int base;
280 int end;
281 char *name_base;
282
283 switch(type)
284 {
285 case VFL_TYPE_GRABBER:
286 base=0;
287 end=64;
288 name_base = "video";
289 break;
290 case VFL_TYPE_VTX:
291 base=192;
292 end=224;
293 name_base = "vtx";
294 break;
295 case VFL_TYPE_VBI:
296 base=224;
297 end=240;
298 name_base = "vbi";
299 break;
300 case VFL_TYPE_RADIO:
301 base=64;
302 end=128;
303 name_base = "radio";
304 break;
305 default:
306 return -1;
307 }
308
309 /* pick a minor number */
310 down(&videodev_lock);
311 if (nr >= 0 && nr < end-base) {
312 /* use the one the driver asked for */
313 i = base+nr;
314 if (NULL != video_device[i]) {
315 up(&videodev_lock);
316 return -ENFILE;
317 }
318 } else {
319 /* use first free */
320 for(i=base;i<end;i++)
321 if (NULL == video_device[i])
322 break;
323 if (i == end) {
324 up(&videodev_lock);
325 return -ENFILE;
326 }
327 }
328 video_device[i]=vfd;
329 vfd->minor=i;
330 up(&videodev_lock);
331
332 sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
333 devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
334 S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
335 init_MUTEX(&vfd->lock);
336
337 /* sysfs class */
338 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
339 if (vfd->dev)
340 vfd->class_dev.dev = vfd->dev;
341 vfd->class_dev.class = &video_class;
342 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
343 strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
344 class_device_register(&vfd->class_dev);
345 class_device_create_file(&vfd->class_dev,
346 &class_device_attr_name);
347
348#if 1 /* needed until all drivers are fixed */
349 if (!vfd->release)
350 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
351 "Please fix your driver for proper sysfs support, see "
352 "http://lwn.net/Articles/36850/\n", vfd->name);
353#endif
354 return 0;
355}
356
357/**
358 * video_unregister_device - unregister a video4linux device
359 * @vfd: the device to unregister
360 *
361 * This unregisters the passed device and deassigns the minor
362 * number. Future open calls will be met with errors.
363 */
364
365void video_unregister_device(struct video_device *vfd)
366{
367 down(&videodev_lock);
368 if(video_device[vfd->minor]!=vfd)
369 panic("videodev: bad unregister");
370
371 devfs_remove(vfd->devfs_name);
372 video_device[vfd->minor]=NULL;
373 class_device_unregister(&vfd->class_dev);
374 up(&videodev_lock);
375}
376
377
378static struct file_operations video_fops=
379{
380 .owner = THIS_MODULE,
381 .llseek = no_llseek,
382 .open = video_open,
383};
384
385/*
386 * Initialise video for linux
387 */
388
389static int __init videodev_init(void)
390{
391 int ret;
392
393 printk(KERN_INFO "Linux video capture interface: v1.00\n");
394 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
395 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
396 return -EIO;
397 }
398
399 ret = class_register(&video_class);
400 if (ret < 0) {
401 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
402 printk(KERN_WARNING "video_dev: class_register failed\n");
403 return -EIO;
404 }
405
406 return 0;
407}
408
409static void __exit videodev_exit(void)
410{
411 class_unregister(&video_class);
412 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
413}
414
415module_init(videodev_init)
416module_exit(videodev_exit)
417
418EXPORT_SYMBOL(video_register_device);
419EXPORT_SYMBOL(video_unregister_device);
420EXPORT_SYMBOL(video_devdata);
421EXPORT_SYMBOL(video_usercopy);
422EXPORT_SYMBOL(video_exclusive_open);
423EXPORT_SYMBOL(video_exclusive_release);
424EXPORT_SYMBOL(video_device_alloc);
425EXPORT_SYMBOL(video_device_release);
426
427MODULE_AUTHOR("Alan Cox");
428MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
429MODULE_LICENSE("GPL");
430
431
432/*
433 * Local variables:
434 * c-basic-offset: 8
435 * End:
436 */
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
new file mode 100644
index 000000000000..76e8681d65c6
--- /dev/null
+++ b/drivers/media/video/vino.c
@@ -0,0 +1,347 @@
1/*
2 * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
7 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/wrapper.h>
16#include <linux/errno.h>
17#include <linux/irq.h>
18#include <linux/delay.h>
19#include <linux/videodev.h>
20#include <linux/i2c.h>
21#include <linux/i2c-algo-sgi.h>
22
23#include <asm/addrspace.h>
24#include <asm/system.h>
25#include <asm/bootinfo.h>
26#include <asm/pgtable.h>
27#include <asm/paccess.h>
28#include <asm/io.h>
29#include <asm/sgi/ip22.h>
30#include <asm/sgi/hpc3.h>
31#include <asm/sgi/mc.h>
32
33#include "vino.h"
34
35/* debugging? */
36#if 1
37#define DEBUG(x...) printk(x);
38#else
39#define DEBUG(x...)
40#endif
41
42
43/* VINO ASIC registers */
44struct sgi_vino *vino;
45
46static const char *vinostr = "VINO IndyCam/TV";
47static int threshold_a = 512;
48static int threshold_b = 512;
49
50struct vino_device {
51 struct video_device vdev;
52#define VINO_CHAN_A 1
53#define VINO_CHAN_B 2
54 int chan;
55};
56
57struct vino_client {
58 struct i2c_client *driver;
59 int owner;
60};
61
62struct vino_video {
63 struct vino_device chA;
64 struct vino_device chB;
65
66 struct vino_client decoder;
67 struct vino_client camera;
68
69 struct semaphore input_lock;
70
71 /* Loaded into VINO descriptors to clear End Of Descriptors table
72 * interupt condition */
73 unsigned long dummy_page;
74 unsigned int dummy_buf[4] __attribute__((aligned(8)));
75};
76
77static struct vino_video *Vino;
78
79unsigned i2c_vino_getctrl(void *data)
80{
81 return vino->i2c_control;
82}
83
84void i2c_vino_setctrl(void *data, unsigned val)
85{
86 vino->i2c_control = val;
87}
88
89unsigned i2c_vino_rdata(void *data)
90{
91 return vino->i2c_data;
92}
93
94void i2c_vino_wdata(void *data, unsigned val)
95{
96 vino->i2c_data = val;
97}
98
99static struct i2c_algo_sgi_data i2c_sgi_vino_data =
100{
101 .getctrl = &i2c_vino_getctrl,
102 .setctrl = &i2c_vino_setctrl,
103 .rdata = &i2c_vino_rdata,
104 .wdata = &i2c_vino_wdata,
105 .xfer_timeout = 200,
106 .ack_timeout = 1000,
107};
108
109/*
110 * There are two possible clients on VINO I2C bus, so we limit usage only
111 * to them.
112 */
113static int i2c_vino_client_reg(struct i2c_client *client)
114{
115 int res = 0;
116
117 down(&Vino->input_lock);
118 switch (client->driver->id) {
119 case I2C_DRIVERID_SAA7191:
120 if (Vino->decoder.driver)
121 res = -EBUSY;
122 else
123 Vino->decoder.driver = client;
124 break;
125 case I2C_DRIVERID_INDYCAM:
126 if (Vino->camera.driver)
127 res = -EBUSY;
128 else
129 Vino->camera.driver = client;
130 break;
131 default:
132 res = -ENODEV;
133 }
134 up(&Vino->input_lock);
135
136 return res;
137}
138
139static int i2c_vino_client_unreg(struct i2c_client *client)
140{
141 int res = 0;
142
143 down(&Vino->input_lock);
144 if (client == Vino->decoder.driver) {
145 if (Vino->decoder.owner)
146 res = -EBUSY;
147 else
148 Vino->decoder.driver = NULL;
149 } else if (client == Vino->camera.driver) {
150 if (Vino->camera.owner)
151 res = -EBUSY;
152 else
153 Vino->camera.driver = NULL;
154 }
155 up(&Vino->input_lock);
156
157 return res;
158}
159
160static struct i2c_adapter vino_i2c_adapter =
161{
162 .name = "VINO I2C bus",
163 .id = I2C_HW_SGI_VINO,
164 .algo_data = &i2c_sgi_vino_data,
165 .client_register = &i2c_vino_client_reg,
166 .client_unregister = &i2c_vino_client_unreg,
167};
168
169static int vino_i2c_add_bus(void)
170{
171 return i2c_sgi_add_bus(&vino_i2c_adapter);
172}
173
174static int vino_i2c_del_bus(void)
175{
176 return i2c_sgi_del_bus(&vino_i2c_adapter);
177}
178
179
180static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
181{
182}
183
184static int vino_open(struct video_device *dev, int flags)
185{
186 struct vino_device *videv = (struct vino_device *)dev;
187
188 return 0;
189}
190
191static void vino_close(struct video_device *dev)
192{
193 struct vino_device *videv = (struct vino_device *)dev;
194}
195
196static int vino_mmap(struct video_device *dev, const char *adr,
197 unsigned long size)
198{
199 struct vino_device *videv = (struct vino_device *)dev;
200
201 return -EINVAL;
202}
203
204static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
205{
206 struct vino_device *videv = (struct vino_device *)dev;
207
208 return -EINVAL;
209}
210
211static const struct video_device vino_device = {
212 .owner = THIS_MODULE,
213 .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
214 .hardware = VID_HARDWARE_VINO,
215 .name = "VINO",
216 .open = vino_open,
217 .close = vino_close,
218 .ioctl = vino_ioctl,
219 .mmap = vino_mmap,
220};
221
222static int __init vino_init(void)
223{
224 unsigned long rev;
225 int i, ret = 0;
226
227 /* VINO is Indy specific beast */
228 if (ip22_is_fullhouse())
229 return -ENODEV;
230
231 /*
232 * VINO is in the EISA address space, so the sysid register will tell
233 * us if the EISA_PRESENT pin on MC has been pulled low.
234 *
235 * If EISA_PRESENT is not set we definitely don't have a VINO equiped
236 * system.
237 */
238 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
239 printk(KERN_ERR "VINO not found\n");
240 return -ENODEV;
241 }
242
243 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
244 if (!vino)
245 return -EIO;
246
247 /* Okay, once we know that VINO is present we'll read its revision
248 * safe way. One never knows... */
249 if (get_dbe(rev, &(vino->rev_id))) {
250 printk(KERN_ERR "VINO: failed to read revision register\n");
251 ret = -ENODEV;
252 goto out_unmap;
253 }
254 if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) {
255 printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev);
256 ret = -ENODEV;
257 goto out_unmap;
258 }
259 printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
260
261 Vino = (struct vino_video *)
262 kmalloc(sizeof(struct vino_video), GFP_KERNEL);
263 if (!Vino) {
264 ret = -ENOMEM;
265 goto out_unmap;
266 }
267
268 Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
269 if (!Vino->dummy_page) {
270 ret = -ENOMEM;
271 goto out_free_vino;
272 }
273 for (i = 0; i < 4; i++)
274 Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page);
275
276 vino->control = 0;
277 /* prevent VINO from throwing spurious interrupts */
278 vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf);
279 vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf);
280 udelay(5);
281 vino->intr_status = 0;
282 /* set threshold level */
283 vino->a.fifo_thres = threshold_a;
284 vino->b.fifo_thres = threshold_b;
285
286 init_MUTEX(&Vino->input_lock);
287
288 if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) {
289 printk(KERN_ERR "VINO: irq%02d registration failed\n",
290 SGI_VINO_IRQ);
291 ret = -EAGAIN;
292 goto out_free_page;
293 }
294
295 ret = vino_i2c_add_bus();
296 if (ret) {
297 printk(KERN_ERR "VINO: I2C bus registration failed\n");
298 goto out_free_irq;
299 }
300
301 if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) {
302 printk("%s, chnl %d: device registration failed.\n",
303 Vino->chA.vdev.name, Vino->chA.chan);
304 ret = -EINVAL;
305 goto out_i2c_del_bus;
306 }
307 if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) {
308 printk("%s, chnl %d: device registration failed.\n",
309 Vino->chB.vdev.name, Vino->chB.chan);
310 ret = -EINVAL;
311 goto out_unregister_vdev;
312 }
313
314 return 0;
315
316out_unregister_vdev:
317 video_unregister_device(&Vino->chA.vdev);
318out_i2c_del_bus:
319 vino_i2c_del_bus();
320out_free_irq:
321 free_irq(SGI_VINO_IRQ, NULL);
322out_free_page:
323 free_page(Vino->dummy_page);
324out_free_vino:
325 kfree(Vino);
326out_unmap:
327 iounmap(vino);
328
329 return ret;
330}
331
332static void __exit vino_exit(void)
333{
334 video_unregister_device(&Vino->chA.vdev);
335 video_unregister_device(&Vino->chB.vdev);
336 vino_i2c_del_bus();
337 free_irq(SGI_VINO_IRQ, NULL);
338 free_page(Vino->dummy_page);
339 kfree(Vino);
340 iounmap(vino);
341}
342
343module_init(vino_init);
344module_exit(vino_exit);
345
346MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
347MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
new file mode 100644
index 000000000000..d2fce472f35a
--- /dev/null
+++ b/drivers/media/video/vino.h
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
3 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
4 */
5
6#ifndef VINO_H
7#define VINO_H
8
9#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
10 * but it is not an EISA bus card */
11
12struct sgi_vino_channel {
13 u32 _pad_alpha;
14 volatile u32 alpha;
15
16#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */
17#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */
18#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */
19 u32 _pad_clip_start;
20 volatile u32 clip_start;
21 u32 _pad_clip_end;
22 volatile u32 clip_end;
23
24#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
25#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */
26 u32 _pad_frame_rate;
27 volatile u32 frame_rate;
28
29 u32 _pad_field_counter;
30 volatile u32 field_counter;
31 u32 _pad_line_size;
32 volatile u32 line_size;
33 u32 _pad_line_count;
34 volatile u32 line_count;
35 u32 _pad_page_index;
36 volatile u32 page_index;
37 u32 _pad_next_4_desc;
38 volatile u32 next_4_desc;
39 u32 _pad_start_desc_tbl;
40 volatile u32 start_desc_tbl;
41
42#define VINO_DESC_JUMP (1<<30)
43#define VINO_DESC_STOP (1<<31)
44#define VINO_DESC_VALID (1<<32)
45 u32 _pad_desc_0;
46 volatile u32 desc_0;
47 u32 _pad_desc_1;
48 volatile u32 desc_1;
49 u32 _pad_desc_2;
50 volatile u32 desc_2;
51 u32 _pad_Bdesc_3;
52 volatile u32 desc_3;
53
54 u32 _pad_fifo_thres;
55 volatile u32 fifo_thres;
56 u32 _pad_fifo_read;
57 volatile u32 fifo_read;
58 u32 _pad_fifo_write;
59 volatile u32 fifo_write;
60};
61
62struct sgi_vino {
63#define VINO_CHIP_ID 0xb
64#define VINO_REV_NUM(x) ((x) & 0x0f)
65#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4)
66 u32 _pad_rev_id;
67 volatile u32 rev_id;
68
69#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
70#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */
71#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */
72#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */
73#define VINO_CTRL_A_INT (VINO_CTRL_A_FIELD_TRANS_INT | \
74 VINO_CTRL_A_FIFO_OF_INT | \
75 VINO_CTRL_A_END_DESC_TBL_INT)
76#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */
77#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */
78#define VINO_CTRL_B_END_DESC_TBL_INT (1<<6) /* End of desc table int */
79#define VINO_CTRL_B_INT (VINO_CTRL_B_FIELD_TRANS_INT | \
80 VINO_CTRL_B_FIFO_OF_INT | \
81 VINO_CTRL_B_END_DESC_TBL_INT)
82#define VINO_CTRL_A_DMA_ENBL (1<<7)
83#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
84#define VINO_CTRL_A_SYNC_ENBL (1<<9)
85#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
86#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
87#define VINO_CTRL_A_LUMA_ONLY (1<<12)
88#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
89#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
90#define VINO_CTRL_A_DEC_SCALE_SHIFT (14)
91#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
92#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
93#define VINO_CTRL_B_DMA_ENBL (1<<19)
94#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
95#define VINO_CTRL_B_SYNC_ENBL (1<<21)
96#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
97#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */
98#define VINO_CTRL_B_LUMA_ONLY (1<<24)
99#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */
100#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */
101#define VINO_CTRL_B_DEC_SCALE_SHIFT (26)
102#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
103#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
104 u32 _pad_control;
105 volatile u32 control;
106
107#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */
108#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */
109#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */
110#define VINO_INTSTAT_A (VINO_INTSTAT_A_FIELD_TRANS | \
111 VINO_INTSTAT_A_FIFO_OF | \
112 VINO_INTSTAT_A_END_DESC_TBL)
113#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */
114#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */
115#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */
116#define VINO_INTSTAT_B (VINO_INTSTAT_B_FIELD_TRANS | \
117 VINO_INTSTAT_B_FIFO_OF | \
118 VINO_INTSTAT_B_END_DESC_TBL)
119 u32 _pad_intr_status;
120 volatile u32 intr_status;
121
122 u32 _pad_i2c_control;
123 volatile u32 i2c_control;
124 u32 _pad_i2c_data;
125 volatile u32 i2c_data;
126
127 struct sgi_vino_channel a;
128 struct sgi_vino_channel b;
129};
130
131#endif
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
new file mode 100644
index 000000000000..0fd6c9a70917
--- /dev/null
+++ b/drivers/media/video/vpx3220.c
@@ -0,0 +1,754 @@
1/*
2 * vpx3220a, vpx3216b & vpx3214c video decoder driver version 0.0.1
3 *
4 * Copyright (C) 2001 Laurent Pinchart <lpinchart@freegates.be>
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
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/types.h>
25#include <linux/slab.h>
26
27#include <linux/byteorder/swab.h>
28
29#include <asm/io.h>
30#include <asm/uaccess.h>
31
32#include <linux/i2c.h>
33#include <linux/i2c-dev.h>
34
35#define I2C_NAME(x) (x)->name
36
37#include <linux/videodev.h>
38#include <linux/video_decoder.h>
39
40#define I2C_VPX3220 0x86
41#define VPX3220_DEBUG KERN_DEBUG "vpx3220: "
42
43static int debug = 0;
44module_param(debug, int, 0);
45MODULE_PARM_DESC(debug, "Debug level (0-1)");
46
47#define dprintk(num, format, args...) \
48 do { \
49 if (debug >= num) \
50 printk(format, ##args); \
51 } while (0)
52
53#define VPX_TIMEOUT_COUNT 10
54
55/* ----------------------------------------------------------------------- */
56
57struct vpx3220 {
58 unsigned char reg[255];
59
60 int norm;
61 int input;
62 int enable;
63 int bright;
64 int contrast;
65 int hue;
66 int sat;
67};
68
69static char *inputs[] = { "internal", "composite", "svideo" };
70
71/* ----------------------------------------------------------------------- */
72static inline int
73vpx3220_write (struct i2c_client *client,
74 u8 reg,
75 u8 value)
76{
77 struct vpx3220 *decoder = i2c_get_clientdata(client);
78
79 decoder->reg[reg] = value;
80 return i2c_smbus_write_byte_data(client, reg, value);
81}
82
83static inline int
84vpx3220_read (struct i2c_client *client,
85 u8 reg)
86{
87 return i2c_smbus_read_byte_data(client, reg);
88}
89
90static int
91vpx3220_fp_status (struct i2c_client *client)
92{
93 unsigned char status;
94 unsigned int i;
95
96 for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
97 status = vpx3220_read(client, 0x29);
98
99 if (!(status & 4))
100 return 0;
101
102 udelay(10);
103
104 if (need_resched())
105 cond_resched();
106 }
107
108 return -1;
109}
110
111static int
112vpx3220_fp_write (struct i2c_client *client,
113 u8 fpaddr,
114 u16 data)
115{
116 /* Write the 16-bit address to the FPWR register */
117 if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
118 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
119 return -1;
120 }
121
122 if (vpx3220_fp_status(client) < 0)
123 return -1;
124
125 /* Write the 16-bit data to the FPDAT register */
126 if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
127 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
128 return -1;
129 }
130
131 return 0;
132}
133
134static u16
135vpx3220_fp_read (struct i2c_client *client,
136 u16 fpaddr)
137{
138 s16 data;
139
140 /* Write the 16-bit address to the FPRD register */
141 if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
142 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
143 return -1;
144 }
145
146 if (vpx3220_fp_status(client) < 0)
147 return -1;
148
149 /* Read the 16-bit data from the FPDAT register */
150 data = i2c_smbus_read_word_data(client, 0x28);
151 if (data == -1) {
152 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
153 return -1;
154 }
155
156 return swab16(data);
157}
158
159static int
160vpx3220_write_block (struct i2c_client *client,
161 const u8 *data,
162 unsigned int len)
163{
164 u8 reg;
165 int ret = -1;
166
167 while (len >= 2) {
168 reg = *data++;
169 if ((ret =
170 vpx3220_write(client, reg, *data++)) < 0)
171 break;
172 len -= 2;
173 }
174
175 return ret;
176}
177
178static int
179vpx3220_write_fp_block (struct i2c_client *client,
180 const u16 *data,
181 unsigned int len)
182{
183 u8 reg;
184 int ret = 0;
185
186 while (len > 1) {
187 reg = *data++;
188 ret |= vpx3220_fp_write(client, reg, *data++);
189 len -= 2;
190 }
191
192 return ret;
193}
194
195/* ---------------------------------------------------------------------- */
196
197static const unsigned short init_ntsc[] = {
198 0x1c, 0x00, /* NTSC tint angle */
199 0x88, 17, /* Window 1 vertical */
200 0x89, 240, /* Vertical lines in */
201 0x8a, 240, /* Vertical lines out */
202 0x8b, 000, /* Horizontal begin */
203 0x8c, 640, /* Horizontal length */
204 0x8d, 640, /* Number of pixels */
205 0x8f, 0xc00, /* Disable window 2 */
206 0xf0, 0x173, /* 13.5 MHz transport, Forced
207 * mode, latch windows */
208 0xf2, 0x13, /* NTSC M, composite input */
209 0xe7, 0x1e1, /* Enable vertical standard
210 * locking @ 240 lines */
211};
212
213static const unsigned short init_pal[] = {
214 0x88, 23, /* Window 1 vertical begin */
215 0x89, 288 + 16, /* Vertical lines in (16 lines
216 * skipped by the VFE) */
217 0x8a, 288 + 16, /* Vertical lines out (16 lines
218 * skipped by the VFE) */
219 0x8b, 16, /* Horizontal begin */
220 0x8c, 768, /* Horizontal length */
221 0x8d, 784, /* Number of pixels
222 * Must be >= Horizontal begin + Horizontal length */
223 0x8f, 0xc00, /* Disable window 2 */
224 0xf0, 0x177, /* 13.5 MHz transport, Forced
225 * mode, latch windows */
226 0xf2, 0x3d1, /* PAL B,G,H,I, composite input */
227 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
228 * change to 0x241 for 288 lines */
229};
230
231static const unsigned short init_secam[] = {
232 0x88, 23 - 16, /* Window 1 vertical begin */
233 0x89, 288 + 16, /* Vertical lines in (16 lines
234 * skipped by the VFE) */
235 0x8a, 288 + 16, /* Vertical lines out (16 lines
236 * skipped by the VFE) */
237 0x8b, 16, /* Horizontal begin */
238 0x8c, 768, /* Horizontal length */
239 0x8d, 784, /* Number of pixels
240 * Must be >= Horizontal begin + Horizontal length */
241 0x8f, 0xc00, /* Disable window 2 */
242 0xf0, 0x177, /* 13.5 MHz transport, Forced
243 * mode, latch windows */
244 0xf2, 0x3d5, /* SECAM, composite input */
245 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
246 * change to 0x241 for 288 lines */
247};
248
249static const unsigned char init_common[] = {
250 0xf2, 0x00, /* Disable all outputs */
251 0x33, 0x0d, /* Luma : VIN2, Chroma : CIN
252 * (clamp off) */
253 0xd8, 0xa8, /* HREF/VREF active high, VREF
254 * pulse = 2, Odd/Even flag */
255 0x20, 0x03, /* IF compensation 0dB/oct */
256 0xe0, 0xff, /* Open up all comparators */
257 0xe1, 0x00,
258 0xe2, 0x7f,
259 0xe3, 0x80,
260 0xe4, 0x7f,
261 0xe5, 0x80,
262 0xe6, 0x00, /* Brightness set to 0 */
263 0xe7, 0xe0, /* Contrast to 1.0, noise shaping
264 * 10 to 8 2-bit error diffusion */
265 0xe8, 0xf8, /* YUV422, CbCr binary offset,
266 * ... (p.32) */
267 0xea, 0x18, /* LLC2 connected, output FIFO
268 * reset with VACTintern */
269 0xf0, 0x8a, /* Half full level to 10, bus
270 * shuffler [7:0, 23:16, 15:8] */
271 0xf1, 0x18, /* Single clock, sync mode, no
272 * FE delay, no HLEN counter */
273 0xf8, 0x12, /* Port A, PIXCLK, HF# & FE#
274 * strength to 2 */
275 0xf9, 0x24, /* Port B, HREF, VREF, PREF &
276 * ALPHA strength to 4 */
277};
278
279static const unsigned short init_fp[] = {
280 0x59, 0,
281 0xa0, 2070, /* ACC reference */
282 0xa3, 0,
283 0xa4, 0,
284 0xa8, 30,
285 0xb2, 768,
286 0xbe, 27,
287 0x58, 0,
288 0x26, 0,
289 0x4b, 0x298, /* PLL gain */
290};
291
292static void
293vpx3220_dump_i2c (struct i2c_client *client)
294{
295 int len = sizeof(init_common);
296 const unsigned char *data = init_common;
297
298 while (len > 1) {
299 dprintk(1,
300 KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n",
301 *data, vpx3220_read(client, *data));
302 data += 2;
303 len -= 2;
304 }
305}
306
307static int
308vpx3220_command (struct i2c_client *client,
309 unsigned int cmd,
310 void *arg)
311{
312 struct vpx3220 *decoder = i2c_get_clientdata(client);
313
314 switch (cmd) {
315 case 0:
316 {
317 vpx3220_write_block(client, init_common,
318 sizeof(init_common));
319 vpx3220_write_fp_block(client, init_fp,
320 sizeof(init_fp) >> 1);
321 switch (decoder->norm) {
322
323 case VIDEO_MODE_NTSC:
324 vpx3220_write_fp_block(client, init_ntsc,
325 sizeof(init_ntsc) >> 1);
326 break;
327
328 case VIDEO_MODE_PAL:
329 vpx3220_write_fp_block(client, init_pal,
330 sizeof(init_pal) >> 1);
331 break;
332 case VIDEO_MODE_SECAM:
333 vpx3220_write_fp_block(client, init_secam,
334 sizeof(init_secam) >> 1);
335 break;
336 default:
337 vpx3220_write_fp_block(client, init_pal,
338 sizeof(init_pal) >> 1);
339 break;
340 }
341 }
342 break;
343
344 case DECODER_DUMP:
345 {
346 vpx3220_dump_i2c(client);
347 }
348 break;
349
350 case DECODER_GET_CAPABILITIES:
351 {
352 struct video_decoder_capability *cap = arg;
353
354 dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
355 I2C_NAME(client));
356
357 cap->flags = VIDEO_DECODER_PAL |
358 VIDEO_DECODER_NTSC |
359 VIDEO_DECODER_SECAM |
360 VIDEO_DECODER_AUTO |
361 VIDEO_DECODER_CCIR;
362 cap->inputs = 3;
363 cap->outputs = 1;
364 }
365 break;
366
367 case DECODER_GET_STATUS:
368 {
369 int res = 0, status;
370
371 dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
372 I2C_NAME(client));
373
374 status = vpx3220_fp_read(client, 0x0f3);
375
376 dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
377 status);
378
379 if (status < 0)
380 return status;
381
382 if ((status & 0x20) == 0) {
383 res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
384
385 switch (status & 0x18) {
386
387 case 0x00:
388 case 0x10:
389 case 0x14:
390 case 0x18:
391 res |= DECODER_STATUS_PAL;
392 break;
393
394 case 0x08:
395 res |= DECODER_STATUS_SECAM;
396 break;
397
398 case 0x04:
399 case 0x0c:
400 case 0x1c:
401 res |= DECODER_STATUS_NTSC;
402 break;
403 }
404 }
405
406 *(int *) arg = res;
407 }
408 break;
409
410 case DECODER_SET_NORM:
411 {
412 int *iarg = arg, data;
413
414 dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
415 I2C_NAME(client), *iarg);
416 switch (*iarg) {
417
418 case VIDEO_MODE_NTSC:
419 vpx3220_write_fp_block(client, init_ntsc,
420 sizeof(init_ntsc) >> 1);
421 dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
422 I2C_NAME(client));
423 break;
424
425 case VIDEO_MODE_PAL:
426 vpx3220_write_fp_block(client, init_pal,
427 sizeof(init_pal) >> 1);
428 dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
429 I2C_NAME(client));
430 break;
431
432 case VIDEO_MODE_SECAM:
433 vpx3220_write_fp_block(client, init_secam,
434 sizeof(init_secam) >> 1);
435 dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
436 I2C_NAME(client));
437 break;
438
439 case VIDEO_MODE_AUTO:
440 /* FIXME This is only preliminary support */
441 data = vpx3220_fp_read(client, 0xf2) & 0x20;
442 vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
443 dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
444 I2C_NAME(client));
445 break;
446
447 default:
448 return -EINVAL;
449
450 }
451 decoder->norm = *iarg;
452 }
453 break;
454
455 case DECODER_SET_INPUT:
456 {
457 int *iarg = arg, data;
458
459 /* RJ: *iarg = 0: ST8 (PCTV) input
460 *iarg = 1: COMPOSITE input
461 *iarg = 2: SVHS input */
462
463 const int input[3][2] = {
464 {0x0c, 0},
465 {0x0d, 0},
466 {0x0e, 1}
467 };
468
469 if (*iarg < 0 || *iarg > 2)
470 return -EINVAL;
471
472 dprintk(1, KERN_INFO "%s: input switched to %s\n",
473 I2C_NAME(client), inputs[*iarg]);
474
475 vpx3220_write(client, 0x33, input[*iarg][0]);
476
477 data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
478 if (data < 0)
479 return data;
480 /* 0x0010 is required to latch the setting */
481 vpx3220_fp_write(client, 0xf2,
482 data | (input[*iarg][1] << 5) | 0x0010);
483
484 udelay(10);
485 }
486 break;
487
488 case DECODER_SET_OUTPUT:
489 {
490 int *iarg = arg;
491
492 /* not much choice of outputs */
493 if (*iarg != 0) {
494 return -EINVAL;
495 }
496 }
497 break;
498
499 case DECODER_ENABLE_OUTPUT:
500 {
501 int *iarg = arg;
502
503 dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
504 I2C_NAME(client), *iarg);
505
506 vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
507 }
508 break;
509
510 case DECODER_SET_PICTURE:
511 {
512 struct video_picture *pic = arg;
513
514 if (decoder->bright != pic->brightness) {
515 /* We want -128 to 128 we get 0-65535 */
516 decoder->bright = pic->brightness;
517 vpx3220_write(client, 0xe6,
518 (decoder->bright - 32768) >> 8);
519 }
520 if (decoder->contrast != pic->contrast) {
521 /* We want 0 to 64 we get 0-65535 */
522 /* Bit 7 and 8 is for noise shaping */
523 decoder->contrast = pic->contrast;
524 vpx3220_write(client, 0xe7,
525 (decoder->contrast >> 10) + 192);
526 }
527 if (decoder->sat != pic->colour) {
528 /* We want 0 to 4096 we get 0-65535 */
529 decoder->sat = pic->colour;
530 vpx3220_fp_write(client, 0xa0,
531 decoder->sat >> 4);
532 }
533 if (decoder->hue != pic->hue) {
534 /* We want -512 to 512 we get 0-65535 */
535 decoder->hue = pic->hue;
536 vpx3220_fp_write(client, 0x1c,
537 ((decoder->hue - 32768) >> 6) & 0xFFF);
538 }
539 }
540 break;
541
542 default:
543 return -EINVAL;
544 }
545
546 return 0;
547}
548
549static int
550vpx3220_init_client (struct i2c_client *client)
551{
552 vpx3220_write_block(client, init_common, sizeof(init_common));
553 vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
554 /* Default to PAL */
555 vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1);
556
557 return 0;
558}
559
560/* -----------------------------------------------------------------------
561 * Client managment code
562 */
563
564/*
565 * Generic i2c probe
566 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
567 */
568static unsigned short normal_i2c[] =
569 { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
570 I2C_CLIENT_END
571};
572static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
573
574static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
575static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
576static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
577static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
578static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
579
580static struct i2c_client_address_data addr_data = {
581 .normal_i2c = normal_i2c,
582 .normal_i2c_range = normal_i2c_range,
583 .probe = probe,
584 .probe_range = probe_range,
585 .ignore = ignore,
586 .ignore_range = ignore_range,
587 .force = force
588};
589
590static struct i2c_driver vpx3220_i2c_driver;
591
592static int
593vpx3220_detach_client (struct i2c_client *client)
594{
595 struct vpx3220 *decoder = i2c_get_clientdata(client);
596 int err;
597
598 err = i2c_detach_client(client);
599 if (err) {
600 return err;
601 }
602
603 kfree(decoder);
604 kfree(client);
605
606 return 0;
607}
608
609static int
610vpx3220_detect_client (struct i2c_adapter *adapter,
611 int address,
612 int kind)
613{
614 int err;
615 struct i2c_client *client;
616 struct vpx3220 *decoder;
617
618 dprintk(1, VPX3220_DEBUG "%s\n", __func__);
619
620 /* Check if the adapter supports the needed features */
621 if (!i2c_check_functionality
622 (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
623 return 0;
624
625 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
626 if (client == NULL) {
627 return -ENOMEM;
628 }
629
630 memset(client, 0, sizeof(struct i2c_client));
631
632 client->addr = address;
633 client->adapter = adapter;
634 client->driver = &vpx3220_i2c_driver;
635 client->flags = I2C_CLIENT_ALLOW_USE;
636
637 /* Check for manufacture ID and part number */
638 if (kind < 0) {
639 u8 id;
640 u16 pn;
641
642 id = vpx3220_read(client, 0x00);
643 if (id != 0xec) {
644 dprintk(1,
645 KERN_INFO
646 "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n",
647 id);
648 kfree(client);
649 return 0;
650 }
651
652 pn = (vpx3220_read(client, 0x02) << 8) +
653 vpx3220_read(client, 0x01);
654 switch (pn) {
655 case 0x4680:
656 strlcpy(I2C_NAME(client), "vpx3220a",
657 sizeof(I2C_NAME(client)));
658 break;
659 case 0x4260:
660 strlcpy(I2C_NAME(client), "vpx3216b",
661 sizeof(I2C_NAME(client)));
662 break;
663 case 0x4280:
664 strlcpy(I2C_NAME(client), "vpx3214c",
665 sizeof(I2C_NAME(client)));
666 break;
667 default:
668 dprintk(1,
669 KERN_INFO
670 "%s: Wrong part number (0x%04x)\n",
671 __func__, pn);
672 kfree(client);
673 return 0;
674 }
675 } else {
676 strlcpy(I2C_NAME(client), "forced vpx32xx",
677 sizeof(I2C_NAME(client)));
678 }
679
680 decoder = kmalloc(sizeof(struct vpx3220), GFP_KERNEL);
681 if (decoder == NULL) {
682 kfree(client);
683 return -ENOMEM;
684 }
685 memset(decoder, 0, sizeof(struct vpx3220));
686 decoder->norm = VIDEO_MODE_PAL;
687 decoder->input = 0;
688 decoder->enable = 1;
689 decoder->bright = 32768;
690 decoder->contrast = 32768;
691 decoder->hue = 32768;
692 decoder->sat = 32768;
693 i2c_set_clientdata(client, decoder);
694
695 err = i2c_attach_client(client);
696 if (err) {
697 kfree(client);
698 kfree(decoder);
699 return err;
700 }
701
702 dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
703 I2C_NAME(client), client->addr << 1);
704
705 vpx3220_init_client(client);
706
707 return 0;
708}
709
710static int
711vpx3220_attach_adapter (struct i2c_adapter *adapter)
712{
713 int ret;
714
715 ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
716 dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
717 __func__, ret);
718 return ret;
719}
720
721/* -----------------------------------------------------------------------
722 * Driver initialization and cleanup code
723 */
724
725static struct i2c_driver vpx3220_i2c_driver = {
726 .owner = THIS_MODULE,
727 .name = "vpx3220",
728
729 .id = I2C_DRIVERID_VPX3220,
730 .flags = I2C_DF_NOTIFY,
731
732 .attach_adapter = vpx3220_attach_adapter,
733 .detach_client = vpx3220_detach_client,
734 .command = vpx3220_command,
735};
736
737static int __init
738vpx3220_init (void)
739{
740 return i2c_add_driver(&vpx3220_i2c_driver);
741}
742
743static void __exit
744vpx3220_cleanup (void)
745{
746 i2c_del_driver(&vpx3220_i2c_driver);
747}
748
749module_init(vpx3220_init);
750module_exit(vpx3220_cleanup);
751
752MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video encoder driver");
753MODULE_AUTHOR("Laurent Pinchart");
754MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
new file mode 100644
index 000000000000..c318ba32fbaf
--- /dev/null
+++ b/drivers/media/video/w9966.c
@@ -0,0 +1,984 @@
1/*
2 Winbond w9966cf Webcam parport driver.
3
4 Version 0.32
5
6 Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
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 Supported devices:
24 *Lifeview FlyCam Supra (using the Philips saa7111a chip)
25
26 Does any other model using the w9966 interface chip exist ?
27
28 Todo:
29
30 *Add a working EPP mode, since DMA ECP read isn't implemented
31 in the parport drivers. (That's why it's so sloow)
32
33 *Add support for other ccd-control chips than the saa7111
34 please send me feedback on what kind of chips you have.
35
36 *Add proper probing. I don't know what's wrong with the IEEE1284
37 parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
38 and nibble read seems to be broken for some peripherals.
39
40 *Add probing for onboard SRAM, port directions etc. (if possible)
41
42 *Add support for the hardware compressed modes (maybe using v4l2)
43
44 *Fix better support for the capture window (no skewed images, v4l
45 interface to capt. window)
46
47 *Probably some bugs that I don't know of
48
49 Please support me by sending feedback!
50
51 Changes:
52
53 Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
54 and owner support for newer module locks
55*/
56
57#include <linux/module.h>
58#include <linux/init.h>
59#include <linux/delay.h>
60#include <linux/videodev.h>
61#include <linux/parport.h>
62
63//#define DEBUG // Undef me for production
64
65#ifdef DEBUG
66#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __FUNCTION__ , ##a)
67#else
68#define DPRINTF(x...)
69#endif
70
71/*
72 * Defines, simple typedefs etc.
73 */
74
75#define W9966_DRIVERNAME "W9966CF Webcam"
76#define W9966_MAXCAMS 4 // Maximum number of cameras
77#define W9966_RBUFFER 2048 // Read buffer (must be an even number)
78#define W9966_SRAMSIZE 131072 // 128kb
79#define W9966_SRAMID 0x02 // check w9966cf.pdf
80
81// Empirically determined window limits
82#define W9966_WND_MIN_X 16
83#define W9966_WND_MIN_Y 14
84#define W9966_WND_MAX_X 705
85#define W9966_WND_MAX_Y 253
86#define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
87#define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
88
89// Keep track of our current state
90#define W9966_STATE_PDEV 0x01
91#define W9966_STATE_CLAIMED 0x02
92#define W9966_STATE_VDEV 0x04
93
94#define W9966_I2C_W_ID 0x48
95#define W9966_I2C_R_ID 0x49
96#define W9966_I2C_R_DATA 0x08
97#define W9966_I2C_R_CLOCK 0x04
98#define W9966_I2C_W_DATA 0x02
99#define W9966_I2C_W_CLOCK 0x01
100
101struct w9966_dev {
102 unsigned char dev_state;
103 unsigned char i2c_state;
104 unsigned short ppmode;
105 struct parport* pport;
106 struct pardevice* pdev;
107 struct video_device vdev;
108 unsigned short width;
109 unsigned short height;
110 unsigned char brightness;
111 signed char contrast;
112 signed char color;
113 signed char hue;
114};
115
116/*
117 * Module specific properties
118 */
119
120MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
121MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
122MODULE_LICENSE("GPL");
123
124
125#ifdef MODULE
126static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
127#else
128static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
129#endif
130module_param_array(pardev, charp, NULL, 0);
131MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
132\teach camera. 'aggressive' means brute-force search.\n\
133\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\
134\tcam 1 to parport3 and search every parport for cam 2 etc...");
135
136static int parmode = 0;
137module_param(parmode, int, 0);
138MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
139
140static int video_nr = -1;
141module_param(video_nr, int, 0);
142
143/*
144 * Private data
145 */
146
147static struct w9966_dev w9966_cams[W9966_MAXCAMS];
148
149/*
150 * Private function declares
151 */
152
153static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
154static inline int w9966_getState(struct w9966_dev* cam, int mask, int val);
155static inline void w9966_pdev_claim(struct w9966_dev *vdev);
156static inline void w9966_pdev_release(struct w9966_dev *vdev);
157
158static int w9966_rReg(struct w9966_dev* cam, int reg);
159static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
160#if 0
161static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
162#endif
163static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
164static int w9966_findlen(int near, int size, int maxlen);
165static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
166static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
167
168static int w9966_init(struct w9966_dev* cam, struct parport* port);
169static void w9966_term(struct w9966_dev* cam);
170
171static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
172static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state);
173static inline int w9966_i2c_getsda(struct w9966_dev* cam);
174static inline int w9966_i2c_getscl(struct w9966_dev* cam);
175static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
176#if 0
177static int w9966_i2c_rbyte(struct w9966_dev* cam);
178#endif
179
180static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
181 unsigned int cmd, unsigned long arg);
182static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
183 size_t count, loff_t *ppos);
184
185static struct file_operations w9966_fops = {
186 .owner = THIS_MODULE,
187 .open = video_exclusive_open,
188 .release = video_exclusive_release,
189 .ioctl = w9966_v4l_ioctl,
190 .read = w9966_v4l_read,
191 .llseek = no_llseek,
192};
193static struct video_device w9966_template = {
194 .owner = THIS_MODULE,
195 .name = W9966_DRIVERNAME,
196 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
197 .hardware = VID_HARDWARE_W9966,
198 .fops = &w9966_fops,
199};
200
201/*
202 * Private function defines
203 */
204
205
206// Set camera phase flags, so we know what to uninit when terminating
207static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
208{
209 cam->dev_state = (cam->dev_state & ~mask) ^ val;
210}
211
212// Get camera phase flags
213static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
214{
215 return ((cam->dev_state & mask) == val);
216}
217
218// Claim parport for ourself
219static inline void w9966_pdev_claim(struct w9966_dev* cam)
220{
221 if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
222 return;
223 parport_claim_or_block(cam->pdev);
224 w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
225}
226
227// Release parport for others to use
228static inline void w9966_pdev_release(struct w9966_dev* cam)
229{
230 if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
231 return;
232 parport_release(cam->pdev);
233 w9966_setState(cam, W9966_STATE_CLAIMED, 0);
234}
235
236// Read register from W9966 interface-chip
237// Expects a claimed pdev
238// -1 on error, else register data (byte)
239static int w9966_rReg(struct w9966_dev* cam, int reg)
240{
241 // ECP, read, regtransfer, REG, REG, REG, REG, REG
242 const unsigned char addr = 0x80 | (reg & 0x1f);
243 unsigned char val;
244
245 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
246 return -1;
247 if (parport_write(cam->pport, &addr, 1) != 1)
248 return -1;
249 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
250 return -1;
251 if (parport_read(cam->pport, &val, 1) != 1)
252 return -1;
253
254 return val;
255}
256
257// Write register to W9966 interface-chip
258// Expects a claimed pdev
259// -1 on error
260static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
261{
262 // ECP, write, regtransfer, REG, REG, REG, REG, REG
263 const unsigned char addr = 0xc0 | (reg & 0x1f);
264 const unsigned char val = data;
265
266 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
267 return -1;
268 if (parport_write(cam->pport, &addr, 1) != 1)
269 return -1;
270 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
271 return -1;
272 if (parport_write(cam->pport, &val, 1) != 1)
273 return -1;
274
275 return 0;
276}
277
278// Initialize camera device. Setup all internal flags, set a
279// default video mode, setup ccd-chip, register v4l device etc..
280// Also used for 'probing' of hardware.
281// -1 on error
282static int w9966_init(struct w9966_dev* cam, struct parport* port)
283{
284 if (cam->dev_state != 0)
285 return -1;
286
287 cam->pport = port;
288 cam->brightness = 128;
289 cam->contrast = 64;
290 cam->color = 64;
291 cam->hue = 0;
292
293// Select requested transfer mode
294 switch(parmode)
295 {
296 default: // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
297 case 0:
298 if (port->modes & PARPORT_MODE_ECP)
299 cam->ppmode = IEEE1284_MODE_ECP;
300 else if (port->modes & PARPORT_MODE_EPP)
301 cam->ppmode = IEEE1284_MODE_EPP;
302 else
303 cam->ppmode = IEEE1284_MODE_ECP;
304 break;
305 case 1: // hw- or sw-ecp
306 cam->ppmode = IEEE1284_MODE_ECP;
307 break;
308 case 2: // hw- or sw-epp
309 cam->ppmode = IEEE1284_MODE_EPP;
310 break;
311 }
312
313// Tell the parport driver that we exists
314 cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
315 if (cam->pdev == NULL) {
316 DPRINTF("parport_register_device() failed\n");
317 return -1;
318 }
319 w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
320
321 w9966_pdev_claim(cam);
322
323// Setup a default capture mode
324 if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
325 DPRINTF("w9966_setup() failed.\n");
326 return -1;
327 }
328
329 w9966_pdev_release(cam);
330
331// Fill in the video_device struct and register us to v4l
332 memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
333 cam->vdev.priv = cam;
334
335 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)
336 return -1;
337
338 w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
339
340 // All ok
341 printk(
342 "w9966cf: Found and initialized a webcam on %s.\n",
343 cam->pport->name
344 );
345 return 0;
346}
347
348
349// Terminate everything gracefully
350static void w9966_term(struct w9966_dev* cam)
351{
352// Unregister from v4l
353 if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
354 video_unregister_device(&cam->vdev);
355 w9966_setState(cam, W9966_STATE_VDEV, 0);
356 }
357
358// Terminate from IEEE1284 mode and release pdev block
359 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
360 w9966_pdev_claim(cam);
361 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
362 w9966_pdev_release(cam);
363 }
364
365// Unregister from parport
366 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
367 parport_unregister_device(cam->pdev);
368 w9966_setState(cam, W9966_STATE_PDEV, 0);
369 }
370}
371
372
373// Find a good length for capture window (used both for W and H)
374// A bit ugly but pretty functional. The capture length
375// have to match the downscale
376static int w9966_findlen(int near, int size, int maxlen)
377{
378 int bestlen = size;
379 int besterr = abs(near - bestlen);
380 int len;
381
382 for(len = size+1;len < maxlen;len++)
383 {
384 int err;
385 if ( ((64*size) %len) != 0)
386 continue;
387
388 err = abs(near - len);
389
390 // Only continue as long as we keep getting better values
391 if (err > besterr)
392 break;
393
394 besterr = err;
395 bestlen = len;
396 }
397
398 return bestlen;
399}
400
401// Modify capture window (if necessary)
402// and calculate downscaling
403// Return -1 on error
404static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
405{
406 int maxlen = max - min;
407 int len = *end - *beg + 1;
408 int newlen = w9966_findlen(len, size, maxlen);
409 int err = newlen - len;
410
411 // Check for bad format
412 if (newlen > maxlen || newlen < size)
413 return -1;
414
415 // Set factor (6 bit fixed)
416 *factor = (64*size) / newlen;
417 if (*factor == 64)
418 *factor = 0x00; // downscale is disabled
419 else
420 *factor |= 0x80; // set downscale-enable bit
421
422 // Modify old beginning and end
423 *beg -= err / 2;
424 *end += err - (err / 2);
425
426 // Move window if outside borders
427 if (*beg < min) {
428 *end += min - *beg;
429 *beg += min - *beg;
430 }
431 if (*end > max) {
432 *beg -= *end - max;
433 *end -= *end - max;
434 }
435
436 return 0;
437}
438
439// Setup the cameras capture window etc.
440// Expects a claimed pdev
441// return -1 on error
442static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
443{
444 unsigned int i;
445 unsigned int enh_s, enh_e;
446 unsigned char scale_x, scale_y;
447 unsigned char regs[0x1c];
448 unsigned char saa7111_regs[] = {
449 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
450 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
451 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
453 };
454
455
456 if (w*h*2 > W9966_SRAMSIZE)
457 {
458 DPRINTF("capture window exceeds SRAM size!.\n");
459 w = 200; h = 160; // Pick default values
460 }
461
462 w &= ~0x1;
463 if (w < 2) w = 2;
464 if (h < 1) h = 1;
465 if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
466 if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
467
468 cam->width = w;
469 cam->height = h;
470
471 enh_s = 0;
472 enh_e = w*h*2;
473
474// Modify capture window if necessary and calculate downscaling
475 if (
476 w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
477 w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
478 ) return -1;
479
480 DPRINTF(
481 "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
482 w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
483 );
484
485// Setup registers
486 regs[0x00] = 0x00; // Set normal operation
487 regs[0x01] = 0x18; // Capture mode
488 regs[0x02] = scale_y; // V-scaling
489 regs[0x03] = scale_x; // H-scaling
490
491 // Capture window
492 regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits)
493 regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits)
494 regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits)
495 regs[0x07] = (y1 & 0x300)>>8; // Y-start (2 high bits)
496 regs[0x08] = (x2 & 0x0ff); // X-end (8 low bits)
497 regs[0x09] = (x2 & 0x300)>>8; // X-end (2 high bits)
498 regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits)
499
500 regs[0x0c] = W9966_SRAMID; // SRAM-banks (1x 128kb)
501
502 // Enhancement layer
503 regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7)
504 regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15)
505 regs[0x0f] = (enh_s& 0x70000)>>16; // Enh. start (16-17/18??)
506 regs[0x10] = (enh_e& 0x000ff); // Enh. end (0-7)
507 regs[0x11] = (enh_e& 0x0ff00)>>8; // Enh. end (8-15)
508 regs[0x12] = (enh_e& 0x70000)>>16; // Enh. end (16-17/18??)
509
510 // Misc
511 regs[0x13] = 0x40; // VEE control (raw 4:2:2)
512 regs[0x17] = 0x00; // ???
513 regs[0x18] = cam->i2c_state = 0x00; // Serial bus
514 regs[0x19] = 0xff; // I/O port direction control
515 regs[0x1a] = 0xff; // I/O port data register
516 regs[0x1b] = 0x10; // ???
517
518 // SAA7111 chip settings
519 saa7111_regs[0x0a] = cam->brightness;
520 saa7111_regs[0x0b] = cam->contrast;
521 saa7111_regs[0x0c] = cam->color;
522 saa7111_regs[0x0d] = cam->hue;
523
524// Reset (ECP-fifo & serial-bus)
525 if (w9966_wReg(cam, 0x00, 0x03) == -1)
526 return -1;
527
528// Write regs to w9966cf chip
529 for (i = 0; i < 0x1c; i++)
530 if (w9966_wReg(cam, i, regs[i]) == -1)
531 return -1;
532
533// Write regs to saa7111 chip
534 for (i = 0; i < 0x20; i++)
535 if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
536 return -1;
537
538 return 0;
539}
540
541/*
542 * Ugly and primitive i2c protocol functions
543 */
544
545// Sets the data line on the i2c bus.
546// Expects a claimed pdev.
547static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
548{
549 if (state)
550 cam->i2c_state |= W9966_I2C_W_DATA;
551 else
552 cam->i2c_state &= ~W9966_I2C_W_DATA;
553
554 w9966_wReg(cam, 0x18, cam->i2c_state);
555 udelay(5);
556}
557
558// Get peripheral clock line
559// Expects a claimed pdev.
560static inline int w9966_i2c_getscl(struct w9966_dev* cam)
561{
562 const unsigned char state = w9966_rReg(cam, 0x18);
563 return ((state & W9966_I2C_R_CLOCK) > 0);
564}
565
566// Sets the clock line on the i2c bus.
567// Expects a claimed pdev. -1 on error
568static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
569{
570 unsigned long timeout;
571
572 if (state)
573 cam->i2c_state |= W9966_I2C_W_CLOCK;
574 else
575 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
576
577 w9966_wReg(cam, 0x18, cam->i2c_state);
578 udelay(5);
579
580 // we go to high, we also expect the peripheral to ack.
581 if (state) {
582 timeout = jiffies + 100;
583 while (!w9966_i2c_getscl(cam)) {
584 if (time_after(jiffies, timeout))
585 return -1;
586 }
587 }
588 return 0;
589}
590
591// Get peripheral data line
592// Expects a claimed pdev.
593static inline int w9966_i2c_getsda(struct w9966_dev* cam)
594{
595 const unsigned char state = w9966_rReg(cam, 0x18);
596 return ((state & W9966_I2C_R_DATA) > 0);
597}
598
599// Write a byte with ack to the i2c bus.
600// Expects a claimed pdev. -1 on error
601static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
602{
603 int i;
604 for (i = 7; i >= 0; i--)
605 {
606 w9966_i2c_setsda(cam, (data >> i) & 0x01);
607
608 if (w9966_i2c_setscl(cam, 1) == -1)
609 return -1;
610 w9966_i2c_setscl(cam, 0);
611 }
612
613 w9966_i2c_setsda(cam, 1);
614
615 if (w9966_i2c_setscl(cam, 1) == -1)
616 return -1;
617 w9966_i2c_setscl(cam, 0);
618
619 return 0;
620}
621
622// Read a data byte with ack from the i2c-bus
623// Expects a claimed pdev. -1 on error
624#if 0
625static int w9966_i2c_rbyte(struct w9966_dev* cam)
626{
627 unsigned char data = 0x00;
628 int i;
629
630 w9966_i2c_setsda(cam, 1);
631
632 for (i = 0; i < 8; i++)
633 {
634 if (w9966_i2c_setscl(cam, 1) == -1)
635 return -1;
636 data = data << 1;
637 if (w9966_i2c_getsda(cam))
638 data |= 0x01;
639
640 w9966_i2c_setscl(cam, 0);
641 }
642 return data;
643}
644#endif
645
646// Read a register from the i2c device.
647// Expects claimed pdev. -1 on error
648#if 0
649static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
650{
651 int data;
652
653 w9966_i2c_setsda(cam, 0);
654 w9966_i2c_setscl(cam, 0);
655
656 if (
657 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
658 w9966_i2c_wbyte(cam, reg) == -1
659 )
660 return -1;
661
662 w9966_i2c_setsda(cam, 1);
663 if (w9966_i2c_setscl(cam, 1) == -1)
664 return -1;
665 w9966_i2c_setsda(cam, 0);
666 w9966_i2c_setscl(cam, 0);
667
668 if (
669 w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
670 (data = w9966_i2c_rbyte(cam)) == -1
671 )
672 return -1;
673
674 w9966_i2c_setsda(cam, 0);
675
676 if (w9966_i2c_setscl(cam, 1) == -1)
677 return -1;
678 w9966_i2c_setsda(cam, 1);
679
680 return data;
681}
682#endif
683
684// Write a register to the i2c device.
685// Expects claimed pdev. -1 on error
686static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
687{
688 w9966_i2c_setsda(cam, 0);
689 w9966_i2c_setscl(cam, 0);
690
691 if (
692 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
693 w9966_i2c_wbyte(cam, reg) == -1 ||
694 w9966_i2c_wbyte(cam, data) == -1
695 )
696 return -1;
697
698 w9966_i2c_setsda(cam, 0);
699 if (w9966_i2c_setscl(cam, 1) == -1)
700 return -1;
701
702 w9966_i2c_setsda(cam, 1);
703
704 return 0;
705}
706
707/*
708 * Video4linux interfacing
709 */
710
711static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
712 unsigned int cmd, void *arg)
713{
714 struct video_device *vdev = video_devdata(file);
715 struct w9966_dev *cam = vdev->priv;
716
717 switch(cmd)
718 {
719 case VIDIOCGCAP:
720 {
721 static struct video_capability vcap = {
722 .name = W9966_DRIVERNAME,
723 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
724 .channels = 1,
725 .maxwidth = W9966_WND_MAX_W,
726 .maxheight = W9966_WND_MAX_H,
727 .minwidth = 2,
728 .minheight = 1,
729 };
730 struct video_capability *cap = arg;
731 *cap = vcap;
732 return 0;
733 }
734 case VIDIOCGCHAN:
735 {
736 struct video_channel *vch = arg;
737 if(vch->channel != 0) // We only support one channel (#0)
738 return -EINVAL;
739 memset(vch,0,sizeof(*vch));
740 strcpy(vch->name, "CCD-input");
741 vch->type = VIDEO_TYPE_CAMERA;
742 return 0;
743 }
744 case VIDIOCSCHAN:
745 {
746 struct video_channel *vch = arg;
747 if(vch->channel != 0)
748 return -EINVAL;
749 return 0;
750 }
751 case VIDIOCGTUNER:
752 {
753 struct video_tuner *vtune = arg;
754 if(vtune->tuner != 0)
755 return -EINVAL;
756 strcpy(vtune->name, "no tuner");
757 vtune->rangelow = 0;
758 vtune->rangehigh = 0;
759 vtune->flags = VIDEO_TUNER_NORM;
760 vtune->mode = VIDEO_MODE_AUTO;
761 vtune->signal = 0xffff;
762 return 0;
763 }
764 case VIDIOCSTUNER:
765 {
766 struct video_tuner *vtune = arg;
767 if (vtune->tuner != 0)
768 return -EINVAL;
769 if (vtune->mode != VIDEO_MODE_AUTO)
770 return -EINVAL;
771 return 0;
772 }
773 case VIDIOCGPICT:
774 {
775 struct video_picture vpic = {
776 cam->brightness << 8, // brightness
777 (cam->hue + 128) << 8, // hue
778 cam->color << 9, // color
779 cam->contrast << 9, // contrast
780 0x8000, // whiteness
781 16, VIDEO_PALETTE_YUV422// bpp, palette format
782 };
783 struct video_picture *pic = arg;
784 *pic = vpic;
785 return 0;
786 }
787 case VIDIOCSPICT:
788 {
789 struct video_picture *vpic = arg;
790 if (vpic->depth != 16 || vpic->palette != VIDEO_PALETTE_YUV422)
791 return -EINVAL;
792
793 cam->brightness = vpic->brightness >> 8;
794 cam->hue = (vpic->hue >> 8) - 128;
795 cam->color = vpic->colour >> 9;
796 cam->contrast = vpic->contrast >> 9;
797
798 w9966_pdev_claim(cam);
799
800 if (
801 w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
802 w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
803 w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
804 w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
805 ) {
806 w9966_pdev_release(cam);
807 return -EIO;
808 }
809
810 w9966_pdev_release(cam);
811 return 0;
812 }
813 case VIDIOCSWIN:
814 {
815 int ret;
816 struct video_window *vwin = arg;
817
818 if (vwin->flags != 0)
819 return -EINVAL;
820 if (vwin->clipcount != 0)
821 return -EINVAL;
822 if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
823 return -EINVAL;
824 if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
825 return -EINVAL;
826
827 // Update camera regs
828 w9966_pdev_claim(cam);
829 ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
830 w9966_pdev_release(cam);
831
832 if (ret != 0) {
833 DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
834 return -EIO;
835 }
836
837 return 0;
838 }
839 case VIDIOCGWIN:
840 {
841 struct video_window *vwin = arg;
842 memset(vwin, 0, sizeof(*vwin));
843 vwin->width = cam->width;
844 vwin->height = cam->height;
845 return 0;
846 }
847 // Unimplemented
848 case VIDIOCCAPTURE:
849 case VIDIOCGFBUF:
850 case VIDIOCSFBUF:
851 case VIDIOCKEY:
852 case VIDIOCGFREQ:
853 case VIDIOCSFREQ:
854 case VIDIOCGAUDIO:
855 case VIDIOCSAUDIO:
856 return -EINVAL;
857 default:
858 return -ENOIOCTLCMD;
859 }
860 return 0;
861}
862
863static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
864 unsigned int cmd, unsigned long arg)
865{
866 return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
867}
868
869// Capture data
870static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
871 size_t count, loff_t *ppos)
872{
873 struct video_device *vdev = video_devdata(file);
874 struct w9966_dev *cam = vdev->priv;
875 unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000
876 unsigned char __user *dest = (unsigned char __user *)buf;
877 unsigned long dleft = count;
878 unsigned char *tbuf;
879
880 // Why would anyone want more than this??
881 if (count > cam->width * cam->height * 2)
882 return -EINVAL;
883
884 w9966_pdev_claim(cam);
885 w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer
886 w9966_wReg(cam, 0x00, 0x00); // Return to normal operation
887 w9966_wReg(cam, 0x01, 0x98); // Enable capture
888
889 // write special capture-addr and negotiate into data transfer
890 if (
891 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )||
892 (parport_write(cam->pport, &addr, 1) != 1 )||
893 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0 )
894 ) {
895 w9966_pdev_release(cam);
896 return -EFAULT;
897 }
898
899 tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
900 if (tbuf == NULL) {
901 count = -ENOMEM;
902 goto out;
903 }
904
905 while(dleft > 0)
906 {
907 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
908
909 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
910 count = -EFAULT;
911 goto out;
912 }
913 if (copy_to_user(dest, tbuf, tsize) != 0) {
914 count = -EFAULT;
915 goto out;
916 }
917 dest += tsize;
918 dleft -= tsize;
919 }
920
921 w9966_wReg(cam, 0x01, 0x18); // Disable capture
922
923out:
924 kfree(tbuf);
925 w9966_pdev_release(cam);
926
927 return count;
928}
929
930
931// Called once for every parport on init
932static void w9966_attach(struct parport *port)
933{
934 int i;
935
936 for (i = 0; i < W9966_MAXCAMS; i++)
937 {
938 if (w9966_cams[i].dev_state != 0) // Cam is already assigned
939 continue;
940 if (
941 strcmp(pardev[i], "aggressive") == 0 ||
942 strcmp(pardev[i], port->name) == 0
943 ) {
944 if (w9966_init(&w9966_cams[i], port) != 0)
945 w9966_term(&w9966_cams[i]);
946 break; // return
947 }
948 }
949}
950
951// Called once for every parport on termination
952static void w9966_detach(struct parport *port)
953{
954 int i;
955 for (i = 0; i < W9966_MAXCAMS; i++)
956 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
957 w9966_term(&w9966_cams[i]);
958}
959
960
961static struct parport_driver w9966_ppd = {
962 .name = W9966_DRIVERNAME,
963 .attach = w9966_attach,
964 .detach = w9966_detach,
965};
966
967// Module entry point
968static int __init w9966_mod_init(void)
969{
970 int i;
971 for (i = 0; i < W9966_MAXCAMS; i++)
972 w9966_cams[i].dev_state = 0;
973
974 return parport_register_driver(&w9966_ppd);
975}
976
977// Module cleanup
978static void __exit w9966_mod_term(void)
979{
980 parport_unregister_driver(&w9966_ppd);
981}
982
983module_init(w9966_mod_init);
984module_exit(w9966_mod_term);
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
new file mode 100644
index 000000000000..9fe6ad3b6352
--- /dev/null
+++ b/drivers/media/video/zoran.h
@@ -0,0 +1,515 @@
1/*
2 * zoran - Iomega Buz driver
3 *
4 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
5 *
6 * based on
7 *
8 * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 *
10 * and
11 *
12 * bttv - Bt848 frame grabber driver
13 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
14 * & Marcus Metzler (mocm@thp.uni-koeln.de)
15 *
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
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#ifndef _BUZ_H_
32#define _BUZ_H_
33
34struct zoran_requestbuffers {
35 unsigned long count; /* Number of buffers for MJPEG grabbing */
36 unsigned long size; /* Size PER BUFFER in bytes */
37};
38
39struct zoran_sync {
40 unsigned long frame; /* number of buffer that has been free'd */
41 unsigned long length; /* number of code bytes in buffer (capture only) */
42 unsigned long seq; /* frame sequence number */
43 struct timeval timestamp; /* timestamp */
44};
45
46struct zoran_status {
47 int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
48 int signal; /* Returned: 1 if valid video signal detected */
49 int norm; /* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
50 int color; /* Returned: 1 if color signal detected */
51};
52
53struct zoran_params {
54
55 /* The following parameters can only be queried */
56
57 int major_version; /* Major version number of driver */
58 int minor_version; /* Minor version number of driver */
59
60 /* Main control parameters */
61
62 int input; /* Input channel: 0 = Composite, 1 = S-VHS */
63 int norm; /* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
64 int decimation; /* decimation of captured video,
65 * enlargement of video played back.
66 * Valid values are 1, 2, 4 or 0.
67 * 0 is a special value where the user
68 * has full control over video scaling */
69
70 /* The following parameters only have to be set if decimation==0,
71 * for other values of decimation they provide the data how the image is captured */
72
73 int HorDcm; /* Horizontal decimation: 1, 2 or 4 */
74 int VerDcm; /* Vertical decimation: 1 or 2 */
75 int TmpDcm; /* Temporal decimation: 1 or 2,
76 * if TmpDcm==2 in capture every second frame is dropped,
77 * in playback every frame is played twice */
78 int field_per_buff; /* Number of fields per buffer: 1 or 2 */
79 int img_x; /* start of image in x direction */
80 int img_y; /* start of image in y direction */
81 int img_width; /* image width BEFORE decimation,
82 * must be a multiple of HorDcm*16 */
83 int img_height; /* image height BEFORE decimation,
84 * must be a multiple of VerDcm*8 */
85
86 /* --- End of parameters for decimation==0 only --- */
87
88 /* JPEG control parameters */
89
90 int quality; /* Measure for quality of compressed images.
91 * Scales linearly with the size of the compressed images.
92 * Must be beetween 0 and 100, 100 is a compression
93 * ratio of 1:4 */
94
95 int odd_even; /* Which field should come first ??? */
96
97 int APPn; /* Number of APP segment to be written, must be 0..15 */
98 int APP_len; /* Length of data in JPEG APPn segment */
99 char APP_data[60]; /* Data in the JPEG APPn segment. */
100
101 int COM_len; /* Length of data in JPEG COM segment */
102 char COM_data[60]; /* Data in JPEG COM segment */
103
104 unsigned long jpeg_markers; /* Which markers should go into the JPEG output.
105 * Unless you exactly know what you do, leave them untouched.
106 * Inluding less markers will make the resulting code
107 * smaller, but there will be fewer aplications
108 * which can read it.
109 * The presence of the APP and COM marker is
110 * influenced by APP0_len and COM_len ONLY! */
111#define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
112#define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
113#define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
114#define JPEG_MARKER_COM (1<<6) /* Comment segment */
115#define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */
116
117 int VFIFO_FB; /* Flag for enabling Video Fifo Feedback.
118 * If this flag is turned on and JPEG decompressing
119 * is going to the screen, the decompress process
120 * is stopped every time the Video Fifo is full.
121 * This enables a smooth decompress to the screen
122 * but the video output signal will get scrambled */
123
124 /* Misc */
125
126 char reserved[312]; /* Makes 512 bytes for this structure */
127};
128
129/*
130Private IOCTL to set up for displaying MJPEG
131*/
132#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct zoran_params)
133#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOCPRIVATE+1, struct zoran_params)
134#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOCPRIVATE+2, struct zoran_requestbuffers)
135#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+3, int)
136#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOCPRIVATE+4, int)
137#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOCPRIVATE+5, struct zoran_sync)
138#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOCPRIVATE+6, struct zoran_status)
139
140
141#ifdef __KERNEL__
142
143#define MAJOR_VERSION 0 /* driver major version */
144#define MINOR_VERSION 9 /* driver minor version */
145#define RELEASE_VERSION 5 /* release version */
146
147#define ZORAN_NAME "ZORAN" /* name of the device */
148
149#define ZR_DEVNAME(zr) ((zr)->name)
150
151#define BUZ_MAX_WIDTH (zr->timing->Wa)
152#define BUZ_MAX_HEIGHT (zr->timing->Ha)
153#define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */
154#define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */
155
156#define BUZ_NUM_STAT_COM 4
157#define BUZ_MASK_STAT_COM 3
158
159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
161
162#define BUZ_MAX_INPUT 8
163
164#if VIDEO_MAX_FRAME <= 32
165# define V4L_MAX_FRAME 32
166#elif VIDEO_MAX_FRAME <= 64
167# define V4L_MAX_FRAME 64
168#else
169# error "Too many video frame buffers to handle"
170#endif
171#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
172
173#define MAX_KMALLOC_MEM (128*1024)
174
175#include "zr36057.h"
176
177enum card_type {
178 UNKNOWN = -1,
179
180 /* Pinnacle/Miro */
181 DC10_old, /* DC30 like */
182 DC10_new, /* DC10plus like */
183 DC10plus,
184 DC30,
185 DC30plus,
186
187 /* Linux Media Labs */
188 LML33,
189 LML33R10,
190
191 /* Iomega */
192 BUZ,
193
194 /* total number of cards */
195 NUM_CARDS
196};
197
198enum zoran_codec_mode {
199 BUZ_MODE_IDLE, /* nothing going on */
200 BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */
201 BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */
202 BUZ_MODE_STILL_COMPRESS, /* still frame conversion */
203 BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */
204};
205
206enum zoran_buffer_state {
207 BUZ_STATE_USER, /* buffer is owned by application */
208 BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */
209 BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */
210 BUZ_STATE_DONE /* buffer is ready to return to application */
211};
212
213enum zoran_map_mode {
214 ZORAN_MAP_MODE_RAW,
215 ZORAN_MAP_MODE_JPG_REC,
216#define ZORAN_MAP_MODE_JPG ZORAN_MAP_MODE_JPG_REC
217 ZORAN_MAP_MODE_JPG_PLAY,
218};
219
220enum gpio_type {
221 GPIO_JPEG_SLEEP = 0,
222 GPIO_JPEG_RESET,
223 GPIO_JPEG_FRAME,
224 GPIO_VID_DIR,
225 GPIO_VID_EN,
226 GPIO_VID_RESET,
227 GPIO_CLK_SEL1,
228 GPIO_CLK_SEL2,
229 GPIO_MAX,
230};
231
232enum gpcs_type {
233 GPCS_JPEG_RESET = 0,
234 GPCS_JPEG_START,
235 GPCS_MAX,
236};
237
238struct zoran_format {
239 char *name;
240 int palette;
241 __u32 fourcc;
242 int colorspace;
243 int depth;
244 __u32 flags;
245};
246/* flags */
247#define ZORAN_FORMAT_COMPRESSED 1<<0
248#define ZORAN_FORMAT_OVERLAY 1<<1
249#define ZORAN_FORMAT_CAPTURE 1<<2
250#define ZORAN_FORMAT_PLAYBACK 1<<3
251
252/* overlay-settings */
253struct zoran_overlay_settings {
254 int is_set;
255 int x, y, width, height; /* position */
256 int clipcount; /* position and number of clips */
257 const struct zoran_format *format; /* overlay format */
258};
259
260/* v4l-capture settings */
261struct zoran_v4l_settings {
262 int width, height, bytesperline; /* capture size */
263 const struct zoran_format *format; /* capture format */
264};
265
266/* whoops, this one is undeclared if !v4l2 */
267#ifndef HAVE_V4L2
268struct v4l2_jpegcompression {
269 int quality;
270 int APPn;
271 int APP_len;
272 char APP_data[60];
273 int COM_len;
274 char COM_data[60];
275 __u32 jpeg_markers;
276 __u8 reserved[116];
277};
278#endif
279
280/* jpg-capture/-playback settings */
281struct zoran_jpg_settings {
282 int decimation; /* this bit is used to set everything to default */
283 int HorDcm, VerDcm, TmpDcm; /* capture decimation settings (TmpDcm=1 means both fields) */
284 int field_per_buff, odd_even; /* field-settings (odd_even=1 (+TmpDcm=1) means top-field-first) */
285 int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */
286 struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */
287};
288
289struct zoran_mapping {
290 struct file *file;
291 int count;
292};
293
294struct zoran_jpg_buffer {
295 struct zoran_mapping *map;
296 u32 *frag_tab; /* addresses of frag table */
297 u32 frag_tab_bus; /* same value cached to save time in ISR */
298 enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
299 struct zoran_sync bs; /* DONE: info to return to application */
300};
301
302struct zoran_v4l_buffer {
303 struct zoran_mapping *map;
304 char *fbuffer; /* virtual address of frame buffer */
305 unsigned long fbuffer_phys; /* physical address of frame buffer */
306 unsigned long fbuffer_bus; /* bus address of frame buffer */
307 enum zoran_buffer_state state; /* state: unused/pending/done */
308 struct zoran_sync bs; /* DONE: info to return to application */
309};
310
311enum zoran_lock_activity {
312 ZORAN_FREE, /* free for use */
313 ZORAN_ACTIVE, /* active but unlocked */
314 ZORAN_LOCKED, /* locked */
315};
316
317/* buffer collections */
318struct zoran_jpg_struct {
319 enum zoran_lock_activity active; /* feature currently in use? */
320 struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */
321 int num_buffers, buffer_size;
322 u8 allocated; /* Flag if buffers are allocated */
323 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
324 u8 need_contiguous; /* Flag if contiguous buffers are needed */
325};
326
327struct zoran_v4l_struct {
328 enum zoran_lock_activity active; /* feature currently in use? */
329 struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
330 int num_buffers, buffer_size;
331 u8 allocated; /* Flag if buffers are allocated */
332 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
333};
334
335struct zoran;
336
337/* zoran_fh contains per-open() settings */
338struct zoran_fh {
339 struct zoran *zr;
340
341 enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
342
343 struct zoran_overlay_settings overlay_settings;
344 u32 *overlay_mask; /* overlay mask */
345 enum zoran_lock_activity overlay_active; /* feature currently in use? */
346
347 struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
348 struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
349
350 struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
351 struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
352};
353
354struct card_info {
355 enum card_type type;
356 char name[32];
357 u16 i2c_decoder, i2c_encoder; /* I2C types */
358 u16 video_vfe, video_codec; /* videocodec types */
359 u16 audio_chip; /* audio type */
360 u16 vendor_id, device_id; /* subsystem vendor/device ID */
361
362 int inputs; /* number of video inputs */
363 struct input {
364 int muxsel;
365 char name[32];
366 } input[BUZ_MAX_INPUT];
367
368 int norms;
369 struct tvnorm *tvn[3]; /* supported TV norms */
370
371 u32 jpeg_int; /* JPEG interrupt */
372 u32 vsync_int; /* VSYNC interrupt */
373 s8 gpio[GPIO_MAX];
374 u8 gpcs[GPCS_MAX];
375
376 struct vfe_polarity vfe_pol;
377 u8 gpio_pol[GPIO_MAX];
378
379 /* is the /GWS line conected? */
380 u8 gws_not_connected;
381
382 void (*init) (struct zoran * zr);
383};
384
385struct zoran {
386 struct video_device *video_dev;
387
388 struct i2c_adapter i2c_adapter; /* */
389 struct i2c_algo_bit_data i2c_algo; /* */
390 u32 i2cbr;
391
392 struct i2c_client *decoder; /* video decoder i2c client */
393 struct i2c_client *encoder; /* video encoder i2c client */
394
395 struct videocodec *codec; /* video codec */
396 struct videocodec *vfe; /* video front end */
397
398 struct semaphore resource_lock; /* prevent evil stuff */
399
400 u8 initialized; /* flag if zoran has been correctly initalized */
401 int user; /* number of current users */
402 struct card_info card;
403 struct tvnorm *timing;
404
405 unsigned short id; /* number of this device */
406 char name[32]; /* name of this device */
407 struct pci_dev *pci_dev; /* PCI device */
408 unsigned char revision; /* revision of zr36057 */
409 unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
410 unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
411
412 spinlock_t spinlock; /* Spinlock */
413
414 /* Video for Linux parameters */
415 int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */
416 int hue, saturation, contrast, brightness; /* Current picture params */
417 struct video_buffer buffer; /* Current buffer params */
418 struct zoran_overlay_settings overlay_settings;
419 u32 *overlay_mask; /* overlay mask */
420 enum zoran_lock_activity overlay_active; /* feature currently in use? */
421
422 wait_queue_head_t v4l_capq;
423
424 int v4l_overlay_active; /* Overlay grab is activated */
425 int v4l_memgrab_active; /* Memory grab is activated */
426
427 int v4l_grab_frame; /* Frame number being currently grabbed */
428#define NO_GRAB_ACTIVE (-1)
429 unsigned long v4l_grab_seq; /* Number of frames grabbed */
430 struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
431
432 /* V4L grab queue of frames pending */
433 unsigned long v4l_pend_head;
434 unsigned long v4l_pend_tail;
435 unsigned long v4l_sync_tail;
436 int v4l_pend[V4L_MAX_FRAME];
437 struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
438
439 /* Buz MJPEG parameters */
440 enum zoran_codec_mode codec_mode; /* status of codec */
441 struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
442
443 wait_queue_head_t jpg_capq; /* wait here for grab to finish */
444
445 /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
446 /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
447 /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
448 unsigned long jpg_que_head; /* Index where to put next buffer which is queued */
449 unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */
450 unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */
451 unsigned long jpg_que_tail; /* Index of last buffer in queue */
452 unsigned long jpg_seq_num; /* count of frames since grab/play started */
453 unsigned long jpg_err_seq; /* last seq_num before error */
454 unsigned long jpg_err_shift;
455 unsigned long jpg_queued_num; /* count of frames queued since grab/play started */
456
457 /* zr36057's code buffer table */
458 u32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
459
460 /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
461 int jpg_pend[BUZ_MAX_FRAME];
462
463 /* array indexed by frame number */
464 struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
465
466 /* Additional stuff for testing */
467#ifdef CONFIG_PROC_FS
468 struct proc_dir_entry *zoran_proc;
469#else
470 void *zoran_proc;
471#endif
472 int testing;
473 int jpeg_error;
474 int intr_counter_GIRQ1;
475 int intr_counter_GIRQ0;
476 int intr_counter_CodRepIRQ;
477 int intr_counter_JPEGRepIRQ;
478 int field_counter;
479 int IRQ1_in;
480 int IRQ1_out;
481 int JPEG_in;
482 int JPEG_out;
483 int JPEG_0;
484 int JPEG_1;
485 int END_event_missed;
486 int JPEG_missed;
487 int JPEG_error;
488 int num_errors;
489 int JPEG_max_missed;
490 int JPEG_min_missed;
491
492 u32 last_isr;
493 unsigned long frame_num;
494
495 wait_queue_head_t test_q;
496};
497
498/*The following should be done in more portable way. It depends on define
499 of _ALPHA_BUZ in the Makefile.*/
500
501#ifdef _ALPHA_BUZ
502#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr))
503#define btread(adr) readl(zr->zr36057_adr+(adr))
504#else
505#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
506#define btread(adr) readl(zr->zr36057_mem+(adr))
507#endif
508
509#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
510#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
511#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
512
513#endif /* __kernel__ */
514
515#endif
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
new file mode 100644
index 000000000000..25743085b2d5
--- /dev/null
+++ b/drivers/media/video/zoran_card.c
@@ -0,0 +1,1583 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/vmalloc.h>
36
37#include <linux/proc_fs.h>
38#include <linux/i2c.h>
39#include <linux/i2c-algo-bit.h>
40#include <linux/videodev.h>
41#include <linux/spinlock.h>
42#include <linux/sem.h>
43#include <linux/kmod.h>
44#include <linux/wait.h>
45
46#include <linux/pci.h>
47#include <linux/interrupt.h>
48#include <linux/video_decoder.h>
49#include <linux/video_encoder.h>
50
51#include <asm/io.h>
52
53#include "videocodec.h"
54#include "zoran.h"
55#include "zoran_card.h"
56#include "zoran_device.h"
57#include "zoran_procfs.h"
58
59#define I2C_NAME(x) (x)->name
60
61extern const struct zoran_format zoran_formats[];
62
63static int card[BUZ_MAX] = { -1, -1, -1, -1 };
64module_param_array(card, int, NULL, 0);
65MODULE_PARM_DESC(card, "The type of card");
66
67static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
68module_param_array(encoder, int, NULL, 0);
69MODULE_PARM_DESC(encoder, "i2c TV encoder");
70
71static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
72module_param_array(decoder, int, NULL, 0);
73MODULE_PARM_DESC(decoder, "i2c TV decoder");
74
75/*
76 The video mem address of the video card.
77 The driver has a little database for some videocards
78 to determine it from there. If your video card is not in there
79 you have either to give it to the driver as a parameter
80 or set in in a VIDIOCSFBUF ioctl
81 */
82
83static unsigned long vidmem = 0; /* Video memory base address */
84module_param(vidmem, ulong, 0);
85
86/*
87 Default input and video norm at startup of the driver.
88*/
89
90static int default_input = 0; /* 0=Composite, 1=S-Video */
91module_param(default_input, int, 0);
92MODULE_PARM_DESC(default_input,
93 "Default input (0=Composite, 1=S-Video, 2=Internal)");
94
95static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */
96module_param(default_norm, int, 0);
97MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
98
99static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
100module_param(video_nr, int, 0);
101MODULE_PARM_DESC(video_nr, "video device number");
102
103/*
104 Number and size of grab buffers for Video 4 Linux
105 The vast majority of applications should not need more than 2,
106 the very popular BTTV driver actually does ONLY have 2.
107 Time sensitive applications might need more, the maximum
108 is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
109
110 The size is set so that the maximum possible request
111 can be satisfied. Decrease it, if bigphys_area alloc'd
112 memory is low. If you don't have the bigphys_area patch,
113 set it to 128 KB. Will you allow only to grab small
114 images with V4L, but that's better than nothing.
115
116 v4l_bufsize has to be given in KB !
117
118*/
119
120int v4l_nbufs = 2;
121int v4l_bufsize = 128; /* Everybody should be able to work with this setting */
122module_param(v4l_nbufs, int, 0);
123MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
124module_param(v4l_bufsize, int, 0);
125MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
126
127int jpg_nbufs = 32;
128int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */
129module_param(jpg_nbufs, int, 0);
130MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
131module_param(jpg_bufsize, int, 0);
132MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
133
134int pass_through = 0; /* 1=Pass through TV signal when device is not used */
135 /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
136module_param(pass_through, int, 0);
137MODULE_PARM_DESC(pass_through,
138 "Pass TV signal through to TV-out when idling");
139
140static int debug = 1;
141int *zr_debug = &debug;
142module_param(debug, int, 0);
143MODULE_PARM_DESC(debug, "Debug level (0-4)");
144
145MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
146MODULE_AUTHOR("Serguei Miridonov");
147MODULE_LICENSE("GPL");
148
149static struct pci_device_id zr36067_pci_tbl[] = {
150 {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057,
151 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
152 {0}
153};
154MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
155
156#define dprintk(num, format, args...) \
157 do { \
158 if (*zr_debug >= num) \
159 printk(format, ##args); \
160 } while (0)
161
162int zoran_num; /* number of Buzs in use */
163struct zoran zoran[BUZ_MAX];
164
165/* videocodec bus functions ZR36060 */
166static u32
167zr36060_read (struct videocodec *codec,
168 u16 reg)
169{
170 struct zoran *zr = (struct zoran *) codec->master_data->data;
171 __u32 data;
172
173 if (post_office_wait(zr)
174 || post_office_write(zr, 0, 1, reg >> 8)
175 || post_office_write(zr, 0, 2, reg & 0xff)) {
176 return -1;
177 }
178
179 data = post_office_read(zr, 0, 3) & 0xff;
180 return data;
181}
182
183static void
184zr36060_write (struct videocodec *codec,
185 u16 reg,
186 u32 val)
187{
188 struct zoran *zr = (struct zoran *) codec->master_data->data;
189
190 if (post_office_wait(zr)
191 || post_office_write(zr, 0, 1, reg >> 8)
192 || post_office_write(zr, 0, 2, reg & 0xff)) {
193 return;
194 }
195
196 post_office_write(zr, 0, 3, val & 0xff);
197}
198
199/* videocodec bus functions ZR36050 */
200static u32
201zr36050_read (struct videocodec *codec,
202 u16 reg)
203{
204 struct zoran *zr = (struct zoran *) codec->master_data->data;
205 __u32 data;
206
207 if (post_office_wait(zr)
208 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
209 return -1;
210 }
211
212 data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read
213 return data;
214}
215
216static void
217zr36050_write (struct videocodec *codec,
218 u16 reg,
219 u32 val)
220{
221 struct zoran *zr = (struct zoran *) codec->master_data->data;
222
223 if (post_office_wait(zr)
224 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
225 return;
226 }
227
228 post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data
229}
230
231/* videocodec bus functions ZR36016 */
232static u32
233zr36016_read (struct videocodec *codec,
234 u16 reg)
235{
236 struct zoran *zr = (struct zoran *) codec->master_data->data;
237 __u32 data;
238
239 if (post_office_wait(zr)) {
240 return -1;
241 }
242
243 data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read
244 return data;
245}
246
247/* hack for in zoran_device.c */
248void
249zr36016_write (struct videocodec *codec,
250 u16 reg,
251 u32 val)
252{
253 struct zoran *zr = (struct zoran *) codec->master_data->data;
254
255 if (post_office_wait(zr)) {
256 return;
257 }
258
259 post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data
260}
261
262/*
263 * Board specific information
264 */
265
266static void
267dc10_init (struct zoran *zr)
268{
269 dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr));
270
271 /* Pixel clock selection */
272 GPIO(zr, 4, 0);
273 GPIO(zr, 5, 1);
274 /* Enable the video bus sync signals */
275 GPIO(zr, 7, 0);
276}
277
278static void
279dc10plus_init (struct zoran *zr)
280{
281 dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr));
282}
283
284static void
285buz_init (struct zoran *zr)
286{
287 dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr));
288
289 /* some stuff from Iomega */
290 pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
291 pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
292 pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
293}
294
295static void
296lml33_init (struct zoran *zr)
297{
298 dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr));
299
300 GPIO(zr, 2, 1); // Set Composite input/output
301}
302
303static char *
304i2cid_to_modulename (u16 i2c_id)
305{
306 char *name = NULL;
307
308 switch (i2c_id) {
309 case I2C_DRIVERID_SAA7110:
310 name = "saa7110";
311 break;
312 case I2C_DRIVERID_SAA7111A:
313 name = "saa7111";
314 break;
315 case I2C_DRIVERID_SAA7114:
316 name = "saa7114";
317 break;
318 case I2C_DRIVERID_SAA7185B:
319 name = "saa7185";
320 break;
321 case I2C_DRIVERID_ADV7170:
322 name = "adv7170";
323 break;
324 case I2C_DRIVERID_ADV7175:
325 name = "adv7175";
326 break;
327 case I2C_DRIVERID_BT819:
328 name = "bt819";
329 break;
330 case I2C_DRIVERID_BT856:
331 name = "bt856";
332 break;
333 case I2C_DRIVERID_VPX3220:
334 name = "vpx3220";
335 break;
336/* case I2C_DRIVERID_VPX3224:
337 name = "vpx3224";
338 break;
339 case I2C_DRIVERID_MSE3000:
340 name = "mse3000";
341 break;*/
342 default:
343 break;
344 }
345
346 return name;
347}
348
349static char *
350codecid_to_modulename (u16 codecid)
351{
352 char *name = NULL;
353
354 switch (codecid) {
355 case CODEC_TYPE_ZR36060:
356 name = "zr36060";
357 break;
358 case CODEC_TYPE_ZR36050:
359 name = "zr36050";
360 break;
361 case CODEC_TYPE_ZR36016:
362 name = "zr36016";
363 break;
364 default:
365 break;
366 }
367
368 return name;
369}
370
371// struct tvnorm {
372// u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
373// };
374
375static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
376static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
377static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
378static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
379
380static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 };
381static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 };
382
383/* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */
384static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
385static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
386
387/* FIXME: I cannot swap U and V in saa7114, so i do one
388 * pixel left shift in zoran (75 -> 74)
389 * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */
390static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
391static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
392
393static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
394 {
395 .type = DC10_old,
396 .name = "DC10(old)",
397 .i2c_decoder = I2C_DRIVERID_VPX3220,
398 /*.i2c_encoder = I2C_DRIVERID_MSE3000,*/
399 .video_codec = CODEC_TYPE_ZR36050,
400 .video_vfe = CODEC_TYPE_ZR36016,
401
402 .inputs = 3,
403 .input = {
404 { 1, "Composite" },
405 { 2, "S-Video" },
406 { 0, "Internal/comp" }
407 },
408 .norms = 3,
409 .tvn = {
410 &f50sqpixel_dc10,
411 &f60sqpixel_dc10,
412 &f50sqpixel_dc10
413 },
414 .jpeg_int = 0,
415 .vsync_int = ZR36057_ISR_GIRQ1,
416 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
417 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
418 .gpcs = { -1, 0 },
419 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
420 .gws_not_connected = 0,
421 .init = &dc10_init,
422 }, {
423 .type = DC10_new,
424 .name = "DC10(new)",
425 .i2c_decoder = I2C_DRIVERID_SAA7110,
426 .i2c_encoder = I2C_DRIVERID_ADV7175,
427 .video_codec = CODEC_TYPE_ZR36060,
428
429 .inputs = 3,
430 .input = {
431 { 0, "Composite" },
432 { 7, "S-Video" },
433 { 5, "Internal/comp" }
434 },
435 .norms = 3,
436 .tvn = {
437 &f50sqpixel,
438 &f60sqpixel,
439 &f50sqpixel},
440 .jpeg_int = ZR36057_ISR_GIRQ0,
441 .vsync_int = ZR36057_ISR_GIRQ1,
442 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
443 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
444 .gpcs = { -1, 1},
445 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
446 .gws_not_connected = 0,
447 .init = &dc10plus_init,
448 }, {
449 .type = DC10plus,
450 .name = "DC10plus",
451 .vendor_id = PCI_VENDOR_ID_MIRO,
452 .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
453 .i2c_decoder = I2C_DRIVERID_SAA7110,
454 .i2c_encoder = I2C_DRIVERID_ADV7175,
455 .video_codec = CODEC_TYPE_ZR36060,
456
457 .inputs = 3,
458 .input = {
459 { 0, "Composite" },
460 { 7, "S-Video" },
461 { 5, "Internal/comp" }
462 },
463 .norms = 3,
464 .tvn = {
465 &f50sqpixel,
466 &f60sqpixel,
467 &f50sqpixel
468 },
469 .jpeg_int = ZR36057_ISR_GIRQ0,
470 .vsync_int = ZR36057_ISR_GIRQ1,
471 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
472 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
473 .gpcs = { -1, 1 },
474 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
475 .gws_not_connected = 0,
476 .init = &dc10plus_init,
477 }, {
478 .type = DC30,
479 .name = "DC30",
480 .i2c_decoder = I2C_DRIVERID_VPX3220,
481 .i2c_encoder = I2C_DRIVERID_ADV7175,
482 .video_codec = CODEC_TYPE_ZR36050,
483 .video_vfe = CODEC_TYPE_ZR36016,
484
485 .inputs = 3,
486 .input = {
487 { 1, "Composite" },
488 { 2, "S-Video" },
489 { 0, "Internal/comp" }
490 },
491 .norms = 3,
492 .tvn = {
493 &f50sqpixel_dc10,
494 &f60sqpixel_dc10,
495 &f50sqpixel_dc10
496 },
497 .jpeg_int = 0,
498 .vsync_int = ZR36057_ISR_GIRQ1,
499 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
500 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
501 .gpcs = { -1, 0 },
502 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
503 .gws_not_connected = 0,
504 .init = &dc10_init,
505 }, {
506 .type = DC30plus,
507 .name = "DC30plus",
508 .vendor_id = PCI_VENDOR_ID_MIRO,
509 .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
510 .i2c_decoder = I2C_DRIVERID_VPX3220,
511 .i2c_encoder = I2C_DRIVERID_ADV7175,
512 .video_codec = CODEC_TYPE_ZR36050,
513 .video_vfe = CODEC_TYPE_ZR36016,
514
515 .inputs = 3,
516 .input = {
517 { 1, "Composite" },
518 { 2, "S-Video" },
519 { 0, "Internal/comp" }
520 },
521 .norms = 3,
522 .tvn = {
523 &f50sqpixel_dc10,
524 &f60sqpixel_dc10,
525 &f50sqpixel_dc10
526 },
527 .jpeg_int = 0,
528 .vsync_int = ZR36057_ISR_GIRQ1,
529 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
530 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
531 .gpcs = { -1, 0 },
532 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
533 .gws_not_connected = 0,
534 .init = &dc10_init,
535 }, {
536 .type = LML33,
537 .name = "LML33",
538 .i2c_decoder = I2C_DRIVERID_BT819,
539 .i2c_encoder = I2C_DRIVERID_BT856,
540 .video_codec = CODEC_TYPE_ZR36060,
541
542 .inputs = 2,
543 .input = {
544 { 0, "Composite" },
545 { 7, "S-Video" }
546 },
547 .norms = 2,
548 .tvn = {
549 &f50ccir601_lml33,
550 &f60ccir601_lml33,
551 NULL
552 },
553 .jpeg_int = ZR36057_ISR_GIRQ1,
554 .vsync_int = ZR36057_ISR_GIRQ0,
555 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
556 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
557 .gpcs = { 3, 1 },
558 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
559 .gws_not_connected = 1,
560 .init = &lml33_init,
561 }, {
562 .type = LML33R10,
563 .name = "LML33R10",
564 .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
565 .device_id = PCI_DEVICE_ID_LML_33R10,
566 .i2c_decoder = I2C_DRIVERID_SAA7114,
567 .i2c_encoder = I2C_DRIVERID_ADV7170,
568 .video_codec = CODEC_TYPE_ZR36060,
569
570 .inputs = 2,
571 .input = {
572 { 0, "Composite" },
573 { 7, "S-Video" }
574 },
575 .norms = 2,
576 .tvn = {
577 &f50ccir601_lm33r10,
578 &f60ccir601_lm33r10,
579 NULL
580 },
581 .jpeg_int = ZR36057_ISR_GIRQ1,
582 .vsync_int = ZR36057_ISR_GIRQ0,
583 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
584 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
585 .gpcs = { 3, 1 },
586 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
587 .gws_not_connected = 1,
588 .init = &lml33_init,
589 }, {
590 .type = BUZ,
591 .name = "Buz",
592 .vendor_id = PCI_VENDOR_ID_IOMEGA,
593 .device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
594 .i2c_decoder = I2C_DRIVERID_SAA7111A,
595 .i2c_encoder = I2C_DRIVERID_SAA7185B,
596 .video_codec = CODEC_TYPE_ZR36060,
597
598 .inputs = 2,
599 .input = {
600 { 3, "Composite" },
601 { 7, "S-Video" }
602 },
603 .norms = 3,
604 .tvn = {
605 &f50ccir601,
606 &f60ccir601,
607 &f50ccir601
608 },
609 .jpeg_int = ZR36057_ISR_GIRQ1,
610 .vsync_int = ZR36057_ISR_GIRQ0,
611 .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
612 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
613 .gpcs = { 3, 1 },
614 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
615 .gws_not_connected = 1,
616 .init = &buz_init,
617 }
618};
619
620/*
621 * I2C functions
622 */
623/* software I2C functions */
624static int
625zoran_i2c_getsda (void *data)
626{
627 struct zoran *zr = (struct zoran *) data;
628
629 return (btread(ZR36057_I2CBR) >> 1) & 1;
630}
631
632static int
633zoran_i2c_getscl (void *data)
634{
635 struct zoran *zr = (struct zoran *) data;
636
637 return btread(ZR36057_I2CBR) & 1;
638}
639
640static void
641zoran_i2c_setsda (void *data,
642 int state)
643{
644 struct zoran *zr = (struct zoran *) data;
645
646 if (state)
647 zr->i2cbr |= 2;
648 else
649 zr->i2cbr &= ~2;
650 btwrite(zr->i2cbr, ZR36057_I2CBR);
651}
652
653static void
654zoran_i2c_setscl (void *data,
655 int state)
656{
657 struct zoran *zr = (struct zoran *) data;
658
659 if (state)
660 zr->i2cbr |= 1;
661 else
662 zr->i2cbr &= ~1;
663 btwrite(zr->i2cbr, ZR36057_I2CBR);
664}
665
666static int
667zoran_i2c_client_register (struct i2c_client *client)
668{
669 struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
670 int res = 0;
671
672 dprintk(2,
673 KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
674 ZR_DEVNAME(zr), client->driver->id);
675
676 down(&zr->resource_lock);
677
678 if (zr->user > 0) {
679 /* we're already busy, so we keep a reference to
680 * them... Could do a lot of stuff here, but this
681 * is easiest. (Did I ever mention I'm a lazy ass?)
682 */
683 res = -EBUSY;
684 goto clientreg_unlock_and_return;
685 }
686
687 if (client->driver->id == zr->card.i2c_decoder)
688 zr->decoder = client;
689 else if (client->driver->id == zr->card.i2c_encoder)
690 zr->encoder = client;
691 else {
692 res = -ENODEV;
693 goto clientreg_unlock_and_return;
694 }
695
696clientreg_unlock_and_return:
697 up(&zr->resource_lock);
698
699 return res;
700}
701
702static int
703zoran_i2c_client_unregister (struct i2c_client *client)
704{
705 struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
706 int res = 0;
707
708 dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
709
710 down(&zr->resource_lock);
711
712 if (zr->user > 0) {
713 res = -EBUSY;
714 goto clientunreg_unlock_and_return;
715 }
716
717 /* try to locate it */
718 if (client == zr->encoder) {
719 zr->encoder = NULL;
720 } else if (client == zr->decoder) {
721 zr->decoder = NULL;
722 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id);
723 }
724clientunreg_unlock_and_return:
725 up(&zr->resource_lock);
726 return res;
727}
728
729static struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
730 .setsda = zoran_i2c_setsda,
731 .setscl = zoran_i2c_setscl,
732 .getsda = zoran_i2c_getsda,
733 .getscl = zoran_i2c_getscl,
734 .udelay = 10,
735 .mdelay = 0,
736 .timeout = 100,
737};
738
739static struct i2c_adapter zoran_i2c_adapter_template = {
740 I2C_DEVNAME("zr36057"),
741 .id = I2C_HW_B_ZR36067,
742 .algo = NULL,
743 .client_register = zoran_i2c_client_register,
744 .client_unregister = zoran_i2c_client_unregister,
745};
746
747static int
748zoran_register_i2c (struct zoran *zr)
749{
750 memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
751 sizeof(struct i2c_algo_bit_data));
752 zr->i2c_algo.data = zr;
753 memcpy(&zr->i2c_adapter, &zoran_i2c_adapter_template,
754 sizeof(struct i2c_adapter));
755 strncpy(I2C_NAME(&zr->i2c_adapter), ZR_DEVNAME(zr),
756 sizeof(I2C_NAME(&zr->i2c_adapter)) - 1);
757 i2c_set_adapdata(&zr->i2c_adapter, zr);
758 zr->i2c_adapter.algo_data = &zr->i2c_algo;
759 return i2c_bit_add_bus(&zr->i2c_adapter);
760}
761
762static void
763zoran_unregister_i2c (struct zoran *zr)
764{
765 i2c_bit_del_bus((&zr->i2c_adapter));
766}
767
768/* Check a zoran_params struct for correctness, insert default params */
769
770int
771zoran_check_jpg_settings (struct zoran *zr,
772 struct zoran_jpg_settings *settings)
773{
774 int err = 0, err0 = 0;
775
776 dprintk(4,
777 KERN_DEBUG
778 "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
779 ZR_DEVNAME(zr), settings->decimation, settings->HorDcm,
780 settings->VerDcm, settings->TmpDcm);
781 dprintk(4,
782 KERN_DEBUG
783 "%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n",
784 ZR_DEVNAME(zr), settings->img_x, settings->img_y,
785 settings->img_width, settings->img_height);
786 /* Check decimation, set default values for decimation = 1, 2, 4 */
787 switch (settings->decimation) {
788 case 1:
789
790 settings->HorDcm = 1;
791 settings->VerDcm = 1;
792 settings->TmpDcm = 1;
793 settings->field_per_buff = 2;
794 settings->img_x = 0;
795 settings->img_y = 0;
796 settings->img_width = BUZ_MAX_WIDTH;
797 settings->img_height = BUZ_MAX_HEIGHT / 2;
798 break;
799 case 2:
800
801 settings->HorDcm = 2;
802 settings->VerDcm = 1;
803 settings->TmpDcm = 2;
804 settings->field_per_buff = 1;
805 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
806 settings->img_y = 0;
807 settings->img_width =
808 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
809 settings->img_height = BUZ_MAX_HEIGHT / 2;
810 break;
811 case 4:
812
813 if (zr->card.type == DC10_new) {
814 dprintk(1,
815 KERN_DEBUG
816 "%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n",
817 ZR_DEVNAME(zr));
818 err0++;
819 break;
820 }
821
822 settings->HorDcm = 4;
823 settings->VerDcm = 2;
824 settings->TmpDcm = 2;
825 settings->field_per_buff = 1;
826 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
827 settings->img_y = 0;
828 settings->img_width =
829 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
830 settings->img_height = BUZ_MAX_HEIGHT / 2;
831 break;
832 case 0:
833
834 /* We have to check the data the user has set */
835
836 if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
837 (zr->card.type == DC10_new || settings->HorDcm != 4))
838 err0++;
839 if (settings->VerDcm != 1 && settings->VerDcm != 2)
840 err0++;
841 if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
842 err0++;
843 if (settings->field_per_buff != 1 &&
844 settings->field_per_buff != 2)
845 err0++;
846 if (settings->img_x < 0)
847 err0++;
848 if (settings->img_y < 0)
849 err0++;
850 if (settings->img_width < 0)
851 err0++;
852 if (settings->img_height < 0)
853 err0++;
854 if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
855 err0++;
856 if (settings->img_y + settings->img_height >
857 BUZ_MAX_HEIGHT / 2)
858 err0++;
859 if (settings->HorDcm && settings->VerDcm) {
860 if (settings->img_width %
861 (16 * settings->HorDcm) != 0)
862 err0++;
863 if (settings->img_height %
864 (8 * settings->VerDcm) != 0)
865 err0++;
866 }
867
868 if (err0) {
869 dprintk(1,
870 KERN_ERR
871 "%s: check_jpg_settings() - error in params for decimation = 0\n",
872 ZR_DEVNAME(zr));
873 err++;
874 }
875 break;
876 default:
877 dprintk(1,
878 KERN_ERR
879 "%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n",
880 ZR_DEVNAME(zr), settings->decimation);
881 err++;
882 break;
883 }
884
885 if (settings->jpg_comp.quality > 100)
886 settings->jpg_comp.quality = 100;
887 if (settings->jpg_comp.quality < 5)
888 settings->jpg_comp.quality = 5;
889 if (settings->jpg_comp.APPn < 0)
890 settings->jpg_comp.APPn = 0;
891 if (settings->jpg_comp.APPn > 15)
892 settings->jpg_comp.APPn = 15;
893 if (settings->jpg_comp.APP_len < 0)
894 settings->jpg_comp.APP_len = 0;
895 if (settings->jpg_comp.APP_len > 60)
896 settings->jpg_comp.APP_len = 60;
897 if (settings->jpg_comp.COM_len < 0)
898 settings->jpg_comp.COM_len = 0;
899 if (settings->jpg_comp.COM_len > 60)
900 settings->jpg_comp.COM_len = 60;
901 if (err)
902 return -EINVAL;
903 return 0;
904}
905
906void
907zoran_open_init_params (struct zoran *zr)
908{
909 int i;
910
911 /* User must explicitly set a window */
912 zr->overlay_settings.is_set = 0;
913 zr->overlay_mask = NULL;
914 zr->overlay_active = ZORAN_FREE;
915
916 zr->v4l_memgrab_active = 0;
917 zr->v4l_overlay_active = 0;
918 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
919 zr->v4l_grab_seq = 0;
920 zr->v4l_settings.width = 192;
921 zr->v4l_settings.height = 144;
922 zr->v4l_settings.format = &zoran_formats[4]; /* YUY2 - YUV-4:2:2 packed */
923 zr->v4l_settings.bytesperline =
924 zr->v4l_settings.width *
925 ((zr->v4l_settings.format->depth + 7) / 8);
926
927 /* DMA ring stuff for V4L */
928 zr->v4l_pend_tail = 0;
929 zr->v4l_pend_head = 0;
930 zr->v4l_sync_tail = 0;
931 zr->v4l_buffers.active = ZORAN_FREE;
932 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
933 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
934 }
935 zr->v4l_buffers.allocated = 0;
936
937 for (i = 0; i < BUZ_MAX_FRAME; i++) {
938 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
939 }
940 zr->jpg_buffers.active = ZORAN_FREE;
941 zr->jpg_buffers.allocated = 0;
942 /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
943 zr->jpg_settings.decimation = 1;
944 zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
945 if (zr->card.type != BUZ)
946 zr->jpg_settings.odd_even = 1;
947 else
948 zr->jpg_settings.odd_even = 0;
949 zr->jpg_settings.jpg_comp.APPn = 0;
950 zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */
951 memset(zr->jpg_settings.jpg_comp.APP_data, 0,
952 sizeof(zr->jpg_settings.jpg_comp.APP_data));
953 zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */
954 memset(zr->jpg_settings.jpg_comp.COM_data, 0,
955 sizeof(zr->jpg_settings.jpg_comp.COM_data));
956 zr->jpg_settings.jpg_comp.jpeg_markers =
957 JPEG_MARKER_DHT | JPEG_MARKER_DQT;
958 i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
959 if (i)
960 dprintk(1,
961 KERN_ERR
962 "%s: zoran_open_init_params() internal error\n",
963 ZR_DEVNAME(zr));
964
965 clear_interrupt_counters(zr);
966 zr->testing = 0;
967}
968
969static void __devinit
970test_interrupts (struct zoran *zr)
971{
972 DEFINE_WAIT(wait);
973 int timeout, icr;
974
975 clear_interrupt_counters(zr);
976
977 zr->testing = 1;
978 icr = btread(ZR36057_ICR);
979 btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR);
980 prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE);
981 timeout = schedule_timeout(HZ);
982 finish_wait(&zr->test_q, &wait);
983 btwrite(0, ZR36057_ICR);
984 btwrite(0x78000000, ZR36057_ISR);
985 zr->testing = 0;
986 dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr));
987 if (timeout) {
988 dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
989 }
990 if (*zr_debug > 1)
991 print_interrupts(zr);
992 btwrite(icr, ZR36057_ICR);
993}
994
995static int __devinit
996zr36057_init (struct zoran *zr)
997{
998 unsigned long mem;
999 void *vdev;
1000 unsigned mem_needed;
1001 int j;
1002 int two = 2;
1003 int zero = 0;
1004
1005 dprintk(1,
1006 KERN_INFO
1007 "%s: zr36057_init() - initializing card[%d], zr=%p\n",
1008 ZR_DEVNAME(zr), zr->id, zr);
1009
1010 /* default setup of all parameters which will persist between opens */
1011 zr->user = 0;
1012
1013 init_waitqueue_head(&zr->v4l_capq);
1014 init_waitqueue_head(&zr->jpg_capq);
1015 init_waitqueue_head(&zr->test_q);
1016 zr->jpg_buffers.allocated = 0;
1017 zr->v4l_buffers.allocated = 0;
1018
1019 zr->buffer.base = (void *) vidmem;
1020 zr->buffer.width = 0;
1021 zr->buffer.height = 0;
1022 zr->buffer.depth = 0;
1023 zr->buffer.bytesperline = 0;
1024
1025 /* Avoid nonsense settings from user for default input/norm */
1026 if (default_norm < VIDEO_MODE_PAL &&
1027 default_norm > VIDEO_MODE_SECAM)
1028 default_norm = VIDEO_MODE_PAL;
1029 zr->norm = default_norm;
1030 if (!(zr->timing = zr->card.tvn[zr->norm])) {
1031 dprintk(1,
1032 KERN_WARNING
1033 "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
1034 ZR_DEVNAME(zr));
1035 zr->norm = VIDEO_MODE_PAL;
1036 zr->timing = zr->card.tvn[zr->norm];
1037 }
1038
1039 zr->input = default_input = (default_input ? 1 : 0);
1040
1041 /* Should the following be reset at every open ? */
1042 zr->hue = 32768;
1043 zr->contrast = 32768;
1044 zr->saturation = 32768;
1045 zr->brightness = 32768;
1046
1047 /* default setup (will be repeated at every open) */
1048 zoran_open_init_params(zr);
1049
1050 /* allocate memory *before* doing anything to the hardware
1051 * in case allocation fails */
1052 mem_needed = BUZ_NUM_STAT_COM * 4;
1053 mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL);
1054 vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL);
1055 if (!mem || !vdev) {
1056 dprintk(1,
1057 KERN_ERR
1058 "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
1059 ZR_DEVNAME(zr));
1060 if (vdev)
1061 kfree(vdev);
1062 if (mem)
1063 kfree((void *)mem);
1064 return -ENOMEM;
1065 }
1066 memset((void *) mem, 0, mem_needed);
1067 zr->stat_com = (u32 *) mem;
1068 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1069 zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */
1070 }
1071
1072 /*
1073 * Now add the template and register the device unit.
1074 */
1075 zr->video_dev = vdev;
1076 memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
1077 strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
1078 if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER,
1079 video_nr) < 0) {
1080 zoran_unregister_i2c(zr);
1081 kfree((void *) zr->stat_com);
1082 kfree(vdev);
1083 return -1;
1084 }
1085
1086 zoran_init_hardware(zr);
1087 if (*zr_debug > 2)
1088 detect_guest_activity(zr);
1089 test_interrupts(zr);
1090 if (!pass_through) {
1091 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1092 encoder_command(zr, ENCODER_SET_INPUT, &two);
1093 }
1094
1095 zr->zoran_proc = NULL;
1096 zr->initialized = 1;
1097 return 0;
1098}
1099
1100static void
1101zoran_release (struct zoran *zr)
1102{
1103 if (!zr->initialized)
1104 return;
1105 /* unregister videocodec bus */
1106 if (zr->codec) {
1107 struct videocodec_master *master = zr->codec->master_data;
1108 videocodec_detach(zr->codec);
1109 if (master)
1110 kfree(master);
1111 }
1112 if (zr->vfe) {
1113 struct videocodec_master *master = zr->vfe->master_data;
1114 videocodec_detach(zr->vfe);
1115 if (master)
1116 kfree(master);
1117 }
1118
1119 /* unregister i2c bus */
1120 zoran_unregister_i2c(zr);
1121 /* disable PCI bus-mastering */
1122 zoran_set_pci_master(zr, 0);
1123 /* put chip into reset */
1124 btwrite(0, ZR36057_SPGPPCR);
1125 free_irq(zr->pci_dev->irq, zr);
1126 /* unmap and free memory */
1127 kfree((void *) zr->stat_com);
1128 zoran_proc_cleanup(zr);
1129 iounmap(zr->zr36057_mem);
1130 pci_disable_device(zr->pci_dev);
1131 video_unregister_device(zr->video_dev);
1132}
1133
1134void
1135zoran_vdev_release (struct video_device *vdev)
1136{
1137 kfree(vdev);
1138}
1139
1140static struct videocodec_master * __devinit
1141zoran_setup_videocodec (struct zoran *zr,
1142 int type)
1143{
1144 struct videocodec_master *m = NULL;
1145
1146 m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
1147 if (!m) {
1148 dprintk(1,
1149 KERN_ERR
1150 "%s: zoran_setup_videocodec() - no memory\n",
1151 ZR_DEVNAME(zr));
1152 return m;
1153 }
1154
1155 m->magic = 0L; /* magic not used */
1156 m->type = VID_HARDWARE_ZR36067;
1157 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
1158 strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
1159 m->data = zr;
1160
1161 switch (type)
1162 {
1163 case CODEC_TYPE_ZR36060:
1164 m->readreg = zr36060_read;
1165 m->writereg = zr36060_write;
1166 m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
1167 break;
1168 case CODEC_TYPE_ZR36050:
1169 m->readreg = zr36050_read;
1170 m->writereg = zr36050_write;
1171 m->flags |= CODEC_FLAG_JPEG;
1172 break;
1173 case CODEC_TYPE_ZR36016:
1174 m->readreg = zr36016_read;
1175 m->writereg = zr36016_write;
1176 m->flags |= CODEC_FLAG_VFE;
1177 break;
1178 }
1179
1180 return m;
1181}
1182
1183/*
1184 * Scan for a Buz card (actually for the PCI contoler ZR36057),
1185 * request the irq and map the io memory
1186 */
1187static int __devinit
1188find_zr36057 (void)
1189{
1190 unsigned char latency, need_latency;
1191 struct zoran *zr;
1192 struct pci_dev *dev = NULL;
1193 int result;
1194 struct videocodec_master *master_vfe = NULL;
1195 struct videocodec_master *master_codec = NULL;
1196 int card_num;
1197 char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
1198
1199 zoran_num = 0;
1200 while (zoran_num < BUZ_MAX &&
1201 (dev =
1202 pci_find_device(PCI_VENDOR_ID_ZORAN,
1203 PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
1204 card_num = card[zoran_num];
1205 zr = &zoran[zoran_num];
1206 memset(zr, 0, sizeof(struct zoran)); // Just in case if previous cycle failed
1207 zr->pci_dev = dev;
1208 //zr->zr36057_mem = NULL;
1209 zr->id = zoran_num;
1210 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
1211 spin_lock_init(&zr->spinlock);
1212 init_MUTEX(&zr->resource_lock);
1213 if (pci_enable_device(dev))
1214 continue;
1215 zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
1216 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
1217 &zr->revision);
1218 if (zr->revision < 2) {
1219 dprintk(1,
1220 KERN_INFO
1221 "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
1222 ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
1223 zr->zr36057_adr);
1224
1225 if (card_num == -1) {
1226 dprintk(1,
1227 KERN_ERR
1228 "%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
1229 ZR_DEVNAME(zr));
1230 continue;
1231 }
1232 } else {
1233 int i;
1234 unsigned short ss_vendor, ss_device;
1235
1236 ss_vendor = zr->pci_dev->subsystem_vendor;
1237 ss_device = zr->pci_dev->subsystem_device;
1238 dprintk(1,
1239 KERN_INFO
1240 "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
1241 ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
1242 zr->zr36057_adr);
1243 dprintk(1,
1244 KERN_INFO
1245 "%s: subsystem vendor=0x%04x id=0x%04x\n",
1246 ZR_DEVNAME(zr), ss_vendor, ss_device);
1247 if (card_num == -1) {
1248 dprintk(3,
1249 KERN_DEBUG
1250 "%s: find_zr36057() - trying to autodetect card type\n",
1251 ZR_DEVNAME(zr));
1252 for (i=0;i<NUM_CARDS;i++) {
1253 if (ss_vendor == zoran_cards[i].vendor_id &&
1254 ss_device == zoran_cards[i].device_id) {
1255 dprintk(3,
1256 KERN_DEBUG
1257 "%s: find_zr36057() - card %s detected\n",
1258 ZR_DEVNAME(zr),
1259 zoran_cards[i].name);
1260 card_num = i;
1261 break;
1262 }
1263 }
1264 if (i == NUM_CARDS) {
1265 dprintk(1,
1266 KERN_ERR
1267 "%s: find_zr36057() - unknown card\n",
1268 ZR_DEVNAME(zr));
1269 continue;
1270 }
1271 }
1272 }
1273
1274 if (card_num < 0 || card_num >= NUM_CARDS) {
1275 dprintk(2,
1276 KERN_ERR
1277 "%s: find_zr36057() - invalid cardnum %d\n",
1278 ZR_DEVNAME(zr), card_num);
1279 continue;
1280 }
1281
1282 /* even though we make this a non pointer and thus
1283 * theoretically allow for making changes to this struct
1284 * on a per-individual card basis at runtime, this is
1285 * strongly discouraged. This structure is intended to
1286 * keep general card information, no settings or anything */
1287 zr->card = zoran_cards[card_num];
1288 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
1289 "%s[%u]", zr->card.name, zr->id);
1290
1291 zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
1292 if (!zr->zr36057_mem) {
1293 dprintk(1,
1294 KERN_ERR
1295 "%s: find_zr36057() - ioremap failed\n",
1296 ZR_DEVNAME(zr));
1297 continue;
1298 }
1299
1300 result = request_irq(zr->pci_dev->irq,
1301 zoran_irq,
1302 SA_SHIRQ | SA_INTERRUPT,
1303 ZR_DEVNAME(zr),
1304 (void *) zr);
1305 if (result < 0) {
1306 if (result == -EINVAL) {
1307 dprintk(1,
1308 KERN_ERR
1309 "%s: find_zr36057() - bad irq number or handler\n",
1310 ZR_DEVNAME(zr));
1311 } else if (result == -EBUSY) {
1312 dprintk(1,
1313 KERN_ERR
1314 "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
1315 ZR_DEVNAME(zr), zr->pci_dev->irq);
1316 } else {
1317 dprintk(1,
1318 KERN_ERR
1319 "%s: find_zr36057() - can't assign irq, error code %d\n",
1320 ZR_DEVNAME(zr), result);
1321 }
1322 goto zr_unmap;
1323 }
1324
1325 /* set PCI latency timer */
1326 pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1327 &latency);
1328 need_latency = zr->revision > 1 ? 32 : 48;
1329 if (latency != need_latency) {
1330 dprintk(2,
1331 KERN_INFO
1332 "%s: Changing PCI latency from %d to %d.\n",
1333 ZR_DEVNAME(zr), latency, need_latency);
1334 pci_write_config_byte(zr->pci_dev,
1335 PCI_LATENCY_TIMER,
1336 need_latency);
1337 }
1338
1339 zr36057_restart(zr);
1340 /* i2c */
1341 dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
1342 ZR_DEVNAME(zr));
1343
1344 /* i2c decoder */
1345 if (decoder[zr->id] != -1) {
1346 i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
1347 zr->card.i2c_decoder = decoder[zr->id];
1348 } else if (zr->card.i2c_decoder != 0) {
1349 i2c_dec_name =
1350 i2cid_to_modulename(zr->card.i2c_decoder);
1351 } else {
1352 i2c_dec_name = NULL;
1353 }
1354
1355 if (i2c_dec_name) {
1356 if ((result = request_module(i2c_dec_name)) < 0) {
1357 dprintk(1,
1358 KERN_ERR
1359 "%s: failed to load module %s: %d\n",
1360 ZR_DEVNAME(zr), i2c_dec_name, result);
1361 }
1362 }
1363
1364 /* i2c encoder */
1365 if (encoder[zr->id] != -1) {
1366 i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
1367 zr->card.i2c_encoder = encoder[zr->id];
1368 } else if (zr->card.i2c_encoder != 0) {
1369 i2c_enc_name =
1370 i2cid_to_modulename(zr->card.i2c_encoder);
1371 } else {
1372 i2c_enc_name = NULL;
1373 }
1374
1375 if (i2c_enc_name) {
1376 if ((result = request_module(i2c_enc_name)) < 0) {
1377 dprintk(1,
1378 KERN_ERR
1379 "%s: failed to load module %s: %d\n",
1380 ZR_DEVNAME(zr), i2c_enc_name, result);
1381 }
1382 }
1383
1384 if (zoran_register_i2c(zr) < 0) {
1385 dprintk(1,
1386 KERN_ERR
1387 "%s: find_zr36057() - can't initialize i2c bus\n",
1388 ZR_DEVNAME(zr));
1389 goto zr_free_irq;
1390 }
1391
1392 dprintk(2,
1393 KERN_INFO "%s: Initializing videocodec bus...\n",
1394 ZR_DEVNAME(zr));
1395
1396 if (zr->card.video_codec != 0 &&
1397 (codec_name =
1398 codecid_to_modulename(zr->card.video_codec)) != NULL) {
1399 if ((result = request_module(codec_name)) < 0) {
1400 dprintk(1,
1401 KERN_ERR
1402 "%s: failed to load modules %s: %d\n",
1403 ZR_DEVNAME(zr), codec_name, result);
1404 }
1405 }
1406 if (zr->card.video_vfe != 0 &&
1407 (vfe_name =
1408 codecid_to_modulename(zr->card.video_vfe)) != NULL) {
1409 if ((result = request_module(vfe_name)) < 0) {
1410 dprintk(1,
1411 KERN_ERR
1412 "%s: failed to load modules %s: %d\n",
1413 ZR_DEVNAME(zr), vfe_name, result);
1414 }
1415 }
1416
1417 /* reset JPEG codec */
1418 jpeg_codec_sleep(zr, 1);
1419 jpeg_codec_reset(zr);
1420 /* video bus enabled */
1421 /* display codec revision */
1422 if (zr->card.video_codec != 0) {
1423 master_codec = zoran_setup_videocodec(zr,
1424 zr->card.video_codec);
1425 if (!master_codec)
1426 goto zr_unreg_i2c;
1427 zr->codec = videocodec_attach(master_codec);
1428 if (!zr->codec) {
1429 dprintk(1,
1430 KERN_ERR
1431 "%s: find_zr36057() - no codec found\n",
1432 ZR_DEVNAME(zr));
1433 goto zr_free_codec;
1434 }
1435 if (zr->codec->type != zr->card.video_codec) {
1436 dprintk(1,
1437 KERN_ERR
1438 "%s: find_zr36057() - wrong codec\n",
1439 ZR_DEVNAME(zr));
1440 goto zr_detach_codec;
1441 }
1442 }
1443 if (zr->card.video_vfe != 0) {
1444 master_vfe = zoran_setup_videocodec(zr,
1445 zr->card.video_vfe);
1446 if (!master_vfe)
1447 goto zr_detach_codec;
1448 zr->vfe = videocodec_attach(master_vfe);
1449 if (!zr->vfe) {
1450 dprintk(1,
1451 KERN_ERR
1452 "%s: find_zr36057() - no VFE found\n",
1453 ZR_DEVNAME(zr));
1454 goto zr_free_vfe;
1455 }
1456 if (zr->vfe->type != zr->card.video_vfe) {
1457 dprintk(1,
1458 KERN_ERR
1459 "%s: find_zr36057() = wrong VFE\n",
1460 ZR_DEVNAME(zr));
1461 goto zr_detach_vfe;
1462 }
1463 }
1464
1465 zoran_num++;
1466 continue;
1467
1468 // Init errors
1469 zr_detach_vfe:
1470 videocodec_detach(zr->vfe);
1471 zr_free_vfe:
1472 kfree(master_vfe);
1473 zr_detach_codec:
1474 videocodec_detach(zr->codec);
1475 zr_free_codec:
1476 kfree(master_codec);
1477 zr_unreg_i2c:
1478 zoran_unregister_i2c(zr);
1479 zr_free_irq:
1480 btwrite(0, ZR36057_SPGPPCR);
1481 free_irq(zr->pci_dev->irq, zr);
1482 zr_unmap:
1483 iounmap(zr->zr36057_mem);
1484 continue;
1485 }
1486 if (zoran_num == 0) {
1487 dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
1488 }
1489 return zoran_num;
1490}
1491
1492static int __init
1493init_dc10_cards (void)
1494{
1495 int i;
1496
1497 memset(zoran, 0, sizeof(zoran));
1498 printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
1499 MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
1500
1501 /* Look for cards */
1502 if (find_zr36057() < 0) {
1503 return -EIO;
1504 }
1505 if (zoran_num == 0)
1506 return -ENODEV;
1507 dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
1508 zoran_num);
1509 /* check the parameters we have been given, adjust if necessary */
1510 if (v4l_nbufs < 2)
1511 v4l_nbufs = 2;
1512 if (v4l_nbufs > VIDEO_MAX_FRAME)
1513 v4l_nbufs = VIDEO_MAX_FRAME;
1514 /* The user specfies the in KB, we want them in byte
1515 * (and page aligned) */
1516 v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
1517 if (v4l_bufsize < 32768)
1518 v4l_bufsize = 32768;
1519 /* 2 MB is arbitrary but sufficient for the maximum possible images */
1520 if (v4l_bufsize > 2048 * 1024)
1521 v4l_bufsize = 2048 * 1024;
1522 if (jpg_nbufs < 4)
1523 jpg_nbufs = 4;
1524 if (jpg_nbufs > BUZ_MAX_FRAME)
1525 jpg_nbufs = BUZ_MAX_FRAME;
1526 jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024);
1527 if (jpg_bufsize < 8192)
1528 jpg_bufsize = 8192;
1529 if (jpg_bufsize > (512 * 1024))
1530 jpg_bufsize = 512 * 1024;
1531 /* Use parameter for vidmem or try to find a video card */
1532 if (vidmem) {
1533 dprintk(1,
1534 KERN_INFO
1535 "%s: Using supplied video memory base address @ 0x%lx\n",
1536 ZORAN_NAME, vidmem);
1537 }
1538
1539 /* random nonsense */
1540 dprintk(5, KERN_DEBUG "Jotti is een held!\n");
1541
1542 /* some mainboards might not do PCI-PCI data transfer well */
1543 if (pci_pci_problems & PCIPCI_FAIL) {
1544 dprintk(1,
1545 KERN_WARNING
1546 "%s: chipset may not support reliable PCI-PCI DMA\n",
1547 ZORAN_NAME);
1548 }
1549
1550 /* take care of Natoma chipset and a revision 1 zr36057 */
1551 for (i = 0; i < zoran_num; i++) {
1552 struct zoran *zr = &zoran[i];
1553
1554 if (pci_pci_problems & PCIPCI_NATOMA && zr->revision <= 1) {
1555 zr->jpg_buffers.need_contiguous = 1;
1556 dprintk(1,
1557 KERN_INFO
1558 "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
1559 ZR_DEVNAME(zr));
1560 }
1561
1562 if (zr36057_init(zr) < 0) {
1563 for (i = 0; i < zoran_num; i++)
1564 zoran_release(&zoran[i]);
1565 return -EIO;
1566 }
1567 zoran_proc_init(zr);
1568 }
1569
1570 return 0;
1571}
1572
1573static void __exit
1574unload_dc10_cards (void)
1575{
1576 int i;
1577
1578 for (i = 0; i < zoran_num; i++)
1579 zoran_release(&zoran[i]);
1580}
1581
1582module_init(init_dc10_cards);
1583module_exit(unload_dc10_cards);
diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h
new file mode 100644
index 000000000000..e5b6acd3eedc
--- /dev/null
+++ b/drivers/media/video/zoran_card.h
@@ -0,0 +1,45 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_CARD_H__
31#define __ZORAN_CARD_H__
32
33/* Anybody who uses more than four? */
34#define BUZ_MAX 4
35extern int zoran_num;
36extern struct zoran zoran[BUZ_MAX];
37
38extern struct video_device zoran_template;
39
40extern int zoran_check_jpg_settings(struct zoran *zr,
41 struct zoran_jpg_settings *settings);
42extern void zoran_open_init_params(struct zoran *zr);
43extern void zoran_vdev_release(struct video_device *vdev);
44
45#endif /* __ZORAN_CARD_H__ */
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
new file mode 100644
index 000000000000..4e15afdec4c9
--- /dev/null
+++ b/drivers/media/video/zoran_device.c
@@ -0,0 +1,1785 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles device access (PCI/I2C/codec/...)
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35#include <linux/byteorder/generic.h>
36
37#include <linux/interrupt.h>
38#include <linux/proc_fs.h>
39#include <linux/i2c.h>
40#include <linux/i2c-algo-bit.h>
41#include <linux/videodev.h>
42#include <linux/spinlock.h>
43#include <linux/sem.h>
44
45#include <linux/pci.h>
46#include <linux/video_decoder.h>
47#include <linux/video_encoder.h>
48#include <linux/delay.h>
49#include <linux/wait.h>
50
51#include <asm/io.h>
52
53#include "videocodec.h"
54#include "zoran.h"
55#include "zoran_device.h"
56
57#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \
58 ZR36057_ISR_GIRQ1 | \
59 ZR36057_ISR_JPEGRepIRQ )
60
61extern const struct zoran_format zoran_formats[];
62
63extern int *zr_debug;
64
65#define dprintk(num, format, args...) \
66 do { \
67 if (*zr_debug >= num) \
68 printk(format, ##args); \
69 } while (0)
70
71static int lml33dpath = 0; /* 1 will use digital path in capture
72 * mode instead of analog. It can be
73 * used for picture adjustments using
74 * tool like xawtv while watching image
75 * on TV monitor connected to the output.
76 * However, due to absence of 75 Ohm
77 * load on Bt819 input, there will be
78 * some image imperfections */
79
80module_param(lml33dpath, bool, 0);
81MODULE_PARM_DESC(lml33dpath,
82 "Use digital path capture mode (on LML33 cards)");
83
84static void
85zr36057_init_vfe (struct zoran *zr);
86
87/*
88 * General Purpose I/O and Guest bus access
89 */
90
91/*
92 * This is a bit tricky. When a board lacks a GPIO function, the corresponding
93 * GPIO bit number in the card_info structure is set to 0.
94 */
95
96void
97GPIO (struct zoran *zr,
98 int bit,
99 unsigned int value)
100{
101 u32 reg;
102 u32 mask;
103
104 /* Make sure the bit number is legal
105 * A bit number of -1 (lacking) gives a mask of 0,
106 * making it harmless */
107 mask = (1 << (24 + bit)) & 0xff000000;
108 reg = btread(ZR36057_GPPGCR1) & ~mask;
109 if (value) {
110 reg |= mask;
111 }
112 btwrite(reg, ZR36057_GPPGCR1);
113 udelay(1);
114}
115
116/*
117 * Wait til post office is no longer busy
118 */
119
120int
121post_office_wait (struct zoran *zr)
122{
123 u32 por;
124
125// while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) {
126 while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) {
127 /* wait for something to happen */
128 }
129 if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) {
130 /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */
131 dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr),
132 por);
133 return -1;
134 }
135
136 return 0;
137}
138
139int
140post_office_write (struct zoran *zr,
141 unsigned int guest,
142 unsigned int reg,
143 unsigned int value)
144{
145 u32 por;
146
147 por =
148 ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) |
149 ((reg & 7) << 16) | (value & 0xFF);
150 btwrite(por, ZR36057_POR);
151
152 return post_office_wait(zr);
153}
154
155int
156post_office_read (struct zoran *zr,
157 unsigned int guest,
158 unsigned int reg)
159{
160 u32 por;
161
162 por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16);
163 btwrite(por, ZR36057_POR);
164 if (post_office_wait(zr) < 0) {
165 return -1;
166 }
167
168 return btread(ZR36057_POR) & 0xFF;
169}
170
171/*
172 * detect guests
173 */
174
175static void
176dump_guests (struct zoran *zr)
177{
178 if (*zr_debug > 2) {
179 int i, guest[8];
180
181 for (i = 1; i < 8; i++) { // Don't read jpeg codec here
182 guest[i] = post_office_read(zr, i, 0);
183 }
184
185 printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
186
187 for (i = 1; i < 8; i++) {
188 printk(" 0x%02x", guest[i]);
189 }
190 printk("\n");
191 }
192}
193
194static inline unsigned long
195get_time (void)
196{
197 struct timeval tv;
198
199 do_gettimeofday(&tv);
200 return (1000000 * tv.tv_sec + tv.tv_usec);
201}
202
203void
204detect_guest_activity (struct zoran *zr)
205{
206 int timeout, i, j, res, guest[8], guest0[8], change[8][3];
207 unsigned long t0, t1;
208
209 dump_guests(zr);
210 printk(KERN_INFO "%s: Detecting guests activity, please wait...\n",
211 ZR_DEVNAME(zr));
212 for (i = 1; i < 8; i++) { // Don't read jpeg codec here
213 guest0[i] = guest[i] = post_office_read(zr, i, 0);
214 }
215
216 timeout = 0;
217 j = 0;
218 t0 = get_time();
219 while (timeout < 10000) {
220 udelay(10);
221 timeout++;
222 for (i = 1; (i < 8) && (j < 8); i++) {
223 res = post_office_read(zr, i, 0);
224 if (res != guest[i]) {
225 t1 = get_time();
226 change[j][0] = (t1 - t0);
227 t0 = t1;
228 change[j][1] = i;
229 change[j][2] = res;
230 j++;
231 guest[i] = res;
232 }
233 }
234 if (j >= 8)
235 break;
236 }
237 printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
238
239 for (i = 1; i < 8; i++) {
240 printk(" 0x%02x", guest0[i]);
241 }
242 printk("\n");
243 if (j == 0) {
244 printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr));
245 return;
246 }
247 for (i = 0; i < j; i++) {
248 printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr),
249 change[i][0], change[i][1], change[i][2]);
250 }
251}
252
253/*
254 * JPEG Codec access
255 */
256
257void
258jpeg_codec_sleep (struct zoran *zr,
259 int sleep)
260{
261 GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
262 if (!sleep) {
263 dprintk(3,
264 KERN_DEBUG
265 "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n",
266 ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
267 udelay(500);
268 } else {
269 dprintk(3,
270 KERN_DEBUG
271 "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n",
272 ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
273 udelay(2);
274 }
275}
276
277int
278jpeg_codec_reset (struct zoran *zr)
279{
280 /* Take the codec out of sleep */
281 jpeg_codec_sleep(zr, 0);
282
283 if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) {
284 post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0,
285 0);
286 udelay(2);
287 } else {
288 GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
289 udelay(2);
290 GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
291 udelay(2);
292 }
293
294 return 0;
295}
296
297/*
298 * Set the registers for the size we have specified. Don't bother
299 * trying to understand this without the ZR36057 manual in front of
300 * you [AC].
301 *
302 * PS: The manual is free for download in .pdf format from
303 * www.zoran.com - nicely done those folks.
304 */
305
306static void
307zr36057_adjust_vfe (struct zoran *zr,
308 enum zoran_codec_mode mode)
309{
310 u32 reg;
311
312 switch (mode) {
313 case BUZ_MODE_MOTION_DECOMPRESS:
314 btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
315 reg = btread(ZR36057_VFEHCR);
316 if ((reg & (1 << 10)) && zr->card.type != LML33R10) {
317 reg += ((1 << 10) | 1);
318 }
319 btwrite(reg, ZR36057_VFEHCR);
320 break;
321 case BUZ_MODE_MOTION_COMPRESS:
322 case BUZ_MODE_IDLE:
323 default:
324 if (zr->norm == VIDEO_MODE_NTSC ||
325 (zr->card.type == LML33R10 &&
326 zr->norm == VIDEO_MODE_PAL))
327 btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
328 else
329 btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
330 reg = btread(ZR36057_VFEHCR);
331 if (!(reg & (1 << 10)) && zr->card.type != LML33R10) {
332 reg -= ((1 << 10) | 1);
333 }
334 btwrite(reg, ZR36057_VFEHCR);
335 break;
336 }
337}
338
339/*
340 * set geometry
341 */
342
343static void
344zr36057_set_vfe (struct zoran *zr,
345 int video_width,
346 int video_height,
347 const struct zoran_format *format)
348{
349 struct tvnorm *tvn;
350 unsigned HStart, HEnd, VStart, VEnd;
351 unsigned DispMode;
352 unsigned VidWinWid, VidWinHt;
353 unsigned hcrop1, hcrop2, vcrop1, vcrop2;
354 unsigned Wa, We, Ha, He;
355 unsigned X, Y, HorDcm, VerDcm;
356 u32 reg;
357 unsigned mask_line_size;
358
359 tvn = zr->timing;
360
361 Wa = tvn->Wa;
362 Ha = tvn->Ha;
363
364 dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
365 ZR_DEVNAME(zr), video_width, video_height);
366
367 if (zr->norm != VIDEO_MODE_PAL &&
368 zr->norm != VIDEO_MODE_NTSC &&
369 zr->norm != VIDEO_MODE_SECAM) {
370 dprintk(1,
371 KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
372 ZR_DEVNAME(zr), zr->norm);
373 return;
374 }
375 if (video_width < BUZ_MIN_WIDTH ||
376 video_height < BUZ_MIN_HEIGHT ||
377 video_width > Wa || video_height > Ha) {
378 dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n",
379 ZR_DEVNAME(zr), video_width, video_height);
380 return;
381 }
382
383 /**** zr36057 ****/
384
385 /* horizontal */
386 VidWinWid = video_width;
387 X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa;
388 We = (VidWinWid * 64) / X;
389 HorDcm = 64 - X;
390 hcrop1 = 2 * ((tvn->Wa - We) / 4);
391 hcrop2 = tvn->Wa - We - hcrop1;
392 HStart = tvn->HStart ? tvn->HStart : 1;
393 /* (Ronald) Original comment:
394 * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+"
395 * this is false. It inverses chroma values on the LML33R10 (so Cr
396 * suddenly is shown as Cb and reverse, really cool effect if you
397 * want to see blue faces, not useful otherwise). So don't use |1.
398 * However, the DC10 has '0' as HStart, but does need |1, so we
399 * use a dirty check...
400 */
401 HEnd = HStart + tvn->Wa - 1;
402 HStart += hcrop1;
403 HEnd -= hcrop2;
404 reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)
405 | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);
406 if (zr->card.vfe_pol.hsync_pol)
407 reg |= ZR36057_VFEHCR_HSPol;
408 btwrite(reg, ZR36057_VFEHCR);
409
410 /* Vertical */
411 DispMode = !(video_height > BUZ_MAX_HEIGHT / 2);
412 VidWinHt = DispMode ? video_height : video_height / 2;
413 Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha;
414 He = (VidWinHt * 64) / Y;
415 VerDcm = 64 - Y;
416 vcrop1 = (tvn->Ha / 2 - He) / 2;
417 vcrop2 = tvn->Ha / 2 - He - vcrop1;
418 VStart = tvn->VStart;
419 VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
420 VStart += vcrop1;
421 VEnd -= vcrop2;
422 reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)
423 | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);
424 if (zr->card.vfe_pol.vsync_pol)
425 reg |= ZR36057_VFEVCR_VSPol;
426 btwrite(reg, ZR36057_VFEVCR);
427
428 /* scaler and pixel format */
429 reg = 0;
430 reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);
431 reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);
432 reg |= (DispMode << ZR36057_VFESPFR_DispMode);
433 if (format->palette != VIDEO_PALETTE_YUV422)
434 reg |= ZR36057_VFESPFR_LittleEndian;
435 /* RJ: I don't know, why the following has to be the opposite
436 * of the corresponding ZR36060 setting, but only this way
437 * we get the correct colors when uncompressing to the screen */
438 //reg |= ZR36057_VFESPFR_VCLKPol; /**/
439 /* RJ: Don't know if that is needed for NTSC also */
440 if (zr->norm != VIDEO_MODE_NTSC)
441 reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
442 reg |= ZR36057_VFESPFR_TopField;
443 switch (format->palette) {
444
445 case VIDEO_PALETTE_YUV422:
446 reg |= ZR36057_VFESPFR_YUV422;
447 break;
448
449 case VIDEO_PALETTE_RGB555:
450 reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;
451 break;
452
453 case VIDEO_PALETTE_RGB565:
454 reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;
455 break;
456
457 case VIDEO_PALETTE_RGB24:
458 reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;
459 break;
460
461 case VIDEO_PALETTE_RGB32:
462 reg |= ZR36057_VFESPFR_RGB888;
463 break;
464
465 default:
466 dprintk(1,
467 KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n",
468 ZR_DEVNAME(zr), format->palette);
469 return;
470
471 }
472 if (HorDcm >= 48) {
473 reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */
474 } else if (HorDcm >= 32) {
475 reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */
476 } else if (HorDcm >= 16) {
477 reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */
478 }
479 btwrite(reg, ZR36057_VFESPFR);
480
481 /* display configuration */
482 reg = (16 << ZR36057_VDCR_MinPix)
483 | (VidWinHt << ZR36057_VDCR_VidWinHt)
484 | (VidWinWid << ZR36057_VDCR_VidWinWid);
485 if (pci_pci_problems & PCIPCI_TRITON)
486 // || zr->revision < 1) // Revision 1 has also Triton support
487 reg &= ~ZR36057_VDCR_Triton;
488 else
489 reg |= ZR36057_VDCR_Triton;
490 btwrite(reg, ZR36057_VDCR);
491
492 /* (Ronald) don't write this if overlay_mask = NULL */
493 if (zr->overlay_mask) {
494 /* Write overlay clipping mask data, but don't enable overlay clipping */
495 /* RJ: since this makes only sense on the screen, we use
496 * zr->overlay_settings.width instead of video_width */
497
498 mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
499 reg = virt_to_bus(zr->overlay_mask);
500 btwrite(reg, ZR36057_MMTR);
501 reg = virt_to_bus(zr->overlay_mask + mask_line_size);
502 btwrite(reg, ZR36057_MMBR);
503 reg =
504 mask_line_size - (zr->overlay_settings.width +
505 31) / 32;
506 if (DispMode == 0)
507 reg += mask_line_size;
508 reg <<= ZR36057_OCR_MaskStride;
509 btwrite(reg, ZR36057_OCR);
510 }
511
512 zr36057_adjust_vfe(zr, zr->codec_mode);
513}
514
515/*
516 * Switch overlay on or off
517 */
518
519void
520zr36057_overlay (struct zoran *zr,
521 int on)
522{
523 u32 reg;
524
525 if (on) {
526 /* do the necessary settings ... */
527 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */
528
529 zr36057_set_vfe(zr,
530 zr->overlay_settings.width,
531 zr->overlay_settings.height,
532 zr->overlay_settings.format);
533
534 /* Start and length of each line MUST be 4-byte aligned.
535 * This should be allready checked before the call to this routine.
536 * All error messages are internal driver checking only! */
537
538 /* video display top and bottom registers */
539 reg = (u32) zr->buffer.base +
540 zr->overlay_settings.x *
541 ((zr->overlay_settings.format->depth + 7) / 8) +
542 zr->overlay_settings.y *
543 zr->buffer.bytesperline;
544 btwrite(reg, ZR36057_VDTR);
545 if (reg & 3)
546 dprintk(1,
547 KERN_ERR
548 "%s: zr36057_overlay() - video_address not aligned\n",
549 ZR_DEVNAME(zr));
550 if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
551 reg += zr->buffer.bytesperline;
552 btwrite(reg, ZR36057_VDBR);
553
554 /* video stride, status, and frame grab register */
555 reg = zr->buffer.bytesperline -
556 zr->overlay_settings.width *
557 ((zr->overlay_settings.format->depth + 7) / 8);
558 if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
559 reg += zr->buffer.bytesperline;
560 if (reg & 3)
561 dprintk(1,
562 KERN_ERR
563 "%s: zr36057_overlay() - video_stride not aligned\n",
564 ZR_DEVNAME(zr));
565 reg = (reg << ZR36057_VSSFGR_DispStride);
566 reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */
567 btwrite(reg, ZR36057_VSSFGR);
568
569 /* Set overlay clipping */
570 if (zr->overlay_settings.clipcount > 0)
571 btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);
572
573 /* ... and switch it on */
574 btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
575 } else {
576 /* Switch it off */
577 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
578 }
579}
580
581/*
582 * The overlay mask has one bit for each pixel on a scan line,
583 * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
584 */
585
586void
587write_overlay_mask (struct file *file,
588 struct video_clip *vp,
589 int count)
590{
591 struct zoran_fh *fh = file->private_data;
592 struct zoran *zr = fh->zr;
593 unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
594 u32 *mask;
595 int x, y, width, height;
596 unsigned i, j, k;
597 u32 reg;
598
599 /* fill mask with one bits */
600 memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
601 reg = 0;
602
603 for (i = 0; i < count; ++i) {
604 /* pick up local copy of clip */
605 x = vp[i].x;
606 y = vp[i].y;
607 width = vp[i].width;
608 height = vp[i].height;
609
610 /* trim clips that extend beyond the window */
611 if (x < 0) {
612 width += x;
613 x = 0;
614 }
615 if (y < 0) {
616 height += y;
617 y = 0;
618 }
619 if (x + width > fh->overlay_settings.width) {
620 width = fh->overlay_settings.width - x;
621 }
622 if (y + height > fh->overlay_settings.height) {
623 height = fh->overlay_settings.height - y;
624 }
625
626 /* ignore degenerate clips */
627 if (height <= 0) {
628 continue;
629 }
630 if (width <= 0) {
631 continue;
632 }
633
634 /* apply clip for each scan line */
635 for (j = 0; j < height; ++j) {
636 /* reset bit for each pixel */
637 /* this can be optimized later if need be */
638 mask = fh->overlay_mask + (y + j) * mask_line_size;
639 for (k = 0; k < width; ++k) {
640 mask[(x + k) / 32] &=
641 ~((u32) 1 << (x + k) % 32);
642 }
643 }
644 }
645}
646
647/* Enable/Disable uncompressed memory grabbing of the 36057 */
648
649void
650zr36057_set_memgrab (struct zoran *zr,
651 int mode)
652{
653 if (mode) {
654 if (btread(ZR36057_VSSFGR) &
655 (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab))
656 dprintk(1,
657 KERN_WARNING
658 "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n",
659 ZR_DEVNAME(zr));
660
661 /* switch on VSync interrupts */
662 btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
663 btor(zr->card.vsync_int, ZR36057_ICR); // SW
664
665 /* enable SnapShot */
666 btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
667
668 /* Set zr36057 video front end and enable video */
669 zr36057_set_vfe(zr, zr->v4l_settings.width,
670 zr->v4l_settings.height,
671 zr->v4l_settings.format);
672
673 zr->v4l_memgrab_active = 1;
674 } else {
675 zr->v4l_memgrab_active = 0;
676
677 /* switch off VSync interrupts */
678 btand(~zr->card.vsync_int, ZR36057_ICR); // SW
679
680 /* reenable grabbing to screen if it was running */
681 if (zr->v4l_overlay_active) {
682 zr36057_overlay(zr, 1);
683 } else {
684 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
685 btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
686 }
687 }
688}
689
690int
691wait_grab_pending (struct zoran *zr)
692{
693 unsigned long flags;
694
695 /* wait until all pending grabs are finished */
696
697 if (!zr->v4l_memgrab_active)
698 return 0;
699
700 wait_event_interruptible(zr->v4l_capq,
701 (zr->v4l_pend_tail == zr->v4l_pend_head));
702 if (signal_pending(current))
703 return -ERESTARTSYS;
704
705 spin_lock_irqsave(&zr->spinlock, flags);
706 zr36057_set_memgrab(zr, 0);
707 spin_unlock_irqrestore(&zr->spinlock, flags);
708
709 return 0;
710}
711
712/*****************************************************************************
713 * *
714 * Set up the Buz-specific MJPEG part *
715 * *
716 *****************************************************************************/
717
718static inline void
719set_frame (struct zoran *zr,
720 int val)
721{
722 GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
723}
724
725static void
726set_videobus_dir (struct zoran *zr,
727 int val)
728{
729 switch (zr->card.type) {
730 case LML33:
731 case LML33R10:
732 if (lml33dpath == 0)
733 GPIO(zr, 5, val);
734 else
735 GPIO(zr, 5, 1);
736 break;
737 default:
738 GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
739 zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
740 break;
741 }
742}
743
744static void
745init_jpeg_queue (struct zoran *zr)
746{
747 int i;
748
749 /* re-initialize DMA ring stuff */
750 zr->jpg_que_head = 0;
751 zr->jpg_dma_head = 0;
752 zr->jpg_dma_tail = 0;
753 zr->jpg_que_tail = 0;
754 zr->jpg_seq_num = 0;
755 zr->JPEG_error = 0;
756 zr->num_errors = 0;
757 zr->jpg_err_seq = 0;
758 zr->jpg_err_shift = 0;
759 zr->jpg_queued_num = 0;
760 for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
761 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
762 }
763 for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
764 zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
765 }
766}
767
768static void
769zr36057_set_jpg (struct zoran *zr,
770 enum zoran_codec_mode mode)
771{
772 struct tvnorm *tvn;
773 u32 reg;
774
775 tvn = zr->timing;
776
777 /* assert P_Reset, disable code transfer, deassert Active */
778 btwrite(0, ZR36057_JPC);
779
780 /* MJPEG compression mode */
781 switch (mode) {
782
783 case BUZ_MODE_MOTION_COMPRESS:
784 default:
785 reg = ZR36057_JMC_MJPGCmpMode;
786 break;
787
788 case BUZ_MODE_MOTION_DECOMPRESS:
789 reg = ZR36057_JMC_MJPGExpMode;
790 reg |= ZR36057_JMC_SyncMstr;
791 /* RJ: The following is experimental - improves the output to screen */
792 //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM
793 break;
794
795 case BUZ_MODE_STILL_COMPRESS:
796 reg = ZR36057_JMC_JPGCmpMode;
797 break;
798
799 case BUZ_MODE_STILL_DECOMPRESS:
800 reg = ZR36057_JMC_JPGExpMode;
801 break;
802
803 }
804 reg |= ZR36057_JMC_JPG;
805 if (zr->jpg_settings.field_per_buff == 1)
806 reg |= ZR36057_JMC_Fld_per_buff;
807 btwrite(reg, ZR36057_JMC);
808
809 /* vertical */
810 btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);
811 reg = (6 << ZR36057_VSP_VsyncSize) |
812 (tvn->Ht << ZR36057_VSP_FrmTot);
813 btwrite(reg, ZR36057_VSP);
814 reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) |
815 (zr->jpg_settings.img_height << ZR36057_FVAP_PAY);
816 btwrite(reg, ZR36057_FVAP);
817
818 /* horizontal */
819 if (zr->card.vfe_pol.hsync_pol)
820 btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
821 else
822 btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
823 reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) |
824 (tvn->Wt << ZR36057_HSP_LineTot);
825 btwrite(reg, ZR36057_HSP);
826 reg = ((zr->jpg_settings.img_x +
827 tvn->HStart + 4) << ZR36057_FHAP_NAX) |
828 (zr->jpg_settings.img_width << ZR36057_FHAP_PAX);
829 btwrite(reg, ZR36057_FHAP);
830
831 /* field process parameters */
832 if (zr->jpg_settings.odd_even)
833 reg = ZR36057_FPP_Odd_Even;
834 else
835 reg = 0;
836
837 btwrite(reg, ZR36057_FPP);
838
839 /* Set proper VCLK Polarity, else colors will be wrong during playback */
840 //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
841
842 /* code base address */
843 reg = virt_to_bus(zr->stat_com);
844 btwrite(reg, ZR36057_JCBA);
845
846 /* FIFO threshold (FIFO is 160. double words) */
847 /* NOTE: decimal values here */
848 switch (mode) {
849
850 case BUZ_MODE_STILL_COMPRESS:
851 case BUZ_MODE_MOTION_COMPRESS:
852 if (zr->card.type != BUZ)
853 reg = 140;
854 else
855 reg = 60;
856 break;
857
858 case BUZ_MODE_STILL_DECOMPRESS:
859 case BUZ_MODE_MOTION_DECOMPRESS:
860 reg = 20;
861 break;
862
863 default:
864 reg = 80;
865 break;
866
867 }
868 btwrite(reg, ZR36057_JCFT);
869 zr36057_adjust_vfe(zr, mode);
870
871}
872
873void
874print_interrupts (struct zoran *zr)
875{
876 int res, noerr = 0;
877
878 printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr));
879 if ((res = zr->field_counter) < -1 || res > 1) {
880 printk(" FD:%d", res);
881 }
882 if ((res = zr->intr_counter_GIRQ1) != 0) {
883 printk(" GIRQ1:%d", res);
884 noerr++;
885 }
886 if ((res = zr->intr_counter_GIRQ0) != 0) {
887 printk(" GIRQ0:%d", res);
888 noerr++;
889 }
890 if ((res = zr->intr_counter_CodRepIRQ) != 0) {
891 printk(" CodRepIRQ:%d", res);
892 noerr++;
893 }
894 if ((res = zr->intr_counter_JPEGRepIRQ) != 0) {
895 printk(" JPEGRepIRQ:%d", res);
896 noerr++;
897 }
898 if (zr->JPEG_max_missed) {
899 printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed,
900 zr->JPEG_min_missed);
901 }
902 if (zr->END_event_missed) {
903 printk(" ENDs missed: %d", zr->END_event_missed);
904 }
905 //if (zr->jpg_queued_num) {
906 printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail,
907 zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head);
908 //}
909 if (!noerr) {
910 printk(": no interrupts detected.");
911 }
912 printk("\n");
913}
914
915void
916clear_interrupt_counters (struct zoran *zr)
917{
918 zr->intr_counter_GIRQ1 = 0;
919 zr->intr_counter_GIRQ0 = 0;
920 zr->intr_counter_CodRepIRQ = 0;
921 zr->intr_counter_JPEGRepIRQ = 0;
922 zr->field_counter = 0;
923 zr->IRQ1_in = 0;
924 zr->IRQ1_out = 0;
925 zr->JPEG_in = 0;
926 zr->JPEG_out = 0;
927 zr->JPEG_0 = 0;
928 zr->JPEG_1 = 0;
929 zr->END_event_missed = 0;
930 zr->JPEG_missed = 0;
931 zr->JPEG_max_missed = 0;
932 zr->JPEG_min_missed = 0x7fffffff;
933}
934
935static u32
936count_reset_interrupt (struct zoran *zr)
937{
938 u32 isr;
939
940 if ((isr = btread(ZR36057_ISR) & 0x78000000)) {
941 if (isr & ZR36057_ISR_GIRQ1) {
942 btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR);
943 zr->intr_counter_GIRQ1++;
944 }
945 if (isr & ZR36057_ISR_GIRQ0) {
946 btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR);
947 zr->intr_counter_GIRQ0++;
948 }
949 if (isr & ZR36057_ISR_CodRepIRQ) {
950 btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR);
951 zr->intr_counter_CodRepIRQ++;
952 }
953 if (isr & ZR36057_ISR_JPEGRepIRQ) {
954 btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR);
955 zr->intr_counter_JPEGRepIRQ++;
956 }
957 }
958 return isr;
959}
960
961/* hack */
962extern void zr36016_write (struct videocodec *codec,
963 u16 reg,
964 u32 val);
965
966void
967jpeg_start (struct zoran *zr)
968{
969 int reg;
970
971 zr->frame_num = 0;
972
973 /* deassert P_reset, disable code transfer, deassert Active */
974 btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
975 /* stop flushing the internal code buffer */
976 btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
977 /* enable code transfer */
978 btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC);
979
980 /* clear IRQs */
981 btwrite(IRQ_MASK, ZR36057_ISR);
982 /* enable the JPEG IRQs */
983 btwrite(zr->card.jpeg_int |
984 ZR36057_ICR_JPEGRepIRQ |
985 ZR36057_ICR_IntPinEn,
986 ZR36057_ICR);
987
988 set_frame(zr, 0); // \FRAME
989
990 /* set the JPEG codec guest ID */
991 reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) |
992 (0 << ZR36057_JCGI_JPEGuestReg);
993 btwrite(reg, ZR36057_JCGI);
994
995 if (zr->card.video_vfe == CODEC_TYPE_ZR36016 &&
996 zr->card.video_codec == CODEC_TYPE_ZR36050) {
997 /* Enable processing on the ZR36016 */
998 if (zr->vfe)
999 zr36016_write(zr->vfe, 0, 1);
1000
1001 /* load the address of the GO register in the ZR36050 latch */
1002 post_office_write(zr, 0, 0, 0);
1003 }
1004
1005 /* assert Active */
1006 btor(ZR36057_JPC_Active, ZR36057_JPC);
1007
1008 /* enable the Go generation */
1009 btor(ZR36057_JMC_Go_en, ZR36057_JMC);
1010 udelay(30);
1011
1012 set_frame(zr, 1); // /FRAME
1013
1014 dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr));
1015}
1016
1017void
1018zr36057_enable_jpg (struct zoran *zr,
1019 enum zoran_codec_mode mode)
1020{
1021 static int zero = 0;
1022 static int one = 1;
1023 struct vfe_settings cap;
1024 int field_size =
1025 zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
1026
1027 zr->codec_mode = mode;
1028
1029 cap.x = zr->jpg_settings.img_x;
1030 cap.y = zr->jpg_settings.img_y;
1031 cap.width = zr->jpg_settings.img_width;
1032 cap.height = zr->jpg_settings.img_height;
1033 cap.decimation =
1034 zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8);
1035 cap.quality = zr->jpg_settings.jpg_comp.quality;
1036
1037 switch (mode) {
1038
1039 case BUZ_MODE_MOTION_COMPRESS: {
1040 struct jpeg_app_marker app;
1041 struct jpeg_com_marker com;
1042
1043 /* In motion compress mode, the decoder output must be enabled, and
1044 * the video bus direction set to input.
1045 */
1046 set_videobus_dir(zr, 0);
1047 decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
1048 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1049
1050 /* Take the JPEG codec and the VFE out of sleep */
1051 jpeg_codec_sleep(zr, 0);
1052
1053 /* set JPEG app/com marker */
1054 app.appn = zr->jpg_settings.jpg_comp.APPn;
1055 app.len = zr->jpg_settings.jpg_comp.APP_len;
1056 memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
1057 zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
1058 sizeof(struct jpeg_app_marker), &app);
1059
1060 com.len = zr->jpg_settings.jpg_comp.COM_len;
1061 memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
1062 zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
1063 sizeof(struct jpeg_com_marker), &com);
1064
1065 /* Setup the JPEG codec */
1066 zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
1067 sizeof(int), &field_size);
1068 zr->codec->set_video(zr->codec, zr->timing, &cap,
1069 &zr->card.vfe_pol);
1070 zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION);
1071
1072 /* Setup the VFE */
1073 if (zr->vfe) {
1074 zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE,
1075 sizeof(int), &field_size);
1076 zr->vfe->set_video(zr->vfe, zr->timing, &cap,
1077 &zr->card.vfe_pol);
1078 zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION);
1079 }
1080
1081 init_jpeg_queue(zr);
1082 zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
1083
1084 clear_interrupt_counters(zr);
1085 dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n",
1086 ZR_DEVNAME(zr));
1087 break;
1088 }
1089
1090 case BUZ_MODE_MOTION_DECOMPRESS:
1091 /* In motion decompression mode, the decoder output must be disabled, and
1092 * the video bus direction set to output.
1093 */
1094 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1095 set_videobus_dir(zr, 1);
1096 encoder_command(zr, ENCODER_SET_INPUT, &one);
1097
1098 /* Take the JPEG codec and the VFE out of sleep */
1099 jpeg_codec_sleep(zr, 0);
1100 /* Setup the VFE */
1101 if (zr->vfe) {
1102 zr->vfe->set_video(zr->vfe, zr->timing, &cap,
1103 &zr->card.vfe_pol);
1104 zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION);
1105 }
1106 /* Setup the JPEG codec */
1107 zr->codec->set_video(zr->codec, zr->timing, &cap,
1108 &zr->card.vfe_pol);
1109 zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION);
1110
1111 init_jpeg_queue(zr);
1112 zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
1113
1114 clear_interrupt_counters(zr);
1115 dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n",
1116 ZR_DEVNAME(zr));
1117 break;
1118
1119 case BUZ_MODE_IDLE:
1120 default:
1121 /* shut down processing */
1122 btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ),
1123 ZR36057_ICR);
1124 btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ,
1125 ZR36057_ISR);
1126 btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en
1127
1128 msleep(50);
1129
1130 set_videobus_dir(zr, 0);
1131 set_frame(zr, 1); // /FRAME
1132 btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush
1133 btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active
1134 btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
1135 btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);
1136 jpeg_codec_reset(zr);
1137 jpeg_codec_sleep(zr, 1);
1138 zr36057_adjust_vfe(zr, mode);
1139
1140 decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
1141 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1142
1143 dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
1144 break;
1145
1146 }
1147}
1148
1149/* when this is called the spinlock must be held */
1150void
1151zoran_feed_stat_com (struct zoran *zr)
1152{
1153 /* move frames from pending queue to DMA */
1154
1155 int frame, i, max_stat_com;
1156
1157 max_stat_com =
1158 (zr->jpg_settings.TmpDcm ==
1159 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
1160
1161 while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com &&
1162 zr->jpg_dma_head < zr->jpg_que_head) {
1163
1164 frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];
1165 if (zr->jpg_settings.TmpDcm == 1) {
1166 /* fill 1 stat_com entry */
1167 i = (zr->jpg_dma_head -
1168 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1169 if (!(zr->stat_com[i] & cpu_to_le32(1)))
1170 break;
1171 zr->stat_com[i] =
1172 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1173 } else {
1174 /* fill 2 stat_com entries */
1175 i = ((zr->jpg_dma_head -
1176 zr->jpg_err_shift) & 1) * 2;
1177 if (!(zr->stat_com[i] & cpu_to_le32(1)))
1178 break;
1179 zr->stat_com[i] =
1180 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1181 zr->stat_com[i + 1] =
1182 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1183 }
1184 zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
1185 zr->jpg_dma_head++;
1186
1187 }
1188 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
1189 zr->jpg_queued_num++;
1190}
1191
1192/* when this is called the spinlock must be held */
1193static void
1194zoran_reap_stat_com (struct zoran *zr)
1195{
1196 /* move frames from DMA queue to done queue */
1197
1198 int i;
1199 u32 stat_com;
1200 unsigned int seq;
1201 unsigned int dif;
1202 struct zoran_jpg_buffer *buffer;
1203 int frame;
1204
1205 /* In motion decompress we don't have a hardware frame counter,
1206 * we just count the interrupts here */
1207
1208 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
1209 zr->jpg_seq_num++;
1210 }
1211 while (zr->jpg_dma_tail < zr->jpg_dma_head) {
1212 if (zr->jpg_settings.TmpDcm == 1)
1213 i = (zr->jpg_dma_tail -
1214 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1215 else
1216 i = ((zr->jpg_dma_tail -
1217 zr->jpg_err_shift) & 1) * 2 + 1;
1218
1219 stat_com = le32_to_cpu(zr->stat_com[i]);
1220
1221 if ((stat_com & 1) == 0) {
1222 return;
1223 }
1224 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1225 buffer = &zr->jpg_buffers.buffer[frame];
1226 do_gettimeofday(&buffer->bs.timestamp);
1227
1228 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1229 buffer->bs.length = (stat_com & 0x7fffff) >> 1;
1230
1231 /* update sequence number with the help of the counter in stat_com */
1232
1233 seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff;
1234 dif = (seq - zr->jpg_seq_num) & 0xff;
1235 zr->jpg_seq_num += dif;
1236 } else {
1237 buffer->bs.length = 0;
1238 }
1239 buffer->bs.seq =
1240 zr->jpg_settings.TmpDcm ==
1241 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
1242 buffer->state = BUZ_STATE_DONE;
1243
1244 zr->jpg_dma_tail++;
1245 }
1246}
1247
1248static void
1249error_handler (struct zoran *zr,
1250 u32 astat,
1251 u32 stat)
1252{
1253 /* This is JPEG error handling part */
1254 if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) &&
1255 (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) {
1256 //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode);
1257 return;
1258 }
1259
1260 if ((stat & 1) == 0 &&
1261 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
1262 zr->jpg_dma_tail - zr->jpg_que_tail >=
1263 zr->jpg_buffers.num_buffers) {
1264 /* No free buffers... */
1265 zoran_reap_stat_com(zr);
1266 zoran_feed_stat_com(zr);
1267 wake_up_interruptible(&zr->jpg_capq);
1268 zr->JPEG_missed = 0;
1269 return;
1270 }
1271
1272 if (zr->JPEG_error != 1) {
1273 /*
1274 * First entry: error just happened during normal operation
1275 *
1276 * In BUZ_MODE_MOTION_COMPRESS:
1277 *
1278 * Possible glitch in TV signal. In this case we should
1279 * stop the codec and wait for good quality signal before
1280 * restarting it to avoid further problems
1281 *
1282 * In BUZ_MODE_MOTION_DECOMPRESS:
1283 *
1284 * Bad JPEG frame: we have to mark it as processed (codec crashed
1285 * and was not able to do it itself), and to remove it from queue.
1286 */
1287 btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
1288 udelay(1);
1289 stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
1290 btwrite(0, ZR36057_JPC);
1291 btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
1292 jpeg_codec_reset(zr);
1293 jpeg_codec_sleep(zr, 1);
1294 zr->JPEG_error = 1;
1295 zr->num_errors++;
1296
1297 /* Report error */
1298 if (*zr_debug > 1 && zr->num_errors <= 8) {
1299 long frame;
1300 frame =
1301 zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1302 printk(KERN_ERR
1303 "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
1304 ZR_DEVNAME(zr), stat, zr->last_isr,
1305 zr->jpg_que_tail, zr->jpg_dma_tail,
1306 zr->jpg_dma_head, zr->jpg_que_head,
1307 zr->jpg_seq_num, frame);
1308 printk("stat_com frames:");
1309 {
1310 int i, j;
1311 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1312 for (i = 0;
1313 i < zr->jpg_buffers.num_buffers;
1314 i++) {
1315 if (le32_to_cpu(zr->stat_com[j]) ==
1316 zr->jpg_buffers.
1317 buffer[i].
1318 frag_tab_bus) {
1319 printk("% d->%d",
1320 j, i);
1321 }
1322 }
1323 }
1324 printk("\n");
1325 }
1326 }
1327 /* Find an entry in stat_com and rotate contents */
1328 {
1329 int i;
1330
1331 if (zr->jpg_settings.TmpDcm == 1)
1332 i = (zr->jpg_dma_tail -
1333 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1334 else
1335 i = ((zr->jpg_dma_tail -
1336 zr->jpg_err_shift) & 1) * 2;
1337 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
1338 /* Mimic zr36067 operation */
1339 zr->stat_com[i] |= cpu_to_le32(1);
1340 if (zr->jpg_settings.TmpDcm != 1)
1341 zr->stat_com[i + 1] |= cpu_to_le32(1);
1342 /* Refill */
1343 zoran_reap_stat_com(zr);
1344 zoran_feed_stat_com(zr);
1345 wake_up_interruptible(&zr->jpg_capq);
1346 /* Find an entry in stat_com again after refill */
1347 if (zr->jpg_settings.TmpDcm == 1)
1348 i = (zr->jpg_dma_tail -
1349 zr->jpg_err_shift) &
1350 BUZ_MASK_STAT_COM;
1351 else
1352 i = ((zr->jpg_dma_tail -
1353 zr->jpg_err_shift) & 1) * 2;
1354 }
1355 if (i) {
1356 /* Rotate stat_comm entries to make current entry first */
1357 int j;
1358 u32 bus_addr[BUZ_NUM_STAT_COM];
1359
1360 /* Here we are copying the stat_com array, which
1361 * is already in little endian format, so
1362 * no endian conversions here
1363 */
1364 memcpy(bus_addr, zr->stat_com,
1365 sizeof(bus_addr));
1366 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1367 zr->stat_com[j] =
1368 bus_addr[(i + j) &
1369 BUZ_MASK_STAT_COM];
1370
1371 }
1372 zr->jpg_err_shift += i;
1373 zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
1374 }
1375 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
1376 zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
1377 }
1378 }
1379
1380 /* Now the stat_comm buffer is ready for restart */
1381 do {
1382 int status, mode;
1383
1384 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1385 decoder_command(zr, DECODER_GET_STATUS, &status);
1386 mode = CODEC_DO_COMPRESSION;
1387 } else {
1388 status = 0;
1389 mode = CODEC_DO_EXPANSION;
1390 }
1391 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1392 (status & DECODER_STATUS_GOOD)) {
1393 /********** RESTART code *************/
1394 jpeg_codec_reset(zr);
1395 zr->codec->set_mode(zr->codec, mode);
1396 zr36057_set_jpg(zr, zr->codec_mode);
1397 jpeg_start(zr);
1398
1399 if (zr->num_errors <= 8)
1400 dprintk(2, KERN_INFO "%s: Restart\n",
1401 ZR_DEVNAME(zr));
1402
1403 zr->JPEG_missed = 0;
1404 zr->JPEG_error = 2;
1405 /********** End RESTART code ***********/
1406 }
1407 } while (0);
1408}
1409
1410irqreturn_t
1411zoran_irq (int irq,
1412 void *dev_id,
1413 struct pt_regs *regs)
1414{
1415 u32 stat, astat;
1416 int count;
1417 struct zoran *zr;
1418 unsigned long flags;
1419
1420 zr = (struct zoran *) dev_id;
1421 count = 0;
1422
1423 if (zr->testing) {
1424 /* Testing interrupts */
1425 spin_lock_irqsave(&zr->spinlock, flags);
1426 while ((stat = count_reset_interrupt(zr))) {
1427 if (count++ > 100) {
1428 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1429 dprintk(1,
1430 KERN_ERR
1431 "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n",
1432 ZR_DEVNAME(zr), stat);
1433 wake_up_interruptible(&zr->test_q);
1434 }
1435 }
1436 zr->last_isr = stat;
1437 spin_unlock_irqrestore(&zr->spinlock, flags);
1438 return IRQ_HANDLED;
1439 }
1440
1441 spin_lock_irqsave(&zr->spinlock, flags);
1442 while (1) {
1443 /* get/clear interrupt status bits */
1444 stat = count_reset_interrupt(zr);
1445 astat = stat & IRQ_MASK;
1446 if (!astat) {
1447 break;
1448 }
1449 dprintk(4,
1450 KERN_DEBUG
1451 "zoran_irq: astat: 0x%08x, mask: 0x%08x\n",
1452 astat, btread(ZR36057_ICR));
1453 if (astat & zr->card.vsync_int) { // SW
1454
1455 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1456 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1457 /* count missed interrupts */
1458 zr->JPEG_missed++;
1459 }
1460 //post_office_read(zr,1,0);
1461 /* Interrupts may still happen when
1462 * zr->v4l_memgrab_active is switched off.
1463 * We simply ignore them */
1464
1465 if (zr->v4l_memgrab_active) {
1466
1467 /* A lot more checks should be here ... */
1468 if ((btread(ZR36057_VSSFGR) &
1469 ZR36057_VSSFGR_SnapShot) == 0)
1470 dprintk(1,
1471 KERN_WARNING
1472 "%s: BuzIRQ with SnapShot off ???\n",
1473 ZR_DEVNAME(zr));
1474
1475 if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
1476 /* There is a grab on a frame going on, check if it has finished */
1477
1478 if ((btread(ZR36057_VSSFGR) &
1479 ZR36057_VSSFGR_FrameGrab) ==
1480 0) {
1481 /* it is finished, notify the user */
1482
1483 zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
1484 zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq;
1485 do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp);
1486 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
1487 zr->v4l_pend_tail++;
1488 }
1489 }
1490
1491 if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)
1492 wake_up_interruptible(&zr->v4l_capq);
1493
1494 /* Check if there is another grab queued */
1495
1496 if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
1497 zr->v4l_pend_tail != zr->v4l_pend_head) {
1498
1499 int frame = zr->v4l_pend[zr->v4l_pend_tail &
1500 V4L_MASK_FRAME];
1501 u32 reg;
1502
1503 zr->v4l_grab_frame = frame;
1504
1505 /* Set zr36057 video front end and enable video */
1506
1507 /* Buffer address */
1508
1509 reg =
1510 zr->v4l_buffers.buffer[frame].
1511 fbuffer_bus;
1512 btwrite(reg, ZR36057_VDTR);
1513 if (zr->v4l_settings.height >
1514 BUZ_MAX_HEIGHT / 2)
1515 reg +=
1516 zr->v4l_settings.
1517 bytesperline;
1518 btwrite(reg, ZR36057_VDBR);
1519
1520 /* video stride, status, and frame grab register */
1521 reg = 0;
1522 if (zr->v4l_settings.height >
1523 BUZ_MAX_HEIGHT / 2)
1524 reg +=
1525 zr->v4l_settings.
1526 bytesperline;
1527 reg =
1528 (reg <<
1529 ZR36057_VSSFGR_DispStride);
1530 reg |= ZR36057_VSSFGR_VidOvf;
1531 reg |= ZR36057_VSSFGR_SnapShot;
1532 reg |= ZR36057_VSSFGR_FrameGrab;
1533 btwrite(reg, ZR36057_VSSFGR);
1534
1535 btor(ZR36057_VDCR_VidEn,
1536 ZR36057_VDCR);
1537 }
1538 }
1539
1540 /* even if we don't grab, we do want to increment
1541 * the sequence counter to see lost frames */
1542 zr->v4l_grab_seq++;
1543 }
1544#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
1545 if (astat & ZR36057_ISR_CodRepIRQ) {
1546 zr->intr_counter_CodRepIRQ++;
1547 IDEBUG(printk
1548 (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
1549 ZR_DEVNAME(zr)));
1550 btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
1551 }
1552#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
1553
1554#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
1555 if (astat & ZR36057_ISR_JPEGRepIRQ) {
1556
1557 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1558 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1559 if (*zr_debug > 1 &&
1560 (!zr->frame_num || zr->JPEG_error)) {
1561 printk(KERN_INFO
1562 "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
1563 ZR_DEVNAME(zr), stat,
1564 zr->jpg_settings.odd_even,
1565 zr->jpg_settings.
1566 field_per_buff,
1567 zr->JPEG_missed);
1568 {
1569 char sc[] = "0000";
1570 char sv[5];
1571 int i;
1572 strcpy(sv, sc);
1573 for (i = 0; i < 4; i++) {
1574 if (le32_to_cpu(zr->stat_com[i]) & 1)
1575 sv[i] = '1';
1576 }
1577 sv[4] = 0;
1578 printk(KERN_INFO
1579 "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
1580 ZR_DEVNAME(zr), sv,
1581 zr->jpg_que_tail,
1582 zr->jpg_dma_tail,
1583 zr->jpg_dma_head,
1584 zr->jpg_que_head);
1585 }
1586 } else {
1587 if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics
1588 zr->JPEG_max_missed =
1589 zr->JPEG_missed;
1590 if (zr->JPEG_missed <
1591 zr->JPEG_min_missed)
1592 zr->JPEG_min_missed =
1593 zr->JPEG_missed;
1594 }
1595
1596 if (*zr_debug > 2 && zr->frame_num < 6) {
1597 int i;
1598 printk("%s: seq=%ld stat_com:",
1599 ZR_DEVNAME(zr), zr->jpg_seq_num);
1600 for (i = 0; i < 4; i++) {
1601 printk(" %08x",
1602 le32_to_cpu(zr->stat_com[i]));
1603 }
1604 printk("\n");
1605 }
1606 zr->frame_num++;
1607 zr->JPEG_missed = 0;
1608 zr->JPEG_error = 0;
1609 zoran_reap_stat_com(zr);
1610 zoran_feed_stat_com(zr);
1611 wake_up_interruptible(&zr->jpg_capq);
1612 } /*else {
1613 dprintk(1,
1614 KERN_ERR
1615 "%s: JPEG interrupt while not in motion (de)compress mode!\n",
1616 ZR_DEVNAME(zr));
1617 }*/
1618 }
1619#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
1620
1621 /* DATERR, too many fields missed, error processing */
1622 if ((astat & zr->card.jpeg_int) ||
1623 zr->JPEG_missed > 25 ||
1624 zr->JPEG_error == 1 ||
1625 ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
1626 (zr->frame_num & (zr->JPEG_missed >
1627 zr->jpg_settings.field_per_buff)))) {
1628 error_handler(zr, astat, stat);
1629 }
1630
1631 count++;
1632 if (count > 10) {
1633 dprintk(2, KERN_WARNING "%s: irq loop %d\n",
1634 ZR_DEVNAME(zr), count);
1635 if (count > 20) {
1636 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1637 dprintk(2,
1638 KERN_ERR
1639 "%s: IRQ lockup, cleared int mask\n",
1640 ZR_DEVNAME(zr));
1641 break;
1642 }
1643 }
1644 zr->last_isr = stat;
1645 }
1646 spin_unlock_irqrestore(&zr->spinlock, flags);
1647
1648 return IRQ_HANDLED;
1649}
1650
1651void
1652zoran_set_pci_master (struct zoran *zr,
1653 int set_master)
1654{
1655 if (set_master) {
1656 pci_set_master(zr->pci_dev);
1657 } else {
1658 u16 command;
1659
1660 pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command);
1661 command &= ~PCI_COMMAND_MASTER;
1662 pci_write_config_word(zr->pci_dev, PCI_COMMAND, command);
1663 }
1664}
1665
1666void
1667zoran_init_hardware (struct zoran *zr)
1668{
1669 int j, zero = 0;
1670
1671 /* Enable bus-mastering */
1672 zoran_set_pci_master(zr, 1);
1673
1674 /* Initialize the board */
1675 if (zr->card.init) {
1676 zr->card.init(zr);
1677 }
1678
1679 j = zr->card.input[zr->input].muxsel;
1680
1681 decoder_command(zr, 0, NULL);
1682 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
1683 decoder_command(zr, DECODER_SET_INPUT, &j);
1684
1685 encoder_command(zr, 0, NULL);
1686 encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
1687 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1688
1689 /* toggle JPEG codec sleep to sync PLL */
1690 jpeg_codec_sleep(zr, 1);
1691 jpeg_codec_sleep(zr, 0);
1692
1693 /* set individual interrupt enables (without GIRQ1)
1694 * but don't global enable until zoran_open() */
1695
1696 //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW
1697 // It looks like using only JPEGRepIRQEn is not always reliable,
1698 // may be when JPEG codec crashes it won't generate IRQ? So,
1699 /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP
1700 zr36057_init_vfe(zr);
1701
1702 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1703
1704 btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
1705}
1706
1707void
1708zr36057_restart (struct zoran *zr)
1709{
1710 btwrite(0, ZR36057_SPGPPCR);
1711 mdelay(1);
1712 btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR);
1713 mdelay(1);
1714
1715 /* assert P_Reset */
1716 btwrite(0, ZR36057_JPC);
1717 /* set up GPIO direction - all output */
1718 btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR);
1719
1720 /* set up GPIO pins and guest bus timing */
1721 btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1);
1722}
1723
1724/*
1725 * initialize video front end
1726 */
1727
1728static void
1729zr36057_init_vfe (struct zoran *zr)
1730{
1731 u32 reg;
1732
1733 reg = btread(ZR36057_VFESPFR);
1734 reg |= ZR36057_VFESPFR_LittleEndian;
1735 reg &= ~ZR36057_VFESPFR_VCLKPol;
1736 reg |= ZR36057_VFESPFR_ExtFl;
1737 reg |= ZR36057_VFESPFR_TopField;
1738 btwrite(reg, ZR36057_VFESPFR);
1739 reg = btread(ZR36057_VDCR);
1740 if (pci_pci_problems & PCIPCI_TRITON)
1741 // || zr->revision < 1) // Revision 1 has also Triton support
1742 reg &= ~ZR36057_VDCR_Triton;
1743 else
1744 reg |= ZR36057_VDCR_Triton;
1745 btwrite(reg, ZR36057_VDCR);
1746}
1747
1748/*
1749 * Interface to decoder and encoder chips using i2c bus
1750 */
1751
1752int
1753decoder_command (struct zoran *zr,
1754 int cmd,
1755 void *data)
1756{
1757 if (zr->decoder == NULL)
1758 return -EIO;
1759
1760 if (zr->card.type == LML33 &&
1761 (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) {
1762 int res;
1763
1764 // Bt819 needs to reset its FIFO buffer using #FRST pin and
1765 // LML33 card uses GPIO(7) for that.
1766 GPIO(zr, 7, 0);
1767 res = zr->decoder->driver->command(zr->decoder, cmd, data);
1768 // Pull #FRST high.
1769 GPIO(zr, 7, 1);
1770 return res;
1771 } else
1772 return zr->decoder->driver->command(zr->decoder, cmd,
1773 data);
1774}
1775
1776int
1777encoder_command (struct zoran *zr,
1778 int cmd,
1779 void *data)
1780{
1781 if (zr->encoder == NULL)
1782 return -1;
1783
1784 return zr->encoder->driver->command(zr->encoder, cmd, data);
1785}
diff --git a/drivers/media/video/zoran_device.h b/drivers/media/video/zoran_device.h
new file mode 100644
index 000000000000..f315203d7105
--- /dev/null
+++ b/drivers/media/video/zoran_device.h
@@ -0,0 +1,91 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_DEVICE_H__
31#define __ZORAN_DEVICE_H__
32
33/* general purpose I/O */
34extern void GPIO(struct zoran *zr,
35 int bit,
36 unsigned int value);
37
38/* codec (or actually: guest bus) access */
39extern int post_office_wait(struct zoran *zr);
40extern int post_office_write(struct zoran *zr,
41 unsigned guest,
42 unsigned reg,
43 unsigned value);
44extern int post_office_read(struct zoran *zr,
45 unsigned guest,
46 unsigned reg);
47
48extern void detect_guest_activity(struct zoran *zr);
49
50extern void jpeg_codec_sleep(struct zoran *zr,
51 int sleep);
52extern int jpeg_codec_reset(struct zoran *zr);
53
54/* zr360x7 access to raw capture */
55extern void zr36057_overlay(struct zoran *zr,
56 int on);
57extern void write_overlay_mask(struct file *file,
58 struct video_clip *vp,
59 int count);
60extern void zr36057_set_memgrab(struct zoran *zr,
61 int mode);
62extern int wait_grab_pending(struct zoran *zr);
63
64/* interrupts */
65extern void print_interrupts(struct zoran *zr);
66extern void clear_interrupt_counters(struct zoran *zr);
67extern irqreturn_t zoran_irq(int irq,
68 void *dev_id,
69 struct pt_regs *regs);
70
71/* JPEG codec access */
72extern void jpeg_start(struct zoran *zr);
73extern void zr36057_enable_jpg(struct zoran *zr,
74 enum zoran_codec_mode mode);
75extern void zoran_feed_stat_com(struct zoran *zr);
76
77/* general */
78extern void zoran_set_pci_master(struct zoran *zr,
79 int set_master);
80extern void zoran_init_hardware(struct zoran *zr);
81extern void zr36057_restart(struct zoran *zr);
82
83/* i2c */
84extern int decoder_command(struct zoran *zr,
85 int cmd,
86 void *data);
87extern int encoder_command(struct zoran *zr,
88 int cmd,
89 void *data);
90
91#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
new file mode 100644
index 000000000000..ba838a42ec80
--- /dev/null
+++ b/drivers/media/video/zoran_driver.c
@@ -0,0 +1,4699 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
7 *
8 * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
9 *
10 * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
11 *
12 * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
13 *
14 * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
15 *
16 * Based on
17 *
18 * Miro DC10 driver
19 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
20 *
21 * Iomega Buz driver version 1.0
22 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
23 *
24 * buz.0.0.3
25 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
26 *
27 * bttv - Bt848 frame grabber driver
28 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
29 * & Marcus Metzler (mocm@thp.uni-koeln.de)
30 *
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45 */
46
47#include <linux/config.h>
48#include <linux/version.h>
49#include <linux/init.h>
50#include <linux/module.h>
51#include <linux/delay.h>
52#include <linux/slab.h>
53#include <linux/pci.h>
54#include <linux/vmalloc.h>
55#include <linux/wait.h>
56#include <linux/byteorder/generic.h>
57
58#include <linux/interrupt.h>
59#include <linux/i2c.h>
60#include <linux/i2c-algo-bit.h>
61
62#include <linux/spinlock.h>
63#define MAP_NR(x) virt_to_page(x)
64#define ZORAN_HARDWARE VID_HARDWARE_ZR36067
65#define ZORAN_VID_TYPE ( \
66 VID_TYPE_CAPTURE | \
67 VID_TYPE_OVERLAY | \
68 VID_TYPE_CLIPPING | \
69 VID_TYPE_FRAMERAM | \
70 VID_TYPE_SCALES | \
71 VID_TYPE_MJPEG_DECODER | \
72 VID_TYPE_MJPEG_ENCODER \
73 )
74
75#include <linux/videodev.h>
76#include "videocodec.h"
77
78#include <asm/io.h>
79#include <asm/uaccess.h>
80#include <linux/proc_fs.h>
81
82#include <linux/video_decoder.h>
83#include <linux/video_encoder.h>
84#include "zoran.h"
85#include "zoran_device.h"
86#include "zoran_card.h"
87
88#ifdef HAVE_V4L2
89 /* we declare some card type definitions here, they mean
90 * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
91#define ZORAN_V4L2_VID_FLAGS ( \
92 V4L2_CAP_STREAMING |\
93 V4L2_CAP_VIDEO_CAPTURE |\
94 V4L2_CAP_VIDEO_OUTPUT |\
95 V4L2_CAP_VIDEO_OVERLAY \
96 )
97#endif
98
99#include <asm/byteorder.h>
100
101const struct zoran_format zoran_formats[] = {
102 {
103 .name = "15-bit RGB",
104 .palette = VIDEO_PALETTE_RGB555,
105#ifdef HAVE_V4L2
106#ifdef __LITTLE_ENDIAN
107 .fourcc = V4L2_PIX_FMT_RGB555,
108#else
109 .fourcc = V4L2_PIX_FMT_RGB555X,
110#endif
111 .colorspace = V4L2_COLORSPACE_SRGB,
112#endif
113 .depth = 15,
114 .flags = ZORAN_FORMAT_CAPTURE |
115 ZORAN_FORMAT_OVERLAY,
116 }, {
117 .name = "16-bit RGB",
118 .palette = VIDEO_PALETTE_RGB565,
119#ifdef HAVE_V4L2
120#ifdef __LITTLE_ENDIAN
121 .fourcc = V4L2_PIX_FMT_RGB565,
122#else
123 .fourcc = V4L2_PIX_FMT_RGB565X,
124#endif
125 .colorspace = V4L2_COLORSPACE_SRGB,
126#endif
127 .depth = 16,
128 .flags = ZORAN_FORMAT_CAPTURE |
129 ZORAN_FORMAT_OVERLAY,
130 }, {
131 .name = "24-bit RGB",
132 .palette = VIDEO_PALETTE_RGB24,
133#ifdef HAVE_V4L2
134#ifdef __LITTLE_ENDIAN
135 .fourcc = V4L2_PIX_FMT_BGR24,
136#else
137 .fourcc = V4L2_PIX_FMT_RGB24,
138#endif
139 .colorspace = V4L2_COLORSPACE_SRGB,
140#endif
141 .depth = 24,
142 .flags = ZORAN_FORMAT_CAPTURE |
143 ZORAN_FORMAT_OVERLAY,
144 }, {
145 .name = "32-bit RGB",
146 .palette = VIDEO_PALETTE_RGB32,
147#ifdef HAVE_V4L2
148#ifdef __LITTLE_ENDIAN
149 .fourcc = V4L2_PIX_FMT_BGR32,
150#else
151 .fourcc = V4L2_PIX_FMT_RGB32,
152#endif
153 .colorspace = V4L2_COLORSPACE_SRGB,
154#endif
155 .depth = 32,
156 .flags = ZORAN_FORMAT_CAPTURE |
157 ZORAN_FORMAT_OVERLAY,
158 }, {
159 .name = "4:2:2, packed, YUYV",
160 .palette = VIDEO_PALETTE_YUV422,
161#ifdef HAVE_V4L2
162 .fourcc = V4L2_PIX_FMT_YUYV,
163 .colorspace = V4L2_COLORSPACE_SMPTE170M,
164#endif
165 .depth = 16,
166 .flags = ZORAN_FORMAT_CAPTURE |
167 ZORAN_FORMAT_OVERLAY,
168 }, {
169 .name = "Hardware-encoded Motion-JPEG",
170 .palette = -1,
171#ifdef HAVE_V4L2
172 .fourcc = V4L2_PIX_FMT_MJPEG,
173 .colorspace = V4L2_COLORSPACE_SMPTE170M,
174#endif
175 .depth = 0,
176 .flags = ZORAN_FORMAT_CAPTURE |
177 ZORAN_FORMAT_PLAYBACK |
178 ZORAN_FORMAT_COMPRESSED,
179 }
180};
181static const int zoran_num_formats =
182 (sizeof(zoran_formats) / sizeof(struct zoran_format));
183
184// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
185#if !defined(CONFIG_BIGPHYS_AREA)
186//#undef CONFIG_BIGPHYS_AREA
187#define BUZ_USE_HIMEM
188#endif
189
190#if defined(CONFIG_BIGPHYS_AREA)
191# include <linux/bigphysarea.h>
192#endif
193
194extern int *zr_debug;
195
196#define dprintk(num, format, args...) \
197 do { \
198 if (*zr_debug >= num) \
199 printk(format, ##args); \
200 } while (0)
201
202extern int v4l_nbufs;
203extern int v4l_bufsize;
204extern int jpg_nbufs;
205extern int jpg_bufsize;
206extern int pass_through;
207
208static int lock_norm = 0; /* 1=Don't change TV standard (norm) */
209module_param(lock_norm, int, 0);
210MODULE_PARM_DESC(lock_norm, "Users can't change norm");
211
212#ifdef HAVE_V4L2
213 /* small helper function for calculating buffersizes for v4l2
214 * we calculate the nearest higher power-of-two, which
215 * will be the recommended buffersize */
216static __u32
217zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
218{
219 __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm;
220 __u32 num = (1024 * 512) / (div);
221 __u32 result = 2;
222
223 num--;
224 while (num) {
225 num >>= 1;
226 result <<= 1;
227 }
228
229 if (result > jpg_bufsize)
230 return jpg_bufsize;
231 if (result < 8192)
232 return 8192;
233 return result;
234}
235#endif
236
237/* forward references */
238static void v4l_fbuffer_free(struct file *file);
239static void jpg_fbuffer_free(struct file *file);
240
241/*
242 * Allocate the V4L grab buffers
243 *
244 * These have to be pysically contiguous.
245 * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
246 * else we try to allocate them with bigphysarea_alloc_pages
247 * if the bigphysarea patch is present in the kernel,
248 * else we try to use high memory (if the user has bootet
249 * Linux with the necessary memory left over).
250 */
251
252#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA)
253static unsigned long
254get_high_mem (unsigned long size)
255{
256/*
257 * Check if there is usable memory at the end of Linux memory
258 * of at least size. Return the physical address of this memory,
259 * return 0 on failure.
260 *
261 * The idea is from Alexandro Rubini's book "Linux device drivers".
262 * The driver from him which is downloadable from O'Reilly's
263 * web site misses the "virt_to_phys(high_memory)" part
264 * (and therefore doesn't work at all - at least with 2.2.x kernels).
265 *
266 * It should be unnecessary to mention that THIS IS DANGEROUS,
267 * if more than one driver at a time has the idea to use this memory!!!!
268 */
269
270 volatile unsigned char __iomem *mem;
271 unsigned char c;
272 unsigned long hi_mem_ph;
273 unsigned long i;
274
275 /* Map the high memory to user space */
276
277 hi_mem_ph = virt_to_phys(high_memory);
278
279 mem = ioremap(hi_mem_ph, size);
280 if (!mem) {
281 dprintk(1,
282 KERN_ERR "%s: get_high_mem() - ioremap failed\n",
283 ZORAN_NAME);
284 return 0;
285 }
286
287 for (i = 0; i < size; i++) {
288 /* Check if it is memory */
289 c = i & 0xff;
290 writeb(c, mem + i);
291 if (readb(mem + i) != c)
292 break;
293 c = 255 - c;
294 writeb(c, mem + i);
295 if (readb(mem + i) != c)
296 break;
297 writeb(0, mem + i); /* zero out memory */
298
299 /* give the kernel air to breath */
300 if ((i & 0x3ffff) == 0x3ffff)
301 schedule();
302 }
303
304 iounmap(mem);
305
306 if (i != size) {
307 dprintk(1,
308 KERN_ERR
309 "%s: get_high_mem() - requested %lu, avail %lu\n",
310 ZORAN_NAME, size, i);
311 return 0;
312 }
313
314 return hi_mem_ph;
315}
316#endif
317
318static int
319v4l_fbuffer_alloc (struct file *file)
320{
321 struct zoran_fh *fh = file->private_data;
322 struct zoran *zr = fh->zr;
323 int i, off;
324 unsigned char *mem;
325#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA)
326 unsigned long pmem = 0;
327#endif
328
329 /* we might have old buffers lying around... */
330 if (fh->v4l_buffers.ready_to_be_freed) {
331 v4l_fbuffer_free(file);
332 }
333
334 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
335 if (fh->v4l_buffers.buffer[i].fbuffer)
336 dprintk(2,
337 KERN_WARNING
338 "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
339 ZR_DEVNAME(zr), i);
340
341 //udelay(20);
342 if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
343 /* Use kmalloc */
344
345 mem =
346 (unsigned char *) kmalloc(fh->v4l_buffers.
347 buffer_size,
348 GFP_KERNEL);
349 if (mem == 0) {
350 dprintk(1,
351 KERN_ERR
352 "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
353 ZR_DEVNAME(zr), i);
354 v4l_fbuffer_free(file);
355 return -ENOBUFS;
356 }
357 fh->v4l_buffers.buffer[i].fbuffer = mem;
358 fh->v4l_buffers.buffer[i].fbuffer_phys =
359 virt_to_phys(mem);
360 fh->v4l_buffers.buffer[i].fbuffer_bus =
361 virt_to_bus(mem);
362 for (off = 0; off < fh->v4l_buffers.buffer_size;
363 off += PAGE_SIZE)
364 SetPageReserved(MAP_NR(mem + off));
365 dprintk(4,
366 KERN_INFO
367 "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
368 ZR_DEVNAME(zr), i, (unsigned long) mem,
369 virt_to_bus(mem));
370 } else {
371#if defined(CONFIG_BIGPHYS_AREA)
372 /* Use bigphysarea_alloc_pages */
373
374 int n =
375 (fh->v4l_buffers.buffer_size + PAGE_SIZE -
376 1) / PAGE_SIZE;
377
378 mem =
379 (unsigned char *) bigphysarea_alloc_pages(n, 0,
380 GFP_KERNEL);
381 if (mem == 0) {
382 dprintk(1,
383 KERN_ERR
384 "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n",
385 ZR_DEVNAME(zr), i);
386 v4l_fbuffer_free(file);
387 return -ENOBUFS;
388 }
389 fh->v4l_buffers.buffer[i].fbuffer = mem;
390 fh->v4l_buffers.buffer[i].fbuffer_phys =
391 virt_to_phys(mem);
392 fh->v4l_buffers.buffer[i].fbuffer_bus =
393 virt_to_bus(mem);
394 dprintk(4,
395 KERN_INFO
396 "%s: Bigphysarea frame %d mem 0x%x (bus: 0x%x)\n",
397 ZR_DEVNAME(zr), i, (unsigned) mem,
398 (unsigned) virt_to_bus(mem));
399
400 /* Zero out the allocated memory */
401 memset(fh->v4l_buffers.buffer[i].fbuffer, 0,
402 fh->v4l_buffers.buffer_size);
403#elif defined(BUZ_USE_HIMEM)
404
405 /* Use high memory which has been left at boot time */
406
407 /* Ok., Ok. this is an evil hack - we make
408 * the assumption that physical addresses are
409 * the same as bus addresses (true at least
410 * for Intel processors). The whole method of
411 * obtaining and using this memory is not very
412 * nice - but I hope it saves some poor users
413 * from kernel hacking, which might have even
414 * more evil results */
415
416 if (i == 0) {
417 int size =
418 fh->v4l_buffers.num_buffers *
419 fh->v4l_buffers.buffer_size;
420
421 pmem = get_high_mem(size);
422 if (pmem == 0) {
423 dprintk(1,
424 KERN_ERR
425 "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
426 ZR_DEVNAME(zr), size >> 10);
427 return -ENOBUFS;
428 }
429 fh->v4l_buffers.buffer[0].fbuffer = NULL;
430 fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
431 fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
432 dprintk(4,
433 KERN_INFO
434 "%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
435 ZR_DEVNAME(zr), size >> 10);
436 } else {
437 fh->v4l_buffers.buffer[i].fbuffer = NULL;
438 fh->v4l_buffers.buffer[i].fbuffer_phys =
439 pmem + i * fh->v4l_buffers.buffer_size;
440 fh->v4l_buffers.buffer[i].fbuffer_bus =
441 pmem + i * fh->v4l_buffers.buffer_size;
442 }
443#else
444 /* No bigphysarea present, usage of high memory disabled,
445 * but user wants buffers of more than MAX_KMALLOC_MEM */
446 dprintk(1,
447 KERN_ERR
448 "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n",
449 ZR_DEVNAME(zr));
450 dprintk(1,
451 KERN_ERR
452 "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n",
453 ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers,
454 fh->v4l_buffers.buffer_size >> 10);
455 return -ENOBUFS;
456#endif
457 }
458 }
459
460 fh->v4l_buffers.allocated = 1;
461
462 return 0;
463}
464
465/* free the V4L grab buffers */
466static void
467v4l_fbuffer_free (struct file *file)
468{
469 struct zoran_fh *fh = file->private_data;
470 struct zoran *zr = fh->zr;
471 int i, off;
472 unsigned char *mem;
473
474 dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
475
476 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
477 if (!fh->v4l_buffers.buffer[i].fbuffer)
478 continue;
479
480 if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
481 mem = fh->v4l_buffers.buffer[i].fbuffer;
482 for (off = 0; off < fh->v4l_buffers.buffer_size;
483 off += PAGE_SIZE)
484 ClearPageReserved(MAP_NR(mem + off));
485 kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
486 }
487#if defined(CONFIG_BIGPHYS_AREA)
488 else
489 bigphysarea_free_pages((void *) fh->v4l_buffers.
490 buffer[i].fbuffer);
491#endif
492 fh->v4l_buffers.buffer[i].fbuffer = NULL;
493 }
494
495 fh->v4l_buffers.allocated = 0;
496 fh->v4l_buffers.ready_to_be_freed = 0;
497}
498
499/*
500 * Allocate the MJPEG grab buffers.
501 *
502 * If the requested buffer size is smaller than MAX_KMALLOC_MEM,
503 * kmalloc is used to request a physically contiguous area,
504 * else we allocate the memory in framgents with get_zeroed_page.
505 *
506 * If a Natoma chipset is present and this is a revision 1 zr36057,
507 * each MJPEG buffer needs to be physically contiguous.
508 * (RJ: This statement is from Dave Perks' original driver,
509 * I could never check it because I have a zr36067)
510 * The driver cares about this because it reduces the buffer
511 * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
512 *
513 * RJ: The contents grab buffers needs never be accessed in the driver.
514 * Therefore there is no need to allocate them with vmalloc in order
515 * to get a contiguous virtual memory space.
516 * I don't understand why many other drivers first allocate them with
517 * vmalloc (which uses internally also get_zeroed_page, but delivers you
518 * virtual addresses) and then again have to make a lot of efforts
519 * to get the physical address.
520 *
521 * Ben Capper:
522 * On big-endian architectures (such as ppc) some extra steps
523 * are needed. When reading and writing to the stat_com array
524 * and fragment buffers, the device expects to see little-
525 * endian values. The use of cpu_to_le32() and le32_to_cpu()
526 * in this function (and one or two others in zoran_device.c)
527 * ensure that these values are always stored in little-endian
528 * form, regardless of architecture. The zr36057 does Very Bad
529 * Things on big endian architectures if the stat_com array
530 * and fragment buffers are not little-endian.
531 */
532
533static int
534jpg_fbuffer_alloc (struct file *file)
535{
536 struct zoran_fh *fh = file->private_data;
537 struct zoran *zr = fh->zr;
538 int i, j, off;
539 unsigned long mem;
540
541 /* we might have old buffers lying around */
542 if (fh->jpg_buffers.ready_to_be_freed) {
543 jpg_fbuffer_free(file);
544 }
545
546 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
547 if (fh->jpg_buffers.buffer[i].frag_tab)
548 dprintk(2,
549 KERN_WARNING
550 "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
551 ZR_DEVNAME(zr), i);
552
553 /* Allocate fragment table for this buffer */
554
555 mem = get_zeroed_page(GFP_KERNEL);
556 if (mem == 0) {
557 dprintk(1,
558 KERN_ERR
559 "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
560 ZR_DEVNAME(zr), i);
561 jpg_fbuffer_free(file);
562 return -ENOBUFS;
563 }
564 memset((void *) mem, 0, PAGE_SIZE);
565 fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem;
566 fh->jpg_buffers.buffer[i].frag_tab_bus =
567 virt_to_bus((void *) mem);
568
569 //if (alloc_contig) {
570 if (fh->jpg_buffers.need_contiguous) {
571 mem =
572 (unsigned long) kmalloc(fh->jpg_buffers.
573 buffer_size,
574 GFP_KERNEL);
575 if (mem == 0) {
576 dprintk(1,
577 KERN_ERR
578 "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
579 ZR_DEVNAME(zr), i);
580 jpg_fbuffer_free(file);
581 return -ENOBUFS;
582 }
583 fh->jpg_buffers.buffer[i].frag_tab[0] =
584 cpu_to_le32(virt_to_bus((void *) mem));
585 fh->jpg_buffers.buffer[i].frag_tab[1] =
586 cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
587 for (off = 0; off < fh->jpg_buffers.buffer_size;
588 off += PAGE_SIZE)
589 SetPageReserved(MAP_NR(mem + off));
590 } else {
591 /* jpg_bufsize is allreay page aligned */
592 for (j = 0;
593 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
594 j++) {
595 mem = get_zeroed_page(GFP_KERNEL);
596 if (mem == 0) {
597 dprintk(1,
598 KERN_ERR
599 "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
600 ZR_DEVNAME(zr), i);
601 jpg_fbuffer_free(file);
602 return -ENOBUFS;
603 }
604
605 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
606 cpu_to_le32(virt_to_bus((void *) mem));
607 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
608 1] =
609 cpu_to_le32((PAGE_SIZE / 4) << 1);
610 SetPageReserved(MAP_NR(mem));
611 }
612
613 fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
614 }
615 }
616
617 dprintk(4,
618 KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
619 ZR_DEVNAME(zr),
620 (fh->jpg_buffers.num_buffers *
621 fh->jpg_buffers.buffer_size) >> 10);
622
623 fh->jpg_buffers.allocated = 1;
624
625 return 0;
626}
627
628/* free the MJPEG grab buffers */
629static void
630jpg_fbuffer_free (struct file *file)
631{
632 struct zoran_fh *fh = file->private_data;
633 struct zoran *zr = fh->zr;
634 int i, j, off;
635 unsigned char *mem;
636
637 dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
638
639 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
640 if (!fh->jpg_buffers.buffer[i].frag_tab)
641 continue;
642
643 //if (alloc_contig) {
644 if (fh->jpg_buffers.need_contiguous) {
645 if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
646 mem = (unsigned char *) bus_to_virt(le32_to_cpu(
647 fh->jpg_buffers.buffer[i].frag_tab[0]));
648 for (off = 0;
649 off < fh->jpg_buffers.buffer_size;
650 off += PAGE_SIZE)
651 ClearPageReserved(MAP_NR
652 (mem + off));
653 kfree((void *) mem);
654 fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
655 fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
656 }
657 } else {
658 for (j = 0;
659 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
660 j++) {
661 if (!fh->jpg_buffers.buffer[i].
662 frag_tab[2 * j])
663 break;
664 ClearPageReserved(MAP_NR
665 (bus_to_virt
666 (le32_to_cpu
667 (fh->jpg_buffers.
668 buffer[i].frag_tab[2 *
669 j]))));
670 free_page((unsigned long)
671 bus_to_virt
672 (le32_to_cpu
673 (fh->jpg_buffers.
674 buffer[i].
675 frag_tab[2 * j])));
676 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
677 0;
678 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
679 1] = 0;
680 }
681 }
682
683 free_page((unsigned long) fh->jpg_buffers.buffer[i].
684 frag_tab);
685 fh->jpg_buffers.buffer[i].frag_tab = NULL;
686 }
687
688 fh->jpg_buffers.allocated = 0;
689 fh->jpg_buffers.ready_to_be_freed = 0;
690}
691
692/*
693 * V4L Buffer grabbing
694 */
695
696static int
697zoran_v4l_set_format (struct file *file,
698 int width,
699 int height,
700 const struct zoran_format *format)
701{
702 struct zoran_fh *fh = file->private_data;
703 struct zoran *zr = fh->zr;
704 int bpp;
705
706 /* Check size and format of the grab wanted */
707
708 if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
709 height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
710 dprintk(1,
711 KERN_ERR
712 "%s: v4l_set_format() - wrong frame size (%dx%d)\n",
713 ZR_DEVNAME(zr), width, height);
714 return -EINVAL;
715 }
716
717 bpp = (format->depth + 7) / 8;
718
719 /* Check against available buffer size */
720 if (height * width * bpp > fh->v4l_buffers.buffer_size) {
721 dprintk(1,
722 KERN_ERR
723 "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
724 ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
725 return -EINVAL;
726 }
727
728 /* The video front end needs 4-byte alinged line sizes */
729
730 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
731 dprintk(1,
732 KERN_ERR
733 "%s: v4l_set_format() - wrong frame alingment\n",
734 ZR_DEVNAME(zr));
735 return -EINVAL;
736 }
737
738 fh->v4l_settings.width = width;
739 fh->v4l_settings.height = height;
740 fh->v4l_settings.format = format;
741 fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width;
742
743 return 0;
744}
745
746static int
747zoran_v4l_queue_frame (struct file *file,
748 int num)
749{
750 struct zoran_fh *fh = file->private_data;
751 struct zoran *zr = fh->zr;
752 unsigned long flags;
753 int res = 0;
754
755 if (!fh->v4l_buffers.allocated) {
756 dprintk(1,
757 KERN_ERR
758 "%s: v4l_queue_frame() - buffers not yet allocated\n",
759 ZR_DEVNAME(zr));
760 res = -ENOMEM;
761 }
762
763 /* No grabbing outside the buffer range! */
764 if (num >= fh->v4l_buffers.num_buffers || num < 0) {
765 dprintk(1,
766 KERN_ERR
767 "%s: v4l_queue_frame() - buffer %d is out of range\n",
768 ZR_DEVNAME(zr), num);
769 res = -EINVAL;
770 }
771
772 spin_lock_irqsave(&zr->spinlock, flags);
773
774 if (fh->v4l_buffers.active == ZORAN_FREE) {
775 if (zr->v4l_buffers.active == ZORAN_FREE) {
776 zr->v4l_buffers = fh->v4l_buffers;
777 fh->v4l_buffers.active = ZORAN_ACTIVE;
778 } else {
779 dprintk(1,
780 KERN_ERR
781 "%s: v4l_queue_frame() - another session is already capturing\n",
782 ZR_DEVNAME(zr));
783 res = -EBUSY;
784 }
785 }
786
787 /* make sure a grab isn't going on currently with this buffer */
788 if (!res) {
789 switch (zr->v4l_buffers.buffer[num].state) {
790 default:
791 case BUZ_STATE_PEND:
792 if (zr->v4l_buffers.active == ZORAN_FREE) {
793 fh->v4l_buffers.active = ZORAN_FREE;
794 zr->v4l_buffers.allocated = 0;
795 }
796 res = -EBUSY; /* what are you doing? */
797 break;
798 case BUZ_STATE_DONE:
799 dprintk(2,
800 KERN_WARNING
801 "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
802 ZR_DEVNAME(zr), num);
803 case BUZ_STATE_USER:
804 /* since there is at least one unused buffer there's room for at least
805 * one more pend[] entry */
806 zr->v4l_pend[zr->v4l_pend_head++ &
807 V4L_MASK_FRAME] = num;
808 zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
809 zr->v4l_buffers.buffer[num].bs.length =
810 fh->v4l_settings.bytesperline *
811 zr->v4l_settings.height;
812 fh->v4l_buffers.buffer[num] =
813 zr->v4l_buffers.buffer[num];
814 break;
815 }
816 }
817
818 spin_unlock_irqrestore(&zr->spinlock, flags);
819
820 if (!res && zr->v4l_buffers.active == ZORAN_FREE)
821 zr->v4l_buffers.active = fh->v4l_buffers.active;
822
823 return res;
824}
825
826static int
827v4l_grab (struct file *file,
828 struct video_mmap *mp)
829{
830 struct zoran_fh *fh = file->private_data;
831 struct zoran *zr = fh->zr;
832 int res = 0, i;
833
834 for (i = 0; i < zoran_num_formats; i++) {
835 if (zoran_formats[i].palette == mp->format &&
836 zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
837 !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
838 break;
839 }
840 if (i == zoran_num_formats || zoran_formats[i].depth == 0) {
841 dprintk(1,
842 KERN_ERR
843 "%s: v4l_grab() - wrong bytes-per-pixel format\n",
844 ZR_DEVNAME(zr));
845 return -EINVAL;
846 }
847
848 /*
849 * To minimize the time spent in the IRQ routine, we avoid setting up
850 * the video front end there.
851 * If this grab has different parameters from a running streaming capture
852 * we stop the streaming capture and start it over again.
853 */
854 if (zr->v4l_memgrab_active &&
855 (zr->v4l_settings.width != mp->width ||
856 zr->v4l_settings.height != mp->height ||
857 zr->v4l_settings.format->palette != mp->format)) {
858 res = wait_grab_pending(zr);
859 if (res)
860 return res;
861 }
862 if ((res = zoran_v4l_set_format(file,
863 mp->width,
864 mp->height,
865 &zoran_formats[i])))
866 return res;
867 zr->v4l_settings = fh->v4l_settings;
868
869 /* queue the frame in the pending queue */
870 if ((res = zoran_v4l_queue_frame(file, mp->frame))) {
871 fh->v4l_buffers.active = ZORAN_FREE;
872 return res;
873 }
874
875 /* put the 36057 into frame grabbing mode */
876 if (!res && !zr->v4l_memgrab_active)
877 zr36057_set_memgrab(zr, 1);
878
879 //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr));
880
881 return res;
882}
883
884/*
885 * Sync on a V4L buffer
886 */
887
888static int
889v4l_sync (struct file *file,
890 int frame)
891{
892 struct zoran_fh *fh = file->private_data;
893 struct zoran *zr = fh->zr;
894 unsigned long flags;
895
896 if (fh->v4l_buffers.active == ZORAN_FREE) {
897 dprintk(1,
898 KERN_ERR
899 "%s: v4l_sync() - no grab active for this session\n",
900 ZR_DEVNAME(zr));
901 return -EINVAL;
902 }
903
904 /* check passed-in frame number */
905 if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
906 dprintk(1,
907 KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
908 ZR_DEVNAME(zr), frame);
909 return -EINVAL;
910 }
911
912 /* Check if is buffer was queued at all */
913 if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
914 dprintk(1,
915 KERN_ERR
916 "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
917 ZR_DEVNAME(zr));
918 return -EPROTO;
919 }
920
921 /* wait on this buffer to get ready */
922 if (!wait_event_interruptible_timeout(zr->v4l_capq,
923 (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
924 10*HZ))
925 return -ETIME;
926 if (signal_pending(current))
927 return -ERESTARTSYS;
928
929 /* buffer should now be in BUZ_STATE_DONE */
930 if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
931 dprintk(2,
932 KERN_ERR "%s: v4l_sync() - internal state error\n",
933 ZR_DEVNAME(zr));
934
935 zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
936 fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
937
938 spin_lock_irqsave(&zr->spinlock, flags);
939
940 /* Check if streaming capture has finished */
941 if (zr->v4l_pend_tail == zr->v4l_pend_head) {
942 zr36057_set_memgrab(zr, 0);
943 if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
944 fh->v4l_buffers.active = zr->v4l_buffers.active =
945 ZORAN_FREE;
946 zr->v4l_buffers.allocated = 0;
947 }
948 }
949
950 spin_unlock_irqrestore(&zr->spinlock, flags);
951
952 return 0;
953}
954
955/*
956 * Queue a MJPEG buffer for capture/playback
957 */
958
959static int
960zoran_jpg_queue_frame (struct file *file,
961 int num,
962 enum zoran_codec_mode mode)
963{
964 struct zoran_fh *fh = file->private_data;
965 struct zoran *zr = fh->zr;
966 unsigned long flags;
967 int res = 0;
968
969 /* Check if buffers are allocated */
970 if (!fh->jpg_buffers.allocated) {
971 dprintk(1,
972 KERN_ERR
973 "%s: jpg_queue_frame() - buffers not yet allocated\n",
974 ZR_DEVNAME(zr));
975 return -ENOMEM;
976 }
977
978 /* No grabbing outside the buffer range! */
979 if (num >= fh->jpg_buffers.num_buffers || num < 0) {
980 dprintk(1,
981 KERN_ERR
982 "%s: jpg_queue_frame() - buffer %d out of range\n",
983 ZR_DEVNAME(zr), num);
984 return -EINVAL;
985 }
986
987 /* what is the codec mode right now? */
988 if (zr->codec_mode == BUZ_MODE_IDLE) {
989 zr->jpg_settings = fh->jpg_settings;
990 } else if (zr->codec_mode != mode) {
991 /* wrong codec mode active - invalid */
992 dprintk(1,
993 KERN_ERR
994 "%s: jpg_queue_frame() - codec in wrong mode\n",
995 ZR_DEVNAME(zr));
996 return -EINVAL;
997 }
998
999 spin_lock_irqsave(&zr->spinlock, flags);
1000
1001 if (fh->jpg_buffers.active == ZORAN_FREE) {
1002 if (zr->jpg_buffers.active == ZORAN_FREE) {
1003 zr->jpg_buffers = fh->jpg_buffers;
1004 fh->jpg_buffers.active = ZORAN_ACTIVE;
1005 } else {
1006 dprintk(1,
1007 KERN_ERR
1008 "%s: jpg_queue_frame() - another session is already capturing\n",
1009 ZR_DEVNAME(zr));
1010 res = -EBUSY;
1011 }
1012 }
1013
1014 if (!res && zr->codec_mode == BUZ_MODE_IDLE) {
1015 /* Ok load up the jpeg codec */
1016 zr36057_enable_jpg(zr, mode);
1017 }
1018
1019 if (!res) {
1020 switch (zr->jpg_buffers.buffer[num].state) {
1021 case BUZ_STATE_DONE:
1022 dprintk(2,
1023 KERN_WARNING
1024 "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
1025 ZR_DEVNAME(zr));
1026 case BUZ_STATE_USER:
1027 /* since there is at least one unused buffer there's room for at
1028 *least one more pend[] entry */
1029 zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
1030 num;
1031 zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
1032 fh->jpg_buffers.buffer[num] =
1033 zr->jpg_buffers.buffer[num];
1034 zoran_feed_stat_com(zr);
1035 break;
1036 default:
1037 case BUZ_STATE_DMA:
1038 case BUZ_STATE_PEND:
1039 if (zr->jpg_buffers.active == ZORAN_FREE) {
1040 fh->jpg_buffers.active = ZORAN_FREE;
1041 zr->jpg_buffers.allocated = 0;
1042 }
1043 res = -EBUSY; /* what are you doing? */
1044 break;
1045 }
1046 }
1047
1048 spin_unlock_irqrestore(&zr->spinlock, flags);
1049
1050 if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
1051 zr->jpg_buffers.active = fh->jpg_buffers.active;
1052 }
1053
1054 return res;
1055}
1056
1057static int
1058jpg_qbuf (struct file *file,
1059 int frame,
1060 enum zoran_codec_mode mode)
1061{
1062 struct zoran_fh *fh = file->private_data;
1063 struct zoran *zr = fh->zr;
1064 int res = 0;
1065
1066 /* Does the user want to stop streaming? */
1067 if (frame < 0) {
1068 if (zr->codec_mode == mode) {
1069 if (fh->jpg_buffers.active == ZORAN_FREE) {
1070 dprintk(1,
1071 KERN_ERR
1072 "%s: jpg_qbuf(-1) - session not active\n",
1073 ZR_DEVNAME(zr));
1074 return -EINVAL;
1075 }
1076 fh->jpg_buffers.active = zr->jpg_buffers.active =
1077 ZORAN_FREE;
1078 zr->jpg_buffers.allocated = 0;
1079 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1080 return 0;
1081 } else {
1082 dprintk(1,
1083 KERN_ERR
1084 "%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
1085 ZR_DEVNAME(zr));
1086 return -EINVAL;
1087 }
1088 }
1089
1090 if ((res = zoran_jpg_queue_frame(file, frame, mode)))
1091 return res;
1092
1093 /* Start the jpeg codec when the first frame is queued */
1094 if (!res && zr->jpg_que_head == 1)
1095 jpeg_start(zr);
1096
1097 return res;
1098}
1099
1100/*
1101 * Sync on a MJPEG buffer
1102 */
1103
1104static int
1105jpg_sync (struct file *file,
1106 struct zoran_sync *bs)
1107{
1108 struct zoran_fh *fh = file->private_data;
1109 struct zoran *zr = fh->zr;
1110 unsigned long flags;
1111 int frame;
1112
1113 if (fh->jpg_buffers.active == ZORAN_FREE) {
1114 dprintk(1,
1115 KERN_ERR
1116 "%s: jpg_sync() - capture is not currently active\n",
1117 ZR_DEVNAME(zr));
1118 return -EINVAL;
1119 }
1120 if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
1121 zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
1122 dprintk(1,
1123 KERN_ERR
1124 "%s: jpg_sync() - codec not in streaming mode\n",
1125 ZR_DEVNAME(zr));
1126 return -EINVAL;
1127 }
1128 if (!wait_event_interruptible_timeout(zr->jpg_capq,
1129 (zr->jpg_que_tail != zr->jpg_dma_tail ||
1130 zr->jpg_dma_tail == zr->jpg_dma_head),
1131 10*HZ)) {
1132 int isr;
1133
1134 btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
1135 udelay(1);
1136 zr->codec->control(zr->codec, CODEC_G_STATUS,
1137 sizeof(isr), &isr);
1138 dprintk(1,
1139 KERN_ERR
1140 "%s: jpg_sync() - timeout: codec isr=0x%02x\n",
1141 ZR_DEVNAME(zr), isr);
1142
1143 return -ETIME;
1144
1145 }
1146 if (signal_pending(current))
1147 return -ERESTARTSYS;
1148
1149 spin_lock_irqsave(&zr->spinlock, flags);
1150
1151 if (zr->jpg_dma_tail != zr->jpg_dma_head)
1152 frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
1153 else
1154 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
1155
1156 /* buffer should now be in BUZ_STATE_DONE */
1157 if (*zr_debug > 0)
1158 if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
1159 dprintk(2,
1160 KERN_ERR
1161 "%s: jpg_sync() - internal state error\n",
1162 ZR_DEVNAME(zr));
1163
1164 *bs = zr->jpg_buffers.buffer[frame].bs;
1165 bs->frame = frame;
1166 zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
1167 fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
1168
1169 spin_unlock_irqrestore(&zr->spinlock, flags);
1170
1171 return 0;
1172}
1173
1174static void
1175zoran_open_init_session (struct file *file)
1176{
1177 int i;
1178 struct zoran_fh *fh = file->private_data;
1179 struct zoran *zr = fh->zr;
1180
1181 /* Per default, map the V4L Buffers */
1182 fh->map_mode = ZORAN_MAP_MODE_RAW;
1183
1184 /* take over the card's current settings */
1185 fh->overlay_settings = zr->overlay_settings;
1186 fh->overlay_settings.is_set = 0;
1187 fh->overlay_settings.format = zr->overlay_settings.format;
1188 fh->overlay_active = ZORAN_FREE;
1189
1190 /* v4l settings */
1191 fh->v4l_settings = zr->v4l_settings;
1192
1193 /* v4l_buffers */
1194 memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
1195 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1196 fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
1197 fh->v4l_buffers.buffer[i].bs.frame = i;
1198 }
1199 fh->v4l_buffers.allocated = 0;
1200 fh->v4l_buffers.ready_to_be_freed = 0;
1201 fh->v4l_buffers.active = ZORAN_FREE;
1202 fh->v4l_buffers.buffer_size = v4l_bufsize;
1203 fh->v4l_buffers.num_buffers = v4l_nbufs;
1204
1205 /* jpg settings */
1206 fh->jpg_settings = zr->jpg_settings;
1207
1208 /* jpg_buffers */
1209 memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
1210 for (i = 0; i < BUZ_MAX_FRAME; i++) {
1211 fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
1212 fh->jpg_buffers.buffer[i].bs.frame = i;
1213 }
1214 fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
1215 fh->jpg_buffers.allocated = 0;
1216 fh->jpg_buffers.ready_to_be_freed = 0;
1217 fh->jpg_buffers.active = ZORAN_FREE;
1218 fh->jpg_buffers.buffer_size = jpg_bufsize;
1219 fh->jpg_buffers.num_buffers = jpg_nbufs;
1220}
1221
1222static void
1223zoran_close_end_session (struct file *file)
1224{
1225 struct zoran_fh *fh = file->private_data;
1226 struct zoran *zr = fh->zr;
1227
1228 /* overlay */
1229 if (fh->overlay_active != ZORAN_FREE) {
1230 fh->overlay_active = zr->overlay_active = ZORAN_FREE;
1231 zr->v4l_overlay_active = 0;
1232 if (!zr->v4l_memgrab_active)
1233 zr36057_overlay(zr, 0);
1234 zr->overlay_mask = NULL;
1235 }
1236
1237 /* v4l capture */
1238 if (fh->v4l_buffers.active != ZORAN_FREE) {
1239 zr36057_set_memgrab(zr, 0);
1240 zr->v4l_buffers.allocated = 0;
1241 zr->v4l_buffers.active = fh->v4l_buffers.active =
1242 ZORAN_FREE;
1243 }
1244
1245 /* v4l buffers */
1246 if (fh->v4l_buffers.allocated ||
1247 fh->v4l_buffers.ready_to_be_freed) {
1248 v4l_fbuffer_free(file);
1249 }
1250
1251 /* jpg capture */
1252 if (fh->jpg_buffers.active != ZORAN_FREE) {
1253 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1254 zr->jpg_buffers.allocated = 0;
1255 zr->jpg_buffers.active = fh->jpg_buffers.active =
1256 ZORAN_FREE;
1257 }
1258
1259 /* jpg buffers */
1260 if (fh->jpg_buffers.allocated ||
1261 fh->jpg_buffers.ready_to_be_freed) {
1262 jpg_fbuffer_free(file);
1263 }
1264}
1265
1266/*
1267 * Open a zoran card. Right now the flags stuff is just playing
1268 */
1269
1270static int
1271zoran_open (struct inode *inode,
1272 struct file *file)
1273{
1274 unsigned int minor = iminor(inode);
1275 struct zoran *zr = NULL;
1276 struct zoran_fh *fh;
1277 int i, res, first_open = 0, have_module_locks = 0;
1278
1279 /* find the device */
1280 for (i = 0; i < zoran_num; i++) {
1281 if (zoran[i].video_dev->minor == minor) {
1282 zr = &zoran[i];
1283 break;
1284 }
1285 }
1286
1287 if (!zr) {
1288 dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
1289 res = -ENODEV;
1290 goto open_unlock_and_return;
1291 }
1292
1293 /* see fs/device.c - the kernel already locks during open(),
1294 * so locking ourselves only causes deadlocks */
1295 /*down(&zr->resource_lock);*/
1296
1297 if (!zr->decoder) {
1298 dprintk(1,
1299 KERN_ERR "%s: no TV decoder loaded for device!\n",
1300 ZR_DEVNAME(zr));
1301 res = -EIO;
1302 goto open_unlock_and_return;
1303 }
1304
1305 /* try to grab a module lock */
1306 if (!try_module_get(THIS_MODULE)) {
1307 dprintk(1,
1308 KERN_ERR
1309 "%s: failed to acquire my own lock! PANIC!\n",
1310 ZR_DEVNAME(zr));
1311 res = -ENODEV;
1312 goto open_unlock_and_return;
1313 }
1314 if (!try_module_get(zr->decoder->driver->owner)) {
1315 dprintk(1,
1316 KERN_ERR
1317 "%s: failed to grab ownership of i2c decoder\n",
1318 ZR_DEVNAME(zr));
1319 res = -EIO;
1320 module_put(THIS_MODULE);
1321 goto open_unlock_and_return;
1322 }
1323 if (zr->encoder &&
1324 !try_module_get(zr->encoder->driver->owner)) {
1325 dprintk(1,
1326 KERN_ERR
1327 "%s: failed to grab ownership of i2c encoder\n",
1328 ZR_DEVNAME(zr));
1329 res = -EIO;
1330 module_put(zr->decoder->driver->owner);
1331 module_put(THIS_MODULE);
1332 goto open_unlock_and_return;
1333 }
1334
1335 have_module_locks = 1;
1336
1337 if (zr->user >= 2048) {
1338 dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
1339 ZR_DEVNAME(zr), zr->user);
1340 res = -EBUSY;
1341 goto open_unlock_and_return;
1342 }
1343
1344 dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
1345 ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
1346
1347 /* now, create the open()-specific file_ops struct */
1348 fh = kmalloc(sizeof(struct zoran_fh), GFP_KERNEL);
1349 if (!fh) {
1350 dprintk(1,
1351 KERN_ERR
1352 "%s: zoran_open() - allocation of zoran_fh failed\n",
1353 ZR_DEVNAME(zr));
1354 res = -ENOMEM;
1355 goto open_unlock_and_return;
1356 }
1357 memset(fh, 0, sizeof(struct zoran_fh));
1358 /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
1359 * on norm-change! */
1360 fh->overlay_mask =
1361 kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);
1362 if (!fh->overlay_mask) {
1363 dprintk(1,
1364 KERN_ERR
1365 "%s: zoran_open() - allocation of overlay_mask failed\n",
1366 ZR_DEVNAME(zr));
1367 kfree(fh);
1368 res = -ENOMEM;
1369 goto open_unlock_and_return;
1370 }
1371
1372 if (zr->user++ == 0)
1373 first_open = 1;
1374
1375 /*up(&zr->resource_lock);*/
1376
1377 /* default setup - TODO: look at flags */
1378 if (first_open) { /* First device open */
1379 zr36057_restart(zr);
1380 zoran_open_init_params(zr);
1381 zoran_init_hardware(zr);
1382
1383 btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
1384 }
1385
1386 /* set file_ops stuff */
1387 file->private_data = fh;
1388 fh->zr = zr;
1389 zoran_open_init_session(file);
1390
1391 return 0;
1392
1393open_unlock_and_return:
1394 /* if we grabbed locks, release them accordingly */
1395 if (have_module_locks) {
1396 module_put(zr->decoder->driver->owner);
1397 if (zr->encoder) {
1398 module_put(zr->encoder->driver->owner);
1399 }
1400 module_put(THIS_MODULE);
1401 }
1402
1403 /* if there's no device found, we didn't obtain the lock either */
1404 if (zr) {
1405 /*up(&zr->resource_lock);*/
1406 }
1407
1408 return res;
1409}
1410
1411static int
1412zoran_close (struct inode *inode,
1413 struct file *file)
1414{
1415 struct zoran_fh *fh = file->private_data;
1416 struct zoran *zr = fh->zr;
1417
1418 dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
1419 ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
1420
1421 /* kernel locks (fs/device.c), so don't do that ourselves
1422 * (prevents deadlocks) */
1423 /*down(&zr->resource_lock);*/
1424
1425 zoran_close_end_session(file);
1426
1427 if (zr->user-- == 1) { /* Last process */
1428 /* Clean up JPEG process */
1429 wake_up_interruptible(&zr->jpg_capq);
1430 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1431 zr->jpg_buffers.allocated = 0;
1432 zr->jpg_buffers.active = ZORAN_FREE;
1433
1434 /* disable interrupts */
1435 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1436
1437 if (*zr_debug > 1)
1438 print_interrupts(zr);
1439
1440 /* Overlay off */
1441 zr->v4l_overlay_active = 0;
1442 zr36057_overlay(zr, 0);
1443 zr->overlay_mask = NULL;
1444
1445 /* capture off */
1446 wake_up_interruptible(&zr->v4l_capq);
1447 zr36057_set_memgrab(zr, 0);
1448 zr->v4l_buffers.allocated = 0;
1449 zr->v4l_buffers.active = ZORAN_FREE;
1450 zoran_set_pci_master(zr, 0);
1451
1452 if (!pass_through) { /* Switch to color bar */
1453 int zero = 0, two = 2;
1454 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1455 encoder_command(zr, ENCODER_SET_INPUT, &two);
1456 }
1457 }
1458
1459 file->private_data = NULL;
1460 kfree(fh->overlay_mask);
1461 kfree(fh);
1462
1463 /* release locks on the i2c modules */
1464 module_put(zr->decoder->driver->owner);
1465 if (zr->encoder) {
1466 module_put(zr->encoder->driver->owner);
1467 }
1468 module_put(THIS_MODULE);
1469
1470 /*up(&zr->resource_lock);*/
1471
1472 dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
1473
1474 return 0;
1475}
1476
1477
1478static ssize_t
1479zoran_read (struct file *file,
1480 char __user *data,
1481 size_t count,
1482 loff_t *ppos)
1483{
1484 /* we simply don't support read() (yet)... */
1485
1486 return -EINVAL;
1487}
1488
1489static ssize_t
1490zoran_write (struct file *file,
1491 const char __user *data,
1492 size_t count,
1493 loff_t *ppos)
1494{
1495 /* ...and the same goes for write() */
1496
1497 return -EINVAL;
1498}
1499
1500static int
1501setup_fbuffer (struct file *file,
1502 void *base,
1503 const struct zoran_format *fmt,
1504 int width,
1505 int height,
1506 int bytesperline)
1507{
1508 struct zoran_fh *fh = file->private_data;
1509 struct zoran *zr = fh->zr;
1510
1511 /* (Ronald) v4l/v4l2 guidelines */
1512 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
1513 return -EPERM;
1514
1515 /* we need a bytesperline value, even if not given */
1516 if (!bytesperline)
1517 bytesperline = width * ((fmt->depth + 7) & ~7) / 8;
1518
1519#if 0
1520 if (zr->overlay_active) {
1521 /* dzjee... stupid users... don't even bother to turn off
1522 * overlay before changing the memory location...
1523 * normally, we would return errors here. However, one of
1524 * the tools that does this is... xawtv! and since xawtv
1525 * is used by +/- 99% of the users, we'd rather be user-
1526 * friendly and silently do as if nothing went wrong */
1527 dprintk(3,
1528 KERN_ERR
1529 "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
1530 ZR_DEVNAME(zr));
1531 zr36057_overlay(zr, 0);
1532 }
1533#endif
1534
1535 if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
1536 dprintk(1,
1537 KERN_ERR
1538 "%s: setup_fbuffer() - no valid overlay format given\n",
1539 ZR_DEVNAME(zr));
1540 return -EINVAL;
1541 }
1542 if (height <= 0 || width <= 0 || bytesperline <= 0) {
1543 dprintk(1,
1544 KERN_ERR
1545 "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
1546 ZR_DEVNAME(zr), width, height, bytesperline);
1547 return -EINVAL;
1548 }
1549 if (bytesperline & 3) {
1550 dprintk(1,
1551 KERN_ERR
1552 "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
1553 ZR_DEVNAME(zr), bytesperline);
1554 return -EINVAL;
1555 }
1556
1557 zr->buffer.base = (void *) ((unsigned long) base & ~3);
1558 zr->buffer.height = height;
1559 zr->buffer.width = width;
1560 zr->buffer.depth = fmt->depth;
1561 zr->overlay_settings.format = fmt;
1562 zr->buffer.bytesperline = bytesperline;
1563
1564 /* The user should set new window parameters */
1565 zr->overlay_settings.is_set = 0;
1566
1567 return 0;
1568}
1569
1570
1571static int
1572setup_window (struct file *file,
1573 int x,
1574 int y,
1575 int width,
1576 int height,
1577 struct video_clip __user *clips,
1578 int clipcount,
1579 void __user *bitmap)
1580{
1581 struct zoran_fh *fh = file->private_data;
1582 struct zoran *zr = fh->zr;
1583 struct video_clip *vcp = NULL;
1584 int on, end;
1585
1586
1587 if (!zr->buffer.base) {
1588 dprintk(1,
1589 KERN_ERR
1590 "%s: setup_window() - frame buffer has to be set first\n",
1591 ZR_DEVNAME(zr));
1592 return -EINVAL;
1593 }
1594
1595 if (!fh->overlay_settings.format) {
1596 dprintk(1,
1597 KERN_ERR
1598 "%s: setup_window() - no overlay format set\n",
1599 ZR_DEVNAME(zr));
1600 return -EINVAL;
1601 }
1602
1603 /*
1604 * The video front end needs 4-byte alinged line sizes, we correct that
1605 * silently here if necessary
1606 */
1607 if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
1608 end = (x + width) & ~1; /* round down */
1609 x = (x + 1) & ~1; /* round up */
1610 width = end - x;
1611 }
1612
1613 if (zr->buffer.depth == 24) {
1614 end = (x + width) & ~3; /* round down */
1615 x = (x + 3) & ~3; /* round up */
1616 width = end - x;
1617 }
1618
1619 if (width > BUZ_MAX_WIDTH)
1620 width = BUZ_MAX_WIDTH;
1621 if (height > BUZ_MAX_HEIGHT)
1622 height = BUZ_MAX_HEIGHT;
1623
1624 /* Check for vaild parameters */
1625 if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT ||
1626 width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
1627 dprintk(1,
1628 KERN_ERR
1629 "%s: setup_window() - width = %d or height = %d invalid\n",
1630 ZR_DEVNAME(zr), width, height);
1631 return -EINVAL;
1632 }
1633
1634 fh->overlay_settings.x = x;
1635 fh->overlay_settings.y = y;
1636 fh->overlay_settings.width = width;
1637 fh->overlay_settings.height = height;
1638 fh->overlay_settings.clipcount = clipcount;
1639
1640 /*
1641 * If an overlay is running, we have to switch it off
1642 * and switch it on again in order to get the new settings in effect.
1643 *
1644 * We also want to avoid that the overlay mask is written
1645 * when an overlay is running.
1646 */
1647
1648 on = zr->v4l_overlay_active && !zr->v4l_memgrab_active &&
1649 zr->overlay_active != ZORAN_FREE &&
1650 fh->overlay_active != ZORAN_FREE;
1651 if (on)
1652 zr36057_overlay(zr, 0);
1653
1654 /*
1655 * Write the overlay mask if clips are wanted.
1656 * We prefer a bitmap.
1657 */
1658 if (bitmap) {
1659 /* fake value - it just means we want clips */
1660 fh->overlay_settings.clipcount = 1;
1661
1662 if (copy_from_user(fh->overlay_mask, bitmap,
1663 (width * height + 7) / 8)) {
1664 return -EFAULT;
1665 }
1666 } else if (clipcount > 0) {
1667 /* write our own bitmap from the clips */
1668 vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
1669 if (vcp == NULL) {
1670 dprintk(1,
1671 KERN_ERR
1672 "%s: setup_window() - Alloc of clip mask failed\n",
1673 ZR_DEVNAME(zr));
1674 return -ENOMEM;
1675 }
1676 if (copy_from_user
1677 (vcp, clips, sizeof(struct video_clip) * clipcount)) {
1678 vfree(vcp);
1679 return -EFAULT;
1680 }
1681 write_overlay_mask(file, vcp, clipcount);
1682 vfree(vcp);
1683 }
1684
1685 fh->overlay_settings.is_set = 1;
1686 if (fh->overlay_active != ZORAN_FREE &&
1687 zr->overlay_active != ZORAN_FREE)
1688 zr->overlay_settings = fh->overlay_settings;
1689
1690 if (on)
1691 zr36057_overlay(zr, 1);
1692
1693 /* Make sure the changes come into effect */
1694 return wait_grab_pending(zr);
1695}
1696
1697static int
1698setup_overlay (struct file *file,
1699 int on)
1700{
1701 struct zoran_fh *fh = file->private_data;
1702 struct zoran *zr = fh->zr;
1703
1704 /* If there is nothing to do, return immediatly */
1705 if ((on && fh->overlay_active != ZORAN_FREE) ||
1706 (!on && fh->overlay_active == ZORAN_FREE))
1707 return 0;
1708
1709 /* check whether we're touching someone else's overlay */
1710 if (on && zr->overlay_active != ZORAN_FREE &&
1711 fh->overlay_active == ZORAN_FREE) {
1712 dprintk(1,
1713 KERN_ERR
1714 "%s: setup_overlay() - overlay is already active for another session\n",
1715 ZR_DEVNAME(zr));
1716 return -EBUSY;
1717 }
1718 if (!on && zr->overlay_active != ZORAN_FREE &&
1719 fh->overlay_active == ZORAN_FREE) {
1720 dprintk(1,
1721 KERN_ERR
1722 "%s: setup_overlay() - you cannot cancel someone else's session\n",
1723 ZR_DEVNAME(zr));
1724 return -EPERM;
1725 }
1726
1727 if (on == 0) {
1728 zr->overlay_active = fh->overlay_active = ZORAN_FREE;
1729 zr->v4l_overlay_active = 0;
1730 /* When a grab is running, the video simply
1731 * won't be switched on any more */
1732 if (!zr->v4l_memgrab_active)
1733 zr36057_overlay(zr, 0);
1734 zr->overlay_mask = NULL;
1735 } else {
1736 if (!zr->buffer.base || !fh->overlay_settings.is_set) {
1737 dprintk(1,
1738 KERN_ERR
1739 "%s: setup_overlay() - buffer or window not set\n",
1740 ZR_DEVNAME(zr));
1741 return -EINVAL;
1742 }
1743 if (!fh->overlay_settings.format) {
1744 dprintk(1,
1745 KERN_ERR
1746 "%s: setup_overlay() - no overlay format set\n",
1747 ZR_DEVNAME(zr));
1748 return -EINVAL;
1749 }
1750 zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
1751 zr->v4l_overlay_active = 1;
1752 zr->overlay_mask = fh->overlay_mask;
1753 zr->overlay_settings = fh->overlay_settings;
1754 if (!zr->v4l_memgrab_active)
1755 zr36057_overlay(zr, 1);
1756 /* When a grab is running, the video will be
1757 * switched on when grab is finished */
1758 }
1759
1760 /* Make sure the changes come into effect */
1761 return wait_grab_pending(zr);
1762}
1763
1764#ifdef HAVE_V4L2
1765 /* get the status of a buffer in the clients buffer queue */
1766static int
1767zoran_v4l2_buffer_status (struct file *file,
1768 struct v4l2_buffer *buf,
1769 int num)
1770{
1771 struct zoran_fh *fh = file->private_data;
1772 struct zoran *zr = fh->zr;
1773
1774 buf->flags = V4L2_BUF_FLAG_MAPPED;
1775
1776 switch (fh->map_mode) {
1777 case ZORAN_MAP_MODE_RAW:
1778
1779 /* check range */
1780 if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
1781 !fh->v4l_buffers.allocated) {
1782 dprintk(1,
1783 KERN_ERR
1784 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1785 ZR_DEVNAME(zr));
1786 return -EINVAL;
1787 }
1788
1789 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1790 buf->length = fh->v4l_buffers.buffer_size;
1791
1792 /* get buffer */
1793 buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
1794 if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
1795 fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
1796 buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
1797 buf->flags |= V4L2_BUF_FLAG_DONE;
1798 buf->timestamp =
1799 fh->v4l_buffers.buffer[num].bs.timestamp;
1800 } else {
1801 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1802 }
1803
1804 if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2)
1805 buf->field = V4L2_FIELD_TOP;
1806 else
1807 buf->field = V4L2_FIELD_INTERLACED;
1808
1809 break;
1810
1811 case ZORAN_MAP_MODE_JPG_REC:
1812 case ZORAN_MAP_MODE_JPG_PLAY:
1813
1814 /* check range */
1815 if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
1816 !fh->jpg_buffers.allocated) {
1817 dprintk(1,
1818 KERN_ERR
1819 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1820 ZR_DEVNAME(zr));
1821 return -EINVAL;
1822 }
1823
1824 buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
1825 V4L2_BUF_TYPE_VIDEO_CAPTURE :
1826 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1827 buf->length = fh->jpg_buffers.buffer_size;
1828
1829 /* these variables are only written after frame has been captured */
1830 if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
1831 fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
1832 buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
1833 buf->timestamp =
1834 fh->jpg_buffers.buffer[num].bs.timestamp;
1835 buf->bytesused =
1836 fh->jpg_buffers.buffer[num].bs.length;
1837 buf->flags |= V4L2_BUF_FLAG_DONE;
1838 } else {
1839 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1840 }
1841
1842 /* which fields are these? */
1843 if (fh->jpg_settings.TmpDcm != 1)
1844 buf->field =
1845 fh->jpg_settings.
1846 odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1847 else
1848 buf->field =
1849 fh->jpg_settings.
1850 odd_even ? V4L2_FIELD_SEQ_TB :
1851 V4L2_FIELD_SEQ_BT;
1852
1853 break;
1854
1855 default:
1856
1857 dprintk(5,
1858 KERN_ERR
1859 "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
1860 ZR_DEVNAME(zr), buf->type, fh->map_mode);
1861 return -EINVAL;
1862 }
1863
1864 buf->memory = V4L2_MEMORY_MMAP;
1865 buf->index = num;
1866 buf->m.offset = buf->length * num;
1867
1868 return 0;
1869}
1870#endif
1871
1872static int
1873zoran_set_norm (struct zoran *zr,
1874 int norm) /* VIDEO_MODE_* */
1875{
1876 int norm_encoder, on;
1877
1878 if (zr->v4l_buffers.active != ZORAN_FREE ||
1879 zr->jpg_buffers.active != ZORAN_FREE) {
1880 dprintk(1,
1881 KERN_WARNING
1882 "%s: set_norm() called while in playback/capture mode\n",
1883 ZR_DEVNAME(zr));
1884 return -EBUSY;
1885 }
1886
1887 if (lock_norm && norm != zr->norm) {
1888 if (lock_norm > 1) {
1889 dprintk(1,
1890 KERN_WARNING
1891 "%s: set_norm() - TV standard is locked, can not switch norm\n",
1892 ZR_DEVNAME(zr));
1893 return -EPERM;
1894 } else {
1895 dprintk(1,
1896 KERN_WARNING
1897 "%s: set_norm() - TV standard is locked, norm was not changed\n",
1898 ZR_DEVNAME(zr));
1899 norm = zr->norm;
1900 }
1901 }
1902
1903 if (norm != VIDEO_MODE_AUTO &&
1904 (norm < 0 || norm >= zr->card.norms ||
1905 !zr->card.tvn[norm])) {
1906 dprintk(1,
1907 KERN_ERR "%s: set_norm() - unsupported norm %d\n",
1908 ZR_DEVNAME(zr), norm);
1909 return -EINVAL;
1910 }
1911
1912 if (norm == VIDEO_MODE_AUTO) {
1913 int status;
1914
1915 /* if we have autodetect, ... */
1916 struct video_decoder_capability caps;
1917 decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
1918 if (!(caps.flags & VIDEO_DECODER_AUTO)) {
1919 dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
1920 ZR_DEVNAME(zr));
1921 return -EINVAL;
1922 }
1923
1924 decoder_command(zr, DECODER_SET_NORM, &norm);
1925
1926 /* let changes come into effect */
1927 ssleep(2);
1928
1929 decoder_command(zr, DECODER_GET_STATUS, &status);
1930 if (!(status & DECODER_STATUS_GOOD)) {
1931 dprintk(1,
1932 KERN_ERR
1933 "%s: set_norm() - no norm detected\n",
1934 ZR_DEVNAME(zr));
1935 /* reset norm */
1936 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
1937 return -EIO;
1938 }
1939
1940 if (status & DECODER_STATUS_NTSC)
1941 norm = VIDEO_MODE_NTSC;
1942 else if (status & DECODER_STATUS_SECAM)
1943 norm = VIDEO_MODE_SECAM;
1944 else
1945 norm = VIDEO_MODE_PAL;
1946 }
1947 zr->timing = zr->card.tvn[norm];
1948 norm_encoder = norm;
1949
1950 /* We switch overlay off and on since a change in the
1951 * norm needs different VFE settings */
1952 on = zr->overlay_active && !zr->v4l_memgrab_active;
1953 if (on)
1954 zr36057_overlay(zr, 0);
1955
1956 decoder_command(zr, DECODER_SET_NORM, &norm);
1957 encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
1958
1959 if (on)
1960 zr36057_overlay(zr, 1);
1961
1962 /* Make sure the changes come into effect */
1963 zr->norm = norm;
1964
1965 return 0;
1966}
1967
1968static int
1969zoran_set_input (struct zoran *zr,
1970 int input)
1971{
1972 int realinput;
1973
1974 if (input == zr->input) {
1975 return 0;
1976 }
1977
1978 if (zr->v4l_buffers.active != ZORAN_FREE ||
1979 zr->jpg_buffers.active != ZORAN_FREE) {
1980 dprintk(1,
1981 KERN_WARNING
1982 "%s: set_input() called while in playback/capture mode\n",
1983 ZR_DEVNAME(zr));
1984 return -EBUSY;
1985 }
1986
1987 if (input < 0 || input >= zr->card.inputs) {
1988 dprintk(1,
1989 KERN_ERR
1990 "%s: set_input() - unnsupported input %d\n",
1991 ZR_DEVNAME(zr), input);
1992 return -EINVAL;
1993 }
1994
1995 realinput = zr->card.input[input].muxsel;
1996 zr->input = input;
1997
1998 decoder_command(zr, DECODER_SET_INPUT, &realinput);
1999
2000 return 0;
2001}
2002
2003/*
2004 * ioctl routine
2005 */
2006
2007static int
2008zoran_do_ioctl (struct inode *inode,
2009 struct file *file,
2010 unsigned int cmd,
2011 void *arg)
2012{
2013 struct zoran_fh *fh = file->private_data;
2014 struct zoran *zr = fh->zr;
2015 /* CAREFUL: used in multiple places here */
2016 struct zoran_jpg_settings settings;
2017
2018 /* we might have older buffers lying around... We don't want
2019 * to wait, but we do want to try cleaning them up ASAP. So
2020 * we try to obtain the lock and free them. If that fails, we
2021 * don't do anything and wait for the next turn. In the end,
2022 * zoran_close() or a new allocation will still free them...
2023 * This is just a 'the sooner the better' extra 'feature'
2024 *
2025 * We don't free the buffers right on munmap() because that
2026 * causes oopses (kfree() inside munmap() oopses for no
2027 * apparent reason - it's also not reproduceable in any way,
2028 * but moving the free code outside the munmap() handler fixes
2029 * all this... If someone knows why, please explain me (Ronald)
2030 */
2031 if (!down_trylock(&zr->resource_lock)) {
2032 /* we obtained it! Let's try to free some things */
2033 if (fh->jpg_buffers.ready_to_be_freed)
2034 jpg_fbuffer_free(file);
2035 if (fh->v4l_buffers.ready_to_be_freed)
2036 v4l_fbuffer_free(file);
2037
2038 up(&zr->resource_lock);
2039 }
2040
2041 switch (cmd) {
2042
2043 case VIDIOCGCAP:
2044 {
2045 struct video_capability *vcap = arg;
2046
2047 dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
2048
2049 memset(vcap, 0, sizeof(struct video_capability));
2050 strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name));
2051 vcap->type = ZORAN_VID_TYPE;
2052
2053 vcap->channels = zr->card.inputs;
2054 vcap->audios = 0;
2055 down(&zr->resource_lock);
2056 vcap->maxwidth = BUZ_MAX_WIDTH;
2057 vcap->maxheight = BUZ_MAX_HEIGHT;
2058 vcap->minwidth = BUZ_MIN_WIDTH;
2059 vcap->minheight = BUZ_MIN_HEIGHT;
2060 up(&zr->resource_lock);
2061
2062 return 0;
2063 }
2064 break;
2065
2066 case VIDIOCGCHAN:
2067 {
2068 struct video_channel *vchan = arg;
2069 int channel = vchan->channel;
2070
2071 dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n",
2072 ZR_DEVNAME(zr), vchan->channel);
2073
2074 memset(vchan, 0, sizeof(struct video_channel));
2075 if (channel > zr->card.inputs || channel < 0) {
2076 dprintk(1,
2077 KERN_ERR
2078 "%s: VIDIOCGCHAN on not existing channel %d\n",
2079 ZR_DEVNAME(zr), channel);
2080 return -EINVAL;
2081 }
2082
2083 strcpy(vchan->name, zr->card.input[channel].name);
2084
2085 vchan->tuners = 0;
2086 vchan->flags = 0;
2087 vchan->type = VIDEO_TYPE_CAMERA;
2088 down(&zr->resource_lock);
2089 vchan->norm = zr->norm;
2090 up(&zr->resource_lock);
2091 vchan->channel = channel;
2092
2093 return 0;
2094 }
2095 break;
2096
2097 /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
2098 *
2099 * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
2100 * * ^^^^^^^
2101 * * The famos BTTV driver has it implemented with a struct video_channel argument
2102 * * and we follow it for compatibility reasons
2103 * *
2104 * * BTW: this is the only way the user can set the norm!
2105 */
2106
2107 case VIDIOCSCHAN:
2108 {
2109 struct video_channel *vchan = arg;
2110 int res;
2111
2112 dprintk(3,
2113 KERN_DEBUG
2114 "%s: VIDIOCSCHAN - channel=%d, norm=%d\n",
2115 ZR_DEVNAME(zr), vchan->channel, vchan->norm);
2116
2117 down(&zr->resource_lock);
2118 if ((res = zoran_set_input(zr, vchan->channel)))
2119 goto schan_unlock_and_return;
2120 if ((res = zoran_set_norm(zr, vchan->norm)))
2121 goto schan_unlock_and_return;
2122
2123 /* Make sure the changes come into effect */
2124 res = wait_grab_pending(zr);
2125 schan_unlock_and_return:
2126 up(&zr->resource_lock);
2127 return res;
2128 }
2129 break;
2130
2131 case VIDIOCGPICT:
2132 {
2133 struct video_picture *vpict = arg;
2134
2135 dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr));
2136
2137 memset(vpict, 0, sizeof(struct video_picture));
2138 down(&zr->resource_lock);
2139 vpict->hue = zr->hue;
2140 vpict->brightness = zr->brightness;
2141 vpict->contrast = zr->contrast;
2142 vpict->colour = zr->saturation;
2143 if (fh->overlay_settings.format) {
2144 vpict->depth = fh->overlay_settings.format->depth;
2145 vpict->palette = fh->overlay_settings.format->palette;
2146 } else {
2147 vpict->depth = 0;
2148 }
2149 up(&zr->resource_lock);
2150
2151 return 0;
2152 }
2153 break;
2154
2155 case VIDIOCSPICT:
2156 {
2157 struct video_picture *vpict = arg;
2158 int i;
2159
2160 dprintk(3,
2161 KERN_DEBUG
2162 "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n",
2163 ZR_DEVNAME(zr), vpict->brightness, vpict->hue,
2164 vpict->colour, vpict->contrast, vpict->depth,
2165 vpict->palette);
2166
2167 for (i = 0; i < zoran_num_formats; i++) {
2168 const struct zoran_format *fmt = &zoran_formats[i];
2169
2170 if (fmt->palette != -1 &&
2171 fmt->flags & ZORAN_FORMAT_OVERLAY &&
2172 fmt->palette == vpict->palette &&
2173 fmt->depth == vpict->depth)
2174 break;
2175 }
2176 if (i == zoran_num_formats) {
2177 dprintk(1,
2178 KERN_ERR
2179 "%s: VIDIOCSPICT - Invalid palette %d\n",
2180 ZR_DEVNAME(zr), vpict->palette);
2181 return -EINVAL;
2182 }
2183
2184 down(&zr->resource_lock);
2185
2186 decoder_command(zr, DECODER_SET_PICTURE, vpict);
2187
2188 zr->hue = vpict->hue;
2189 zr->contrast = vpict->contrast;
2190 zr->saturation = vpict->colour;
2191 zr->brightness = vpict->brightness;
2192
2193 fh->overlay_settings.format = &zoran_formats[i];
2194
2195 up(&zr->resource_lock);
2196
2197 return 0;
2198 }
2199 break;
2200
2201 case VIDIOCCAPTURE:
2202 {
2203 int *on = arg, res;
2204
2205 dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n",
2206 ZR_DEVNAME(zr), *on);
2207
2208 down(&zr->resource_lock);
2209 res = setup_overlay(file, *on);
2210 up(&zr->resource_lock);
2211
2212 return res;
2213 }
2214 break;
2215
2216 case VIDIOCGWIN:
2217 {
2218 struct video_window *vwin = arg;
2219
2220 dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr));
2221
2222 memset(vwin, 0, sizeof(struct video_window));
2223 down(&zr->resource_lock);
2224 vwin->x = fh->overlay_settings.x;
2225 vwin->y = fh->overlay_settings.y;
2226 vwin->width = fh->overlay_settings.width;
2227 vwin->height = fh->overlay_settings.height;
2228 up(&zr->resource_lock);
2229 vwin->clipcount = 0;
2230 return 0;
2231 }
2232 break;
2233
2234 case VIDIOCSWIN:
2235 {
2236 struct video_window *vwin = arg;
2237 int res;
2238
2239 dprintk(3,
2240 KERN_DEBUG
2241 "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n",
2242 ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width,
2243 vwin->height, vwin->clipcount);
2244
2245 down(&zr->resource_lock);
2246 res =
2247 setup_window(file, vwin->x, vwin->y, vwin->width,
2248 vwin->height, vwin->clips,
2249 vwin->clipcount, NULL);
2250 up(&zr->resource_lock);
2251
2252 return res;
2253 }
2254 break;
2255
2256 case VIDIOCGFBUF:
2257 {
2258 struct video_buffer *vbuf = arg;
2259
2260 dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr));
2261
2262 down(&zr->resource_lock);
2263 *vbuf = zr->buffer;
2264 up(&zr->resource_lock);
2265 return 0;
2266 }
2267 break;
2268
2269 case VIDIOCSFBUF:
2270 {
2271 struct video_buffer *vbuf = arg;
2272 int i, res = 0;
2273
2274 dprintk(3,
2275 KERN_DEBUG
2276 "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
2277 ZR_DEVNAME(zr), vbuf->base, vbuf->width,
2278 vbuf->height, vbuf->depth, vbuf->bytesperline);
2279
2280 for (i = 0; i < zoran_num_formats; i++)
2281 if (zoran_formats[i].depth == vbuf->depth)
2282 break;
2283 if (i == zoran_num_formats) {
2284 dprintk(1,
2285 KERN_ERR
2286 "%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
2287 ZR_DEVNAME(zr), vbuf->depth);
2288 return -EINVAL;
2289 }
2290
2291 down(&zr->resource_lock);
2292 res =
2293 setup_fbuffer(file, vbuf->base, &zoran_formats[i],
2294 vbuf->width, vbuf->height,
2295 vbuf->bytesperline);
2296 up(&zr->resource_lock);
2297
2298 return res;
2299 }
2300 break;
2301
2302 case VIDIOCSYNC:
2303 {
2304 int *frame = arg, res;
2305
2306 dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n",
2307 ZR_DEVNAME(zr), *frame);
2308
2309 down(&zr->resource_lock);
2310 res = v4l_sync(file, *frame);
2311 up(&zr->resource_lock);
2312 if (!res)
2313 zr->v4l_sync_tail++;
2314 return res;
2315 }
2316 break;
2317
2318 case VIDIOCMCAPTURE:
2319 {
2320 struct video_mmap *vmap = arg;
2321 int res;
2322
2323 dprintk(3,
2324 KERN_DEBUG
2325 "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n",
2326 ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height,
2327 vmap->format);
2328
2329 down(&zr->resource_lock);
2330 res = v4l_grab(file, vmap);
2331 up(&zr->resource_lock);
2332 return res;
2333 }
2334 break;
2335
2336 case VIDIOCGMBUF:
2337 {
2338 struct video_mbuf *vmbuf = arg;
2339 int i, res = 0;
2340
2341 dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr));
2342
2343 vmbuf->size =
2344 fh->v4l_buffers.num_buffers *
2345 fh->v4l_buffers.buffer_size;
2346 vmbuf->frames = fh->v4l_buffers.num_buffers;
2347 for (i = 0; i < vmbuf->frames; i++) {
2348 vmbuf->offsets[i] =
2349 i * fh->v4l_buffers.buffer_size;
2350 }
2351
2352 down(&zr->resource_lock);
2353
2354 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
2355 dprintk(1,
2356 KERN_ERR
2357 "%s: VIDIOCGMBUF - buffers already allocated\n",
2358 ZR_DEVNAME(zr));
2359 res = -EINVAL;
2360 goto v4l1reqbuf_unlock_and_return;
2361 }
2362
2363 if (v4l_fbuffer_alloc(file)) {
2364 res = -ENOMEM;
2365 goto v4l1reqbuf_unlock_and_return;
2366 }
2367
2368 /* The next mmap will map the V4L buffers */
2369 fh->map_mode = ZORAN_MAP_MODE_RAW;
2370 v4l1reqbuf_unlock_and_return:
2371 up(&zr->resource_lock);
2372
2373 return res;
2374 }
2375 break;
2376
2377 case VIDIOCGUNIT:
2378 {
2379 struct video_unit *vunit = arg;
2380
2381 dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr));
2382
2383 vunit->video = zr->video_dev->minor;
2384 vunit->vbi = VIDEO_NO_UNIT;
2385 vunit->radio = VIDEO_NO_UNIT;
2386 vunit->audio = VIDEO_NO_UNIT;
2387 vunit->teletext = VIDEO_NO_UNIT;
2388
2389 return 0;
2390 }
2391 break;
2392
2393 /*
2394 * RJ: In principal we could support subcaptures for V4L grabbing.
2395 * Not even the famous BTTV driver has them, however.
2396 * If there should be a strong demand, one could consider
2397 * to implement them.
2398 */
2399 case VIDIOCGCAPTURE:
2400 {
2401 dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n",
2402 ZR_DEVNAME(zr));
2403 return -EINVAL;
2404 }
2405 break;
2406
2407 case VIDIOCSCAPTURE:
2408 {
2409 dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n",
2410 ZR_DEVNAME(zr));
2411 return -EINVAL;
2412 }
2413 break;
2414
2415 case BUZIOC_G_PARAMS:
2416 {
2417 struct zoran_params *bparams = arg;
2418
2419 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr));
2420
2421 memset(bparams, 0, sizeof(struct zoran_params));
2422 bparams->major_version = MAJOR_VERSION;
2423 bparams->minor_version = MINOR_VERSION;
2424
2425 down(&zr->resource_lock);
2426
2427 bparams->norm = zr->norm;
2428 bparams->input = zr->input;
2429
2430 bparams->decimation = fh->jpg_settings.decimation;
2431 bparams->HorDcm = fh->jpg_settings.HorDcm;
2432 bparams->VerDcm = fh->jpg_settings.VerDcm;
2433 bparams->TmpDcm = fh->jpg_settings.TmpDcm;
2434 bparams->field_per_buff = fh->jpg_settings.field_per_buff;
2435 bparams->img_x = fh->jpg_settings.img_x;
2436 bparams->img_y = fh->jpg_settings.img_y;
2437 bparams->img_width = fh->jpg_settings.img_width;
2438 bparams->img_height = fh->jpg_settings.img_height;
2439 bparams->odd_even = fh->jpg_settings.odd_even;
2440
2441 bparams->quality = fh->jpg_settings.jpg_comp.quality;
2442 bparams->APPn = fh->jpg_settings.jpg_comp.APPn;
2443 bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len;
2444 memcpy(bparams->APP_data,
2445 fh->jpg_settings.jpg_comp.APP_data,
2446 sizeof(bparams->APP_data));
2447 bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len;
2448 memcpy(bparams->COM_data,
2449 fh->jpg_settings.jpg_comp.COM_data,
2450 sizeof(bparams->COM_data));
2451 bparams->jpeg_markers =
2452 fh->jpg_settings.jpg_comp.jpeg_markers;
2453
2454 up(&zr->resource_lock);
2455
2456 bparams->VFIFO_FB = 0;
2457
2458 return 0;
2459 }
2460 break;
2461
2462 case BUZIOC_S_PARAMS:
2463 {
2464 struct zoran_params *bparams = arg;
2465 int res = 0;
2466
2467 dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
2468
2469 settings.decimation = bparams->decimation;
2470 settings.HorDcm = bparams->HorDcm;
2471 settings.VerDcm = bparams->VerDcm;
2472 settings.TmpDcm = bparams->TmpDcm;
2473 settings.field_per_buff = bparams->field_per_buff;
2474 settings.img_x = bparams->img_x;
2475 settings.img_y = bparams->img_y;
2476 settings.img_width = bparams->img_width;
2477 settings.img_height = bparams->img_height;
2478 settings.odd_even = bparams->odd_even;
2479
2480 settings.jpg_comp.quality = bparams->quality;
2481 settings.jpg_comp.APPn = bparams->APPn;
2482 settings.jpg_comp.APP_len = bparams->APP_len;
2483 memcpy(settings.jpg_comp.APP_data, bparams->APP_data,
2484 sizeof(bparams->APP_data));
2485 settings.jpg_comp.COM_len = bparams->COM_len;
2486 memcpy(settings.jpg_comp.COM_data, bparams->COM_data,
2487 sizeof(bparams->COM_data));
2488 settings.jpg_comp.jpeg_markers = bparams->jpeg_markers;
2489
2490 down(&zr->resource_lock);
2491
2492 if (zr->codec_mode != BUZ_MODE_IDLE) {
2493 dprintk(1,
2494 KERN_ERR
2495 "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n",
2496 ZR_DEVNAME(zr));
2497 res = -EINVAL;
2498 goto sparams_unlock_and_return;
2499 }
2500
2501 /* Check the params first before overwriting our
2502 * nternal values */
2503 if (zoran_check_jpg_settings(zr, &settings)) {
2504 res = -EINVAL;
2505 goto sparams_unlock_and_return;
2506 }
2507
2508 fh->jpg_settings = settings;
2509 sparams_unlock_and_return:
2510 up(&zr->resource_lock);
2511
2512 return res;
2513 }
2514 break;
2515
2516 case BUZIOC_REQBUFS:
2517 {
2518 struct zoran_requestbuffers *breq = arg;
2519 int res = 0;
2520
2521 dprintk(3,
2522 KERN_DEBUG
2523 "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n",
2524 ZR_DEVNAME(zr), breq->count, breq->size);
2525
2526 /* Enforce reasonable lower and upper limits */
2527 if (breq->count < 4)
2528 breq->count = 4; /* Could be choosen smaller */
2529 if (breq->count > jpg_nbufs)
2530 breq->count = jpg_nbufs;
2531 breq->size = PAGE_ALIGN(breq->size);
2532 if (breq->size < 8192)
2533 breq->size = 8192; /* Arbitrary */
2534 /* breq->size is limited by 1 page for the stat_com
2535 * tables to a Maximum of 2 MB */
2536 if (breq->size > jpg_bufsize)
2537 breq->size = jpg_bufsize;
2538 if (fh->jpg_buffers.need_contiguous &&
2539 breq->size > MAX_KMALLOC_MEM)
2540 breq->size = MAX_KMALLOC_MEM;
2541
2542 down(&zr->resource_lock);
2543
2544 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
2545 dprintk(1,
2546 KERN_ERR
2547 "%s: BUZIOC_REQBUFS - buffers allready allocated\n",
2548 ZR_DEVNAME(zr));
2549 res = -EBUSY;
2550 goto jpgreqbuf_unlock_and_return;
2551 }
2552
2553 fh->jpg_buffers.num_buffers = breq->count;
2554 fh->jpg_buffers.buffer_size = breq->size;
2555
2556 if (jpg_fbuffer_alloc(file)) {
2557 res = -ENOMEM;
2558 goto jpgreqbuf_unlock_and_return;
2559 }
2560
2561 /* The next mmap will map the MJPEG buffers - could
2562 * also be *_PLAY, but it doesn't matter here */
2563 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
2564 jpgreqbuf_unlock_and_return:
2565 up(&zr->resource_lock);
2566
2567 return res;
2568 }
2569 break;
2570
2571 case BUZIOC_QBUF_CAPT:
2572 {
2573 int *frame = arg, res;
2574
2575 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n",
2576 ZR_DEVNAME(zr), *frame);
2577
2578 down(&zr->resource_lock);
2579 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
2580 up(&zr->resource_lock);
2581
2582 return res;
2583 }
2584 break;
2585
2586 case BUZIOC_QBUF_PLAY:
2587 {
2588 int *frame = arg, res;
2589
2590 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n",
2591 ZR_DEVNAME(zr), *frame);
2592
2593 down(&zr->resource_lock);
2594 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
2595 up(&zr->resource_lock);
2596
2597 return res;
2598 }
2599 break;
2600
2601 case BUZIOC_SYNC:
2602 {
2603 struct zoran_sync *bsync = arg;
2604 int res;
2605
2606 dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
2607
2608 down(&zr->resource_lock);
2609 res = jpg_sync(file, bsync);
2610 up(&zr->resource_lock);
2611
2612 return res;
2613 }
2614 break;
2615
2616 case BUZIOC_G_STATUS:
2617 {
2618 struct zoran_status *bstat = arg;
2619 int norm, input, status, res = 0;
2620
2621 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
2622
2623 if (zr->codec_mode != BUZ_MODE_IDLE) {
2624 dprintk(1,
2625 KERN_ERR
2626 "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n",
2627 ZR_DEVNAME(zr));
2628 return -EINVAL;
2629 }
2630
2631 input = zr->card.input[bstat->input].muxsel;
2632 norm = VIDEO_MODE_AUTO;
2633
2634 down(&zr->resource_lock);
2635
2636 if (zr->codec_mode != BUZ_MODE_IDLE) {
2637 dprintk(1,
2638 KERN_ERR
2639 "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n",
2640 ZR_DEVNAME(zr));
2641 res = -EINVAL;
2642 goto gstat_unlock_and_return;
2643 }
2644
2645 decoder_command(zr, DECODER_SET_INPUT, &input);
2646 decoder_command(zr, DECODER_SET_NORM, &norm);
2647
2648 /* sleep 1 second */
2649 ssleep(1);
2650
2651 /* Get status of video decoder */
2652 decoder_command(zr, DECODER_GET_STATUS, &status);
2653
2654 /* restore previous input and norm */
2655 input = zr->card.input[zr->input].muxsel;
2656 decoder_command(zr, DECODER_SET_INPUT, &input);
2657 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
2658 gstat_unlock_and_return:
2659 up(&zr->resource_lock);
2660
2661 if (!res) {
2662 bstat->signal =
2663 (status & DECODER_STATUS_GOOD) ? 1 : 0;
2664 if (status & DECODER_STATUS_NTSC)
2665 bstat->norm = VIDEO_MODE_NTSC;
2666 else if (status & DECODER_STATUS_SECAM)
2667 bstat->norm = VIDEO_MODE_SECAM;
2668 else
2669 bstat->norm = VIDEO_MODE_PAL;
2670
2671 bstat->color =
2672 (status & DECODER_STATUS_COLOR) ? 1 : 0;
2673 }
2674
2675 return res;
2676 }
2677 break;
2678
2679#ifdef HAVE_V4L2
2680
2681 /* The new video4linux2 capture interface - much nicer than video4linux1, since
2682 * it allows for integrating the JPEG capturing calls inside standard v4l2
2683 */
2684
2685 case VIDIOC_QUERYCAP:
2686 {
2687 struct v4l2_capability *cap = arg;
2688
2689 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
2690
2691 memset(cap, 0, sizeof(*cap));
2692 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
2693 strncpy(cap->driver, "zoran", sizeof(cap->driver));
2694 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2695 pci_name(zr->pci_dev));
2696 cap->version =
2697 KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
2698 RELEASE_VERSION);
2699 cap->capabilities = ZORAN_V4L2_VID_FLAGS;
2700
2701 return 0;
2702 }
2703 break;
2704
2705 case VIDIOC_ENUM_FMT:
2706 {
2707 struct v4l2_fmtdesc *fmt = arg;
2708 int index = fmt->index, num = -1, i, flag = 0, type =
2709 fmt->type;
2710
2711 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n",
2712 ZR_DEVNAME(zr), fmt->index);
2713
2714 switch (fmt->type) {
2715 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2716 flag = ZORAN_FORMAT_CAPTURE;
2717 break;
2718 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2719 flag = ZORAN_FORMAT_PLAYBACK;
2720 break;
2721 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2722 flag = ZORAN_FORMAT_OVERLAY;
2723 break;
2724 default:
2725 dprintk(1,
2726 KERN_ERR
2727 "%s: VIDIOC_ENUM_FMT - unknown type %d\n",
2728 ZR_DEVNAME(zr), fmt->type);
2729 return -EINVAL;
2730 }
2731
2732 for (i = 0; i < zoran_num_formats; i++) {
2733 if (zoran_formats[i].flags & flag)
2734 num++;
2735 if (num == fmt->index)
2736 break;
2737 }
2738 if (fmt->index < 0 /* late, but not too late */ ||
2739 i == zoran_num_formats)
2740 return -EINVAL;
2741
2742 memset(fmt, 0, sizeof(*fmt));
2743 fmt->index = index;
2744 fmt->type = type;
2745 strncpy(fmt->description, zoran_formats[i].name, 31);
2746 fmt->pixelformat = zoran_formats[i].fourcc;
2747 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2748 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
2749
2750 return 0;
2751 }
2752 break;
2753
2754 case VIDIOC_G_FMT:
2755 {
2756 struct v4l2_format *fmt = arg;
2757 int type = fmt->type;
2758
2759 dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr));
2760
2761 memset(fmt, 0, sizeof(*fmt));
2762 fmt->type = type;
2763
2764 switch (fmt->type) {
2765 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2766
2767 down(&zr->resource_lock);
2768
2769 fmt->fmt.win.w.left = fh->overlay_settings.x;
2770 fmt->fmt.win.w.top = fh->overlay_settings.y;
2771 fmt->fmt.win.w.width = fh->overlay_settings.width;
2772 fmt->fmt.win.w.height =
2773 fh->overlay_settings.height;
2774 if (fh->overlay_settings.width * 2 >
2775 BUZ_MAX_HEIGHT)
2776 fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
2777 else
2778 fmt->fmt.win.field = V4L2_FIELD_TOP;
2779
2780 up(&zr->resource_lock);
2781
2782 break;
2783
2784 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2785 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2786
2787 down(&zr->resource_lock);
2788
2789 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2790 fh->map_mode == ZORAN_MAP_MODE_RAW) {
2791
2792 fmt->fmt.pix.width =
2793 fh->v4l_settings.width;
2794 fmt->fmt.pix.height =
2795 fh->v4l_settings.height;
2796 fmt->fmt.pix.sizeimage =
2797 fh->v4l_buffers.buffer_size;
2798 fmt->fmt.pix.pixelformat =
2799 fh->v4l_settings.format->fourcc;
2800 fmt->fmt.pix.colorspace =
2801 fh->v4l_settings.format->colorspace;
2802 fmt->fmt.pix.bytesperline = 0;
2803 if (BUZ_MAX_HEIGHT <
2804 (fh->v4l_settings.height * 2))
2805 fmt->fmt.pix.field =
2806 V4L2_FIELD_INTERLACED;
2807 else
2808 fmt->fmt.pix.field =
2809 V4L2_FIELD_TOP;
2810
2811 } else {
2812
2813 fmt->fmt.pix.width =
2814 fh->jpg_settings.img_width /
2815 fh->jpg_settings.HorDcm;
2816 fmt->fmt.pix.height =
2817 fh->jpg_settings.img_height /
2818 (fh->jpg_settings.VerDcm *
2819 fh->jpg_settings.TmpDcm);
2820 fmt->fmt.pix.sizeimage =
2821 zoran_v4l2_calc_bufsize(&fh->
2822 jpg_settings);
2823 fmt->fmt.pix.pixelformat =
2824 V4L2_PIX_FMT_MJPEG;
2825 if (fh->jpg_settings.TmpDcm == 1)
2826 fmt->fmt.pix.field =
2827 (fh->jpg_settings.
2828 odd_even ? V4L2_FIELD_SEQ_BT :
2829 V4L2_FIELD_SEQ_BT);
2830 else
2831 fmt->fmt.pix.field =
2832 (fh->jpg_settings.
2833 odd_even ? V4L2_FIELD_TOP :
2834 V4L2_FIELD_BOTTOM);
2835
2836 fmt->fmt.pix.bytesperline = 0;
2837 fmt->fmt.pix.colorspace =
2838 V4L2_COLORSPACE_SMPTE170M;
2839 }
2840
2841 up(&zr->resource_lock);
2842
2843 break;
2844
2845 default:
2846 dprintk(1,
2847 KERN_ERR
2848 "%s: VIDIOC_G_FMT - unsupported type %d\n",
2849 ZR_DEVNAME(zr), fmt->type);
2850 return -EINVAL;
2851 }
2852 return 0;
2853 }
2854 break;
2855
2856 case VIDIOC_S_FMT:
2857 {
2858 struct v4l2_format *fmt = arg;
2859 int i, res = 0;
2860 __u32 printformat;
2861
2862 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
2863 ZR_DEVNAME(zr), fmt->type);
2864
2865 switch (fmt->type) {
2866 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2867
2868 dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
2869 fmt->fmt.win.w.left, fmt->fmt.win.w.top,
2870 fmt->fmt.win.w.width,
2871 fmt->fmt.win.w.height,
2872 fmt->fmt.win.clipcount,
2873 fmt->fmt.win.bitmap);
2874 down(&zr->resource_lock);
2875 res =
2876 setup_window(file, fmt->fmt.win.w.left,
2877 fmt->fmt.win.w.top,
2878 fmt->fmt.win.w.width,
2879 fmt->fmt.win.w.height,
2880 (struct video_clip __user *)
2881 fmt->fmt.win.clips,
2882 fmt->fmt.win.clipcount,
2883 fmt->fmt.win.bitmap);
2884 up(&zr->resource_lock);
2885 return res;
2886 break;
2887
2888 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2889 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2890
2891 printformat =
2892 __cpu_to_le32(fmt->fmt.pix.pixelformat);
2893 dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
2894 fmt->fmt.pix.width, fmt->fmt.pix.height,
2895 fmt->fmt.pix.pixelformat,
2896 (char *) &printformat);
2897
2898 if (fmt->fmt.pix.bytesperline > 0) {
2899 dprintk(5,
2900 KERN_ERR "%s: bpl not supported\n",
2901 ZR_DEVNAME(zr));
2902 return -EINVAL;
2903 }
2904
2905 /* we can be requested to do JPEG/raw playback/capture */
2906 if (!
2907 (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2908 (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
2909 fmt->fmt.pix.pixelformat ==
2910 V4L2_PIX_FMT_MJPEG))) {
2911 dprintk(1,
2912 KERN_ERR
2913 "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
2914 ZR_DEVNAME(zr), fmt->type,
2915 fmt->fmt.pix.pixelformat,
2916 (char *) &printformat);
2917 return -EINVAL;
2918 }
2919
2920 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
2921 down(&zr->resource_lock);
2922
2923 settings = fh->jpg_settings;
2924
2925 if (fh->v4l_buffers.allocated ||
2926 fh->jpg_buffers.allocated) {
2927 dprintk(1,
2928 KERN_ERR
2929 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2930 ZR_DEVNAME(zr));
2931 res = -EBUSY;
2932 goto sfmtjpg_unlock_and_return;
2933 }
2934
2935 /* we actually need to set 'real' parameters now */
2936 if ((fmt->fmt.pix.height * 2) >
2937 BUZ_MAX_HEIGHT)
2938 settings.TmpDcm = 1;
2939 else
2940 settings.TmpDcm = 2;
2941 settings.decimation = 0;
2942 if (fmt->fmt.pix.height <=
2943 fh->jpg_settings.img_height / 2)
2944 settings.VerDcm = 2;
2945 else
2946 settings.VerDcm = 1;
2947 if (fmt->fmt.pix.width <=
2948 fh->jpg_settings.img_width / 4)
2949 settings.HorDcm = 4;
2950 else if (fmt->fmt.pix.width <=
2951 fh->jpg_settings.img_width / 2)
2952 settings.HorDcm = 2;
2953 else
2954 settings.HorDcm = 1;
2955 if (settings.TmpDcm == 1)
2956 settings.field_per_buff = 2;
2957 else
2958 settings.field_per_buff = 1;
2959
2960 /* check */
2961 if ((res =
2962 zoran_check_jpg_settings(zr,
2963 &settings)))
2964 goto sfmtjpg_unlock_and_return;
2965
2966 /* it's ok, so set them */
2967 fh->jpg_settings = settings;
2968
2969 /* tell the user what we actually did */
2970 fmt->fmt.pix.width =
2971 settings.img_width / settings.HorDcm;
2972 fmt->fmt.pix.height =
2973 settings.img_height * 2 /
2974 (settings.TmpDcm * settings.VerDcm);
2975 if (settings.TmpDcm == 1)
2976 fmt->fmt.pix.field =
2977 (fh->jpg_settings.
2978 odd_even ? V4L2_FIELD_SEQ_TB :
2979 V4L2_FIELD_SEQ_BT);
2980 else
2981 fmt->fmt.pix.field =
2982 (fh->jpg_settings.
2983 odd_even ? V4L2_FIELD_TOP :
2984 V4L2_FIELD_BOTTOM);
2985 fh->jpg_buffers.buffer_size =
2986 zoran_v4l2_calc_bufsize(&fh->
2987 jpg_settings);
2988 fmt->fmt.pix.sizeimage =
2989 fh->jpg_buffers.buffer_size;
2990
2991 /* we hereby abuse this variable to show that
2992 * we're gonna do mjpeg capture */
2993 fh->map_mode =
2994 (fmt->type ==
2995 V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
2996 ZORAN_MAP_MODE_JPG_REC :
2997 ZORAN_MAP_MODE_JPG_PLAY;
2998 sfmtjpg_unlock_and_return:
2999 up(&zr->resource_lock);
3000 } else {
3001 for (i = 0; i < zoran_num_formats; i++)
3002 if (fmt->fmt.pix.pixelformat ==
3003 zoran_formats[i].fourcc)
3004 break;
3005 if (i == zoran_num_formats) {
3006 dprintk(1,
3007 KERN_ERR
3008 "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
3009 ZR_DEVNAME(zr),
3010 fmt->fmt.pix.pixelformat,
3011 (char *) &printformat);
3012 return -EINVAL;
3013 }
3014 down(&zr->resource_lock);
3015 if (fh->jpg_buffers.allocated ||
3016 (fh->v4l_buffers.allocated &&
3017 fh->v4l_buffers.active !=
3018 ZORAN_FREE)) {
3019 dprintk(1,
3020 KERN_ERR
3021 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
3022 ZR_DEVNAME(zr));
3023 res = -EBUSY;
3024 goto sfmtv4l_unlock_and_return;
3025 }
3026 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
3027 fmt->fmt.pix.height =
3028 BUZ_MAX_HEIGHT;
3029 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
3030 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
3031
3032 if ((res =
3033 zoran_v4l_set_format(file,
3034 fmt->fmt.pix.
3035 width,
3036 fmt->fmt.pix.
3037 height,
3038 &zoran_formats
3039 [i])))
3040 goto sfmtv4l_unlock_and_return;
3041
3042 /* tell the user the
3043 * results/missing stuff */
3044 fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size /*zr->gbpl * zr->gheight */
3045 ;
3046 if (BUZ_MAX_HEIGHT <
3047 (fh->v4l_settings.height * 2))
3048 fmt->fmt.pix.field =
3049 V4L2_FIELD_INTERLACED;
3050 else
3051 fmt->fmt.pix.field =
3052 V4L2_FIELD_TOP;
3053
3054 fh->map_mode = ZORAN_MAP_MODE_RAW;
3055 sfmtv4l_unlock_and_return:
3056 up(&zr->resource_lock);
3057 }
3058
3059 break;
3060
3061 default:
3062 dprintk(3, "unsupported\n");
3063 dprintk(1,
3064 KERN_ERR
3065 "%s: VIDIOC_S_FMT - unsupported type %d\n",
3066 ZR_DEVNAME(zr), fmt->type);
3067 return -EINVAL;
3068 }
3069
3070 return res;
3071 }
3072 break;
3073
3074 case VIDIOC_G_FBUF:
3075 {
3076 struct v4l2_framebuffer *fb = arg;
3077
3078 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr));
3079
3080 memset(fb, 0, sizeof(*fb));
3081 down(&zr->resource_lock);
3082 fb->base = zr->buffer.base;
3083 fb->fmt.width = zr->buffer.width;
3084 fb->fmt.height = zr->buffer.height;
3085 if (zr->overlay_settings.format) {
3086 fb->fmt.pixelformat =
3087 fh->overlay_settings.format->fourcc;
3088 }
3089 fb->fmt.bytesperline = zr->buffer.bytesperline;
3090 up(&zr->resource_lock);
3091 fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
3092 fb->fmt.field = V4L2_FIELD_INTERLACED;
3093 fb->flags = V4L2_FBUF_FLAG_OVERLAY;
3094 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
3095
3096 return 0;
3097 }
3098 break;
3099
3100 case VIDIOC_S_FBUF:
3101 {
3102 int i, res = 0;
3103 struct v4l2_framebuffer *fb = arg;
3104 __u32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
3105
3106 dprintk(3,
3107 KERN_DEBUG
3108 "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n",
3109 ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height,
3110 fb->fmt.bytesperline, fb->fmt.pixelformat,
3111 (char *) &printformat);
3112
3113 for (i = 0; i < zoran_num_formats; i++)
3114 if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
3115 break;
3116 if (i == zoran_num_formats) {
3117 dprintk(1,
3118 KERN_ERR
3119 "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
3120 ZR_DEVNAME(zr), fb->fmt.pixelformat,
3121 (char *) &printformat);
3122 return -EINVAL;
3123 }
3124
3125 down(&zr->resource_lock);
3126 res =
3127 setup_fbuffer(file, fb->base, &zoran_formats[i],
3128 fb->fmt.width, fb->fmt.height,
3129 fb->fmt.bytesperline);
3130 up(&zr->resource_lock);
3131
3132 return res;
3133 }
3134 break;
3135
3136 case VIDIOC_OVERLAY:
3137 {
3138 int *on = arg, res;
3139
3140 dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n",
3141 ZR_DEVNAME(zr), *on);
3142
3143 down(&zr->resource_lock);
3144 res = setup_overlay(file, *on);
3145 up(&zr->resource_lock);
3146
3147 return res;
3148 }
3149 break;
3150
3151 case VIDIOC_REQBUFS:
3152 {
3153 struct v4l2_requestbuffers *req = arg;
3154 int res = 0;
3155
3156 dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
3157 ZR_DEVNAME(zr), req->type);
3158
3159 if (req->memory != V4L2_MEMORY_MMAP) {
3160 dprintk(1,
3161 KERN_ERR
3162 "%s: only MEMORY_MMAP capture is supported, not %d\n",
3163 ZR_DEVNAME(zr), req->memory);
3164 return -EINVAL;
3165 }
3166
3167 down(&zr->resource_lock);
3168
3169 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
3170 dprintk(1,
3171 KERN_ERR
3172 "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
3173 ZR_DEVNAME(zr));
3174 res = -EBUSY;
3175 goto v4l2reqbuf_unlock_and_return;
3176 }
3177
3178 if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
3179 req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3180
3181 /* control user input */
3182 if (req->count < 2)
3183 req->count = 2;
3184 if (req->count > v4l_nbufs)
3185 req->count = v4l_nbufs;
3186 fh->v4l_buffers.num_buffers = req->count;
3187
3188 if (v4l_fbuffer_alloc(file)) {
3189 res = -ENOMEM;
3190 goto v4l2reqbuf_unlock_and_return;
3191 }
3192
3193 /* The next mmap will map the V4L buffers */
3194 fh->map_mode = ZORAN_MAP_MODE_RAW;
3195
3196 } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
3197 fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3198
3199 /* we need to calculate size ourselves now */
3200 if (req->count < 4)
3201 req->count = 4;
3202 if (req->count > jpg_nbufs)
3203 req->count = jpg_nbufs;
3204 fh->jpg_buffers.num_buffers = req->count;
3205 fh->jpg_buffers.buffer_size =
3206 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3207
3208 if (jpg_fbuffer_alloc(file)) {
3209 res = -ENOMEM;
3210 goto v4l2reqbuf_unlock_and_return;
3211 }
3212
3213 /* The next mmap will map the MJPEG buffers */
3214 if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
3215 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
3216 else
3217 fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
3218
3219 } else {
3220 dprintk(1,
3221 KERN_ERR
3222 "%s: VIDIOC_REQBUFS - unknown type %d\n",
3223 ZR_DEVNAME(zr), req->type);
3224 res = -EINVAL;
3225 goto v4l2reqbuf_unlock_and_return;
3226 }
3227 v4l2reqbuf_unlock_and_return:
3228 up(&zr->resource_lock);
3229
3230 return 0;
3231 }
3232 break;
3233
3234 case VIDIOC_QUERYBUF:
3235 {
3236 struct v4l2_buffer *buf = arg;
3237 __u32 type = buf->type;
3238 int index = buf->index, res;
3239
3240 dprintk(3,
3241 KERN_DEBUG
3242 "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
3243 ZR_DEVNAME(zr), buf->index, buf->type);
3244
3245 memset(buf, 0, sizeof(buf));
3246 buf->type = type;
3247 buf->index = index;
3248
3249 down(&zr->resource_lock);
3250 res = zoran_v4l2_buffer_status(file, buf, buf->index);
3251 up(&zr->resource_lock);
3252
3253 return res;
3254 }
3255 break;
3256
3257 case VIDIOC_QBUF:
3258 {
3259 struct v4l2_buffer *buf = arg;
3260 int res = 0, codec_mode, buf_type;
3261
3262 dprintk(3,
3263 KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n",
3264 ZR_DEVNAME(zr), buf->type, buf->index);
3265
3266 down(&zr->resource_lock);
3267
3268 switch (fh->map_mode) {
3269 case ZORAN_MAP_MODE_RAW:
3270 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3271 dprintk(1,
3272 KERN_ERR
3273 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3274 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3275 res = -EINVAL;
3276 goto qbuf_unlock_and_return;
3277 }
3278
3279 res = zoran_v4l_queue_frame(file, buf->index);
3280 if (res)
3281 goto qbuf_unlock_and_return;
3282 if (!zr->v4l_memgrab_active &&
3283 fh->v4l_buffers.active == ZORAN_LOCKED)
3284 zr36057_set_memgrab(zr, 1);
3285 break;
3286
3287 case ZORAN_MAP_MODE_JPG_REC:
3288 case ZORAN_MAP_MODE_JPG_PLAY:
3289 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3290 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3291 codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
3292 } else {
3293 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3294 codec_mode = BUZ_MODE_MOTION_COMPRESS;
3295 }
3296
3297 if (buf->type != buf_type) {
3298 dprintk(1,
3299 KERN_ERR
3300 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3301 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3302 res = -EINVAL;
3303 goto qbuf_unlock_and_return;
3304 }
3305
3306 res =
3307 zoran_jpg_queue_frame(file, buf->index,
3308 codec_mode);
3309 if (res != 0)
3310 goto qbuf_unlock_and_return;
3311 if (zr->codec_mode == BUZ_MODE_IDLE &&
3312 fh->jpg_buffers.active == ZORAN_LOCKED) {
3313 zr36057_enable_jpg(zr, codec_mode);
3314 }
3315 break;
3316
3317 default:
3318 dprintk(1,
3319 KERN_ERR
3320 "%s: VIDIOC_QBUF - unsupported type %d\n",
3321 ZR_DEVNAME(zr), buf->type);
3322 res = -EINVAL;
3323 goto qbuf_unlock_and_return;
3324 }
3325 qbuf_unlock_and_return:
3326 up(&zr->resource_lock);
3327
3328 return res;
3329 }
3330 break;
3331
3332 case VIDIOC_DQBUF:
3333 {
3334 struct v4l2_buffer *buf = arg;
3335 int res = 0, buf_type, num = -1; /* compiler borks here (?) */
3336
3337 dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
3338 ZR_DEVNAME(zr), buf->type);
3339
3340 down(&zr->resource_lock);
3341
3342 switch (fh->map_mode) {
3343 case ZORAN_MAP_MODE_RAW:
3344 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3345 dprintk(1,
3346 KERN_ERR
3347 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3348 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3349 res = -EINVAL;
3350 goto dqbuf_unlock_and_return;
3351 }
3352
3353 num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
3354 if (file->f_flags & O_NONBLOCK &&
3355 zr->v4l_buffers.buffer[num].state !=
3356 BUZ_STATE_DONE) {
3357 res = -EAGAIN;
3358 goto dqbuf_unlock_and_return;
3359 }
3360 res = v4l_sync(file, num);
3361 if (res)
3362 goto dqbuf_unlock_and_return;
3363 else
3364 zr->v4l_sync_tail++;
3365 res = zoran_v4l2_buffer_status(file, buf, num);
3366 break;
3367
3368 case ZORAN_MAP_MODE_JPG_REC:
3369 case ZORAN_MAP_MODE_JPG_PLAY:
3370 {
3371 struct zoran_sync bs;
3372
3373 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
3374 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3375 else
3376 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3377
3378 if (buf->type != buf_type) {
3379 dprintk(1,
3380 KERN_ERR
3381 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3382 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3383 res = -EINVAL;
3384 goto dqbuf_unlock_and_return;
3385 }
3386
3387 num =
3388 zr->jpg_pend[zr->
3389 jpg_que_tail & BUZ_MASK_FRAME];
3390
3391 if (file->f_flags & O_NONBLOCK &&
3392 zr->jpg_buffers.buffer[num].state !=
3393 BUZ_STATE_DONE) {
3394 res = -EAGAIN;
3395 goto dqbuf_unlock_and_return;
3396 }
3397 res = jpg_sync(file, &bs);
3398 if (res)
3399 goto dqbuf_unlock_and_return;
3400 res =
3401 zoran_v4l2_buffer_status(file, buf, bs.frame);
3402 break;
3403 }
3404
3405 default:
3406 dprintk(1,
3407 KERN_ERR
3408 "%s: VIDIOC_DQBUF - unsupported type %d\n",
3409 ZR_DEVNAME(zr), buf->type);
3410 res = -EINVAL;
3411 goto dqbuf_unlock_and_return;
3412 }
3413 dqbuf_unlock_and_return:
3414 up(&zr->resource_lock);
3415
3416 return res;
3417 }
3418 break;
3419
3420 case VIDIOC_STREAMON:
3421 {
3422 int res = 0;
3423
3424 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
3425
3426 down(&zr->resource_lock);
3427
3428 switch (fh->map_mode) {
3429 case ZORAN_MAP_MODE_RAW: /* raw capture */
3430 if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
3431 fh->v4l_buffers.active != ZORAN_ACTIVE) {
3432 res = -EBUSY;
3433 goto strmon_unlock_and_return;
3434 }
3435
3436 zr->v4l_buffers.active = fh->v4l_buffers.active =
3437 ZORAN_LOCKED;
3438 zr->v4l_settings = fh->v4l_settings;
3439
3440 zr->v4l_sync_tail = zr->v4l_pend_tail;
3441 if (!zr->v4l_memgrab_active &&
3442 zr->v4l_pend_head != zr->v4l_pend_tail) {
3443 zr36057_set_memgrab(zr, 1);
3444 }
3445 break;
3446
3447 case ZORAN_MAP_MODE_JPG_REC:
3448 case ZORAN_MAP_MODE_JPG_PLAY:
3449 /* what is the codec mode right now? */
3450 if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
3451 fh->jpg_buffers.active != ZORAN_ACTIVE) {
3452 res = -EBUSY;
3453 goto strmon_unlock_and_return;
3454 }
3455
3456 zr->jpg_buffers.active = fh->jpg_buffers.active =
3457 ZORAN_LOCKED;
3458
3459 if (zr->jpg_que_head != zr->jpg_que_tail) {
3460 /* Start the jpeg codec when the first frame is queued */
3461 jpeg_start(zr);
3462 }
3463
3464 break;
3465 default:
3466 dprintk(1,
3467 KERN_ERR
3468 "%s: VIDIOC_STREAMON - invalid map mode %d\n",
3469 ZR_DEVNAME(zr), fh->map_mode);
3470 res = -EINVAL;
3471 goto strmon_unlock_and_return;
3472 }
3473 strmon_unlock_and_return:
3474 up(&zr->resource_lock);
3475
3476 return res;
3477 }
3478 break;
3479
3480 case VIDIOC_STREAMOFF:
3481 {
3482 int i, res = 0;
3483
3484 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
3485
3486 down(&zr->resource_lock);
3487
3488 switch (fh->map_mode) {
3489 case ZORAN_MAP_MODE_RAW: /* raw capture */
3490 if (fh->v4l_buffers.active == ZORAN_FREE &&
3491 zr->v4l_buffers.active != ZORAN_FREE) {
3492 res = -EPERM; /* stay off other's settings! */
3493 goto strmoff_unlock_and_return;
3494 }
3495 if (zr->v4l_buffers.active == ZORAN_FREE)
3496 goto strmoff_unlock_and_return;
3497
3498 /* unload capture */
3499 if (zr->v4l_memgrab_active)
3500 zr36057_set_memgrab(zr, 0);
3501
3502 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
3503 zr->v4l_buffers.buffer[i].state =
3504 BUZ_STATE_USER;
3505 fh->v4l_buffers = zr->v4l_buffers;
3506
3507 zr->v4l_buffers.active = fh->v4l_buffers.active =
3508 ZORAN_FREE;
3509
3510 zr->v4l_grab_seq = 0;
3511 zr->v4l_pend_head = zr->v4l_pend_tail = 0;
3512 zr->v4l_sync_tail = 0;
3513
3514 break;
3515
3516 case ZORAN_MAP_MODE_JPG_REC:
3517 case ZORAN_MAP_MODE_JPG_PLAY:
3518 if (fh->jpg_buffers.active == ZORAN_FREE &&
3519 zr->jpg_buffers.active != ZORAN_FREE) {
3520 res = -EPERM; /* stay off other's settings! */
3521 goto strmoff_unlock_and_return;
3522 }
3523 if (zr->jpg_buffers.active == ZORAN_FREE)
3524 goto strmoff_unlock_and_return;
3525
3526 res =
3527 jpg_qbuf(file, -1,
3528 (fh->map_mode ==
3529 ZORAN_MAP_MODE_JPG_REC) ?
3530 BUZ_MODE_MOTION_COMPRESS :
3531 BUZ_MODE_MOTION_DECOMPRESS);
3532 if (res)
3533 goto strmoff_unlock_and_return;
3534 break;
3535 default:
3536 dprintk(1,
3537 KERN_ERR
3538 "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
3539 ZR_DEVNAME(zr), fh->map_mode);
3540 res = -EINVAL;
3541 goto strmoff_unlock_and_return;
3542 }
3543 strmoff_unlock_and_return:
3544 up(&zr->resource_lock);
3545
3546 return res;
3547 }
3548 break;
3549
3550 case VIDIOC_QUERYCTRL:
3551 {
3552 struct v4l2_queryctrl *ctrl = arg;
3553
3554 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n",
3555 ZR_DEVNAME(zr), ctrl->id);
3556
3557 /* we only support hue/saturation/contrast/brightness */
3558 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3559 ctrl->id > V4L2_CID_HUE)
3560 return -EINVAL;
3561 else {
3562 int id = ctrl->id;
3563 memset(ctrl, 0, sizeof(*ctrl));
3564 ctrl->id = id;
3565 }
3566
3567 switch (ctrl->id) {
3568 case V4L2_CID_BRIGHTNESS:
3569 strncpy(ctrl->name, "Brightness", 31);
3570 break;
3571 case V4L2_CID_CONTRAST:
3572 strncpy(ctrl->name, "Contrast", 31);
3573 break;
3574 case V4L2_CID_SATURATION:
3575 strncpy(ctrl->name, "Saturation", 31);
3576 break;
3577 case V4L2_CID_HUE:
3578 strncpy(ctrl->name, "Hue", 31);
3579 break;
3580 }
3581
3582 ctrl->minimum = 0;
3583 ctrl->maximum = 65535;
3584 ctrl->step = 1;
3585 ctrl->default_value = 32768;
3586 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
3587
3588 return 0;
3589 }
3590 break;
3591
3592 case VIDIOC_G_CTRL:
3593 {
3594 struct v4l2_control *ctrl = arg;
3595
3596 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
3597 ZR_DEVNAME(zr), ctrl->id);
3598
3599 /* we only support hue/saturation/contrast/brightness */
3600 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3601 ctrl->id > V4L2_CID_HUE)
3602 return -EINVAL;
3603
3604 down(&zr->resource_lock);
3605 switch (ctrl->id) {
3606 case V4L2_CID_BRIGHTNESS:
3607 ctrl->value = zr->brightness;
3608 break;
3609 case V4L2_CID_CONTRAST:
3610 ctrl->value = zr->contrast;
3611 break;
3612 case V4L2_CID_SATURATION:
3613 ctrl->value = zr->saturation;
3614 break;
3615 case V4L2_CID_HUE:
3616 ctrl->value = zr->hue;
3617 break;
3618 }
3619 up(&zr->resource_lock);
3620
3621 return 0;
3622 }
3623 break;
3624
3625 case VIDIOC_S_CTRL:
3626 {
3627 struct v4l2_control *ctrl = arg;
3628 struct video_picture pict;
3629
3630 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n",
3631 ZR_DEVNAME(zr), ctrl->id);
3632
3633 /* we only support hue/saturation/contrast/brightness */
3634 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3635 ctrl->id > V4L2_CID_HUE)
3636 return -EINVAL;
3637
3638 if (ctrl->value < 0 || ctrl->value > 65535) {
3639 dprintk(1,
3640 KERN_ERR
3641 "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
3642 ZR_DEVNAME(zr), ctrl->value, ctrl->id);
3643 return -EINVAL;
3644 }
3645
3646 down(&zr->resource_lock);
3647 switch (ctrl->id) {
3648 case V4L2_CID_BRIGHTNESS:
3649 zr->brightness = ctrl->value;
3650 break;
3651 case V4L2_CID_CONTRAST:
3652 zr->contrast = ctrl->value;
3653 break;
3654 case V4L2_CID_SATURATION:
3655 zr->saturation = ctrl->value;
3656 break;
3657 case V4L2_CID_HUE:
3658 zr->hue = ctrl->value;
3659 break;
3660 }
3661 pict.brightness = zr->brightness;
3662 pict.contrast = zr->contrast;
3663 pict.colour = zr->saturation;
3664 pict.hue = zr->hue;
3665
3666 decoder_command(zr, DECODER_SET_PICTURE, &pict);
3667
3668 up(&zr->resource_lock);
3669
3670 return 0;
3671 }
3672 break;
3673
3674 case VIDIOC_ENUMSTD:
3675 {
3676 struct v4l2_standard *std = arg;
3677
3678 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n",
3679 ZR_DEVNAME(zr), std->index);
3680
3681 if (std->index < 0 || std->index >= (zr->card.norms + 1))
3682 return -EINVAL;
3683 else {
3684 int id = std->index;
3685 memset(std, 0, sizeof(*std));
3686 std->index = id;
3687 }
3688
3689 if (std->index == zr->card.norms) {
3690 /* if we have autodetect, ... */
3691 struct video_decoder_capability caps;
3692 decoder_command(zr, DECODER_GET_CAPABILITIES,
3693 &caps);
3694 if (caps.flags & VIDEO_DECODER_AUTO) {
3695 std->id = V4L2_STD_ALL;
3696 strncpy(std->name, "Autodetect", 31);
3697 return 0;
3698 } else
3699 return -EINVAL;
3700 }
3701 switch (std->index) {
3702 case 0:
3703 std->id = V4L2_STD_PAL;
3704 strncpy(std->name, "PAL", 31);
3705 std->frameperiod.numerator = 1;
3706 std->frameperiod.denominator = 25;
3707 std->framelines = zr->card.tvn[0]->Ht;
3708 break;
3709 case 1:
3710 std->id = V4L2_STD_NTSC;
3711 strncpy(std->name, "NTSC", 31);
3712 std->frameperiod.numerator = 1001;
3713 std->frameperiod.denominator = 30000;
3714 std->framelines = zr->card.tvn[1]->Ht;
3715 break;
3716 case 2:
3717 std->id = V4L2_STD_SECAM;
3718 strncpy(std->name, "SECAM", 31);
3719 std->frameperiod.numerator = 1;
3720 std->frameperiod.denominator = 25;
3721 std->framelines = zr->card.tvn[2]->Ht;
3722 break;
3723 }
3724
3725 return 0;
3726 }
3727 break;
3728
3729 case VIDIOC_G_STD:
3730 {
3731 v4l2_std_id *std = arg;
3732 int norm;
3733
3734 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr));
3735
3736 down(&zr->resource_lock);
3737 norm = zr->norm;
3738 up(&zr->resource_lock);
3739
3740 switch (norm) {
3741 case VIDEO_MODE_PAL:
3742 *std = V4L2_STD_PAL;
3743 break;
3744 case VIDEO_MODE_NTSC:
3745 *std = V4L2_STD_NTSC;
3746 break;
3747 case VIDEO_MODE_SECAM:
3748 *std = V4L2_STD_SECAM;
3749 break;
3750 }
3751
3752 return 0;
3753 }
3754 break;
3755
3756 case VIDIOC_S_STD:
3757 {
3758 int norm = -1, res = 0;
3759 v4l2_std_id *std = arg;
3760
3761 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
3762 ZR_DEVNAME(zr), (unsigned long long)*std);
3763
3764 if (*std == V4L2_STD_PAL)
3765 norm = VIDEO_MODE_PAL;
3766 else if (*std == V4L2_STD_NTSC)
3767 norm = VIDEO_MODE_NTSC;
3768 else if (*std == V4L2_STD_SECAM)
3769 norm = VIDEO_MODE_SECAM;
3770 else if (*std == V4L2_STD_ALL)
3771 norm = VIDEO_MODE_AUTO;
3772 else {
3773 dprintk(1,
3774 KERN_ERR
3775 "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
3776 ZR_DEVNAME(zr), (unsigned long long)*std);
3777 return -EINVAL;
3778 }
3779
3780 down(&zr->resource_lock);
3781 if ((res = zoran_set_norm(zr, norm)))
3782 goto sstd_unlock_and_return;
3783
3784 res = wait_grab_pending(zr);
3785 sstd_unlock_and_return:
3786 up(&zr->resource_lock);
3787 return res;
3788 }
3789 break;
3790
3791 case VIDIOC_ENUMINPUT:
3792 {
3793 struct v4l2_input *inp = arg;
3794 int status;
3795
3796 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n",
3797 ZR_DEVNAME(zr), inp->index);
3798
3799 if (inp->index < 0 || inp->index >= zr->card.inputs)
3800 return -EINVAL;
3801 else {
3802 int id = inp->index;
3803 memset(inp, 0, sizeof(*inp));
3804 inp->index = id;
3805 }
3806
3807 strncpy(inp->name, zr->card.input[inp->index].name,
3808 sizeof(inp->name) - 1);
3809 inp->type = V4L2_INPUT_TYPE_CAMERA;
3810 inp->std = V4L2_STD_ALL;
3811
3812 /* Get status of video decoder */
3813 down(&zr->resource_lock);
3814 decoder_command(zr, DECODER_GET_STATUS, &status);
3815 up(&zr->resource_lock);
3816
3817 if (!(status & DECODER_STATUS_GOOD)) {
3818 inp->status |= V4L2_IN_ST_NO_POWER;
3819 inp->status |= V4L2_IN_ST_NO_SIGNAL;
3820 }
3821 if (!(status & DECODER_STATUS_COLOR))
3822 inp->status |= V4L2_IN_ST_NO_COLOR;
3823
3824 return 0;
3825 }
3826 break;
3827
3828 case VIDIOC_G_INPUT:
3829 {
3830 int *input = arg;
3831
3832 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr));
3833
3834 down(&zr->resource_lock);
3835 *input = zr->input;
3836 up(&zr->resource_lock);
3837
3838 return 0;
3839 }
3840 break;
3841
3842 case VIDIOC_S_INPUT:
3843 {
3844 int *input = arg, res = 0;
3845
3846 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n",
3847 ZR_DEVNAME(zr), *input);
3848
3849 down(&zr->resource_lock);
3850 if ((res = zoran_set_input(zr, *input)))
3851 goto sinput_unlock_and_return;
3852
3853 /* Make sure the changes come into effect */
3854 res = wait_grab_pending(zr);
3855 sinput_unlock_and_return:
3856 up(&zr->resource_lock);
3857 return res;
3858 }
3859 break;
3860
3861 case VIDIOC_ENUMOUTPUT:
3862 {
3863 struct v4l2_output *outp = arg;
3864
3865 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n",
3866 ZR_DEVNAME(zr), outp->index);
3867
3868 if (outp->index != 0)
3869 return -EINVAL;
3870
3871 memset(outp, 0, sizeof(*outp));
3872 outp->index = 0;
3873 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
3874 strncpy(outp->name, "Autodetect", 31);
3875
3876 return 0;
3877 }
3878 break;
3879
3880 case VIDIOC_G_OUTPUT:
3881 {
3882 int *output = arg;
3883
3884 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr));
3885
3886 *output = 0;
3887
3888 return 0;
3889 }
3890 break;
3891
3892 case VIDIOC_S_OUTPUT:
3893 {
3894 int *output = arg;
3895
3896 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n",
3897 ZR_DEVNAME(zr), *output);
3898
3899 if (*output != 0)
3900 return -EINVAL;
3901
3902 return 0;
3903 }
3904 break;
3905
3906 /* cropping (sub-frame capture) */
3907 case VIDIOC_CROPCAP:
3908 {
3909 struct v4l2_cropcap *cropcap = arg;
3910 int type = cropcap->type, res = 0;
3911
3912 dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n",
3913 ZR_DEVNAME(zr), cropcap->type);
3914
3915 memset(cropcap, 0, sizeof(*cropcap));
3916 cropcap->type = type;
3917
3918 down(&zr->resource_lock);
3919
3920 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3921 (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3922 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3923 dprintk(1,
3924 KERN_ERR
3925 "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
3926 ZR_DEVNAME(zr));
3927 res = -EINVAL;
3928 goto cropcap_unlock_and_return;
3929 }
3930
3931 cropcap->bounds.top = cropcap->bounds.left = 0;
3932 cropcap->bounds.width = BUZ_MAX_WIDTH;
3933 cropcap->bounds.height = BUZ_MAX_HEIGHT;
3934 cropcap->defrect.top = cropcap->defrect.left = 0;
3935 cropcap->defrect.width = BUZ_MIN_WIDTH;
3936 cropcap->defrect.height = BUZ_MIN_HEIGHT;
3937 cropcap_unlock_and_return:
3938 up(&zr->resource_lock);
3939 return res;
3940 }
3941 break;
3942
3943 case VIDIOC_G_CROP:
3944 {
3945 struct v4l2_crop *crop = arg;
3946 int type = crop->type, res = 0;
3947
3948 dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n",
3949 ZR_DEVNAME(zr), crop->type);
3950
3951 memset(crop, 0, sizeof(*crop));
3952 crop->type = type;
3953
3954 down(&zr->resource_lock);
3955
3956 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3957 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3958 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3959 dprintk(1,
3960 KERN_ERR
3961 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3962 ZR_DEVNAME(zr));
3963 res = -EINVAL;
3964 goto gcrop_unlock_and_return;
3965 }
3966
3967 crop->c.top = fh->jpg_settings.img_y;
3968 crop->c.left = fh->jpg_settings.img_x;
3969 crop->c.width = fh->jpg_settings.img_width;
3970 crop->c.height = fh->jpg_settings.img_height;
3971
3972 gcrop_unlock_and_return:
3973 up(&zr->resource_lock);
3974
3975 return res;
3976 }
3977 break;
3978
3979 case VIDIOC_S_CROP:
3980 {
3981 struct v4l2_crop *crop = arg;
3982 int res = 0;
3983
3984 settings = fh->jpg_settings;
3985
3986 dprintk(3,
3987 KERN_ERR
3988 "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n",
3989 ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top,
3990 crop->c.width, crop->c.height);
3991
3992 down(&zr->resource_lock);
3993
3994 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
3995 dprintk(1,
3996 KERN_ERR
3997 "%s: VIDIOC_S_CROP - cannot change settings while active\n",
3998 ZR_DEVNAME(zr));
3999 res = -EBUSY;
4000 goto scrop_unlock_and_return;
4001 }
4002
4003 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
4004 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4005 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
4006 dprintk(1,
4007 KERN_ERR
4008 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
4009 ZR_DEVNAME(zr));
4010 res = -EINVAL;
4011 goto scrop_unlock_and_return;
4012 }
4013
4014 /* move into a form that we understand */
4015 settings.img_x = crop->c.left;
4016 settings.img_y = crop->c.top;
4017 settings.img_width = crop->c.width;
4018 settings.img_height = crop->c.height;
4019
4020 /* check validity */
4021 if ((res = zoran_check_jpg_settings(zr, &settings)))
4022 goto scrop_unlock_and_return;
4023
4024 /* accept */
4025 fh->jpg_settings = settings;
4026
4027 scrop_unlock_and_return:
4028 up(&zr->resource_lock);
4029 return res;
4030 }
4031 break;
4032
4033 case VIDIOC_G_JPEGCOMP:
4034 {
4035 struct v4l2_jpegcompression *params = arg;
4036
4037 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n",
4038 ZR_DEVNAME(zr));
4039
4040 memset(params, 0, sizeof(*params));
4041
4042 down(&zr->resource_lock);
4043
4044 params->quality = fh->jpg_settings.jpg_comp.quality;
4045 params->APPn = fh->jpg_settings.jpg_comp.APPn;
4046 memcpy(params->APP_data,
4047 fh->jpg_settings.jpg_comp.APP_data,
4048 fh->jpg_settings.jpg_comp.APP_len);
4049 params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
4050 memcpy(params->COM_data,
4051 fh->jpg_settings.jpg_comp.COM_data,
4052 fh->jpg_settings.jpg_comp.COM_len);
4053 params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
4054 params->jpeg_markers =
4055 fh->jpg_settings.jpg_comp.jpeg_markers;
4056
4057 up(&zr->resource_lock);
4058
4059 return 0;
4060 }
4061 break;
4062
4063 case VIDIOC_S_JPEGCOMP:
4064 {
4065 struct v4l2_jpegcompression *params = arg;
4066 int res = 0;
4067
4068 settings = fh->jpg_settings;
4069
4070 dprintk(3,
4071 KERN_DEBUG
4072 "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
4073 ZR_DEVNAME(zr), params->quality, params->APPn,
4074 params->APP_len, params->COM_len);
4075
4076 settings.jpg_comp = *params;
4077
4078 down(&zr->resource_lock);
4079
4080 if (fh->v4l_buffers.active != ZORAN_FREE ||
4081 fh->jpg_buffers.active != ZORAN_FREE) {
4082 dprintk(1,
4083 KERN_WARNING
4084 "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
4085 ZR_DEVNAME(zr));
4086 res = -EBUSY;
4087 goto sjpegc_unlock_and_return;
4088 }
4089
4090 if ((res = zoran_check_jpg_settings(zr, &settings)))
4091 goto sjpegc_unlock_and_return;
4092 if (!fh->jpg_buffers.allocated)
4093 fh->jpg_buffers.buffer_size =
4094 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
4095 fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
4096 sjpegc_unlock_and_return:
4097 up(&zr->resource_lock);
4098
4099 return 0;
4100 }
4101 break;
4102
4103 case VIDIOC_QUERYSTD: /* why is this useful? */
4104 {
4105 v4l2_std_id *std = arg;
4106
4107 dprintk(3,
4108 KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n",
4109 ZR_DEVNAME(zr), (unsigned long long)*std);
4110
4111 if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC ||
4112 *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM &&
4113 zr->card.norms == 3)) {
4114 return 0;
4115 }
4116
4117 return -EINVAL;
4118 }
4119 break;
4120
4121 case VIDIOC_TRY_FMT:
4122 {
4123 struct v4l2_format *fmt = arg;
4124 int res = 0;
4125
4126 dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n",
4127 ZR_DEVNAME(zr), fmt->type);
4128
4129 switch (fmt->type) {
4130 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
4131 down(&zr->resource_lock);
4132
4133 if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
4134 fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
4135 if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
4136 fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
4137 if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
4138 fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
4139 if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
4140 fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
4141
4142 up(&zr->resource_lock);
4143 break;
4144
4145 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
4146 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
4147 if (fmt->fmt.pix.bytesperline > 0)
4148 return -EINVAL;
4149
4150 down(&zr->resource_lock);
4151
4152 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
4153 settings = fh->jpg_settings;
4154
4155 /* we actually need to set 'real' parameters now */
4156 if ((fmt->fmt.pix.height * 2) >
4157 BUZ_MAX_HEIGHT)
4158 settings.TmpDcm = 1;
4159 else
4160 settings.TmpDcm = 2;
4161 settings.decimation = 0;
4162 if (fmt->fmt.pix.height <=
4163 fh->jpg_settings.img_height / 2)
4164 settings.VerDcm = 2;
4165 else
4166 settings.VerDcm = 1;
4167 if (fmt->fmt.pix.width <=
4168 fh->jpg_settings.img_width / 4)
4169 settings.HorDcm = 4;
4170 else if (fmt->fmt.pix.width <=
4171 fh->jpg_settings.img_width / 2)
4172 settings.HorDcm = 2;
4173 else
4174 settings.HorDcm = 1;
4175 if (settings.TmpDcm == 1)
4176 settings.field_per_buff = 2;
4177 else
4178 settings.field_per_buff = 1;
4179
4180 /* check */
4181 if ((res =
4182 zoran_check_jpg_settings(zr,
4183 &settings)))
4184 goto tryfmt_unlock_and_return;
4185
4186 /* tell the user what we actually did */
4187 fmt->fmt.pix.width =
4188 settings.img_width / settings.HorDcm;
4189 fmt->fmt.pix.height =
4190 settings.img_height * 2 /
4191 (settings.TmpDcm * settings.VerDcm);
4192 if (settings.TmpDcm == 1)
4193 fmt->fmt.pix.field =
4194 (fh->jpg_settings.
4195 odd_even ? V4L2_FIELD_SEQ_TB :
4196 V4L2_FIELD_SEQ_BT);
4197 else
4198 fmt->fmt.pix.field =
4199 (fh->jpg_settings.
4200 odd_even ? V4L2_FIELD_TOP :
4201 V4L2_FIELD_BOTTOM);
4202
4203 fmt->fmt.pix.sizeimage =
4204 zoran_v4l2_calc_bufsize(&settings);
4205 } else if (fmt->type ==
4206 V4L2_BUF_TYPE_VIDEO_CAPTURE) {
4207 int i;
4208
4209 for (i = 0; i < zoran_num_formats; i++)
4210 if (zoran_formats[i].fourcc ==
4211 fmt->fmt.pix.pixelformat)
4212 break;
4213 if (i == zoran_num_formats) {
4214 res = -EINVAL;
4215 goto tryfmt_unlock_and_return;
4216 }
4217
4218 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
4219 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
4220 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
4221 fmt->fmt.pix.width = BUZ_MIN_WIDTH;
4222 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
4223 fmt->fmt.pix.height =
4224 BUZ_MAX_HEIGHT;
4225 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
4226 fmt->fmt.pix.height =
4227 BUZ_MIN_HEIGHT;
4228 } else {
4229 res = -EINVAL;
4230 goto tryfmt_unlock_and_return;
4231 }
4232 tryfmt_unlock_and_return:
4233 up(&zr->resource_lock);
4234
4235 return res;
4236 break;
4237
4238 default:
4239 return -EINVAL;
4240 }
4241
4242 return 0;
4243 }
4244 break;
4245#endif
4246
4247 default:
4248 dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
4249 ZR_DEVNAME(zr), cmd);
4250 return -ENOIOCTLCMD;
4251 break;
4252
4253 }
4254 return 0;
4255}
4256
4257
4258static int
4259zoran_ioctl (struct inode *inode,
4260 struct file *file,
4261 unsigned int cmd,
4262 unsigned long arg)
4263{
4264 return video_usercopy(inode, file, cmd, arg, zoran_do_ioctl);
4265}
4266
4267static unsigned int
4268zoran_poll (struct file *file,
4269 poll_table *wait)
4270{
4271 struct zoran_fh *fh = file->private_data;
4272 struct zoran *zr = fh->zr;
4273 wait_queue_head_t *queue = NULL;
4274 int res = 0, frame;
4275
4276 /* we should check whether buffers are ready to be synced on
4277 * (w/o waits - O_NONBLOCK) here
4278 * if ready for read (sync), return POLLIN|POLLRDNORM,
4279 * if ready for write (sync), return POLLOUT|POLLWRNORM,
4280 * if error, return POLLERR,
4281 * if no buffers queued or so, return POLLNVAL
4282 */
4283
4284 down(&zr->resource_lock);
4285
4286 switch (fh->map_mode) {
4287 case ZORAN_MAP_MODE_RAW:
4288 if (fh->v4l_buffers.active == ZORAN_FREE ||
4289 zr->v4l_pend_head == zr->v4l_pend_tail) {
4290 dprintk(1,
4291 "%s: zoran_poll() - no buffers queued\n",
4292 ZR_DEVNAME(zr));
4293 res = POLLNVAL;
4294 goto poll_unlock_and_return;
4295 }
4296 queue = &zr->v4l_capq;
4297 frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
4298 poll_wait(file, queue, wait);
4299 if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
4300 res = POLLIN | POLLRDNORM;
4301 break;
4302
4303 case ZORAN_MAP_MODE_JPG_REC:
4304 case ZORAN_MAP_MODE_JPG_PLAY:
4305 if (fh->jpg_buffers.active == ZORAN_FREE ||
4306 zr->jpg_que_head == zr->jpg_que_tail) {
4307 dprintk(1,
4308 "%s: zoran_poll() - no buffers queued\n",
4309 ZR_DEVNAME(zr));
4310 res = POLLNVAL;
4311 goto poll_unlock_and_return;
4312 }
4313 queue = &zr->jpg_capq;
4314 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
4315 poll_wait(file, queue, wait);
4316 if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
4317 if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
4318 res = POLLIN | POLLRDNORM;
4319 else
4320 res = POLLOUT | POLLWRNORM;
4321 }
4322 break;
4323
4324 default:
4325 dprintk(1,
4326 "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
4327 ZR_DEVNAME(zr), fh->map_mode);
4328 res = POLLNVAL;
4329 goto poll_unlock_and_return;
4330 }
4331
4332poll_unlock_and_return:
4333 up(&zr->resource_lock);
4334
4335 return res;
4336}
4337
4338
4339/*
4340 * This maps the buffers to user space.
4341 *
4342 * Depending on the state of fh->map_mode
4343 * the V4L or the MJPEG buffers are mapped
4344 * per buffer or all together
4345 *
4346 * Note that we need to connect to some
4347 * unmap signal event to unmap the de-allocate
4348 * the buffer accordingly (zoran_vm_close())
4349 */
4350
4351static void
4352zoran_vm_open (struct vm_area_struct *vma)
4353{
4354 struct zoran_mapping *map = vma->vm_private_data;
4355
4356 map->count++;
4357}
4358
4359static void
4360zoran_vm_close (struct vm_area_struct *vma)
4361{
4362 struct zoran_mapping *map = vma->vm_private_data;
4363 struct file *file = map->file;
4364 struct zoran_fh *fh = file->private_data;
4365 struct zoran *zr = fh->zr;
4366 int i;
4367
4368 map->count--;
4369 if (map->count == 0) {
4370 switch (fh->map_mode) {
4371 case ZORAN_MAP_MODE_JPG_REC:
4372 case ZORAN_MAP_MODE_JPG_PLAY:
4373
4374 dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
4375 ZR_DEVNAME(zr));
4376
4377 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
4378 if (fh->jpg_buffers.buffer[i].map == map) {
4379 fh->jpg_buffers.buffer[i].map =
4380 NULL;
4381 }
4382 }
4383 kfree(map);
4384
4385 for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
4386 if (fh->jpg_buffers.buffer[i].map)
4387 break;
4388 if (i == fh->jpg_buffers.num_buffers) {
4389 down(&zr->resource_lock);
4390
4391 if (fh->jpg_buffers.active != ZORAN_FREE) {
4392 jpg_qbuf(file, -1, zr->codec_mode);
4393 zr->jpg_buffers.allocated = 0;
4394 zr->jpg_buffers.active =
4395 fh->jpg_buffers.active =
4396 ZORAN_FREE;
4397 }
4398 //jpg_fbuffer_free(file);
4399 fh->jpg_buffers.allocated = 0;
4400 fh->jpg_buffers.ready_to_be_freed = 1;
4401
4402 up(&zr->resource_lock);
4403 }
4404
4405 break;
4406
4407 case ZORAN_MAP_MODE_RAW:
4408
4409 dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
4410 ZR_DEVNAME(zr));
4411
4412 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
4413 if (fh->v4l_buffers.buffer[i].map == map) {
4414 /* unqueue/unmap */
4415 fh->v4l_buffers.buffer[i].map =
4416 NULL;
4417 }
4418 }
4419 kfree(map);
4420
4421 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
4422 if (fh->v4l_buffers.buffer[i].map)
4423 break;
4424 if (i == fh->v4l_buffers.num_buffers) {
4425 down(&zr->resource_lock);
4426
4427 if (fh->v4l_buffers.active != ZORAN_FREE) {
4428 zr36057_set_memgrab(zr, 0);
4429 zr->v4l_buffers.allocated = 0;
4430 zr->v4l_buffers.active =
4431 fh->v4l_buffers.active =
4432 ZORAN_FREE;
4433 }
4434 //v4l_fbuffer_free(file);
4435 fh->v4l_buffers.allocated = 0;
4436 fh->v4l_buffers.ready_to_be_freed = 1;
4437
4438 up(&zr->resource_lock);
4439 }
4440
4441 break;
4442
4443 default:
4444 printk(KERN_ERR
4445 "%s: munmap() - internal error - unknown map mode %d\n",
4446 ZR_DEVNAME(zr), fh->map_mode);
4447 break;
4448
4449 }
4450 }
4451}
4452
4453static struct vm_operations_struct zoran_vm_ops = {
4454 .open = zoran_vm_open,
4455 .close = zoran_vm_close,
4456};
4457
4458static int
4459zoran_mmap (struct file *file,
4460 struct vm_area_struct *vma)
4461{
4462 struct zoran_fh *fh = file->private_data;
4463 struct zoran *zr = fh->zr;
4464 unsigned long size = (vma->vm_end - vma->vm_start);
4465 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
4466 int i, j;
4467 unsigned long page, start = vma->vm_start, todo, pos, fraglen;
4468 int first, last;
4469 struct zoran_mapping *map;
4470 int res = 0;
4471
4472 dprintk(3,
4473 KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
4474 ZR_DEVNAME(zr),
4475 fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
4476 vma->vm_start, vma->vm_end, size);
4477
4478 if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
4479 !(vma->vm_flags & VM_WRITE)) {
4480 dprintk(1,
4481 KERN_ERR
4482 "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
4483 ZR_DEVNAME(zr));
4484 return -EINVAL;
4485 }
4486
4487 switch (fh->map_mode) {
4488
4489 case ZORAN_MAP_MODE_JPG_REC:
4490 case ZORAN_MAP_MODE_JPG_PLAY:
4491
4492 /* lock */
4493 down(&zr->resource_lock);
4494
4495 /* Map the MJPEG buffers */
4496 if (!fh->jpg_buffers.allocated) {
4497 dprintk(1,
4498 KERN_ERR
4499 "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
4500 ZR_DEVNAME(zr));
4501 res = -ENOMEM;
4502 goto jpg_mmap_unlock_and_return;
4503 }
4504
4505 first = offset / fh->jpg_buffers.buffer_size;
4506 last = first - 1 + size / fh->jpg_buffers.buffer_size;
4507 if (offset % fh->jpg_buffers.buffer_size != 0 ||
4508 size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
4509 last < 0 || first >= fh->jpg_buffers.num_buffers ||
4510 last >= fh->jpg_buffers.num_buffers) {
4511 dprintk(1,
4512 KERN_ERR
4513 "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
4514 ZR_DEVNAME(zr), offset, size,
4515 fh->jpg_buffers.buffer_size,
4516 fh->jpg_buffers.num_buffers);
4517 res = -EINVAL;
4518 goto jpg_mmap_unlock_and_return;
4519 }
4520 for (i = first; i <= last; i++) {
4521 if (fh->jpg_buffers.buffer[i].map) {
4522 dprintk(1,
4523 KERN_ERR
4524 "%s: mmap(MJPEG) - buffer %d already mapped\n",
4525 ZR_DEVNAME(zr), i);
4526 res = -EBUSY;
4527 goto jpg_mmap_unlock_and_return;
4528 }
4529 }
4530
4531 /* map these buffers (v4l_buffers[i]) */
4532 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
4533 if (!map) {
4534 res = -ENOMEM;
4535 goto jpg_mmap_unlock_and_return;
4536 }
4537 map->file = file;
4538 map->count = 1;
4539
4540 vma->vm_ops = &zoran_vm_ops;
4541 vma->vm_flags |= VM_DONTEXPAND;
4542 vma->vm_private_data = map;
4543
4544 for (i = first; i <= last; i++) {
4545 for (j = 0;
4546 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
4547 j++) {
4548 fraglen =
4549 (le32_to_cpu(fh->jpg_buffers.buffer[i].
4550 frag_tab[2 * j + 1]) & ~1) << 1;
4551 todo = size;
4552 if (todo > fraglen)
4553 todo = fraglen;
4554 pos =
4555 le32_to_cpu((unsigned long) fh->jpg_buffers.
4556 buffer[i].frag_tab[2 * j]);
4557 /* should just be pos on i386 */
4558 page = virt_to_phys(bus_to_virt(pos))
4559 >> PAGE_SHIFT;
4560 if (remap_pfn_range(vma, start, page,
4561 todo, PAGE_SHARED)) {
4562 dprintk(1,
4563 KERN_ERR
4564 "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
4565 ZR_DEVNAME(zr));
4566 res = -EAGAIN;
4567 goto jpg_mmap_unlock_and_return;
4568 }
4569 size -= todo;
4570 start += todo;
4571 if (size == 0)
4572 break;
4573 if (le32_to_cpu(fh->jpg_buffers.buffer[i].
4574 frag_tab[2 * j + 1]) & 1)
4575 break; /* was last fragment */
4576 }
4577 fh->jpg_buffers.buffer[i].map = map;
4578 if (size == 0)
4579 break;
4580
4581 }
4582 jpg_mmap_unlock_and_return:
4583 up(&zr->resource_lock);
4584
4585 break;
4586
4587 case ZORAN_MAP_MODE_RAW:
4588
4589 down(&zr->resource_lock);
4590
4591 /* Map the V4L buffers */
4592 if (!fh->v4l_buffers.allocated) {
4593 dprintk(1,
4594 KERN_ERR
4595 "%s: zoran_mmap(V4L) - buffers not yet allocated\n",
4596 ZR_DEVNAME(zr));
4597 res = -ENOMEM;
4598 goto v4l_mmap_unlock_and_return;
4599 }
4600
4601 first = offset / fh->v4l_buffers.buffer_size;
4602 last = first - 1 + size / fh->v4l_buffers.buffer_size;
4603 if (offset % fh->v4l_buffers.buffer_size != 0 ||
4604 size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
4605 last < 0 || first >= fh->v4l_buffers.num_buffers ||
4606 last >= fh->v4l_buffers.buffer_size) {
4607 dprintk(1,
4608 KERN_ERR
4609 "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
4610 ZR_DEVNAME(zr), offset, size,
4611 fh->v4l_buffers.buffer_size,
4612 fh->v4l_buffers.num_buffers);
4613 res = -EINVAL;
4614 goto v4l_mmap_unlock_and_return;
4615 }
4616 for (i = first; i <= last; i++) {
4617 if (fh->v4l_buffers.buffer[i].map) {
4618 dprintk(1,
4619 KERN_ERR
4620 "%s: mmap(V4L) - buffer %d already mapped\n",
4621 ZR_DEVNAME(zr), i);
4622 res = -EBUSY;
4623 goto v4l_mmap_unlock_and_return;
4624 }
4625 }
4626
4627 /* map these buffers (v4l_buffers[i]) */
4628 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
4629 if (!map) {
4630 res = -ENOMEM;
4631 goto v4l_mmap_unlock_and_return;
4632 }
4633 map->file = file;
4634 map->count = 1;
4635
4636 vma->vm_ops = &zoran_vm_ops;
4637 vma->vm_flags |= VM_DONTEXPAND;
4638 vma->vm_private_data = map;
4639
4640 for (i = first; i <= last; i++) {
4641 todo = size;
4642 if (todo > fh->v4l_buffers.buffer_size)
4643 todo = fh->v4l_buffers.buffer_size;
4644 page = fh->v4l_buffers.buffer[i].fbuffer_phys;
4645 if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
4646 todo, PAGE_SHARED)) {
4647 dprintk(1,
4648 KERN_ERR
4649 "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
4650 ZR_DEVNAME(zr));
4651 res = -EAGAIN;
4652 goto v4l_mmap_unlock_and_return;
4653 }
4654 size -= todo;
4655 start += todo;
4656 fh->v4l_buffers.buffer[i].map = map;
4657 if (size == 0)
4658 break;
4659 }
4660 v4l_mmap_unlock_and_return:
4661 up(&zr->resource_lock);
4662
4663 break;
4664
4665 default:
4666 dprintk(1,
4667 KERN_ERR
4668 "%s: zoran_mmap() - internal error - unknown map mode %d\n",
4669 ZR_DEVNAME(zr), fh->map_mode);
4670 break;
4671 }
4672
4673 return 0;
4674}
4675
4676static struct file_operations zoran_fops = {
4677 .owner = THIS_MODULE,
4678 .open = zoran_open,
4679 .release = zoran_close,
4680 .ioctl = zoran_ioctl,
4681 .llseek = no_llseek,
4682 .read = zoran_read,
4683 .write = zoran_write,
4684 .mmap = zoran_mmap,
4685 .poll = zoran_poll,
4686};
4687
4688struct video_device zoran_template __devinitdata = {
4689 .name = ZORAN_NAME,
4690 .type = ZORAN_VID_TYPE,
4691#ifdef HAVE_V4L2
4692 .type2 = ZORAN_V4L2_VID_FLAGS,
4693#endif
4694 .hardware = ZORAN_HARDWARE,
4695 .fops = &zoran_fops,
4696 .release = &zoran_vdev_release,
4697 .minor = -1
4698};
4699
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c
new file mode 100644
index 000000000000..f0d9b13c3c6c
--- /dev/null
+++ b/drivers/media/video/zoran_procfs.c
@@ -0,0 +1,233 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles the procFS entries (/proc/ZORAN[%d])
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include <linux/i2c.h>
39#include <linux/i2c-algo-bit.h>
40#include <linux/videodev.h>
41#include <linux/spinlock.h>
42#include <linux/sem.h>
43#include <linux/seq_file.h>
44
45#include <linux/ctype.h>
46#include <asm/io.h>
47
48#include "videocodec.h"
49#include "zoran.h"
50#include "zoran_procfs.h"
51
52extern int *zr_debug;
53
54#define dprintk(num, format, args...) \
55 do { \
56 if (*zr_debug >= num) \
57 printk(format, ##args); \
58 } while (0)
59
60#ifdef CONFIG_PROC_FS
61struct procfs_params_zr36067 {
62 char *name;
63 short reg;
64 u32 mask;
65 short bit;
66};
67
68static const struct procfs_params_zr36067 zr67[] = {
69 {"HSPol", 0x000, 1, 30},
70 {"HStart", 0x000, 0x3ff, 10},
71 {"HEnd", 0x000, 0x3ff, 0},
72
73 {"VSPol", 0x004, 1, 30},
74 {"VStart", 0x004, 0x3ff, 10},
75 {"VEnd", 0x004, 0x3ff, 0},
76
77 {"ExtFl", 0x008, 1, 26},
78 {"TopField", 0x008, 1, 25},
79 {"VCLKPol", 0x008, 1, 24},
80 {"DupFld", 0x008, 1, 20},
81 {"LittleEndian", 0x008, 1, 0},
82
83 {"HsyncStart", 0x10c, 0xffff, 16},
84 {"LineTot", 0x10c, 0xffff, 0},
85
86 {"NAX", 0x110, 0xffff, 16},
87 {"PAX", 0x110, 0xffff, 0},
88
89 {"NAY", 0x114, 0xffff, 16},
90 {"PAY", 0x114, 0xffff, 0},
91
92 /* {"",,,}, */
93
94 {NULL, 0, 0, 0},
95};
96
97static void
98setparam (struct zoran *zr,
99 char *name,
100 char *sval)
101{
102 int i = 0, reg0, reg, val;
103
104 while (zr67[i].name != NULL) {
105 if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
106 reg = reg0 = btread(zr67[i].reg);
107 reg &= ~(zr67[i].mask << zr67[i].bit);
108 if (!isdigit(sval[0]))
109 break;
110 val = simple_strtoul(sval, NULL, 0);
111 if ((val & ~zr67[i].mask))
112 break;
113 reg |= (val & zr67[i].mask) << zr67[i].bit;
114 dprintk(4,
115 KERN_INFO
116 "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
117 ZR_DEVNAME(zr), zr67[i].reg, reg0, reg,
118 zr67[i].name, val);
119 btwrite(reg, zr67[i].reg);
120 break;
121 }
122 i++;
123 }
124}
125
126static int zoran_show(struct seq_file *p, void *v)
127{
128 struct zoran *zr = p->private;
129 int i;
130
131 seq_printf(p, "ZR36067 registers:\n");
132 for (i = 0; i < 0x130; i += 16)
133 seq_printf(p, "%03X %08X %08X %08X %08X \n", i,
134 btread(i), btread(i+4), btread(i+8), btread(i+12));
135 return 0;
136}
137
138static int zoran_open(struct inode *inode, struct file *file)
139{
140 struct zoran *data = PDE(inode)->data;
141 return single_open(file, zoran_show, data);
142}
143
144static ssize_t zoran_write(struct file *file, const char __user *buffer,
145 size_t count, loff_t *ppos)
146{
147 struct zoran *zr = PDE(file->f_dentry->d_inode)->data;
148 char *string, *sp;
149 char *line, *ldelim, *varname, *svar, *tdelim;
150
151 if (count > 32768) /* Stupidity filter */
152 return -EINVAL;
153
154 string = sp = vmalloc(count + 1);
155 if (!string) {
156 dprintk(1,
157 KERN_ERR
158 "%s: write_proc: can not allocate memory\n",
159 ZR_DEVNAME(zr));
160 return -ENOMEM;
161 }
162 if (copy_from_user(string, buffer, count)) {
163 vfree (string);
164 return -EFAULT;
165 }
166 string[count] = 0;
167 dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n",
168 ZR_DEVNAME(zr), file->f_dentry->d_name.name, count, zr);
169 ldelim = " \t\n";
170 tdelim = "=";
171 line = strpbrk(sp, ldelim);
172 while (line) {
173 *line = 0;
174 svar = strpbrk(sp, tdelim);
175 if (svar) {
176 *svar = 0;
177 varname = sp;
178 svar++;
179 setparam(zr, varname, svar);
180 }
181 sp = line + 1;
182 line = strpbrk(sp, ldelim);
183 }
184 vfree(string);
185
186 return count;
187}
188
189static struct file_operations zoran_operations = {
190 .open = zoran_open,
191 .read = seq_read,
192 .write = zoran_write,
193 .llseek = seq_lseek,
194 .release = single_release,
195};
196#endif
197
198int
199zoran_proc_init (struct zoran *zr)
200{
201#ifdef CONFIG_PROC_FS
202 char name[8];
203
204 snprintf(name, 7, "zoran%d", zr->id);
205 if ((zr->zoran_proc = create_proc_entry(name, 0, NULL))) {
206 zr->zoran_proc->data = zr;
207 zr->zoran_proc->owner = THIS_MODULE;
208 zr->zoran_proc->proc_fops = &zoran_operations;
209 dprintk(2,
210 KERN_INFO
211 "%s: procfs entry /proc/%s allocated. data=%p\n",
212 ZR_DEVNAME(zr), name, zr->zoran_proc->data);
213 } else {
214 dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
215 ZR_DEVNAME(zr), name);
216 return 1;
217 }
218#endif
219 return 0;
220}
221
222void
223zoran_proc_cleanup (struct zoran *zr)
224{
225#ifdef CONFIG_PROC_FS
226 char name[8];
227
228 snprintf(name, 7, "zoran%d", zr->id);
229 if (zr->zoran_proc)
230 remove_proc_entry(name, NULL);
231 zr->zoran_proc = NULL;
232#endif
233}
diff --git a/drivers/media/video/zoran_procfs.h b/drivers/media/video/zoran_procfs.h
new file mode 100644
index 000000000000..8904fc959555
--- /dev/null
+++ b/drivers/media/video/zoran_procfs.h
@@ -0,0 +1,36 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_PROCFS_H__
31#define __ZORAN_PROCFS_H__
32
33extern int zoran_proc_init(struct zoran *zr);
34extern void zoran_proc_cleanup(struct zoran *zr);
35
36#endif /* __ZORAN_PROCFS_H__ */
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
new file mode 100644
index 000000000000..d4740a89cea1
--- /dev/null
+++ b/drivers/media/video/zr36016.c
@@ -0,0 +1,532 @@
1/*
2 * Zoran ZR36016 basic configuration functions
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36016.c,v 1.1.2.14 2003/08/20 19:46:55 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR016_VERSION "v0.7"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* v4l API */
46#include<linux/videodev.h>
47
48/* headerfile of this module */
49#include"zr36016.h"
50
51/* codec io API */
52#include"videocodec.h"
53
54/* it doesn't make sense to have more than 20 or so,
55 just to prevent some unwanted loops */
56#define MAX_CODECS 20
57
58/* amount of chips attached via this driver */
59static int zr36016_codecs = 0;
60
61/* debugging is available via module parameter */
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-4)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* =========================================================================
74 Local hardware I/O functions:
75
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
78
79/* read and write functions */
80static u8
81zr36016_read (struct zr36016 *ptr,
82 u16 reg)
83{
84 u8 value = 0;
85
86 // just in case something is wrong...
87 if (ptr->codec->master_data->readreg)
88 value =
89 (ptr->codec->master_data->
90 readreg(ptr->codec, reg)) & 0xFF;
91 else
92 dprintk(1,
93 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
94 ptr->name);
95
96 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
97 value);
98
99 return value;
100}
101
102static void
103zr36016_write (struct zr36016 *ptr,
104 u16 reg,
105 u8 value)
106{
107 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
108 reg);
109
110 // just in case something is wrong...
111 if (ptr->codec->master_data->writereg) {
112 ptr->codec->master_data->writereg(ptr->codec, reg, value);
113 } else
114 dprintk(1,
115 KERN_ERR
116 "%s: invalid I/O setup, nothing written!\n",
117 ptr->name);
118}
119
120/* indirect read and write functions */
121/* the 016 supports auto-addr-increment, but
122 * writing it all time cost not much and is safer... */
123static u8
124zr36016_readi (struct zr36016 *ptr,
125 u16 reg)
126{
127 u8 value = 0;
128
129 // just in case something is wrong...
130 if ((ptr->codec->master_data->writereg) &&
131 (ptr->codec->master_data->readreg)) {
132 ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
133 value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA
134 } else
135 dprintk(1,
136 KERN_ERR
137 "%s: invalid I/O setup, nothing read (i)!\n",
138 ptr->name);
139
140 dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name,
141 reg, value);
142 return value;
143}
144
145static void
146zr36016_writei (struct zr36016 *ptr,
147 u16 reg,
148 u8 value)
149{
150 dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name,
151 value, reg);
152
153 // just in case something is wrong...
154 if (ptr->codec->master_data->writereg) {
155 ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
156 ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA
157 } else
158 dprintk(1,
159 KERN_ERR
160 "%s: invalid I/O setup, nothing written (i)!\n",
161 ptr->name);
162}
163
164/* =========================================================================
165 Local helper function:
166
167 version read
168 ========================================================================= */
169
170/* version kept in datastructure */
171static u8
172zr36016_read_version (struct zr36016 *ptr)
173{
174 ptr->version = zr36016_read(ptr, 0) >> 4;
175 return ptr->version;
176}
177
178/* =========================================================================
179 Local helper function:
180
181 basic test of "connectivity", writes/reads to/from PAX-Lo register
182 ========================================================================= */
183
184static int
185zr36016_basic_test (struct zr36016 *ptr)
186{
187 if (debug) {
188 int i;
189 zr36016_writei(ptr, ZR016I_PAX_LO, 0x55);
190 dprintk(1, KERN_INFO "%s: registers: ", ptr->name);
191 for (i = 0; i <= 0x0b; i++)
192 dprintk(1, "%02x ", zr36016_readi(ptr, i));
193 dprintk(1, "\n");
194 }
195 // for testing just write 0, then the default value to a register and read
196 // it back in both cases
197 zr36016_writei(ptr, ZR016I_PAX_LO, 0x00);
198 if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) {
199 dprintk(1,
200 KERN_ERR
201 "%s: attach failed, can't connect to vfe processor!\n",
202 ptr->name);
203 return -ENXIO;
204 }
205 zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0);
206 if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) {
207 dprintk(1,
208 KERN_ERR
209 "%s: attach failed, can't connect to vfe processor!\n",
210 ptr->name);
211 return -ENXIO;
212 }
213 // we allow version numbers from 0-3, should be enough, though
214 zr36016_read_version(ptr);
215 if (ptr->version & 0x0c) {
216 dprintk(1,
217 KERN_ERR
218 "%s: attach failed, suspicious version %d found...\n",
219 ptr->name, ptr->version);
220 return -ENXIO;
221 }
222
223 return 0; /* looks good! */
224}
225
226/* =========================================================================
227 Local helper function:
228
229 simple loop for pushing the init datasets - NO USE --
230 ========================================================================= */
231
232#if 0
233static int zr36016_pushit (struct zr36016 *ptr,
234 u16 startreg,
235 u16 len,
236 const char *data)
237{
238 int i=0;
239
240 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n",
241 ptr->name, startreg,len);
242 while (i<len) {
243 zr36016_writei(ptr, startreg++, data[i++]);
244 }
245
246 return i;
247}
248#endif
249
250/* =========================================================================
251 Basic datasets & init:
252
253 //TODO//
254 ========================================================================= */
255
256// needed offset values PAL NTSC SECAM
257static const int zr016_xoff[] = { 20, 20, 20 };
258static const int zr016_yoff[] = { 8, 9, 7 };
259
260static void
261zr36016_init (struct zr36016 *ptr)
262{
263 // stop any processing
264 zr36016_write(ptr, ZR016_GOSTOP, 0);
265
266 // mode setup (yuv422 in and out, compression/expansuon due to mode)
267 zr36016_write(ptr, ZR016_MODE,
268 ZR016_YUV422 | ZR016_YUV422_YUV422 |
269 (ptr->mode == CODEC_DO_COMPRESSION ?
270 ZR016_COMPRESSION : ZR016_EXPANSION));
271
272 // misc setup
273 zr36016_writei(ptr, ZR016I_SETUP1,
274 (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) |
275 (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI);
276 zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR);
277
278 // Window setup
279 // (no extra offset for now, norm defines offset, default width height)
280 zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8);
281 zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF);
282 zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8);
283 zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF);
284 zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8);
285 zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF);
286 zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8);
287 zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF);
288
289 /* shall we continue now, please? */
290 zr36016_write(ptr, ZR016_GOSTOP, 1);
291}
292
293/* =========================================================================
294 CODEC API FUNCTIONS
295
296 this functions are accessed by the master via the API structure
297 ========================================================================= */
298
299/* set compression/expansion mode and launches codec -
300 this should be the last call from the master before starting processing */
301static int
302zr36016_set_mode (struct videocodec *codec,
303 int mode)
304{
305 struct zr36016 *ptr = (struct zr36016 *) codec->data;
306
307 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
308
309 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
310 return -EINVAL;
311
312 ptr->mode = mode;
313 zr36016_init(ptr);
314
315 return 0;
316}
317
318/* set picture size */
319static int
320zr36016_set_video (struct videocodec *codec,
321 struct tvnorm *norm,
322 struct vfe_settings *cap,
323 struct vfe_polarity *pol)
324{
325 struct zr36016 *ptr = (struct zr36016 *) codec->data;
326
327 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n",
328 ptr->name, norm->HStart, norm->VStart,
329 cap->x, cap->y, cap->width, cap->height,
330 cap->decimation);
331
332 /* if () return -EINVAL;
333 * trust the master driver that it knows what it does - so
334 * we allow invalid startx/y for now ... */
335 ptr->width = cap->width;
336 ptr->height = cap->height;
337 /* (Ronald) This is ugly. zoran_device.c, line 387
338 * already mentions what happens if HStart is even
339 * (blue faces, etc., cr/cb inversed). There's probably
340 * some good reason why HStart is 0 instead of 1, so I'm
341 * leaving it to this for now, but really... This can be
342 * done a lot simpler */
343 ptr->xoff = (norm->HStart ? norm->HStart : 1) + cap->x;
344 /* Something to note here (I don't understand it), setting
345 * VStart too high will cause the codec to 'not work'. I
346 * really don't get it. values of 16 (VStart) already break
347 * it here. Just '0' seems to work. More testing needed! */
348 ptr->yoff = norm->VStart + cap->y;
349 /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
350 ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
351 ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1;
352
353 return 0;
354}
355
356/* additional control functions */
357static int
358zr36016_control (struct videocodec *codec,
359 int type,
360 int size,
361 void *data)
362{
363 struct zr36016 *ptr = (struct zr36016 *) codec->data;
364 int *ival = (int *) data;
365
366 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
367 size);
368
369 switch (type) {
370 case CODEC_G_STATUS: /* get last status - we don't know it ... */
371 if (size != sizeof(int))
372 return -EFAULT;
373 *ival = 0;
374 break;
375
376 case CODEC_G_CODEC_MODE:
377 if (size != sizeof(int))
378 return -EFAULT;
379 *ival = 0;
380 break;
381
382 case CODEC_S_CODEC_MODE:
383 if (size != sizeof(int))
384 return -EFAULT;
385 if (*ival != 0)
386 return -EINVAL;
387 /* not needed, do nothing */
388 return 0;
389
390 case CODEC_G_VFE:
391 case CODEC_S_VFE:
392 return 0;
393
394 case CODEC_S_MMAP:
395 /* not available, give an error */
396 return -ENXIO;
397
398 default:
399 return -EINVAL;
400 }
401
402 return size;
403}
404
405/* =========================================================================
406 Exit and unregister function:
407
408 Deinitializes Zoran's JPEG processor
409 ========================================================================= */
410
411static int
412zr36016_unset (struct videocodec *codec)
413{
414 struct zr36016 *ptr = codec->data;
415
416 if (ptr) {
417 /* do wee need some codec deinit here, too ???? */
418
419 dprintk(1, "%s: finished codec #%d\n", ptr->name,
420 ptr->num);
421 kfree(ptr);
422 codec->data = NULL;
423
424 zr36016_codecs--;
425 return 0;
426 }
427
428 return -EFAULT;
429}
430
431/* =========================================================================
432 Setup and registry function:
433
434 Initializes Zoran's JPEG processor
435
436 Also sets pixel size, average code size, mode (compr./decompr.)
437 (the given size is determined by the processor with the video interface)
438 ========================================================================= */
439
440static int
441zr36016_setup (struct videocodec *codec)
442{
443 struct zr36016 *ptr;
444 int res;
445
446 dprintk(2, "zr36016: initializing VFE subsystem #%d.\n",
447 zr36016_codecs);
448
449 if (zr36016_codecs == MAX_CODECS) {
450 dprintk(1,
451 KERN_ERR "zr36016: Can't attach more codecs!\n");
452 return -ENOSPC;
453 }
454 //mem structure init
455 codec->data = ptr = kmalloc(sizeof(struct zr36016), GFP_KERNEL);
456 if (NULL == ptr) {
457 dprintk(1, KERN_ERR "zr36016: Can't get enough memory!\n");
458 return -ENOMEM;
459 }
460 memset(ptr, 0, sizeof(struct zr36016));
461
462 snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]",
463 zr36016_codecs);
464 ptr->num = zr36016_codecs++;
465 ptr->codec = codec;
466
467 //testing
468 res = zr36016_basic_test(ptr);
469 if (res < 0) {
470 zr36016_unset(codec);
471 return res;
472 }
473 //final setup
474 ptr->mode = CODEC_DO_COMPRESSION;
475 ptr->width = 768;
476 ptr->height = 288;
477 ptr->xdec = 1;
478 ptr->ydec = 0;
479 zr36016_init(ptr);
480
481 dprintk(1, KERN_INFO "%s: codec v%d attached and running\n",
482 ptr->name, ptr->version);
483
484 return 0;
485}
486
487static const struct videocodec zr36016_codec = {
488 .owner = THIS_MODULE,
489 .name = "zr36016",
490 .magic = 0L, // magic not used
491 .flags =
492 CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER |
493 CODEC_FLAG_DECODER,
494 .type = CODEC_TYPE_ZR36016,
495 .setup = zr36016_setup, // functionality
496 .unset = zr36016_unset,
497 .set_mode = zr36016_set_mode,
498 .set_video = zr36016_set_video,
499 .control = zr36016_control,
500 // others are not used
501};
502
503/* =========================================================================
504 HOOK IN DRIVER AS KERNEL MODULE
505 ========================================================================= */
506
507static int __init
508zr36016_init_module (void)
509{
510 //dprintk(1, "ZR36016 driver %s\n",ZR016_VERSION);
511 zr36016_codecs = 0;
512 return videocodec_register(&zr36016_codec);
513}
514
515static void __exit
516zr36016_cleanup_module (void)
517{
518 if (zr36016_codecs) {
519 dprintk(1,
520 "zr36016: something's wrong - %d codecs left somehow.\n",
521 zr36016_codecs);
522 }
523 videocodec_unregister(&zr36016_codec);
524}
525
526module_init(zr36016_init_module);
527module_exit(zr36016_cleanup_module);
528
529MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
530MODULE_DESCRIPTION("Driver module for ZR36016 video frontends "
531 ZR016_VERSION);
532MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36016.h b/drivers/media/video/zr36016.h
new file mode 100644
index 000000000000..8c79229f69d1
--- /dev/null
+++ b/drivers/media/video/zr36016.h
@@ -0,0 +1,111 @@
1/*
2 * Zoran ZR36016 basic configuration functions - header file
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36016.h,v 1.1.2.3 2003/01/14 21:18:07 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36016_H
28#define ZR36016_H
29
30/* data stored for each zoran jpeg codec chip */
31struct zr36016 {
32 char name[32];
33 int num;
34 /* io datastructure */
35 struct videocodec *codec;
36 // coder status
37 __u8 version;
38 // actual coder setup
39 int mode;
40
41 __u16 xoff;
42 __u16 yoff;
43 __u16 width;
44 __u16 height;
45 __u16 xdec;
46 __u16 ydec;
47};
48
49/* direct register addresses */
50#define ZR016_GOSTOP 0x00
51#define ZR016_MODE 0x01
52#define ZR016_IADDR 0x02
53#define ZR016_IDATA 0x03
54
55/* indirect register addresses */
56#define ZR016I_SETUP1 0x00
57#define ZR016I_SETUP2 0x01
58#define ZR016I_NAX_LO 0x02
59#define ZR016I_NAX_HI 0x03
60#define ZR016I_PAX_LO 0x04
61#define ZR016I_PAX_HI 0x05
62#define ZR016I_NAY_LO 0x06
63#define ZR016I_NAY_HI 0x07
64#define ZR016I_PAY_LO 0x08
65#define ZR016I_PAY_HI 0x09
66#define ZR016I_NOL_LO 0x0a
67#define ZR016I_NOL_HI 0x0b
68
69/* possible values for mode register */
70#define ZR016_RGB444_YUV444 0x00
71#define ZR016_RGB444_YUV422 0x01
72#define ZR016_RGB444_YUV411 0x02
73#define ZR016_RGB444_Y400 0x03
74#define ZR016_RGB444_RGB444 0x04
75#define ZR016_YUV444_YUV444 0x08
76#define ZR016_YUV444_YUV422 0x09
77#define ZR016_YUV444_YUV411 0x0a
78#define ZR016_YUV444_Y400 0x0b
79#define ZR016_YUV444_RGB444 0x0c
80#define ZR016_YUV422_YUV422 0x11
81#define ZR016_YUV422_YUV411 0x12
82#define ZR016_YUV422_Y400 0x13
83#define ZR016_YUV411_YUV411 0x16
84#define ZR016_YUV411_Y400 0x17
85#define ZR016_4444_4444 0x19
86#define ZR016_100_100 0x1b
87
88#define ZR016_RGB444 0x00
89#define ZR016_YUV444 0x20
90#define ZR016_YUV422 0x40
91
92#define ZR016_COMPRESSION 0x80
93#define ZR016_EXPANSION 0x80
94
95/* possible values for setup 1 register */
96#define ZR016_CKRT 0x80
97#define ZR016_VERT 0x40
98#define ZR016_HORZ 0x20
99#define ZR016_HRFL 0x10
100#define ZR016_DSFL 0x08
101#define ZR016_SBFL 0x04
102#define ZR016_RSTR 0x02
103#define ZR016_CNTI 0x01
104
105/* possible values for setup 2 register */
106#define ZR016_SYEN 0x40
107#define ZR016_CCIR 0x04
108#define ZR016_SIGN 0x02
109#define ZR016_YMCS 0x01
110
111#endif /*fndef ZR36016_H */
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
new file mode 100644
index 000000000000..13b1e7b6fd6e
--- /dev/null
+++ b/drivers/media/video/zr36050.c
@@ -0,0 +1,907 @@
1/*
2 * Zoran ZR36050 basic configuration functions
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36050.c,v 1.1.2.11 2003/08/03 14:54:53 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR050_VERSION "v0.7.1"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* headerfile of this module */
46#include"zr36050.h"
47
48/* codec io API */
49#include"videocodec.h"
50
51/* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
53#define MAX_CODECS 20
54
55/* amount of chips attached via this driver */
56static int zr36050_codecs = 0;
57
58/* debugging is available via module parameter */
59
60static int debug = 0;
61module_param(debug, int, 0);
62MODULE_PARM_DESC(debug, "Debug level (0-4)");
63
64#define dprintk(num, format, args...) \
65 do { \
66 if (debug >= num) \
67 printk(format, ##args); \
68 } while (0)
69
70/* =========================================================================
71 Local hardware I/O functions:
72
73 read/write via codec layer (registers are located in the master device)
74 ========================================================================= */
75
76/* read and write functions */
77static u8
78zr36050_read (struct zr36050 *ptr,
79 u16 reg)
80{
81 u8 value = 0;
82
83 // just in case something is wrong...
84 if (ptr->codec->master_data->readreg)
85 value = (ptr->codec->master_data->readreg(ptr->codec,
86 reg)) & 0xFF;
87 else
88 dprintk(1,
89 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
90 ptr->name);
91
92 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
93 value);
94
95 return value;
96}
97
98static void
99zr36050_write (struct zr36050 *ptr,
100 u16 reg,
101 u8 value)
102{
103 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
104 reg);
105
106 // just in case something is wrong...
107 if (ptr->codec->master_data->writereg)
108 ptr->codec->master_data->writereg(ptr->codec, reg, value);
109 else
110 dprintk(1,
111 KERN_ERR
112 "%s: invalid I/O setup, nothing written!\n",
113 ptr->name);
114}
115
116/* =========================================================================
117 Local helper function:
118
119 status read
120 ========================================================================= */
121
122/* status is kept in datastructure */
123static u8
124zr36050_read_status1 (struct zr36050 *ptr)
125{
126 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
127
128 zr36050_read(ptr, 0);
129 return ptr->status1;
130}
131
132/* =========================================================================
133 Local helper function:
134
135 scale factor read
136 ========================================================================= */
137
138/* scale factor is kept in datastructure */
139static u16
140zr36050_read_scalefactor (struct zr36050 *ptr)
141{
142 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
143 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
144
145 /* leave 0 selected for an eventually GO from master */
146 zr36050_read(ptr, 0);
147 return ptr->scalefact;
148}
149
150/* =========================================================================
151 Local helper function:
152
153 wait if codec is ready to proceed (end of processing) or time is over
154 ========================================================================= */
155
156static void
157zr36050_wait_end (struct zr36050 *ptr)
158{
159 int i = 0;
160
161 while (!(zr36050_read_status1(ptr) & 0x4)) {
162 udelay(1);
163 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
164 dprintk(1,
165 "%s: timout at wait_end (last status: 0x%02x)\n",
166 ptr->name, ptr->status1);
167 break;
168 }
169 }
170}
171
172/* =========================================================================
173 Local helper function:
174
175 basic test of "connectivity", writes/reads to/from memory the SOF marker
176 ========================================================================= */
177
178static int
179zr36050_basic_test (struct zr36050 *ptr)
180{
181 zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
182 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
183 if ((zr36050_read(ptr, ZR050_SOF_IDX) |
184 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
185 dprintk(1,
186 KERN_ERR
187 "%s: attach failed, can't connect to jpeg processor!\n",
188 ptr->name);
189 return -ENXIO;
190 }
191 zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
192 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
193 if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
194 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
195 dprintk(1,
196 KERN_ERR
197 "%s: attach failed, can't connect to jpeg processor!\n",
198 ptr->name);
199 return -ENXIO;
200 }
201
202 zr36050_wait_end(ptr);
203 if ((ptr->status1 & 0x4) == 0) {
204 dprintk(1,
205 KERN_ERR
206 "%s: attach failed, jpeg processor failed (end flag)!\n",
207 ptr->name);
208 return -EBUSY;
209 }
210
211 return 0; /* looks good! */
212}
213
214/* =========================================================================
215 Local helper function:
216
217 simple loop for pushing the init datasets
218 ========================================================================= */
219
220static int
221zr36050_pushit (struct zr36050 *ptr,
222 u16 startreg,
223 u16 len,
224 const char *data)
225{
226 int i = 0;
227
228 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
229 startreg, len);
230 while (i < len) {
231 zr36050_write(ptr, startreg++, data[i++]);
232 }
233
234 return i;
235}
236
237/* =========================================================================
238 Basic datasets:
239
240 jpeg baseline setup data (you find it on lots places in internet, or just
241 extract it from any regular .jpg image...)
242
243 Could be variable, but until it's not needed it they are just fixed to save
244 memory. Otherwise expand zr36050 structure with arrays, push the values to
245 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
246 ========================================================================= */
247
248static const char zr36050_dqt[0x86] = {
249 0xff, 0xdb, //Marker: DQT
250 0x00, 0x84, //Length: 2*65+2
251 0x00, //Pq,Tq first table
252 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
253 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
254 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
255 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
256 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
257 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
258 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
259 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
260 0x01, //Pq,Tq second table
261 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
262 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
263 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
264 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
265 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
266 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
267 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
268 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
269};
270
271static const char zr36050_dht[0x1a4] = {
272 0xff, 0xc4, //Marker: DHT
273 0x01, 0xa2, //Length: 2*AC, 2*DC
274 0x00, //DC first table
275 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
276 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
277 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
278 0x01, //DC second table
279 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
280 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
281 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
282 0x10, //AC first table
283 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
284 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
285 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
286 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
287 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
288 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
289 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
290 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
291 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
292 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
293 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
294 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
295 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
296 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
297 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
298 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
299 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
300 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
301 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
302 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
303 0xF8, 0xF9, 0xFA,
304 0x11, //AC second table
305 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
306 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
307 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
308 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
309 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
310 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
311 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
312 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
313 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
314 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
315 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
316 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
317 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
318 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
319 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
320 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
321 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
322 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
323 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
324 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
325 0xF9, 0xFA
326};
327
328/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
329#define NO_OF_COMPONENTS 0x3 //Y,U,V
330#define BASELINE_PRECISION 0x8 //MCU size (?)
331static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
332static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
333static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
334
335/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
336static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
337static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
338
339/* =========================================================================
340 Local helper functions:
341
342 calculation and setup of parameter-dependent JPEG baseline segments
343 (needed for compression only)
344 ========================================================================= */
345
346/* ------------------------------------------------------------------------- */
347
348/* SOF (start of frame) segment depends on width, height and sampling ratio
349 of each color component */
350
351static int
352zr36050_set_sof (struct zr36050 *ptr)
353{
354 char sof_data[34]; // max. size of register set
355 int i;
356
357 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
358 ptr->width, ptr->height, NO_OF_COMPONENTS);
359 sof_data[0] = 0xff;
360 sof_data[1] = 0xc0;
361 sof_data[2] = 0x00;
362 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
363 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050
364 sof_data[5] = (ptr->height) >> 8;
365 sof_data[6] = (ptr->height) & 0xff;
366 sof_data[7] = (ptr->width) >> 8;
367 sof_data[8] = (ptr->width) & 0xff;
368 sof_data[9] = NO_OF_COMPONENTS;
369 for (i = 0; i < NO_OF_COMPONENTS; i++) {
370 sof_data[10 + (i * 3)] = i; // index identifier
371 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
372 sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
373 }
374 return zr36050_pushit(ptr, ZR050_SOF_IDX,
375 (3 * NO_OF_COMPONENTS) + 10, sof_data);
376}
377
378/* ------------------------------------------------------------------------- */
379
380/* SOS (start of scan) segment depends on the used scan components
381 of each color component */
382
383static int
384zr36050_set_sos (struct zr36050 *ptr)
385{
386 char sos_data[16]; // max. size of register set
387 int i;
388
389 dprintk(3, "%s: write SOS\n", ptr->name);
390 sos_data[0] = 0xff;
391 sos_data[1] = 0xda;
392 sos_data[2] = 0x00;
393 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
394 sos_data[4] = NO_OF_COMPONENTS;
395 for (i = 0; i < NO_OF_COMPONENTS; i++) {
396 sos_data[5 + (i * 2)] = i; // index
397 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel.
398 }
399 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
400 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
401 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
402 return zr36050_pushit(ptr, ZR050_SOS1_IDX,
403 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
404 sos_data);
405}
406
407/* ------------------------------------------------------------------------- */
408
409/* DRI (define restart interval) */
410
411static int
412zr36050_set_dri (struct zr36050 *ptr)
413{
414 char dri_data[6]; // max. size of register set
415
416 dprintk(3, "%s: write DRI\n", ptr->name);
417 dri_data[0] = 0xff;
418 dri_data[1] = 0xdd;
419 dri_data[2] = 0x00;
420 dri_data[3] = 0x04;
421 dri_data[4] = ptr->dri >> 8;
422 dri_data[5] = ptr->dri & 0xff;
423 return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
424}
425
426/* =========================================================================
427 Setup function:
428
429 Setup compression/decompression of Zoran's JPEG processor
430 ( see also zoran 36050 manual )
431
432 ... sorry for the spaghetti code ...
433 ========================================================================= */
434static void
435zr36050_init (struct zr36050 *ptr)
436{
437 int sum = 0;
438 long bitcnt, tmp;
439
440 if (ptr->mode == CODEC_DO_COMPRESSION) {
441 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
442
443 /* 050 communicates with 057 in master mode */
444 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
445
446 /* encoding table preload for compression */
447 zr36050_write(ptr, ZR050_MODE,
448 ZR050_MO_COMP | ZR050_MO_TLM);
449 zr36050_write(ptr, ZR050_OPTIONS, 0);
450
451 /* disable all IRQs */
452 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
453 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
454
455 /* volume control settings */
456 /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
457 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
458 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
459
460 zr36050_write(ptr, ZR050_AF_HI, 0xff);
461 zr36050_write(ptr, ZR050_AF_M, 0xff);
462 zr36050_write(ptr, ZR050_AF_LO, 0xff);
463
464 /* setup the variable jpeg tables */
465 sum += zr36050_set_sof(ptr);
466 sum += zr36050_set_sos(ptr);
467 sum += zr36050_set_dri(ptr);
468
469 /* setup the fixed jpeg tables - maybe variable, though -
470 * (see table init section above) */
471 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
472 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
473 sizeof(zr36050_dqt), zr36050_dqt);
474 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
475 sizeof(zr36050_dht), zr36050_dht);
476 zr36050_write(ptr, ZR050_APP_IDX, 0xff);
477 zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
478 zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
479 zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
480 sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
481 ptr->app.data) + 4;
482 zr36050_write(ptr, ZR050_COM_IDX, 0xff);
483 zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
484 zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
485 zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
486 sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
487 ptr->com.data) + 4;
488
489 /* do the internal huffman table preload */
490 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
491
492 zr36050_write(ptr, ZR050_GO, 1); // launch codec
493 zr36050_wait_end(ptr);
494 dprintk(2, "%s: Status after table preload: 0x%02x\n",
495 ptr->name, ptr->status1);
496
497 if ((ptr->status1 & 0x4) == 0) {
498 dprintk(1, KERN_ERR "%s: init aborted!\n",
499 ptr->name);
500 return; // something is wrong, its timed out!!!!
501 }
502
503 /* setup misc. data for compression (target code sizes) */
504
505 /* size of compressed code to reach without header data */
506 sum = ptr->real_code_vol - sum;
507 bitcnt = sum << 3; /* need the size in bits */
508
509 tmp = bitcnt >> 16;
510 dprintk(3,
511 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
512 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
513 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
514 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
515 tmp = bitcnt & 0xffff;
516 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
517 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
518
519 bitcnt -= bitcnt >> 7; // bits without stuffing
520 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
521
522 tmp = bitcnt >> 16;
523 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
524 ptr->name, bitcnt, tmp);
525 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
526 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
527 tmp = bitcnt & 0xffff;
528 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
529 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
530
531 /* compression setup with or without bitrate control */
532 zr36050_write(ptr, ZR050_MODE,
533 ZR050_MO_COMP | ZR050_MO_PASS2 |
534 (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
535
536 /* this headers seem to deliver "valid AVI" jpeg frames */
537 zr36050_write(ptr, ZR050_MARKERS_EN,
538 ZR050_ME_DQT | ZR050_ME_DHT |
539 ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
540 ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
541 } else {
542 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
543
544 /* 050 communicates with 055 in master mode */
545 zr36050_write(ptr, ZR050_HARDWARE,
546 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
547
548 /* encoding table preload */
549 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
550
551 /* disable all IRQs */
552 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
553 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
554
555 dprintk(3, "%s: write DHT\n", ptr->name);
556 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
557 zr36050_dht);
558
559 /* do the internal huffman table preload */
560 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
561
562 zr36050_write(ptr, ZR050_GO, 1); // launch codec
563 zr36050_wait_end(ptr);
564 dprintk(2, "%s: Status after table preload: 0x%02x\n",
565 ptr->name, ptr->status1);
566
567 if ((ptr->status1 & 0x4) == 0) {
568 dprintk(1, KERN_ERR "%s: init aborted!\n",
569 ptr->name);
570 return; // something is wrong, its timed out!!!!
571 }
572
573 /* setup misc. data for expansion */
574 zr36050_write(ptr, ZR050_MODE, 0);
575 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
576 }
577
578 /* adr on selected, to allow GO from master */
579 zr36050_read(ptr, 0);
580}
581
582/* =========================================================================
583 CODEC API FUNCTIONS
584
585 this functions are accessed by the master via the API structure
586 ========================================================================= */
587
588/* set compression/expansion mode and launches codec -
589 this should be the last call from the master before starting processing */
590static int
591zr36050_set_mode (struct videocodec *codec,
592 int mode)
593{
594 struct zr36050 *ptr = (struct zr36050 *) codec->data;
595
596 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
597
598 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
599 return -EINVAL;
600
601 ptr->mode = mode;
602 zr36050_init(ptr);
603
604 return 0;
605}
606
607/* set picture size (norm is ignored as the codec doesn't know about it) */
608static int
609zr36050_set_video (struct videocodec *codec,
610 struct tvnorm *norm,
611 struct vfe_settings *cap,
612 struct vfe_polarity *pol)
613{
614 struct zr36050 *ptr = (struct zr36050 *) codec->data;
615 int size;
616
617 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
618 ptr->name, norm->HStart, norm->VStart,
619 cap->x, cap->y, cap->width, cap->height,
620 cap->decimation, cap->quality);
621 /* if () return -EINVAL;
622 * trust the master driver that it knows what it does - so
623 * we allow invalid startx/y and norm for now ... */
624 ptr->width = cap->width / (cap->decimation & 0xff);
625 ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
626
627 /* (KM) JPEG quality */
628 size = ptr->width * ptr->height;
629 size *= 16; /* size in bits */
630 /* apply quality setting */
631 size = size * cap->quality / 200;
632
633 /* Minimum: 1kb */
634 if (size < 8192)
635 size = 8192;
636 /* Maximum: 7/8 of code buffer */
637 if (size > ptr->total_code_vol * 7)
638 size = ptr->total_code_vol * 7;
639
640 ptr->real_code_vol = size >> 3; /* in bytes */
641
642 /* Set max_block_vol here (previously in zr36050_init, moved
643 * here for consistency with zr36060 code */
644 zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
645
646 return 0;
647}
648
649/* additional control functions */
650static int
651zr36050_control (struct videocodec *codec,
652 int type,
653 int size,
654 void *data)
655{
656 struct zr36050 *ptr = (struct zr36050 *) codec->data;
657 int *ival = (int *) data;
658
659 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
660 size);
661
662 switch (type) {
663 case CODEC_G_STATUS: /* get last status */
664 if (size != sizeof(int))
665 return -EFAULT;
666 zr36050_read_status1(ptr);
667 *ival = ptr->status1;
668 break;
669
670 case CODEC_G_CODEC_MODE:
671 if (size != sizeof(int))
672 return -EFAULT;
673 *ival = CODEC_MODE_BJPG;
674 break;
675
676 case CODEC_S_CODEC_MODE:
677 if (size != sizeof(int))
678 return -EFAULT;
679 if (*ival != CODEC_MODE_BJPG)
680 return -EINVAL;
681 /* not needed, do nothing */
682 return 0;
683
684 case CODEC_G_VFE:
685 case CODEC_S_VFE:
686 /* not needed, do nothing */
687 return 0;
688
689 case CODEC_S_MMAP:
690 /* not available, give an error */
691 return -ENXIO;
692
693 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
694 if (size != sizeof(int))
695 return -EFAULT;
696 *ival = ptr->total_code_vol;
697 break;
698
699 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
700 if (size != sizeof(int))
701 return -EFAULT;
702 ptr->total_code_vol = *ival;
703 /* (Kieran Morrissey)
704 * code copied from zr36060.c to ensure proper bitrate */
705 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
706 break;
707
708 case CODEC_G_JPEG_SCALE: /* get scaling factor */
709 if (size != sizeof(int))
710 return -EFAULT;
711 *ival = zr36050_read_scalefactor(ptr);
712 break;
713
714 case CODEC_S_JPEG_SCALE: /* set scaling factor */
715 if (size != sizeof(int))
716 return -EFAULT;
717 ptr->scalefact = *ival;
718 break;
719
720 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
721 struct jpeg_app_marker *app = data;
722
723 if (size != sizeof(struct jpeg_app_marker))
724 return -EFAULT;
725
726 *app = ptr->app;
727 break;
728 }
729
730 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
731 struct jpeg_app_marker *app = data;
732
733 if (size != sizeof(struct jpeg_app_marker))
734 return -EFAULT;
735
736 ptr->app = *app;
737 break;
738 }
739
740 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
741 struct jpeg_com_marker *com = data;
742
743 if (size != sizeof(struct jpeg_com_marker))
744 return -EFAULT;
745
746 *com = ptr->com;
747 break;
748 }
749
750 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
751 struct jpeg_com_marker *com = data;
752
753 if (size != sizeof(struct jpeg_com_marker))
754 return -EFAULT;
755
756 ptr->com = *com;
757 break;
758 }
759
760 default:
761 return -EINVAL;
762 }
763
764 return size;
765}
766
767/* =========================================================================
768 Exit and unregister function:
769
770 Deinitializes Zoran's JPEG processor
771 ========================================================================= */
772
773static int
774zr36050_unset (struct videocodec *codec)
775{
776 struct zr36050 *ptr = codec->data;
777
778 if (ptr) {
779 /* do wee need some codec deinit here, too ???? */
780
781 dprintk(1, "%s: finished codec #%d\n", ptr->name,
782 ptr->num);
783 kfree(ptr);
784 codec->data = NULL;
785
786 zr36050_codecs--;
787 return 0;
788 }
789
790 return -EFAULT;
791}
792
793/* =========================================================================
794 Setup and registry function:
795
796 Initializes Zoran's JPEG processor
797
798 Also sets pixel size, average code size, mode (compr./decompr.)
799 (the given size is determined by the processor with the video interface)
800 ========================================================================= */
801
802static int
803zr36050_setup (struct videocodec *codec)
804{
805 struct zr36050 *ptr;
806 int res;
807
808 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
809 zr36050_codecs);
810
811 if (zr36050_codecs == MAX_CODECS) {
812 dprintk(1,
813 KERN_ERR "zr36050: Can't attach more codecs!\n");
814 return -ENOSPC;
815 }
816 //mem structure init
817 codec->data = ptr = kmalloc(sizeof(struct zr36050), GFP_KERNEL);
818 if (NULL == ptr) {
819 dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
820 return -ENOMEM;
821 }
822 memset(ptr, 0, sizeof(struct zr36050));
823
824 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
825 zr36050_codecs);
826 ptr->num = zr36050_codecs++;
827 ptr->codec = codec;
828
829 //testing
830 res = zr36050_basic_test(ptr);
831 if (res < 0) {
832 zr36050_unset(codec);
833 return res;
834 }
835 //final setup
836 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
837 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
838
839 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
840 * (what is the difference?) */
841 ptr->mode = CODEC_DO_COMPRESSION;
842 ptr->width = 384;
843 ptr->height = 288;
844 ptr->total_code_vol = 16000;
845 ptr->max_block_vol = 240;
846 ptr->scalefact = 0x100;
847 ptr->dri = 1;
848
849 /* no app/com marker by default */
850 ptr->app.appn = 0;
851 ptr->app.len = 0;
852 ptr->com.len = 0;
853
854 zr36050_init(ptr);
855
856 dprintk(1, KERN_INFO "%s: codec attached and running\n",
857 ptr->name);
858
859 return 0;
860}
861
862static const struct videocodec zr36050_codec = {
863 .owner = THIS_MODULE,
864 .name = "zr36050",
865 .magic = 0L, // magic not used
866 .flags =
867 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
868 CODEC_FLAG_DECODER,
869 .type = CODEC_TYPE_ZR36050,
870 .setup = zr36050_setup, // functionality
871 .unset = zr36050_unset,
872 .set_mode = zr36050_set_mode,
873 .set_video = zr36050_set_video,
874 .control = zr36050_control,
875 // others are not used
876};
877
878/* =========================================================================
879 HOOK IN DRIVER AS KERNEL MODULE
880 ========================================================================= */
881
882static int __init
883zr36050_init_module (void)
884{
885 //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
886 zr36050_codecs = 0;
887 return videocodec_register(&zr36050_codec);
888}
889
890static void __exit
891zr36050_cleanup_module (void)
892{
893 if (zr36050_codecs) {
894 dprintk(1,
895 "zr36050: something's wrong - %d codecs left somehow.\n",
896 zr36050_codecs);
897 }
898 videocodec_unregister(&zr36050_codec);
899}
900
901module_init(zr36050_init_module);
902module_exit(zr36050_cleanup_module);
903
904MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
905MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
906 ZR050_VERSION);
907MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36050.h b/drivers/media/video/zr36050.h
new file mode 100644
index 000000000000..9f52f0cdde50
--- /dev/null
+++ b/drivers/media/video/zr36050.h
@@ -0,0 +1,184 @@
1/*
2 * Zoran ZR36050 basic configuration functions - header file
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36050.h,v 1.1.2.2 2003/01/14 21:18:22 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36050_H
28#define ZR36050_H
29
30#include "videocodec.h"
31
32/* data stored for each zoran jpeg codec chip */
33struct zr36050 {
34 char name[32];
35 int num;
36 /* io datastructure */
37 struct videocodec *codec;
38 // last coder status
39 __u8 status1;
40 // actual coder setup
41 int mode;
42
43 __u16 width;
44 __u16 height;
45
46 __u16 bitrate_ctrl;
47
48 __u32 total_code_vol;
49 __u32 real_code_vol;
50 __u16 max_block_vol;
51
52 __u8 h_samp_ratio[8];
53 __u8 v_samp_ratio[8];
54 __u16 scalefact;
55 __u16 dri;
56
57 /* com/app marker */
58 struct jpeg_com_marker com;
59 struct jpeg_app_marker app;
60};
61
62/* zr36050 register addresses */
63#define ZR050_GO 0x000
64#define ZR050_HARDWARE 0x002
65#define ZR050_MODE 0x003
66#define ZR050_OPTIONS 0x004
67#define ZR050_MBCV 0x005
68#define ZR050_MARKERS_EN 0x006
69#define ZR050_INT_REQ_0 0x007
70#define ZR050_INT_REQ_1 0x008
71#define ZR050_TCV_NET_HI 0x009
72#define ZR050_TCV_NET_MH 0x00a
73#define ZR050_TCV_NET_ML 0x00b
74#define ZR050_TCV_NET_LO 0x00c
75#define ZR050_TCV_DATA_HI 0x00d
76#define ZR050_TCV_DATA_MH 0x00e
77#define ZR050_TCV_DATA_ML 0x00f
78#define ZR050_TCV_DATA_LO 0x010
79#define ZR050_SF_HI 0x011
80#define ZR050_SF_LO 0x012
81#define ZR050_AF_HI 0x013
82#define ZR050_AF_M 0x014
83#define ZR050_AF_LO 0x015
84#define ZR050_ACV_HI 0x016
85#define ZR050_ACV_MH 0x017
86#define ZR050_ACV_ML 0x018
87#define ZR050_ACV_LO 0x019
88#define ZR050_ACT_HI 0x01a
89#define ZR050_ACT_MH 0x01b
90#define ZR050_ACT_ML 0x01c
91#define ZR050_ACT_LO 0x01d
92#define ZR050_ACV_TRUN_HI 0x01e
93#define ZR050_ACV_TRUN_MH 0x01f
94#define ZR050_ACV_TRUN_ML 0x020
95#define ZR050_ACV_TRUN_LO 0x021
96#define ZR050_STATUS_0 0x02e
97#define ZR050_STATUS_1 0x02f
98
99#define ZR050_SOF_IDX 0x040
100#define ZR050_SOS1_IDX 0x07a
101#define ZR050_SOS2_IDX 0x08a
102#define ZR050_SOS3_IDX 0x09a
103#define ZR050_SOS4_IDX 0x0aa
104#define ZR050_DRI_IDX 0x0c0
105#define ZR050_DNL_IDX 0x0c6
106#define ZR050_DQT_IDX 0x0cc
107#define ZR050_DHT_IDX 0x1d4
108#define ZR050_APP_IDX 0x380
109#define ZR050_COM_IDX 0x3c0
110
111/* zr36050 hardware register bits */
112
113#define ZR050_HW_BSWD 0x80
114#define ZR050_HW_MSTR 0x40
115#define ZR050_HW_DMA 0x20
116#define ZR050_HW_CFIS_1_CLK 0x00
117#define ZR050_HW_CFIS_2_CLK 0x04
118#define ZR050_HW_CFIS_3_CLK 0x08
119#define ZR050_HW_CFIS_4_CLK 0x0C
120#define ZR050_HW_CFIS_5_CLK 0x10
121#define ZR050_HW_CFIS_6_CLK 0x14
122#define ZR050_HW_CFIS_7_CLK 0x18
123#define ZR050_HW_CFIS_8_CLK 0x1C
124#define ZR050_HW_BELE 0x01
125
126/* zr36050 mode register bits */
127
128#define ZR050_MO_COMP 0x80
129#define ZR050_MO_COMP 0x80
130#define ZR050_MO_ATP 0x40
131#define ZR050_MO_PASS2 0x20
132#define ZR050_MO_TLM 0x10
133#define ZR050_MO_DCONLY 0x08
134#define ZR050_MO_BRC 0x04
135
136#define ZR050_MO_ATP 0x40
137#define ZR050_MO_PASS2 0x20
138#define ZR050_MO_TLM 0x10
139#define ZR050_MO_DCONLY 0x08
140
141/* zr36050 option register bits */
142
143#define ZR050_OP_NSCN_1 0x00
144#define ZR050_OP_NSCN_2 0x20
145#define ZR050_OP_NSCN_3 0x40
146#define ZR050_OP_NSCN_4 0x60
147#define ZR050_OP_NSCN_5 0x80
148#define ZR050_OP_NSCN_6 0xA0
149#define ZR050_OP_NSCN_7 0xC0
150#define ZR050_OP_NSCN_8 0xE0
151#define ZR050_OP_OVF 0x10
152
153
154/* zr36050 markers-enable register bits */
155
156#define ZR050_ME_APP 0x80
157#define ZR050_ME_COM 0x40
158#define ZR050_ME_DRI 0x20
159#define ZR050_ME_DQT 0x10
160#define ZR050_ME_DHT 0x08
161#define ZR050_ME_DNL 0x04
162#define ZR050_ME_DQTI 0x02
163#define ZR050_ME_DHTI 0x01
164
165/* zr36050 status0/1 register bit masks */
166
167#define ZR050_ST_RST_MASK 0x20
168#define ZR050_ST_SOF_MASK 0x02
169#define ZR050_ST_SOS_MASK 0x02
170#define ZR050_ST_DATRDY_MASK 0x80
171#define ZR050_ST_MRKDET_MASK 0x40
172#define ZR050_ST_RFM_MASK 0x10
173#define ZR050_ST_RFD_MASK 0x08
174#define ZR050_ST_END_MASK 0x04
175#define ZR050_ST_TCVOVF_MASK 0x02
176#define ZR050_ST_DATOVF_MASK 0x01
177
178/* pixel component idx */
179
180#define ZR050_Y_COMPONENT 0
181#define ZR050_U_COMPONENT 1
182#define ZR050_V_COMPONENT 2
183
184#endif /*fndef ZR36050_H */
diff --git a/drivers/media/video/zr36057.h b/drivers/media/video/zr36057.h
new file mode 100644
index 000000000000..159abfa034d9
--- /dev/null
+++ b/drivers/media/video/zr36057.h
@@ -0,0 +1,168 @@
1/*
2 * zr36057.h - zr36057 register offsets
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
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
21#ifndef _ZR36057_H_
22#define _ZR36057_H_
23
24
25/* Zoran ZR36057 registers */
26
27#define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */
28#define ZR36057_VFEHCR_HSPol (1<<30)
29#define ZR36057_VFEHCR_HStart 10
30#define ZR36057_VFEHCR_HEnd 0
31#define ZR36057_VFEHCR_Hmask 0x3ff
32
33#define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */
34#define ZR36057_VFEVCR_VSPol (1<<30)
35#define ZR36057_VFEVCR_VStart 10
36#define ZR36057_VFEVCR_VEnd 0
37#define ZR36057_VFEVCR_Vmask 0x3ff
38
39#define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */
40#define ZR36057_VFESPFR_ExtFl (1<<26)
41#define ZR36057_VFESPFR_TopField (1<<25)
42#define ZR36057_VFESPFR_VCLKPol (1<<24)
43#define ZR36057_VFESPFR_HFilter 21
44#define ZR36057_VFESPFR_HorDcm 14
45#define ZR36057_VFESPFR_VerDcm 8
46#define ZR36057_VFESPFR_DispMode 6
47#define ZR36057_VFESPFR_YUV422 (0<<3)
48#define ZR36057_VFESPFR_RGB888 (1<<3)
49#define ZR36057_VFESPFR_RGB565 (2<<3)
50#define ZR36057_VFESPFR_RGB555 (3<<3)
51#define ZR36057_VFESPFR_ErrDif (1<<2)
52#define ZR36057_VFESPFR_Pack24 (1<<1)
53#define ZR36057_VFESPFR_LittleEndian (1<<0)
54
55#define ZR36057_VDTR 0x00c /* Video Display "Top" Register */
56
57#define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */
58
59#define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */
60#define ZR36057_VSSFGR_DispStride 16
61#define ZR36057_VSSFGR_VidOvf (1<<8)
62#define ZR36057_VSSFGR_SnapShot (1<<1)
63#define ZR36057_VSSFGR_FrameGrab (1<<0)
64
65#define ZR36057_VDCR 0x018 /* Video Display Configuration Register */
66#define ZR36057_VDCR_VidEn (1<<31)
67#define ZR36057_VDCR_MinPix 24
68#define ZR36057_VDCR_Triton (1<<24)
69#define ZR36057_VDCR_VidWinHt 12
70#define ZR36057_VDCR_VidWinWid 0
71
72#define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */
73
74#define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */
75
76#define ZR36057_OCR 0x024 /* Overlay Control Register */
77#define ZR36057_OCR_OvlEnable (1 << 15)
78#define ZR36057_OCR_MaskStride 0
79
80#define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */
81#define ZR36057_SPGPPCR_SoftReset (1<<24)
82
83#define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */
84
85#define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */
86
87#define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */
88#define ZR36057_MCTCR_CodTime (1 << 30)
89#define ZR36057_MCTCR_CEmpty (1 << 29)
90#define ZR36057_MCTCR_CFlush (1 << 28)
91#define ZR36057_MCTCR_CodGuestID 20
92#define ZR36057_MCTCR_CodGuestReg 16
93
94#define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */
95
96#define ZR36057_ISR 0x03c /* Interrupt Status Register */
97#define ZR36057_ISR_GIRQ1 (1<<30)
98#define ZR36057_ISR_GIRQ0 (1<<29)
99#define ZR36057_ISR_CodRepIRQ (1<<28)
100#define ZR36057_ISR_JPEGRepIRQ (1<<27)
101
102#define ZR36057_ICR 0x040 /* Interrupt Control Register */
103#define ZR36057_ICR_GIRQ1 (1<<30)
104#define ZR36057_ICR_GIRQ0 (1<<29)
105#define ZR36057_ICR_CodRepIRQ (1<<28)
106#define ZR36057_ICR_JPEGRepIRQ (1<<27)
107#define ZR36057_ICR_IntPinEn (1<<24)
108
109#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
110#define ZR36057_I2CBR_SDA (1<<1)
111#define ZR36057_I2CBR_SCL (1<<0)
112
113#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
114#define ZR36057_JMC_JPG (1 << 31)
115#define ZR36057_JMC_JPGExpMode (0 << 29)
116#define ZR36057_JMC_JPGCmpMode (1 << 29)
117#define ZR36057_JMC_MJPGExpMode (2 << 29)
118#define ZR36057_JMC_MJPGCmpMode (3 << 29)
119#define ZR36057_JMC_RTBUSY_FB (1 << 6)
120#define ZR36057_JMC_Go_en (1 << 5)
121#define ZR36057_JMC_SyncMstr (1 << 4)
122#define ZR36057_JMC_Fld_per_buff (1 << 3)
123#define ZR36057_JMC_VFIFO_FB (1 << 2)
124#define ZR36057_JMC_CFIFO_FB (1 << 1)
125#define ZR36057_JMC_Stll_LitEndian (1 << 0)
126
127#define ZR36057_JPC 0x104 /* JPEG Process Control */
128#define ZR36057_JPC_P_Reset (1 << 7)
129#define ZR36057_JPC_CodTrnsEn (1 << 5)
130#define ZR36057_JPC_Active (1 << 0)
131
132#define ZR36057_VSP 0x108 /* Vertical Sync Parameters */
133#define ZR36057_VSP_VsyncSize 16
134#define ZR36057_VSP_FrmTot 0
135
136#define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */
137#define ZR36057_HSP_HsyncStart 16
138#define ZR36057_HSP_LineTot 0
139
140#define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */
141#define ZR36057_FHAP_NAX 16
142#define ZR36057_FHAP_PAX 0
143
144#define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */
145#define ZR36057_FVAP_NAY 16
146#define ZR36057_FVAP_PAY 0
147
148#define ZR36057_FPP 0x118 /* Field Process Parameters */
149#define ZR36057_FPP_Odd_Even (1 << 0)
150
151#define ZR36057_JCBA 0x11c /* JPEG Code Base Address */
152
153#define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */
154
155#define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */
156#define ZR36057_JCGI_JPEGuestID 4
157#define ZR36057_JCGI_JPEGuestReg 0
158
159#define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */
160
161#define ZR36057_POR 0x200 /* Post Office Register */
162#define ZR36057_POR_POPen (1<<25)
163#define ZR36057_POR_POTime (1<<24)
164#define ZR36057_POR_PODir (1<<23)
165
166#define ZR36057_STR 0x300 /* "Still" Transfer Register */
167
168#endif
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
new file mode 100644
index 000000000000..b50dc403e6db
--- /dev/null
+++ b/drivers/media/video/zr36060.c
@@ -0,0 +1,1016 @@
1/*
2 * Zoran ZR36060 basic configuration functions
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR060_VERSION "v0.7"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* headerfile of this module */
46#include"zr36060.h"
47
48/* codec io API */
49#include"videocodec.h"
50
51/* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
53#define MAX_CODECS 20
54
55/* amount of chips attached via this driver */
56static int zr36060_codecs = 0;
57
58static int low_bitrate = 0;
59module_param(low_bitrate, bool, 0);
60MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
61
62/* debugging is available via module parameter */
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-4)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* =========================================================================
74 Local hardware I/O functions:
75
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
78
79/* read and write functions */
80static u8
81zr36060_read (struct zr36060 *ptr,
82 u16 reg)
83{
84 u8 value = 0;
85
86 // just in case something is wrong...
87 if (ptr->codec->master_data->readreg)
88 value = (ptr->codec->master_data->readreg(ptr->codec,
89 reg)) & 0xff;
90 else
91 dprintk(1,
92 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
93 ptr->name);
94
95 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
96
97 return value;
98}
99
100static void
101zr36060_write(struct zr36060 *ptr,
102 u16 reg,
103 u8 value)
104{
105 //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg);
106 dprintk(4, "0x%02x @0x%04x\n", value, reg);
107
108 // just in case something is wrong...
109 if (ptr->codec->master_data->writereg)
110 ptr->codec->master_data->writereg(ptr->codec, reg, value);
111 else
112 dprintk(1,
113 KERN_ERR
114 "%s: invalid I/O setup, nothing written!\n",
115 ptr->name);
116}
117
118/* =========================================================================
119 Local helper function:
120
121 status read
122 ========================================================================= */
123
124/* status is kept in datastructure */
125static u8
126zr36060_read_status (struct zr36060 *ptr)
127{
128 ptr->status = zr36060_read(ptr, ZR060_CFSR);
129
130 zr36060_read(ptr, 0);
131 return ptr->status;
132}
133
134/* =========================================================================
135 Local helper function:
136
137 scale factor read
138 ========================================================================= */
139
140/* scale factor is kept in datastructure */
141static u16
142zr36060_read_scalefactor (struct zr36060 *ptr)
143{
144 ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
145 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
146
147 /* leave 0 selected for an eventually GO from master */
148 zr36060_read(ptr, 0);
149 return ptr->scalefact;
150}
151
152/* =========================================================================
153 Local helper function:
154
155 wait if codec is ready to proceed (end of processing) or time is over
156 ========================================================================= */
157
158static void
159zr36060_wait_end (struct zr36060 *ptr)
160{
161 int i = 0;
162
163 while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
164 udelay(1);
165 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
166 dprintk(1,
167 "%s: timout at wait_end (last status: 0x%02x)\n",
168 ptr->name, ptr->status);
169 break;
170 }
171 }
172}
173
174/* =========================================================================
175 Local helper function:
176
177 basic test of "connectivity", writes/reads to/from memory the SOF marker
178 ========================================================================= */
179
180static int
181zr36060_basic_test (struct zr36060 *ptr)
182{
183 if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
184 (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
185 dprintk(1,
186 KERN_ERR
187 "%s: attach failed, can't connect to jpeg processor!\n",
188 ptr->name);
189 return -ENXIO;
190 }
191
192 zr36060_wait_end(ptr);
193 if (ptr->status & ZR060_CFSR_Busy) {
194 dprintk(1,
195 KERN_ERR
196 "%s: attach failed, jpeg processor failed (end flag)!\n",
197 ptr->name);
198 return -EBUSY;
199 }
200
201 return 0; /* looks good! */
202}
203
204/* =========================================================================
205 Local helper function:
206
207 simple loop for pushing the init datasets
208 ========================================================================= */
209
210static int
211zr36060_pushit (struct zr36060 *ptr,
212 u16 startreg,
213 u16 len,
214 const char *data)
215{
216 int i = 0;
217
218 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
219 startreg, len);
220 while (i < len) {
221 zr36060_write(ptr, startreg++, data[i++]);
222 }
223
224 return i;
225}
226
227/* =========================================================================
228 Basic datasets:
229
230 jpeg baseline setup data (you find it on lots places in internet, or just
231 extract it from any regular .jpg image...)
232
233 Could be variable, but until it's not needed it they are just fixed to save
234 memory. Otherwise expand zr36060 structure with arrays, push the values to
235 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
236 ========================================================================= */
237
238static const char zr36060_dqt[0x86] = {
239 0xff, 0xdb, //Marker: DQT
240 0x00, 0x84, //Length: 2*65+2
241 0x00, //Pq,Tq first table
242 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
243 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
244 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
245 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
246 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
247 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
248 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
249 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
250 0x01, //Pq,Tq second table
251 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
252 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
253 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
254 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
255 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
256 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
257 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
258 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
259};
260
261static const char zr36060_dht[0x1a4] = {
262 0xff, 0xc4, //Marker: DHT
263 0x01, 0xa2, //Length: 2*AC, 2*DC
264 0x00, //DC first table
265 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
266 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
267 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
268 0x01, //DC second table
269 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
270 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
271 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
272 0x10, //AC first table
273 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
274 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
275 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
276 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
277 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
278 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
279 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
280 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
281 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
282 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
283 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
284 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
285 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
286 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
287 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
288 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
289 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
290 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
291 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
292 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
293 0xF8, 0xF9, 0xFA,
294 0x11, //AC second table
295 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
296 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
297 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
298 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
299 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
300 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
301 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
302 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
303 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
304 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
305 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
306 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
307 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
308 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
309 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
310 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
311 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
312 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
313 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
314 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
315 0xF9, 0xFA
316};
317
318/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
319#define NO_OF_COMPONENTS 0x3 //Y,U,V
320#define BASELINE_PRECISION 0x8 //MCU size (?)
321static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
322static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
323static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
324
325/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
326static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
327static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
328
329/* =========================================================================
330 Local helper functions:
331
332 calculation and setup of parameter-dependent JPEG baseline segments
333 (needed for compression only)
334 ========================================================================= */
335
336/* ------------------------------------------------------------------------- */
337
338/* SOF (start of frame) segment depends on width, height and sampling ratio
339 of each color component */
340
341static int
342zr36060_set_sof (struct zr36060 *ptr)
343{
344 char sof_data[34]; // max. size of register set
345 int i;
346
347 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
348 ptr->width, ptr->height, NO_OF_COMPONENTS);
349 sof_data[0] = 0xff;
350 sof_data[1] = 0xc0;
351 sof_data[2] = 0x00;
352 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
353 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060
354 sof_data[5] = (ptr->height) >> 8;
355 sof_data[6] = (ptr->height) & 0xff;
356 sof_data[7] = (ptr->width) >> 8;
357 sof_data[8] = (ptr->width) & 0xff;
358 sof_data[9] = NO_OF_COMPONENTS;
359 for (i = 0; i < NO_OF_COMPONENTS; i++) {
360 sof_data[10 + (i * 3)] = i; // index identifier
361 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
362 (ptr->v_samp_ratio[i]); // sampling ratios
363 sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
364 }
365 return zr36060_pushit(ptr, ZR060_SOF_IDX,
366 (3 * NO_OF_COMPONENTS) + 10, sof_data);
367}
368
369/* ------------------------------------------------------------------------- */
370
371/* SOS (start of scan) segment depends on the used scan components
372 of each color component */
373
374static int
375zr36060_set_sos (struct zr36060 *ptr)
376{
377 char sos_data[16]; // max. size of register set
378 int i;
379
380 dprintk(3, "%s: write SOS\n", ptr->name);
381 sos_data[0] = 0xff;
382 sos_data[1] = 0xda;
383 sos_data[2] = 0x00;
384 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
385 sos_data[4] = NO_OF_COMPONENTS;
386 for (i = 0; i < NO_OF_COMPONENTS; i++) {
387 sos_data[5 + (i * 2)] = i; // index
388 sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
389 zr36060_ta[i]; // AC/DC tbl.sel.
390 }
391 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
392 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
393 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
394 return zr36060_pushit(ptr, ZR060_SOS_IDX,
395 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
396 sos_data);
397}
398
399/* ------------------------------------------------------------------------- */
400
401/* DRI (define restart interval) */
402
403static int
404zr36060_set_dri (struct zr36060 *ptr)
405{
406 char dri_data[6]; // max. size of register set
407
408 dprintk(3, "%s: write DRI\n", ptr->name);
409 dri_data[0] = 0xff;
410 dri_data[1] = 0xdd;
411 dri_data[2] = 0x00;
412 dri_data[3] = 0x04;
413 dri_data[4] = (ptr->dri) >> 8;
414 dri_data[5] = (ptr->dri) & 0xff;
415 return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
416}
417
418/* =========================================================================
419 Setup function:
420
421 Setup compression/decompression of Zoran's JPEG processor
422 ( see also zoran 36060 manual )
423
424 ... sorry for the spaghetti code ...
425 ========================================================================= */
426static void
427zr36060_init (struct zr36060 *ptr)
428{
429 int sum = 0;
430 long bitcnt, tmp;
431
432 if (ptr->mode == CODEC_DO_COMPRESSION) {
433 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
434
435 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
436
437 /* 060 communicates with 067 in master mode */
438 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
439
440 /* Compression with or without variable scale factor */
441 /*FIXME: What about ptr->bitrate_ctrl? */
442 zr36060_write(ptr, ZR060_CMR,
443 ZR060_CMR_Comp | ZR060_CMR_Pass2 |
444 ZR060_CMR_BRB);
445
446 /* Must be zero */
447 zr36060_write(ptr, ZR060_MBZ, 0x00);
448 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
449 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
450
451 /* Disable all IRQs - no DataErr means autoreset */
452 zr36060_write(ptr, ZR060_IMR, 0);
453
454 /* volume control settings */
455 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
456 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
457
458 zr36060_write(ptr, ZR060_AF_HI, 0xff);
459 zr36060_write(ptr, ZR060_AF_M, 0xff);
460 zr36060_write(ptr, ZR060_AF_LO, 0xff);
461
462 /* setup the variable jpeg tables */
463 sum += zr36060_set_sof(ptr);
464 sum += zr36060_set_sos(ptr);
465 sum += zr36060_set_dri(ptr);
466
467 /* setup the fixed jpeg tables - maybe variable, though -
468 * (see table init section above) */
469 sum +=
470 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
471 zr36060_dqt);
472 sum +=
473 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
474 zr36060_dht);
475 zr36060_write(ptr, ZR060_APP_IDX, 0xff);
476 zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
477 zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
478 zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
479 sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
480 ptr->app.data) + 4;
481 zr36060_write(ptr, ZR060_COM_IDX, 0xff);
482 zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
483 zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
484 zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
485 sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
486 ptr->com.data) + 4;
487
488 /* setup misc. data for compression (target code sizes) */
489
490 /* size of compressed code to reach without header data */
491 sum = ptr->real_code_vol - sum;
492 bitcnt = sum << 3; /* need the size in bits */
493
494 tmp = bitcnt >> 16;
495 dprintk(3,
496 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
497 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
498 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
499 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
500 tmp = bitcnt & 0xffff;
501 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
502 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
503
504 bitcnt -= bitcnt >> 7; // bits without stuffing
505 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
506
507 tmp = bitcnt >> 16;
508 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
509 ptr->name, bitcnt, tmp);
510 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
511 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
512 tmp = bitcnt & 0xffff;
513 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
514 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
515
516 /* JPEG markers to be included in the compressed stream */
517 zr36060_write(ptr, ZR060_MER,
518 ZR060_MER_DQT | ZR060_MER_DHT |
519 ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
520 ((ptr->app.len > 0) ? ZR060_MER_App : 0));
521
522 /* Setup the Video Frontend */
523 /* Limit pixel range to 16..235 as per CCIR-601 */
524 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
525
526 } else {
527 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
528
529 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
530
531 /* 060 communicates with 067 in master mode */
532 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
533
534 /* Decompression */
535 zr36060_write(ptr, ZR060_CMR, 0);
536
537 /* Must be zero */
538 zr36060_write(ptr, ZR060_MBZ, 0x00);
539 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
540 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
541
542 /* Disable all IRQs - no DataErr means autoreset */
543 zr36060_write(ptr, ZR060_IMR, 0);
544
545 /* setup misc. data for expansion */
546 zr36060_write(ptr, ZR060_MER, 0);
547
548 /* setup the fixed jpeg tables - maybe variable, though -
549 * (see table init section above) */
550 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
551 zr36060_dht);
552
553 /* Setup the Video Frontend */
554 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
555 //this doesn't seem right and doesn't work...
556 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
557 }
558
559 /* Load the tables */
560 zr36060_write(ptr, ZR060_LOAD,
561 ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
562 zr36060_wait_end(ptr);
563 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
564 ptr->status);
565
566 if (ptr->status & ZR060_CFSR_Busy) {
567 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
568 return; // something is wrong, its timed out!!!!
569 }
570}
571
572/* =========================================================================
573 CODEC API FUNCTIONS
574
575 this functions are accessed by the master via the API structure
576 ========================================================================= */
577
578/* set compression/expansion mode and launches codec -
579 this should be the last call from the master before starting processing */
580static int
581zr36060_set_mode (struct videocodec *codec,
582 int mode)
583{
584 struct zr36060 *ptr = (struct zr36060 *) codec->data;
585
586 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
587
588 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
589 return -EINVAL;
590
591 ptr->mode = mode;
592 zr36060_init(ptr);
593
594 return 0;
595}
596
597/* set picture size (norm is ignored as the codec doesn't know about it) */
598static int
599zr36060_set_video (struct videocodec *codec,
600 struct tvnorm *norm,
601 struct vfe_settings *cap,
602 struct vfe_polarity *pol)
603{
604 struct zr36060 *ptr = (struct zr36060 *) codec->data;
605 u32 reg;
606 int size;
607
608 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
609 cap->x, cap->y, cap->width, cap->height, cap->decimation);
610
611 /* if () return -EINVAL;
612 * trust the master driver that it knows what it does - so
613 * we allow invalid startx/y and norm for now ... */
614 ptr->width = cap->width / (cap->decimation & 0xff);
615 ptr->height = cap->height / (cap->decimation >> 8);
616
617 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
618
619 /* Note that VSPol/HSPol bits in zr36060 have the opposite
620 * meaning of their zr360x7 counterparts with the same names
621 * N.b. for VSPol this is only true if FIVEdge = 0 (default,
622 * left unchanged here - in accordance with datasheet).
623 */
624 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
625 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
626 | (pol->field_pol ? ZR060_VPR_FIPol : 0)
627 | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
628 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
629 | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
630 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
631 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
632 zr36060_write(ptr, ZR060_VPR, reg);
633
634 reg = 0;
635 switch (cap->decimation & 0xff) {
636 default:
637 case 1:
638 break;
639
640 case 2:
641 reg |= ZR060_SR_HScale2;
642 break;
643
644 case 4:
645 reg |= ZR060_SR_HScale4;
646 break;
647 }
648
649 switch (cap->decimation >> 8) {
650 default:
651 case 1:
652 break;
653
654 case 2:
655 reg |= ZR060_SR_VScale;
656 break;
657 }
658 zr36060_write(ptr, ZR060_SR, reg);
659
660 zr36060_write(ptr, ZR060_BCR_Y, 0x00);
661 zr36060_write(ptr, ZR060_BCR_U, 0x80);
662 zr36060_write(ptr, ZR060_BCR_V, 0x80);
663
664 /* sync generator */
665
666 reg = norm->Ht - 1; /* Vtotal */
667 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
668 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
669
670 reg = norm->Wt - 1; /* Htotal */
671 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
672 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
673
674 reg = 6 - 1; /* VsyncSize */
675 zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
676
677 //reg = 30 - 1; /* HsyncSize */
678///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
679 reg = 68;
680 zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
681
682 reg = norm->VStart - 1; /* BVstart */
683 zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
684
685 reg += norm->Ha / 2; /* BVend */
686 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
687 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
688
689 reg = norm->HStart - 1; /* BHstart */
690 zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
691
692 reg += norm->Wa; /* BHend */
693 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
694 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
695
696 /* active area */
697 reg = cap->y + norm->VStart; /* Vstart */
698 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
699 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
700
701 reg += cap->height; /* Vend */
702 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
703 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
704
705 reg = cap->x + norm->HStart; /* Hstart */
706 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
707 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
708
709 reg += cap->width; /* Hend */
710 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
711 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
712
713 /* subimage area */
714 reg = norm->VStart - 4; /* SVstart */
715 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
716 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
717
718 reg += norm->Ha / 2 + 8; /* SVend */
719 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
720 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
721
722 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */
723 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
724 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
725
726 reg += norm->Wa + 8; /* SHend */
727 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
728 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
729
730 size = ptr->width * ptr->height;
731 /* Target compressed field size in bits: */
732 size = size * 16; /* uncompressed size in bits */
733 /* (Ronald) by default, quality = 100 is a compression
734 * ratio 1:2. Setting low_bitrate (insmod option) sets
735 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
736 * buz can't handle more at decimation=1... Use low_bitrate if
737 * you have a Buz, unless you know what you're doing */
738 size = size * cap->quality / (low_bitrate ? 400 : 200);
739 /* Lower limit (arbitrary, 1 KB) */
740 if (size < 8192)
741 size = 8192;
742 /* Upper limit: 7/8 of the code buffers */
743 if (size > ptr->total_code_vol * 7)
744 size = ptr->total_code_vol * 7;
745
746 ptr->real_code_vol = size >> 3; /* in bytes */
747
748 /* the MBCVR is the *maximum* block volume, according to the
749 * JPEG ISO specs, this shouldn't be used, since that allows
750 * for the best encoding quality. So set it to it's max value */
751 reg = ptr->max_block_vol;
752 zr36060_write(ptr, ZR060_MBCVR, reg);
753
754 return 0;
755}
756
757/* additional control functions */
758static int
759zr36060_control (struct videocodec *codec,
760 int type,
761 int size,
762 void *data)
763{
764 struct zr36060 *ptr = (struct zr36060 *) codec->data;
765 int *ival = (int *) data;
766
767 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
768 size);
769
770 switch (type) {
771 case CODEC_G_STATUS: /* get last status */
772 if (size != sizeof(int))
773 return -EFAULT;
774 zr36060_read_status(ptr);
775 *ival = ptr->status;
776 break;
777
778 case CODEC_G_CODEC_MODE:
779 if (size != sizeof(int))
780 return -EFAULT;
781 *ival = CODEC_MODE_BJPG;
782 break;
783
784 case CODEC_S_CODEC_MODE:
785 if (size != sizeof(int))
786 return -EFAULT;
787 if (*ival != CODEC_MODE_BJPG)
788 return -EINVAL;
789 /* not needed, do nothing */
790 return 0;
791
792 case CODEC_G_VFE:
793 case CODEC_S_VFE:
794 /* not needed, do nothing */
795 return 0;
796
797 case CODEC_S_MMAP:
798 /* not available, give an error */
799 return -ENXIO;
800
801 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
802 if (size != sizeof(int))
803 return -EFAULT;
804 *ival = ptr->total_code_vol;
805 break;
806
807 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
808 if (size != sizeof(int))
809 return -EFAULT;
810 ptr->total_code_vol = *ival;
811 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
812 break;
813
814 case CODEC_G_JPEG_SCALE: /* get scaling factor */
815 if (size != sizeof(int))
816 return -EFAULT;
817 *ival = zr36060_read_scalefactor(ptr);
818 break;
819
820 case CODEC_S_JPEG_SCALE: /* set scaling factor */
821 if (size != sizeof(int))
822 return -EFAULT;
823 ptr->scalefact = *ival;
824 break;
825
826 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
827 struct jpeg_app_marker *app = data;
828
829 if (size != sizeof(struct jpeg_app_marker))
830 return -EFAULT;
831
832 *app = ptr->app;
833 break;
834 }
835
836 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
837 struct jpeg_app_marker *app = data;
838
839 if (size != sizeof(struct jpeg_app_marker))
840 return -EFAULT;
841
842 ptr->app = *app;
843 break;
844 }
845
846 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
847 struct jpeg_com_marker *com = data;
848
849 if (size != sizeof(struct jpeg_com_marker))
850 return -EFAULT;
851
852 *com = ptr->com;
853 break;
854 }
855
856 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
857 struct jpeg_com_marker *com = data;
858
859 if (size != sizeof(struct jpeg_com_marker))
860 return -EFAULT;
861
862 ptr->com = *com;
863 break;
864 }
865
866 default:
867 return -EINVAL;
868 }
869
870 return size;
871}
872
873/* =========================================================================
874 Exit and unregister function:
875
876 Deinitializes Zoran's JPEG processor
877 ========================================================================= */
878
879static int
880zr36060_unset (struct videocodec *codec)
881{
882 struct zr36060 *ptr = codec->data;
883
884 if (ptr) {
885 /* do wee need some codec deinit here, too ???? */
886
887 dprintk(1, "%s: finished codec #%d\n", ptr->name,
888 ptr->num);
889 kfree(ptr);
890 codec->data = NULL;
891
892 zr36060_codecs--;
893 return 0;
894 }
895
896 return -EFAULT;
897}
898
899/* =========================================================================
900 Setup and registry function:
901
902 Initializes Zoran's JPEG processor
903
904 Also sets pixel size, average code size, mode (compr./decompr.)
905 (the given size is determined by the processor with the video interface)
906 ========================================================================= */
907
908static int
909zr36060_setup (struct videocodec *codec)
910{
911 struct zr36060 *ptr;
912 int res;
913
914 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
915 zr36060_codecs);
916
917 if (zr36060_codecs == MAX_CODECS) {
918 dprintk(1,
919 KERN_ERR "zr36060: Can't attach more codecs!\n");
920 return -ENOSPC;
921 }
922 //mem structure init
923 codec->data = ptr = kmalloc(sizeof(struct zr36060), GFP_KERNEL);
924 if (NULL == ptr) {
925 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
926 return -ENOMEM;
927 }
928 memset(ptr, 0, sizeof(struct zr36060));
929
930 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
931 zr36060_codecs);
932 ptr->num = zr36060_codecs++;
933 ptr->codec = codec;
934
935 //testing
936 res = zr36060_basic_test(ptr);
937 if (res < 0) {
938 zr36060_unset(codec);
939 return res;
940 }
941 //final setup
942 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
943 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
944
945 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
946 * (what is the difference?) */
947 ptr->mode = CODEC_DO_COMPRESSION;
948 ptr->width = 384;
949 ptr->height = 288;
950 ptr->total_code_vol = 16000; /* CHECKME */
951 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
952 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */
953 ptr->scalefact = 0x100;
954 ptr->dri = 1; /* CHECKME, was 8 is 1 */
955
956 /* by default, no COM or APP markers - app should set those */
957 ptr->com.len = 0;
958 ptr->app.appn = 0;
959 ptr->app.len = 0;
960
961 zr36060_init(ptr);
962
963 dprintk(1, KERN_INFO "%s: codec attached and running\n",
964 ptr->name);
965
966 return 0;
967}
968
969static const struct videocodec zr36060_codec = {
970 .owner = THIS_MODULE,
971 .name = "zr36060",
972 .magic = 0L, // magic not used
973 .flags =
974 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
975 CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
976 .type = CODEC_TYPE_ZR36060,
977 .setup = zr36060_setup, // functionality
978 .unset = zr36060_unset,
979 .set_mode = zr36060_set_mode,
980 .set_video = zr36060_set_video,
981 .control = zr36060_control,
982 // others are not used
983};
984
985/* =========================================================================
986 HOOK IN DRIVER AS KERNEL MODULE
987 ========================================================================= */
988
989static int __init
990zr36060_init_module (void)
991{
992 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
993 zr36060_codecs = 0;
994 return videocodec_register(&zr36060_codec);
995}
996
997static void __exit
998zr36060_cleanup_module (void)
999{
1000 if (zr36060_codecs) {
1001 dprintk(1,
1002 "zr36060: something's wrong - %d codecs left somehow.\n",
1003 zr36060_codecs);
1004 }
1005
1006 /* however, we can't just stay alive */
1007 videocodec_unregister(&zr36060_codec);
1008}
1009
1010module_init(zr36060_init_module);
1011module_exit(zr36060_cleanup_module);
1012
1013MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
1014MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
1015 ZR060_VERSION);
1016MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36060.h b/drivers/media/video/zr36060.h
new file mode 100644
index 000000000000..914ffa4ad8d3
--- /dev/null
+++ b/drivers/media/video/zr36060.h
@@ -0,0 +1,220 @@
1/*
2 * Zoran ZR36060 basic configuration functions - header file
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.h,v 1.1.1.1.2.3 2003/01/14 21:18:47 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36060_H
28#define ZR36060_H
29
30#include "videocodec.h"
31
32/* data stored for each zoran jpeg codec chip */
33struct zr36060 {
34 char name[32];
35 int num;
36 /* io datastructure */
37 struct videocodec *codec;
38 // last coder status
39 __u8 status;
40 // actual coder setup
41 int mode;
42
43 __u16 width;
44 __u16 height;
45
46 __u16 bitrate_ctrl;
47
48 __u32 total_code_vol;
49 __u32 real_code_vol;
50 __u16 max_block_vol;
51
52 __u8 h_samp_ratio[8];
53 __u8 v_samp_ratio[8];
54 __u16 scalefact;
55 __u16 dri;
56
57 /* app/com marker data */
58 struct jpeg_app_marker app;
59 struct jpeg_com_marker com;
60};
61
62/* ZR36060 register addresses */
63#define ZR060_LOAD 0x000
64#define ZR060_CFSR 0x001
65#define ZR060_CIR 0x002
66#define ZR060_CMR 0x003
67#define ZR060_MBZ 0x004
68#define ZR060_MBCVR 0x005
69#define ZR060_MER 0x006
70#define ZR060_IMR 0x007
71#define ZR060_ISR 0x008
72#define ZR060_TCV_NET_HI 0x009
73#define ZR060_TCV_NET_MH 0x00a
74#define ZR060_TCV_NET_ML 0x00b
75#define ZR060_TCV_NET_LO 0x00c
76#define ZR060_TCV_DATA_HI 0x00d
77#define ZR060_TCV_DATA_MH 0x00e
78#define ZR060_TCV_DATA_ML 0x00f
79#define ZR060_TCV_DATA_LO 0x010
80#define ZR060_SF_HI 0x011
81#define ZR060_SF_LO 0x012
82#define ZR060_AF_HI 0x013
83#define ZR060_AF_M 0x014
84#define ZR060_AF_LO 0x015
85#define ZR060_ACV_HI 0x016
86#define ZR060_ACV_MH 0x017
87#define ZR060_ACV_ML 0x018
88#define ZR060_ACV_LO 0x019
89#define ZR060_ACT_HI 0x01a
90#define ZR060_ACT_MH 0x01b
91#define ZR060_ACT_ML 0x01c
92#define ZR060_ACT_LO 0x01d
93#define ZR060_ACV_TRUN_HI 0x01e
94#define ZR060_ACV_TRUN_MH 0x01f
95#define ZR060_ACV_TRUN_ML 0x020
96#define ZR060_ACV_TRUN_LO 0x021
97#define ZR060_IDR_DEV 0x022
98#define ZR060_IDR_REV 0x023
99#define ZR060_TCR_HI 0x024
100#define ZR060_TCR_LO 0x025
101#define ZR060_VCR 0x030
102#define ZR060_VPR 0x031
103#define ZR060_SR 0x032
104#define ZR060_BCR_Y 0x033
105#define ZR060_BCR_U 0x034
106#define ZR060_BCR_V 0x035
107#define ZR060_SGR_VTOTAL_HI 0x036
108#define ZR060_SGR_VTOTAL_LO 0x037
109#define ZR060_SGR_HTOTAL_HI 0x038
110#define ZR060_SGR_HTOTAL_LO 0x039
111#define ZR060_SGR_VSYNC 0x03a
112#define ZR060_SGR_HSYNC 0x03b
113#define ZR060_SGR_BVSTART 0x03c
114#define ZR060_SGR_BHSTART 0x03d
115#define ZR060_SGR_BVEND_HI 0x03e
116#define ZR060_SGR_BVEND_LO 0x03f
117#define ZR060_SGR_BHEND_HI 0x040
118#define ZR060_SGR_BHEND_LO 0x041
119#define ZR060_AAR_VSTART_HI 0x042
120#define ZR060_AAR_VSTART_LO 0x043
121#define ZR060_AAR_VEND_HI 0x044
122#define ZR060_AAR_VEND_LO 0x045
123#define ZR060_AAR_HSTART_HI 0x046
124#define ZR060_AAR_HSTART_LO 0x047
125#define ZR060_AAR_HEND_HI 0x048
126#define ZR060_AAR_HEND_LO 0x049
127#define ZR060_SWR_VSTART_HI 0x04a
128#define ZR060_SWR_VSTART_LO 0x04b
129#define ZR060_SWR_VEND_HI 0x04c
130#define ZR060_SWR_VEND_LO 0x04d
131#define ZR060_SWR_HSTART_HI 0x04e
132#define ZR060_SWR_HSTART_LO 0x04f
133#define ZR060_SWR_HEND_HI 0x050
134#define ZR060_SWR_HEND_LO 0x051
135
136#define ZR060_SOF_IDX 0x060
137#define ZR060_SOS_IDX 0x07a
138#define ZR060_DRI_IDX 0x0c0
139#define ZR060_DQT_IDX 0x0cc
140#define ZR060_DHT_IDX 0x1d4
141#define ZR060_APP_IDX 0x380
142#define ZR060_COM_IDX 0x3c0
143
144/* ZR36060 LOAD register bits */
145
146#define ZR060_LOAD_Load (1 << 7)
147#define ZR060_LOAD_SyncRst (1 << 0)
148
149/* ZR36060 Code FIFO Status register bits */
150
151#define ZR060_CFSR_Busy (1 << 7)
152#define ZR060_CFSR_CBusy (1 << 2)
153#define ZR060_CFSR_CFIFO (3 << 0)
154
155/* ZR36060 Code Interface register */
156
157#define ZR060_CIR_Code16 (1 << 7)
158#define ZR060_CIR_Endian (1 << 6)
159#define ZR060_CIR_CFIS (1 << 2)
160#define ZR060_CIR_CodeMstr (1 << 0)
161
162/* ZR36060 Codec Mode register */
163
164#define ZR060_CMR_Comp (1 << 7)
165#define ZR060_CMR_ATP (1 << 6)
166#define ZR060_CMR_Pass2 (1 << 5)
167#define ZR060_CMR_TLM (1 << 4)
168#define ZR060_CMR_BRB (1 << 2)
169#define ZR060_CMR_FSF (1 << 1)
170
171/* ZR36060 Markers Enable register */
172
173#define ZR060_MER_App (1 << 7)
174#define ZR060_MER_Com (1 << 6)
175#define ZR060_MER_DRI (1 << 5)
176#define ZR060_MER_DQT (1 << 4)
177#define ZR060_MER_DHT (1 << 3)
178
179/* ZR36060 Interrupt Mask register */
180
181#define ZR060_IMR_EOAV (1 << 3)
182#define ZR060_IMR_EOI (1 << 2)
183#define ZR060_IMR_End (1 << 1)
184#define ZR060_IMR_DataErr (1 << 0)
185
186/* ZR36060 Interrupt Status register */
187
188#define ZR060_ISR_ProCnt (3 << 6)
189#define ZR060_ISR_EOAV (1 << 3)
190#define ZR060_ISR_EOI (1 << 2)
191#define ZR060_ISR_End (1 << 1)
192#define ZR060_ISR_DataErr (1 << 0)
193
194/* ZR36060 Video Control register */
195
196#define ZR060_VCR_Video8 (1 << 7)
197#define ZR060_VCR_Range (1 << 6)
198#define ZR060_VCR_FIDet (1 << 3)
199#define ZR060_VCR_FIVedge (1 << 2)
200#define ZR060_VCR_FIExt (1 << 1)
201#define ZR060_VCR_SyncMstr (1 << 0)
202
203/* ZR36060 Video Polarity register */
204
205#define ZR060_VPR_VCLKPol (1 << 7)
206#define ZR060_VPR_PValPol (1 << 6)
207#define ZR060_VPR_PoePol (1 << 5)
208#define ZR060_VPR_SImgPol (1 << 4)
209#define ZR060_VPR_BLPol (1 << 3)
210#define ZR060_VPR_FIPol (1 << 2)
211#define ZR060_VPR_HSPol (1 << 1)
212#define ZR060_VPR_VSPol (1 << 0)
213
214/* ZR36060 Scaling register */
215
216#define ZR060_SR_VScale (1 << 2)
217#define ZR060_SR_HScale2 (1 << 0)
218#define ZR060_SR_HScale4 (2 << 0)
219
220#endif /*fndef ZR36060_H */
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
new file mode 100644
index 000000000000..c33533155cc7
--- /dev/null
+++ b/drivers/media/video/zr36120.c
@@ -0,0 +1,2073 @@
1/*
2 zr36120.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/init.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/major.h>
28#include <linux/slab.h>
29#include <linux/vmalloc.h>
30#include <linux/mm.h>
31#include <linux/pci.h>
32#include <linux/signal.h>
33#include <linux/wait.h>
34#include <asm/io.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <linux/sched.h>
38#include <linux/video_decoder.h>
39
40#include <asm/uaccess.h>
41
42#include "tuner.h"
43#include "zr36120.h"
44#include "zr36120_mem.h"
45
46/* mark an required function argument unused - lintism */
47#define UNUSED(x) (void)(x)
48
49/* sensible default */
50#ifndef CARDTYPE
51#define CARDTYPE 0
52#endif
53
54/* Anybody who uses more than four? */
55#define ZORAN_MAX 4
56
57static unsigned int triton1=0; /* triton1 chipset? */
58static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
59static int video_nr = -1;
60static int vbi_nr = -1;
61
62static struct pci_device_id zr36120_pci_tbl[] = {
63 { PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120,
64 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
65 { 0 }
66};
67MODULE_DEVICE_TABLE(pci, zr36120_pci_tbl);
68
69MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
70MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
71MODULE_LICENSE("GPL");
72
73MODULE_PARM(triton1,"i");
74MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
75MODULE_PARM(video_nr,"i");
76MODULE_PARM(vbi_nr,"i");
77
78static int zoran_cards;
79static struct zoran zorans[ZORAN_MAX];
80
81/*
82 * the meaning of each element can be found in zr36120.h
83 * Determining the value of gpdir/gpval can be tricky. The
84 * best way is to run the card under the original software
85 * and read the values from the general purpose registers
86 * 0x28 and 0x2C. How you do that is left as an exercise
87 * to the impatient reader :)
88 */
89#define T 1 /* to separate the bools from the ints */
90#define F 0
91static struct tvcard tvcards[] = {
92 /* reported working by <middelin@polyware.nl> */
93/*0*/ { "Trust Victor II",
94 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
95 /* reported working by <Michael.Paxton@aihw.gov.au> */
96/*1*/ { "Aitech WaveWatcher TV-PCI",
97 3, 0, T, F, T, T, 0x7F, 0x80, { 1, TUNER(3), SVHS(6) }, { 0 } },
98 /* reported working by ? */
99/*2*/ { "Genius Video Wonder PCI Video Capture Card",
100 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
101 /* reported working by <Pascal.Gabriel@wanadoo.fr> */
102/*3*/ { "Guillemot Maxi-TV PCI",
103 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
104 /* reported working by "Craig Whitmore <lennon@igrin.co.nz> */
105/*4*/ { "Quadrant Buster",
106 3, 3, T, F, T, T, 0x7F, 0x80, { SVHS(1), TUNER(2), 3 }, { 1, 2, 3 } },
107 /* a debug entry which has all inputs mapped */
108/*5*/ { "ZR36120 based framegrabber (all inputs enabled)",
109 6, 0, T, T, T, T, 0x7F, 0x80, { 1, 2, 3, 4, 5, 6 }, { 0 } }
110};
111#undef T
112#undef F
113#define NRTVCARDS (sizeof(tvcards)/sizeof(tvcards[0]))
114
115#ifdef __sparc__
116#define ENDIANESS 0
117#else
118#define ENDIANESS ZORAN_VFEC_LE
119#endif
120
121static struct { const char name[8]; uint mode; uint bpp; } palette2fmt[] = {
122/* n/a */ { "n/a", 0, 0 },
123/* GREY */ { "GRAY", 0, 0 },
124/* HI240 */ { "HI240", 0, 0 },
125/* RGB565 */ { "RGB565", ZORAN_VFEC_RGB_RGB565|ENDIANESS, 2 },
126/* RGB24 */ { "RGB24", ZORAN_VFEC_RGB_RGB888|ENDIANESS|ZORAN_VFEC_PACK24, 3 },
127/* RGB32 */ { "RGB32", ZORAN_VFEC_RGB_RGB888|ENDIANESS, 4 },
128/* RGB555 */ { "RGB555", ZORAN_VFEC_RGB_RGB555|ENDIANESS, 2 },
129/* YUV422 */ { "YUV422", ZORAN_VFEC_RGB_YUV422|ENDIANESS, 2 },
130/* YUYV */ { "YUYV", 0, 0 },
131/* UYVY */ { "UYVY", 0, 0 },
132/* YUV420 */ { "YUV420", 0, 0 },
133/* YUV411 */ { "YUV411", 0, 0 },
134/* RAW */ { "RAW", 0, 0 },
135/* YUV422P */ { "YUV422P", 0, 0 },
136/* YUV411P */ { "YUV411P", 0, 0 }};
137#define NRPALETTES (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
138#undef ENDIANESS
139
140/* ----------------------------------------------------------------------- */
141/* ZORAN chipset detector */
142/* shamelessly stolen from bttv.c */
143/* Reason for beeing here: we need to detect if we are running on a */
144/* Triton based chipset, and if so, enable a certain bit */
145/* ----------------------------------------------------------------------- */
146static
147void __init handle_chipset(void)
148{
149 /* Just in case some nut set this to something dangerous */
150 if (triton1)
151 triton1 = ZORAN_VDC_TRICOM;
152
153 if (pci_pci_problems & PCIPCI_TRITON) {
154 printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
155 triton1 = ZORAN_VDC_TRICOM;
156 }
157}
158
159/* ----------------------------------------------------------------------- */
160/* ZORAN functions */
161/* ----------------------------------------------------------------------- */
162
163static void zoran_set_geo(struct zoran* ztv, struct vidinfo* i);
164
165#if 0 /* unused */
166static
167void zoran_dump(struct zoran *ztv)
168{
169 char str[256];
170 char *p=str; /* shut up, gcc! */
171 int i;
172
173 for (i=0; i<0x60; i+=4) {
174 if ((i % 16) == 0) {
175 if (i) printk("%s\n",str);
176 p = str;
177 p+= sprintf(str, KERN_DEBUG " %04x: ",i);
178 }
179 p += sprintf(p, "%08x ",zrread(i));
180 }
181}
182#endif /* unused */
183
184static
185void reap_states(struct zoran* ztv)
186{
187 /* count frames */
188 ztv->fieldnr++;
189
190 /*
191 * Are we busy at all?
192 * This depends on if there is a workqueue AND the
193 * videotransfer is enabled on the chip...
194 */
195 if (ztv->workqueue && (zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
196 {
197 struct vidinfo* newitem;
198
199 /* did we get a complete frame? */
200 if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
201 return;
202
203DEBUG(printk(CARD_DEBUG "completed %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
204
205 /* we are done with this buffer, tell everyone */
206 ztv->workqueue->status = FBUFFER_DONE;
207 ztv->workqueue->fieldnr = ztv->fieldnr;
208 /* not good, here for BTTV_FIELDNR reasons */
209 ztv->lastfieldnr = ztv->fieldnr;
210
211 switch (ztv->workqueue->kindof) {
212 case FBUFFER_GRAB:
213 wake_up_interruptible(&ztv->grabq);
214 break;
215 case FBUFFER_VBI:
216 wake_up_interruptible(&ztv->vbiq);
217 break;
218 default:
219 printk(CARD_INFO "somebody killed the workqueue (kindof=%d)!\n",CARD,ztv->workqueue->kindof);
220 }
221
222 /* item completed, skip to next item in queue */
223 write_lock(&ztv->lock);
224 newitem = ztv->workqueue->next;
225 ztv->workqueue->next = 0; /* mark completed */
226 ztv->workqueue = newitem;
227 write_unlock(&ztv->lock);
228 }
229
230 /*
231 * ok, so it seems we have nothing in progress right now.
232 * Lets see if we can find some work.
233 */
234 if (ztv->workqueue)
235 {
236 struct vidinfo* newitem;
237again:
238
239DEBUG(printk(CARD_DEBUG "starting %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
240
241 /* loadup the frame settings */
242 read_lock(&ztv->lock);
243 zoran_set_geo(ztv,ztv->workqueue);
244 read_unlock(&ztv->lock);
245
246 switch (ztv->workqueue->kindof) {
247 case FBUFFER_GRAB:
248 case FBUFFER_VBI:
249 zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
250 zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
251 zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
252
253 /* start single-shot grab */
254 zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
255 break;
256 default:
257 printk(CARD_INFO "what is this doing on the queue? (kindof=%d)\n",CARD,ztv->workqueue->kindof);
258 write_lock(&ztv->lock);
259 newitem = ztv->workqueue->next;
260 ztv->workqueue->next = 0;
261 ztv->workqueue = newitem;
262 write_unlock(&ztv->lock);
263 if (newitem)
264 goto again; /* yeah, sure.. */
265 }
266 /* bye for now */
267 return;
268 }
269DEBUG(printk(CARD_DEBUG "nothing in queue\n",CARD));
270
271 /*
272 * What? Even the workqueue is empty? Am i really here
273 * for nothing? Did i come all that way to... do nothing?
274 */
275
276 /* do we need to overlay? */
277 if (test_bit(STATE_OVERLAY, &ztv->state))
278 {
279 /* are we already overlaying? */
280 if (!(zrread(ZORAN_OCR) & ZORAN_OCR_OVLEN) ||
281 !(zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
282 {
283DEBUG(printk(CARD_DEBUG "starting overlay\n",CARD));
284
285 read_lock(&ztv->lock);
286 zoran_set_geo(ztv,&ztv->overinfo);
287 read_unlock(&ztv->lock);
288
289 zror(ZORAN_OCR_OVLEN, ZORAN_OCR);
290 zrand(~ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
291 zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
292 }
293
294 /*
295 * leave overlaying on, but turn interrupts off.
296 */
297 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
298 return;
299 }
300
301 /* do we have any VBI idle time processing? */
302 if (test_bit(STATE_VBI, &ztv->state))
303 {
304 struct vidinfo* item;
305 struct vidinfo* lastitem;
306
307 /* protect the workqueue */
308 write_lock(&ztv->lock);
309 lastitem = ztv->workqueue;
310 if (lastitem)
311 while (lastitem->next) lastitem = lastitem->next;
312 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
313 if (item->next == 0 && item->status == FBUFFER_FREE)
314 {
315DEBUG(printk(CARD_DEBUG "%p added to queue\n",CARD,item));
316 item->status = FBUFFER_BUSY;
317 if (!lastitem)
318 ztv->workqueue = item;
319 else
320 lastitem->next = item;
321 lastitem = item;
322 }
323 write_unlock(&ztv->lock);
324 if (ztv->workqueue)
325 goto again; /* hey, _i_ graduated :) */
326 }
327
328 /*
329 * Then we must be realy IDLE
330 */
331DEBUG(printk(CARD_DEBUG "turning off\n",CARD));
332 /* nothing further to do, disable DMA and further IRQs */
333 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
334 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
335}
336
337static
338void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
339{
340 u32 stat,estat;
341 int count = 0;
342 struct zoran *ztv = dev_id;
343
344 UNUSED(irq); UNUSED(regs);
345 for (;;) {
346 /* get/clear interrupt status bits */
347 stat=zrread(ZORAN_ISR);
348 estat=stat & zrread(ZORAN_ICR);
349 if (!estat)
350 return;
351 zrwrite(estat,ZORAN_ISR);
352 IDEBUG(printk(CARD_DEBUG "estat %08x\n",CARD,estat));
353 IDEBUG(printk(CARD_DEBUG " stat %08x\n",CARD,stat));
354
355 if (estat & ZORAN_ISR_CODE)
356 {
357 IDEBUG(printk(CARD_DEBUG "CodReplIRQ\n",CARD));
358 }
359 if (estat & ZORAN_ISR_GIRQ0)
360 {
361 IDEBUG(printk(CARD_DEBUG "GIRQ0\n",CARD));
362 if (!ztv->card->usegirq1)
363 reap_states(ztv);
364 }
365 if (estat & ZORAN_ISR_GIRQ1)
366 {
367 IDEBUG(printk(CARD_DEBUG "GIRQ1\n",CARD));
368 if (ztv->card->usegirq1)
369 reap_states(ztv);
370 }
371
372 count++;
373 if (count > 10)
374 printk(CARD_ERR "irq loop %d (%x)\n",CARD,count,estat);
375 if (count > 20)
376 {
377 zrwrite(0, ZORAN_ICR);
378 printk(CARD_ERR "IRQ lockup, cleared int mask\n",CARD);
379 }
380 }
381}
382
383static
384int zoran_muxsel(struct zoran* ztv, int channel, int norm)
385{
386 int rv;
387
388 /* set the new video norm */
389 rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
390 if (rv)
391 return rv;
392 ztv->norm = norm;
393
394 /* map the given channel to the cards decoder's channel */
395 channel = ztv->card->video_mux[channel] & CHANNEL_MASK;
396
397 /* set the new channel */
398 rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &channel);
399 return rv;
400}
401
402/* Tell the interrupt handler what to to. */
403static
404void zoran_cap(struct zoran* ztv, int on)
405{
406DEBUG(printk(CARD_DEBUG "zoran_cap(%d) state=%x\n",CARD,on,ztv->state));
407
408 if (on) {
409 ztv->running = 1;
410
411 /*
412 * turn interrupts (back) on. The DMA will be enabled
413 * inside the irq handler when it detects a restart.
414 */
415 zror(ZORAN_ICR_EN,ZORAN_ICR);
416 }
417 else {
418 /*
419 * turn both interrupts and DMA off
420 */
421 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
422 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
423
424 ztv->running = 0;
425 }
426}
427
428static ulong dmask[] = {
429 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
430 0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
431 0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
432 0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
433 0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
434 0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
435 0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
436 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000
437};
438
439static
440void zoran_built_overlay(struct zoran* ztv, int count, struct video_clip *vcp)
441{
442 ulong* mtop;
443 int ystep = (ztv->vidXshift + ztv->vidWidth+31)/32; /* next DWORD */
444 int i;
445
446DEBUG(printk(KERN_DEBUG " overlay at %p, ystep=%d, clips=%d\n",ztv->overinfo.overlay,ystep,count));
447
448 for (i=0; i<count; i++) {
449 struct video_clip *vp = vcp+i;
450 UNUSED(vp);
451DEBUG(printk(KERN_DEBUG " %d: clip(%d,%d,%d,%d)\n", i,vp->x,vp->y,vp->width,vp->height));
452 }
453
454 /*
455 * activate the visible portion of the screen
456 * Note we take some shortcuts here, because we
457 * know the width can never be < 32. (I.e. a DWORD)
458 * We also assume the overlay starts somewhere in
459 * the FIRST dword.
460 */
461 {
462 int start = ztv->vidXshift;
463 ulong firstd = dmask[start];
464 ulong lastd = ~dmask[(start + ztv->overinfo.w) & 31];
465 mtop = ztv->overinfo.overlay;
466 for (i=0; i<ztv->overinfo.h; i++) {
467 int w = ztv->vidWidth;
468 ulong* line = mtop;
469 if (start & 31) {
470 *line++ = firstd;
471 w -= 32-(start&31);
472 }
473 memset(line, ~0, w/8);
474 if (w & 31)
475 line[w/32] = lastd;
476 mtop += ystep;
477 }
478 }
479
480 /* process clipping regions */
481 for (i=0; i<count; i++) {
482 int h;
483 if (vcp->x < 0 || (uint)vcp->x > ztv->overinfo.w ||
484 vcp->y < 0 || vcp->y > ztv->overinfo.h ||
485 vcp->width < 0 || (uint)(vcp->x+vcp->width) > ztv->overinfo.w ||
486 vcp->height < 0 || (vcp->y+vcp->height) > ztv->overinfo.h)
487 {
488 DEBUG(printk(CARD_DEBUG "invalid clipzone (%d,%d,%d,%d) not in (0,0,%d,%d), adapting\n",CARD,vcp->x,vcp->y,vcp->width,vcp->height,ztv->overinfo.w,ztv->overinfo.h));
489 if (vcp->x < 0) vcp->x = 0;
490 if ((uint)vcp->x > ztv->overinfo.w) vcp->x = ztv->overinfo.w;
491 if (vcp->y < 0) vcp->y = 0;
492 if (vcp->y > ztv->overinfo.h) vcp->y = ztv->overinfo.h;
493 if (vcp->width < 0) vcp->width = 0;
494 if ((uint)(vcp->x+vcp->width) > ztv->overinfo.w) vcp->width = ztv->overinfo.w - vcp->x;
495 if (vcp->height < 0) vcp->height = 0;
496 if (vcp->y+vcp->height > ztv->overinfo.h) vcp->height = ztv->overinfo.h - vcp->y;
497// continue;
498 }
499
500 mtop = &ztv->overinfo.overlay[vcp->y*ystep];
501 for (h=0; h<=vcp->height; h++) {
502 int w;
503 int x = ztv->vidXshift + vcp->x;
504 for (w=0; w<=vcp->width; w++) {
505 clear_bit(x&31, &mtop[x/32]);
506 x++;
507 }
508 mtop += ystep;
509 }
510 ++vcp;
511 }
512
513 mtop = ztv->overinfo.overlay;
514 zrwrite(virt_to_bus(mtop), ZORAN_MTOP);
515 zrwrite(virt_to_bus(mtop+ystep), ZORAN_MBOT);
516 zraor((ztv->vidInterlace*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR);
517}
518
519struct tvnorm
520{
521 u16 Wt, Wa, Ht, Ha, HStart, VStart;
522};
523
524static struct tvnorm tvnorms[] = {
525 /* PAL-BDGHI */
526/* { 864, 720, 625, 576, 131, 21 },*/
527/*00*/ { 864, 768, 625, 576, 81, 17 },
528 /* NTSC */
529/*01*/ { 858, 720, 525, 480, 121, 10 },
530 /* SECAM */
531/*02*/ { 864, 720, 625, 576, 131, 21 },
532 /* BW50 */
533/*03*/ { 864, 720, 625, 576, 131, 21 },
534 /* BW60 */
535/*04*/ { 858, 720, 525, 480, 121, 10 }
536};
537#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
538
539/*
540 * Program the chip for a setup as described in the vidinfo struct.
541 *
542 * Side-effects: calculates vidXshift, vidInterlace,
543 * vidHeight, vidWidth which are used in a later stage
544 * to calculate the overlay mask
545 *
546 * This is an internal function, as such it does not check the
547 * validity of the struct members... Spectaculair crashes will
548 * follow /very/ quick when you're wrong and the chip right :)
549 */
550static
551void zoran_set_geo(struct zoran* ztv, struct vidinfo* i)
552{
553 ulong top, bot;
554 int stride;
555 int winWidth, winHeight;
556 int maxWidth, maxHeight, maxXOffset, maxYOffset;
557 long vfec;
558
559DEBUG(printk(CARD_DEBUG "set_geo(rect=(%d,%d,%d,%d), norm=%d, format=%d, bpp=%d, bpl=%d, busadr=%lx, overlay=%p)\n",CARD,i->x,i->y,i->w,i->h,ztv->norm,i->format,i->bpp,i->bpl,i->busadr,i->overlay));
560
561 /*
562 * make sure the DMA transfers are inhibited during our
563 * reprogramming of the chip
564 */
565 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
566
567 maxWidth = tvnorms[ztv->norm].Wa;
568 maxHeight = tvnorms[ztv->norm].Ha/2;
569 maxXOffset = tvnorms[ztv->norm].HStart;
570 maxYOffset = tvnorms[ztv->norm].VStart;
571
572 /* setup vfec register (keep ExtFl,TopField and VCLKPol settings) */
573 vfec = (zrread(ZORAN_VFEC) & (ZORAN_VFEC_EXTFL|ZORAN_VFEC_TOPFIELD|ZORAN_VFEC_VCLKPOL)) |
574 (palette2fmt[i->format].mode & (ZORAN_VFEC_RGB|ZORAN_VFEC_ERRDIF|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24));
575
576 /*
577 * Set top, bottom ptrs. Since these must be DWORD aligned,
578 * possible adjust the x and the width of the window.
579 * so the endposition stay the same. The vidXshift will make
580 * sure we are not writing pixels before the requested x.
581 */
582 ztv->vidXshift = 0;
583 winWidth = i->w;
584 if (winWidth < 0)
585 winWidth = -winWidth;
586 top = i->busadr + i->x*i->bpp + i->y*i->bpl;
587 if (top & 3) {
588 ztv->vidXshift = (top & 3) / i->bpp;
589 winWidth += ztv->vidXshift;
590 DEBUG(printk(KERN_DEBUG " window-x shifted %d pixels left\n",ztv->vidXshift));
591 top &= ~3;
592 }
593
594 /*
595 * bottom points to next frame but in interleaved mode we want
596 * to 'mix' the 2 frames to one capture, so 'bot' points to one
597 * (physical) line below the top line.
598 */
599 bot = top + i->bpl;
600 zrwrite(top,ZORAN_VTOP);
601 zrwrite(bot,ZORAN_VBOT);
602
603 /*
604 * Make sure the winWidth is DWORD aligned too,
605 * thereby automaticly making sure the stride to the
606 * next line is DWORD aligned too (as required by spec).
607 */
608 if ((winWidth*i->bpp) & 3) {
609DEBUG(printk(KERN_DEBUG " window-width enlarged by %d pixels\n",(winWidth*i->bpp) & 3));
610 winWidth += (winWidth*i->bpp) & 3;
611 }
612
613 /* determine the DispMode and stride */
614 if (i->h >= 0 && i->h <= maxHeight) {
615 /* single frame grab suffices for this height. */
616 vfec |= ZORAN_VFEC_DISPMOD;
617 ztv->vidInterlace = 0;
618 stride = i->bpl - (winWidth*i->bpp);
619 winHeight = i->h;
620 }
621 else {
622 /* interleaving needed for this height */
623 ztv->vidInterlace = 1;
624 stride = i->bpl*2 - (winWidth*i->bpp);
625 winHeight = i->h/2;
626 }
627 if (winHeight < 0) /* can happen for VBI! */
628 winHeight = -winHeight;
629
630 /* safety net, sometimes bpl is too short??? */
631 if (stride<0) {
632DEBUG(printk(CARD_DEBUG "WARNING stride = %d\n",CARD,stride));
633 stride = 0;
634 }
635
636 zraor((winHeight<<12)|(winWidth<<0),~(ZORAN_VDC_VIDWINHT|ZORAN_VDC_VIDWINWID), ZORAN_VDC);
637 zraor(stride<<16,~ZORAN_VSTR_DISPSTRIDE,ZORAN_VSTR);
638
639 /* remember vidWidth, vidHeight for overlay calculations */
640 ztv->vidWidth = winWidth;
641 ztv->vidHeight = winHeight;
642DEBUG(printk(KERN_DEBUG " top=%08lx, bottom=%08lx\n",top,bot));
643DEBUG(printk(KERN_DEBUG " winWidth=%d, winHeight=%d\n",winWidth,winHeight));
644DEBUG(printk(KERN_DEBUG " maxWidth=%d, maxHeight=%d\n",maxWidth,maxHeight));
645DEBUG(printk(KERN_DEBUG " stride=%d\n",stride));
646
647 /*
648 * determine horizontal scales and crops
649 */
650 if (i->w < 0) {
651 int Hstart = 1;
652 int Hend = Hstart + winWidth;
653DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Hstart, Hend));
654 zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
655 }
656 else {
657 int Wa = maxWidth;
658 int X = (winWidth*64+Wa-1)/Wa;
659 int We = winWidth*64/X;
660 int HorDcm = 64-X;
661 int hcrop1 = 2*(Wa-We)/4;
662 /*
663 * BUGFIX: Juha Nurmela <junki@qn-lpr2-165.quicknet.inet.fi>
664 * found the solution to the color phase shift.
665 * See ChangeLog for the full explanation)
666 */
667 int Hstart = (maxXOffset + hcrop1) | 1;
668 int Hend = Hstart + We - 1;
669
670DEBUG(printk(KERN_DEBUG " X: scale=%d, start=%d, end=%d\n", HorDcm, Hstart, Hend));
671
672 zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
673 vfec |= HorDcm<<14;
674
675 if (HorDcm<16)
676 vfec |= ZORAN_VFEC_HFILTER_1; /* no filter */
677 else if (HorDcm<32)
678 vfec |= ZORAN_VFEC_HFILTER_3; /* 3 tap filter */
679 else if (HorDcm<48)
680 vfec |= ZORAN_VFEC_HFILTER_4; /* 4 tap filter */
681 else vfec |= ZORAN_VFEC_HFILTER_5; /* 5 tap filter */
682 }
683
684 /*
685 * Determine vertical scales and crops
686 *
687 * when height is negative, we want to read starting at line 0
688 * One day someone might need access to these lines...
689 */
690 if (i->h < 0) {
691 int Vstart = 0;
692 int Vend = Vstart + winHeight;
693DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Vstart, Vend));
694 zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
695 }
696 else {
697 int Ha = maxHeight;
698 int Y = (winHeight*64+Ha-1)/Ha;
699 int He = winHeight*64/Y;
700 int VerDcm = 64-Y;
701 int vcrop1 = 2*(Ha-He)/4;
702 int Vstart = maxYOffset + vcrop1;
703 int Vend = Vstart + He - 1;
704
705DEBUG(printk(KERN_DEBUG " Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
706 zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
707 vfec |= VerDcm<<8;
708 }
709
710DEBUG(printk(KERN_DEBUG " F: format=%d(=%s)\n",i->format,palette2fmt[i->format].name));
711
712 /* setup the requested format */
713 zrwrite(vfec, ZORAN_VFEC);
714}
715
716static
717void zoran_common_open(struct zoran* ztv, int flags)
718{
719 UNUSED(flags);
720
721 /* already opened? */
722 if (ztv->users++ != 0)
723 return;
724
725 /* unmute audio */
726 /* /what/ audio? */
727
728 ztv->state = 0;
729
730 /* setup the encoder to the initial values */
731 ztv->picture.colour=254<<7;
732 ztv->picture.brightness=128<<8;
733 ztv->picture.hue=128<<8;
734 ztv->picture.contrast=216<<7;
735 i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &ztv->picture);
736
737 /* default to the composite input since my camera is there */
738 zoran_muxsel(ztv, 0, VIDEO_MODE_PAL);
739}
740
741static
742void zoran_common_close(struct zoran* ztv)
743{
744 if (--ztv->users != 0)
745 return;
746
747 /* mute audio */
748 /* /what/ audio? */
749
750 /* stop the chip */
751 zoran_cap(ztv, 0);
752}
753
754/*
755 * Open a zoran card. Right now the flags are just a hack
756 */
757static int zoran_open(struct video_device *dev, int flags)
758{
759 struct zoran *ztv = (struct zoran*)dev;
760 struct vidinfo* item;
761 char* pos;
762
763 DEBUG(printk(CARD_DEBUG "open(dev,%d)\n",CARD,flags));
764
765 /*********************************************
766 * We really should be doing lazy allocing...
767 *********************************************/
768 /* allocate a frame buffer */
769 if (!ztv->fbuffer)
770 ztv->fbuffer = bmalloc(ZORAN_MAX_FBUFSIZE);
771 if (!ztv->fbuffer) {
772 /* could not get a buffer, bail out */
773 return -ENOBUFS;
774 }
775 /* at this time we _always_ have a framebuffer */
776 memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);
777
778 if (!ztv->overinfo.overlay)
779 ztv->overinfo.overlay = kmalloc(1024*1024/8, GFP_KERNEL);
780 if (!ztv->overinfo.overlay) {
781 /* could not get an overlay buffer, bail out */
782 bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
783 return -ENOBUFS;
784 }
785 /* at this time we _always_ have a overlay */
786
787 /* clear buffer status, and give them a DMAable address */
788 pos = ztv->fbuffer;
789 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
790 {
791 item->status = FBUFFER_FREE;
792 item->memadr = pos;
793 item->busadr = virt_to_bus(pos);
794 pos += ZORAN_MAX_FBUFFER;
795 }
796
797 /* do the common part of all open's */
798 zoran_common_open(ztv, flags);
799
800 return 0;
801}
802
803static
804void zoran_close(struct video_device* dev)
805{
806 struct zoran *ztv = (struct zoran*)dev;
807
808 DEBUG(printk(CARD_DEBUG "close(dev)\n",CARD));
809
810 /* driver specific closure */
811 clear_bit(STATE_OVERLAY, &ztv->state);
812
813 zoran_common_close(ztv);
814
815 /*
816 * This is sucky but right now I can't find a good way to
817 * be sure its safe to free the buffer. We wait 5-6 fields
818 * which is more than sufficient to be sure.
819 */
820 msleep(100); /* Wait 1/10th of a second */
821
822 /* free the allocated framebuffer */
823 if (ztv->fbuffer)
824 bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
825 ztv->fbuffer = 0;
826 if (ztv->overinfo.overlay)
827 kfree( ztv->overinfo.overlay );
828 ztv->overinfo.overlay = 0;
829
830}
831
832/*
833 * This read function could be used reentrant in a SMP situation.
834 *
835 * This is made possible by the spinlock which is kept till we
836 * found and marked a buffer for our own use. The lock must
837 * be released as soon as possible to prevent lock contention.
838 */
839static
840long zoran_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
841{
842 struct zoran *ztv = (struct zoran*)dev;
843 unsigned long max;
844 struct vidinfo* unused = 0;
845 struct vidinfo* done = 0;
846
847 DEBUG(printk(CARD_DEBUG "zoran_read(%p,%ld,%d)\n",CARD,buf,count,nonblock));
848
849 /* find ourself a free or completed buffer */
850 for (;;) {
851 struct vidinfo* item;
852
853 write_lock_irq(&ztv->lock);
854 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
855 {
856 if (!unused && item->status == FBUFFER_FREE)
857 unused = item;
858 if (!done && item->status == FBUFFER_DONE)
859 done = item;
860 }
861 if (done || unused)
862 break;
863
864 /* no more free buffers, wait for them. */
865 write_unlock_irq(&ztv->lock);
866 if (nonblock)
867 return -EWOULDBLOCK;
868 interruptible_sleep_on(&ztv->grabq);
869 if (signal_pending(current))
870 return -EINTR;
871 }
872
873 /* Do we have 'ready' data? */
874 if (!done) {
875 /* no? than this will take a while... */
876 if (nonblock) {
877 write_unlock_irq(&ztv->lock);
878 return -EWOULDBLOCK;
879 }
880
881 /* mark the unused buffer as wanted */
882 unused->status = FBUFFER_BUSY;
883 unused->w = 320;
884 unused->h = 240;
885 unused->format = VIDEO_PALETTE_RGB24;
886 unused->bpp = palette2fmt[unused->format].bpp;
887 unused->bpl = unused->w * unused->bpp;
888 unused->next = 0;
889 { /* add to tail of queue */
890 struct vidinfo* oldframe = ztv->workqueue;
891 if (!oldframe) ztv->workqueue = unused;
892 else {
893 while (oldframe->next) oldframe = oldframe->next;
894 oldframe->next = unused;
895 }
896 }
897 write_unlock_irq(&ztv->lock);
898
899 /* tell the state machine we want it filled /NOW/ */
900 zoran_cap(ztv, 1);
901
902 /* wait till this buffer gets grabbed */
903 wait_event_interruptible(ztv->grabq,
904 (unused->status != FBUFFER_BUSY));
905 /* see if a signal did it */
906 if (signal_pending(current))
907 return -EINTR;
908 done = unused;
909 }
910 else
911 write_unlock_irq(&ztv->lock);
912
913 /* Yes! we got data! */
914 max = done->bpl * done->h;
915 if (count > max)
916 count = max;
917 if (copy_to_user((void*)buf, done->memadr, count))
918 count = -EFAULT;
919
920 /* keep the engine running */
921 done->status = FBUFFER_FREE;
922// zoran_cap(ztv,1);
923
924 /* tell listeners this buffer became free */
925 wake_up_interruptible(&ztv->grabq);
926
927 /* goodbye */
928 DEBUG(printk(CARD_DEBUG "zoran_read() returns %lu\n",CARD,count));
929 return count;
930}
931
932static
933long zoran_write(struct video_device* dev, const char* buf, unsigned long count, int nonblock)
934{
935 struct zoran *ztv = (struct zoran *)dev;
936 UNUSED(ztv); UNUSED(dev); UNUSED(buf); UNUSED(count); UNUSED(nonblock);
937 DEBUG(printk(CARD_DEBUG "zoran_write\n",CARD));
938 return -EINVAL;
939}
940
941static
942unsigned int zoran_poll(struct video_device *dev, struct file *file, poll_table *wait)
943{
944 struct zoran *ztv = (struct zoran *)dev;
945 struct vidinfo* item;
946 unsigned int mask = 0;
947
948 poll_wait(file, &ztv->grabq, wait);
949
950 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
951 if (item->status == FBUFFER_DONE)
952 {
953 mask |= (POLLIN | POLLRDNORM);
954 break;
955 }
956
957 DEBUG(printk(CARD_DEBUG "zoran_poll()=%x\n",CARD,mask));
958
959 return mask;
960}
961
962/* append a new clipregion to the vector of video_clips */
963static
964void new_clip(struct video_window* vw, struct video_clip* vcp, int x, int y, int w, int h)
965{
966 vcp[vw->clipcount].x = x;
967 vcp[vw->clipcount].y = y;
968 vcp[vw->clipcount].width = w;
969 vcp[vw->clipcount].height = h;
970 vw->clipcount++;
971}
972
973static
974int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
975{
976 struct zoran* ztv = (struct zoran*)dev;
977
978 switch (cmd) {
979 case VIDIOCGCAP:
980 {
981 struct video_capability c;
982 DEBUG(printk(CARD_DEBUG "VIDIOCGCAP\n",CARD));
983
984 strcpy(c.name,ztv->video_dev.name);
985 c.type = VID_TYPE_CAPTURE|
986 VID_TYPE_OVERLAY|
987 VID_TYPE_CLIPPING|
988 VID_TYPE_FRAMERAM|
989 VID_TYPE_SCALES;
990 if (ztv->have_tuner)
991 c.type |= VID_TYPE_TUNER;
992 if (ztv->have_decoder) {
993 c.channels = ztv->card->video_inputs;
994 c.audios = ztv->card->audio_inputs;
995 } else
996 /* no decoder -> no channels */
997 c.channels = c.audios = 0;
998 c.maxwidth = 768;
999 c.maxheight = 576;
1000 c.minwidth = 32;
1001 c.minheight = 32;
1002 if (copy_to_user(arg,&c,sizeof(c)))
1003 return -EFAULT;
1004 break;
1005 }
1006
1007 case VIDIOCGCHAN:
1008 {
1009 struct video_channel v;
1010 int mux;
1011 if (copy_from_user(&v, arg,sizeof(v)))
1012 return -EFAULT;
1013 DEBUG(printk(CARD_DEBUG "VIDIOCGCHAN(%d)\n",CARD,v.channel));
1014 v.flags=VIDEO_VC_AUDIO
1015#ifdef VIDEO_VC_NORM
1016 |VIDEO_VC_NORM
1017#endif
1018 ;
1019 v.tuners=0;
1020 v.type=VIDEO_TYPE_CAMERA;
1021#ifdef I_EXPECT_POSSIBLE_NORMS_IN_THE_API
1022 v.norm=VIDEO_MODE_PAL|
1023 VIDEO_MODE_NTSC|
1024 VIDEO_MODE_SECAM;
1025#else
1026 v.norm=VIDEO_MODE_PAL;
1027#endif
1028 /* too many inputs? no decoder -> no channels */
1029 if (!ztv->have_decoder || v.channel < 0 || v.channel >= ztv->card->video_inputs)
1030 return -EINVAL;
1031
1032 /* now determine the name of the channel */
1033 mux = ztv->card->video_mux[v.channel];
1034 if (mux & IS_TUNER) {
1035 /* lets assume only one tuner, yes? */
1036 strcpy(v.name,"Television");
1037 v.type = VIDEO_TYPE_TV;
1038 if (ztv->have_tuner) {
1039 v.flags |= VIDEO_VC_TUNER;
1040 v.tuners = 1;
1041 }
1042 }
1043 else if (mux & IS_SVHS)
1044 sprintf(v.name,"S-Video-%d",v.channel);
1045 else
1046 sprintf(v.name,"CVBS-%d",v.channel);
1047
1048 if (copy_to_user(arg,&v,sizeof(v)))
1049 return -EFAULT;
1050 break;
1051 }
1052 case VIDIOCSCHAN:
1053 { /* set video channel */
1054 struct video_channel v;
1055 if (copy_from_user(&v, arg,sizeof(v)))
1056 return -EFAULT;
1057 DEBUG(printk(CARD_DEBUG "VIDIOCSCHAN(%d,%d)\n",CARD,v.channel,v.norm));
1058
1059 /* too many inputs? no decoder -> no channels */
1060 if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs || v.channel < 0)
1061 return -EINVAL;
1062
1063 if (v.norm != VIDEO_MODE_PAL &&
1064 v.norm != VIDEO_MODE_NTSC &&
1065 v.norm != VIDEO_MODE_SECAM &&
1066 v.norm != VIDEO_MODE_AUTO)
1067 return -EOPNOTSUPP;
1068
1069 /* make it happen, nr1! */
1070 return zoran_muxsel(ztv,v.channel,v.norm);
1071 }
1072
1073 case VIDIOCGTUNER:
1074 {
1075 struct video_tuner v;
1076 if (copy_from_user(&v, arg,sizeof(v)))
1077 return -EFAULT;
1078 DEBUG(printk(CARD_DEBUG "VIDIOCGTUNER(%d)\n",CARD,v.tuner));
1079
1080 /* Only no or one tuner for now */
1081 if (!ztv->have_tuner || v.tuner)
1082 return -EINVAL;
1083
1084 strcpy(v.name,"Television");
1085 v.rangelow = 0;
1086 v.rangehigh = ~0;
1087 v.flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1088 v.mode = ztv->norm;
1089 v.signal = 0xFFFF; /* unknown */
1090
1091 if (copy_to_user(arg,&v,sizeof(v)))
1092 return -EFAULT;
1093 break;
1094 }
1095 case VIDIOCSTUNER:
1096 {
1097 struct video_tuner v;
1098 if (copy_from_user(&v, arg, sizeof(v)))
1099 return -EFAULT;
1100 DEBUG(printk(CARD_DEBUG "VIDIOCSTUNER(%d,%d)\n",CARD,v.tuner,v.mode));
1101
1102 /* Only no or one tuner for now */
1103 if (!ztv->have_tuner || v.tuner)
1104 return -EINVAL;
1105
1106 /* and it only has certain valid modes */
1107 if( v.mode != VIDEO_MODE_PAL &&
1108 v.mode != VIDEO_MODE_NTSC &&
1109 v.mode != VIDEO_MODE_SECAM)
1110 return -EOPNOTSUPP;
1111
1112 /* engage! */
1113 return zoran_muxsel(ztv,v.tuner,v.mode);
1114 }
1115
1116 case VIDIOCGPICT:
1117 {
1118 struct video_picture p = ztv->picture;
1119 DEBUG(printk(CARD_DEBUG "VIDIOCGPICT\n",CARD));
1120 p.depth = ztv->depth;
1121 switch (p.depth) {
1122 case 8: p.palette=VIDEO_PALETTE_YUV422;
1123 break;
1124 case 15: p.palette=VIDEO_PALETTE_RGB555;
1125 break;
1126 case 16: p.palette=VIDEO_PALETTE_RGB565;
1127 break;
1128 case 24: p.palette=VIDEO_PALETTE_RGB24;
1129 break;
1130 case 32: p.palette=VIDEO_PALETTE_RGB32;
1131 break;
1132 }
1133 if (copy_to_user(arg, &p, sizeof(p)))
1134 return -EFAULT;
1135 break;
1136 }
1137 case VIDIOCSPICT:
1138 {
1139 struct video_picture p;
1140 if (copy_from_user(&p, arg,sizeof(p)))
1141 return -EFAULT;
1142 DEBUG(printk(CARD_DEBUG "VIDIOCSPICT(%d,%d,%d,%d,%d,%d,%d)\n",CARD,p.brightness,p.hue,p.colour,p.contrast,p.whiteness,p.depth,p.palette));
1143
1144 /* depth must match with framebuffer */
1145 if (p.depth != ztv->depth)
1146 return -EINVAL;
1147
1148 /* check if palette matches this bpp */
1149 if (p.palette>NRPALETTES ||
1150 palette2fmt[p.palette].bpp != ztv->overinfo.bpp)
1151 return -EINVAL;
1152
1153 write_lock_irq(&ztv->lock);
1154 ztv->overinfo.format = p.palette;
1155 ztv->picture = p;
1156 write_unlock_irq(&ztv->lock);
1157
1158 /* tell the decoder */
1159 i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
1160 break;
1161 }
1162
1163 case VIDIOCGWIN:
1164 {
1165 struct video_window vw;
1166 DEBUG(printk(CARD_DEBUG "VIDIOCGWIN\n",CARD));
1167 read_lock(&ztv->lock);
1168 vw.x = ztv->overinfo.x;
1169 vw.y = ztv->overinfo.y;
1170 vw.width = ztv->overinfo.w;
1171 vw.height = ztv->overinfo.h;
1172 vw.chromakey= 0;
1173 vw.flags = 0;
1174 if (ztv->vidInterlace)
1175 vw.flags|=VIDEO_WINDOW_INTERLACE;
1176 read_unlock(&ztv->lock);
1177 if (copy_to_user(arg,&vw,sizeof(vw)))
1178 return -EFAULT;
1179 break;
1180 }
1181 case VIDIOCSWIN:
1182 {
1183 struct video_window vw;
1184 struct video_clip *vcp;
1185 int on;
1186 if (copy_from_user(&vw,arg,sizeof(vw)))
1187 return -EFAULT;
1188 DEBUG(printk(CARD_DEBUG "VIDIOCSWIN(%d,%d,%d,%d,%x,%d)\n",CARD,vw.x,vw.y,vw.width,vw.height,vw.flags,vw.clipcount));
1189
1190 if (vw.flags)
1191 return -EINVAL;
1192
1193 if (vw.clipcount <0 || vw.clipcount>256)
1194 return -EDOM; /* Too many! */
1195
1196 /*
1197 * Do any clips.
1198 */
1199 vcp = vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
1200 if (vcp==NULL)
1201 return -ENOMEM;
1202 if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount)) {
1203 vfree(vcp);
1204 return -EFAULT;
1205 }
1206
1207 on = ztv->running;
1208 if (on)
1209 zoran_cap(ztv, 0);
1210
1211 /*
1212 * strange, it seems xawtv sometimes calls us with 0
1213 * width and/or height. Ignore these values
1214 */
1215 if (vw.x == 0)
1216 vw.x = ztv->overinfo.x;
1217 if (vw.y == 0)
1218 vw.y = ztv->overinfo.y;
1219
1220 /* by now we are committed to the new data... */
1221 write_lock_irq(&ztv->lock);
1222 ztv->overinfo.x = vw.x;
1223 ztv->overinfo.y = vw.y;
1224 ztv->overinfo.w = vw.width;
1225 ztv->overinfo.h = vw.height;
1226 write_unlock_irq(&ztv->lock);
1227
1228 /*
1229 * Impose display clips
1230 */
1231 if (vw.x+vw.width > ztv->swidth)
1232 new_clip(&vw, vcp, ztv->swidth-vw.x, 0, vw.width-1, vw.height-1);
1233 if (vw.y+vw.height > ztv->sheight)
1234 new_clip(&vw, vcp, 0, ztv->sheight-vw.y, vw.width-1, vw.height-1);
1235
1236 /* built the requested clipping zones */
1237 zoran_set_geo(ztv, &ztv->overinfo);
1238 zoran_built_overlay(ztv, vw.clipcount, vcp);
1239 vfree(vcp);
1240
1241 /* if we were on, restart the video engine */
1242 if (on)
1243 zoran_cap(ztv, 1);
1244 break;
1245 }
1246
1247 case VIDIOCCAPTURE:
1248 {
1249 int v;
1250 if (get_user(v, (int *)arg))
1251 return -EFAULT;
1252 DEBUG(printk(CARD_DEBUG "VIDIOCCAPTURE(%d)\n",CARD,v));
1253
1254 if (v==0) {
1255 clear_bit(STATE_OVERLAY, &ztv->state);
1256 zoran_cap(ztv, 1);
1257 }
1258 else {
1259 /* is VIDIOCSFBUF, VIDIOCSWIN done? */
1260 if (ztv->overinfo.busadr==0 || ztv->overinfo.w==0 || ztv->overinfo.h==0)
1261 return -EINVAL;
1262
1263 set_bit(STATE_OVERLAY, &ztv->state);
1264 zoran_cap(ztv, 1);
1265 }
1266 break;
1267 }
1268
1269 case VIDIOCGFBUF:
1270 {
1271 struct video_buffer v;
1272 DEBUG(printk(CARD_DEBUG "VIDIOCGFBUF\n",CARD));
1273 read_lock(&ztv->lock);
1274 v.base = (void *)ztv->overinfo.busadr;
1275 v.height = ztv->sheight;
1276 v.width = ztv->swidth;
1277 v.depth = ztv->depth;
1278 v.bytesperline = ztv->overinfo.bpl;
1279 read_unlock(&ztv->lock);
1280 if(copy_to_user(arg, &v,sizeof(v)))
1281 return -EFAULT;
1282 break;
1283 }
1284 case VIDIOCSFBUF:
1285 {
1286 struct video_buffer v;
1287 if(!capable(CAP_SYS_ADMIN))
1288 return -EPERM;
1289 if (copy_from_user(&v, arg,sizeof(v)))
1290 return -EFAULT;
1291 DEBUG(printk(CARD_DEBUG "VIDIOCSFBUF(%p,%d,%d,%d,%d)\n",CARD,v.base, v.width,v.height,v.depth,v.bytesperline));
1292
1293 if (v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
1294 return -EINVAL;
1295 if (v.bytesperline<1)
1296 return -EINVAL;
1297 if (ztv->running)
1298 return -EBUSY;
1299 write_lock_irq(&ztv->lock);
1300 ztv->overinfo.busadr = (ulong)v.base;
1301 ztv->sheight = v.height;
1302 ztv->swidth = v.width;
1303 ztv->depth = v.depth; /* bits per pixel */
1304 ztv->overinfo.bpp = ((v.depth+1)&0x38)/8;/* bytes per pixel */
1305 ztv->overinfo.bpl = v.bytesperline; /* bytes per line */
1306 write_unlock_irq(&ztv->lock);
1307 break;
1308 }
1309
1310 case VIDIOCKEY:
1311 {
1312 /* Will be handled higher up .. */
1313 break;
1314 }
1315
1316 case VIDIOCSYNC:
1317 {
1318 int i;
1319 if (get_user(i, (int *) arg))
1320 return -EFAULT;
1321 DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d)\n",CARD,i));
1322 if (i<0 || i>ZORAN_MAX_FBUFFERS)
1323 return -EINVAL;
1324 switch (ztv->grabinfo[i].status) {
1325 case FBUFFER_FREE:
1326 return -EINVAL;
1327 case FBUFFER_BUSY:
1328 /* wait till this buffer gets grabbed */
1329 wait_event_interruptible(ztv->grabq,
1330 (ztv->grabinfo[i].status != FBUFFER_BUSY));
1331 /* see if a signal did it */
1332 if (signal_pending(current))
1333 return -EINTR;
1334 /* don't fall through; a DONE buffer is not UNUSED */
1335 break;
1336 case FBUFFER_DONE:
1337 ztv->grabinfo[i].status = FBUFFER_FREE;
1338 /* tell ppl we have a spare buffer */
1339 wake_up_interruptible(&ztv->grabq);
1340 break;
1341 }
1342 DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d) returns\n",CARD,i));
1343 break;
1344 }
1345
1346 case VIDIOCMCAPTURE:
1347 {
1348 struct video_mmap vm;
1349 struct vidinfo* frame;
1350 if (copy_from_user(&vm,arg,sizeof(vm)))
1351 return -EFAULT;
1352 DEBUG(printk(CARD_DEBUG "VIDIOCMCAPTURE(%d,(%d,%d),%d)\n",CARD,vm.frame,vm.width,vm.height,vm.format));
1353 if (vm.frame<0 || vm.frame>ZORAN_MAX_FBUFFERS ||
1354 vm.width<32 || vm.width>768 ||
1355 vm.height<32 || vm.height>576 ||
1356 vm.format>NRPALETTES ||
1357 palette2fmt[vm.format].mode == 0)
1358 return -EINVAL;
1359
1360 /* we are allowed to take over UNUSED and DONE buffers */
1361 frame = &ztv->grabinfo[vm.frame];
1362 if (frame->status == FBUFFER_BUSY)
1363 return -EBUSY;
1364
1365 /* setup the other parameters if they are given */
1366 write_lock_irq(&ztv->lock);
1367 frame->w = vm.width;
1368 frame->h = vm.height;
1369 frame->format = vm.format;
1370 frame->bpp = palette2fmt[frame->format].bpp;
1371 frame->bpl = frame->w*frame->bpp;
1372 frame->status = FBUFFER_BUSY;
1373 frame->next = 0;
1374 { /* add to tail of queue */
1375 struct vidinfo* oldframe = ztv->workqueue;
1376 if (!oldframe) ztv->workqueue = frame;
1377 else {
1378 while (oldframe->next) oldframe = oldframe->next;
1379 oldframe->next = frame;
1380 }
1381 }
1382 write_unlock_irq(&ztv->lock);
1383 zoran_cap(ztv, 1);
1384 break;
1385 }
1386
1387 case VIDIOCGMBUF:
1388 {
1389 struct video_mbuf mb;
1390 int i;
1391 DEBUG(printk(CARD_DEBUG "VIDIOCGMBUF\n",CARD));
1392 mb.size = ZORAN_MAX_FBUFSIZE;
1393 mb.frames = ZORAN_MAX_FBUFFERS;
1394 for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
1395 mb.offsets[i] = i*ZORAN_MAX_FBUFFER;
1396 if(copy_to_user(arg, &mb,sizeof(mb)))
1397 return -EFAULT;
1398 break;
1399 }
1400
1401 case VIDIOCGUNIT:
1402 {
1403 struct video_unit vu;
1404 DEBUG(printk(CARD_DEBUG "VIDIOCGUNIT\n",CARD));
1405 vu.video = ztv->video_dev.minor;
1406 vu.vbi = ztv->vbi_dev.minor;
1407 vu.radio = VIDEO_NO_UNIT;
1408 vu.audio = VIDEO_NO_UNIT;
1409 vu.teletext = VIDEO_NO_UNIT;
1410 if(copy_to_user(arg, &vu,sizeof(vu)))
1411 return -EFAULT;
1412 break;
1413 }
1414
1415 case VIDIOCGFREQ:
1416 {
1417 unsigned long v = ztv->tuner_freq;
1418 if (copy_to_user(arg,&v,sizeof(v)))
1419 return -EFAULT;
1420 DEBUG(printk(CARD_DEBUG "VIDIOCGFREQ\n",CARD));
1421 break;
1422 }
1423 case VIDIOCSFREQ:
1424 {
1425 unsigned long v;
1426 if (copy_from_user(&v, arg, sizeof(v)))
1427 return -EFAULT;
1428 DEBUG(printk(CARD_DEBUG "VIDIOCSFREQ\n",CARD));
1429
1430 if (ztv->have_tuner) {
1431 int fixme = v;
1432 if (i2c_control_device(&(ztv->i2c), I2C_DRIVERID_TUNER, TUNER_SET_TVFREQ, &fixme) < 0)
1433 return -EAGAIN;
1434 }
1435 ztv->tuner_freq = v;
1436 break;
1437 }
1438
1439 /* Why isn't this in the API?
1440 * And why doesn't it take a buffer number?
1441 case BTTV_FIELDNR:
1442 {
1443 unsigned long v = ztv->lastfieldnr;
1444 if (copy_to_user(arg,&v,sizeof(v)))
1445 return -EFAULT;
1446 DEBUG(printk(CARD_DEBUG "BTTV_FIELDNR\n",CARD));
1447 break;
1448 }
1449 */
1450
1451 default:
1452 return -ENOIOCTLCMD;
1453 }
1454 return 0;
1455}
1456
1457static
1458int zoran_mmap(struct vm_area_struct *vma, struct video_device* dev, const char* adr, unsigned long size)
1459{
1460 struct zoran* ztv = (struct zoran*)dev;
1461 unsigned long start = (unsigned long)adr;
1462 unsigned long pos;
1463
1464 DEBUG(printk(CARD_DEBUG "zoran_mmap(0x%p,%ld)\n",CARD,adr,size));
1465
1466 /* sanity checks */
1467 if (size > ZORAN_MAX_FBUFSIZE || !ztv->fbuffer)
1468 return -EINVAL;
1469
1470 /* start mapping the whole shabang to user memory */
1471 pos = (unsigned long)ztv->fbuffer;
1472 while (size>0) {
1473 unsigned long pfn = virt_to_phys((void*)pos) >> PAGE_SHIFT;
1474 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
1475 return -EAGAIN;
1476 start += PAGE_SIZE;
1477 pos += PAGE_SIZE;
1478 size -= PAGE_SIZE;
1479 }
1480 return 0;
1481}
1482
1483static struct video_device zr36120_template=
1484{
1485 .owner = THIS_MODULE,
1486 .name = "UNSET",
1487 .type = VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
1488 .hardware = VID_HARDWARE_ZR36120,
1489 .open = zoran_open,
1490 .close = zoran_close,
1491 .read = zoran_read,
1492 .write = zoran_write,
1493 .poll = zoran_poll,
1494 .ioctl = zoran_ioctl,
1495 .mmap = zoran_mmap,
1496 .minor = -1,
1497};
1498
1499static
1500int vbi_open(struct video_device *dev, int flags)
1501{
1502 struct zoran *ztv = dev->priv;
1503 struct vidinfo* item;
1504
1505 DEBUG(printk(CARD_DEBUG "vbi_open(dev,%d)\n",CARD,flags));
1506
1507 /*
1508 * During VBI device open, we continiously grab VBI-like
1509 * data in the vbi buffer when we have nothing to do.
1510 * Only when there is an explicit request for VBI data
1511 * (read call) we /force/ a read.
1512 */
1513
1514 /* allocate buffers */
1515 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1516 {
1517 item->status = FBUFFER_FREE;
1518
1519 /* alloc */
1520 if (!item->memadr) {
1521 item->memadr = bmalloc(ZORAN_VBI_BUFSIZE);
1522 if (!item->memadr) {
1523 /* could not get a buffer, bail out */
1524 while (item != ztv->readinfo) {
1525 item--;
1526 bfree(item->memadr, ZORAN_VBI_BUFSIZE);
1527 item->memadr = 0;
1528 item->busadr = 0;
1529 }
1530 return -ENOBUFS;
1531 }
1532 }
1533
1534 /* determine the DMAable address */
1535 item->busadr = virt_to_bus(item->memadr);
1536 }
1537
1538 /* do the common part of all open's */
1539 zoran_common_open(ztv, flags);
1540
1541 set_bit(STATE_VBI, &ztv->state);
1542 /* start read-ahead */
1543 zoran_cap(ztv, 1);
1544
1545 return 0;
1546}
1547
1548static
1549void vbi_close(struct video_device *dev)
1550{
1551 struct zoran *ztv = dev->priv;
1552 struct vidinfo* item;
1553
1554 DEBUG(printk(CARD_DEBUG "vbi_close(dev)\n",CARD));
1555
1556 /* driver specific closure */
1557 clear_bit(STATE_VBI, &ztv->state);
1558
1559 zoran_common_close(ztv);
1560
1561 /*
1562 * This is sucky but right now I can't find a good way to
1563 * be sure its safe to free the buffer. We wait 5-6 fields
1564 * which is more than sufficient to be sure.
1565 */
1566 msleep(100); /* Wait 1/10th of a second */
1567
1568 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1569 {
1570 if (item->memadr)
1571 bfree(item->memadr, ZORAN_VBI_BUFSIZE);
1572 item->memadr = 0;
1573 }
1574
1575}
1576
1577/*
1578 * This read function could be used reentrant in a SMP situation.
1579 *
1580 * This is made possible by the spinlock which is kept till we
1581 * found and marked a buffer for our own use. The lock must
1582 * be released as soon as possible to prevent lock contention.
1583 */
1584static
1585long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
1586{
1587 struct zoran *ztv = dev->priv;
1588 unsigned long max;
1589 struct vidinfo* unused = 0;
1590 struct vidinfo* done = 0;
1591
1592 DEBUG(printk(CARD_DEBUG "vbi_read(0x%p,%ld,%d)\n",CARD,buf,count,nonblock));
1593
1594 /* find ourself a free or completed buffer */
1595 for (;;) {
1596 struct vidinfo* item;
1597
1598 write_lock_irq(&ztv->lock);
1599 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++) {
1600 if (!unused && item->status == FBUFFER_FREE)
1601 unused = item;
1602 if (!done && item->status == FBUFFER_DONE)
1603 done = item;
1604 }
1605 if (done || unused)
1606 break;
1607
1608 /* no more free buffers, wait for them. */
1609 write_unlock_irq(&ztv->lock);
1610 if (nonblock)
1611 return -EWOULDBLOCK;
1612 interruptible_sleep_on(&ztv->vbiq);
1613 if (signal_pending(current))
1614 return -EINTR;
1615 }
1616
1617 /* Do we have 'ready' data? */
1618 if (!done) {
1619 /* no? than this will take a while... */
1620 if (nonblock) {
1621 write_unlock_irq(&ztv->lock);
1622 return -EWOULDBLOCK;
1623 }
1624
1625 /* mark the unused buffer as wanted */
1626 unused->status = FBUFFER_BUSY;
1627 unused->next = 0;
1628 { /* add to tail of queue */
1629 struct vidinfo* oldframe = ztv->workqueue;
1630 if (!oldframe) ztv->workqueue = unused;
1631 else {
1632 while (oldframe->next) oldframe = oldframe->next;
1633 oldframe->next = unused;
1634 }
1635 }
1636 write_unlock_irq(&ztv->lock);
1637
1638 /* tell the state machine we want it filled /NOW/ */
1639 zoran_cap(ztv, 1);
1640
1641 /* wait till this buffer gets grabbed */
1642 wait_event_interruptible(ztv->vbiq,
1643 (unused->status != FBUFFER_BUSY));
1644 /* see if a signal did it */
1645 if (signal_pending(current))
1646 return -EINTR;
1647 done = unused;
1648 }
1649 else
1650 write_unlock_irq(&ztv->lock);
1651
1652 /* Yes! we got data! */
1653 max = done->bpl * -done->h;
1654 if (count > max)
1655 count = max;
1656
1657 /* check if the user gave us enough room to write the data */
1658 if (!access_ok(VERIFY_WRITE, buf, count)) {
1659 count = -EFAULT;
1660 goto out;
1661 }
1662
1663 /*
1664 * Now transform/strip the data from YUV to Y-only
1665 * NB. Assume the Y is in the LSB of the YUV data.
1666 */
1667 {
1668 unsigned char* optr = buf;
1669 unsigned char* eptr = buf+count;
1670
1671 /* are we beeing accessed from an old driver? */
1672 if (count == 2*19*2048) {
1673 /*
1674 * Extreme HACK, old VBI programs expect 2048 points
1675 * of data, and we only got 864 orso. Double each
1676 * datapoint and clear the rest of the line.
1677 * This way we have appear to have a
1678 * sample_frequency of 29.5 Mc.
1679 */
1680 int x,y;
1681 unsigned char* iptr = done->memadr+1;
1682 for (y=done->h; optr<eptr && y<0; y++)
1683 {
1684 /* copy to doubled data to userland */
1685 for (x=0; optr+1<eptr && x<-done->w; x++)
1686 {
1687 unsigned char a = iptr[x*2];
1688 __put_user(a, optr++);
1689 __put_user(a, optr++);
1690 }
1691 /* and clear the rest of the line */
1692 for (x*=2; optr<eptr && x<done->bpl; x++)
1693 __put_user(0, optr++);
1694 /* next line */
1695 iptr += done->bpl;
1696 }
1697 }
1698 else {
1699 /*
1700 * Other (probably newer) programs asked
1701 * us what geometry we are using, and are
1702 * reading the correct size.
1703 */
1704 int x,y;
1705 unsigned char* iptr = done->memadr+1;
1706 for (y=done->h; optr<eptr && y<0; y++)
1707 {
1708 /* copy to doubled data to userland */
1709 for (x=0; optr<eptr && x<-done->w; x++)
1710 __put_user(iptr[x*2], optr++);
1711 /* and clear the rest of the line */
1712 for (;optr<eptr && x<done->bpl; x++)
1713 __put_user(0, optr++);
1714 /* next line */
1715 iptr += done->bpl;
1716 }
1717 }
1718
1719 /* API compliance:
1720 * place the framenumber (half fieldnr) in the last long
1721 */
1722 __put_user(done->fieldnr/2, ((ulong*)eptr)[-1]);
1723 }
1724
1725 /* keep the engine running */
1726 done->status = FBUFFER_FREE;
1727 zoran_cap(ztv, 1);
1728
1729 /* tell listeners this buffer just became free */
1730 wake_up_interruptible(&ztv->vbiq);
1731
1732 /* goodbye */
1733out:
1734 DEBUG(printk(CARD_DEBUG "vbi_read() returns %lu\n",CARD,count));
1735 return count;
1736}
1737
1738static
1739unsigned int vbi_poll(struct video_device *dev, struct file *file, poll_table *wait)
1740{
1741 struct zoran *ztv = dev->priv;
1742 struct vidinfo* item;
1743 unsigned int mask = 0;
1744
1745 poll_wait(file, &ztv->vbiq, wait);
1746
1747 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1748 if (item->status == FBUFFER_DONE)
1749 {
1750 mask |= (POLLIN | POLLRDNORM);
1751 break;
1752 }
1753
1754 DEBUG(printk(CARD_DEBUG "vbi_poll()=%x\n",CARD,mask));
1755
1756 return mask;
1757}
1758
1759static
1760int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
1761{
1762 struct zoran* ztv = dev->priv;
1763
1764 switch (cmd) {
1765 case VIDIOCGVBIFMT:
1766 {
1767 struct vbi_format f;
1768 DEBUG(printk(CARD_DEBUG "VIDIOCGVBIINFO\n",CARD));
1769 f.sampling_rate = 14750000UL;
1770 f.samples_per_line = -ztv->readinfo[0].w;
1771 f.sample_format = VIDEO_PALETTE_RAW;
1772 f.start[0] = f.start[1] = ztv->readinfo[0].y;
1773 f.start[1] += 312;
1774 f.count[0] = f.count[1] = -ztv->readinfo[0].h;
1775 f.flags = VBI_INTERLACED;
1776 if (copy_to_user(arg,&f,sizeof(f)))
1777 return -EFAULT;
1778 break;
1779 }
1780 case VIDIOCSVBIFMT:
1781 {
1782 struct vbi_format f;
1783 int i;
1784 if (copy_from_user(&f, arg,sizeof(f)))
1785 return -EFAULT;
1786 DEBUG(printk(CARD_DEBUG "VIDIOCSVBIINFO(%d,%d,%d,%d,%d,%d,%d,%x)\n",CARD,f.sampling_rate,f.samples_per_line,f.sample_format,f.start[0],f.start[1],f.count[0],f.count[1],f.flags));
1787
1788 /* lots of parameters are fixed... (PAL) */
1789 if (f.sampling_rate != 14750000UL ||
1790 f.samples_per_line > 864 ||
1791 f.sample_format != VIDEO_PALETTE_RAW ||
1792 f.start[0] < 0 ||
1793 f.start[0] != f.start[1]-312 ||
1794 f.count[0] != f.count[1] ||
1795 f.start[0]+f.count[0] >= 288 ||
1796 f.flags != VBI_INTERLACED)
1797 return -EINVAL;
1798
1799 write_lock_irq(&ztv->lock);
1800 ztv->readinfo[0].y = f.start[0];
1801 ztv->readinfo[0].w = -f.samples_per_line;
1802 ztv->readinfo[0].h = -f.count[0];
1803 ztv->readinfo[0].bpl = f.samples_per_line*ztv->readinfo[0].bpp;
1804 for (i=1; i<ZORAN_VBI_BUFFERS; i++)
1805 ztv->readinfo[i] = ztv->readinfo[i];
1806 write_unlock_irq(&ztv->lock);
1807 break;
1808 }
1809 default:
1810 return -ENOIOCTLCMD;
1811 }
1812 return 0;
1813}
1814
1815static struct video_device vbi_template=
1816{
1817 .owner = THIS_MODULE,
1818 .name = "UNSET",
1819 .type = VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
1820 .hardware = VID_HARDWARE_ZR36120,
1821 .open = vbi_open,
1822 .close = vbi_close,
1823 .read = vbi_read,
1824 .write = zoran_write,
1825 .poll = vbi_poll,
1826 .ioctl = vbi_ioctl,
1827 .minor = -1,
1828};
1829
1830/*
1831 * Scan for a Zoran chip, request the irq and map the io memory
1832 */
1833static
1834int __init find_zoran(void)
1835{
1836 int result;
1837 struct zoran *ztv;
1838 struct pci_dev *dev = NULL;
1839 unsigned char revision;
1840 int zoran_num=0;
1841
1842 while ((dev = pci_find_device(PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120, dev)))
1843 {
1844 /* Ok, a ZR36120/ZR36125 found! */
1845 ztv = &zorans[zoran_num];
1846 ztv->dev = dev;
1847
1848 if (pci_enable_device(dev))
1849 return -EIO;
1850
1851 pci_read_config_byte(dev, PCI_CLASS_REVISION, &revision);
1852 printk(KERN_INFO "zoran: Zoran %x (rev %d) ",
1853 dev->device, revision);
1854 printk("bus: %d, devfn: %d, irq: %d, ",
1855 dev->bus->number, dev->devfn, dev->irq);
1856 printk("memory: 0x%08lx.\n", ztv->zoran_adr);
1857
1858 ztv->zoran_mem = ioremap(ztv->zoran_adr, 0x1000);
1859 DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));
1860
1861 result = request_irq(dev->irq, zoran_irq,
1862 SA_SHIRQ|SA_INTERRUPT,"zoran", ztv);
1863 if (result==-EINVAL)
1864 {
1865 iounmap(ztv->zoran_mem);
1866 printk(KERN_ERR "zoran: Bad irq number or handler\n");
1867 return -EINVAL;
1868 }
1869 if (result==-EBUSY)
1870 printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",dev->irq);
1871 if (result < 0) {
1872 iounmap(ztv->zoran_mem);
1873 return result;
1874 }
1875 /* Enable bus-mastering */
1876 pci_set_master(dev);
1877
1878 zoran_num++;
1879 }
1880 if(zoran_num)
1881 printk(KERN_INFO "zoran: %d Zoran card(s) found.\n",zoran_num);
1882 return zoran_num;
1883}
1884
1885static
1886int __init init_zoran(int card)
1887{
1888 struct zoran *ztv = &zorans[card];
1889 int i;
1890
1891 /* if the given cardtype valid? */
1892 if (cardtype[card]>=NRTVCARDS) {
1893 printk(KERN_INFO "invalid cardtype(%d) detected\n",cardtype[card]);
1894 return -1;
1895 }
1896
1897 /* reset the zoran */
1898 zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
1899 udelay(10);
1900 zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
1901 udelay(10);
1902
1903 /* zoran chip specific details */
1904 ztv->card = tvcards+cardtype[card]; /* point to the selected card */
1905 ztv->norm = 0; /* PAL */
1906 ztv->tuner_freq = 0;
1907
1908 /* videocard details */
1909 ztv->swidth = 800;
1910 ztv->sheight = 600;
1911 ztv->depth = 16;
1912
1913 /* State details */
1914 ztv->fbuffer = 0;
1915 ztv->overinfo.kindof = FBUFFER_OVERLAY;
1916 ztv->overinfo.status = FBUFFER_FREE;
1917 ztv->overinfo.x = 0;
1918 ztv->overinfo.y = 0;
1919 ztv->overinfo.w = 768; /* 640 */
1920 ztv->overinfo.h = 576; /* 480 */
1921 ztv->overinfo.format = VIDEO_PALETTE_RGB565;
1922 ztv->overinfo.bpp = palette2fmt[ztv->overinfo.format].bpp;
1923 ztv->overinfo.bpl = ztv->overinfo.bpp*ztv->swidth;
1924 ztv->overinfo.busadr = 0;
1925 ztv->overinfo.memadr = 0;
1926 ztv->overinfo.overlay = 0;
1927 for (i=0; i<ZORAN_MAX_FBUFFERS; i++) {
1928 ztv->grabinfo[i] = ztv->overinfo;
1929 ztv->grabinfo[i].kindof = FBUFFER_GRAB;
1930 }
1931 init_waitqueue_head(&ztv->grabq);
1932
1933 /* VBI details */
1934 ztv->readinfo[0] = ztv->overinfo;
1935 ztv->readinfo[0].kindof = FBUFFER_VBI;
1936 ztv->readinfo[0].w = -864;
1937 ztv->readinfo[0].h = -38;
1938 ztv->readinfo[0].format = VIDEO_PALETTE_YUV422;
1939 ztv->readinfo[0].bpp = palette2fmt[ztv->readinfo[0].format].bpp;
1940 ztv->readinfo[0].bpl = 1024*ztv->readinfo[0].bpp;
1941 for (i=1; i<ZORAN_VBI_BUFFERS; i++)
1942 ztv->readinfo[i] = ztv->readinfo[0];
1943 init_waitqueue_head(&ztv->vbiq);
1944
1945 /* maintenance data */
1946 ztv->have_decoder = 0;
1947 ztv->have_tuner = 0;
1948 ztv->tuner_type = 0;
1949 ztv->running = 0;
1950 ztv->users = 0;
1951 rwlock_init(&ztv->lock);
1952 ztv->workqueue = 0;
1953 ztv->fieldnr = 0;
1954 ztv->lastfieldnr = 0;
1955
1956 if (triton1)
1957 zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC);
1958
1959 /* external FL determines TOP frame */
1960 zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC);
1961
1962 /* set HSpol */
1963 if (ztv->card->hsync_pos)
1964 zrwrite(ZORAN_VFEH_HSPOL, ZORAN_VFEH);
1965 /* set VSpol */
1966 if (ztv->card->vsync_pos)
1967 zrwrite(ZORAN_VFEV_VSPOL, ZORAN_VFEV);
1968
1969 /* Set the proper General Purpuse register bits */
1970 /* implicit: no softreset, 0 waitstates */
1971 zrwrite(ZORAN_PCI_SOFTRESET|(ztv->card->gpdir<<0),ZORAN_PCI);
1972 /* implicit: 3 duration and recovery PCI clocks on guest 0-3 */
1973 zrwrite(ztv->card->gpval<<24,ZORAN_GUEST);
1974
1975 /* clear interrupt status */
1976 zrwrite(~0, ZORAN_ISR);
1977
1978 /*
1979 * i2c template
1980 */
1981 ztv->i2c = zoran_i2c_bus_template;
1982 sprintf(ztv->i2c.name,"zoran-%d",card);
1983 ztv->i2c.data = ztv;
1984
1985 /*
1986 * Now add the template and register the device unit
1987 */
1988 ztv->video_dev = zr36120_template;
1989 strcpy(ztv->video_dev.name, ztv->i2c.name);
1990 ztv->video_dev.priv = ztv;
1991 if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER, video_nr) < 0)
1992 return -1;
1993
1994 ztv->vbi_dev = vbi_template;
1995 strcpy(ztv->vbi_dev.name, ztv->i2c.name);
1996 ztv->vbi_dev.priv = ztv;
1997 if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI, vbi_nr) < 0) {
1998 video_unregister_device(&ztv->video_dev);
1999 return -1;
2000 }
2001 i2c_register_bus(&ztv->i2c);
2002
2003 /* set interrupt mask - the PIN enable will be set later */
2004 zrwrite(ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1|ZORAN_ICR_CODE, ZORAN_ICR);
2005
2006 printk(KERN_INFO "%s: installed %s\n",ztv->i2c.name,ztv->card->name);
2007 return 0;
2008}
2009
2010static
2011void release_zoran(int max)
2012{
2013 struct zoran *ztv;
2014 int i;
2015
2016 for (i=0;i<max; i++)
2017 {
2018 ztv = &zorans[i];
2019
2020 /* turn off all capturing, DMA and IRQs */
2021 /* reset the zoran */
2022 zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
2023 udelay(10);
2024 zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
2025 udelay(10);
2026
2027 /* first disable interrupts before unmapping the memory! */
2028 zrwrite(0, ZORAN_ICR);
2029 zrwrite(0xffffffffUL,ZORAN_ISR);
2030
2031 /* free it */
2032 free_irq(ztv->dev->irq,ztv);
2033
2034 /* unregister i2c_bus */
2035 i2c_unregister_bus((&ztv->i2c));
2036
2037 /* unmap and free memory */
2038 if (ztv->zoran_mem)
2039 iounmap(ztv->zoran_mem);
2040
2041 video_unregister_device(&ztv->video_dev);
2042 video_unregister_device(&ztv->vbi_dev);
2043 }
2044}
2045
2046void __exit zr36120_exit(void)
2047{
2048 release_zoran(zoran_cards);
2049}
2050
2051int __init zr36120_init(void)
2052{
2053 int card;
2054
2055 handle_chipset();
2056 zoran_cards = find_zoran();
2057 if (zoran_cards<0)
2058 /* no cards found, no need for a driver */
2059 return -EIO;
2060
2061 /* initialize Zorans */
2062 for (card=0; card<zoran_cards; card++) {
2063 if (init_zoran(card)<0) {
2064 /* only release the zorans we have registered */
2065 release_zoran(card);
2066 return -EIO;
2067 }
2068 }
2069 return 0;
2070}
2071
2072module_init(zr36120_init);
2073module_exit(zr36120_exit);
diff --git a/drivers/media/video/zr36120.h b/drivers/media/video/zr36120.h
new file mode 100644
index 000000000000..571f8e84b58a
--- /dev/null
+++ b/drivers/media/video/zr36120.h
@@ -0,0 +1,279 @@
1/*
2 zr36120.h - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink (middelin@polyware.nl)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _ZR36120_H
22#define _ZR36120_H
23
24#ifdef __KERNEL__
25
26#include <linux/types.h>
27#include <linux/wait.h>
28
29#include <linux/i2c-old.h>
30#include <linux/videodev.h>
31
32#include <asm/io.h>
33
34/*
35 * Debug macro's, place an x behind the ) for actual debug-compilation
36 * E.g. #define DEBUG(x...) x
37 */
38#define DEBUG(x...) /* Debug driver */
39#define IDEBUG(x...) /* Debug interrupt handler */
40#define PDEBUG 0 /* Debug PCI writes */
41
42/* defined in zr36120_i2c */
43extern struct i2c_bus zoran_i2c_bus_template;
44
45#define ZORAN_MAX_FBUFFERS 2
46#define ZORAN_MAX_FBUFFER (768*576*2)
47#define ZORAN_MAX_FBUFSIZE (ZORAN_MAX_FBUFFERS*ZORAN_MAX_FBUFFER)
48
49#define ZORAN_VBI_BUFFERS 2
50#define ZORAN_VBI_BUFSIZE (22*1024*2)
51
52struct tvcard {
53 char* name; /* name of the cardtype */
54 int video_inputs; /* number of channels defined in video_mux */
55 int audio_inputs; /* number of channels defined in audio_mux */
56 __u32 swapi2c:1, /* need to swap i2c wires SDA/SCL? */
57 usegirq1:1, /* VSYNC at GIRQ1 instead of GIRQ0? */
58 vsync_pos:1, /* positive VSYNC signal? */
59 hsync_pos:1, /* positive HSYNC signal? */
60 gpdir:8, /* General Purpose Direction register */
61 gpval:8; /* General Purpose Value register */
62 int video_mux[6]; /* mapping channel number to physical input */
63#define IS_TUNER 0x80
64#define IS_SVHS 0x40
65#define CHANNEL_MASK 0x3F
66 int audio_mux[6]; /* mapping channel number to physical input */
67};
68#define TUNER(x) ((x)|IS_TUNER)
69#define SVHS(x) ((x)|IS_SVHS)
70
71struct vidinfo {
72 struct vidinfo* next; /* next active buffer */
73 uint kindof;
74#define FBUFFER_OVERLAY 0
75#define FBUFFER_GRAB 1
76#define FBUFFER_VBI 2
77 uint status;
78#define FBUFFER_FREE 0
79#define FBUFFER_BUSY 1
80#define FBUFFER_DONE 2
81 ulong fieldnr; /* # of field, not framer! */
82 uint x,y;
83 int w,h; /* w,h can be negative! */
84 uint format; /* index in palette2fmt[] */
85 uint bpp; /* lookup from palette2fmt[] */
86 uint bpl; /* calc: width * bpp */
87 ulong busadr; /* bus addr for DMA engine */
88 char* memadr; /* kernel addr for making copies */
89 ulong* overlay; /* kernel addr of overlay mask */
90};
91
92struct zoran
93{
94 struct video_device video_dev;
95#define CARD_DEBUG KERN_DEBUG "%s(%lu): "
96#define CARD_INFO KERN_INFO "%s(%lu): "
97#define CARD_ERR KERN_ERR "%s(%lu): "
98#define CARD ztv->video_dev.name,ztv->fieldnr
99
100 /* zoran chip specific details */
101 struct i2c_bus i2c; /* i2c registration data */
102 struct pci_dev* dev; /* ptr to PCI device */
103 ulong zoran_adr; /* bus address of IO memory */
104 char* zoran_mem; /* kernel address of IO memory */
105 struct tvcard* card; /* the cardtype */
106 uint norm; /* 0=PAL, 1=NTSC, 2=SECAM */
107 uint tuner_freq; /* Current freq in kHz */
108 struct video_picture picture; /* Current picture params */
109
110 /* videocard details */
111 uint swidth; /* screen width */
112 uint sheight; /* screen height */
113 uint depth; /* depth in bits */
114
115 /* State details */
116 char* fbuffer; /* framebuffers for mmap */
117 struct vidinfo overinfo; /* overlay data */
118 struct vidinfo grabinfo[ZORAN_MAX_FBUFFERS]; /* grabbing data*/
119 wait_queue_head_t grabq; /* grabbers queue */
120
121 /* VBI details */
122 struct video_device vbi_dev;
123 struct vidinfo readinfo[2]; /* VBI data - flip buffers */
124 wait_queue_head_t vbiq; /* vbi queue */
125
126 /* maintenance data */
127 int have_decoder; /* did we detect a mux? */
128 int have_tuner; /* did we detect a tuner? */
129 int users; /* howmany video/vbi open? */
130 int tuner_type; /* tuner type, when found */
131 int running; /* are we rolling? */
132 rwlock_t lock;
133 long state; /* what is requested of us? */
134#define STATE_OVERLAY 0
135#define STATE_VBI 1
136 struct vidinfo* workqueue; /* buffers to grab, head is active */
137 ulong fieldnr; /* #field, ticked every VSYNC */
138 ulong lastfieldnr; /* #field, ticked every GRAB */
139
140 int vidInterlace; /* calculated */
141 int vidXshift; /* calculated */
142 uint vidWidth; /* calculated */
143 uint vidHeight; /* calculated */
144};
145
146#define zrwrite(dat,adr) writel((dat),(char *) (ztv->zoran_mem+(adr)))
147#define zrread(adr) readl(ztv->zoran_mem+(adr))
148
149#if PDEBUG == 0
150#define zrand(dat,adr) zrwrite((dat) & zrread(adr), adr)
151#define zror(dat,adr) zrwrite((dat) | zrread(adr), adr)
152#define zraor(dat,mask,adr) zrwrite( ((dat)&~(mask)) | ((mask)&zrread(adr)), adr)
153#else
154#define zrand(dat, adr) \
155do { \
156 ulong data = (dat) & zrread((adr)); \
157 zrwrite(data, (adr)); \
158 if (0 != (~(dat) & zrread((adr)))) \
159 printk(KERN_DEBUG "zoran: zrand at %d(%d) detected set bits(%x)\n", __LINE__, (adr), (dat)); \
160} while(0)
161
162#define zror(dat, adr) \
163do { \
164 ulong data = (dat) | zrread((adr)); \
165 zrwrite(data, (adr)); \
166 if ((dat) != ((dat) & zrread(adr))) \
167 printk(KERN_DEBUG "zoran: zror at %d(%d) detected unset bits(%x)\n", __LINE__, (adr), (dat)); \
168} while(0)
169
170#define zraor(dat, mask, adr) \
171do { \
172 ulong data; \
173 if ((dat) & (mask)) \
174 printk(KERN_DEBUG "zoran: zraor at %d(%d) detected bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
175 data = ((dat)&~(mask)) | ((mask) & zrread((adr))); \
176 zrwrite(data,(adr)); \
177 if ( (dat) != (~(mask) & zrread((adr))) ) \
178 printk(KERN_DEBUG "zoran: zraor at %d(%d) could not set all bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
179} while(0)
180#endif
181
182#endif
183
184/* zoran PCI address space */
185#define ZORAN_VFEH 0x000 /* Video Front End Horizontal Conf. */
186#define ZORAN_VFEH_HSPOL (1<<30)
187#define ZORAN_VFEH_HSTART (0x3FF<<10)
188#define ZORAN_VFEH_HEND (0x3FF<<0)
189
190#define ZORAN_VFEV 0x004 /* Video Front End Vertical Conf. */
191#define ZORAN_VFEV_VSPOL (1<<30)
192#define ZORAN_VFEV_VSTART (0x3FF<<10)
193#define ZORAN_VFEV_VEND (0x3FF<<0)
194
195#define ZORAN_VFEC 0x008 /* Video Front End Scaler and Pixel */
196#define ZORAN_VFEC_EXTFL (1<<26)
197#define ZORAN_VFEC_TOPFIELD (1<<25)
198#define ZORAN_VFEC_VCLKPOL (1<<24)
199#define ZORAN_VFEC_HFILTER (7<<21)
200#define ZORAN_VFEC_HFILTER_1 (0<<21) /* no lumi, 3-tap chromo */
201#define ZORAN_VFEC_HFILTER_2 (1<<21) /* 3-tap lumi, 3-tap chromo */
202#define ZORAN_VFEC_HFILTER_3 (2<<21) /* 4-tap lumi, 4-tap chromo */
203#define ZORAN_VFEC_HFILTER_4 (3<<21) /* 5-tap lumi, 4-tap chromo */
204#define ZORAN_VFEC_HFILTER_5 (4<<21) /* 4-tap lumi, 4-tap chromo */
205#define ZORAN_VFEC_DUPFLD (1<<20)
206#define ZORAN_VFEC_HORDCM (63<<14)
207#define ZORAN_VFEC_VERDCM (63<<8)
208#define ZORAN_VFEC_DISPMOD (1<<6)
209#define ZORAN_VFEC_RGB (3<<3)
210#define ZORAN_VFEC_RGB_YUV422 (0<<3)
211#define ZORAN_VFEC_RGB_RGB888 (1<<3)
212#define ZORAN_VFEC_RGB_RGB565 (2<<3)
213#define ZORAN_VFEC_RGB_RGB555 (3<<3)
214#define ZORAN_VFEC_ERRDIF (1<<2)
215#define ZORAN_VFEC_PACK24 (1<<1)
216#define ZORAN_VFEC_LE (1<<0)
217
218#define ZORAN_VTOP 0x00C /* Video Display "Top" */
219
220#define ZORAN_VBOT 0x010 /* Video Display "Bottom" */
221
222#define ZORAN_VSTR 0x014 /* Video Display Stride */
223#define ZORAN_VSTR_DISPSTRIDE (0xFFFF<<16)
224#define ZORAN_VSTR_VIDOVF (1<<8)
225#define ZORAN_VSTR_SNAPSHOT (1<<1)
226#define ZORAN_VSTR_GRAB (1<<0)
227
228#define ZORAN_VDC 0x018 /* Video Display Conf. */
229#define ZORAN_VDC_VIDEN (1<<31)
230#define ZORAN_VDC_MINPIX (0x1F<<25)
231#define ZORAN_VDC_TRICOM (1<<24)
232#define ZORAN_VDC_VIDWINHT (0x3FF<<12)
233#define ZORAN_VDC_VIDWINWID (0x3FF<<0)
234
235#define ZORAN_MTOP 0x01C /* Masking Map "Top" */
236
237#define ZORAN_MBOT 0x020 /* Masking Map "Bottom" */
238
239#define ZORAN_OCR 0x024 /* Overlay Control */
240#define ZORAN_OCR_OVLEN (1<<15)
241#define ZORAN_OCR_MASKSTRIDE (0xFF<<0)
242
243#define ZORAN_PCI 0x028 /* System, PCI and GPP Control */
244#define ZORAN_PCI_SOFTRESET (1<<24)
245#define ZORAN_PCI_WAITSTATE (3<<16)
246#define ZORAN_PCI_GENPURDIR (0xFF<<0)
247
248#define ZORAN_GUEST 0x02C /* GuestBus Control */
249
250#define ZORAN_CSOURCE 0x030 /* Code Source Address */
251
252#define ZORAN_CTRANS 0x034 /* Code Transfer Control */
253
254#define ZORAN_CMEM 0x038 /* Code Memory Pointer */
255
256#define ZORAN_ISR 0x03C /* Interrupt Status Register */
257#define ZORAN_ISR_CODE (1<<28)
258#define ZORAN_ISR_GIRQ0 (1<<29)
259#define ZORAN_ISR_GIRQ1 (1<<30)
260
261#define ZORAN_ICR 0x040 /* Interrupt Control Register */
262#define ZORAN_ICR_EN (1<<24)
263#define ZORAN_ICR_CODE (1<<28)
264#define ZORAN_ICR_GIRQ0 (1<<29)
265#define ZORAN_ICR_GIRQ1 (1<<30)
266
267#define ZORAN_I2C 0x044 /* I2C-Bus */
268#define ZORAN_I2C_SCL (1<<1)
269#define ZORAN_I2C_SDA (1<<0)
270
271#define ZORAN_POST 0x48 /* PostOffice */
272#define ZORAN_POST_PEN (1<<25)
273#define ZORAN_POST_TIME (1<<24)
274#define ZORAN_POST_DIR (1<<23)
275#define ZORAN_POST_GUESTID (3<<20)
276#define ZORAN_POST_GUEST (7<<16)
277#define ZORAN_POST_DATA (0xFF<<0)
278
279#endif
diff --git a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c
new file mode 100644
index 000000000000..6bfe84d657f1
--- /dev/null
+++ b/drivers/media/video/zr36120_i2c.c
@@ -0,0 +1,132 @@
1/*
2 zr36120_i2c.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/types.h>
22#include <linux/delay.h>
23#include <asm/io.h>
24
25#include <linux/video_decoder.h>
26#include <asm/uaccess.h>
27
28#include "tuner.h"
29#include "zr36120.h"
30
31/* ----------------------------------------------------------------------- */
32/* I2C functions */
33/* ----------------------------------------------------------------------- */
34
35/* software I2C functions */
36
37#define I2C_DELAY 10
38
39static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
40{
41 struct zoran *ztv = (struct zoran*)bus->data;
42 unsigned int b = 0;
43 if (data) b |= ztv->card->swapi2c ? ZORAN_I2C_SCL : ZORAN_I2C_SDA;
44 if (ctrl) b |= ztv->card->swapi2c ? ZORAN_I2C_SDA : ZORAN_I2C_SCL;
45 zrwrite(b, ZORAN_I2C);
46 udelay(I2C_DELAY);
47}
48
49static int i2c_getdataline(struct i2c_bus *bus)
50{
51 struct zoran *ztv = (struct zoran*)bus->data;
52 if (ztv->card->swapi2c)
53 return zrread(ZORAN_I2C) & ZORAN_I2C_SCL;
54 return zrread(ZORAN_I2C) & ZORAN_I2C_SDA;
55}
56
57static
58void attach_inform(struct i2c_bus *bus, int id)
59{
60 struct zoran *ztv = (struct zoran*)bus->data;
61 struct video_decoder_capability dc;
62 int rv;
63
64 switch (id) {
65 case I2C_DRIVERID_VIDEODECODER:
66 DEBUG(printk(CARD_INFO "decoder attached\n",CARD));
67
68 /* fetch the capabilites of the decoder */
69 rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
70 if (rv) {
71 DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD));
72 break;
73 }
74 DEBUG(printk(CARD_DEBUG "capabilities %d %d %d\n",CARD,dc.flags,dc.inputs,dc.outputs));
75
76 /* Test if the decoder can de VBI transfers */
77 if (dc.flags & 16 /*VIDEO_DECODER_VBI*/)
78 ztv->have_decoder = 2;
79 else
80 ztv->have_decoder = 1;
81 break;
82 case I2C_DRIVERID_TUNER:
83 ztv->have_tuner = 1;
84 DEBUG(printk(CARD_INFO "tuner attached\n",CARD));
85 if (ztv->tuner_type >= 0)
86 {
87 if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
88 DEBUG(printk(CARD_INFO "attach_inform; tuner won't be set to type %d\n",CARD,ztv->tuner_type));
89 }
90 break;
91 default:
92 DEBUG(printk(CARD_INFO "attach_inform; unknown device id=%d\n",CARD,id));
93 break;
94 }
95}
96
97static
98void detach_inform(struct i2c_bus *bus, int id)
99{
100 struct zoran *ztv = (struct zoran*)bus->data;
101
102 switch (id) {
103 case I2C_DRIVERID_VIDEODECODER:
104 ztv->have_decoder = 0;
105 DEBUG(printk(CARD_INFO "decoder detached\n",CARD));
106 break;
107 case I2C_DRIVERID_TUNER:
108 ztv->have_tuner = 0;
109 DEBUG(printk(CARD_INFO "tuner detached\n",CARD));
110 break;
111 default:
112 DEBUG(printk(CARD_INFO "detach_inform; unknown device id=%d\n",CARD,id));
113 break;
114 }
115}
116
117struct i2c_bus zoran_i2c_bus_template =
118{
119 "ZR36120",
120 I2C_BUSID_ZORAN,
121 NULL,
122
123 SPIN_LOCK_UNLOCKED,
124
125 attach_inform,
126 detach_inform,
127
128 i2c_setlines,
129 i2c_getdataline,
130 NULL,
131 NULL
132};
diff --git a/drivers/media/video/zr36120_mem.c b/drivers/media/video/zr36120_mem.c
new file mode 100644
index 000000000000..c87113d6cc60
--- /dev/null
+++ b/drivers/media/video/zr36120_mem.c
@@ -0,0 +1,79 @@
1/*
2 zr36120_mem.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/config.h>
22#include <linux/mm.h>
23#include <linux/pci.h>
24#include <linux/slab.h>
25#include <linux/module.h>
26#include <asm/io.h>
27#ifdef CONFIG_BIGPHYS_AREA
28#include <linux/bigphysarea.h>
29#endif
30
31#include "zr36120.h"
32#include "zr36120_mem.h"
33
34/*******************************/
35/* Memory management functions */
36/*******************************/
37
38void* bmalloc(unsigned long size)
39{
40 void* mem;
41#ifdef CONFIG_BIGPHYS_AREA
42 mem = bigphysarea_alloc_pages(size/PAGE_SIZE, 1, GFP_KERNEL);
43#else
44 /*
45 * The following function got a lot of memory at boottime,
46 * so we know its always there...
47 */
48 mem = (void*)__get_free_pages(GFP_USER|GFP_DMA,get_order(size));
49#endif
50 if (mem) {
51 unsigned long adr = (unsigned long)mem;
52 while (size > 0) {
53 SetPageReserved(virt_to_page(phys_to_virt(adr)));
54 adr += PAGE_SIZE;
55 size -= PAGE_SIZE;
56 }
57 }
58 return mem;
59}
60
61void bfree(void* mem, unsigned long size)
62{
63 if (mem) {
64 unsigned long adr = (unsigned long)mem;
65 unsigned long siz = size;
66 while (siz > 0) {
67 ClearPageReserved(virt_to_page(phys_to_virt(adr)));
68 adr += PAGE_SIZE;
69 siz -= PAGE_SIZE;
70 }
71#ifdef CONFIG_BIGPHYS_AREA
72 bigphysarea_free_pages(mem);
73#else
74 free_pages((unsigned long)mem,get_order(size));
75#endif
76 }
77}
78
79MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36120_mem.h b/drivers/media/video/zr36120_mem.h
new file mode 100644
index 000000000000..aad117acc91d
--- /dev/null
+++ b/drivers/media/video/zr36120_mem.h
@@ -0,0 +1,3 @@
1/* either kmalloc() or bigphysarea() alloced memory - continuous */
2void* bmalloc(unsigned long size);
3void bfree(void* mem, unsigned long size);